drivers: timer: stm32_lptim: fix sys_clock_* return value
This commit finish to fix the bug describe by 85e2a0679a68f02f7ef. With the previous correction, the uptime read could be in the past: if the counter rewinds just after testing ARRM flag, we had lost some counts. Signed-off-by: Julien D'Ascenzio <julien.dascenzio@paratronic.fr>
This commit is contained in:
parent
25279df662
commit
704ca8f1b4
1 changed files with 31 additions and 26 deletions
|
@ -86,6 +86,11 @@ static struct k_spinlock lock;
|
|||
#endif
|
||||
#endif /* !CONFIG_STM32_LPTIM_TICK_FREQ_RATIO_OVERRIDE */
|
||||
|
||||
static inline bool arrm_state_get(void)
|
||||
{
|
||||
return (LL_LPTIM_IsActiveFlag_ARRM(LPTIM) && LL_LPTIM_IsEnabledIT_ARRM(LPTIM));
|
||||
}
|
||||
|
||||
static void lptim_irq_handler(const struct device *unused)
|
||||
{
|
||||
|
||||
|
@ -105,9 +110,7 @@ static void lptim_irq_handler(const struct device *unused)
|
|||
}
|
||||
}
|
||||
|
||||
if ((LL_LPTIM_IsActiveFlag_ARRM(LPTIM) != 0)
|
||||
&& LL_LPTIM_IsEnabledIT_ARRM(LPTIM) != 0) {
|
||||
|
||||
if (arrm_state_get()) {
|
||||
k_spinlock_key_t key = k_spin_lock(&lock);
|
||||
|
||||
/* do not change ARR yet, sys_clock_announce will do */
|
||||
|
@ -238,6 +241,29 @@ void sys_clock_set_timeout(int32_t ticks, bool idle)
|
|||
k_spin_unlock(&lock, key);
|
||||
}
|
||||
|
||||
static uint32_t sys_clock_lp_time_get(void)
|
||||
{
|
||||
uint32_t lp_time;
|
||||
|
||||
do {
|
||||
/* In case of counter roll-over, add the autoreload value,
|
||||
* because the irq has not yet been handled
|
||||
*/
|
||||
if (arrm_state_get()) {
|
||||
lp_time = LL_LPTIM_GetAutoReload(LPTIM) + 1;
|
||||
lp_time += z_clock_lptim_getcounter();
|
||||
break;
|
||||
}
|
||||
|
||||
lp_time = z_clock_lptim_getcounter();
|
||||
|
||||
/* Check if the flag ARRM wasn't be set during the process */
|
||||
} while (arrm_state_get());
|
||||
|
||||
return lp_time;
|
||||
}
|
||||
|
||||
|
||||
uint32_t sys_clock_elapsed(void)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
|
||||
|
@ -246,20 +272,7 @@ uint32_t sys_clock_elapsed(void)
|
|||
|
||||
k_spinlock_key_t key = k_spin_lock(&lock);
|
||||
|
||||
uint32_t lp_time = 0;
|
||||
|
||||
/* In case of counter roll-over, add the autoreload value,
|
||||
* even if the irq has not yet been handled.
|
||||
* Check ARRM flag before loading counter to make
|
||||
* sure we don't use a counter close to ARR that
|
||||
* hasn't triggered ARRM yet, which would mistakenly
|
||||
* account for double the number of ticks.
|
||||
*/
|
||||
if ((LL_LPTIM_IsActiveFlag_ARRM(LPTIM) != 0)
|
||||
&& LL_LPTIM_IsEnabledIT_ARRM(LPTIM) != 0) {
|
||||
lp_time += LL_LPTIM_GetAutoReload(LPTIM) + 1;
|
||||
}
|
||||
lp_time += z_clock_lptim_getcounter();
|
||||
uint32_t lp_time = sys_clock_lp_time_get();
|
||||
|
||||
k_spin_unlock(&lock, key);
|
||||
|
||||
|
@ -277,15 +290,7 @@ uint32_t sys_clock_cycle_get_32(void)
|
|||
|
||||
k_spinlock_key_t key = k_spin_lock(&lock);
|
||||
|
||||
uint32_t lp_time = z_clock_lptim_getcounter();
|
||||
|
||||
/* In case of counter roll-over, add this value,
|
||||
* even if the irq has not yet been handled
|
||||
*/
|
||||
if ((LL_LPTIM_IsActiveFlag_ARRM(LPTIM) != 0)
|
||||
&& LL_LPTIM_IsEnabledIT_ARRM(LPTIM) != 0) {
|
||||
lp_time += LL_LPTIM_GetAutoReload(LPTIM) + 1;
|
||||
}
|
||||
uint32_t lp_time = sys_clock_lp_time_get();
|
||||
|
||||
lp_time += accumulated_lptim_cnt;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue