1#include "stm32_usb_dev.hpp"
3#include "stm32_dcache.hpp"
4#if defined(HAL_PCD_MODULE_ENABLED)
8stm32_usb_dev_id_t STM32USBDeviceGetID(PCD_HandleTypeDef* hpcd)
10 for (
int i = 0; i < STM32_USB_DEV_ID_NUM; i++)
12 if (STM32USBDevice::map_[i] && STM32USBDevice::map_[i]->hpcd_ == hpcd)
14 return static_cast<stm32_usb_dev_id_t
>(i);
17 return STM32_USB_DEV_ID_NUM;
20extern "C" void HAL_PCD_SOFCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
22extern "C" void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef* hpcd)
24 auto id = STM32USBDeviceGetID(hpcd);
26 if (
id >= STM32_USB_DEV_ID_NUM)
31 auto usb = STM32USBDevice::map_[id];
38 if (STM32USBUsesDma(hpcd))
43 usb->GetEndpoint0In()->SetState(USB::Endpoint::State::IDLE);
44 usb->GetEndpoint0Out()->SetState(USB::Endpoint::State::IDLE);
49extern "C" void HAL_PCD_ResetCallback(PCD_HandleTypeDef* hpcd)
51 auto id = STM32USBDeviceGetID(hpcd);
53 if (
id >= STM32_USB_DEV_ID_NUM)
58 auto usb = STM32USBDevice::map_[id];
69extern "C" void HAL_PCD_SuspendCallback(PCD_HandleTypeDef* hpcd)
71 auto id = STM32USBDeviceGetID(hpcd);
73 if (
id >= STM32_USB_DEV_ID_NUM)
78 auto usb = STM32USBDevice::map_[id];
87extern "C" void HAL_PCD_ResumeCallback(PCD_HandleTypeDef* hpcd)
89 auto id = STM32USBDeviceGetID(hpcd);
91 if (
id >= STM32_USB_DEV_ID_NUM)
96 auto usb = STM32USBDevice::map_[id];
105extern "C" void HAL_PCD_ConnectCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
107extern "C" void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
109#if (defined(USB_OTG_FS))
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,
117 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
118 const std::initializer_list<
const std::initializer_list<USB::ConfigDescriptorItem*>>
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)
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);
128 auto rx_cfgs_itr = RX_EP_CFGS.begin();
129 auto tx_cfgs_itr = TX_EP_CFGS.begin();
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);
137 USB::Endpoint::Direction::OUT, rx_fifo_size, (*rx_cfgs_itr));
146 size_t fifo_used_size = rx_fifo_size;
148 for (; rx_cfgs_itr != RX_EP_CFGS.end(); rx_cfgs_itr++)
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);
158 for (; tx_cfgs_itr != TX_EP_CFGS.end(); tx_cfgs_itr++)
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);
164 fifo_used_size += (*tx_cfgs_itr).fifo_size;
167 if (fifo_used_size > USB_OTG_FS_TOTAL_FIFO_SIZE)
173ErrorCode STM32USBDeviceOtgFS::SetAddress(uint8_t address,
176 HAL_StatusTypeDef ans = HAL_OK;
178 if (context == USB::DeviceCore::Context::STATUS_IN_ARMED)
180 ans = HAL_PCD_SetAddress(hpcd_, address);
182 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
187#if (defined(USB_OTG_HS))
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,
195 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
196 const std::initializer_list<
const std::initializer_list<USB::ConfigDescriptorItem*>>
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)
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);
208 auto rx_cfgs_itr = RX_EP_CFGS.begin();
209 auto tx_cfgs_itr = TX_EP_CFGS.begin();
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);
217 USB::Endpoint::Direction::OUT, rx_fifo_size, (*rx_cfgs_itr));
226 size_t fifo_used_size = rx_fifo_size;
228 for (; rx_cfgs_itr != RX_EP_CFGS.end(); rx_cfgs_itr++)
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);
238 for (; tx_cfgs_itr != TX_EP_CFGS.end(); tx_cfgs_itr++)
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);
244 fifo_used_size += (*tx_cfgs_itr).fifo_size;
247 if (fifo_used_size > USB_OTG_HS_TOTAL_FIFO_SIZE)
253ErrorCode STM32USBDeviceOtgHS::SetAddress(uint8_t address,
256 HAL_StatusTypeDef ans = HAL_OK;
258 if (context == USB::DeviceCore::Context::STATUS_IN_ARMED)
260 ans = HAL_PCD_SetAddress(hpcd_, address);
262 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
268STM32USBDeviceDevFs::STM32USBDeviceDevFs(
269 PCD_HandleTypeDef* hpcd,
const std::initializer_list<EPConfig> EP_CFGS,
272 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
273 const std::initializer_list<
const std::initializer_list<USB::ConfigDescriptorItem*>>
276 :
STM32USBDevice(hpcd, STM32_USB_FS_DEV, EP_CFGS.size() * 2, packet_size, vid, pid,
277 bcd, LANG_LIST, CONFIGS, uid)
279 ASSERT(EP_CFGS.size() > 0 && EP_CFGS.size() <= hpcd->Init.dev_endpoints);
281 auto cfgs_itr = EP_CFGS.begin();
283#if defined(PMA_START_ADDR)
284 size_t buffer_offset = PMA_START_ADDR;
286 size_t buffer_offset = BTABLE_ADDRESS + hpcd_->Init.dev_endpoints * 8U;
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);
293 buffer_offset += (*cfgs_itr).hw_buffer_size2;
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);
299 buffer_offset += (*cfgs_itr).hw_buffer_size1;
307 while (cfgs_itr != EP_CFGS.end())
309 if (cfgs_itr->hw_buffer_size2 == 0)
311 ASSERT(cfgs_itr->buffer1.size_ % 2 == 0);
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);
319 buffer_offset += (*cfgs_itr).hw_buffer_size1;
324 ASSERT(cfgs_itr->buffer1.size_ % 2 == 0);
325 ASSERT(cfgs_itr->buffer2.size_ % 2 == 0);
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;
343 ASSERT(buffer_offset <= LIBXR_STM32_USB_PMA_SIZE);
346ErrorCode STM32USBDeviceDevFs::SetAddress(uint8_t address,
349 HAL_StatusTypeDef ans = HAL_OK;
351 if (context == USB::DeviceCore::Context::STATUS_IN_COMPLETE)
353 ans = HAL_PCD_SetAddress(hpcd_, address);
355 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
只读原始数据视图 / Immutable raw data view
STM32 USB 端点实现 / STM32 USB endpoint implementation.
STM32 USB 设备核心实现 / STM32 USB device core implementation.
Context
控制传输上下文 / Control transfer context
PacketSize0
控制端点0最大包长度枚举 Packet size for endpoint 0 (bMaxPacketSize0)
EPNumber
端点号 Endpoint number
static constexpr uint8_t EPNumberToInt8(EPNumber ep)
端点号转换为 uint8_t / Convert endpoint number to uint8_t
static constexpr EPNumber NextEPNumber(EPNumber ep)
获取下一个端点号 / Get the next endpoint number
void SetEndpoint0(Endpoint *ep0_in, Endpoint *ep0_out)
设置端点0的IN/OUT对象 / Set Endpoint 0 IN/OUT objects
void STM32_InvalidateDCacheByAddr(const void *addr, size_t size)
Invalidates D-Cache lines covering the specified memory range.
USB 标准请求 SETUP 包(固定8字节) Standard USB setup packet (8 bytes)