libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
stm32_uart_gpdma.hpp
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5
6#include "main.h"
7
8#if defined(STM32H5)
9#define LIBXR_STM32_UART_GPDMA 1
10#endif
11
12#if (defined(LIBXR_STM32_UART_GPDMA) && defined(HAL_UART_MODULE_ENABLED)) || \
13 defined(__DOXYGEN__)
14
15#if !defined(HAL_DMA_MODULE_ENABLED) || !defined(DMA_LINKEDLIST_CIRCULAR) || \
16 !defined(DMA_GPDMA_LINEAR_NODE) || !defined(IS_GPDMA_INSTANCE)
17#error "STM32H5 UART requires the HAL GPDMA linked-list API"
18#endif
19
20#if (defined(STM32H503xx) || defined(STM32H523xx) || defined(STM32H533xx) || \
21 defined(STM32H543xx) || defined(STM32H553xx) || defined(STM32H562xx) || \
22 defined(STM32H563xx) || defined(STM32H573xx)) && \
23 !defined(USART_DMAREQUESTS_SW_WA)
24#error "STM32H5 UART requires the HAL USART DMA-request workaround"
25#endif
26
27namespace LibXR
28{
41{
42 public:
43 static constexpr size_t RX_NODE_COUNT = 4U;
44 using AbortCallback = void (*)(DMA_HandleTypeDef*);
45
47 explicit STM32GpdmaUartAdapter(UART_HandleTypeDef* uart_handle);
48
50 HAL_StatusTypeDef StartLinkedListDmaRx(uint8_t* buffer, size_t total_size, bool in_isr);
52 [[nodiscard]] uint8_t* GetLinkedListDmaRxProducer() const;
57 [[nodiscard]] bool LaunchStop(DMA_HandleTypeDef* dma_handle, AbortCallback callback,
58 bool in_isr);
60 [[nodiscard]] static bool StopComplete(DMA_HandleTypeDef* dma_handle);
62 [[nodiscard]] bool AllStopsComplete() const;
64 static void FinalizeStopped(DMA_HandleTypeDef* dma_handle, bool in_isr);
65
66 private:
67 // 节点保持在同一 64 KiB 链表地址窗口内。
68 // Keep all nodes within one 64 KiB linked-list address window.
69 struct alignas(256) StateBlock
70 {
71 DMA_NodeTypeDef nodes_[RX_NODE_COUNT];
72 DMA_QListTypeDef rx_queue_{};
73 UART_HandleTypeDef* uart_handle_ = nullptr;
74 uint8_t* rx_buffer_ = nullptr;
75 size_t rx_total_size_ = 0U;
76 size_t rx_node_size_ = 0U;
77 bool rx_queue_built_ = false;
78 };
79 static_assert(offsetof(StateBlock, nodes_) == 0U);
80 static_assert(sizeof(StateBlock) == 256U);
81
82 [[nodiscard]] static bool IsStopped(DMA_HandleTypeDef* dma_handle);
83 static void DisableInterrupts(DMA_HandleTypeDef* dma_handle);
84 static void ClearFlags(DMA_HandleTypeDef* dma_handle);
85 void BuildRxQueue(uint8_t* buffer, size_t total_size, bool in_isr);
86 StateBlock state_{};
87};
88static_assert(sizeof(STM32GpdmaUartAdapter) == 256U);
89} // namespace LibXR
90#endif
STM32 GPDMA 串口适配器 / STM32 GPDMA UART adapter.
static void FinalizeStopped(DMA_HandleTypeDef *dma_handle, bool in_isr)
在停止状态清除旧标志和链表计数 / Clear stale flags and list count while stopped.
static bool StopComplete(DMA_HandleTypeDef *dma_handle)
检查通道及 HAL 链表均已停止 / Check that the channel and HAL list have stopped.
bool AllStopsComplete() const
检查所有已配置的 DMA 通道均已停止 / Check all configured DMA channels have stopped.
bool LaunchStop(DMA_HandleTypeDef *dma_handle, AbortCallback callback, bool in_isr)
启动异步中止或接续已有中止 / Start an asynchronous abort or join an existing abort.
uint8_t * GetLinkedListDmaRxProducer() const
读取一次当前 DMA 写入地址 / Read the current DMA destination address once.
HAL_StatusTypeDef StartLinkedListDmaRx(uint8_t *buffer, size_t total_size, bool in_isr)
构建或复用四节点循环链表并启动 RX / Build or reuse the four-node ring and start RX.
STM32GpdmaUartAdapter(UART_HandleTypeDef *uart_handle)
绑定已初始化的 UART 句柄 / Bind an initialized UART handle.
void CloseTxTerminalSource() const
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14