Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Stm32Blinker.hxx
Go to the documentation of this file.
1
34#ifndef _FREERTOS_DRIVERS_ST_STM32BLINKER_HXX_
35#define _FREERTOS_DRIVERS_ST_STM32BLINKER_HXX_
36
37/* How to use:
38
39Add the following code to the hardware.hxx
40```
41 #define BLINKER_INTERRUPT_HANDLER timer14_interrupt_handler
42
43 struct BlinkerHw
44 {
45 static constexpr uint32_t TIMER_BASE = TIM14_BASE;
46 static constexpr auto TIMER_IRQn = TIM14_IRQn;
47 static void clock_enable()
48 {
49 __HAL_RCC_TIM14_CLK_ENABLE();
50 }
51 };
52```
53
54then
55```
56#include "freertos_drivers/st/Stm32Blinker.hxx"
57```
58
59in HwInit.cxx after hardware.hxx was included. Call setup_blinker() in
60hw_preinit.
61*/
62
63#ifndef BLINKER_INTERRUPT_HANDLER
64#error must include hardware.hxx before Stm32Blinker.hxx
65#endif
66
68static inline TIM_TypeDef *get_blinker_timer()
69{
70 return (TIM_TypeDef *)BlinkerHw::TIMER_BASE;
71}
72
73extern "C" {
74
77{
78 BlinkerHw::clock_enable();
79 /* Initializes the blinker timer. */
80 TIM_HandleTypeDef TimHandle;
81 memset(&TimHandle, 0, sizeof(TimHandle));
82 TimHandle.Instance = get_blinker_timer();
83 TimHandle.Init.Period = configCPU_CLOCK_HZ / 10000 / 5;
84 TimHandle.Init.Prescaler = 10000;
85 TimHandle.Init.ClockDivision = 0;
86 TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
87 TimHandle.Init.RepetitionCounter = 0;
88 if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
89 {
90 /* Initialization Error */
91 HASSERT(0);
92 }
93 if (HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
94 {
95 /* Starting Error */
96 HASSERT(0);
97 }
98 NVIC_SetPriority(BlinkerHw::TIMER_IRQn, 0);
99 NVIC_EnableIRQ(BlinkerHw::TIMER_IRQn);
100}
101
103uint32_t blinker_pattern = 0;
105static uint32_t rest_pattern = 0;
106
107extern void hw_set_to_safe(void);
108
109void resetblink(uint32_t pattern)
110{
111 blinker_pattern = pattern;
112 rest_pattern = pattern ? 1 : 0;
113 BLINKER_RAW_Pin::set(pattern ? true : false);
114 /* todo: make a timer event trigger immediately */
115}
116
117void setblink(uint32_t pattern)
118{
119 resetblink(pattern);
120}
121
122void BLINKER_INTERRUPT_HANDLER(void)
123{
124 //
125 // Clear the timer interrupt.
126 //
127 get_blinker_timer()->SR = ~TIM_IT_UPDATE;
128
129 // Set output LED.
130 BLINKER_RAW_Pin::set(rest_pattern & 1);
131
132 // Shift and maybe reset pattern.
133 rest_pattern >>= 1;
134 if (!rest_pattern)
135 {
137 }
138}
139
140void wait_with_blinker(void)
141{
142 if (get_blinker_timer()->SR & TIM_IT_UPDATE)
143 {
144 BLINKER_INTERRUPT_HANDLER();
145 }
146}
147
148void diewith(uint32_t pattern)
149{
150 asm("cpsid i\n");
151 hw_set_to_safe();
152 resetblink(pattern);
153 while (1)
154 {
155 wait_with_blinker();
156 }
157}
158
159} // extern "C"
160
161#endif // _FREERTOS_DRIVERS_ST_STM32BLINKER_HXX_
uint32_t blinker_pattern
Stores the canonical pattern for the blinker.
void diewith(uint32_t pattern)
Sets a blinking pattern and never returns.
static uint32_t rest_pattern
Stores what is left of the pattern during the current period.
void setup_blinker()
Call this function in hw_preinit to set up the blinker timer.
void resetblink(uint32_t pattern)
Changes the blinking pattern.
static TIM_TypeDef * get_blinker_timer()
void setblink(uint32_t pattern)
Initializes the blinker routine with a specific blinking pattern.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138