libxr 1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
stm32_usb.hpp
1#pragma once
2
3#include "main.h"
4
5#ifdef HAL_PCD_MODULE_ENABLED
6
7#ifdef UART
8#undef UART
9#endif
10
11#include <type_traits>
12#include <utility>
13
14#include "libxr_def.hpp"
15#include "libxr_rw.hpp"
16#include "uart.hpp"
17#include "usbd_cdc.h"
18#include "usbd_cdc_if.h"
19
20extern uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
21extern uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
22
23int8_t libxr_stm32_virtual_uart_init(void);
24
25int8_t libxr_stm32_virtual_uart_deinit(void);
26
27int8_t libxr_stm32_virtual_uart_control(uint8_t cmd, uint8_t *pbuf, uint16_t len);
28
29int8_t libxr_stm32_virtual_uart_receive(uint8_t *pbuf, uint32_t *Len);
30
31int8_t libxr_stm32_virtual_uart_transmit(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
32
33namespace LibXR
34{
35class STM32VirtualUART : public UART
36{
37 public:
38 template <typename, typename = void>
39 struct HasTransmitCplt : std::false_type
40 {
41 };
42
43 template <typename T>
44 struct HasTransmitCplt<T, std::void_t<decltype(std::declval<T>().TransmitCplt)>>
45 : std::true_type
46 {
47 };
48 template <typename T>
49 typename std::enable_if<!HasTransmitCplt<T>::value, USBD_CDC_ItfTypeDef>::type Apply()
50 {
51 return {libxr_stm32_virtual_uart_init, libxr_stm32_virtual_uart_deinit,
52 libxr_stm32_virtual_uart_control, libxr_stm32_virtual_uart_receive};
53 }
54
55 template <typename T>
56 typename std::enable_if<HasTransmitCplt<T>::value, USBD_CDC_ItfTypeDef>::type Apply()
57 {
58 return {libxr_stm32_virtual_uart_init, libxr_stm32_virtual_uart_deinit,
59 libxr_stm32_virtual_uart_control, libxr_stm32_virtual_uart_receive,
60 libxr_stm32_virtual_uart_transmit};
61 }
62
63 using WriteFunctionType = ErrorCode (*)(WritePort &);
64
65 static ErrorCode WriteFun(WritePort &port)
66 {
67 STM32VirtualUART *uart = CONTAINER_OF(&port, STM32VirtualUART, write_port_);
68 auto p_data_class =
69 reinterpret_cast<USBD_CDC_HandleTypeDef *>(uart->usb_handle_->pClassData);
70
71 if (p_data_class == nullptr)
72 {
73 WritePort::WriteInfo info;
74 port.queue_info_->Pop(info);
75 port.queue_data_->PopBatch(uart->tx_buffer_, info.size);
76 info.op.UpdateStatus(false, ErrorCode::INIT_ERR);
77 return ErrorCode::INIT_ERR;
78 }
79
80#if defined(STM32F1)
81 if (!uart->writing_ && p_data_class->TxState == 0)
82#else
83 if (p_data_class->TxState == 0)
84#endif
85 {
86 WritePort::WriteInfo info;
87 auto ans = port.queue_info_->Peek(info);
88
89 if (ans != ErrorCode::OK)
90 {
91 return ErrorCode::EMPTY;
92 }
93
94 if (port.queue_data_->PopBatch(uart->tx_buffer_, info.size) != ErrorCode::OK)
95 {
96 ASSERT(false);
97 return ErrorCode::EMPTY;
98 }
99#if defined(STM32F1)
100 uart->write_size_ = info.size;
101 uart->writing_ = true;
102#endif
103
104 USBD_CDC_SetTxBuffer(uart->usb_handle_, uart->tx_buffer_, info.size);
105 USBD_CDC_TransmitPacket(uart->usb_handle_);
106
107 info.op.MarkAsRunning();
108
109 return ErrorCode::OK;
110 }
111 return ErrorCode::OK;
112 }
113
114 static ErrorCode ReadFun(ReadPort &port)
115 {
116 ReadInfoBlock block;
117
118 if (port.queue_block_->Peek(block) != ErrorCode::OK)
119 {
120 return ErrorCode::EMPTY;
121 }
122
123 block.op_.MarkAsRunning();
124
125 if (port.queue_data_->Size() >= block.data_.size_)
126 {
127 port.queue_data_->PopBatch(block.data_.addr_, block.data_.size_);
128 port.queue_block_->Pop();
129
130 port.read_size_ = block.data_.size_;
131 block.op_.UpdateStatus(false, ErrorCode::OK);
132 return ErrorCode::OK;
133 }
134 else
135 {
136 return ErrorCode::OK;
137 }
138 }
139
140 STM32VirtualUART(USBD_HandleTypeDef &usb_handle, uint8_t *tx_buffer = UserTxBufferFS,
141 uint8_t *rx_buffer = UserRxBufferFS, uint32_t rx_queue_size = 5,
144 usb_handle_(&usb_handle),
145 tx_buffer_(tx_buffer),
146 rx_buffer_(rx_buffer)
147 {
148 map[0] = this;
149
151
153
156
157 USBD_CDC_ReceivePacket(usb_handle_);
158 }
159
161 {
162 UNUSED(config);
163 return ErrorCode::OK;
164 }
165
166 static STM32VirtualUART *map[1]; // NOLINT
167
168 USBD_HandleTypeDef *usb_handle_ = nullptr;
169 uint8_t *tx_buffer_ = nullptr;
170 uint8_t *rx_buffer_ = nullptr;
171
172#if defined(STM32F1)
173 bool writing_ = false;
174 uint32_t write_size_ = 0;
175#endif
176};
177
178} // namespace LibXR
179
180#endif
ErrorCode SetConfig(UART::Configuration config)
设置 UART 配置 / Sets the UART configuration
通用异步收发传输(UART)基类 / Abstract base class for Universal Asynchronous Receiver-Transmitter (UART)
Definition uart.hpp:19
UART(size_t rx_queue_size, size_t rx_buffer_size, size_t tx_queue_size, size_t tx_buffer_size)
UART 构造函数 / UART constructor.
Definition uart.hpp:64
WritePort write_port_
写入端口 / Write port
Definition uart.hpp:52
ReadPort read_port_
读取端口 / Read port
Definition uart.hpp:51
LibXR Color Control Library / LibXR终端颜色控制库
Definition esp_gpio.hpp:8
ErrorCode(* ReadFun)(ReadPort &port)
Function pointer type for read operations.
Definition libxr_rw.hpp:281
ErrorCode(* WriteFun)(WritePort &port)
Function pointer type for write operations.
Definition libxr_rw.hpp:277
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值
UART 配置结构体 / UART configuration structure.
Definition uart.hpp:44