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->GetEndpoint0In()->SetState(USB::Endpoint::State::IDLE);
40 usb->GetEndpoint0Out()->SetState(USB::Endpoint::State::IDLE);
41
42 usb->OnSetupPacket(true, reinterpret_cast<USB::SetupPacket*>(hpcd->Setup));
43}
44
45extern "C" void HAL_PCD_ResetCallback(PCD_HandleTypeDef* hpcd)
46{
47 auto id = STM32USBDeviceGetID(hpcd);
48
49 ASSERT(id < STM32_USB_DEV_ID_NUM);
50
51 auto usb = STM32USBDevice::map_[id];
52
53 if (!usb)
54 {
55 return;
56 }
57
58 usb->Deinit(true);
59 usb->Init(true);
60}
61
62extern "C" void HAL_PCD_SuspendCallback(PCD_HandleTypeDef* hpcd)
63{
64 auto id = STM32USBDeviceGetID(hpcd);
65
66 ASSERT(id < STM32_USB_DEV_ID_NUM);
67
68 auto usb = STM32USBDevice::map_[id];
69
70 if (!usb)
71 {
72 return;
73 }
74 usb->Deinit(true);
75}
76
77extern "C" void HAL_PCD_ResumeCallback(PCD_HandleTypeDef* hpcd)
78{
79 auto id = STM32USBDeviceGetID(hpcd);
80
81 ASSERT(id < STM32_USB_DEV_ID_NUM);
82
83 auto usb = STM32USBDevice::map_[id];
84
85 if (!usb)
86 {
87 return;
88 }
89 usb->Init(true);
90}
91
92extern "C" void HAL_PCD_ConnectCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
93
94extern "C" void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
95
96#if (defined(USB_OTG_FS))
97
98STM32USBDeviceOtgFS::STM32USBDeviceOtgFS(
99 PCD_HandleTypeDef* hpcd, size_t rx_fifo_size,
100 const std::initializer_list<LibXR::RawData> RX_EP_CFGS,
101 const std::initializer_list<EPInConfig> TX_EP_CFGS,
102 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
103 uint16_t bcd,
104 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
105 const std::initializer_list<const std::initializer_list<USB::ConfigDescriptorItem*>>
106 CONFIGS,
107 ConstRawData uid)
108 : STM32USBDevice(hpcd, STM32_USB_OTG_FS, RX_EP_CFGS.size() + TX_EP_CFGS.size(),
109 packet_size, vid, pid, bcd, LANG_LIST, CONFIGS, uid)
110{
111 ASSERT(RX_EP_CFGS.size() > 0 && RX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_FS_MAX_SIZE);
112 ASSERT(TX_EP_CFGS.size() > 0 && TX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_FS_MAX_SIZE);
113 ASSERT(64 * RX_EP_CFGS.size() <= rx_fifo_size);
114
115 auto rx_cfgs_itr = RX_EP_CFGS.begin();
116 auto tx_cfgs_itr = TX_EP_CFGS.begin();
117
118 auto ep0_in = new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
119 USB::Endpoint::Direction::IN, (*tx_cfgs_itr).fifo_size,
120 (*tx_cfgs_itr).buffer);
121
122 auto ep0_out =
123 new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
124 USB::Endpoint::Direction::OUT, rx_fifo_size, (*rx_cfgs_itr));
125
126 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
127
128 rx_cfgs_itr++;
129 tx_cfgs_itr++;
130
131 USB::Endpoint::EPNumber rx_ep_index = USB::Endpoint::EPNumber::EP1;
132
133 size_t fifo_used_size = rx_fifo_size;
134
135 for (; rx_cfgs_itr != RX_EP_CFGS.end(); rx_cfgs_itr++)
136 {
137 auto ep = new STM32Endpoint(rx_ep_index, id_, hpcd_, USB::Endpoint::Direction::OUT,
138 rx_fifo_size, (*rx_cfgs_itr));
139 USB::EndpointPool::Put(ep);
140 rx_ep_index = USB::Endpoint::NextEPNumber(rx_ep_index);
141 }
142
143 USB::Endpoint::EPNumber tx_ep_index = USB::Endpoint::EPNumber::EP1;
144
145 for (; tx_cfgs_itr != TX_EP_CFGS.end(); tx_cfgs_itr++)
146 {
147 auto ep = new STM32Endpoint(tx_ep_index, id_, hpcd_, USB::Endpoint::Direction::IN,
148 (*tx_cfgs_itr).fifo_size, (*tx_cfgs_itr).buffer);
149 USB::EndpointPool::Put(ep);
150 tx_ep_index = USB::Endpoint::NextEPNumber(tx_ep_index);
151 fifo_used_size += (*tx_cfgs_itr).fifo_size;
152 }
153
154 if (fifo_used_size > USB_OTG_FS_TOTAL_FIFO_SIZE)
155 {
156 ASSERT(false);
157 }
158}
159
160ErrorCode STM32USBDeviceOtgFS::SetAddress(uint8_t address,
162{
163 HAL_StatusTypeDef ans = HAL_OK;
164
165 if (context == USB::DeviceCore::Context::SETUP)
166 {
167 ans = HAL_PCD_SetAddress(hpcd_, address);
168 }
169 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
170}
171
172#endif
173
174#if (defined(USB_OTG_HS))
175
176STM32USBDeviceOtgHS::STM32USBDeviceOtgHS(
177 PCD_HandleTypeDef* hpcd, size_t rx_fifo_size,
178 const std::initializer_list<LibXR::RawData> RX_EP_CFGS,
179 const std::initializer_list<EPInConfig> TX_EP_CFGS,
180 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
181 uint16_t bcd,
182 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
183 const std::initializer_list<const std::initializer_list<USB::ConfigDescriptorItem*>>
184 CONFIGS,
185 ConstRawData uid)
187 hpcd, STM32_USB_OTG_HS, RX_EP_CFGS.size() + TX_EP_CFGS.size(), packet_size, vid,
188 pid, bcd, LANG_LIST, CONFIGS, uid,
189 hpcd->Init.speed == PCD_SPEED_HIGH ? USB::Speed::HIGH : USB::Speed::FULL)
190{
191 ASSERT(RX_EP_CFGS.size() > 0 && RX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_HS_MAX_SIZE);
192 ASSERT(TX_EP_CFGS.size() > 0 && TX_EP_CFGS.size() <= STM32Endpoint::EP_OTG_HS_MAX_SIZE);
193 ASSERT(64 * RX_EP_CFGS.size() <= rx_fifo_size);
194
195 auto rx_cfgs_itr = RX_EP_CFGS.begin();
196 auto tx_cfgs_itr = TX_EP_CFGS.begin();
197
198 auto ep0_in = new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
199 USB::Endpoint::Direction::IN, (*tx_cfgs_itr).fifo_size,
200 (*tx_cfgs_itr).buffer);
201
202 auto ep0_out =
203 new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
204 USB::Endpoint::Direction::OUT, rx_fifo_size, (*rx_cfgs_itr));
205
206 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
207
208 rx_cfgs_itr++;
209 tx_cfgs_itr++;
210
211 USB::Endpoint::EPNumber rx_ep_index = USB::Endpoint::EPNumber::EP1;
212
213 size_t fifo_used_size = rx_fifo_size;
214
215 for (; rx_cfgs_itr != RX_EP_CFGS.end(); rx_cfgs_itr++)
216 {
217 auto ep = new STM32Endpoint(rx_ep_index, id_, hpcd_, USB::Endpoint::Direction::OUT,
218 rx_fifo_size, (*rx_cfgs_itr));
219 USB::EndpointPool::Put(ep);
220 rx_ep_index = USB::Endpoint::NextEPNumber(rx_ep_index);
221 }
222
223 USB::Endpoint::EPNumber tx_ep_index = USB::Endpoint::EPNumber::EP1;
224
225 for (; tx_cfgs_itr != TX_EP_CFGS.end(); tx_cfgs_itr++)
226 {
227 auto ep = new STM32Endpoint(tx_ep_index, id_, hpcd_, USB::Endpoint::Direction::IN,
228 (*tx_cfgs_itr).fifo_size, (*tx_cfgs_itr).buffer);
229 USB::EndpointPool::Put(ep);
230 tx_ep_index = USB::Endpoint::NextEPNumber(tx_ep_index);
231 fifo_used_size += (*tx_cfgs_itr).fifo_size;
232 }
233
234 if (fifo_used_size > USB_OTG_HS_TOTAL_FIFO_SIZE)
235 {
236 ASSERT(false);
237 }
238}
239
240ErrorCode STM32USBDeviceOtgHS::SetAddress(uint8_t address,
242{
243 HAL_StatusTypeDef ans = HAL_OK;
244
245 if (context == USB::DeviceCore::Context::SETUP)
246 {
247 ans = HAL_PCD_SetAddress(hpcd_, address);
248 }
249 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
250}
251
252#endif
253
254#if defined(USB_BASE)
255STM32USBDeviceDevFs::STM32USBDeviceDevFs(
256 PCD_HandleTypeDef* hpcd, const std::initializer_list<EPConfig> EP_CFGS,
257 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
258 uint16_t bcd,
259 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
260 const std::initializer_list<const std::initializer_list<USB::ConfigDescriptorItem*>>
261 CONFIGS,
262 ConstRawData uid)
263 : STM32USBDevice(hpcd, STM32_USB_FS_DEV, EP_CFGS.size() * 2, packet_size, vid, pid,
264 bcd, LANG_LIST, CONFIGS, uid)
265{
266 ASSERT(EP_CFGS.size() > 0 && EP_CFGS.size() <= hpcd->Init.dev_endpoints);
267
268 auto cfgs_itr = EP_CFGS.begin();
269
270#if defined(PMA_START_ADDR)
271 size_t buffer_offset = PMA_START_ADDR;
272#else
273 size_t buffer_offset = BTABLE_ADDRESS + hpcd_->Init.dev_endpoints * 8U; // 字节
274#endif
275
276 auto ep0_out = new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
277 USB::Endpoint::Direction::OUT, buffer_offset,
278 (*cfgs_itr).hw_buffer_size2, (*cfgs_itr).buffer2);
279
280 buffer_offset += (*cfgs_itr).hw_buffer_size2;
281
282 auto ep0_in = new STM32Endpoint(USB::Endpoint::EPNumber::EP0, id_, hpcd_,
283 USB::Endpoint::Direction::IN, buffer_offset,
284 (*cfgs_itr).hw_buffer_size1, (*cfgs_itr).buffer1);
285
286 buffer_offset += (*cfgs_itr).hw_buffer_size1;
287
288 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
289
290 cfgs_itr++;
291
292 USB::Endpoint::EPNumber ep_index = USB::Endpoint::EPNumber::EP1;
293
294 while (cfgs_itr != EP_CFGS.end())
295 {
296 if (cfgs_itr->hw_buffer_size2 == 0)
297 {
298 ASSERT(cfgs_itr->buffer1.size_ % 2 == 0);
299 auto ep = new STM32Endpoint(
300 ep_index, id_, hpcd_,
301 cfgs_itr->double_buffer_is_in ? USB::Endpoint::Direction::IN
302 : USB::Endpoint::Direction::OUT,
303 buffer_offset, (*cfgs_itr).hw_buffer_size1, (*cfgs_itr).buffer1);
304 USB::EndpointPool::Put(ep);
305 ep_index = USB::Endpoint::NextEPNumber(ep_index);
306 buffer_offset += (*cfgs_itr).hw_buffer_size1;
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,
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,
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.
STM32 USB 端点实现 / STM32 USB endpoint implementation.
STM32 USB 设备核心实现 / STM32 USB device core implementation.
Context
控制传输上下文 / Control transfer context
Definition dev_core.hpp:188
PacketSize0
控制端点0最大包长度枚举 Packet size for endpoint 0 (bMaxPacketSize0)
Definition desc_dev.hpp:75
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 命名空间
Definition ch32_can.hpp:14
USB 标准请求 SETUP 包(固定8字节) Standard USB setup packet (8 bytes)
Definition core.hpp:57