0x2121 · hiResWheel
High-resolution scroll wheel — read capabilities, get or set the wheel mode (resolution, ratchet vs. free-spin, event routing), and listen for diverted scroll and ratchet-switch events.
High-resolution scrolling. The wheel can report fine-grained motion, switch between ratchet and free-spin, and route its events either as standard HID or as HID++ notifications. Functions cover reading the wheel capability, getting/setting the current mode, and inverting direction.
Spec: Logitech HID++ 2.0 — x2121 hiResWheel (v1).
Function reference
The HiResWheelFeature wrapper (0x2121) exposes:
Methods
| Function | HID++ fn | Signature | Returns |
|---|---|---|---|
get_wheel_capabilities | 0 | () | WheelCapabilities |
get_wheel_mode | 1 | () | WheelMode |
set_wheel_mode | 2 | (target: WheelEventTarget, resolution: WheelResolution, inverted: bool) | WheelMode |
get_ratchet_switch_state | 3 | () | WheelRatchetState |
listen | event | () | Receiver<HiResWheelEvent> |
All request methods are async and return Result<…, Hidpp20Error>. listen is synchronous and returns an async_channel::Receiver<HiResWheelEvent> directly. The analytics functions are intentionally not wrapped — their data structure is undocumented.
Types
WheelCapabilities
Wheel and feature capabilities, returned by get_wheel_capabilities.
| Field | Type | Description |
|---|---|---|
multiplier | u8 | Hi-res report multiplier: reports produced per ratchet distance in hi-res mode. |
has_invert | bool | Device can invert scroll direction in native HID mode (never in diverted mode). |
has_switch | bool | Device has a physical switch for the ratchet mode. |
ratches_per_rotation | u8 | Ratchets generated by one full wheel rotation. |
wheel_diameter | u8 | Nominal wheel diameter in millimeters. |
WheelMode
Current wheel mode, returned by get_wheel_mode / set_wheel_mode.
| Field | Type | Description |
|---|---|---|
inverted | bool | Scroll direction inverted (native HID mode only). |
resolution | WheelResolution | Current scrolling resolution. |
target | WheelEventTarget | Where wheel reports are routed. |
WheelResolution
| Variant | Value | Description |
|---|---|---|
Low | 0 | Low-resolution wheel reporting. |
High | 1 | High-resolution wheel reporting. |
WheelEventTarget
| Variant | Value | Description |
|---|---|---|
Native | 0 | Wheel reports go to the native HID path. |
Diverted | 1 | Wheel reports are diverted to HID++ events. |
WheelRatchetState
| Variant | Value | Description |
|---|---|---|
Freespin | 0 | Wheel is in free-spin mode. |
Ratchet | 1 | Wheel is in ratchet mode. |
Events
HiResWheelEvent
| Variant | Payload | Description |
|---|---|---|
WheelMovement | WheelMovementData | Emitted on wheel movement in diverted HID++ mode. |
RatchetSwitch | WheelRatchetState | Emitted when the ratchet mode changes. Always enabled. |
WheelMovementData
| Field | Type | Description |
|---|---|---|
resolution | WheelResolution | Current wheel resolution. |
periods | U4 | Number of sampling periods for this event; U4 is a 4-bit unsigned integer (nibble), range 0–15. |
delta_vertical | i16 | Vertical movement delta; moving away from the user is positive. |
Wire format
All request payloads are 3 bytes. Responses are read from the 16-byte long payload returned by the HID++ 2.0 frame (extend_payload()). Event payloads are also parsed from that same 16-byte area.
get_wheel_capabilities (fn 0)
Request: [0x00, 0x00, 0x00]
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0 | multiplier | Hi-res report multiplier (u8). |
| 1 bit 3 | has_invert | payload[1] & (1 << 3) != 0 |
| 1 bit 2 | has_switch | payload[1] & (1 << 2) != 0 |
| 2 | ratches_per_rotation | Ratchets per full rotation (u8). |
| 3 | wheel_diameter | Nominal diameter in mm (u8). |
get_wheel_mode (fn 1)
Request: [0x00, 0x00, 0x00]
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0 bit 2 | inverted | payload[0] & (1 << 2) != 0 |
| 0 bit 1 | resolution | (payload[0] & (1 << 1)) >> 1 → WheelResolution |
| 0 bit 0 | target | payload[0] & 1 → WheelEventTarget |
set_wheel_mode (fn 2)
Request: [mode_byte, 0x00, 0x00]
mode_byte is assembled as:
| Bit | Parameter | Notes |
|---|---|---|
| 2 | inverted | Set when inverted == true |
| 1 | resolution | u8::from(resolution) << 1 |
| 0 | target | u8::from(target) |
Response: same byte layout as get_wheel_mode.
get_ratchet_switch_state (fn 3)
Request: [0x00, 0x00, 0x00]
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0 bit 0 | ratchet state | payload[0] & 1 → WheelRatchetState |
Events
WheelMovement (event fn 0)
| Byte | Field | Notes |
|---|---|---|
| 0 bit 4 | resolution | (payload[0] & (1 << 4)) >> 4 → WheelResolution |
| 0 bits 3–0 | periods | U4::from_lo(payload[0]) — lower nibble, range 0–15 |
| 1–2 | delta_vertical | i16::from_be_bytes([payload[1], payload[2]]) |
RatchetSwitch (event fn 1)
| Byte | Field | Notes |
|---|---|---|
| 0 bit 0 | ratchet state | payload[0] & 1 → WheelRatchetState |
Usage (Rust)
use hidpp::{device::Device, feature::hires_wheel::{HiResWheelFeature, WheelEventTarget, WheelResolution}};
// mut device: Device, obtained via Device::new(channel, index).await?
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<HiResWheelFeature>() {
let caps = feat.get_wheel_capabilities().await?;
println!("multiplier={}, ratchets/rot={}", caps.multiplier, caps.ratches_per_rotation);
// Enable hi-res diverted mode (scroll events arrive as HID++ notifications)
feat.set_wheel_mode(WheelEventTarget::Diverted, WheelResolution::High, false).await?;
// Listen for wheel movement and ratchet-switch events
let rx = feat.listen();
while let Ok(event) = rx.recv().await {
println!("{event:?}");
}
}0x2120 · highResolutionScrolling
Older feature for querying and enabling fine-grained high-resolution wheel reporting — a predecessor to 0x2121 hiResWheel without ratchet-mode switching.
0x2150 · thumbwheel
Horizontal thumb-wheel control — query capabilities, divert rotation events from HID to HID++, and read touch and tap status.