libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
hid.hpp
1#pragma once
2#include <cstring>
3
4#include "dev_core.hpp"
5#include "usb/core/desc_cfg.hpp"
6
7namespace LibXR::USB
8{
9
21template <size_t REPORT_DESC_LEN, size_t TX_REPORT_LEN, size_t RX_REPORT_LEN = 0>
22class HID : public DeviceClass
23{
24 public:
26 enum class HIDDescriptorType : uint8_t
27 {
28 HID = 0x21,
29 REPORT = 0x22,
30 PHYSICAL = 0x23
31 };
32
34 enum class ClassRequest : uint8_t
35 {
36 GET_REPORT = 0x01,
37 GET_IDLE = 0x02,
38 GET_PROTOCOL = 0x03,
39 SET_REPORT = 0x09,
40 SET_IDLE = 0x0A,
41 SET_PROTOCOL = 0x0B
42 };
43
45 enum class Protocol : uint8_t
46 {
47 BOOT = 0x00,
48 REPORT = 0x01
49 };
50
52 enum class ReportType : uint8_t
53 {
54 INPUT = 1,
55 OUTPUT = 2,
56 FEATURE = 3
57 };
58
59#pragma pack(push, 1)
75
86
98#pragma pack(pop)
99
110 HID(bool enable_out_endpoint = false, uint8_t in_ep_interval = 10,
111 uint8_t out_ep_interval = 10,
114 : in_ep_interval_(in_ep_interval),
115 out_ep_interval_(out_ep_interval),
116 in_ep_num_(in_ep_num),
117 out_ep_num_(out_ep_num),
118 enable_out_endpoint_(enable_out_endpoint)
119 {
120 }
121
122 protected:
129 void Init(EndpointPool& endpoint_pool, uint8_t start_itf_num) override
130 {
131 inited_ = false;
132 itf_num_ = start_itf_num;
133 ep_in_ = nullptr;
134 ep_out_ = nullptr;
135
136 // 获取IN端点
137 auto ans = endpoint_pool.Get(ep_in_, Endpoint::Direction::IN, in_ep_num_);
138 ASSERT(ans == ErrorCode::OK);
141
143 {
144 ans = endpoint_pool.Get(ep_out_, Endpoint::Direction::OUT, out_ep_num_);
145 ASSERT(ans == ErrorCode::OK);
148 }
149
150 // 填充接口描述符
151 desc_.intf = {
152 9, // bLength
153 static_cast<uint8_t>(DescriptorType::INTERFACE), // bDescriptorType
154 static_cast<uint8_t>(itf_num_), // bInterfaceNumber
155 0, // bAlternateSetting
156 static_cast<uint8_t>(enable_out_endpoint_ ? 2 : 1), // bNumEndpoints
157 0x03, // bInterfaceClass (HID)
158 0x00, // bInterfaceSubClass
159 0x00, // bInterfaceProtocol (可选键盘/鼠标设置1/2)
160 0 // iInterface
161 };
162
163 // 填充HID描述符
164 desc_.hid = {9,
166 0x0111, // HID v1.11
167 0x00, // 国家码
168 0x01, // 只有一个后续描述符(Report Desc)
170 REPORT_DESC_LEN};
171
172 // 填充IN端点描述符
173 desc_.ep_in = {
174 7,
175 static_cast<uint8_t>(DescriptorType::ENDPOINT),
177 static_cast<uint8_t>(Endpoint::Type::INTERRUPT),
178 TX_REPORT_LEN,
179 in_ep_interval_ // 轮询间隔ms
180 };
181
182 // 填充OUT端点描述符(如启用)
184 {
185 desc_.ep_out = {7,
186 static_cast<uint8_t>(DescriptorType::ENDPOINT),
188 static_cast<uint8_t>(Endpoint::Type::INTERRUPT),
189 RX_REPORT_LEN,
191 }
192
193 // 设置最终数据指针
195 {
196 SetData(RawData{reinterpret_cast<uint8_t*>(&desc_), sizeof(HIDDescBlockINOUT)});
197 }
198 else
199 {
200 SetData(RawData{reinterpret_cast<uint8_t*>(&desc_), sizeof(HIDDescBlockIN)});
201 }
202
203 ep_in_->SetOnTransferCompleteCallback(on_data_in_complete_cb_);
204
206 {
207 ep_out_->SetOnTransferCompleteCallback(on_data_out_complete_cb_);
208 ep_out_->Transfer(RX_REPORT_LEN);
209 }
210
211 inited_ = true;
212 }
213
214 static void OnDataOutCompleteStatic(bool in_isr, HID* self, LibXR::ConstRawData& data)
215 {
216 self->OnDataOutComplete(in_isr, data);
217 self->ep_out_->Transfer(RX_REPORT_LEN);
218 }
219
220 static void OnDataInCompleteStatic(bool in_isr, HID* self, LibXR::ConstRawData& data)
221 {
222 self->OnDataInComplete(in_isr, data);
223 }
224
225 virtual void OnDataOutComplete(bool in_isr, LibXR::ConstRawData& data)
226 {
227 UNUSED(in_isr);
228 UNUSED(data);
229 }
230
231 virtual void OnDataInComplete(bool in_isr, LibXR::ConstRawData& data)
232 {
233 UNUSED(in_isr);
234 UNUSED(data);
235 }
236
242 void Deinit(EndpointPool& endpoint_pool) override
243 {
244 inited_ = false;
245 if (ep_in_)
246 {
247 ep_in_->Close();
248 endpoint_pool.Release(ep_in_);
249 ep_in_ = nullptr;
250 }
251 if (ep_out_)
252 {
253 ep_out_->Close();
254 endpoint_pool.Release(ep_out_);
255 ep_out_ = nullptr;
256 }
257 }
258
264 size_t GetInterfaceNum() override { return 1; }
265
273 bool HasIAD() override { return false; }
274
275 bool OwnsEndpoint(uint8_t ep_addr) const override
276 {
277 if (!inited_)
278 {
279 return false;
280 }
281
282 return ep_in_->GetAddress() == ep_addr ||
283 (enable_out_endpoint_ && ep_out_->GetAddress() == ep_addr);
284 }
285
291 size_t GetMaxConfigSize() override
292 {
293 return enable_out_endpoint_ ? sizeof(HIDDescBlockINOUT) : sizeof(HIDDescBlockIN);
294 }
295
307 ErrorCode OnGetDescriptor(bool in_isr, uint8_t bRequest, uint16_t wValue,
308 uint16_t wLength, ConstRawData& need_write) override
309 {
310 UNUSED(in_isr);
311 UNUSED(bRequest);
312
313 uint8_t desc_type = (wValue >> 8) & 0xFF;
314 // uint8_t desc_index = wValue & 0xFF; // 一般为0,暂不需要
315
316 switch (desc_type)
317 {
318 case static_cast<uint8_t>(HIDDescriptorType::HID): // 0x21
319 {
320 // 返回 HID 描述符
321 ConstRawData desc = GetHIDDesc();
322 need_write.addr_ = desc.addr_;
323 need_write.size_ = (wLength < desc.size_) ? wLength : desc.size_;
324 return ErrorCode::OK;
325 }
326 case static_cast<uint8_t>(HIDDescriptorType::REPORT): // 0x22
327 {
328 // 返回 Report Descriptor
330 need_write.addr_ = desc.addr_;
331 need_write.size_ = (wLength < desc.size_) ? wLength : desc.size_;
332 return ErrorCode::OK;
333 }
334 case static_cast<uint8_t>(HIDDescriptorType::PHYSICAL):
335 // 物理描述符(很少用,未实现)
336 default:
337 return ErrorCode::NOT_SUPPORT;
338 }
339 }
340
352 ErrorCode OnClassRequest(bool in_isr, uint8_t bRequest, uint16_t wValue,
353 uint16_t wLength, uint16_t wIndex,
354 DeviceClass::RequestResult& result) override
355 {
356 UNUSED(in_isr);
357 UNUSED(wIndex);
358
359 uint8_t report_id = wValue & 0xFF;
360
361 switch (static_cast<ClassRequest>(bRequest))
362 {
364 {
365 ReportType report_type = static_cast<ReportType>((wValue >> 8) & 0xFF);
366 switch (report_type)
367 {
369 // 查找或生成 Input Report(按你的设备实际逻辑)
370 return OnGetInputReport(report_id, result);
372 // 查找或返回最近收到的 Output Report(通常很少实现GET Output)
373 return OnGetLastOutputReport(report_id, result);
375 // 查找或生成 Feature Report
376 return OnGetFeatureReport(report_id, result);
377 default:
378 return OnCustomClassRequest(in_isr, bRequest, wValue, wLength, result);
379 }
380 }
381
383 if (wLength == 0)
384 {
385 return ErrorCode::ARG_ERR;
386 }
387 // 由OnClassData阶段接收
388 return OnSetReport(report_id, result);
389
391 // 仅支持一个Idle rate
392 if (wLength != 1 || report_id != 0)
393 {
394 return ErrorCode::ARG_ERR;
395 }
396 result.write_data = ConstRawData{&idle_rate_, 1};
397 return ErrorCode::OK;
398
400 if (report_id != 0)
401 {
402 return ErrorCode::ARG_ERR;
403 }
404 idle_rate_ = wValue >> 8;
405 result.write_zlp = true;
406 return ErrorCode::OK;
407
409 result.write_data = ConstRawData{reinterpret_cast<uint8_t*>(&protocol_), 1};
410 return ErrorCode::OK;
411
413 protocol_ = static_cast<Protocol>(wValue & 0xFF);
414 result.write_zlp = true;
415 return ErrorCode::OK;
416
417 default:
418 return ErrorCode::NOT_SUPPORT;
419 }
420 }
421
426 ErrorCode OnClassData(bool in_isr, uint8_t bRequest, LibXR::ConstRawData& data) override
427 {
428 UNUSED(in_isr);
429
430 switch (static_cast<ClassRequest>(bRequest))
431 {
433 {
434 // 通常为 Output Report 或 Feature Report
435 // 你可以区分是 Output 还是 Feature,也可以统一交给
436 // OnSetReportData(推荐如下写法)
437 auto ans = OnSetReportData(in_isr, data);
438 if (ans == ErrorCode::OK)
439 {
440 // 可选:记录最近一次 report id(假定第一个字节是 report id,没有 report id
441 // 就写0)
443 (data.size_ > 0) ? reinterpret_cast<const uint8_t*>(data.addr_)[0] : 0;
444 }
445 return ans;
446 }
447 default:
448 return OnCustomClassData(in_isr, bRequest, data);
449 }
450 }
451
458
465
472 {
473 return ConstRawData{&desc_.hid, sizeof(HIDDescriptor)};
474 }
475
480 virtual ErrorCode OnGetInputReport(uint8_t report_id,
482 {
483 UNUSED(report_id);
484 result.write_data = ConstRawData{nullptr, 0};
485 return ErrorCode::OK;
486 }
487
492 virtual ErrorCode OnGetLastOutputReport(uint8_t report_id,
494 {
495 UNUSED(report_id);
496 result.write_data = ConstRawData{nullptr, 0};
497 return ErrorCode::OK;
498 }
499
504 virtual ErrorCode OnGetFeatureReport(uint8_t report_id,
506 {
507 UNUSED(report_id);
508 result.write_data = ConstRawData{nullptr, 0};
509 return ErrorCode::OK;
510 }
511
523 virtual ErrorCode OnCustomClassRequest(bool in_isr, uint8_t bRequest, uint16_t wValue,
524 uint16_t wLength, RequestResult& result)
525 {
526 UNUSED(in_isr);
527 UNUSED(bRequest);
528 UNUSED(wValue);
529 UNUSED(wLength);
530 UNUSED(result);
531 return ErrorCode::NOT_SUPPORT;
532 }
533
534 virtual ErrorCode OnCustomClassData(bool in_isr, uint8_t bRequest, ConstRawData& data)
535 {
536 UNUSED(in_isr);
537 UNUSED(bRequest);
538 UNUSED(data);
539 return ErrorCode::NOT_SUPPORT;
540 }
541
546 virtual ErrorCode OnSetReport(uint8_t report_id, DeviceClass::RequestResult& result)
547 {
548 UNUSED(report_id);
549 UNUSED(result);
550
551 return ErrorCode::NOT_SUPPORT;
552 }
553
558 virtual ErrorCode OnSetReportData(bool in_isr, ConstRawData& data)
559 {
560 UNUSED(in_isr);
561 UNUSED(data);
562
563 return ErrorCode::OK;
564 }
565
574 {
575 if (!inited_ || !ep_in_)
576 {
577 return ErrorCode::FAILED;
578 }
579 if (!report.addr_ || report.size_ == 0 || report.size_ > TX_REPORT_LEN)
580 {
581 return ErrorCode::ARG_ERR;
582 }
583
585 {
586 return ErrorCode::BUSY;
587 }
588
589 // 数据拷贝到端点缓冲区
590 auto buf = ep_in_->GetBuffer();
591 if (report.size_ > buf.size_)
592 {
593 return ErrorCode::NO_BUFF;
594 }
595
596 LibXR::Memory::FastCopy(buf.addr_, report.addr_, report.size_);
597
598 // 启动端点传输
599 return ep_in_->Transfer(report.size_);
600 }
601
608 uint8_t GetIDLERate() const { return idle_rate_; }
609
617
625
630 bool HasOutEndpoint() const { return enable_out_endpoint_; }
631
632 private:
638 Endpoint* ep_in_ = nullptr;
639 Endpoint* ep_out_ = nullptr;
641 bool inited_ = false;
642 size_t itf_num_;
643
645 uint8_t idle_rate_ = 0;
647 0;
648
649 LibXR::Callback<LibXR::ConstRawData&> on_data_out_complete_cb_ =
650 LibXR::Callback<LibXR::ConstRawData&>::Create(OnDataOutCompleteStatic, this);
651
652 LibXR::Callback<LibXR::ConstRawData&> on_data_in_complete_cb_ =
653 LibXR::Callback<LibXR::ConstRawData&>::Create(OnDataInCompleteStatic, this);
654};
655
656} // namespace LibXR::USB
提供一个通用的回调包装,支持动态参数传递。 Provides a generic callback wrapper, supporting dynamic argument passing.
Definition libxr_cb.hpp:124
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.
void SetData(RawData data)
设置配置项数据 Set configuration item data
Definition desc_cfg.hpp:212
USB 设备类接口基类,所有自定义 USB 类(如 HID、CDC、MSC)都需派生自本类。 USB device class base interface, all custom device cla...
Definition dev_core.hpp:22
USB端点基类 / USB Endpoint base class.
Definition ep.hpp:22
EPNumber
端点号 / Endpoint number
Definition ep.hpp:39
@ EP_AUTO
自动分配端点号 / Auto allocate
uint8_t GetAddress() const
获取端点地址(方向 + 号) Get endpoint address (dir + num)
Definition ep.hpp:199
@ IN
输入方向 / IN direction
@ OUT
输出方向 / OUT direction
void SetOnTransferCompleteCallback(Callback< ConstRawData & > cb)
设置传输完成回调 / Set transfer complete callback
Definition ep.hpp:273
virtual void Configure(const Config &cfg)=0
二次初始化/配置端点协议参数(由Pool/Manager分配后调用) Configure endpoint protocol parameters (call after pool allocation...
@ INTERRUPT
中断端点 / Interrupt
virtual void Close()=0
关闭端点(软禁用/资源复位) Close (soft disable)
State GetState() const
获取端点状态 Get endpoint state
Definition ep.hpp:212
virtual ErrorCode Transfer(size_t size)=0
传输数据 Transfer data
RawData GetBuffer() const
获取端点缓冲区 Get endpoint buffer
Definition ep.hpp:256
USB端点池类 / USB endpoint pool class.
Definition ep_pool.hpp:23
ErrorCode Get(Endpoint *&ep_info, Endpoint::Direction direction, Endpoint::EPNumber ep_num=Endpoint::EPNumber::EP_AUTO)
分配端点 / Allocate endpoint
Definition ep_pool.cpp:11
ErrorCode Release(Endpoint *ep_info)
回收端点 / Release endpoint
Definition ep_pool.cpp:37
USB HID(Human Interface Device)基类,支持可选 OUT 端点、自动生成描述符,适合键盘、鼠标、手柄等扩展。 USB HID (Human Interface Device)...
Definition hid.hpp:23
virtual ConstRawData GetHIDDesc()
获取 HID 描述符 Get HID Descriptor
Definition hid.hpp:471
bool enable_out_endpoint_
是否启用 OUT 端点 / Whether OUT endpoint is enabled
Definition hid.hpp:640
virtual ErrorCode OnGetLastOutputReport(uint8_t report_id, DeviceClass::RequestResult &result)
获取最近一次输出报告 Get last Output Report
Definition hid.hpp:492
virtual ErrorCode OnSetReport(uint8_t report_id, DeviceClass::RequestResult &result)
处理 SET_REPORT 请求 Handle SET_REPORT request
Definition hid.hpp:546
ErrorCode OnGetDescriptor(bool in_isr, uint8_t bRequest, uint16_t wValue, uint16_t wLength, ConstRawData &need_write) override
处理标准请求 GET_DESCRIPTOR(HID/Report 描述符)。 Handle standard GET_DESCRIPTOR requests for HID/Report Descrip...
Definition hid.hpp:307
Endpoint * GetOutEndpoint()
获取输出端点 Get OUT endpoint
Definition hid.hpp:624
bool HasIAD() override
检查是否包含IAD Check if IAD is present
Definition hid.hpp:273
uint8_t last_output_report_id_
最近的 Output Report ID / Last Output Report ID
Definition hid.hpp:646
Endpoint * ep_out_
输出端点指针 / OUT endpoint pointer
Definition hid.hpp:639
HID(bool enable_out_endpoint=false, uint8_t in_ep_interval=10, uint8_t out_ep_interval=10, Endpoint::EPNumber in_ep_num=Endpoint::EPNumber::EP_AUTO, Endpoint::EPNumber out_ep_num=Endpoint::EPNumber::EP_AUTO)
HID 构造函数 HID class constructor.
Definition hid.hpp:110
virtual ConstRawData GetReportDesc()=0
获取 HID 报告描述符 Get HID Report Descriptor
uint8_t idle_rate_
当前空闲率/ Current idle rate (unit 4ms)
Definition hid.hpp:645
ErrorCode SendInputReport(ConstRawData report)
发送输入报告到主机 Send Input Report to host
Definition hid.hpp:573
Endpoint * ep_in_
输入端点指针 / IN endpoint pointer
Definition hid.hpp:638
virtual ErrorCode OnGetFeatureReport(uint8_t report_id, DeviceClass::RequestResult &result)
获取特征报告 Get Feature Report
Definition hid.hpp:504
virtual ErrorCode OnCustomClassRequest(bool in_isr, uint8_t bRequest, uint16_t wValue, uint16_t wLength, RequestResult &result)
处理自定义类请求 Handle custom class request
Definition hid.hpp:523
uint8_t out_ep_interval_
输出端点间隔 / OUT endpoint interval
Definition hid.hpp:634
Protocol
HID 协议类型 / HID Protocol Types.
Definition hid.hpp:46
@ REPORT
报告协议 / Report protocol (通用)
@ BOOT
启动协议 / Boot protocol (键盘/鼠标)
virtual ErrorCode OnGetInputReport(uint8_t report_id, DeviceClass::RequestResult &result)
获取输入报告 Get Input Report
Definition hid.hpp:480
size_t GetMaxConfigSize() override
获取最大配置描述符块长度 Get max config descriptor size.
Definition hid.hpp:291
HIDDescBlockINOUT desc_
HID 描述符块/ Descriptor block.
Definition hid.hpp:635
bool OwnsEndpoint(uint8_t ep_addr) const override
判断是否拥有该端点 Check if this configuration item owns this endpoint
Definition hid.hpp:275
uint8_t in_ep_interval_
输入端点间隔 / IN endpoint interval
Definition hid.hpp:633
Endpoint::EPNumber out_ep_num_
输出端点号 / OUT endpoint number
Definition hid.hpp:637
bool HasOutEndpoint() const
查询是否支持OUT端点 Check if OUT endpoint is enabled
Definition hid.hpp:630
void Init(EndpointPool &endpoint_pool, uint8_t start_itf_num) override
初始化 HID 设备,自动选择端点与描述符块 Initialize HID device and select descriptor block (IN or IN+OUT).
Definition hid.hpp:129
size_t itf_num_
接口号 / Interface number
Definition hid.hpp:642
uint8_t GetIDLERate() const
获取IDLE报告率 Get IDLE report rate
Definition hid.hpp:608
ErrorCode OnClassRequest(bool in_isr, uint8_t bRequest, uint16_t wValue, uint16_t wLength, uint16_t wIndex, DeviceClass::RequestResult &result) override
处理 HID 类请求 Handle HID class-specific requests
Definition hid.hpp:352
ReportType
HID 报告类型 / HID Report Types.
Definition hid.hpp:53
@ OUTPUT
输出报告 / Output report
@ INPUT
输入报告 / Input report
@ FEATURE
特征报告 / Feature report
Endpoint * GetInEndpoint()
获取输入端点 Get IN endpoint
Definition hid.hpp:616
virtual ErrorCode OnSetReportData(bool in_isr, ConstRawData &data)
处理 SET_REPORT 数据阶段 Handle SET_REPORT data stage
Definition hid.hpp:558
Endpoint::EPNumber in_ep_num_
输入端点号 / IN endpoint number
Definition hid.hpp:636
Protocol protocol_
当前协议类型 / Current protocol
Definition hid.hpp:644
uint8_t GetLastOutputReportID() const
获取最近一次 Output Report 的 Report ID Get the last received Output Report ID.
Definition hid.hpp:457
void Deinit(EndpointPool &endpoint_pool) override
反初始化 HID 设备 Deinitialize HID device.
Definition hid.hpp:242
bool inited_
初始化标志 / Initialization flag
Definition hid.hpp:641
HIDDescriptorType
HID 描述符类型 / HID Descriptor Types.
Definition hid.hpp:27
@ HID
HID 类描述符 / HID Class Descriptor.
@ REPORT
报告描述符 / Report Descriptor
@ PHYSICAL
物理描述符 / Physical Descriptor (rarely used)
size_t GetInterfaceNum() override
获取接口数量 Get number of interfaces
Definition hid.hpp:264
ClassRequest
HID 类请求代码 / HID Class-Specific Requests.
Definition hid.hpp:35
@ SET_PROTOCOL
设置协议 / Set Protocol
@ GET_PROTOCOL
获取协议 / Get Protocol
@ GET_REPORT
获取报告 / Get Report
@ SET_REPORT
设置报告 / Set Report
@ SET_IDLE
设置空闲率 / Set Idle
@ GET_IDLE
获取空闲率 / Get Idle
ErrorCode OnClassData(bool in_isr, uint8_t bRequest, LibXR::ConstRawData &data) override
处理类请求数据阶段 Handle class data stage
Definition hid.hpp:426
端点描述符结构体 Endpoint descriptor structure (USB 2.0 Spec 9.6.6)
Definition desc_cfg.hpp:92
接口描述符结构体 Interface descriptor structure (USB 2.0 Spec 9.6.5)
Definition desc_cfg.hpp:74
控制请求结果结构体 / Structure for control transfer results
Definition dev_core.hpp:28
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
包含 IN 端点的描述符块 Descriptor block with IN endpoint.
Definition hid.hpp:81
EndpointDescriptor ep_in
IN 端点描述符 / IN endpoint descriptor.
Definition hid.hpp:84
HIDDescriptor hid
HID 描述符 / HID descriptor.
Definition hid.hpp:83
InterfaceDescriptor intf
接口描述符 / Interface descriptor
Definition hid.hpp:82
包含 IN+OUT 端点的描述符块 Descriptor block with IN and OUT endpoints.
Definition hid.hpp:92
HIDDescriptor hid
HID 描述符 / HID descriptor.
Definition hid.hpp:94
EndpointDescriptor ep_out
OUT 端点描述符 / OUT endpoint descriptor.
Definition hid.hpp:96
EndpointDescriptor ep_in
IN 端点描述符 / IN endpoint descriptor.
Definition hid.hpp:95
InterfaceDescriptor intf
接口描述符 / Interface descriptor
Definition hid.hpp:93
HID描述符结构体 HID descriptor structure.
Definition hid.hpp:65
uint8_t bLength
描述符长度 / Descriptor length
Definition hid.hpp:66
uint8_t bNumDescriptors
后续描述符数量 / Number of subordinate descriptors
Definition hid.hpp:70
uint16_t bcdHID
HID 版本号 / HID class specification release.
Definition hid.hpp:68
HIDDescriptorType bReportDescriptorType
报告描述符类型 / Report descriptor type (0x22)
Definition hid.hpp:72
HIDDescriptorType bDescriptorType
描述符类型 / Descriptor type (0x21)
Definition hid.hpp:67
uint16_t wReportDescriptorLength
报告描述符长度 / Report descriptor length
Definition hid.hpp:73
uint8_t bCountryCode
国家码 / Country code
Definition hid.hpp:69