libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
ch32_usb_dev.cpp
1#include "ch32_usb_dev.hpp"
2
3#include "ch32_usb_endpoint.hpp"
4#include "ep.hpp"
5
6using namespace LibXR;
7using namespace LibXR::USB;
8
9#if defined(USBFSD)
10
11// NOLINTNEXTLINE
12extern "C" __attribute__((interrupt)) void USBFS_IRQHandler(void)
13{
14 uint8_t intflag = USBFSD->INT_FG; // NOLINT
15 uint8_t intst = USBFSD->INT_ST; // NOLINT
16
17 auto& map = LibXR::CH32EndpointOtgFs::map_otg_fs_;
18
19 if (intflag & USBFS_UIF_TRANSFER)
20 {
21 uint8_t token = intst & USBFS_UIS_TOKEN_MASK;
22 uint8_t epnum = intst & USBFS_UIS_ENDP_MASK;
23
24 auto ep = map[epnum];
25 USBFSD->INT_FG = USBFS_UIF_TRANSFER; // NOLINT
26
27 if (ep)
28 {
29 switch (token)
30 {
31 case USBFS_UIS_TOKEN_SETUP:
32 USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK; // NOLINT
33 USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_NAK; // NOLINT
34 LibXR::CH32EndpointOtgFs::map_otg_fs_[0][0]->tog_ = true;
35 LibXR::CH32EndpointOtgFs::map_otg_fs_[0][1]->tog_ = true;
36
37 map[0][0]->SetState(Endpoint::State::IDLE);
38 map[0][1]->SetState(Endpoint::State::IDLE);
39
40 LibXR::CH32USBDeviceFS::self_->OnSetupPacket(
41 true, reinterpret_cast<const SetupPacket*>(
42 LibXR::CH32EndpointOtgFs::map_otg_fs_[0][0]->GetBuffer().addr_));
43 break;
44
45 case USBFS_UIS_TOKEN_OUT:
46 {
47 uint16_t len = USBFSD->RX_LEN; // NOLINT
48 ep[static_cast<uint8_t>(Endpoint::Direction::OUT)]->TransferComplete(len);
49 break;
50 }
51 case USBFS_UIS_TOKEN_IN:
52 {
53 ep[static_cast<uint8_t>(Endpoint::Direction::IN)]->TransferComplete(0);
54 break;
55 }
56
57 // 其他情况略
58 default:
59 break;
60 }
61 }
62 }
63 else if (intflag & USBFS_UIF_BUS_RST)
64 {
65 USBFSD->INT_FG = USBFS_UIF_BUS_RST; // NOLINT
66 USBFSD->DEV_ADDR = 0; // NOLINT
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; // NOLINT
74 USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_NAK; // NOLINT
75 }
76 else if (intflag & USBFS_UIF_SUSPEND)
77 {
78 USBFSD->INT_FG = USBFS_UIF_SUSPEND; // NOLINT
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; // NOLINT
86 USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_NAK; // NOLINT
87 }
88 else
89 {
90 USBFSD->INT_FG = intflag; // NOLINT
91 }
92}
93
94CH32USBDeviceFS::CH32USBDeviceFS(
95 const std::initializer_list<EPConfig> EP_CFGS,
96 USB::DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid,
97 uint16_t bcd,
98 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
99 const std::initializer_list<const std::initializer_list<USB::ConfigDescriptorItem*>>
100 CONFIGS,
101 ConstRawData uid)
102 : USB::EndpointPool(EP_CFGS.size() * 2),
103 USB::DeviceCore(*this, USB::USBSpec::USB_2_0, USB::Speed::FULL, packet_size, vid,
104 pid, bcd, LANG_LIST, CONFIGS, uid)
105{
106 self_ = this;
107 ASSERT(EP_CFGS.size() > 0 && EP_CFGS.size() <= CH32EndpointOtgFs::EP_OTG_FS_MAX_SIZE);
108
109 auto cfgs_itr = EP_CFGS.begin();
110
111 auto ep0_out =
112 new CH32EndpointOtgFs(USB::Endpoint::EPNumber::EP0, USB::Endpoint::Direction::OUT,
113 cfgs_itr->buffer, false);
114 auto ep0_in =
115 new CH32EndpointOtgFs(USB::Endpoint::EPNumber::EP0, USB::Endpoint::Direction::IN,
116 cfgs_itr->buffer, false);
117
118 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
119
120 USB::Endpoint::EPNumber ep_index = USB::Endpoint::EPNumber::EP1;
121
122 for (++cfgs_itr, ep_index = USB::Endpoint::EPNumber::EP1; cfgs_itr != EP_CFGS.end();
123 ++cfgs_itr, ep_index = USB::Endpoint::NextEPNumber(ep_index))
124 {
125 if (cfgs_itr->is_in == -1)
126 {
127 auto ep_out = new CH32EndpointOtgFs(ep_index, USB::Endpoint::Direction::OUT,
128 cfgs_itr->buffer, false);
129 USB::EndpointPool::Put(ep_out);
130
131 auto ep_in = new CH32EndpointOtgFs(ep_index, USB::Endpoint::Direction::IN,
132 cfgs_itr->buffer, false);
133 USB::EndpointPool::Put(ep_in);
134 }
135 else
136 {
137 auto ep = new CH32EndpointOtgFs(
138 ep_index,
139 cfgs_itr->is_in ? USB::Endpoint::Direction::IN : USB::Endpoint::Direction::OUT,
140 cfgs_itr->buffer, true);
141 USB::EndpointPool::Put(ep);
142 }
143 }
144}
145
146ErrorCode CH32USBDeviceFS::SetAddress(uint8_t address, USB::DeviceCore::Context context)
147{
148 if (context == USB::DeviceCore::Context::STATUS_IN)
149 {
150 USBFSD->DEV_ADDR = (USBFSD->DEV_ADDR & USBFS_UDA_GP_BIT) | address; // NOLINT
151 USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK; // NOLINT
152 USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_ACK; // NOLINT
153 }
154 return ErrorCode::OK;
155}
156
157void CH32USBDeviceFS::Start()
158{
159 USBFSH->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL; // NOLINT
160 USBFSH->BASE_CTRL = 0x00; // NOLINT
161 USBFSD->INT_EN = USBFS_UIE_SUSPEND | USBFS_UIE_BUS_RST | USBFS_UIE_TRANSFER; // NOLINT
162 USBFSD->BASE_CTRL = USBFS_UC_DEV_PU_EN | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN; // NOLINT
163 USBFSD->UDEV_CTRL = USBFS_UD_PD_DIS | USBFS_UD_PORT_EN; // NOLINT
164 NVIC_EnableIRQ(USBFS_IRQn);
165}
166
167void CH32USBDeviceFS::Stop()
168{
169 USBFSH->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL; // NOLINT
170 USBFSD->BASE_CTRL = 0x00; // NOLINT
171 NVIC_DisableIRQ(USBFS_IRQn);
172}
173
174#endif
175#if defined(USBHSD)
176// NOLINTNEXTLINE
177extern "C" __attribute__((interrupt)) void USBHS_IRQHandler(void)
178{
179 uint8_t intflag = USBHSD->INT_FG; // NOLINT
180 uint8_t intst = USBHSD->INT_ST; // NOLINT
181
182 auto& map = LibXR::CH32EndpointOtgHs::map_otg_hs_;
183
184 if (intflag & USBHS_UIF_TRANSFER)
185 {
186 uint8_t token = intst & USBHS_UIS_TOKEN_MASK;
187 uint8_t epnum = intst & USBHS_UIS_ENDP_MASK;
188
189 auto ep = map[epnum];
190
191 if (ep)
192 {
193 switch (token)
194 {
195 case USBHS_UIS_TOKEN_SETUP:
196 USBHSD->INT_FG = USBHS_UIF_TRANSFER; // NOLINT
197
198 USBHSD->UEP0_TX_CTRL = USBHS_UEP_T_RES_NAK | USBHS_UEP_T_TOG_DATA1; // NOLINT
199 USBHSD->UEP0_RX_CTRL = USBHS_UEP_T_RES_NAK | USBHS_UEP_R_TOG_DATA1; // NOLINT
200 map[0][0]->SetState(Endpoint::State::IDLE);
201 map[0][1]->SetState(Endpoint::State::IDLE);
202
203 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog0_ = true;
204 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog0_ = true;
205 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog1_ = false;
206 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog1_ = false;
207
208 LibXR::CH32USBDeviceHS::self_->OnSetupPacket(
209 true, reinterpret_cast<const SetupPacket*>(
210 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->GetBuffer().addr_));
211 break;
212
213 case USBHS_UIS_TOKEN_OUT:
214 {
215 USBHSD->INT_FG = USBHS_UIF_TRANSFER; // NOLINT
216
217 uint16_t len = USBHSD->RX_LEN; // NOLINT
218 ep[static_cast<uint8_t>(Endpoint::Direction::OUT)]->TransferComplete(len);
219 break;
220 }
221 case USBHS_UIS_TOKEN_IN:
222 {
223 ep[static_cast<uint8_t>(Endpoint::Direction::IN)]->TransferComplete(0);
224 break;
225 }
226 case USBHS_UIS_TOKEN_SOF:
227 default:
228 break;
229 }
230 }
231 }
232 else if (intflag & USBHS_UIF_SETUP_ACT)
233 {
234 USBHSD->UEP0_TX_CTRL = USBHS_UEP_T_TOG_DATA1 | USBHS_UEP_T_RES_NAK; // NOLINT
235 USBHSD->UEP0_RX_CTRL = USBHS_UEP_R_TOG_DATA1 | USBHS_UEP_T_RES_NAK; // NOLINT
236
237 map[0][0]->SetState(Endpoint::State::IDLE);
238 map[0][1]->SetState(Endpoint::State::IDLE);
239
240 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog0_ = true;
241 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog0_ = true;
242 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog1_ = false;
243 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog1_ = false;
244
245 LibXR::CH32USBDeviceHS::self_->OnSetupPacket(
246 true, reinterpret_cast<const SetupPacket*>(
247 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->GetBuffer().addr_));
248 USBHSD->INT_FG = USBHS_UIF_SETUP_ACT; // NOLINT
249 }
250 else if (intflag & USBHS_UIF_BUS_RST)
251 {
252 USBHSD->INT_FG = USBHS_UIF_BUS_RST; // NOLINT
253 USBHSD->DEV_AD = 0; // NOLINT
254 LibXR::CH32USBDeviceHS::self_->Deinit();
255 LibXR::CH32USBDeviceHS::self_->Init();
256 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog0_ = true;
257 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog0_ = true;
258 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog1_ = false;
259 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog1_ = false;
260 USBHSD->UEP0_TX_CTRL = USBHS_UEP_T_TOG_DATA1 | USBHS_UEP_T_RES_NAK; // NOLINT
261 USBHSD->UEP0_RX_CTRL = USBHS_UEP_R_TOG_DATA1 | USBHS_UEP_R_RES_NAK; // NOLINT
262
263 map[0][0]->SetState(Endpoint::State::IDLE);
264 map[0][1]->SetState(Endpoint::State::IDLE);
265 }
266 else if (intflag & USBHS_UIF_SUSPEND)
267 {
268 USBHSD->INT_FG = USBHS_UIF_SUSPEND; // NOLINT
269 LibXR::CH32USBDeviceHS::self_->Deinit();
270 LibXR::CH32USBDeviceHS::self_->Init();
271 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog0_ = true;
272 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog0_ = true;
273 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][0]->tog1_ = false;
274 LibXR::CH32EndpointOtgHs::map_otg_hs_[0][1]->tog1_ = false;
275 USBHSD->UEP0_TX_CTRL = USBHS_UEP_T_TOG_DATA1 | USBHS_UEP_T_RES_NAK; // NOLINT
276 USBHSD->UEP0_RX_CTRL = USBHS_UEP_R_TOG_DATA1 | USBHS_UEP_R_RES_NAK; // NOLINT
277
278 map[0][0]->SetState(Endpoint::State::IDLE);
279 map[0][1]->SetState(Endpoint::State::IDLE);
280 }
281 else
282 {
283 USBHSD->INT_FG = intflag; // NOLINT
284 }
285}
286
287CH32USBDeviceHS::CH32USBDeviceHS(
288 const std::initializer_list<CH32USBDeviceHS::EPConfig> EP_CFGS, uint16_t vid,
289 uint16_t pid, uint16_t bcd,
290 const std::initializer_list<const USB::DescriptorStrings::LanguagePack*> LANG_LIST,
291 const std::initializer_list<const std::initializer_list<USB::ConfigDescriptorItem*>>
292 CONFIGS,
293 ConstRawData uid)
294 : USB::EndpointPool(EP_CFGS.size() * 2),
295 USB::DeviceCore(*this, USB::USBSpec::USB_2_0, USB::Speed::HIGH,
296 USB::DeviceDescriptor::PacketSize0::SIZE_64, vid, pid, bcd,
297 LANG_LIST, CONFIGS, uid)
298{
299 self_ = this;
300 ASSERT(EP_CFGS.size() > 0 && EP_CFGS.size() <= CH32EndpointOtgHs::EP_OTG_HS_MAX_SIZE);
301
302 auto cfgs_itr = EP_CFGS.begin();
303
304 // EP0 必须 IN+OUT 共用同一个缓冲(64 Byte)
305 ASSERT(cfgs_itr->buffer_tx.size_ == 64 && cfgs_itr->double_buffer == false);
306
307 auto ep0_out =
308 new CH32EndpointOtgHs(USB::Endpoint::EPNumber::EP0, USB::Endpoint::Direction::OUT,
309 cfgs_itr->buffer_rx, false);
310 auto ep0_in =
311 new CH32EndpointOtgHs(USB::Endpoint::EPNumber::EP0, USB::Endpoint::Direction::IN,
312 cfgs_itr->buffer_tx, false);
313
314 USB::EndpointPool::SetEndpoint0(ep0_in, ep0_out);
315
316 USB::Endpoint::EPNumber ep_index = USB::Endpoint::EPNumber::EP1;
317
318 for (++cfgs_itr, ep_index = USB::Endpoint::EPNumber::EP1; cfgs_itr != EP_CFGS.end();
319 ++cfgs_itr, ep_index = USB::Endpoint::NextEPNumber(ep_index))
320 {
321 if (!cfgs_itr->double_buffer)
322 {
323 auto ep_out = new CH32EndpointOtgHs(ep_index, USB::Endpoint::Direction::OUT,
324 cfgs_itr->buffer_rx, false);
325 USB::EndpointPool::Put(ep_out);
326
327 auto ep_in = new CH32EndpointOtgHs(ep_index, USB::Endpoint::Direction::IN,
328 cfgs_itr->buffer_tx, false);
329 USB::EndpointPool::Put(ep_in);
330 }
331 else
332 {
333 auto ep = new CH32EndpointOtgHs(
334 ep_index,
335 cfgs_itr->is_in ? USB::Endpoint::Direction::IN : USB::Endpoint::Direction::OUT,
336 cfgs_itr->buffer_tx, true);
337 USB::EndpointPool::Put(ep);
338 }
339 }
340}
341
342ErrorCode CH32USBDeviceHS::SetAddress(uint8_t address, USB::DeviceCore::Context context)
343{
344 if (context == USB::DeviceCore::Context::STATUS_IN)
345 {
346 USBHSD->DEV_AD = address; // NOLINT
347 }
348 return ErrorCode::OK;
349}
350
351void CH32USBDeviceHS::Start()
352{
353 // NOLINTBEGIN
354 USBHSD->CONTROL = USBHS_UC_CLR_ALL | USBHS_UC_RESET_SIE;
355 USBHSD->CONTROL &= ~USBHS_UC_RESET_SIE;
356 USBHSD->HOST_CTRL = USBHS_UH_PHY_SUSPENDM;
357 USBHSD->CONTROL = USBHS_UC_DMA_EN | USBHS_UC_INT_BUSY | USBHS_UC_SPEED_HIGH;
358 USBHSD->INT_EN = USBHS_UIE_SETUP_ACT | USBHS_UIE_TRANSFER | USBHS_UIE_DETECT |
359 USBHS_UIE_SUSPEND | USBHS_UIE_ISO_ACT;
360 USBHSD->CONTROL |= USBHS_UC_DEV_PU_EN;
361 NVIC_EnableIRQ(USBHS_IRQn);
362 // NOLINTEND
363}
364
365void CH32USBDeviceHS::Stop()
366{
367 // NOLINTBEGIN
368 USBHSD->CONTROL = USBHS_UC_CLR_ALL | USBHS_UC_RESET_SIE;
369 USBHSD->CONTROL = 0;
370 NVIC_DisableIRQ(USBHS_IRQn);
371 // NOLINTEND
372}
373
374#endif
常量原始数据封装类。 A class for encapsulating constant raw data.
USB 设备协议栈核心类,负责端点 0 控制传输及配置、描述符、标准请求处理等。 USB device protocol stack core class. Handles EP0 control tr...
Definition dev_core.hpp:136
Context
控制传输状态枚举 / Control transfer context enum
Definition dev_core.hpp:142
USB描述符基类 USB descriptor base class.
Definition desc_dev.hpp:37
PacketSize0
控制端点0最大包长度枚举 Packet size for endpoint 0 (bMaxPacketSize0)
Definition desc_dev.hpp:72
EPNumber
端点号 Endpoint number
Definition ep.hpp:41
static constexpr EPNumber NextEPNumber(EPNumber ep)
获取下一个端点号 / Get the next endpoint number
Definition ep.hpp:127
USB端点池类 / USB endpoint pool class.
Definition ep_pool.hpp:23
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