3个不稳定版本
0.2.1 | 2024年6月10日 |
---|---|
0.2.0 | 2024年5月23日 |
0.1.0 | 2024年5月15日 |
#546 在 硬件支持
91 每月下载量
在 2 crate 中使用
1MB
16K SLoC
hut - HID使用表
此crate提供对HID使用表 (HUT)的访问。
此模块是通过从HID使用表生成代码创建的。
此crate仅提供枚举和函数以在值之间进行转换,它不关心如何获取要使用的值。例如,查看hidreport
crate以解析HID报告描述符。
use hut::*;
let usage = Usage::from(GenericDesktop::Mouse);
let usage_page_value: u16 = 0x01; // Generic Desktop
let usage_id_value: u16 = 0x02; // Mouse
let usage_value: u32 = (usage_page_value as u32) << 16 | usage_id_value as u32;
let u: Usage = Usage::try_from(usage_value).unwrap();
请参阅文档以获取更多详细信息。
许可证
lib.rs
:
对HID使用表 (HUT)的包装。
在本文档中,除非另有说明,否则对“HID部分a.b.c”的引用是指HID设备类定义1.11。
在本文档中,除非另有说明,否则对“HUT部分a.b.c”的引用是指HID使用表(HUT)版本1.5。
此模块是通过从HID使用表生成代码创建的。
术语
请参阅HID第5.5节:HID使用是一个32位值,由一个16位的用法页面和一个16位的用法ID组成。在此模块中
- "用法页面"指的是16位值。在将用法页面转换为或从32位值转换时,用法页面位于该值的最高16位,而最低16位被忽略或设置为零。
- "用法ID"指的是16位值。在将用法ID转换为或从32位值转换时,用法位于该值的最低16位,而最高16位被忽略或设置为零。
- "用法"指的是包含用法页面和用法的32位值。
类型之间转换
所有定义的 使用 和 使用页面 实现了 [AsUsagePage] 和(如果适用)[AsUsage],以及 From<u16>
、From<u32>
、TryFrom<u16>
和 TryFrom<u32>
转换,以便
let usage_page_value: u16 = 0x01; // Generic Desktop
let usage_id_value: u16 = 0x02; // Mouse
let usage_value: u32 = (usage_page_value as u32) << 16 | usage_id_value as u32;
// Create a known Usage from a 32-bit value
let u: Usage = Usage::try_from(usage_value).unwrap();
assert!(matches!(u, Usage::GenericDesktop { usage: GenericDesktop::Mouse }));
// Create a known Usage from the Usage Page and Usage ID values
let u2 = Usage::new_from_page_and_id(usage_page_value, usage_id_value).unwrap();
assert_eq!(u, u2);
// Create a known Usage from an individual Usage Page enum item
let u3 = Usage::from(GenericDesktop::Mouse);
assert_eq!(u, u3);
// Convert to and fro the Usage either via u32 or the AsUsage trait
let u = GenericDesktop::Mouse;
assert_eq!(u32::from(&u), usage_value);
assert_eq!(u.usage_value(), usage_value);
// Extract the 16-bit Usage ID either via u16 or the AsUsage trait
assert_eq!(usage_id_value, u16::from(&u));
assert_eq!(usage_id_value, u.usage_id_value());
// Extract the Usage Page from Usage enum value
let up: UsagePage = UsagePage::from(&u);
assert!(matches!(up, UsagePage::GenericDesktop));
// Get the Usage Page numeric value is via the AsUsagePage
assert_eq!(usage_page_value, u16::from(&up));
assert_eq!(usage_page_value, up.usage_page_value());
上面的方法适用于定义的使用页面,生成使用页面(见下文)需要通过其单独的元素进行解构
let usage_page_value: u16 = 0x09; // Button
let usage_id_value: u16 = 8; // Button number 8
let usage_value: u32 = (usage_page_value as u32) << 16 | usage_id_value as u32;
let u = Usage::try_from(usage_value).unwrap();
assert!(matches!(Usage::try_from(usage_value).unwrap(),
Usage::Button {
usage: Button::Button { button: 8 }
}));
一旦创建了使用,[AsUsagePage] 和 [AsUsage] 特性和从 [u16] 和 [u32] 的转换与定义使用页面相同。
生成使用页面
HUT 之间的“定义”和“生成”使用页面不同。前者定义使用 ID 值及其含义,后者定义一个使用 ID 范围,实际使用 ID 简单地指的是“此使用页面中的第 n 个东西”。一个例子是按钮使用页面(0x09),其中使用 ID 3 表示“按钮 3”。
let b = Button::Button { button: 3 };
let o = Ordinal::Ordinal { instance: 23 };
与定义使用页面不同,生成使用页面需要在 match
语句中进行解构。
以下使用页面是生成的
- 使用页面 0x9 - [Button]
- 使用页面 0xA - [Ordinal]
- 使用页面 0x10 - [Unicode]
- 使用页面 0x81 - [MonitorEnumerated]
进一步的特殊情况是 [Unicode] 使用页面,它不在 HUT 文档中,而是在代码生成期间插入的。
供应商定义的使用页面(0xFF00 到 0xFFFF)
供应商定义的使用页面 和 VendorUsages 不是自动生成的,因此采用不同的方法:使用页面内的使用是简单的数字使用,需要在 match
语句中进行解构。
一个值得注意的例外是 [Wacom](0xFF0D
),它技术上是一个供应商定义的页面,但具有定义的使用。从 [UsagePage] 或 [Usage] 数字值转换将产生正确的或 [Wacom] 使用,而不是 VendorDefinedPage::VendorUsage。
保留使用页面
保留使用页面 和 ReservedUsages 不是自动生成的,因此采用不同的方法:使用页面内的使用是简单的数字使用,需要在 match
语句中进行解构。
与 供应商定义的使用页面 不同,一个 保留使用页面 可能会在 HUT 标准的后续版本中成为定义页面,因此在这个 crate 的未来版本中。调用者不应依赖保留使用页面或保留使用保持不变。
以下使用页面在 HUT 1.5 中保留(见 HUT 部分 3,第 15 页)
0x13
,0x15-0x1F
0x21-0x3F
0x42-0x58
0x5A-0x7F
0x83-0x83
0x86-0x8B
0x8F-0x8F
0x93-0xF1CF
0xF1D1-0xFEFF
重命名
由于技术原因,使用页面和用法名称中会去除空格(
)、破折号(-
)和斜杠(/
)。通过Display
特质的字符串表示将保留未修改的值。
依赖项
~265–720KB
~17K SLoC