33
33
34
34
#include <stddef.h>
35
35
#include "mbed_error.h"
36
+ #include "mbed_critical.h"
36
37
#include "us_ticker_api.h"
37
38
#include "PeripheralNames.h"
38
39
#include "tmr.h"
40
+ #include "assert.h"
39
41
40
42
#define US_TIMER MXC_TMR0
41
43
#define US_TIMER_IRQn TMR0_0_IRQn
@@ -49,7 +51,7 @@ static volatile uint64_t event_cnt; // Holds the value of the next event
49
51
#define MAX_TICK_VAL ((uint64_t)0xFFFFFFFF * ticks_per_us)
50
52
51
53
//******************************************************************************
52
- static inline void inc_current_cnt (uint32_t inc )
54
+ static inline void inc_current_cnt_no_crit (uint32_t inc )
53
55
{
54
56
// Overflow the ticker when the us ticker overflows
55
57
current_cnt += inc ;
@@ -58,6 +60,14 @@ static inline void inc_current_cnt(uint32_t inc)
58
60
}
59
61
}
60
62
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
+
61
71
//******************************************************************************
62
72
static inline int event_passed (uint64_t current , uint64_t event )
63
73
{
@@ -89,11 +99,12 @@ static void tmr_handler(void)
89
99
{
90
100
uint32_t cmp = TMR32_GetCompare (US_TIMER );
91
101
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
+ }
92
105
TMR32_ClearFlag (US_TIMER );
93
106
NVIC_ClearPendingIRQ (US_TIMER_IRQn );
94
107
95
- inc_current_cnt (cmp );
96
-
97
108
if (event_passed (current_cnt + TMR32_GetCount (US_TIMER ), event_cnt )) {
98
109
// the timestamp has expired
99
110
event_cnt = 0xFFFFFFFFFFFFFFFFULL ; // reset to max value
@@ -162,6 +173,7 @@ uint32_t us_ticker_read(void)
162
173
uint64_t current_cnt1 , current_cnt2 ;
163
174
uint32_t cmp , cnt ;
164
175
uint32_t flag1 , flag2 ;
176
+ static uint32_t last = 0 ;
165
177
166
178
if (!us_ticker_inited ) {
167
179
us_ticker_init ();
@@ -179,12 +191,19 @@ uint32_t us_ticker_read(void)
179
191
180
192
// Account for an unserviced interrupt
181
193
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
+
182
199
current_cnt1 += cmp ;
183
200
}
184
201
185
202
current_cnt1 += cnt ;
186
203
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 ;
188
207
}
189
208
190
209
//******************************************************************************
@@ -228,6 +247,7 @@ void us_ticker_set_interrupt(timestamp_t timestamp)
228
247
TMR32_Start (US_TIMER );
229
248
}
230
249
250
+ //******************************************************************************
231
251
void us_ticker_fire_interrupt (void )
232
252
{
233
253
NVIC_SetPendingIRQ (US_TIMER_IRQn );
0 commit comments