libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::STM32UART Class Reference

STM32 UART 驱动实现 / STM32 UART driver implementation. More...

#include <stm32_uart.hpp>

Inheritance diagram for LibXR::STM32UART:
[legend]
Collaboration diagram for LibXR::STM32UART:
[legend]

Public Member Functions

 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
 
void SetRxDMA ()
 
void OnRxDataAvailable (bool in_isr)
 
- Public Member Functions inherited from LibXR::UART
template<typename ReadPortType = ReadPort, typename WritePortType = WritePort>
 UART (ReadPortType *read_port, WritePortType *write_port)
 UART 构造函数 / UART constructor.
 
template<typename OperationType , typename = std::enable_if_t<std::is_base_of_v< WriteOperation, std::decay_t<OperationType>>>>
ErrorCode Write (ConstRawData data, OperationType &&op, bool in_isr=false)
 
template<typename OperationType , typename = std::enable_if_t<std::is_base_of_v< ReadOperation, std::decay_t<OperationType>>>>
ErrorCode Read (RawData data, OperationType &&op, bool in_isr=false)
 

Static Public Member Functions

static ErrorCode WriteFun (WritePort &port, bool in_isr)
 
static ErrorCode ReadFun (ReadPort &port, bool in_isr)
 

Data Fields

ReadPort _read_port
 
WritePort _write_port
 
LatestSnapshot< UART::Configurationrequested_config_
 
UartRxConfigGate rx_config_gate_
 
UartCircularDmaRxModel rx_dma_model_
 
UartDmaTxModel< STM32UARTtx_dma_model_
 
UART_HandleTypeDef * uart_handle_
 
stm32_uart_id_t id_ = STM32_UART_ID_ERROR
 
- Data Fields inherited from LibXR::UART
ReadPortread_port_
 读取端口 / Read port
 
WritePortwrite_port_
 写入端口 / Write port
 

Static Public Attributes

static STM32UARTmap [STM32_UART_NUMBER] = {nullptr}
 

Private Member Functions

void OnConfigRequested ()
 
bool ApplyPendingConfig (bool in_isr)
 
bool OnConfigApplied (bool)
 
void StartCircularDmaRx (uint8_t *data, size_t size)
 通过 STM32 HAL 配置并启动 UART 循环 RX DMA / Configure and start circular UART RX DMA through STM32 HAL
 
size_t GetCircularDmaRxRemaining () const
 获取 STM32 RX DMA 剩余传输计数 / Get the STM32 RX DMA remaining count
 
void PrepareCircularDmaRxForCpu (uint8_t *data, size_t size)
 使循环 DMA RX 数据对 CPU 可见 / Make circular DMA RX data visible to the CPU
 
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
 

Friends

class UartCircularDmaRxModel
 
class UartDmaTxModel< STM32UART >
 

Additional Inherited Members

- Public Types inherited from LibXR::UART
enum class  Parity : uint8_t { NO_PARITY = 0 , EVEN = 1 , ODD = 2 }
 奇偶校验模式 / Parity mode More...
 

Detailed Description

STM32 UART 驱动实现 / STM32 UART driver implementation.

Warning
使用循环 RX DMA 时,UART 全局中断与对应 RX DMA 中断必须配置为相同的 NVIC 抢占优先级。HAL 的 UART IDLE、DMA HT 和 DMA TC 路径都可能进入同一 RX event callback;本驱动依赖相同优先级保证这些入口不重入。 When circular RX DMA is enabled, the UART global IRQ and its RX DMA IRQ must use the same NVIC preemption priority and, on multicore devices, the same target core. UART IDLE, DMA HT, and DMA TC paths may all enter the same HAL RX event callback; they must remain one logical SPSC producer. Runtime configuration may execute on another core and is coordinated separately by UartRxConfigGate.

Definition at line 128 of file stm32_uart.hpp.

Constructor & Destructor Documentation

◆ STM32UART()

STM32UART::STM32UART ( UART_HandleTypeDef * uart_handle,
RawData dma_buff_rx,
RawData dma_buff_tx,
uint32_t tx_queue_size = 5 )

构造 UART 对象 / Construct UART object

Definition at line 220 of file stm32_uart.cpp.

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))
230{
231 ASSERT(id_ != STM32_UART_ID_ERROR);
232
233 map[id_] = this;
234
235 if ((uart_handle->Init.Mode & UART_MODE_TX) == UART_MODE_TX)
236 {
237 ASSERT(uart_handle_->hdmatx != NULL);
238 _write_port = WriteFun;
239 }
240
241 SetRxDMA();
242}
size_t size_
数据字节数 / Data size in bytes
UART(ReadPortType *read_port, WritePortType *write_port)
UART 构造函数 / UART constructor.
Definition uart.hpp:66
ErrorCode(* WriteFun)(WritePort &port, bool in_isr)
Function pointer type for write operations.

Member Function Documentation

◆ ApplyPendingConfig()

bool STM32UART::ApplyPendingConfig ( bool in_isr)
private

Definition at line 261 of file stm32_uart.cpp.

262{
263 if (!rx_config_gate_.TryEnterConfig())
264 {
265 return false;
266 }
267
268 UART::Configuration config{};
269 (void)requested_config_.LoadLatest(config);
270
271 HAL_UART_DeInit(uart_handle_);
272 uart_handle_->Init.BaudRate = config.baudrate;
273
274 switch (config.parity)
275 {
277 uart_handle_->Init.Parity = UART_PARITY_NONE;
278 uart_handle_->Init.WordLength = UART_WORDLENGTH_8B;
279 break;
281 uart_handle_->Init.Parity = UART_PARITY_EVEN;
282 uart_handle_->Init.WordLength = UART_WORDLENGTH_9B;
283 break;
285 uart_handle_->Init.Parity = UART_PARITY_ODD;
286 uart_handle_->Init.WordLength = UART_WORDLENGTH_9B;
287 break;
288 default:
289 DEV_ASSERT_FROM_CALLBACK(false, in_isr);
290 return true;
291 }
292
293 switch (config.stop_bits)
294 {
295 case 1:
296 uart_handle_->Init.StopBits = UART_STOPBITS_1;
297 break;
298 case 2:
299 uart_handle_->Init.StopBits = UART_STOPBITS_2;
300 break;
301 default:
302 DEV_ASSERT_FROM_CALLBACK(false, in_isr);
303 return true;
304 }
305
306 if (HAL_UART_Init(uart_handle_) != HAL_OK)
307 {
308 DEV_ASSERT_FROM_CALLBACK(false, in_isr);
309 return true;
310 }
311
312 SetRxDMA();
313 return true;
314}
@ NO_PARITY
无校验 / No parity
@ ODD
奇校验 / Odd parity
@ EVEN
偶校验 / Even parity
UART 配置结构体 / UART configuration structure.
Definition uart.hpp:44

◆ GetCircularDmaRxRemaining()

size_t LibXR::STM32UART::GetCircularDmaRxRemaining ( ) const
inlinenodiscardprivate

获取 STM32 RX DMA 剩余传输计数 / Get the STM32 RX DMA remaining count

Returns
DMA 尚未写入的字节数 / Number of bytes not yet written by DMA

Definition at line 189 of file stm32_uart.hpp.

190 {
191 return __HAL_DMA_GET_COUNTER(uart_handle_->hdmarx);
192 }

◆ OnConfigApplied()

bool LibXR::STM32UART::OnConfigApplied ( bool )
inlineprivate

Definition at line 166 of file stm32_uart.hpp.

167 {
168 rx_config_gate_.LeaveConfig();
169 return true;
170 }

◆ OnConfigRequested()

void LibXR::STM32UART::OnConfigRequested ( )
inlineprivate

Definition at line 164 of file stm32_uart.hpp.

164{ rx_config_gate_.RequestConfig(); }

◆ OnRxDataAvailable()

void STM32UART::OnRxDataAvailable ( bool in_isr)

Definition at line 334 of file stm32_uart.cpp.

335{
336 if (!rx_config_gate_.TryEnterRx())
337 {
338 return;
339 }
340
341 rx_dma_model_.OnDataAvailable(*this, _read_port, in_isr);
342 if (rx_config_gate_.LeaveRx())
343 {
344 tx_dma_model_.RequestConfig(in_isr);
345 }
346}
void OnDataAvailable(Backend &backend, ReadPort &port, bool in_isr)
消费上次 DMA 事件后新产生的数据 / Consume bytes produced since the previous DMA event

◆ PrepareCircularDmaRxForCpu()

void LibXR::STM32UART::PrepareCircularDmaRxForCpu ( uint8_t * data,
size_t size )
inlineprivate

使循环 DMA RX 数据对 CPU 可见 / Make circular DMA RX data visible to the CPU

Parameters
dataDMA 接收缓冲区起始地址 / DMA receive buffer start address
size接收缓冲区字节数 / Receive buffer capacity in bytes

Definition at line 199 of file stm32_uart.hpp.

200 {
202 }
void STM32_InvalidateDCacheByAddr(const void *addr, size_t size)
Invalidates D-Cache lines covering the specified memory range.

◆ ReadFun()

ErrorCode STM32UART::ReadFun ( ReadPort & port,
bool in_isr )
static

Definition at line 201 of file stm32_uart.cpp.

201{ return ErrorCode::PENDING; }
@ PENDING
等待中 | Pending

◆ SetConfig()

ErrorCode STM32UART::SetConfig ( UART::Configuration config)
virtual

设置 UART 配置 / Sets the UART configuration

Parameters
configUART 配置信息 / UART configuration settings
Returns
返回操作状态,成功时返回 ErrorCode::OK,否则返回相应错误码 / Returns the operation status, ErrorCode::OK if successful, otherwise an error code

该方法为纯虚函数,子类必须实现具体的 UART 配置逻辑。 This is a pure virtual function. Subclasses must implement the specific UART configuration logic.

Implements LibXR::UART.

Definition at line 244 of file stm32_uart.cpp.

245{
246 if ((config.stop_bits != 1U) && (config.stop_bits != 2U))
247 {
248 return ErrorCode::ARG_ERR;
249 }
250 if ((config.parity != UART::Parity::NO_PARITY) &&
251 (config.parity != UART::Parity::EVEN) && (config.parity != UART::Parity::ODD))
252 {
253 return ErrorCode::ARG_ERR;
254 }
255
256 requested_config_.Store(config);
257 tx_dma_model_.RequestConfig(false);
258 return ErrorCode::OK;
259}
@ OK
操作成功 | Operation successful
@ ARG_ERR
参数错误 | Argument error
uint8_t stop_bits
停止位长度 / Number of stop bits
Definition uart.hpp:50
Parity parity
校验模式 / Parity mode
Definition uart.hpp:47

◆ SetRxDMA()

void STM32UART::SetRxDMA ( )

Definition at line 316 of file stm32_uart.cpp.

317{
318 if ((uart_handle_->Init.Mode & UART_MODE_RX) == UART_MODE_RX)
319 {
320 ASSERT(uart_handle_->hdmarx != NULL);
321
322 rx_dma_model_.Start(*this);
323 _read_port = ReadFun;
324 }
325}
void Start(Backend &backend)
复位读取位置并启动循环 DMA / Reset the read position and start circular DMA
ErrorCode(* ReadFun)(ReadPort &port, bool in_isr)
Function pointer type for read notifications.

◆ StartCircularDmaRx()

void LibXR::STM32UART::StartCircularDmaRx ( uint8_t * data,
size_t size )
inlineprivate

通过 STM32 HAL 配置并启动 UART 循环 RX DMA / Configure and start circular UART RX DMA through STM32 HAL

Parameters
dataDMA 可写的接收缓冲区 / DMA-writable receive buffer
size接收缓冲区字节数 / Receive buffer capacity in bytes

Definition at line 178 of file stm32_uart.hpp.

179 {
180 uart_handle_->hdmarx->Init.Mode = DMA_CIRCULAR;
181 HAL_DMA_Init(uart_handle_->hdmarx);
182 HAL_UARTEx_ReceiveToIdle_DMA(uart_handle_, data, size);
183 }

◆ StartDmaTx()

bool STM32UART::StartDmaTx ( uint8_t * data,
size_t size,
int block )
private

通过 STM32 HAL 启动一个 active UART TX DMA 载荷 / Start one active UART TX DMA payload through STM32 HAL

Parameters
dataDMA 可读的载荷缓冲区 / DMA-readable payload buffer
size载荷字节数 / Payload size in bytes
blockactive 双缓冲块索引,STM32 HAL 不使用 / Active double-buffer block index, unused by STM32 HAL
Returns
HAL 接受 DMA 传输时返回 true / True when HAL accepts the DMA transfer

Definition at line 377 of file stm32_uart.cpp.

378{
379 STM32_CleanDCacheByAddr(data, size);
380 return HAL_UART_Transmit_DMA(uart_handle_, data, size) == HAL_OK;
381}
void STM32_CleanDCacheByAddr(const void *addr, size_t size)
Cleans D-Cache lines covering the specified memory range.

◆ WriteFun()

ErrorCode STM32UART::WriteFun ( WritePort & port,
bool in_isr )
static

Definition at line 195 of file stm32_uart.cpp.

196{
197 auto* uart = LibXR::ContainerOf(&port, &STM32UART::_write_port);
198 return uart->tx_dma_model_.Submit(in_isr);
199}
OwnerType * ContainerOf(MemberType *ptr, MemberType OwnerType::*member) noexcept
通过成员指针恢复其所属对象指针

Friends And Related Symbol Documentation

◆ UartCircularDmaRxModel

friend class UartCircularDmaRxModel
friend

Definition at line 130 of file stm32_uart.hpp.

◆ UartDmaTxModel< STM32UART >

friend class UartDmaTxModel< STM32UART >
friend

Definition at line 130 of file stm32_uart.hpp.

Field Documentation

◆ _read_port

ReadPort LibXR::STM32UART::_read_port

Definition at line 149 of file stm32_uart.hpp.

◆ _write_port

WritePort LibXR::STM32UART::_write_port

Definition at line 150 of file stm32_uart.hpp.

◆ id_

stm32_uart_id_t LibXR::STM32UART::id_ = STM32_UART_ID_ERROR

Definition at line 159 of file stm32_uart.hpp.

◆ map

STM32UART * STM32UART::map = {nullptr}
static

Definition at line 161 of file stm32_uart.hpp.

◆ requested_config_

LatestSnapshot<UART::Configuration> LibXR::STM32UART::requested_config_

Definition at line 152 of file stm32_uart.hpp.

◆ rx_config_gate_

UartRxConfigGate LibXR::STM32UART::rx_config_gate_

Definition at line 153 of file stm32_uart.hpp.

◆ rx_dma_model_

UartCircularDmaRxModel LibXR::STM32UART::rx_dma_model_

Definition at line 154 of file stm32_uart.hpp.

◆ tx_dma_model_

UartDmaTxModel<STM32UART> LibXR::STM32UART::tx_dma_model_

Definition at line 155 of file stm32_uart.hpp.

◆ uart_handle_

UART_HandleTypeDef* LibXR::STM32UART::uart_handle_

Definition at line 157 of file stm32_uart.hpp.


The documentation for this class was generated from the following files: