mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Revision:
187:0387e8f68319
Parent:
186:707f6e361f3e
Child:
188:bcfe06ba3d64
--- 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;