Skip to content

Commit b9b5f0b

Browse files
committed
STM32 16bits ticker: rework us_ticker_read()
Move to a single more reliable implementation of us_ticker_read() There were historically 2 versions of us_ticker_read() implementation. The one removed here was not reliable because us_ticker_read() can be called in interrupt context which means that TIM_MST->CNT would have wrapped around while SlaveCounter is not yet updated. So there is a need to check the TIM_FLAG_UPDATE inside this function, which was not done in the implementation that is removed here.
1 parent 40042f0 commit b9b5f0b

File tree

2 files changed

+13
-19
lines changed

2 files changed

+13
-19
lines changed

targets/TARGET_STM/hal_tick_16b.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ extern TIM_HandleTypeDef TimMasterHandle;
2525
extern volatile uint32_t SlaveCounter;
2626
extern volatile uint32_t oc_int_part;
2727
extern volatile uint16_t oc_rem_part;
28-
extern volatile uint8_t tim_it_update;
29-
extern volatile uint32_t tim_it_counter;
3028

3129
volatile uint32_t PreviousVal = 0;
3230

@@ -47,8 +45,6 @@ void timer_irq_handler(void)
4745
if (__HAL_TIM_GET_IT_SOURCE(&TimMasterHandle, TIM_IT_UPDATE) == SET) {
4846
__HAL_TIM_CLEAR_IT(&TimMasterHandle, TIM_IT_UPDATE);
4947
SlaveCounter++;
50-
tim_it_counter = cnt_val + (uint32_t)(SlaveCounter << 16);
51-
tim_it_update = 1;
5248
}
5349
}
5450

targets/TARGET_STM/us_ticker_16b.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ TIM_HandleTypeDef TimMasterHandle;
2626
volatile uint32_t SlaveCounter = 0;
2727
volatile uint32_t oc_int_part = 0;
2828
volatile uint16_t oc_rem_part = 0;
29-
volatile uint8_t tim_it_update; // TIM_IT_UPDATE event flag set in timer_irq_handler()
30-
volatile uint32_t tim_it_counter = 0; // Time stamp to be updated by timer_irq_handler()
3129

3230
static int us_ticker_inited = 0;
3331

@@ -52,22 +50,32 @@ void us_ticker_init(void)
5250

5351
uint32_t us_ticker_read()
5452
{
55-
uint32_t counter;
56-
5753
TimMasterHandle.Instance = TIM_MST;
5854

5955
if (!us_ticker_inited) us_ticker_init();
6056

61-
#if defined(TARGET_STM32L0)
6257
uint16_t cntH_old, cntH, cntL;
6358
do {
59+
#if defined(TARGET_STM32L0)
6460
// For some reason on L0xx series we need to read and clear the
6561
// overflow flag which give extra time to propelry handle possible
6662
// hiccup after ~60s
6763
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_CC1OF) == SET) {
6864
__HAL_TIM_CLEAR_FLAG(&TimMasterHandle, TIM_FLAG_CC1OF);
6965
}
66+
#endif
7067
cntH_old = SlaveCounter;
68+
/* SlaveCounter needs to be checked before AND after we read the
69+
* current counter TIM_MST->CNT, in case it wraps around.
70+
* there are 2 possible cases of wrap around
71+
* 1) in case this function is interrupted by timer_irq_handler and
72+
* the SlaveCounter is updated. In that case we will loop again.
73+
* 2) in case this function is called from context interrupt during
74+
* wrap-around condtion. That would prevent/delay the timer_irq_handler
75+
* to be called so we need to locally check the FLAG_UPDATE and
76+
* update the cntH accordingly. The SlaveCounter variable itself will
77+
* be updated in the interrupt handler just after ...
78+
*/
7179
if (__HAL_TIM_GET_FLAG(&TimMasterHandle, TIM_FLAG_UPDATE) == SET) {
7280
cntH_old += 1;
7381
}
@@ -79,16 +87,6 @@ uint32_t us_ticker_read()
7987
} while(cntH_old != cntH);
8088
// Glue the upper and lower part together to get a 32 bit timer
8189
return (uint32_t)(cntH << 16 | cntL);
82-
#else
83-
tim_it_update = 0; // Clear TIM_IT_UPDATE event flag
84-
counter = TIM_MST->CNT + (uint32_t)(SlaveCounter << 16); // Calculate new time stamp
85-
if (tim_it_update == 1) {
86-
return tim_it_counter; // In case of TIM_IT_UPDATE return the time stamp that was calculated in timer_irq_handler()
87-
}
88-
else {
89-
return counter; // Otherwise return the time stamp calculated here
90-
}
91-
#endif
9290
}
9391

9492
void us_ticker_set_interrupt(timestamp_t timestamp)

0 commit comments

Comments
 (0)