3333
3434#include <stddef.h>
3535#include "mbed_error.h"
36+ #include "mbed_critical.h"
3637#include "us_ticker_api.h"
3738#include "PeripheralNames.h"
3839#include "tmr.h"
40+ #include "assert.h"
3941
4042#define US_TIMER MXC_TMR0
4143#define US_TIMER_IRQn TMR0_0_IRQn
@@ -49,7 +51,7 @@ static volatile uint64_t event_cnt; // Holds the value of the next event
4951#define MAX_TICK_VAL ((uint64_t)0xFFFFFFFF * ticks_per_us)
5052
5153//******************************************************************************
52- static inline void inc_current_cnt (uint32_t inc )
54+ static inline void inc_current_cnt_no_crit (uint32_t inc )
5355{
5456 // Overflow the ticker when the us ticker overflows
5557 current_cnt += inc ;
@@ -58,6 +60,14 @@ static inline void inc_current_cnt(uint32_t inc)
5860 }
5961}
6062
63+ //******************************************************************************
64+ static inline void inc_current_cnt (uint32_t inc )
65+ {
66+ core_util_critical_section_enter ();
67+ inc_current_cnt_no_crit (inc );
68+ core_util_critical_section_exit ();
69+ }
70+
6171//******************************************************************************
6272static inline int event_passed (uint64_t current , uint64_t event )
6373{
@@ -89,11 +99,12 @@ static void tmr_handler(void)
8999{
90100 uint32_t cmp = TMR32_GetCompare (US_TIMER );
91101 TMR32_SetCompare (US_TIMER , 0xFFFFFFFF ); // reset to max value to prevent further interrupts
102+ if (TMR32_GetFlag (US_TIMER )) {
103+ inc_current_cnt_no_crit (cmp );
104+ }
92105 TMR32_ClearFlag (US_TIMER );
93106 NVIC_ClearPendingIRQ (US_TIMER_IRQn );
94107
95- inc_current_cnt (cmp );
96-
97108 if (event_passed (current_cnt + TMR32_GetCount (US_TIMER ), event_cnt )) {
98109 // the timestamp has expired
99110 event_cnt = 0xFFFFFFFFFFFFFFFFULL ; // reset to max value
@@ -162,6 +173,7 @@ uint32_t us_ticker_read(void)
162173 uint64_t current_cnt1 , current_cnt2 ;
163174 uint32_t cmp , cnt ;
164175 uint32_t flag1 , flag2 ;
176+ static uint32_t last = 0 ;
165177
166178 if (!us_ticker_inited ) {
167179 us_ticker_init ();
@@ -179,12 +191,19 @@ uint32_t us_ticker_read(void)
179191
180192 // Account for an unserviced interrupt
181193 if (flag1 ) {
194+ // Clear peripheral interrupt flag; leaving NVIC pending set
195+ TMR32_ClearFlag (US_TIMER );
196+ // Advance global count
197+ inc_current_cnt (cmp + cnt );
198+
182199 current_cnt1 += cmp ;
183200 }
184201
185202 current_cnt1 += cnt ;
186203
187- return (current_cnt1 / ticks_per_us );
204+ assert (last <= (current_cnt1 / ticks_per_us ));
205+ last = (current_cnt1 / ticks_per_us );
206+ return last ;
188207}
189208
190209//******************************************************************************
@@ -228,6 +247,7 @@ void us_ticker_set_interrupt(timestamp_t timestamp)
228247 TMR32_Start (US_TIMER );
229248}
230249
250+ //******************************************************************************
231251void us_ticker_fire_interrupt (void )
232252{
233253 TMR32_SetCompare (US_TIMER , 1 );
0 commit comments