1#include "stm32_uart.hpp"
3#ifdef HAL_UART_MODULE_ENABLED
7STM32UART* STM32UART::map[STM32_UART_NUMBER] = {
nullptr};
9stm32_uart_id_t stm32_uart_get_id(USART_TypeDef* addr)
13 return stm32_uart_id_t::STM32_UART_ID_ERROR;
16 else if (addr == USART1)
18 return stm32_uart_id_t::STM32_USART1;
22 else if (addr == USART2)
24 return stm32_uart_id_t::STM32_USART2;
28 else if (addr == USART3)
30 return stm32_uart_id_t::STM32_USART3;
34 else if (addr == USART4)
36 return stm32_uart_id_t::STM32_USART4;
40 else if (addr == USART5)
42 return stm32_uart_id_t::STM32_USART5;
46 else if (addr == USART6)
48 return stm32_uart_id_t::STM32_USART6;
52 else if (addr == USART7)
54 return stm32_uart_id_t::STM32_USART7;
58 else if (addr == USART8)
60 return stm32_uart_id_t::STM32_USART8;
64 else if (addr == USART9)
66 return stm32_uart_id_t::STM32_USART9;
70 else if (addr == USART10)
72 return stm32_uart_id_t::STM32_USART10;
76 else if (addr == USART11)
78 return stm32_uart_id_t::STM32_USART11;
82 else if (addr == USART12)
84 return stm32_uart_id_t::STM32_USART12;
88 else if (addr == USART13)
90 return stm32_uart_id_t::STM32_USART13;
94 else if (addr == UART1)
96 return stm32_uart_id_t::STM32_UART1;
100 else if (addr == UART2)
102 return stm32_uart_id_t::STM32_UART2;
106 else if (addr == UART3)
108 return stm32_uart_id_t::STM32_UART3;
112 else if (addr == UART4)
114 return stm32_uart_id_t::STM32_UART4;
118 else if (addr == UART5)
120 return stm32_uart_id_t::STM32_UART5;
124 else if (addr == UART6)
126 return stm32_uart_id_t::STM32_UART6;
130 else if (addr == UART7)
132 return stm32_uart_id_t::STM32_UART7;
136 else if (addr == UART8)
138 return stm32_uart_id_t::STM32_UART8;
142 else if (addr == UART9)
144 return stm32_uart_id_t::STM32_UART9;
148 else if (addr == UART10)
150 return stm32_uart_id_t::STM32_UART10;
154 else if (addr == UART11)
156 return stm32_uart_id_t::STM32_UART11;
160 else if (addr == UART12)
162 return stm32_uart_id_t::STM32_UART12;
166 else if (addr == UART13)
168 return stm32_uart_id_t::STM32_UART13;
172 else if (addr == LPUART1)
174 return stm32_uart_id_t::STM32_LPUART1;
178 else if (addr == LPUART2)
180 return stm32_uart_id_t::STM32_LPUART2;
184 else if (addr == LPUART3)
186 return stm32_uart_id_t::STM32_LPUART3;
191 return stm32_uart_id_t::STM32_UART_ID_ERROR;
198 return uart->tx_dma_model_.Submit(in_isr);
206 if (handle->Init.Parity == UART_PARITY_EVEN)
210 else if (handle->Init.Parity == UART_PARITY_ODD)
216 handle->Init.BaudRate, parity, 8U,
217 static_cast<uint8_t
>(handle->Init.StopBits == UART_STOPBITS_2 ? 2U : 1U)};
221 RawData dma_buff_tx, uint32_t tx_queue_size)
222 :
UART(&_read_port, &_write_port),
223 _read_port(dma_buff_rx.size_),
224 _write_port(tx_queue_size, dma_buff_tx.size_ / 2),
225 requested_config_(STM32_UART_GetConfig(uart_handle)),
226 rx_dma_model_(dma_buff_rx),
227 tx_dma_model_(*this, _write_port, dma_buff_tx),
228 uart_handle_(uart_handle),
229 id_(stm32_uart_get_id(uart_handle_->Instance))
231 ASSERT(id_ != STM32_UART_ID_ERROR);
235 if ((uart_handle->Init.Mode & UART_MODE_TX) == UART_MODE_TX)
237 ASSERT(uart_handle_->hdmatx != NULL);
256 requested_config_.Store(config);
257 tx_dma_model_.RequestConfig(
false);
261bool STM32UART::ApplyPendingConfig(
bool in_isr)
263 if (!rx_config_gate_.TryEnterConfig())
269 (void)requested_config_.LoadLatest(config);
271 HAL_UART_DeInit(uart_handle_);
272 uart_handle_->Init.BaudRate = config.baudrate;
274 switch (config.parity)
277 uart_handle_->Init.Parity = UART_PARITY_NONE;
278 uart_handle_->Init.WordLength = UART_WORDLENGTH_8B;
281 uart_handle_->Init.Parity = UART_PARITY_EVEN;
282 uart_handle_->Init.WordLength = UART_WORDLENGTH_9B;
285 uart_handle_->Init.Parity = UART_PARITY_ODD;
286 uart_handle_->Init.WordLength = UART_WORDLENGTH_9B;
289 DEV_ASSERT_FROM_CALLBACK(
false, in_isr);
293 switch (config.stop_bits)
296 uart_handle_->Init.StopBits = UART_STOPBITS_1;
299 uart_handle_->Init.StopBits = UART_STOPBITS_2;
302 DEV_ASSERT_FROM_CALLBACK(
false, in_isr);
306 if (HAL_UART_Init(uart_handle_) != HAL_OK)
308 DEV_ASSERT_FROM_CALLBACK(
false, in_isr);
316void STM32UART::SetRxDMA()
318 if ((uart_handle_->Init.Mode & UART_MODE_RX) == UART_MODE_RX)
320 ASSERT(uart_handle_->hdmarx != NULL);
322 rx_dma_model_.
Start(*
this);
328static inline void STM32_UART_RX_ISR_Handler(UART_HandleTypeDef* uart_handle)
330 auto uart = STM32UART::map[stm32_uart_get_id(uart_handle->Instance)];
331 uart->OnRxDataAvailable(
true);
334void STM32UART::OnRxDataAvailable(
bool in_isr)
336 if (!rx_config_gate_.TryEnterRx())
344 tx_dma_model_.RequestConfig(in_isr);
349void STM32_UART_ISR_Handler_TX_CPLT(stm32_uart_id_t
id)
351 auto uart = STM32UART::map[id];
352 uart->tx_dma_model_.OnTransferDone(
true);
355extern "C" void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef* huart, uint16_t)
357 STM32_UART_RX_ISR_Handler(huart);
360extern "C" void HAL_UART_TxCpltCallback(UART_HandleTypeDef* huart)
362 STM32_UART_ISR_Handler_TX_CPLT(stm32_uart_get_id(huart->Instance));
365extern "C" __attribute__((used))
void HAL_UART_ErrorCallback(UART_HandleTypeDef* huart)
367 auto uart = STM32UART::map[stm32_uart_get_id(huart->Instance)];
368 uart->tx_dma_model_.RequestConfig(
true);
371extern "C" void HAL_UART_AbortCpltCallback(UART_HandleTypeDef* huart)
373 auto uart = STM32UART::map[stm32_uart_get_id(huart->Instance)];
374 uart->tx_dma_model_.RequestConfig(
true);
380 return HAL_UART_Transmit_DMA(uart_handle_, data, size) == HAL_OK;
可写原始数据视图 / Mutable raw data view
ReadPort class for handling read operations.
STM32 UART 驱动实现 / STM32 UART driver implementation.
bool StartDmaTx(uint8_t *data, size_t size, int block)
通过 STM32 HAL 启动一个 active UART TX DMA 载荷 / Start one active UART TX DMA payload through STM32 HAL
STM32UART(UART_HandleTypeDef *uart_handle, RawData dma_buff_rx, RawData dma_buff_tx, uint32_t tx_queue_size=5)
构造 UART 对象 / Construct UART object
ErrorCode SetConfig(UART::Configuration config)
设置 UART 配置 / Sets the UART configuration
通用异步收发传输(UART)基类 / Abstract base class for Universal Asynchronous Receiver-Transmitter (UART)
Parity
奇偶校验模式 / Parity mode
@ NO_PARITY
无校验 / No parity
void OnDataAvailable(Backend &backend, ReadPort &port, bool in_isr)
消费上次 DMA 事件后新产生的数据 / Consume bytes produced since the previous DMA event
void Start(Backend &backend)
复位读取位置并启动循环 DMA / Reset the read position and start circular DMA
WritePort class for handling write operations.
@ OK
操作成功 | Operation successful
@ ARG_ERR
参数错误 | Argument error
ErrorCode(* ReadFun)(ReadPort &port, bool in_isr)
Function pointer type for read notifications.
ErrorCode(* WriteFun)(WritePort &port, bool in_isr)
Function pointer type for write operations.
OwnerType * ContainerOf(MemberType *ptr, MemberType OwnerType::*member) noexcept
通过成员指针恢复其所属对象指针
void STM32_CleanDCacheByAddr(const void *addr, size_t size)
Cleans D-Cache lines covering the specified memory range.
UART 配置结构体 / UART configuration structure.
uint8_t stop_bits
停止位长度 / Number of stop bits
Parity parity
校验模式 / Parity mode