21
21
#include "nu_miscutil.h"
22
22
#include "critical.h"
23
23
24
+ // us_ticker tick = us = timestamp
24
25
#define US_PER_TICK 1
26
+ #define US_PER_SEC (1000 * 1000)
25
27
26
- // NOTE: mbed-drivers-test-timeout test requires 100 us timer granularity.
27
- // NOTE: us_ticker will alarm the system for its counting, so make the counting period as long as possible for better power saving.
28
- #define US_PER_TMR0HIRES_INT (1000 * 1000 * 10)
29
- #define TMR0HIRES_FIRE_FREQ (1000 * 1000 / US_PER_TMR0HIRES_INT)
30
- #define US_PER_TMR0HIRES_CLK 1
31
- #define TMR0HIRES_CLK_FREQ (1000 * 1000 / US_PER_TMR0HIRES_CLK)
28
+ #define TMR0HIRES_CLK_PER_SEC (1000 * 1000)
29
+ #define TMR1HIRES_CLK_PER_SEC (1000 * 1000)
30
+ #define TMR1LORES_CLK_PER_SEC (__LIRC)
31
+
32
+ #define US_PER_TMR0HIRES_CLK (US_PER_SEC / TMR0HIRES_CLK_PER_SEC)
33
+ #define US_PER_TMR1HIRES_CLK (US_PER_SEC / TMR1HIRES_CLK_PER_SEC)
34
+ #define US_PER_TMR1LORES_CLK (US_PER_SEC / TMR1LORES_CLK_PER_SEC)
35
+
36
+ #define US_PER_TMR0HIRES_INT (1000 * 1000 * 10)
37
+ #define TMR0HIRES_CLK_PER_TMR0HIRES_INT ((uint32_t) ((uint64_t) US_PER_TMR0HIRES_INT * TMR0HIRES_CLK_PER_SEC / US_PER_SEC))
32
38
33
- #define US_PER_TMR1LORES_CLK 100
34
- #define TMR1LORES_CLK_FREQ (1000 * 1000 / US_PER_TMR1LORES_CLK)
35
- #define US_PER_TMR1HIRES_CLK 1
36
- #define TMR1HIRES_CLK_FREQ (1000 * 1000 / US_PER_TMR1HIRES_CLK)
37
39
38
40
// Determine to use lo-res/hi-res timer according to CD period
39
- #define CD_TMR_SEP_US 1000
41
+ #define US_TMR_SEP_CD 1000
40
42
41
43
static void tmr0_vec (void );
42
44
static void tmr1_vec (void );
@@ -88,9 +90,10 @@ void us_ticker_init(void)
88
90
89
91
// Timer for normal counter
90
92
uint32_t clk_timer0 = TIMER_GetModuleClock ((TIMER_T * ) NU_MODBASE (timer0hires_modinit .modname ));
91
- uint32_t prescale_timer0 = clk_timer0 / TMR0HIRES_CLK_FREQ - 1 ;
93
+ uint32_t prescale_timer0 = clk_timer0 / TMR0HIRES_CLK_PER_SEC - 1 ;
92
94
MBED_ASSERT ((prescale_timer0 != (uint32_t ) -1 ) && prescale_timer0 <= 127 );
93
- uint32_t cmp_timer0 = US_PER_TMR0HIRES_INT / US_PER_TMR0HIRES_CLK ;
95
+ MBED_ASSERT ((clk_timer0 % TMR0HIRES_CLK_PER_SEC ) == 0 );
96
+ uint32_t cmp_timer0 = TMR0HIRES_CLK_PER_TMR0HIRES_INT ;
94
97
MBED_ASSERT (cmp_timer0 >= TMR_CMP_MIN && cmp_timer0 <= TMR_CMP_MAX );
95
98
// NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451. In M451, TIMER_CNT is updated continuously by default.
96
99
((TIMER_T * ) NU_MODBASE (timer0hires_modinit .modname ))-> CTL = TIMER_PERIODIC_MODE | prescale_timer0 /* | TIMER_CTL_CNTDATEN_Msk*/ ;
@@ -229,22 +232,22 @@ static void tmr1_vec(void)
229
232
static void us_ticker_arm_cd (void )
230
233
{
231
234
TIMER_T * timer1_base = (TIMER_T * ) NU_MODBASE (timer1lores_modinit .modname );
232
- uint32_t tmr1_clk_freq ;
235
+ uint32_t tmr1_clk_per_sec ;
233
236
uint32_t us_per_tmr1_clk ;
234
237
235
238
/**
236
- * Reserve CD_TMR_SEP_US -plus alarm period for hi-res timer
237
- * 1. period >= CD_TMR_SEP_US * 2. Divide into two rounds:
238
- * CD_TMR_SEP_US * n (lo-res timer)
239
- * CD_TMR_SEP_US + period % CD_TMR_SEP_US (hi-res timer)
240
- * 2. period < CD_TMR_SEP_US * 2. Just one round:
239
+ * Reserve US_TMR_SEP_CD -plus alarm period for hi-res timer
240
+ * 1. period >= US_TMR_SEP_CD * 2. Divide into two rounds:
241
+ * US_TMR_SEP_CD * n (lo-res timer)
242
+ * US_TMR_SEP_CD + period % US_TMR_SEP_CD (hi-res timer)
243
+ * 2. period < US_TMR_SEP_CD * 2. Just one round:
241
244
* period (hi-res timer)
242
245
*/
243
- if (cd_major_minor_us >= CD_TMR_SEP_US * 2 ) {
244
- cd_minor_us = cd_major_minor_us - cd_major_minor_us % CD_TMR_SEP_US - CD_TMR_SEP_US ;
246
+ if (cd_major_minor_us >= US_TMR_SEP_CD * 2 ) {
247
+ cd_minor_us = cd_major_minor_us - cd_major_minor_us % US_TMR_SEP_CD - US_TMR_SEP_CD ;
245
248
246
249
CLK_SetModuleClock (timer1lores_modinit .clkidx , timer1lores_modinit .clksrc , timer1lores_modinit .clkdiv );
247
- tmr1_clk_freq = TMR1LORES_CLK_FREQ ;
250
+ tmr1_clk_per_sec = TMR1LORES_CLK_PER_SEC ;
248
251
us_per_tmr1_clk = US_PER_TMR1LORES_CLK ;
249
252
250
253
cd_hires_tmr_armed = 0 ;
@@ -253,7 +256,7 @@ static void us_ticker_arm_cd(void)
253
256
cd_minor_us = cd_major_minor_us ;
254
257
255
258
CLK_SetModuleClock (timer1hires_modinit .clkidx , timer1hires_modinit .clksrc , timer1hires_modinit .clkdiv );
256
- tmr1_clk_freq = TMR1HIRES_CLK_FREQ ;
259
+ tmr1_clk_per_sec = TMR1HIRES_CLK_PER_SEC ;
257
260
us_per_tmr1_clk = US_PER_TMR1HIRES_CLK ;
258
261
259
262
cd_hires_tmr_armed = 1 ;
@@ -263,14 +266,16 @@ static void us_ticker_arm_cd(void)
263
266
timer1_base -> CTL |= TIMER_CTL_RSTCNT_Msk ;
264
267
// One-shot mode, Clock = 1 MHz
265
268
uint32_t clk_timer1 = TIMER_GetModuleClock ((TIMER_T * ) NU_MODBASE (timer1lores_modinit .modname ));
266
- uint32_t prescale_timer1 = clk_timer1 / tmr1_clk_freq - 1 ;
269
+ uint32_t prescale_timer1 = clk_timer1 / tmr1_clk_per_sec - 1 ;
267
270
MBED_ASSERT ((prescale_timer1 != (uint32_t ) -1 ) && prescale_timer1 <= 127 );
271
+ MBED_ASSERT ((clk_timer1 % tmr1_clk_per_sec ) == 0 );
268
272
// NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451. In M451, TIMER_CNT is updated continuously by default.
269
273
timer1_base -> CTL &= ~(TIMER_CTL_OPMODE_Msk | TIMER_CTL_PSC_Msk /* | TIMER_CTL_CNTDATEN_Msk*/ );
270
274
timer1_base -> CTL |= TIMER_ONESHOT_MODE | prescale_timer1 /* | TIMER_CTL_CNTDATEN_Msk*/ ;
271
275
272
- cd_minor_us = NU_CLAMP (cd_minor_us , TMR_CMP_MIN * us_per_tmr1_clk , TMR_CMP_MAX * us_per_tmr1_clk );
273
- timer1_base -> CMP = cd_minor_us / us_per_tmr1_clk ;
276
+ uint32_t cmp_timer1 = cd_minor_us / us_per_tmr1_clk ;
277
+ cmp_timer1 = NU_CLAMP (cmp_timer1 , TMR_CMP_MIN , TMR_CMP_MAX );
278
+ timer1_base -> CMP = cmp_timer1 ;
274
279
275
280
TIMER_EnableInt (timer1_base );
276
281
TIMER_Start (timer1_base );
0 commit comments