libxr 1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
stm32_uart.cpp
1#include "stm32_uart.hpp"
2
3#ifdef HAL_UART_MODULE_ENABLED
4
5using namespace LibXR;
6
7STM32UART *STM32UART::map[STM32_UART_NUMBER] = {nullptr};
8
9stm32_uart_id_t STM32_UART_GetID(USART_TypeDef *addr)
10{
11 if (addr == nullptr)
12 { // NOLINT
13 return stm32_uart_id_t::STM32_UART_ID_ERROR;
14 }
15#ifdef USART1
16 else if (addr == USART1)
17 { // NOLINT
18 return stm32_uart_id_t::STM32_USART1;
19 }
20#endif
21#ifdef USART2
22 else if (addr == USART2)
23 { // NOLINT
24 return stm32_uart_id_t::STM32_USART2;
25 }
26#endif
27#ifdef USART3
28 else if (addr == USART3)
29 { // NOLINT
30 return stm32_uart_id_t::STM32_USART3;
31 }
32#endif
33#ifdef USART4
34 else if (addr == USART4)
35 { // NOLINT
36 return stm32_uart_id_t::STM32_USART4;
37 }
38#endif
39#ifdef USART5
40 else if (addr == USART5)
41 { // NOLINT
42 return stm32_uart_id_t::STM32_USART5;
43 }
44#endif
45#ifdef USART6
46 else if (addr == USART6)
47 { // NOLINT
48 return stm32_uart_id_t::STM32_USART6;
49 }
50#endif
51#ifdef USART7
52 else if (addr == USART7)
53 { // NOLINT
54 return stm32_uart_id_t::STM32_USART7;
55 }
56#endif
57#ifdef USART8
58 else if (addr == USART8)
59 { // NOLINT
60 return stm32_uart_id_t::STM32_USART8;
61 }
62#endif
63#ifdef USART9
64 else if (addr == USART9)
65 { // NOLINT
66 return stm32_uart_id_t::STM32_USART9;
67 }
68#endif
69#ifdef USART10
70 else if (addr == USART10)
71 { // NOLINT
72 return stm32_uart_id_t::STM32_USART10;
73 }
74#endif
75#ifdef USART11
76 else if (addr == USART11)
77 { // NOLINT
78 return stm32_uart_id_t::STM32_USART11;
79 }
80#endif
81#ifdef USART12
82 else if (addr == USART12)
83 { // NOLINT
84 return stm32_uart_id_t::STM32_USART12;
85 }
86#endif
87#ifdef USART13
88 else if (addr == USART13)
89 { // NOLINT
90 return stm32_uart_id_t::STM32_USART13;
91 }
92#endif
93#ifdef UART1
94 else if (addr == UART1)
95 { // NOLINT
96 return stm32_uart_id_t::STM32_UART1;
97 }
98#endif
99#ifdef UART2
100 else if (addr == UART2)
101 { // NOLINT
102 return stm32_uart_id_t::STM32_UART2;
103 }
104#endif
105#ifdef UART3
106 else if (addr == UART3)
107 { // NOLINT
108 return stm32_uart_id_t::STM32_UART3;
109 }
110#endif
111#ifdef UART4
112 else if (addr == UART4)
113 { // NOLINT
114 return stm32_uart_id_t::STM32_UART4;
115 }
116#endif
117#ifdef UART5
118 else if (addr == UART5)
119 { // NOLINT
120 return stm32_uart_id_t::STM32_UART5;
121 }
122#endif
123#ifdef UART6
124 else if (addr == UART6)
125 { // NOLINT
126 return stm32_uart_id_t::STM32_UART6;
127 }
128#endif
129#ifdef UART7
130 else if (addr == UART7)
131 { // NOLINT
132 return stm32_uart_id_t::STM32_UART7;
133 }
134#endif
135#ifdef UART8
136 else if (addr == UART8)
137 { // NOLINT
138 return stm32_uart_id_t::STM32_UART8;
139 }
140#endif
141#ifdef UART9
142 else if (addr == UART9)
143 { // NOLINT
144 return stm32_uart_id_t::STM32_UART9;
145 }
146#endif
147#ifdef UART10
148 else if (addr == UART10)
149 { // NOLINT
150 return stm32_uart_id_t::STM32_UART10;
151 }
152#endif
153#ifdef UART11
154 else if (addr == UART11)
155 { // NOLINT
156 return stm32_uart_id_t::STM32_UART11;
157 }
158#endif
159#ifdef UART12
160 else if (addr == UART12)
161 { // NOLINT
162 return stm32_uart_id_t::STM32_UART12;
163 }
164#endif
165#ifdef UART13
166 else if (addr == UART13)
167 { // NOLINT
168 return stm32_uart_id_t::STM32_UART13;
169 }
170#endif
171#ifdef LPUART1
172 else if (addr == LPUART1)
173 { // NOLINT
174 return stm32_uart_id_t::STM32_LPUART1;
175 }
176#endif
177#ifdef LPUART2
178 else if (addr == LPUART2)
179 { // NOLINT
180 return stm32_uart_id_t::STM32_LPUART2;
181 }
182#endif
183#ifdef LPUART3
184 else if (addr == LPUART3)
185 { // NOLINT
186 return stm32_uart_id_t::STM32_LPUART3;
187 }
188#endif
189 else
190 {
191 return stm32_uart_id_t::STM32_UART_ID_ERROR;
192 }
193}
194
195// NOLINTNEXTLINE
196extern "C" void STM32_UART_ISR_Handler_IDLE(UART_HandleTypeDef *uart_handle)
197{
199 {
201 size_t len = uart_handle->RxXferSize - __HAL_DMA_GET_COUNTER(uart_handle->hdmarx);
202
203 auto uart = STM32UART::map[STM32_UART_GetID(uart_handle->Instance)];
204
206 uart->read_port_.queue_data_->PushBatch(uart->dma_buff_rx_.addr_, len);
207 uart->read_port_.ProcessPendingReads();
209 reinterpret_cast<uint8_t *>(uart->dma_buff_rx_.addr_),
210 uart->dma_buff_rx_.size_);
211 }
212}
213
214void STM32_UART_ISR_Handler_TX_CPLT(stm32_uart_id_t id)
215{ // NOLINT
216 auto uart = STM32UART::map[id];
217
219 if (uart->write_port_.queue_info_->Pop(info) != ErrorCode::OK)
220 {
221 ASSERT(false);
222 return;
223 }
224
225 uart->write_port_.write_size_ = uart->uart_handle_->TxXferSize;
226 info.op.UpdateStatus(true, ErrorCode::OK);
227
228 if (uart->write_port_.queue_info_->Peek(info) != ErrorCode::OK)
229 {
230 return;
231 }
232
233 if (uart->write_port_.queue_data_->PopBatch(
234 reinterpret_cast<uint8_t *>(uart->dma_buff_tx_.addr_), info.size) !=
235 ErrorCode::OK)
236 {
237 ASSERT(false);
238 return;
239 }
240
241 HAL_UART_Transmit_DMA(uart->uart_handle_,
242 static_cast<uint8_t *>(uart->dma_buff_tx_.addr_), info.size);
243
244 info.op.MarkAsRunning();
245}
246
247extern "C" void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
248{
249 STM32_UART_ISR_Handler_TX_CPLT(STM32_UART_GetID(huart->Instance));
250}
251
252extern "C" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
253{
254 UNUSED(huart);
255 auto len = huart->RxXferSize;
256 auto uart = STM32UART::map[STM32_UART_GetID(huart->Instance)];
257 uart->read_port_.queue_data_->PushBatch(static_cast<uint8_t *>(huart->pRxBuffPtr),
258 min(uart->read_port_.queue_data_->Size(), len));
259 HAL_UART_Receive_DMA(huart, huart->pRxBuffPtr, len);
260 uart->read_port_.ProcessPendingReads();
261}
262
263extern "C" __attribute__((used)) void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
264{
266}
267
268extern "C" void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
269{
270 auto uart = STM32UART::map[STM32_UART_GetID(huart->Instance)];
271 HAL_UART_Receive_DMA(huart, huart->pRxBuffPtr, uart->dma_buff_rx_.size_);
273 if (uart->write_port_.queue_info_->Peek(info) == ErrorCode::OK)
274 {
275 info.op.UpdateStatus(true, ErrorCode::FAILED);
276 }
277 uart->read_port_.Reset();
278 uart->write_port_.Reset();
279}
280
281extern "C" void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
282{
283 auto uart = STM32UART::map[STM32_UART_GetID(huart->Instance)];
285 if (uart->write_port_.queue_info_->Peek(info) == ErrorCode::OK)
286 {
287 info.op.UpdateStatus(true, ErrorCode::FAILED);
288 }
289 uart->write_port_.Reset();
290}
291
292extern "C" void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
293{
295 huart, huart->pRxBuffPtr,
296 STM32UART::map[STM32_UART_GetID(huart->Instance)]->dma_buff_rx_.size_);
297}
298
299#endif
ErrorCode PushBatch(const void *data, size_t size)
批量推入多个元素 (Push multiple elements into the queue).
Definition queue.hpp:175
void UpdateStatus(bool in_isr, Args &&...args)
Updates operation status based on type.
Definition libxr_rw.hpp:205
ReadPort read_port_
读取端口 / Read port
Definition uart.hpp:51
LibXR Color Control Library / LibXR终端颜色控制库
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值