@@ -33,6 +33,7 @@ void us_ticker_init(void) {
33
33
34
34
// Time base configuration
35
35
// TIM1 is used as "master", "TIM4" as "slave". TIM4 is clocked by TIM1.
36
+ TIM_TimeBaseStructInit (& TIM_TimeBaseStructure );
36
37
TIM_TimeBaseStructure .TIM_Period = 0xFFFF ;
37
38
TIM_TimeBaseStructure .TIM_Prescaler = (uint16_t )(SystemCoreClock / 1000000 ) - 1 ; // 1 µs tick
38
39
TIM_TimeBaseStructure .TIM_ClockDivision = 0 ;
@@ -42,6 +43,7 @@ void us_ticker_init(void) {
42
43
TIM_TimeBaseInit (TIM4 , & TIM_TimeBaseStructure );
43
44
44
45
// Master timer configuration
46
+ TIM_OCStructInit (& TIM_OCInitStructure );
45
47
TIM_OCInitStructure .TIM_OCMode = TIM_OCMode_Toggle ;
46
48
TIM_OCInitStructure .TIM_OutputState = TIM_OutputState_Enable ;
47
49
TIM_OCInitStructure .TIM_Pulse = 0 ;
@@ -51,7 +53,7 @@ void us_ticker_init(void) {
51
53
TIM_SelectOutputTrigger (TIM1 , TIM_TRGOSource_Update );
52
54
53
55
// Slave timer configuration
54
- TIM_SelectSlaveMode (TIM4 , TIM_SlaveMode_Gated );
56
+ TIM_SelectSlaveMode (TIM4 , TIM_SlaveMode_External1 );
55
57
TIM_SelectInputTrigger (TIM4 , TIM_TS_ITR0 );
56
58
57
59
// Enable timers
@@ -60,10 +62,21 @@ void us_ticker_init(void) {
60
62
}
61
63
62
64
uint32_t us_ticker_read () {
63
- uint32_t counter ;
65
+ uint32_t counter , counter2 ;
64
66
if (!us_ticker_inited ) us_ticker_init ();
65
- counter = (uint32_t )((uint32_t )TIM_GetCounter (TIM4 ) << 16 ) + (uint32_t )TIM_GetCounter (TIM1 );
66
- return counter ;
67
+ // A situation might appear when TIM1 overflows right after TIM4 is read and before the
68
+ // new (overflowed) value of TIM1 is read, which would make the code below consider the
69
+ // previous (incorrect) value of TIM4 and the new value of TIM1, which would return a
70
+ // value in the past. Avoid this by computing consecutive values of the timer until they
71
+ // are properly ordered.
72
+ counter = counter2 = (uint32_t )((uint32_t )TIM_GetCounter (TIM4 ) << 16 ) + (uint32_t )TIM_GetCounter (TIM1 );
73
+ while (1 ) {
74
+ counter2 = (uint32_t )((uint32_t )TIM_GetCounter (TIM4 ) << 16 ) + (uint32_t )TIM_GetCounter (TIM1 );
75
+ if (counter2 > counter )
76
+ break ;
77
+ counter = counter2 ;
78
+ }
79
+ return counter2 ;
67
80
}
68
81
69
82
void us_ticker_set_interrupt (unsigned int timestamp ) {
0 commit comments