Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Stm32Uart.cxx
Go to the documentation of this file.
1
36#include "Stm32Uart.hxx"
37
38#include "freertos/tc_ioctl.h"
39#include "stm32f_hal_conf.hxx"
40
41#include "FreeRTOSConfig.h"
42
43// static
45// static
46uint8_t Stm32Uart::interrupt2_8EnableCnt = 0;
47
53Stm32Uart::Stm32Uart(const char *name, USART_TypeDef *base, IRQn_Type interrupt)
54 : Serial(name)
55 , interrupt(interrupt)
56{
57 memset(&uartHandle, 0, sizeof(uartHandle));
58 uartHandle.Instance = base;
59 HAL_UART_DeInit(&uartHandle);
60
61 HAL_NVIC_DisableIRQ(interrupt);
62#if defined(GCC_ARMCM0)
63 HAL_NVIC_SetPriority(interrupt, 3, 0);
64#elif defined(GCC_ARMCM3)
65 // Below kernel-compatible interrupt priority.
66 SetInterruptPriority(interrupt, configMAX_SYSCALL_INTERRUPT_PRIORITY + 0x20);
67#else
68#error not defined how to set interrupt priority
69#endif
70}
71
75{
76 uartHandle.Init.BaudRate = 115200;
77 uartHandle.Init.WordLength = UART_WORDLENGTH_8B;
78 uartHandle.Init.StopBits = UART_STOPBITS_1;
79 uartHandle.Init.Parity = UART_PARITY_NONE;
80 uartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
81 uartHandle.Init.Mode = UART_MODE_TX_RX;
82 uartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
83
84 volatile auto ret = HAL_UART_Init(&uartHandle);
85 HASSERT(HAL_OK == ret);
86 __HAL_UART_ENABLE_IT(&uartHandle, UART_IT_RXNE);
87 __HAL_UART_ENABLE_IT(&uartHandle, UART_IT_ERR);
88
89 // Verifies shared interrupts.
90 if (false)
91 {
92 }
93#if defined(SHARED_UART3_8_IRQn)
94 else if (interrupt == SHARED_UART3_8_IRQn)
95 {
96 if (interrupt3_to_8EnableCnt++ == 0)
97 {
98 HAL_NVIC_EnableIRQ(interrupt);
99 }
100 }
101#endif
102#if defined(STM32G0B1xx)
103 // This is the only device we support with more than one shared interrupt
104 // line.
105 else if (interrupt == USART2_LPUART2_IRQn)
106 {
107 if (interrupt2_8EnableCnt++ == 0)
108 {
109 HAL_NVIC_EnableIRQ(interrupt);
110 }
111 }
112#endif
113 else
114 {
115 // Individual interrupt.
116 HAL_NVIC_EnableIRQ(interrupt);
117 }
118}
119
123{
124 // Verifies shared interrupts.
125 if (false) { }
126#if defined(SHARED_UART3_8_IRQn)
127 else if (interrupt == SHARED_UART3_8_IRQn)
128 {
129 if (--interrupt3_to_8EnableCnt == 0)
130 {
131 HAL_NVIC_DisableIRQ(interrupt);
132 }
133 }
134#endif
135#if defined(STM32G0B1xx)
136 // This is the only device we support with more than one shared interrupt
137 // lines.
138 else if (interrupt == USART2_LPUART2_IRQn)
139 {
140 if (--interrupt2_8EnableCnt == 0)
141 {
142 HAL_NVIC_DisableIRQ(interrupt);
143 }
144 }
145#endif
146 else
147 {
148 // Individual interrupt.
149 HAL_NVIC_DisableIRQ(interrupt);
150 }
151
152 __HAL_UART_DISABLE_IT(&uartHandle, UART_IT_TXE);
153 __HAL_UART_DISABLE_IT(&uartHandle, UART_IT_ERR);
154 __HAL_UART_DISABLE_IT(&uartHandle, UART_IT_RXNE);
155 HAL_UART_DeInit(&uartHandle);
156}
157
158int Stm32Uart::ioctl(File *file, unsigned long int key, unsigned long data)
159{
160 switch (key)
161 {
162 default:
163 return -EINVAL;
164 case TCBAUDRATE:
165 uartHandle.Init.BaudRate = data;
166 volatile auto ret = HAL_UART_Init(&uartHandle);
167 HASSERT(HAL_OK == ret);
168 break;
169 }
170 return 0;
171}
172
176{
177 if (!__HAL_UART_GET_IT_SOURCE(&uartHandle, UART_IT_TXE))
178 {
179 uint8_t data = 0;
180
181 if (txBuf->get(&data, 1))
182 {
183 uartHandle.Instance->TDR = data;
184 __HAL_UART_ENABLE_IT(&uartHandle, UART_IT_TXE);
186 }
187 }
188}
189
193{
194 if (__HAL_UART_GET_IT(&uartHandle, UART_IT_ORE))
195 {
196 /* overrun error */
197 ++overrunCount;
198 __HAL_UART_CLEAR_IT(&uartHandle, UART_CLEAR_OREF);
199 }
200 if (__HAL_UART_GET_IT(&uartHandle, UART_IT_NE))
201 {
202 /* noise error */
203 __HAL_UART_CLEAR_IT(&uartHandle, UART_CLEAR_NEF);
204 }
205 if (__HAL_UART_GET_IT(&uartHandle, UART_IT_FE))
206 {
207 /* framing error */
208 __HAL_UART_CLEAR_IT(&uartHandle, UART_CLEAR_FEF);
209 }
210 while (__HAL_UART_GET_IT(&uartHandle, UART_IT_RXNE))
211 {
215 uint8_t data = uartHandle.Instance->RDR;
216 if (rxBuf->put(&data, 1) == 0)
217 {
218 ++overrunCount;
219 }
221 }
222 while (__HAL_UART_GET_IT(&uartHandle, UART_IT_TXE) &&
223 __HAL_UART_GET_IT_SOURCE(&uartHandle, UART_IT_TXE))
224 {
228 uint8_t data;
229 if (txBuf->get(&data, 1) != 0)
230 {
231 uartHandle.Instance->TDR = data;
233 }
234 else
235 {
236 /* no more data pending */
237 __HAL_UART_DISABLE_IT(&uartHandle, UART_IT_TXE);
238 break;
239 }
240 }
241}
void signal_condition()
Signal the wakeup condition.
void signal_condition_from_isr()
Signal the wakeup condition from an ISR context.
size_t get(T *buf, size_t items)
remove a number of items from the buffer.
size_t put(const T *buf, size_t items)
Insert a number of items to the buffer.
Private data for a serial device.
Definition Serial.hxx:46
DeviceBuffer< uint8_t > * rxBuf
receive buffer
Definition Serial.hxx:85
DeviceBuffer< uint8_t > * txBuf
transmit buffer
Definition Serial.hxx:84
unsigned int overrunCount
overrun count
Definition Serial.hxx:86
void disable() override
function to disable device
IRQn_Type interrupt
interrupt of this device
void enable() override
function to enable device
Definition Stm32Uart.cxx:74
Stm32Uart()
Default constructor.
static uint8_t interrupt3_to_8EnableCnt
number of times interrupts have been enabled on these UART channels
int ioctl(File *file, unsigned long int key, unsigned long data) override
Request an ioctl transaction.
UART_HandleTypeDef uartHandle
Handle to the UART setup.
void tx_char() override
Try and transmit a message.
void interrupt_handler()
handle an interrupt.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138
File information.
Definition Devtab.hxx:52
#define TCBAUDRATE
Argument is the desired baud rate for the port.
Definition tc_ioctl.h:61