semf
stm32uart.cpp
Go to the documentation of this file.
1
12
13#if defined(STM32) && defined(HAL_UART_MODULE_ENABLED)
14extern "C" void HAL_UART_TxCpltCallback(UART_HandleTypeDef* huart)
15{
17}
18extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart)
19{
21}
22
23namespace semf
24{
25LinkedQueue<Stm32Uart> Stm32Uart::m_queue;
26Stm32Uart::Stm32Uart(UART_HandleTypeDef& hwHandle)
27: m_hwHandle(&hwHandle)
28{
29 queue()->push(*this);
30}
31
33{
34 SEMF_INFO("init");
35 HAL_StatusTypeDef state = HAL_UART_Init(m_hwHandle);
36 if (state != HAL_OK)
37 {
38 if (state == HAL_ERROR)
39 {
40 SEMF_ERROR("hal error");
41 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::Init_HalError)));
42 }
43 else if (state == HAL_BUSY)
44 {
45 SEMF_ERROR("hal busy");
46 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::Init_HalBusy)));
47 }
48 else if (state == HAL_TIMEOUT)
49 {
50 SEMF_ERROR("hal timeout");
51 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::Init_HalTimeout)));
52 }
53 return;
54 }
55}
56
58{
59 SEMF_INFO("deinit");
60 HAL_StatusTypeDef state = HAL_UART_DeInit(m_hwHandle);
61 if (state != HAL_OK)
62 {
63 if (state == HAL_ERROR)
64 {
65 SEMF_ERROR("hal error");
66 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::Deinit_HalError)));
67 }
68 else if (state == HAL_BUSY)
69 {
70 SEMF_ERROR("hal busy");
71 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::Deinit_HalBusy)));
72 }
73 else if (state == HAL_TIMEOUT)
74 {
75 SEMF_ERROR("hal timeout");
76 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::Deinit_HalTimeout)));
77 }
78 return;
79 }
80}
81
83{
84 SEMF_INFO("stop write");
85 HAL_StatusTypeDef state = HAL_UART_AbortTransmit(m_hwHandle);
86 if (state != HAL_OK)
87 {
88 if (state == HAL_ERROR)
89 {
90 SEMF_ERROR("hal error");
91 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::StopWrite_HalError)));
92 }
93 else if (state == HAL_BUSY)
94 {
95 SEMF_ERROR("hal busy");
96 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::StopWrite_HalBusy)));
97 }
98 else if (state == HAL_TIMEOUT)
99 {
100 SEMF_ERROR("hal timeout");
101 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::StopWrite_HalTimeout)));
102 }
103 return;
104 }
105 writeStopped();
106}
107
109{
110 SEMF_INFO("stop read");
111 HAL_StatusTypeDef state = HAL_UART_AbortReceive(m_hwHandle);
112 if (state != HAL_OK)
113 {
114 if (state == HAL_ERROR)
115 {
116 SEMF_ERROR("hal error");
117 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::StopRead_HalError)));
118 }
119 else if (state == HAL_BUSY)
120 {
121 SEMF_ERROR("hal busy");
122 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::StopRead_HalBusy)));
123 }
124 else if (state == HAL_TIMEOUT)
125 {
126 SEMF_ERROR("hal timeout");
127 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::StopRead_HalTimeout)));
128 }
129 return;
130 }
131 readStopped();
132}
133
134void Stm32Uart::setFormat(uint8_t bits, WireMode wire, Parity par, StopBits stop, FlowControl flow)
135{
136 SEMF_INFO("set format, bits %u, wire %u, parity %u, stop %u, flow %u", bits, static_cast<uint32_t>(wire), static_cast<uint32_t>(par),
137 static_cast<uint32_t>(stop), static_cast<uint32_t>(flow));
138
139 halLock();
140 if (par == Parity::NoParity)
141 {
142 switch (bits)
143 {
144#if !defined(STM32F4) && !defined(STM32F1) && !defined(STM32F0)
145 case 7:
146 m_hwHandle->Init.WordLength = UART_WORDLENGTH_7B;
147 break;
148#endif
149 case 8:
150 m_hwHandle->Init.WordLength = UART_WORDLENGTH_8B;
151 break;
152 case 9:
153 m_hwHandle->Init.WordLength = UART_WORDLENGTH_9B;
154 break;
155 default:
156 SEMF_ERROR("word length invalid %u", bits);
157 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::SetFormat_WordLengthInvalid)));
158 break;
159 }
160 }
161 else
162 {
163 switch (bits)
164 {
165#if !defined(STM32F4) && !defined(STM32F1) && !defined(STM32F0)
166 case 6:
167 m_hwHandle->Init.WordLength = UART_WORDLENGTH_7B;
168 break;
169#endif
170 case 7:
171 m_hwHandle->Init.WordLength = UART_WORDLENGTH_8B;
172 break;
173 case 8:
174 m_hwHandle->Init.WordLength = UART_WORDLENGTH_9B;
175 break;
176 default:
177 SEMF_ERROR("word length invalid %u", bits);
178 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::SetFormat_WordLengthInvalid)));
179 break;
180 }
181 }
182
183 switch (wire)
184 {
186 m_hwHandle->Init.Mode = UART_MODE_RX;
187 break;
189 m_hwHandle->Init.Mode = UART_MODE_TX;
190 break;
192 m_hwHandle->Init.Mode = UART_MODE_TX_RX;
193 break;
194 default:
195 SEMF_ERROR("wire invalid %u", static_cast<uint32_t>(wire));
196 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::SetFormat_WireInvalid)));
197 return;
198 }
199
200 switch (par)
201 {
202 case Parity::NoParity:
203 m_hwHandle->Init.Parity = UART_PARITY_NONE;
204 break;
206 m_hwHandle->Init.Parity = UART_PARITY_ODD;
207 break;
209 m_hwHandle->Init.Parity = UART_PARITY_EVEN;
210 break;
211 default:
212 SEMF_ERROR("parity invalid %u", static_cast<uint32_t>(par));
213 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::SetFormat_ParityInvalid)));
214 return;
215 }
216
217 switch (stop)
218 {
220 m_hwHandle->Init.StopBits = UART_STOPBITS_1;
221 break;
223 m_hwHandle->Init.StopBits = UART_STOPBITS_2;
224 break;
225#if !defined(STM32F4) && !defined(STM32F1)
227 m_hwHandle->Init.StopBits = UART_STOPBITS_0_5;
228 break;
230 m_hwHandle->Init.StopBits = UART_STOPBITS_1_5;
231 break;
232#endif
233 default:
234 SEMF_ERROR("stop bits invalid %u", static_cast<uint32_t>(stop));
235 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::SetFormat_StopBitsInvalid)));
236 return;
237 }
238
239 switch (flow)
240 {
242 m_hwHandle->Init.HwFlowCtl = UART_HWCONTROL_NONE;
243 break;
245 m_hwHandle->Init.HwFlowCtl = UART_HWCONTROL_RTS;
246 break;
248 m_hwHandle->Init.HwFlowCtl = UART_HWCONTROL_CTS;
249 break;
251 m_hwHandle->Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS;
252 break;
253 default:
254 SEMF_ERROR("flow invalid %u", static_cast<uint32_t>(flow));
255 onError(Error(kSemfClassId, static_cast<uint32_t>(ErrorCode::SetFormat_FlowInvalid)));
256 return;
257 }
258 __HAL_UNLOCK(m_hwHandle);
259}
260
261void Stm32Uart::setBaud(uint32_t baud)
262{
263 SEMF_INFO("set baud %u", baud);
264 halLock();
265 m_hwHandle->Init.BaudRate = baud;
266 __HAL_UNLOCK(m_hwHandle);
267}
268
270{
271 return m_hwHandle->Init.BaudRate;
272}
273
275{
277 return &queue;
278}
279
280void Stm32Uart::systemIsrRead(UART_HandleTypeDef& uart)
281{
282 for (Stm32Uart& i : *(queue()))
283 i.isrRead(uart);
284}
285
286void Stm32Uart::systemIsrWritten(UART_HandleTypeDef& uart)
287{
288 for (Stm32Uart& i : *(queue()))
289 i.isrWritten(uart);
290}
291
292void Stm32Uart::isrRead(UART_HandleTypeDef& uart)
293{
294 if (m_hwHandle == &uart)
295 {
297 }
298}
299
300void Stm32Uart::isrWritten(UART_HandleTypeDef& uart)
301{
302 if (m_hwHandle == &uart)
303 {
305 }
306}
307
308void Stm32Uart::writeHardware(const uint8_t data[], size_t dataSize)
309{
310 __HAL_UNLOCK(m_hwHandle);
311 HAL_StatusTypeDef state = HAL_UART_Transmit_IT(m_hwHandle, const_cast<uint8_t*>(data), static_cast<uint16_t>(dataSize));
312 if (state != HAL_OK)
313 {
314 if (state == HAL_ERROR)
315 {
316 SEMF_ERROR("hal error");
317 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::WriteHardware_HalError)));
318 }
319 else if (state == HAL_BUSY)
320 {
321 SEMF_ERROR("hal busy");
322 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::WriteHardware_HalBusy)));
323 }
324 else if (state == HAL_TIMEOUT)
325 {
326 SEMF_ERROR("hal timeout");
327 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::WriteHardware_HalTimeout)));
328 }
329 return;
330 }
331}
332
333void Stm32Uart::readHardware(uint8_t buffer[], size_t bufferSize)
334{
335 __HAL_UNLOCK(m_hwHandle);
336 HAL_StatusTypeDef state = HAL_UART_Receive_IT(m_hwHandle, buffer, static_cast<uint16_t>(bufferSize));
337 if (state != HAL_OK)
338 {
339 if (state == HAL_ERROR)
340 {
341 SEMF_ERROR("hal error");
342 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::ReadHardware_HalError)));
343 }
344 else if (state == HAL_BUSY)
345 {
346 SEMF_ERROR("hal busy");
347 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::ReadHardware_HalBusy)));
348 }
349 else if (state == HAL_TIMEOUT)
350 {
351 SEMF_ERROR("hal timeout");
352 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::ReadHardware_HalTimeout)));
353 }
354 return;
355 }
356}
357
358HAL_StatusTypeDef Stm32Uart::halLock()
359{
360 __HAL_LOCK(m_hwHandle);
361 return HAL_OK;
362}
363} /* namespace semf */
364#endif
Class for representing errors. Every error should have a unique source code. As a user feel encourage...
Definition: error.h:22
LinkedQueue is an managed single linked queue implementation.
Definition: linkedqueue.h:38
UartHardware implemenation for STM32.
Definition: stm32uart.h:24
Stm32Uart(UART_HandleTypeDef &hwHandle)
Constructor.
Definition: stm32uart.cpp:26
void isrRead(UART_HandleTypeDef &uart)
Interrupt service routine for uart object receive.
Definition: stm32uart.cpp:292
uint32_t baud() override
Returns the currently used baud rate.
Definition: stm32uart.cpp:269
void stopWrite() override
Definition: stm32uart.cpp:82
void stopRead() override
Definition: stm32uart.cpp:108
void writeHardware(const uint8_t data[], size_t dataSize) override
Hardware will write data in interrupt mode.
Definition: stm32uart.cpp:308
void readHardware(uint8_t buffer[], size_t bufferSize) override
Hardware will read data in interrupt mode.
Definition: stm32uart.cpp:333
static LinkedQueue< Stm32Uart > * queue()
Get the list with all uarts.
Definition: stm32uart.cpp:274
void isrWritten(UART_HandleTypeDef &uart)
Interrupt service routine for uart object transmit.
Definition: stm32uart.cpp:300
void deinit() override
Definition: stm32uart.cpp:57
void init() override
Definition: stm32uart.cpp:32
static void systemIsrRead(UART_HandleTypeDef &uart)
System-wide interrupt service routine for uart receive.
Definition: stm32uart.cpp:280
static void systemIsrWritten(UART_HandleTypeDef &uart)
System-wide interrupt service routine for uart transmit.
Definition: stm32uart.cpp:286
void setBaud(uint32_t baud) override
Sets the baud rate.
Definition: stm32uart.cpp:261
void setFormat(uint8_t bits, WireMode wire, Parity par, StopBits stop, FlowControl flow) override
Sets the format for the spi slave device.
Definition: stm32uart.cpp:134
void onError(Error thrown)
Is called if an error occurred by hardware read or write access. Will throw error signal.
Parity
Definition: uart.h:37
FlowControl
Definition: uart.h:29
@ RtsFlowControl
Receive flow control setting, RXD, TXD and RTS pins are used.
@ RtsAndCtsFlowControl
Full flow control setting, RXD, TXD, CTS and RTS pins are used.
@ CtsFlowControl
Transmit flow control setting, RXD, TXD and CTS pins are used.
@ NoFlowControl
No flow control setting, only RXD and TXD pins are used.
WireMode
Definition: uart.h:52
StopBits
Definition: uart.h:44
#define SEMF_ERROR(...)
Definition: debug.h:39
#define SEMF_INFO(...)
Definition: debug.h:41
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
Definition: stm32uart.cpp:14
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
Definition: stm32uart.cpp:18