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