libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
dev_core.cpp
1#include "dev_core.hpp"
2
3using namespace LibXR::USB;
4
6 EndpointPool &ep_pool, USBSpec spec, Speed speed,
7 DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid, uint16_t bcd,
8 const std::initializer_list<const DescriptorStrings::LanguagePack *> &lang_list,
9 const std::initializer_list<const std::initializer_list<ConfigDescriptorItem *>>
10 &configs)
11 : config_desc_(ep_pool, configs),
12 device_desc_(spec, packet_size, vid, pid, bcd, config_desc_.GetConfigNum()),
13 strings_(lang_list),
14 endpoint_({ep_pool, nullptr, nullptr, {}, {}}),
15 state_({false, speed, Context::UNKNOW, Context::UNKNOW, 0xFF, nullptr, false})
16{
17 ASSERT(IsValidUSBCombination(spec, speed, packet_size));
18
19 endpoint_.ep0_in_cb =
20 LibXR::Callback<LibXR::ConstRawData &>::Create(OnEP0InCompleteStatic, this);
21
22 endpoint_.ep0_out_cb =
23 LibXR::Callback<LibXR::ConstRawData &>::Create(OnEP0OutCompleteStatic, this);
24}
25
28{
29 self->OnEP0OutComplete(in_isr, data);
30}
31
34{
35 self->OnEP0InComplete(in_isr, data);
36}
37
38bool DeviceCore::IsValidUSBCombination(USBSpec spec, Speed speed,
40{
41 const uint8_t SIZE = static_cast<uint8_t>(packet_size);
42
43 switch (speed)
44 {
45 case Speed::LOW:
46 // USB 1.0/1.1 可允许 LOW,包长必须为 8
47 return (spec == USBSpec::USB_1_0 || spec == USBSpec::USB_1_1) && SIZE == 8;
48
49 case Speed::FULL:
50 // USB 1.x/2.0 均可运行在 FULL
51 if (!(spec >= USBSpec::USB_1_0 && spec <= USBSpec::USB_2_1))
52 {
53 return false;
54 }
55 return SIZE == 8 || SIZE == 16 || SIZE == 32 || SIZE == 64;
56
57 case Speed::HIGH:
58 // 只有 USB 2.0+ 才能跑 HIGH,包长必须是 64
59 if (spec < USBSpec::USB_2_0)
60 {
61 return false;
62 }
63 return SIZE == 64;
64
65 case Speed::SUPER: // NOLINT
66 case Speed::SUPER_PLUS:
67 return false;
68
69 default:
70 return false;
71 }
72}
73
75{
76 state_.out0 = context;
77 endpoint_.out0->TransferZLP();
78}
79
81{
82 state_.in0 = context;
83 endpoint_.in0->TransferZLP();
84}
85
87{
88 endpoint_.in0 = endpoint_.pool.GetEndpoint0In();
89 endpoint_.out0 = endpoint_.pool.GetEndpoint0Out();
90
91 endpoint_.in0->Configure({Endpoint::Direction::IN, Endpoint::Type::CONTROL, 64});
92 endpoint_.out0->Configure({Endpoint::Direction::OUT, Endpoint::Type::CONTROL, 64});
93
94 endpoint_.in0->SetOnTransferCompleteCallback(endpoint_.ep0_in_cb);
95 endpoint_.out0->SetOnTransferCompleteCallback(endpoint_.ep0_out_cb);
96
98
99 state_.inited = true;
100}
101
103{
104 state_.inited = false;
106 endpoint_.in0->Close();
107 endpoint_.out0->Close();
108}
109
111{
112 if (!state_.inited)
113 {
114 return;
115 }
116 auto status = this->state_.out0;
117 state_.out0 = Context::UNKNOW;
118
119 switch (status)
120 {
121 case Context::ZLP:
123 break;
125 if (data.size_ > 0)
126 {
127 LibXR::Memory::FastCopy(state_.out0_buffer, data.addr_, data.size_);
128 }
129
130 if (state_.read_remain.size_ > 0)
131 {
132 state_.out0_buffer += data.size_;
133 DevReadEP0Data(state_.read_remain, endpoint_.out0->MaxTransferSize());
134 }
135 else if (class_req_.read)
136 {
137 class_req_.read = false;
138 class_req_.class_ptr->OnClassData(in_isr, class_req_.b_request, data);
139 WriteZLP();
140 }
141 else
142 {
143 WriteZLP();
144 }
145 break;
146 default:
148 break;
149 }
150}
151
153{
154 if (!state_.inited)
155 {
156 return;
157 }
158 UNUSED(in_isr);
159 UNUSED(data);
160
161 auto status = state_.in0;
162
163 state_.in0 = Context::UNKNOW;
164
165 switch (status)
166 {
167 case Context::ZLP:
168 break;
170 if (state_.pending_addr != 0xFF)
171 {
172 SetAddress(state_.pending_addr, Context::STATUS_IN);
173 state_.pending_addr = 0xFF;
174 }
175 break;
176 case Context::DATA_IN:
177 if (state_.write_remain.size_ > 0)
178 {
179 DevWriteEP0Data(state_.write_remain, endpoint_.in0->MaxTransferSize());
180 }
181 else if (state_.need_write_zlp)
182 {
183 state_.need_write_zlp = false;
184 ReadZLP();
185 WriteZLP();
186 }
187 else if (class_req_.write)
188 {
189 class_req_.write = false;
190 class_req_.class_ptr->OnClassData(in_isr, class_req_.b_request, data);
191 }
192 break;
193 default:
195 break;
196 }
197}
198
199void DeviceCore::DevWriteEP0Data(LibXR::ConstRawData data, size_t packet_max_length,
200 size_t request_size)
201{
202 state_.in0 = Context::DATA_IN;
203
204 // 限制最大传输长度
205 if (request_size > 0 && request_size < data.size_)
206 {
207 data.size_ = request_size;
208 }
209
210 // 数据长度为 0,直接 STALL(协议层面不允许)
211 if (data.size_ == 0 || data.size_ > 0xFFFF)
212 {
214 return;
215 }
216
217 // 判断是否需要拆包或发送 ZLP
218 bool has_more = data.size_ > packet_max_length;
219
220 // 拆分数据包
221 if (has_more)
222 {
223 state_.write_remain = {
224 reinterpret_cast<const uint8_t *>(data.addr_) + packet_max_length,
225 data.size_ - packet_max_length};
226 data.size_ = packet_max_length;
227 state_.need_write_zlp = false;
228 }
229 else
230 {
231 state_.write_remain = {nullptr, 0};
232 state_.need_write_zlp = data.size_ % endpoint_.in0->MaxPacketSize() == 0;
233 }
234
235 auto buffer = endpoint_.in0->GetBuffer();
236 ASSERT(buffer.size_ >= data.size_);
237 LibXR::Memory::FastCopy(buffer.addr_, data.addr_, data.size_);
238
239 // 如果一次就能结束,并且不需要 ZLP,直接准备状态阶段 OUT
240 if (!has_more && !state_.need_write_zlp)
241 {
242 ReadZLP();
243 }
244
245 endpoint_.in0->Transfer(data.size_);
246}
247
248void DeviceCore::DevReadEP0Data(LibXR::RawData data, size_t packet_max_length)
249{
250 state_.out0 = Context::DATA_OUT;
251
252 // 限制最大接收长度
253 if (data.size_ == 0 || data.size_ > 0xFFFF)
254 {
256 return;
257 }
258
259 // 数据长度 <= 一个包长,直接收一次即可
260 if (data.size_ <= packet_max_length)
261 {
262 state_.read_remain = {nullptr, 0}; // 标记本次已收完
263 }
264 else
265 {
266 // 数据需要多包接收
267 state_.read_remain = {reinterpret_cast<uint8_t *>(data.addr_) + packet_max_length,
268 data.size_ - packet_max_length};
269 data.size_ = packet_max_length;
270 }
271
272 state_.out0_buffer = reinterpret_cast<uint8_t *>(data.addr_);
273 endpoint_.out0->Transfer(data.size_); // 一次性收满,HAL/底层自动搞定多包
274}
275
276void DeviceCore::OnSetupPacket(bool in_isr, const SetupPacket *setup)
277{
278 if (!state_.inited)
279 {
280 return;
281 }
282 RequestDirection direction =
283 static_cast<RequestDirection>(setup->bmRequestType & REQ_DIRECTION_MASK);
284 RequestType type = static_cast<RequestType>(setup->bmRequestType & REQ_TYPE_MASK);
285 Recipient recipient = static_cast<Recipient>(setup->bmRequestType & REQ_RECIPIENT_MASK);
286
287 if (endpoint_.in0->IsStalled())
288 {
289 endpoint_.in0->ClearStall();
290 }
291
292 if (endpoint_.out0->IsStalled())
293 {
294 endpoint_.out0->ClearStall();
295 }
296
297 ErrorCode ans = ErrorCode::OK;
298
299 switch (type)
300 {
301 case RequestType::STANDARD:
302 ans = ProcessStandardRequest(in_isr, setup, direction, recipient);
303 break;
304 case RequestType::CLASS:
305 ans = ProcessClassRequest(in_isr, setup, direction, recipient);
306 break;
307 case RequestType::VENDOR:
308 ans = ProcessVendorRequest(in_isr, setup, direction, recipient);
309 break;
310 default:
311 ans = ErrorCode::ARG_ERR;
312 break;
313 }
314
315 if (ans != ErrorCode::OK)
316 {
318 }
319}
320
321ErrorCode DeviceCore::ProcessStandardRequest(bool in_isr, const SetupPacket *&setup,
322 RequestDirection direction,
323 Recipient recipient)
324{
325 UNUSED(in_isr);
326 UNUSED(direction);
327 UNUSED(recipient);
328 // 根据 recipient 处理不同目标的请求
329 StandardRequest req = static_cast<StandardRequest>(setup->bRequest);
330
331 ErrorCode ans = ErrorCode::OK;
332
333 switch (req)
334 {
335 case StandardRequest::GET_STATUS:
336 // 设备/接口/端点的状态请求
337 ans = RespondWithStatus(setup, recipient);
338 break;
339 case StandardRequest::CLEAR_FEATURE:
340 // 解除某个特性(如端点的HALT)
341 ans = ClearFeature(setup, recipient);
342 break;
343 case StandardRequest::SET_FEATURE:
344 // 设置特性(如Remote Wakeup/端点STALL)
345 ans = ApplyFeature(setup, recipient);
346 break;
347 case StandardRequest::SET_ADDRESS:
348 // 设置USB地址,status阶段后生效
349 ans = PrepareAddressChange(setup->wValue);
350 break;
351 case StandardRequest::GET_DESCRIPTOR:
352 // 返回设备/配置/字符串等描述符
353 ans = SendDescriptor(in_isr, setup, recipient);
354 break;
355 case StandardRequest::SET_DESCRIPTOR:
356 // TODO: 很少用,可选实现
357 break;
358 case StandardRequest::GET_CONFIGURATION:
359 // 返回当前配置
360 ans = SendConfiguration();
361 break;
362 case StandardRequest::SET_CONFIGURATION:
363 // 设置当前配置(切换Config描述符索引)
364 ans = SwitchConfiguration(setup->wValue);
365 break;
366 case StandardRequest::GET_INTERFACE:
367 {
368 if (recipient != Recipient::INTERFACE)
369 {
370 ans = ErrorCode::ARG_ERR;
371 break;
372 }
373
374 uint8_t interface_index = static_cast<uint8_t>(setup->wIndex & 0xFF);
375
376 uint8_t alt = 0;
377 auto item = config_desc_.GetItemByInterfaceNum(interface_index);
378
379 if (item != nullptr)
380 {
381 item->GetAltSetting(interface_index, alt);
382 }
383 else
384 {
385 ans = ErrorCode::NOT_FOUND;
386 break;
387 }
388
389 DevWriteEP0Data(LibXR::ConstRawData(&alt, 1), endpoint_.in0->MaxTransferSize(), 1);
390
391 return ErrorCode::OK;
392 }
393 case StandardRequest::SET_INTERFACE:
394 {
395 if (recipient != Recipient::INTERFACE)
396 {
397 ans = ErrorCode::ARG_ERR;
398 break;
399 }
400
401 uint8_t interface_index = static_cast<uint8_t>(setup->wIndex & 0xFF);
402 uint8_t alt_setting = static_cast<uint8_t>(setup->wValue);
403
404 auto item = config_desc_.GetItemByInterfaceNum(interface_index);
405 if (item == nullptr)
406 {
407 ans = ErrorCode::NOT_FOUND;
408 break;
409 }
410
411 ans = item->SetAltSetting(interface_index, alt_setting);
412 break;
413 }
414 case StandardRequest::SYNCH_FRAME:
415 // TODO: 一般仅用于同步端点
416 ans = ErrorCode::NOT_SUPPORT;
417 break;
418 default:
419 // 未知请求,直接STALL
420 ans = ErrorCode::ARG_ERR;
421 }
422
423 return ans;
424}
425
426ErrorCode DeviceCore::RespondWithStatus(const SetupPacket *setup, Recipient recipient)
427{
428 if (setup->wLength != 2)
429 {
430 return ErrorCode::ARG_ERR;
431 }
432
433 uint16_t status = 0;
434 switch (recipient)
435 {
436 case Recipient::DEVICE:
437 status = config_desc_.GetDeviceStatus();
438 break;
439 case Recipient::INTERFACE:
440 status = 0x0000;
441 break;
442 case Recipient::ENDPOINT:
443 {
444 uint8_t ep_addr = setup->wIndex & 0xFF;
445 Endpoint *ep = nullptr;
446 endpoint_.pool.FindEndpoint(ep_addr, ep);
447
448 if (ep == nullptr)
449 {
450 return ErrorCode::NOT_FOUND;
451 }
452
454 {
455 status = 0x0001;
456 }
457 break;
458 }
459 default:
460 return ErrorCode::ARG_ERR;
461 }
462
463 LibXR::ConstRawData data(&status, 2);
464 DevWriteEP0Data(data, endpoint_.in0->MaxTransferSize(), setup->wLength);
465
466 return ErrorCode::OK;
467}
468
469ErrorCode DeviceCore::ClearFeature(const SetupPacket *setup, Recipient recipient)
470{
471 switch (recipient)
472 {
473 case Recipient::ENDPOINT:
474 {
475 // 只允许清除 ENDPOINT_HALT 特性(wValue==0)
476 if (setup->wValue == 0) // 0 = ENDPOINT_HALT
477 {
478 uint8_t ep_addr = setup->wIndex & 0xFF; // 端点号(低7位=EP号, 高位=方向)
479 // 清除端点STALL
480 Endpoint *ep = nullptr;
481 endpoint_.pool.FindEndpoint(ep_addr, ep);
482 if (ep)
483 {
484 ep->ClearStall();
485 // 状态阶段:回复ZLP
486 WriteZLP();
487 }
488 else
489 {
490 return ErrorCode::NOT_FOUND;
491 }
492 }
493 else
494 {
495 return ErrorCode::ARG_ERR;
496 }
497 break;
498 }
499 case Recipient::DEVICE:
500 // 可选:处理Remote Wakeup等设备级特性
501 if (setup->wValue == 1) // 1 = DEVICE_REMOTE_WAKEUP
502 {
504 WriteZLP();
505 }
506 else
507 {
508 return ErrorCode::ARG_ERR;
509 }
510 break;
511 default:
512 return ErrorCode::ARG_ERR;
513 }
514
515 return ErrorCode::OK;
516}
517
518ErrorCode DeviceCore::ApplyFeature(const SetupPacket *setup, Recipient recipient)
519{
520 switch (recipient)
521 {
522 case Recipient::ENDPOINT:
523 {
524 if (setup->wValue == 0) // 0 = ENDPOINT_HALT
525 {
526 uint8_t ep_addr = setup->wIndex & 0xFF;
527 // 设置端点STALL
528 Endpoint *ep = nullptr;
529 endpoint_.pool.FindEndpoint(ep_addr, ep);
530 if (ep)
531 {
532 ep->Stall(); // 设置端点STALL
533 // 状态阶段回复ZLP
534 WriteZLP();
535 }
536 else
537 {
538 return ErrorCode::NOT_FOUND;
539 }
540 }
541 else
542 {
543 return ErrorCode::ARG_ERR;
544 }
545 break;
546 }
547 case Recipient::DEVICE:
548 if (setup->wValue == 1) // 1 = DEVICE_REMOTE_WAKEUP
549 {
551 WriteZLP();
552 }
553 else
554 {
555 return ErrorCode::ARG_ERR;
556 }
557 break;
558 default:
559 return ErrorCode::ARG_ERR;
560 }
561
562 return ErrorCode::OK;
563}
564
565ErrorCode DeviceCore::SendDescriptor(bool in_isr, const SetupPacket *setup,
566 Recipient recipient)
567{
568 uint8_t desc_type = (setup->wValue >> 8) & 0xFF;
569 uint8_t desc_idx = (setup->wValue) & 0xFF;
570 ConstRawData data = {nullptr, 0};
571 switch (desc_type)
572 {
573 case 0x01: // DEVICE
574 data = device_desc_.GetData();
576 {
578 }
579 break;
580 case 0x02: // CONFIGURATION
582 data = config_desc_.GetData();
583 break;
584 case 0x03: // STRING
585 {
586 uint8_t string_idx = desc_idx;
587 uint16_t lang = setup->wIndex;
588 if (string_idx == 0)
589 {
590 data = strings_.GetLangIDData();
591 }
592 else
593 {
594 ErrorCode ec = strings_.GenerateString(
595 static_cast<DescriptorStrings::Index>(string_idx), lang);
596 if (ec != ErrorCode::OK)
597 {
598 return ec;
599 }
600 data = strings_.GetData();
601 }
602 break;
603 }
604 case 0x06: // Device Qualifier (USB 2.0+)
605 // TODO: Device Qualifier HS Only
606 case 0x07: // Other Speed Configurations
607 return ErrorCode::NOT_SUPPORT;
608 default:
609 {
610 uint8_t intf_num = 0;
611
612 if (recipient == Recipient::INTERFACE)
613 {
614 intf_num = setup->wIndex & 0xFF;
615 }
616 else
617 {
618 return ErrorCode::ARG_ERR;
619 }
620
621 auto *item =
622 reinterpret_cast<DeviceClass *>(config_desc_.GetItemByInterfaceNum(intf_num));
623 if (item && item->OnGetDescriptor(in_isr, setup->bRequest, setup->wValue,
624 setup->wLength, data) == ErrorCode::OK)
625 {
626 break; // 成功处理
627 }
628 else
629 {
630 return ErrorCode::ARG_ERR;
631 }
632 }
633 }
634
635 DevWriteEP0Data(data, endpoint_.in0->MaxTransferSize(), setup->wLength);
636
637 return ErrorCode::OK;
638}
639
640ErrorCode DeviceCore::PrepareAddressChange(uint16_t address)
641{
642 state_.pending_addr = static_cast<uint8_t>(address & 0x7F);
643
645 return SetAddress(address, Context::SETUP);
646}
647
648ErrorCode DeviceCore::SwitchConfiguration(uint16_t value)
649{
650 if (value == 0) // reset
651 {
652 // TODO: reset
653 return ErrorCode::NOT_SUPPORT;
654 }
655
656 if (config_desc_.SwitchConfig(value) != ErrorCode::OK)
657 {
658 return ErrorCode::NOT_FOUND;
659 }
660 // ACK status阶段
661 WriteZLP();
662
663 return ErrorCode::OK;
664}
665
667{
668 uint8_t cfg = config_desc_.GetCurrentConfig();
669 LibXR::ConstRawData data(&cfg, 1);
670 DevWriteEP0Data(data, endpoint_.in0->MaxTransferSize(), 1);
671
672 return ErrorCode::OK;
673}
674
676{
677 endpoint_.pool.GetEndpoint0Out()->Stall();
678 endpoint_.pool.GetEndpoint0In()->Stall();
679}
680
682{
683 endpoint_.pool.GetEndpoint0Out()->ClearStall();
684 endpoint_.pool.GetEndpoint0In()->ClearStall();
685}
686
687ErrorCode DeviceCore::ProcessClassRequest(bool in_isr, const SetupPacket *setup,
688 RequestDirection direction, Recipient recipient)
689{
690 UNUSED(direction);
691
692 if (recipient != Recipient::INTERFACE)
693 {
694 return ErrorCode::NOT_SUPPORT;
695 }
696
697 uint8_t intf_num = setup->wIndex & 0xFF;
698
699 auto *item =
700 reinterpret_cast<DeviceClass *>(config_desc_.GetItemByInterfaceNum(intf_num));
701 if (!item)
702 {
703 return ErrorCode::NOT_FOUND;
704 }
705
707
708 auto ans = item->OnClassRequest(in_isr, setup->bRequest, setup->wValue, setup->wLength,
709 result);
710
711 if (ans != ErrorCode::OK)
712 {
713 return ans;
714 }
715
716 if (result.read_data.size_ > 0)
717 {
718 class_req_.read = true;
719 class_req_.class_ptr = item;
720 class_req_.b_request = setup->bRequest;
721 DevReadEP0Data(result.read_data, endpoint_.in0->MaxTransferSize());
722 }
723 else if (result.write_data.size_ > 0)
724 {
725 class_req_.write = true;
726 class_req_.class_ptr = item;
727 class_req_.b_request = setup->bRequest;
728 DevWriteEP0Data(result.write_data, endpoint_.in0->MaxTransferSize());
729 }
730 else if (result.read_zlp)
731 {
732 ReadZLP();
733 }
734 else if (result.write_zlp)
735 {
736 WriteZLP();
737 }
738
739 return ErrorCode::OK;
740}
741
742ErrorCode DeviceCore::ProcessVendorRequest(bool in_isr, const SetupPacket *&setup,
743 RequestDirection direction,
744 Recipient recipient)
745{
746 UNUSED(in_isr);
747 UNUSED(setup);
748 UNUSED(direction);
749 UNUSED(recipient);
750
751 // TODO: 处理厂商自定义请求
752 return ErrorCode::NOT_SUPPORT;
753}
754
755Speed DeviceCore::GetSpeed() const { return state_.speed; }
static Callback Create(FunType fun, ArgType arg)
创建一个新的回调对象,并绑定回调函数和参数。 Creates a new callback instance, binding a function and an argument.
Definition libxr_cb.hpp:142
常量原始数据封装类。 A class for encapsulating constant raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).
static void FastCopy(void *dst, const void *src, size_t size)
快速内存拷贝 / Fast memory copy
Definition libxr_mem.cpp:17
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
bool IsComposite() const
判断是否为复合设备(composite device) Check if this is a composite device
Definition desc_cfg.cpp:159
RawData GetData() const
获取拼接好的配置描述符数据 Get the generated configuration descriptor data
Definition desc_cfg.cpp:178
uint16_t GetDeviceStatus() const
获取当前设备状态 / Get the current device status
Definition desc_cfg.cpp:184
void AssignEndpoints()
分配端点并分配总缓冲区 Assign endpoints and allocate the total config descriptor buffer
Definition desc_cfg.cpp:87
ErrorCode OverrideDeviceDescriptor(DeviceDescriptor &descriptor)
覆盖设备描述符(非IAD时可用) Override the device descriptor (can be used when not using IAD)
Definition desc_cfg.cpp:161
void ReleaseEndpoints()
释放所有功能项占用的端点资源 Release all endpoints/resources allocated by function blocks
Definition desc_cfg.cpp:106
ErrorCode Generate()
生成完整的配置描述符(自动拼接 header 和所有功能项数据) Generate and assemble the full configuration descriptor (header + al...
Definition desc_cfg.cpp:122
size_t GetCurrentConfig() const
获取当前配置值 / Get the current configuration value
Definition desc_cfg.cpp:182
ConfigDescriptorItem * GetItemByInterfaceNum(size_t index) const
获取指定接口的配置项 / Get the configuration item by interface number
Definition desc_cfg.cpp:190
virtual ErrorCode SetAltSetting(uint8_t itf, uint8_t alt)
设置接口的备用设置 Set the alternate setting of an interface
Definition desc_cfg.hpp:134
ErrorCode GenerateString(Index index, uint16_t lang)
生成指定语言和索引的字符串描述符 Generate USB string descriptor for given language and string index
Definition desc_str.cpp:30
RawData GetData()
获取当前构建好的字符串描述符数据 Get the descriptor buffer
Definition desc_str.cpp:63
RawData GetLangIDData()
获取语言ID描述符内容 Get LangID descriptor data
Definition desc_str.cpp:70
Index
描述符字符串索引 / USB descriptor string index
Definition desc_str.hpp:25
USB 设备类接口基类,所有自定义 USB 类(如 HID、CDC、MSC)都需派生自本类。 USB device class base interface, all custom device cla...
Definition dev_core.hpp:22
USB 设备协议栈核心类,负责端点 0 控制传输及配置、描述符、标准请求处理等。 USB device protocol stack core class. Handles EP0 control tr...
Definition dev_core.hpp:108
ErrorCode SwitchConfiguration(uint16_t value)
切换配置 / Switch USB configuration
Definition dev_core.cpp:648
virtual void EnableRemoteWakeup()
启用远程唤醒功能(SetFeature: DEVICE_REMOTE_WAKEUP) Enable remote wakeup (via SetFeature)
Definition dev_core.hpp:314
ConfigDescriptor config_desc_
配置描述符 / Config descriptor
Definition dev_core.hpp:335
static void OnEP0OutCompleteStatic(bool in_isr, DeviceCore *self, LibXR::ConstRawData &data)
EP0 OUT 端点传输完成回调(静态) EP0 OUT endpoint transfer complete (static)
Definition dev_core.cpp:26
ErrorCode PrepareAddressChange(uint16_t address)
预设地址变更 / Prepare address change
Definition dev_core.cpp:640
ErrorCode RespondWithStatus(const SetupPacket *setup, Recipient recipient)
返回状态响应 / Respond with status stage
Definition dev_core.cpp:426
ErrorCode ProcessStandardRequest(bool in_isr, const SetupPacket *&setup, RequestDirection direction, Recipient recipient)
处理标准请求 Process standard USB requests
Definition dev_core.cpp:321
static bool IsValidUSBCombination(USBSpec spec, Speed speed, DeviceDescriptor::PacketSize0 packet_size)
检查 USB 组合是否合法 / Check if USB combination is valid
Definition dev_core.cpp:38
Context
控制传输状态枚举 / Control transfer context enum
Definition dev_core.hpp:114
@ SETUP
SETUP 阶段 / Setup stage.
Definition dev_core.hpp:116
@ UNKNOW
未知 / Unknown
Definition dev_core.hpp:115
@ STATUS_IN
状态 IN 阶段 / Status in stage
Definition dev_core.hpp:120
@ DATA_OUT
数据 OUT 阶段 / Data out stage
Definition dev_core.hpp:117
@ STATUS_OUT
状态 OUT 阶段 / Status out stage
Definition dev_core.hpp:118
@ DATA_IN
数据 IN 阶段 / Data in stage
Definition dev_core.hpp:119
@ ZLP
0 长度包 / Zero-length packet
Definition dev_core.hpp:121
DeviceCore(EndpointPool &ep_pool, USBSpec spec, Speed speed, DeviceDescriptor::PacketSize0 packet_size, uint16_t vid, uint16_t pid, uint16_t bcd, const std::initializer_list< const DescriptorStrings::LanguagePack * > &lang_list, const std::initializer_list< const std::initializer_list< ConfigDescriptorItem * > > &configs)
构造函数 / Constructor
Definition dev_core.cpp:5
void ReadZLP(Context context=Context::ZLP)
接收 0 长度包 / Receive zero-length packet (ZLP)
Definition dev_core.cpp:74
ErrorCode ProcessVendorRequest(bool in_isr, const SetupPacket *&setup, RequestDirection direction, Recipient recipient)
处理厂商请求 / Process vendor-specific request
Definition dev_core.cpp:742
DeviceDescriptor device_desc_
设备描述符 / Device descriptor
Definition dev_core.hpp:336
virtual void Deinit()
反初始化 USB 设备 / Deinitialize USB device
Definition dev_core.cpp:102
void OnEP0InComplete(bool in_isr, LibXR::ConstRawData &data)
EP0 IN 端点传输完成回调 / EP0 IN endpoint transfer complete.
Definition dev_core.cpp:152
Speed GetSpeed() const
获取当前 USB 速度 / Get current USB speed
Definition dev_core.cpp:755
void WriteZLP(Context context=Context::ZLP)
发送 0 长度包 / Send zero-length packet (ZLP)
Definition dev_core.cpp:80
void OnEP0OutComplete(bool in_isr, LibXR::ConstRawData &data)
EP0 OUT 端点传输完成回调 / EP0 OUT endpoint transfer complete.
Definition dev_core.cpp:110
void DevReadEP0Data(LibXR::RawData data, size_t packet_max_length)
接收主机发送的 EP0 数据包 Receive data packet from host via EP0
Definition dev_core.cpp:248
virtual void DisableRemoteWakeup()
禁用远程唤醒功能(ClearFeature: DEVICE_REMOTE_WAKEUP) Disable remote wakeup (via ClearFeature)
Definition dev_core.hpp:320
static void OnEP0InCompleteStatic(bool in_isr, DeviceCore *self, LibXR::ConstRawData &data)
EP0 IN 端点传输完成回调(静态) EP0 IN endpoint transfer complete (static)
Definition dev_core.cpp:32
ErrorCode ClearFeature(const SetupPacket *setup, Recipient recipient)
清除功能特性 / Clear USB feature
Definition dev_core.cpp:469
ErrorCode SendDescriptor(bool in_isr, const SetupPacket *setup, Recipient recipient)
发送描述符 / Send USB descriptor
Definition dev_core.cpp:565
ErrorCode ApplyFeature(const SetupPacket *setup, Recipient recipient)
启用功能特性 / Apply USB feature
Definition dev_core.cpp:518
Speed speed
当前速度 / Current speed
Definition dev_core.hpp:351
DescriptorStrings strings_
字符串描述符管理 / String descriptors
Definition dev_core.hpp:337
ErrorCode ProcessClassRequest(bool in_isr, const SetupPacket *setup, RequestDirection direction, Recipient recipient)
处理类请求 / Process class-specific request
Definition dev_core.cpp:687
void OnSetupPacket(bool in_isr, const SetupPacket *setup)
处理主机发送的 SETUP 包 Handle USB setup packet from host
Definition dev_core.cpp:276
ErrorCode SendConfiguration()
发送配置响应 / Send configuration
Definition dev_core.cpp:666
virtual void Init()
初始化 USB 设备 / Initialize USB device
Definition dev_core.cpp:86
void StallControlEndpoint()
设置控制端点为 STALL / Stall control endpoint
Definition dev_core.cpp:675
void ClearControlEndpointStall()
清除控制端点 STALL / Clear control endpoint stall
Definition dev_core.cpp:681
virtual ErrorCode SetAddress(uint8_t address, Context state)=0
设置设备地址(必须由子类实现) Set device address (must be implemented by subclass)
void DevWriteEP0Data(LibXR::ConstRawData data, size_t packet_max_length, size_t request_size=0)
向主机发送 EP0 数据包 Send data packet to host via EP0
Definition dev_core.cpp:199
PacketSize0
控制端点0最大包长度枚举 Packet size for endpoint 0 (bMaxPacketSize0)
Definition desc_dev.hpp:72
RawData GetData()
获取设备描述符的原始数据指针及长度 Get the raw device descriptor data pointer and length
Definition desc_dev.cpp:24
USB端点基类 / USB Endpoint base class.
Definition ep.hpp:22
virtual ErrorCode Stall()=0
停止端点传输 Stop endpoint transfer
@ IN
输入方向 / IN direction
@ OUT
输出方向 / OUT direction
virtual ErrorCode ClearStall()=0
清除端点停止状态 Clear endpoint stop status
@ CONTROL
控制端点 / Control
@ STALLED
挂起 / Stalled
State GetState() const
获取端点状态 Get endpoint state
Definition ep.hpp:212
USB端点池类 / USB endpoint pool class.
Definition ep_pool.hpp:23
控制请求结果结构体 / Structure for control transfer results
Definition dev_core.hpp:28
RawData read_data
设备返回给主机的数据 / Data to read (to host)
Definition dev_core.hpp:29
bool write_zlp
写操作是否需要发送 0 长度包 / Send ZLP after write
Definition dev_core.hpp:33
ConstRawData write_data
主机写入设备的数据 / Data to write (from host)
Definition dev_core.hpp:30
bool read_zlp
读操作是否需要发送 0 长度包 / Send ZLP after read
Definition dev_core.hpp:32
USB 标准请求 SETUP 包(固定8字节) Standard USB setup packet (8 bytes)
Definition core.hpp:57
uint16_t wIndex
对象索引,如接口号或端点号 / Index (e.g., interface or endpoint)
Definition core.hpp:63
uint16_t wLength
数据阶段长度 / Number of bytes in data stage
Definition core.hpp:64
uint16_t wValue
参数字段,含请求相关值 / Value field (e.g., descriptor type/index)
Definition core.hpp:62
uint8_t bRequest
请求码 / Request code (e.g., GET_DESCRIPTOR)
Definition core.hpp:60