Modified for BG96
Fork of mbed-dev by
Diff: hal/mbed_ticker_api.c
- Revision:
- 187:0387e8f68319
- Parent:
- 186:707f6e361f3e
diff -r 707f6e361f3e -r 0387e8f68319 hal/mbed_ticker_api.c --- a/hal/mbed_ticker_api.c Fri Jun 22 16:45:37 2018 +0100 +++ b/hal/mbed_ticker_api.c Thu Sep 06 13:40:20 2018 +0100 @@ -23,13 +23,13 @@ static void update_present_time(const ticker_data_t *const ticker); /* - * Initialize a ticker instance. + * Initialize a ticker instance. */ static void initialize(const ticker_data_t *ticker) { - // return if the queue has already been initialized, in that case the + // return if the queue has already been initialized, in that case the // interface used by the queue is already initialized. - if (ticker->queue->initialized) { + if (ticker->queue->initialized) { return; } @@ -57,7 +57,7 @@ } uint32_t max_delta = 0x7 << (bits - 4); // 7/16th uint64_t max_delta_us = - ((uint64_t)max_delta * 1000000 + frequency - 1) / frequency; + ((uint64_t)max_delta * 1000000 + frequency - 1) / frequency; ticker->queue->event_handler = NULL; ticker->queue->head = NULL; @@ -69,14 +69,15 @@ ticker->queue->max_delta = max_delta; ticker->queue->max_delta_us = max_delta_us; ticker->queue->present_time = 0; + ticker->queue->dispatching = false; ticker->queue->initialized = true; - + update_present_time(ticker); schedule_interrupt(ticker); } /** - * Set the event handler function of a ticker instance. + * Set the event handler function of a ticker instance. */ static void set_handler(const ticker_data_t *const ticker, ticker_event_handler handler) { @@ -86,18 +87,18 @@ /* * Convert a 32 bit timestamp into a 64 bit timestamp. * - * A 64 bit timestamp is used as the point of time of reference while the - * timestamp to convert is relative to this point of time. + * A 64 bit timestamp is used as the point of time of reference while the + * timestamp to convert is relative to this point of time. + * + * The lower 32 bits of the timestamp returned will be equal to the timestamp to + * convert. * - * The lower 32 bits of the timestamp returned will be equal to the timestamp to - * convert. - * - * If the timestamp to convert is less than the lower 32 bits of the time - * reference then the timestamp to convert is seen as an overflowed value and - * the upper 32 bit of the timestamp returned will be equal to the upper 32 bit - * of the reference point + 1. - * Otherwise, the upper 32 bit returned will be equal to the upper 32 bit of the - * reference point. + * If the timestamp to convert is less than the lower 32 bits of the time + * reference then the timestamp to convert is seen as an overflowed value and + * the upper 32 bit of the timestamp returned will be equal to the upper 32 bit + * of the reference point + 1. + * Otherwise, the upper 32 bit returned will be equal to the upper 32 bit of the + * reference point. * * @param ref: The 64 bit timestamp of reference. * @param timestamp: The timestamp to convert. @@ -107,8 +108,8 @@ bool overflow = timestamp < ((timestamp_t) ref) ? true : false; us_timestamp_t result = (ref & ~((us_timestamp_t)UINT32_MAX)) | timestamp; - if (overflow) { - result += (1ULL<<32); + if (overflow) { + result += (1ULL << 32); } return result; @@ -214,21 +215,27 @@ } /** - * Compute the time when the interrupt has to be triggered and schedule it. - * - * If there is no event in the queue or the next event to execute is in more + * Compute the time when the interrupt has to be triggered and schedule it. + * + * If there is no event in the queue or the next event to execute is in more * than ticker.queue.max_delta ticks from now then the ticker irq will be * scheduled in ticker.queue.max_delta ticks. Otherwise the irq will be * scheduled to happen when the running counter reach the timestamp of the * first event in the queue. - * - * @note If there is no event in the queue then the interrupt is scheduled to + * + * @note If there is no event in the queue then the interrupt is scheduled to * in ticker.queue.max_delta. This is necessary to keep track * of the timer overflow. */ static void schedule_interrupt(const ticker_data_t *const ticker) { ticker_event_queue_t *queue = ticker->queue; + if (ticker->queue->dispatching) { + // Don't schedule the next interrupt until dispatching is + // finished. This prevents repeated calls to interface->set_interrupt + return; + } + update_present_time(ticker); if (ticker->queue->head) { @@ -259,7 +266,7 @@ } } else { uint32_t match_tick = - (queue->tick_last_read + queue->max_delta) & queue->bitmask; + (queue->tick_last_read + queue->max_delta) & queue->bitmask; ticker->interface->set_interrupt(match_tick); } } @@ -280,15 +287,16 @@ ticker->interface->clear_interrupt(); /* Go through all the pending TimerEvents */ + ticker->queue->dispatching = true; while (1) { if (ticker->queue->head == NULL) { break; } - // update the current timestamp used by the queue + // update the current timestamp used by the queue update_present_time(ticker); - if (ticker->queue->head->timestamp <= ticker->queue->present_time) { + if (ticker->queue->head->timestamp <= ticker->queue->present_time) { // This event was in the past: // point to the following one and execute its handler ticker_event_t *p = ticker->queue->head; @@ -300,8 +308,9 @@ * event handler may have altered the chain of pending events. */ } else { break; - } + } } + ticker->queue->dispatching = false; schedule_interrupt(ticker); @@ -315,13 +324,13 @@ // update the current timestamp update_present_time(ticker); us_timestamp_t absolute_timestamp = convert_timestamp( - ticker->queue->present_time, - timestamp - ); + ticker->queue->present_time, + timestamp + ); // defer to ticker_insert_event_us ticker_insert_event_us( - ticker, + ticker, obj, absolute_timestamp, id ); @@ -352,7 +361,7 @@ prev = p; p = p->next; } - + /* if we're at the end p will be NULL, which is correct */ obj->next = p; @@ -378,7 +387,7 @@ schedule_interrupt(ticker); } else { // find the object before me, then drop me - ticker_event_t* p = ticker->queue->head; + ticker_event_t *p = ticker->queue->head; while (p != NULL) { if (p->next == obj) { p->next = obj->next;