1#include "ch32_usb_dev.hpp"
3#include "ch32_usb_endpoint.hpp"
7using namespace LibXR::USB;
12extern "C" __attribute__((interrupt))
void USBFS_IRQHandler(
void)
14 uint8_t intflag = USBFSD->INT_FG;
15 uint8_t intst = USBFSD->INT_ST;
17 auto& map = LibXR::CH32EndpointOtgFs::map_otg_fs_;
19 if (intflag & USBFS_UIF_TRANSFER)
21 uint8_t token = intst & USBFS_UIS_TOKEN_MASK;
22 uint8_t epnum = intst & USBFS_UIS_ENDP_MASK;
25 USBFSD->INT_FG = USBFS_UIF_TRANSFER;
31 case USBFS_UIS_TOKEN_SETUP:
32 USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
33 USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_NAK;
34 LibXR::CH32EndpointOtgFs::map_otg_fs_[0][0]->tog_ =
true;
35 LibXR::CH32EndpointOtgFs::map_otg_fs_[0][1]->tog_ =
true;
37 map[0][0]->SetState(Endpoint::State::IDLE);
38 map[0][1]->SetState(Endpoint::State::IDLE);
40 LibXR::CH32USBDeviceFS::self_->OnSetupPacket(
42 LibXR::CH32EndpointOtgFs::map_otg_fs_[0][0]->GetBuffer().addr_));
45 case USBFS_UIS_TOKEN_OUT:
47 uint16_t len = USBFSD->RX_LEN;
48 ep[
static_cast<uint8_t
>(Endpoint::Direction::OUT)]->TransferComplete(len);
51 case USBFS_UIS_TOKEN_IN:
53 ep[
static_cast<uint8_t
>(Endpoint::Direction::IN)]->TransferComplete(0);
63 else if (intflag & USBFS_UIF_BUS_RST)
65 USBFSD->INT_FG = USBFS_UIF_BUS_RST;
67 LibXR::CH32USBDeviceFS::self_->Deinit();
68 LibXR::CH32USBDeviceFS::self_->Init();
69 LibXR::CH32EndpointOtgFs::map_otg_fs_[0][0]->tog_ =
true;
70 LibXR::CH32EndpointOtgFs::map_otg_fs_[0][1]->tog_ =
true;
71 map[0][0]->SetState(Endpoint::State::IDLE);
72 map[0][1]->SetState(Endpoint::State::IDLE);
73 USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
74 USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_NAK;
76 else if (intflag & USBFS_UIF_SUSPEND)
78 USBFSD->INT_FG = USBFS_UIF_SUSPEND;
79 LibXR::CH32USBDeviceFS::self_->Deinit();
80 LibXR::CH32USBDeviceFS::self_->Init();
81 LibXR::CH32EndpointOtgFs::map_otg_fs_[0][0]->tog_ =
true;
82 LibXR::CH32EndpointOtgFs::map_otg_fs_[0][1]->tog_ =
true;
83 map[0][0]->SetState(Endpoint::State::IDLE);
84 map[0][1]->SetState(Endpoint::State::IDLE);
85 USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
86 USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_NAK;
90 USBFSD->INT_FG = intflag;
94CH32USBDeviceFS::CH32USBDeviceFS(
95 const std::initializer_list<EPConfig> EP_CFGS,
98 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
99 const std::initializer_list<
const std::initializer_list<USB::ConfigDescriptorItem*>>
102 USB::
DeviceCore(*this, USB::USBSpec::USB_2_0, USB::Speed::FULL, packet_size, vid,
103 pid, bcd, LANG_LIST, CONFIGS)
106 ASSERT(EP_CFGS.size() > 0 && EP_CFGS.size() <= CH32EndpointOtgFs::EP_OTG_FS_MAX_SIZE);
108 auto cfgs_itr = EP_CFGS.begin();
111 new CH32EndpointOtgFs(USB::Endpoint::EPNumber::EP0, USB::Endpoint::Direction::OUT,
112 cfgs_itr->buffer,
false);
114 new CH32EndpointOtgFs(USB::Endpoint::EPNumber::EP0, USB::Endpoint::Direction::IN,
115 cfgs_itr->buffer,
false);
121 for (++cfgs_itr, ep_index = USB::Endpoint::EPNumber::EP1; cfgs_itr != EP_CFGS.end();
124 if (cfgs_itr->is_in == -1)
126 auto ep_out =
new CH32EndpointOtgFs(ep_index, USB::Endpoint::Direction::OUT,
127 cfgs_itr->buffer,
false);
128 USB::EndpointPool::Put(ep_out);
130 auto ep_in =
new CH32EndpointOtgFs(ep_index, USB::Endpoint::Direction::IN,
131 cfgs_itr->buffer,
false);
132 USB::EndpointPool::Put(ep_in);
136 auto ep =
new CH32EndpointOtgFs(
138 cfgs_itr->is_in ? USB::Endpoint::Direction::IN : USB::Endpoint::Direction::OUT,
139 cfgs_itr->buffer,
true);
140 USB::EndpointPool::Put(ep);
147 if (context == USB::DeviceCore::Context::STATUS_IN)
149 USBFSD->DEV_ADDR = (USBFSD->DEV_ADDR & USBFS_UDA_GP_BIT) | address;
150 USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
151 USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_ACK;
153 return ErrorCode::OK;
156void CH32USBDeviceFS::Start()
158 USBFSH->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL;
159 USBFSH->BASE_CTRL = 0x00;
160 USBFSD->INT_EN = USBFS_UIE_SUSPEND | USBFS_UIE_BUS_RST | USBFS_UIE_TRANSFER;
161 USBFSD->BASE_CTRL = USBFS_UC_DEV_PU_EN | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN;
162 USBFSD->UDEV_CTRL = USBFS_UD_PD_DIS | USBFS_UD_PORT_EN;
163 NVIC_EnableIRQ(USBFS_IRQn);
166void CH32USBDeviceFS::Stop()
168 USBFSH->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL;
169 USBFSD->BASE_CTRL = 0x00;
170 NVIC_DisableIRQ(USBFS_IRQn);
176extern "C" __attribute__((interrupt))
void USBHS_IRQHandler(
void)
178 uint8_t intflag = USBHSD->INT_FG;
179 uint8_t intst = USBHSD->INT_ST;
181 auto& map = LibXR::CH32EndpointOtgHs::map_otg_hs_;
183 if (intflag & USBHS_UIF_TRANSFER)
185 uint8_t token = intst & USBHS_UIS_TOKEN_MASK;
186 uint8_t epnum = intst & USBHS_UIS_ENDP_MASK;
188 auto ep = map[epnum];
194 case USBHS_UIS_TOKEN_SETUP:
195 USBHSD->INT_FG = USBHS_UIF_TRANSFER;
197 USBHSD->UEP0_TX_CTRL = USBHS_UEP_T_RES_NAK | USBHS_UEP_T_TOG_DATA1;
198 USBHSD->UEP0_RX_CTRL = USBHS_UEP_T_RES_NAK | USBHS_UEP_R_TOG_DATA1;
199 map[0][0]->SetState(Endpoint::State::IDLE);
200 map[0][1]->SetState(Endpoint::State::IDLE);
202 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog0_ =
true;
203 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog0_ =
true;
204 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog1_ =
false;
205 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog1_ =
false;
207 LibXR::CH32USBDeviceHS::self_->OnSetupPacket(
209 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->GetBuffer().addr_));
212 case USBHS_UIS_TOKEN_OUT:
214 USBHSD->INT_FG = USBHS_UIF_TRANSFER;
216 uint16_t len = USBHSD->RX_LEN;
217 ep[
static_cast<uint8_t
>(Endpoint::Direction::OUT)]->TransferComplete(len);
220 case USBHS_UIS_TOKEN_IN:
222 ep[
static_cast<uint8_t
>(Endpoint::Direction::IN)]->TransferComplete(0);
225 case USBHS_UIS_TOKEN_SOF:
231 else if (intflag & USBHS_UIF_SETUP_ACT)
233 USBHSD->UEP0_TX_CTRL = USBHS_UEP_T_TOG_DATA1 | USBHS_UEP_T_RES_NAK;
234 USBHSD->UEP0_RX_CTRL = USBHS_UEP_R_TOG_DATA1 | USBHS_UEP_T_RES_NAK;
236 map[0][0]->SetState(Endpoint::State::IDLE);
237 map[0][1]->SetState(Endpoint::State::IDLE);
239 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog0_ =
true;
240 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog0_ =
true;
241 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog1_ =
false;
242 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog1_ =
false;
244 LibXR::CH32USBDeviceHS::self_->OnSetupPacket(
246 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->GetBuffer().addr_));
247 USBHSD->INT_FG = USBHS_UIF_SETUP_ACT;
249 else if (intflag & USBHS_UIF_BUS_RST)
251 USBHSD->INT_FG = USBHS_UIF_BUS_RST;
253 LibXR::CH32USBDeviceHS::self_->Deinit();
254 LibXR::CH32USBDeviceHS::self_->Init();
255 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog0_ =
true;
256 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog0_ =
true;
257 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog1_ =
false;
258 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog1_ =
false;
259 USBHSD->UEP0_TX_CTRL = USBHS_UEP_T_TOG_DATA1 | USBHS_UEP_T_RES_NAK;
260 USBHSD->UEP0_RX_CTRL = USBHS_UEP_R_TOG_DATA1 | USBHS_UEP_R_RES_NAK;
262 map[0][0]->SetState(Endpoint::State::IDLE);
263 map[0][1]->SetState(Endpoint::State::IDLE);
265 else if (intflag & USBHS_UIF_SUSPEND)
267 USBHSD->INT_FG = USBHS_UIF_SUSPEND;
268 LibXR::CH32USBDeviceHS::self_->Deinit();
269 LibXR::CH32USBDeviceHS::self_->Init();
270 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog0_ =
true;
271 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog0_ =
true;
272 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog1_ =
false;
273 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog1_ =
false;
274 USBHSD->UEP0_TX_CTRL = USBHS_UEP_T_TOG_DATA1 | USBHS_UEP_T_RES_NAK;
275 USBHSD->UEP0_RX_CTRL = USBHS_UEP_R_TOG_DATA1 | USBHS_UEP_R_RES_NAK;
277 map[0][0]->SetState(Endpoint::State::IDLE);
278 map[0][1]->SetState(Endpoint::State::IDLE);
282 USBHSD->INT_FG = intflag;
286CH32USBDeviceHS::CH32USBDeviceHS(
287 const std::initializer_list<CH32USBDeviceHS::EPConfig> EP_CFGS, uint16_t vid,
288 uint16_t pid, uint16_t bcd,
289 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
290 const std::initializer_list<
const std::initializer_list<USB::ConfigDescriptorItem*>>
293 USB::
DeviceCore(*this, USB::USBSpec::USB_2_0, USB::Speed::HIGH,
298 ASSERT(EP_CFGS.size() > 0 && EP_CFGS.size() <= CH32EndpointOtgHs::EP_OTG_HS_MAX_SIZE);
300 auto cfgs_itr = EP_CFGS.begin();
303 ASSERT(cfgs_itr->buffer_tx.size_ == 64 && cfgs_itr->double_buffer ==
false);
306 new CH32EndpointOtgHs(USB::Endpoint::EPNumber::EP0, USB::Endpoint::Direction::OUT,
307 cfgs_itr->buffer_rx,
false);
309 new CH32EndpointOtgHs(USB::Endpoint::EPNumber::EP0, USB::Endpoint::Direction::IN,
310 cfgs_itr->buffer_tx,
false);
316 for (++cfgs_itr, ep_index = USB::Endpoint::EPNumber::EP1; cfgs_itr != EP_CFGS.end();
319 if (!cfgs_itr->double_buffer)
321 auto ep_out =
new CH32EndpointOtgHs(ep_index, USB::Endpoint::Direction::OUT,
322 cfgs_itr->buffer_rx,
false);
323 USB::EndpointPool::Put(ep_out);
325 auto ep_in =
new CH32EndpointOtgHs(ep_index, USB::Endpoint::Direction::IN,
326 cfgs_itr->buffer_tx,
false);
327 USB::EndpointPool::Put(ep_in);
331 auto ep =
new CH32EndpointOtgHs(
333 cfgs_itr->is_in ? USB::Endpoint::Direction::IN : USB::Endpoint::Direction::OUT,
334 cfgs_itr->buffer_tx,
true);
335 USB::EndpointPool::Put(ep);
342 if (context == USB::DeviceCore::Context::STATUS_IN)
344 USBHSD->DEV_AD = address;
346 return ErrorCode::OK;
349void CH32USBDeviceHS::Start()
352 USBHSD->CONTROL = USBHS_UC_CLR_ALL | USBHS_UC_RESET_SIE;
353 USBHSD->CONTROL &= ~USBHS_UC_RESET_SIE;
354 USBHSD->HOST_CTRL = USBHS_UH_PHY_SUSPENDM;
355 USBHSD->CONTROL = USBHS_UC_DMA_EN | USBHS_UC_INT_BUSY | USBHS_UC_SPEED_HIGH;
356 USBHSD->INT_EN = USBHS_UIE_SETUP_ACT | USBHS_UIE_TRANSFER | USBHS_UIE_DETECT |
357 USBHS_UIE_SUSPEND | USBHS_UIE_ISO_ACT;
358 USBHSD->CONTROL |= USBHS_UC_DEV_PU_EN;
359 NVIC_EnableIRQ(USBHS_IRQn);
363void CH32USBDeviceHS::Stop()
366 USBHSD->CONTROL = USBHS_UC_CLR_ALL | USBHS_UC_RESET_SIE;
368 NVIC_DisableIRQ(USBHS_IRQn);
USB 设备协议栈核心类,负责端点 0 控制传输及配置、描述符、标准请求处理等。 USB device protocol stack core class. Handles EP0 control tr...
Context
控制传输状态枚举 / Control transfer context enum
USB描述符基类 USB descriptor base class.
PacketSize0
控制端点0最大包长度枚举 Packet size for endpoint 0 (bMaxPacketSize0)
EPNumber
端点号 / Endpoint number
static constexpr EPNumber NextEPNumber(EPNumber ep)
获取下一个端点号 / Get the next endpoint number
USB端点池类 / USB endpoint pool class.
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)