STM32: Fix 32-bit us ticker interrupt scheduling

For STM32 targets using a 32-bit timer for the microsecond ticker, the
driver did not properly handle timestamps that are in the past.  It
would just blindly set the compare register to the requested timestamp,
resulting in the interrupt being serviced up to 4295 seconds late
(i.e. after the 32-bit timer counts all the way around to hit the
timestamp again).

This problem can easily be reproduced by creating a Timeout object
then calling the timeout's attach_us() member function to attach a
callback with a timeout of 0 us.  The callback will not get called for
over 2147 seconds, and possibly up to 4295 seconds late if no other
microsecond ticker events are getting scheduled in the meantime.

Now, after the compare register has been set, the timestamp is checked
against the current time to see if the timestamp is in the past, and
if so, the compare event is manually set.

NOTE: By checking if the timestamp is in the past after configuring the
capture register, we ensure proper handling in the case where the timer
updates past the timestamp while setting the capture register.
pull/4417/head
Bradley Scott 2017-05-31 16:46:14 -04:00
parent 944a17fe3c
commit 260378e774
49 changed files with 52 additions and 0 deletions

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f0xx.h"
#include "stm32f0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM1

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f0xx.h"
#include "stm32f0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM1

View File

@ -40,6 +40,7 @@ extern "C" {
#endif
#include "stm32f0xx.h"
#include "stm32f0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@ extern "C" {
#endif
#include "stm32f0xx.h"
#include "stm32f0xx_ll_tim.h":
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f0xx.h"
#include "stm32f0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM1

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f0xx.h"
#include "stm32f0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f0xx.h"
#include "stm32f0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f1xx.h"
#include "stm32f1xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM4

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f1xx.h"
#include "stm32f1xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM4

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f1xx.h"
#include "stm32f1xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM4

View File

@ -40,6 +40,7 @@ extern "C" {
#endif
#include "stm32f2xx.h"
#include "stm32f2xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f3xx.h"
#include "stm32f3xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f3xx.h"
#include "stm32f3xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f3xx.h"
#include "stm32f3xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f3xx.h"
#include "stm32f3xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f3xx.h"
#include "stm32f3xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f4xx.h"
#include "stm32f4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f7xx.h"
#include "stm32f7xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f7xx.h"
#include "stm32f7xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f7xx.h"
#include "stm32f7xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32f7xx.h"
#include "stm32f7xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l0xx.h"
#include "stm32l0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM21

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l0xx.h"
#include "stm32l0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM21

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l0xx.h"
#include "stm32l0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM21

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l0xx.h"
#include "stm32l0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM21

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l0xx.h"
#include "stm32l0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM21

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l0xx.h"
#include "stm32l0xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM21

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l1xx.h"
#include "stm32l1xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l1xx.h"
#include "stm32l1xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l1xx.h"
#include "stm32l1xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l1xx.h"
#include "stm32l1xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l4xx.h"
#include "stm32l4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM2

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l4xx.h"
#include "stm32l4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -40,6 +40,7 @@
#endif
#include "stm32l4xx.h"
#include "stm32l4xx_ll_tim.h"
#include "cmsis_nvic.h"
#define TIM_MST TIM5

View File

@ -48,6 +48,10 @@ void us_ticker_set_interrupt(timestamp_t timestamp)
__HAL_TIM_SET_COMPARE(&TimMasterHandle, TIM_CHANNEL_1, (uint32_t)timestamp);
// Enable IT
__HAL_TIM_ENABLE_IT(&TimMasterHandle, TIM_IT_CC1);
// Check if timestamp has already passed, and if so, set the event immediately
if ((int32_t)(timestamp - TIM_MST->CNT) <= 0) {
LL_TIM_GenerateEvent_CC1(TimMasterHandle.Instance);
}
}
void us_ticker_disable_interrupt(void)