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 ConstRawData uid)
105 : STM32USBDevice(hpcd, STM32_USB_OTG_FS, RX_EP_CFGS.size() + TX_EP_CFGS.size(),
106 packet_size, vid, pid, bcd, LANG_LIST, CONFIGS, uid)
107{
108 ASSERT(RX_EP_CFGS.size() > 0 && RX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_FS_MAX_SIZE);
109 ASSERT(TX_EP_CFGS.size() > 0 && TX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_FS_MAX_SIZE);
110 ASSERT(64 * RX_EP_CFGS.size() <= rx_fifo_size);
111
112 auto rx_cfgs_itr = RX_EP_CFGS.begin();
113 auto tx_cfgs_itr = TX_EP_CFGS.begin();
114
115 auto ep0_in = new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
116 USB::Endpoint::Direction::IN, (*tx_cfgs_itr).fifo_size,
117 (*tx_cfgs_itr).buffer);
118
119 auto ep0_out =
120 new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
121 USB::Endpoint::Direction::OUT, rx_fifo_size, (*rx_cfgs_itr));
122
123 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
124
125 rx_cfgs_itr++;
126 tx_cfgs_itr++;
127
128 USB::Endpoint::EPNumber rx_ep_index = USB::Endpoint::EPNumber::EP1;
129
130 size_t fifo_used_size = rx_fifo_size;
131
132 for (; rx_cfgs_itr != RX_EP_CFGS.end(); rx_cfgs_itr++)
133 {
134 auto ep = new STM32Endpoint(rx_ep_index, id_, hpcd_, USB::Endpoint::Direction::OUT,
135 rx_fifo_size, (*rx_cfgs_itr));
136 USB::EndpointPool::Put(ep);
137 rx_ep_index = USB::Endpoint::NextEPNumber(rx_ep_index);
138 }
139
140 USB::Endpoint::EPNumber tx_ep_index = USB::Endpoint::EPNumber::EP1;
141
142 for (; tx_cfgs_itr != TX_EP_CFGS.end(); tx_cfgs_itr++)
143 {
144 auto ep = new STM32Endpoint(tx_ep_index, id_, hpcd_, USB::Endpoint::Direction::IN,
145 (*tx_cfgs_itr).fifo_size, (*tx_cfgs_itr).buffer);
146 USB::EndpointPool::Put(ep);
147 tx_ep_index = USB::Endpoint::NextEPNumber(tx_ep_index);
148 fifo_used_size += (*tx_cfgs_itr).fifo_size;
149 }
150
151 if (fifo_used_size > USB_OTG_FS_TOTAL_FIFO_SIZE)
152 {
153 ASSERT(false);
154 }
155}
156
157ErrorCode STM32USBDeviceOtgFS::SetAddress(uint8_t address,
159{
160 HAL_StatusTypeDef ans = HAL_OK;
161
162 if (context == USB::DeviceCore::Context::SETUP)
163 {
164 ans = HAL_PCD_SetAddress(hpcd_, address);
165 }
166 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
167}
168
169#endif
170
171#if (defined(USB_OTG_HS))
172
173STM32USBDeviceOtgHS::STM32USBDeviceOtgHS(
174 PCD_HandleTypeDef *hpcd, size_t rx_fifo_size,
175 const std::initializer_list<LibXR::RawData> RX_EP_CFGS,
176 const std::initializer_list<EPInConfig> TX_EP_CFGS,
177 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
178 uint16_t bcd,
179 const std::initializer_list<const USB::DescriptorStrings::LanguagePack *> LANG_LIST,
180 const std::initializer_list<const std::initializer_list<USB::ConfigDescriptorItem *>>
181 CONFIGS,
182 ConstRawData uid)
184 hpcd, STM32_USB_OTG_HS, RX_EP_CFGS.size() + TX_EP_CFGS.size(), packet_size, vid,
185 pid, bcd, LANG_LIST, CONFIGS, uid,
186 hpcd->Init.speed == PCD_SPEED_HIGH ? USB::Speed::HIGH : USB::Speed::FULL)
187{
188 ASSERT(RX_EP_CFGS.size() > 0 && RX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_HS_MAX_SIZE);
189 ASSERT(TX_EP_CFGS.size() > 0 && TX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_HS_MAX_SIZE);
190 ASSERT(64 * RX_EP_CFGS.size() <= rx_fifo_size);
191
192 auto rx_cfgs_itr = RX_EP_CFGS.begin();
193 auto tx_cfgs_itr = TX_EP_CFGS.begin();
194
195 auto ep0_in = new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
196 USB::Endpoint::Direction::IN, (*tx_cfgs_itr).fifo_size,
197 (*tx_cfgs_itr).buffer);
198
199 auto ep0_out =
200 new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
201 USB::Endpoint::Direction::OUT, rx_fifo_size, (*rx_cfgs_itr));
202
203 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
204
205 rx_cfgs_itr++;
206 tx_cfgs_itr++;
207
208 USB::Endpoint::EPNumber rx_ep_index = USB::Endpoint::EPNumber::EP1;
209
210 size_t fifo_used_size = rx_fifo_size;
211
212 for (; rx_cfgs_itr != RX_EP_CFGS.end(); rx_cfgs_itr++)
213 {
214 auto ep = new STM32Endpoint(rx_ep_index, id_, hpcd_, USB::Endpoint::Direction::OUT,
215 rx_fifo_size, (*rx_cfgs_itr));
216 USB::EndpointPool::Put(ep);
217 rx_ep_index = USB::Endpoint::NextEPNumber(rx_ep_index);
218 }
219
220 USB::Endpoint::EPNumber tx_ep_index = USB::Endpoint::EPNumber::EP1;
221
222 for (; tx_cfgs_itr != TX_EP_CFGS.end(); tx_cfgs_itr++)
223 {
224 auto ep = new STM32Endpoint(tx_ep_index, id_, hpcd_, USB::Endpoint::Direction::IN,
225 (*tx_cfgs_itr).fifo_size, (*tx_cfgs_itr).buffer);
226 USB::EndpointPool::Put(ep);
227 tx_ep_index = USB::Endpoint::NextEPNumber(tx_ep_index);
228 fifo_used_size += (*tx_cfgs_itr).fifo_size;
229 }
230
231 if (fifo_used_size > USB_OTG_HS_TOTAL_FIFO_SIZE)
232 {
233 ASSERT(false);
234 }
235}
236
237ErrorCode STM32USBDeviceOtgHS::SetAddress(uint8_t address,
239{
240 HAL_StatusTypeDef ans = HAL_OK;
241
242 if (context == USB::DeviceCore::Context::SETUP)
243 {
244 ans = HAL_PCD_SetAddress(hpcd_, address);
245 }
246 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
247}
248
249#endif
250
251#if defined(USB_BASE)
252STM32USBDeviceDevFs::STM32USBDeviceDevFs(
253 PCD_HandleTypeDef *hpcd, const std::initializer_list<EPConfig> EP_CFGS,
254 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
255 uint16_t bcd,
256 const std::initializer_list<const USB::DescriptorStrings::LanguagePack *> LANG_LIST,
257 const std::initializer_list<const std::initializer_list<USB::ConfigDescriptorItem *>>
258 CONFIGS,
259 ConstRawData uid)
260 : STM32USBDevice(hpcd, STM32_USB_FS_DEV, EP_CFGS.size() * 2, packet_size, vid, pid,
261 bcd, LANG_LIST, CONFIGS, uid)
262{
263 ASSERT(EP_CFGS.size() > 0 && EP_CFGS.size() <= hpcd->Init.dev_endpoints);
264
265 auto cfgs_itr = EP_CFGS.begin();
266
267 ASSERT(cfgs_itr->double_buffer == false);
268
269#if defined(PMA_START_ADDR)
270 size_t buffer_offset = PMA_START_ADDR;
271#else
272 size_t buffer_offset = (BTABLE_ADDRESS + hpcd_->Init.dev_endpoints * 8U) * 2; // 字节
273#endif
274
275 auto ep0_out = new STM32Endpoint(
276 USB::Endpoint::EPNumber::EP0, id_, hpcd_, USB::Endpoint::Direction::OUT,
277 buffer_offset, (*cfgs_itr).hw_buffer_size2, false, (*cfgs_itr).buffer2);
278
279 buffer_offset += (*cfgs_itr).hw_buffer_size2;
280
281 auto ep0_in = new STM32Endpoint(
282 USB::Endpoint::EPNumber::EP0, id_, hpcd_, USB::Endpoint::Direction::IN,
283 buffer_offset, (*cfgs_itr).hw_buffer_size1, false, (*cfgs_itr).buffer1);
284
285 buffer_offset += (*cfgs_itr).hw_buffer_size1;
286
287 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
288
289 cfgs_itr++;
290
291 USB::Endpoint::EPNumber ep_index = USB::Endpoint::EPNumber::EP1;
292
293 while (cfgs_itr != EP_CFGS.end())
294 {
295 if (cfgs_itr->hw_buffer_size2 == 0)
296 {
297 ASSERT(cfgs_itr->buffer1.size_ % 2 == 0);
298 auto ep =
299 new STM32Endpoint(ep_index, id_, hpcd_,
300 cfgs_itr->double_buffer_is_in ? USB::Endpoint::Direction::IN
301 : USB::Endpoint::Direction::OUT,
302 buffer_offset, (*cfgs_itr).hw_buffer_size1,
303 (*cfgs_itr).double_buffer, (*cfgs_itr).buffer1);
304 USB::EndpointPool::Put(ep);
305 ep_index = USB::Endpoint::NextEPNumber(ep_index);
306 buffer_offset += (*cfgs_itr).hw_buffer_size1 * 2;
307 cfgs_itr++;
308 }
309 else
310 {
311 ASSERT(cfgs_itr->buffer1.size_ % 2 == 0);
312 ASSERT(cfgs_itr->buffer2.size_ % 2 == 0);
313
314 auto ep_in = new STM32Endpoint(ep_index, id_, hpcd_, USB::Endpoint::Direction::IN,
315 buffer_offset, (*cfgs_itr).hw_buffer_size1, false,
316 (*cfgs_itr).buffer1);
317 USB::EndpointPool::Put(ep_in);
318 buffer_offset += (*cfgs_itr).hw_buffer_size1;
319 auto ep_out = new STM32Endpoint(ep_index, id_, hpcd_, USB::Endpoint::Direction::OUT,
320 buffer_offset, (*cfgs_itr).hw_buffer_size2, false,
321 (*cfgs_itr).buffer2);
322 USB::EndpointPool::Put(ep_out);
323 buffer_offset += (*cfgs_itr).hw_buffer_size2;
324 ep_index = USB::Endpoint::NextEPNumber(ep_index);
325 cfgs_itr++;
326 }
327 }
328
329 ASSERT(USB::Endpoint::EPNumberToInt8(ep_index) <= hpcd->Init.dev_endpoints);
330 ASSERT(buffer_offset <= LIBXR_STM32_USB_PMA_SIZE);
331}
332
333ErrorCode STM32USBDeviceDevFs::SetAddress(uint8_t address,
335{
336 HAL_StatusTypeDef ans = HAL_OK;
337
338 if (context == USB::DeviceCore::Context::STATUS_IN)
339 {
340 ans = HAL_PCD_SetAddress(hpcd_, address);
341 }
342 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
343}
344#endif
345
346#endif
常量原始数据封装类。 A class for encapsulating constant raw data.
Context
控制传输状态枚举 / Control transfer context enum
Definition dev_core.hpp:142
PacketSize0
控制端点0最大包长度枚举 Packet size for endpoint 0 (bMaxPacketSize0)
Definition desc_dev.hpp:72
EPNumber
端点号 Endpoint number
Definition ep.hpp:41
static constexpr uint8_t EPNumberToInt8(EPNumber ep)
端点号转换为 uint8_t / Convert endpoint number to uint8_t
Definition ep.hpp:93
static constexpr EPNumber NextEPNumber(EPNumber ep)
获取下一个端点号 / Get the next endpoint number
Definition ep.hpp:127
void SetEndpoint0(Endpoint *ep0_in, Endpoint *ep0_out)
设置端点0的IN/OUT对象 / Set Endpoint 0 IN/OUT objects
Definition ep_pool.cpp:96
LibXR 命名空间
USB 标准请求 SETUP 包(固定8字节) Standard USB setup packet (8 bytes)
Definition core.hpp:57