1#include "stm32_usb_dev.hpp"
3#if defined(HAL_PCD_MODULE_ENABLED)
7stm32_usb_dev_id_t STM32USBDeviceGetID(PCD_HandleTypeDef* hpcd)
9 for (
int i = 0; i < STM32_USB_DEV_ID_NUM; i++)
11 if (STM32USBDevice::map_[i] && STM32USBDevice::map_[i]->hpcd_ == hpcd)
13 return static_cast<stm32_usb_dev_id_t
>(i);
16 return STM32_USB_DEV_ID_NUM;
19extern "C" void HAL_PCD_SOFCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
21extern "C" void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef* hpcd)
23 auto id = STM32USBDeviceGetID(hpcd);
25 ASSERT(
id < STM32_USB_DEV_ID_NUM);
27 auto usb = STM32USBDevice::map_[id];
34#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
35 SCB_InvalidateDCache_by_Addr(hpcd->Setup,
39 usb->GetEndpoint0In()->SetState(USB::Endpoint::State::IDLE);
40 usb->GetEndpoint0Out()->SetState(USB::Endpoint::State::IDLE);
45extern "C" void HAL_PCD_ResetCallback(PCD_HandleTypeDef* hpcd)
47 auto id = STM32USBDeviceGetID(hpcd);
49 ASSERT(
id < STM32_USB_DEV_ID_NUM);
51 auto usb = STM32USBDevice::map_[id];
62extern "C" void HAL_PCD_SuspendCallback(PCD_HandleTypeDef* hpcd)
64 auto id = STM32USBDeviceGetID(hpcd);
66 ASSERT(
id < STM32_USB_DEV_ID_NUM);
68 auto usb = STM32USBDevice::map_[id];
77extern "C" void HAL_PCD_ResumeCallback(PCD_HandleTypeDef* hpcd)
79 auto id = STM32USBDeviceGetID(hpcd);
81 ASSERT(
id < STM32_USB_DEV_ID_NUM);
83 auto usb = STM32USBDevice::map_[id];
92extern "C" void HAL_PCD_ConnectCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
94extern "C" void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef* hpcd) { UNUSED(hpcd); }
96#if (defined(USB_OTG_FS))
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,
104 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
105 const std::initializer_list<
const std::initializer_list<USB::ConfigDescriptorItem*>>
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)
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);
115 auto rx_cfgs_itr = RX_EP_CFGS.begin();
116 auto tx_cfgs_itr = TX_EP_CFGS.begin();
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);
124 USB::Endpoint::Direction::OUT, rx_fifo_size, (*rx_cfgs_itr));
133 size_t fifo_used_size = rx_fifo_size;
135 for (; rx_cfgs_itr != RX_EP_CFGS.end(); rx_cfgs_itr++)
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);
145 for (; tx_cfgs_itr != TX_EP_CFGS.end(); tx_cfgs_itr++)
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);
151 fifo_used_size += (*tx_cfgs_itr).fifo_size;
154 if (fifo_used_size > USB_OTG_FS_TOTAL_FIFO_SIZE)
160ErrorCode STM32USBDeviceOtgFS::SetAddress(uint8_t address,
163 HAL_StatusTypeDef ans = HAL_OK;
165 if (context == USB::DeviceCore::Context::SETUP)
167 ans = HAL_PCD_SetAddress(hpcd_, address);
169 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
174#if (defined(USB_OTG_HS))
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,
182 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
183 const std::initializer_list<
const std::initializer_list<USB::ConfigDescriptorItem*>>
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)
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);
195 auto rx_cfgs_itr = RX_EP_CFGS.begin();
196 auto tx_cfgs_itr = TX_EP_CFGS.begin();
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);
204 USB::Endpoint::Direction::OUT, rx_fifo_size, (*rx_cfgs_itr));
213 size_t fifo_used_size = rx_fifo_size;
215 for (; rx_cfgs_itr != RX_EP_CFGS.end(); rx_cfgs_itr++)
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);
225 for (; tx_cfgs_itr != TX_EP_CFGS.end(); tx_cfgs_itr++)
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);
231 fifo_used_size += (*tx_cfgs_itr).fifo_size;
234 if (fifo_used_size > USB_OTG_HS_TOTAL_FIFO_SIZE)
240ErrorCode STM32USBDeviceOtgHS::SetAddress(uint8_t address,
243 HAL_StatusTypeDef ans = HAL_OK;
245 if (context == USB::DeviceCore::Context::SETUP)
247 ans = HAL_PCD_SetAddress(hpcd_, address);
249 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
255STM32USBDeviceDevFs::STM32USBDeviceDevFs(
256 PCD_HandleTypeDef* hpcd,
const std::initializer_list<EPConfig> EP_CFGS,
259 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
260 const std::initializer_list<
const std::initializer_list<USB::ConfigDescriptorItem*>>
263 :
STM32USBDevice(hpcd, STM32_USB_FS_DEV, EP_CFGS.size() * 2, packet_size, vid, pid,
264 bcd, LANG_LIST, CONFIGS, uid)
266 ASSERT(EP_CFGS.size() > 0 && EP_CFGS.size() <= hpcd->Init.dev_endpoints);
268 auto cfgs_itr = EP_CFGS.begin();
270#if defined(PMA_START_ADDR)
271 size_t buffer_offset = PMA_START_ADDR;
273 size_t buffer_offset = BTABLE_ADDRESS + hpcd_->Init.dev_endpoints * 8U;
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);
280 buffer_offset += (*cfgs_itr).hw_buffer_size2;
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);
286 buffer_offset += (*cfgs_itr).hw_buffer_size1;
294 while (cfgs_itr != EP_CFGS.end())
296 if (cfgs_itr->hw_buffer_size2 == 0)
298 ASSERT(cfgs_itr->buffer1.size_ % 2 == 0);
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);
306 buffer_offset += (*cfgs_itr).hw_buffer_size1;
311 ASSERT(cfgs_itr->buffer1.size_ % 2 == 0);
312 ASSERT(cfgs_itr->buffer2.size_ % 2 == 0);
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;
330 ASSERT(buffer_offset <= LIBXR_STM32_USB_PMA_SIZE);
333ErrorCode STM32USBDeviceDevFs::SetAddress(uint8_t address,
336 HAL_StatusTypeDef ans = HAL_OK;
338 if (context == USB::DeviceCore::Context::STATUS_IN)
340 ans = HAL_PCD_SetAddress(hpcd_, address);
342 return (ans == HAL_OK) ? ErrorCode::OK : ErrorCode::FAILED;
常量原始数据封装类。 A class for encapsulating constant raw data.
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
USB 标准请求 SETUP 包(固定8字节) Standard USB setup packet (8 bytes)