api-hal-timebase-timer.h 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #pragma once
  2. #include <stm32wbxx_ll_lptim.h>
  3. #include <stdbool.h>
  4. static inline void assert(bool value) {
  5. if (!value) asm("bkpt 1");
  6. }
  7. // Timer used for system ticks
  8. #define API_HAL_TIMEBASE_TIMER_MAX 0xFFFF
  9. #define API_HAL_TIMEBASE_TIMER_REG_LOAD_DLY 0x1
  10. #define API_HAL_TIMEBASE_TIMER LPTIM2
  11. #define API_HAL_TIMEBASE_TIMER_IRQ LPTIM2_IRQn
  12. #define API_HAL_TIMEBASE_TIMER_CLOCK_INIT() \
  13. { \
  14. LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_LSE); \
  15. LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPTIM2); \
  16. } \
  17. static inline void api_hal_timebase_timer_init() {
  18. API_HAL_TIMEBASE_TIMER_CLOCK_INIT();
  19. LL_LPTIM_Enable(API_HAL_TIMEBASE_TIMER);
  20. while(!LL_LPTIM_IsEnabled(API_HAL_TIMEBASE_TIMER)) {}
  21. LL_LPTIM_SetClockSource(API_HAL_TIMEBASE_TIMER, LL_LPTIM_CLK_SOURCE_INTERNAL);
  22. LL_LPTIM_SetPrescaler(API_HAL_TIMEBASE_TIMER, LL_LPTIM_PRESCALER_DIV1);
  23. LL_LPTIM_SetPolarity(API_HAL_TIMEBASE_TIMER, LL_LPTIM_OUTPUT_POLARITY_REGULAR);
  24. LL_LPTIM_SetUpdateMode(API_HAL_TIMEBASE_TIMER, LL_LPTIM_UPDATE_MODE_IMMEDIATE);
  25. LL_LPTIM_SetCounterMode(API_HAL_TIMEBASE_TIMER, LL_LPTIM_COUNTER_MODE_INTERNAL);
  26. LL_LPTIM_TrigSw(API_HAL_TIMEBASE_TIMER);
  27. LL_LPTIM_SetInput1Src(API_HAL_TIMEBASE_TIMER, LL_LPTIM_INPUT1_SRC_GPIO);
  28. LL_LPTIM_SetInput2Src(API_HAL_TIMEBASE_TIMER, LL_LPTIM_INPUT2_SRC_GPIO);
  29. NVIC_SetPriority(API_HAL_TIMEBASE_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
  30. NVIC_EnableIRQ(API_HAL_TIMEBASE_TIMER_IRQ);
  31. }
  32. static inline uint32_t api_hal_timebase_timer_get_cnt() {
  33. uint32_t counter = LL_LPTIM_GetCounter(API_HAL_TIMEBASE_TIMER);
  34. uint32_t counter_shadow = LL_LPTIM_GetCounter(API_HAL_TIMEBASE_TIMER);
  35. while(counter != counter_shadow) {
  36. counter = counter_shadow;
  37. counter_shadow = LL_LPTIM_GetCounter(API_HAL_TIMEBASE_TIMER);
  38. }
  39. return counter;
  40. }
  41. static inline bool api_hal_timebase_timer_arr_is_ok() {
  42. return LL_LPTIM_IsActiveFlag_ARROK(API_HAL_TIMEBASE_TIMER);
  43. }
  44. static inline uint32_t api_hal_timebase_timer_get_arr() {
  45. return LL_LPTIM_GetAutoReload(API_HAL_TIMEBASE_TIMER);;
  46. }
  47. static inline void api_hal_timebase_timer_set_arr(uint32_t value) {
  48. value &= API_HAL_TIMEBASE_TIMER_MAX;
  49. if (value != api_hal_timebase_timer_get_arr()) {
  50. assert(api_hal_timebase_timer_arr_is_ok());
  51. LL_LPTIM_ClearFlag_ARROK(API_HAL_TIMEBASE_TIMER);
  52. LL_LPTIM_SetAutoReload(API_HAL_TIMEBASE_TIMER, value);
  53. }
  54. }
  55. static inline bool api_hal_timebase_timer_cmp_is_ok() {
  56. return LL_LPTIM_IsActiveFlag_CMPOK(API_HAL_TIMEBASE_TIMER);
  57. }
  58. static inline uint32_t api_hal_timebase_timer_get_cmp() {
  59. return LL_LPTIM_GetCompare(API_HAL_TIMEBASE_TIMER);
  60. }
  61. static inline void api_hal_timebase_timer_set_cmp(uint32_t value) {
  62. value &= API_HAL_TIMEBASE_TIMER_MAX;
  63. if (value != api_hal_timebase_timer_get_cmp()) {
  64. assert(api_hal_timebase_timer_cmp_is_ok());
  65. LL_LPTIM_ClearFlag_CMPOK(API_HAL_TIMEBASE_TIMER);
  66. LL_LPTIM_SetCompare(API_HAL_TIMEBASE_TIMER, value);
  67. }
  68. }
  69. static inline bool api_hal_timebase_timer_is_safe() {
  70. uint16_t cmp = api_hal_timebase_timer_get_cmp();
  71. uint16_t cnt = api_hal_timebase_timer_get_cnt();
  72. uint16_t margin = (cmp > cnt) ? cmp - cnt : cnt - cmp;
  73. if (margin < 8) {
  74. return false;
  75. }
  76. if (!api_hal_timebase_timer_cmp_is_ok()) {
  77. return false;
  78. }
  79. return true;
  80. }