Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 35 additions & 10 deletions sys/xtimer/xtimer_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ void _xtimer_set64(xtimer_t *timer, uint32_t offset, uint32_t long_offset)
}

_add_timer_to_long_list(&long_list_head, timer);
/* No timer scheduled in this timer period
* schedule callback on next overflow */
if (!timer_list_head) {
_lltimer_set(_xtimer_lltimer_mask(0xFFFFFFFF));
}
irq_restore(state);
DEBUG("xtimer_set64(): added longterm timer (long_target=%" PRIu32 " target=%" PRIu32 ")\n",
timer->long_target, timer->target);
Expand Down Expand Up @@ -200,11 +205,21 @@ int _xtimer_set_absolute(xtimer_t *timer, uint32_t target)
if ( (timer->long_target > _long_cnt) || !_this_high_period(target) ) {
DEBUG("xtimer_set_absolute(): the timer doesn't fit into the low-level timer's mask.\n");
_add_timer_to_long_list(&long_list_head, timer);
/* No timer scheduled in this timer period
* schedule callback on next overflow */
if (!timer_list_head) {
_lltimer_set(_xtimer_lltimer_mask(0xFFFFFFFF));
}
}
else {
if (_xtimer_lltimer_mask(now) >= target) {
DEBUG("xtimer_set_absolute(): the timer will expire in the next timer period\n");
_add_timer_to_list(&overflow_list_head, timer);
/* No timer scheduled in this timer period
* schedule callback on next overflow */
if (!timer_list_head) {
_lltimer_set(_xtimer_lltimer_mask(0xFFFFFFFF));
}
}
else {
DEBUG("timer_set_absolute(): timer will expire in this timer period.\n");
Expand Down Expand Up @@ -260,16 +275,18 @@ static int _remove_timer_from_list(xtimer_t **list_head, xtimer_t *timer)
static void _remove(xtimer_t *timer)
{
if (timer_list_head == timer) {
uint32_t next;
timer_list_head = timer->next;
if (timer_list_head) {
/* schedule callback on next timer target time */
next = timer_list_head->target - XTIMER_OVERHEAD;
_lltimer_set(timer_list_head->target - XTIMER_OVERHEAD);
}
else if (overflow_list_head || long_list_head) {
/* schedule callback on next overflow */
_lltimer_set(_xtimer_lltimer_mask(0xFFFFFFFF));
}
else {
next = _xtimer_lltimer_mask(0xFFFFFFFF);
/* zero ongoing timer, no callback schedule */
}
_lltimer_set(next);
}
else {
if (!_remove_timer_from_list(&timer_list_head, timer)) {
Expand Down Expand Up @@ -505,11 +522,13 @@ static void _timer_callback(void)
if (next_target < (_xtimer_lltimer_now() + XTIMER_ISR_BACKOFF)) {
goto overflow;
}

_in_handler = 0;
/* set low level timer */
_lltimer_set(next_target);
}
else {
/* there's no timer planned for this timer period */
/* schedule callback on next overflow */
next_target = _xtimer_lltimer_mask(0xFFFFFFFF);
uint32_t now = _xtimer_lltimer_now();

/* check for overflow again */
Expand All @@ -528,10 +547,16 @@ static void _timer_callback(void)
goto overflow;
}
}
}

_in_handler = 0;
_in_handler = 0;

/* set low level timer */
_lltimer_set(next_target);
if (overflow_list_head || long_list_head) {
/* some timers are scheduled for the future timer periods */
/* schedule callback on next overflow */
_lltimer_set(_xtimer_lltimer_mask(0xFFFFFFFF));
}
else {
/* zero ongoing timer, no callback schedule */
}
}
}