libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
stm32_usb_dev.cpp
1#include "stm32_usb_dev.hpp"
2
3#include "stm32_dcache.hpp"
4#if defined(HAL_PCD_MODULE_ENABLED)
5
6using namespace LibXR;
7
8stm32_usb_dev_id_t STM32USBDeviceGetID(PCD_HandleTypeDef* hpcd)
9{
10 for (int i = 0; i < STM32_USB_DEV_ID_NUM; i++)
11 {
12 if (STM32USBDevice::map_[i] && STM32USBDevice::map_[i]->hpcd_ == hpcd)
13 {
14 return static_cast<stm32_usb_dev_id_t>(i);
15 }
16 }
17 return STM32_USB_DEV_ID_NUM;
18}
19
20extern "C" void HAL_PCD_SOFCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
21
22extern "C" void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef* hpcd)
23{
24 auto id = STM32USBDeviceGetID(hpcd);
25
26 if (id >= STM32_USB_DEV_ID_NUM)
27 {
28 return;
29 }
30
31 auto usb = STM32USBDevice::map_[id];
32
33 if (!usb)
34 {
35 return;
36 }
37
38 if (STM32USBUsesDma(hpcd))
39 {
41 }
42
43 usb->GetEndpoint0In()->SetState(USB::Endpoint::State::IDLE);
44 usb->GetEndpoint0Out()->SetState(USB::Endpoint::State::IDLE);
45
46 usb->OnSetupPacket(true, reinterpret_cast<USB::SetupPacket*>(hpcd->Setup));
47}
48
49extern "C" void HAL_PCD_ResetCallback(PCD_HandleTypeDef* hpcd)
50{
51 auto id = STM32USBDeviceGetID(hpcd);
52
53 if (id >= STM32_USB_DEV_ID_NUM)
54 {
55 return;
56 }
57
58 auto usb = STM32USBDevice::map_[id];
59
60 if (!usb)
61 {
62 return;
63 }
64
65 usb->Deinit(true);
66 usb->Init(true);
67}
68
69extern "C" void HAL_PCD_SuspendCallback(PCD_HandleTypeDef* hpcd)
70{
71 auto id = STM32USBDeviceGetID(hpcd);
72
73 if (id >= STM32_USB_DEV_ID_NUM)
74 {
75 return;
76 }
77
78 auto usb = STM32USBDevice::map_[id];
79
80 if (!usb)
81 {
82 return;
83 }
84 usb->Deinit(true);
85}
86
87extern "C" void HAL_PCD_ResumeCallback(PCD_HandleTypeDef* hpcd)
88{
89 auto id = STM32USBDeviceGetID(hpcd);
90
91 if (id >= STM32_USB_DEV_ID_NUM)
92 {
93 return;
94 }
95
96 auto usb = STM32USBDevice::map_[id];
97
98 if (!usb)
99 {
100 return;
101 }
102 usb->Init(true);
103}
104
105extern "C" void HAL_PCD_ConnectCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
106
107extern "C" void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
108
109#if (defined(USB_OTG_FS))
110
111STM32USBDeviceOtgFS::STM32USBDeviceOtgFS(
112 PCD_HandleTypeDef* hpcd, size_t rx_fifo_size,
113 const std::initializer_list<LibXR::RawData> RX_EP_CFGS,
114 const std::initializer_list<EPInConfig> TX_EP_CFGS,
115 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
116 uint16_t bcd,
117 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
118 const std::initializer_list<const std::initializer_list<USB::ConfigDescriptorItem*>>
119 CONFIGS,
120 ConstRawData uid)
121 : STM32USBDevice(hpcd, STM32_USB_OTG_FS, RX_EP_CFGS.size() + TX_EP_CFGS.size(),
122 packet_size, vid, pid, bcd, LANG_LIST, CONFIGS, uid)
123{
124 ASSERT(RX_EP_CFGS.size() > 0 && RX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_FS_MAX_SIZE);
125 ASSERT(TX_EP_CFGS.size() > 0 && TX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_FS_MAX_SIZE);
126 ASSERT(64 * RX_EP_CFGS.size() <= rx_fifo_size);
127
128 auto rx_cfgs_itr = RX_EP_CFGS.begin();
129 auto tx_cfgs_itr = TX_EP_CFGS.begin();
130
131 auto ep0_in = new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
132 USB::Endpoint::Direction::IN, (*tx_cfgs_itr).fifo_size,
133 (*tx_cfgs_itr).buffer);
134
135 auto ep0_out =
136 new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
137 USB::Endpoint::Direction::OUT, rx_fifo_size, (*rx_cfgs_itr));
138
139 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
140
141 rx_cfgs_itr++;
142 tx_cfgs_itr++;
143
144 USB::Endpoint::EPNumber rx_ep_index = USB::Endpoint::EPNumber::EP1;
145
146 size_t fifo_used_size = rx_fifo_size;
147
148 for (; rx_cfgs_itr != RX_EP_CFGS.end(); rx_cfgs_itr++)
149 {
150 auto ep = new STM32Endpoint(rx_ep_index, id_, hpcd_, USB::Endpoint::Direction::OUT,
151 rx_fifo_size, (*rx_cfgs_itr));
152 USB::EndpointPool::Put(ep);
153 rx_ep_index = USB::Endpoint::NextEPNumber(rx_ep_index);
154 }
155
156 USB::Endpoint::EPNumber tx_ep_index = USB::Endpoint::EPNumber::EP1;
157
158 for (; tx_cfgs_itr != TX_EP_CFGS.end(); tx_cfgs_itr++)
159 {
160 auto ep = new STM32Endpoint(tx_ep_index, id_, hpcd_, USB::Endpoint::Direction::IN,
161 (*tx_cfgs_itr).fifo_size, (*tx_cfgs_itr).buffer);
162 USB::EndpointPool::Put(ep);
163 tx_ep_index = USB::Endpoint::NextEPNumber(tx_ep_index);
164 fifo_used_size += (*tx_cfgs_itr).fifo_size;
165 }
166
167 if (fifo_used_size > USB_OTG_FS_TOTAL_FIFO_SIZE)
168 {
169 ASSERT(false);
170 }
171}
172
173ErrorCode STM32USBDeviceOtgFS::SetAddress(uint8_t address,
175{
176 HAL_StatusTypeDef ans = HAL_OK;
177
178 if (context == USB::DeviceCore::Context::STATUS_IN_ARMED)
179 {
180 ans = HAL_PCD_SetAddress(hpcd_, address);
181 }
182 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
183}
184
185#endif
186
187#if (defined(USB_OTG_HS))
188
189STM32USBDeviceOtgHS::STM32USBDeviceOtgHS(
190 PCD_HandleTypeDef* hpcd, size_t rx_fifo_size,
191 const std::initializer_list<LibXR::RawData> RX_EP_CFGS,
192 const std::initializer_list<EPInConfig> TX_EP_CFGS,
193 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
194 uint16_t bcd,
195 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
196 const std::initializer_list<const std::initializer_list<USB::ConfigDescriptorItem*>>
197 CONFIGS,
198 ConstRawData uid)
200 hpcd, STM32_USB_OTG_HS, RX_EP_CFGS.size() + TX_EP_CFGS.size(), packet_size, vid,
201 pid, bcd, LANG_LIST, CONFIGS, uid,
202 hpcd->Init.speed == PCD_SPEED_HIGH ? USB::Speed::HIGH : USB::Speed::FULL)
203{
204 ASSERT(RX_EP_CFGS.size() > 0 && RX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_HS_MAX_SIZE);
205 ASSERT(TX_EP_CFGS.size() > 0 && TX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_HS_MAX_SIZE);
206 ASSERT(64 * RX_EP_CFGS.size() <= rx_fifo_size);
207
208 auto rx_cfgs_itr = RX_EP_CFGS.begin();
209 auto tx_cfgs_itr = TX_EP_CFGS.begin();
210
211 auto ep0_in = new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
212 USB::Endpoint::Direction::IN, (*tx_cfgs_itr).fifo_size,
213 (*tx_cfgs_itr).buffer);
214
215 auto ep0_out =
216 new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
217 USB::Endpoint::Direction::OUT, rx_fifo_size, (*rx_cfgs_itr));
218
219 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
220
221 rx_cfgs_itr++;
222 tx_cfgs_itr++;
223
224 USB::Endpoint::EPNumber rx_ep_index = USB::Endpoint::EPNumber::EP1;
225
226 size_t fifo_used_size = rx_fifo_size;
227
228 for (; rx_cfgs_itr != RX_EP_CFGS.end(); rx_cfgs_itr++)
229 {
230 auto ep = new STM32Endpoint(rx_ep_index, id_, hpcd_, USB::Endpoint::Direction::OUT,
231 rx_fifo_size, (*rx_cfgs_itr));
232 USB::EndpointPool::Put(ep);
233 rx_ep_index = USB::Endpoint::NextEPNumber(rx_ep_index);
234 }
235
236 USB::Endpoint::EPNumber tx_ep_index = USB::Endpoint::EPNumber::EP1;
237
238 for (; tx_cfgs_itr != TX_EP_CFGS.end(); tx_cfgs_itr++)
239 {
240 auto ep = new STM32Endpoint(tx_ep_index, id_, hpcd_, USB::Endpoint::Direction::IN,
241 (*tx_cfgs_itr).fifo_size, (*tx_cfgs_itr).buffer);
242 USB::EndpointPool::Put(ep);
243 tx_ep_index = USB::Endpoint::NextEPNumber(tx_ep_index);
244 fifo_used_size += (*tx_cfgs_itr).fifo_size;
245 }
246
247 if (fifo_used_size > USB_OTG_HS_TOTAL_FIFO_SIZE)
248 {
249 ASSERT(false);
250 }
251}
252
253ErrorCode STM32USBDeviceOtgHS::SetAddress(uint8_t address,
255{
256 HAL_StatusTypeDef ans = HAL_OK;
257
258 if (context == USB::DeviceCore::Context::STATUS_IN_ARMED)
259 {
260 ans = HAL_PCD_SetAddress(hpcd_, address);
261 }
262 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
263}
264
265#endif
266
267#if defined(USB_BASE)
268STM32USBDeviceDevFs::STM32USBDeviceDevFs(
269 PCD_HandleTypeDef* hpcd, const std::initializer_list<EPConfig> EP_CFGS,
270 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
271 uint16_t bcd,
272 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
273 const std::initializer_list<const std::initializer_list<USB::ConfigDescriptorItem*>>
274 CONFIGS,
275 ConstRawData uid)
276 : STM32USBDevice(hpcd, STM32_USB_FS_DEV, EP_CFGS.size() * 2, packet_size, vid, pid,
277 bcd, LANG_LIST, CONFIGS, uid)
278{
279 ASSERT(EP_CFGS.size() > 0 && EP_CFGS.size() <= hpcd->Init.dev_endpoints);
280
281 auto cfgs_itr = EP_CFGS.begin();
282
283#if defined(PMA_START_ADDR)
284 size_t buffer_offset = PMA_START_ADDR;
285#else
286 size_t buffer_offset = BTABLE_ADDRESS + hpcd_->Init.dev_endpoints * 8U; // 字节
287#endif
288
289 auto ep0_out = new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
290 USB::Endpoint::Direction::OUT, buffer_offset,
291 (*cfgs_itr).hw_buffer_size2, (*cfgs_itr).buffer2);
292
293 buffer_offset += (*cfgs_itr).hw_buffer_size2;
294
295 auto ep0_in = new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
296 USB::Endpoint::Direction::IN, buffer_offset,
297 (*cfgs_itr).hw_buffer_size1, (*cfgs_itr).buffer1);
298
299 buffer_offset += (*cfgs_itr).hw_buffer_size1;
300
301 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
302
303 cfgs_itr++;
304
305 USB::Endpoint::EPNumber ep_index = USB::Endpoint::EPNumber::EP1;
306
307 while (cfgs_itr != EP_CFGS.end())
308 {
309 if (cfgs_itr->hw_buffer_size2 == 0)
310 {
311 ASSERT(cfgs_itr->buffer1.size_ % 2 == 0);
312 auto ep = new STM32Endpoint(
313 ep_index, id_, hpcd_,
314 cfgs_itr->double_buffer_is_in ? USB::Endpoint::Direction::IN
315 : USB::Endpoint::Direction::OUT,
316 buffer_offset, (*cfgs_itr).hw_buffer_size1, (*cfgs_itr).buffer1);
317 USB::EndpointPool::Put(ep);
318 ep_index = USB::Endpoint::NextEPNumber(ep_index);
319 buffer_offset += (*cfgs_itr).hw_buffer_size1;
320 cfgs_itr++;
321 }
322 else
323 {
324 ASSERT(cfgs_itr->buffer1.size_ % 2 == 0);
325 ASSERT(cfgs_itr->buffer2.size_ % 2 == 0);
326
327 auto ep_in = new STM32Endpoint(ep_index, id_, hpcd_, USB::Endpoint::Direction::IN,
328 buffer_offset, (*cfgs_itr).hw_buffer_size1,
329 (*cfgs_itr).buffer1);
330 USB::EndpointPool::Put(ep_in);
331 buffer_offset += (*cfgs_itr).hw_buffer_size1;
332 auto ep_out = new STM32Endpoint(ep_index, id_, hpcd_, USB::Endpoint::Direction::OUT,
333 buffer_offset, (*cfgs_itr).hw_buffer_size2,
334 (*cfgs_itr).buffer2);
335 USB::EndpointPool::Put(ep_out);
336 buffer_offset += (*cfgs_itr).hw_buffer_size2;
337 ep_index = USB::Endpoint::NextEPNumber(ep_index);
338 cfgs_itr++;
339 }
340 }
341
342 ASSERT(USB::Endpoint::EPNumberToInt8(ep_index) < hpcd->Init.dev_endpoints);
343 ASSERT(buffer_offset <= LIBXR_STM32_USB_PMA_SIZE);
344}
345
346ErrorCode STM32USBDeviceDevFs::SetAddress(uint8_t address,
348{
349 HAL_StatusTypeDef ans = HAL_OK;
350
351 if (context == USB::DeviceCore::Context::STATUS_IN_COMPLETE)
352 {
353 ans = HAL_PCD_SetAddress(hpcd_, address);
354 }
355 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
356}
357#endif
358
359#endif
只读原始数据视图 / Immutable raw data view
STM32 USB 端点实现 / STM32 USB endpoint implementation.
STM32 USB 设备核心实现 / STM32 USB device core implementation.
Context
控制传输上下文 / Control transfer context
Definition dev_core.hpp:31
PacketSize0
控制端点0最大包长度枚举 Packet size for endpoint 0 (bMaxPacketSize0)
Definition desc_dev.hpp:75
EPNumber
端点号 Endpoint number
Definition ep.hpp:42
static constexpr uint8_t EPNumberToInt8(EPNumber ep)
端点号转换为 uint8_t / Convert endpoint number to uint8_t
Definition ep.hpp:94
static constexpr EPNumber NextEPNumber(EPNumber ep)
获取下一个端点号 / Get the next endpoint number
Definition ep.hpp:128
void SetEndpoint0(Endpoint *ep0_in, Endpoint *ep0_out)
设置端点0的IN/OUT对象 / Set Endpoint 0 IN/OUT objects
Definition ep_pool.cpp:96
LibXR 命名空间
Definition ch32_can.hpp:14
void STM32_InvalidateDCacheByAddr(const void *addr, size_t size)
Invalidates D-Cache lines covering the specified memory range.
ErrorCode
定义错误码枚举
@ FULL
已满 | Full
USB 标准请求 SETUP 包(固定8字节) Standard USB setup packet (8 bytes)
Definition core.hpp:58