mbed library sources. Supersedes mbed-src.

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

Revision:
169:e3b6fe271b81
Parent:
167:e84263d55307
Child:
174:b96e65c34a4d
--- a/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c	Thu Jul 06 15:42:05 2017 +0100
+++ b/targets/TARGET_ONSEMI/TARGET_NCS36510/ncs36510_us_ticker_api.c	Wed Jul 19 17:31:21 2017 +0100
@@ -38,7 +38,7 @@
 static void us_timer_init(void);
 
 static uint32_t us_ticker_target = 0;
-static volatile uint32_t msb_counter = 0;
+static volatile uint16_t msb_counter = 0;
 
 void us_ticker_init(void)
 {
@@ -55,7 +55,6 @@
  * which is why a software timer is required to get 32-bit word length.
  ******************************************************************************/
 /* TODO - Need some sort of load value/prescale calculation for non-32MHz clock */
-/* TODO - Add msb_counter rollover protection at 16 bits count? */
 /* TODO - How is overflow handled? */
 
 /* Timer 0 for free running time */
@@ -108,22 +107,21 @@
 /* Reads 32 bit timer's current value (16 bit s/w timer | 16 bit h/w timer) */
 uint32_t us_ticker_read()
 {
-    uint32_t retval, tim0cval;
 
     if (!us_ticker_inited) {
         us_timer_init();
     }
 
+    NVIC_DisableIRQ(Tim0_IRQn);
+    uint32_t retval, tim0cval;
     /* Get the current tick from the hw and sw timers */
     tim0cval = TIM0REG->VALUE;         /* read current time */
     retval = (0xFFFF - tim0cval);      /* subtract down count */
 
-    NVIC_DisableIRQ(Tim0_IRQn);
     if (TIM0REG->CONTROL.BITS.INT) {
-        TIM0REG->CLEAR = 0;
-        msb_counter++;
-        tim0cval = TIM0REG->VALUE;    /* read current time again after interrupt */
-        retval = (0xFFFF - tim0cval);
+        us_timer_isr(); /* handle ISR again */
+        NVIC_ClearPendingIRQ(Tim0_IRQn);
+        retval = (0xFFFF - TIM0REG->VALUE);
     }
     retval |= msb_counter << 16;      /* add software bits */
     NVIC_EnableIRQ(Tim0_IRQn);
@@ -168,25 +166,21 @@
     /* Clear IRQ flag */
     TIM1REG->CLEAR = 0;
 
-    int32_t delta = us_ticker_target - us_ticker_read();
-    if (delta <= 0) {
-        TIM1REG->CONTROL.BITS.ENABLE = False;
-        us_ticker_irq_handler();
+    if (us_ticker_target > 0) {
+        --us_ticker_target;
+        ticker_set(0xFFFF);
     } else {
-        // Clamp at max value of timer
-        if (delta > 0xFFFF) {
-            delta = 0xFFFF;
-        }
-
-        ticker_set(delta);
+        us_ticker_irq_handler();
     }
 }
 
 /* Set timer 1 ticker interrupt */
 void us_ticker_set_interrupt(timestamp_t timestamp)
 {
-    us_ticker_target = (uint32_t)timestamp;
-    int32_t delta = us_ticker_target - us_ticker_read();
+    int32_t delta = timestamp - us_ticker_read();
+    // we got 16 bit timer, use upper 16bit as a simple counter how many times
+    // we need to schedule full range ticker count
+    us_ticker_target = (uint32_t)delta >> 16;
 
     if (delta <= 0) {
         /* This event was in the past */
@@ -200,10 +194,6 @@
         return;
     }
 
-    // Clamp at max value of timer
-    if (delta > 0xFFFF) {
-        delta = 0xFFFF;
-    }
-
-    ticker_set(delta);
+    // we set the full reminder of 16 bit, the next ISR will do the upper part
+    ticker_set(delta & 0xFFFF);
 }