Lancaster University's (short term!) clone of mbed-src for micro:bit. This is a copy of the github branch https://github.com/lancaster-university/mbed-classic

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

Comitter:
LancasterUniversity
Date:
Wed Jul 13 12:52:54 2016 +0100
Parent:
640:0bc7942c2877
Commit message:
Synchronized with git rev 1fb8ab4c
Author: James Devine
mbed-classic: BUGFIX for timer when using wait_ms from interrupt context

Previously if a user used wait[_ms,_us] in interrupt context the device would
hang indefinitely. This was due to incrementing overflowCount from
interrupt context only.

This meant that if a user used wait[_ms,_us] in an ISR with
the same or greater interrupt priority, it would result in an infinite
loop as the overflowCount variable would never be incremented, and
wait[_ms,_us] would never return.

This patch simply applies a better solution for the race condition
mentioned in the previous commit. It instead disables the timer1
interrupt and increments the overflowCount variable, preventing
the race condition whilst supporting wait[_ms,_us] in interrupt
context.

Changed in this revision

targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c	Fri Apr 08 01:06:01 2016 +0100
+++ b/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c	Wed Jul 13 12:52:54 2016 +0100
@@ -141,14 +141,19 @@
  */
 static inline uint64_t tmr1_getCounter64(void)
 {
-    int o = 0;
-
     NRF_TIMER1->TASKS_CAPTURE[2] = 1;
 
-    if (NRF_TIMER1->EVENTS_COMPARE[3]) 
-        o++;
+    NVIC_DisableIRQ(TIMER1_IRQn);
 
-    return (((uint64_t)(overflowCount+o)) << 16) | (NRF_TIMER1->CC[2] & MAX_TMR1_COUNTER_VAL);
+    if (NRF_TIMER1->EVENTS_COMPARE[3])
+    {
+        NRF_TIMER1->EVENTS_COMPARE[3] = 0;
+        overflowCount++;
+    }
+
+    NVIC_EnableIRQ(TIMER1_IRQn);
+
+    return (((uint64_t)(overflowCount)) << 16) | (NRF_TIMER1->CC[2] & MAX_TMR1_COUNTER_VAL);
 }
 
 /**