libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
stm32_uart.hpp
1#pragma once
2
3#include <atomic>
4
5#include "main.h"
6#include "stm32_uart_gpdma.hpp"
7
8#ifdef HAL_UART_MODULE_ENABLED
9
10#ifdef UART
11#undef UART
12#endif
13
14#include "double_buffer.hpp"
15#include "flag.hpp"
16#include "libxr_def.hpp"
17#include "libxr_rw.hpp"
18#include "serialized_service.hpp"
19#include "uart.hpp"
20
21typedef enum : uint8_t
22{
23#ifdef USART1
24 STM32_USART1,
25#endif
26#ifdef USART2
27 STM32_USART2,
28#endif
29#ifdef USART3
30 STM32_USART3,
31#endif
32#ifdef USART4
33 STM32_USART4,
34#endif
35#ifdef USART5
36 STM32_USART5,
37#endif
38#ifdef USART6
39 STM32_USART6,
40#endif
41#ifdef USART7
42 STM32_USART7,
43#endif
44#ifdef USART8
45 STM32_USART8,
46#endif
47#ifdef USART9
48 STM32_USART9,
49#endif
50#ifdef USART10
51 STM32_USART10,
52#endif
53#ifdef USART11
54 STM32_USART11,
55#endif
56#ifdef USART12
57 STM32_USART12,
58#endif
59#ifdef USART13
60 STM32_USART13,
61#endif
62#ifdef UART1
63 STM32_UART1,
64#endif
65#ifdef UART2
66 STM32_UART2,
67#endif
68#ifdef UART3
69 STM32_UART3,
70#endif
71#ifdef UART4
72 STM32_UART4,
73#endif
74#ifdef UART5
75 STM32_UART5,
76#endif
77#ifdef UART6
78 STM32_UART6,
79#endif
80#ifdef UART7
81 STM32_UART7,
82#endif
83#ifdef UART8
84 STM32_UART8,
85#endif
86#ifdef UART9
87 STM32_UART9,
88#endif
89#ifdef UART10
90 STM32_UART10,
91#endif
92#ifdef UART11
93 STM32_UART11,
94#endif
95#ifdef UART12
96 STM32_UART12,
97#endif
98#ifdef UART13
99 STM32_UART13,
100#endif
101#ifdef LPUART1
102 STM32_LPUART1,
103#endif
104#ifdef LPUART2
105 STM32_LPUART2,
106#endif
107#ifdef LPUART3
108 STM32_LPUART3,
109#endif
110 STM32_UART_NUMBER,
111 STM32_UART_ID_ERROR
112} stm32_uart_id_t;
113
114stm32_uart_id_t stm32_uart_get_id(USART_TypeDef* addr);
115
116namespace LibXR
117{
137class STM32UART : public UART
138{
139 public:
141 static void WriteFun(WritePort& port, bool in_isr);
142
152 STM32UART(UART_HandleTypeDef* uart_handle, RawData dma_buff_rx, RawData dma_buff_tx,
153 uint32_t tx_queue_size = 5);
154
166 ErrorCode SetConfig(UART::Configuration config, bool in_isr = false) override;
167
169 void SetRxDMA(bool in_isr = false);
173 void RxEventIRQHandler();
175 void ErrorIRQHandler();
179
184
189
191 size_t last_rx_pos_ = 0;
192
193 UART_HandleTypeDef* uart_handle_;
194
197
198 stm32_uart_id_t id_ = STM32_UART_ID_ERROR;
199
200 static STM32UART* map[STM32_UART_NUMBER]; // NOLINT
201
202 private:
204 enum class ConfigState : uint32_t
205 {
206 EMPTY = 0U,
207 RESERVED = 1U,
208 PUBLISHED = 2U,
209 };
210
211 static constexpr uint32_t TX_EVENT_WRITE = 1U << 0U;
212 static constexpr uint32_t TX_EVENT_DONE = 1U << 1U;
213 static constexpr uint32_t TX_EVENT_CONFIG = 1U << 2U;
214 static constexpr uint32_t TX_EVENT_RX_WORK = 1U << 3U;
215 static constexpr uint32_t TX_EVENT_ABORT = 1U << 4U;
216 static constexpr uint32_t TX_EVENT_ERROR = 1U << 5U;
217#if defined(LIBXR_STM32_UART_GPDMA)
218 static constexpr uint32_t TX_EVENT_START_RX = 1U << 6U;
219 static void DmaAbortCallback(DMA_HandleTypeDef* dma_handle);
220#endif
221
224 void BeginAbort(bool in_isr);
225
227 void HandleTxService(uint32_t events, bool in_isr);
229 void FillTx(bool in_isr);
231 void HandleTxDone(bool in_isr);
233 void StartTxDma(bool in_isr);
235 void ApplyConfig(UART::Configuration config, bool in_isr);
237 void TryApplyConfig(bool in_isr);
239 void HandleRxData(bool in_isr);
240
242 SerializedService tx_service_;
246 bool abort_pending_ = false;
248 std::atomic<ConfigState> config_state_{ConfigState::EMPTY};
251 UART::Configuration pending_config_{};
252#if defined(LIBXR_STM32_UART_GPDMA)
253 STM32GpdmaUartAdapter gpdma_adapter_;
254#endif
255};
256
257} // namespace LibXR
258
259#endif
双缓冲区管理类 / Double buffer manager class
普通标志位(非原子)/ Non-atomic flag
Definition flag.hpp:115
可写原始数据视图 / Mutable raw data view
基于 SPSC 字节队列的读端口 / Read endpoint backed by an SPSC byte queue.
Definition read_port.hpp:30
使用循环接收 DMA 和双缓冲发送的 STM32 串口 / STM32 UART with circular RX DMA and double-buffered TX.
RawData dma_buff_rx_
调用者提供的接收 DMA 缓冲区 / Caller-provided RX DMA buffer.
void ErrorIRQHandler()
通知错误,由后端处理器启动中止 / Report an error; the service initiates the abort.
void SetRxDMA(bool in_isr=false)
初始化循环接收 DMA 并检查启动结果 / Initialize circular RX DMA and check startup.
DoubleBuffer dma_buff_tx_
当前与待发送的 DMA 半区 / Active and pending TX DMA halves.
Flag::Plain tx_busy_
发送半区是否在使用,仅后端处理器访问 / TX half in use; service-only access.
void AbortCompleteIRQHandler()
WritePort _write_port
写请求及发送字节队列 / Write requests and TX byte queue.
void TxCompleteIRQHandler()
通知发送完成,交给后端释放半区 / Notify TX completion to release the active half.
size_t last_rx_pos_
上次已处理的 DMA 接收位置 / Last processed RX DMA position.
STM32UART(UART_HandleTypeDef *uart_handle, RawData dma_buff_rx, RawData dma_buff_tx, uint32_t tx_queue_size=5)
构造串口并关联 DMA 缓冲区 / Construct a UART with DMA buffers.
void RxEventIRQHandler()
通知接收位置变化 / Notify RX position changes.
ErrorCode SetConfig(UART::Configuration config, bool in_isr=false) override
提交串口配置请求 / Submit a UART configuration request.
ReadPort _read_port
接收字节队列与读请求 / RX byte queue and read requests.
事件合并与回调串行化服务 / Event-coalescing serialized-callback service.
通用异步收发传输(UART)基类 / Abstract base class for Universal Asynchronous Receiver-Transmitter (UART)
Definition uart.hpp:19
基于 SPSC 字节队列的写端口 / Write endpoint backed by an SPSC byte queue.
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ EMPTY
为空 / Empty
void(* WriteFun)(WritePort &port, bool in_isr)
写入进度通知函数类型 / Write progress notification function type.
UART 配置结构体 / UART configuration structure.
Definition uart.hpp:44