How OpenLogi Maps SmartShift Wheel Configuration to HID++ Feature 0x2111
OpenLogi implements SmartShift wheel configuration by mapping user settings to HID++ feature 0x2111 (Reprogrammable Controls) using task ID 0x9D and control ID 0xC4, encoding wheel modes into device-specific packets in crates/openlogi-device/src/write/smartshift.rs.
OpenLogi is an open-source Rust framework for configuring Logitech HID++ devices. When users configure SmartShift wheel behavior in their TOML files, the framework translates these high-level settings into low-level HID++ feature 0x2111 commands that directly manipulate wheel modes in the device firmware.
Understanding HID++ Feature 0x2111 and SmartShift
HID++ feature 0x2111 represents the Reprogrammable Controls feature in Logitech's HID++ protocol. Within the OpenLogi codebase, this feature handles dynamic button and wheel reassignment. The SmartShift functionality specifically utilizes task ID 0x9D and control ID 0xC4 within this feature to manage automatic wheel mode switching.
The mapping works as follows:
- Feature 0x2111: Base HID++ reprogrammable controls feature that enables runtime configuration of input controls.
- Task 0x9D: Specific task identifier for SmartShift operations, defined in
crates/openlogi-hidpp/src/feature/reprog_controls/task_ids.rs. - Control 0xC4: Control identifier for the SmartShift wheel mode, defined in
crates/openlogi-hidpp/src/feature/reprog_controls/control_ids.rs.
Architecture: From Configuration to HID++ Packets
OpenLogi uses a layered architecture to bridge user configuration and hardware commands.
Configuration Layer
The SmartShiftConfig struct in crates/openlogi-device/src/reprog_controls.rs stores user-defined wheel settings parsed from docs/config.example.toml. This struct encapsulates the wheel mode selection (SmartShift or DPI Change) and associated DPI step values.
Core Translation Layer
The crates/openlogi-core/src/hid/smartshift.rs module provides the high-level API that translates SmartShiftConfig into HID++ protocol structures. This layer references TaskId::SmartShift (0x9D) and ControlId::SmartShiftWheel (0xC4) to construct the proper feature 0x2111 command payload.
Device Write Layer
The crates/openlogi-device/src/write/smartshift.rs file handles the final transmission. It implements the write_smart_shift function that encodes the configuration into binary HID++ packets and dispatches them to the physical device using the reprogrammable controls feature.
Code Implementation Details
User Configuration
Users define SmartShift behavior in the TOML configuration file:
[device.<device-id>.smart_shift]
# Choose the wheel mode: "SmartShift" or "DpiChange"
wheel_mode = "SmartShift"
# Optional: DPI steps when SmartShift switches
dpi_steps = [800, 1600, 2400]
Building the HID++ Packet
The core layer constructs the packet using the specific feature identifiers:
use openlogi_core::hid::smartshift::SmartShiftConfig;
use openlogi_hidpp::feature::reprog_controls::{TaskId, ControlId};
let cfg = SmartShiftConfig {
wheel_mode: WheelMode::SmartShift,
dpi_steps: vec![800, 1600, 2400],
};
let packet = cfg.to_hidpp_packet(
TaskId::SmartShift, // 0x9D (feature 0x2111 task)
ControlId::SmartShiftWheel, // 0xC4
);
device.send_hidpp(packet)?;
Device-Side Write Implementation
The device write layer sends the finalized command:
pub fn write_smart_shift(
dev: &mut Device,
cfg: &SmartShiftConfig,
) -> Result<()> {
let payload = cfg.encode(); // encodes DPI steps, mode, …
dev.write_reprog_control(TaskId::SmartShift, // 0x9D
ControlId::SmartShiftWheel, // 0xC4
&payload)
}
Key Source Files
The following files implement the SmartShift to HID++ 0x2111 mapping:
crates/openlogi-hidpp/src/feature/reprog_controls/task_ids.rs: Defines task ID 0x9D for SmartShift operations.crates/openlogi-hidpp/src/feature/reprog_controls/control_ids.rs: Defines control ID 0xC4 for SmartShift wheel mode.crates/openlogi-core/src/hid/smartshift.rs: High-level API that builds HID++ packets for feature 0x2111.crates/openlogi-device/src/write/smartshift.rs: Encodes and sends the feature 0x2111 write requests to the hardware.crates/openlogi-device/src/reprog_controls.rs: Contains theSmartShiftConfigstruct and TOML integration logic.docs/config.example.toml: Reference configuration showing valid SmartShift wheel settings.
Summary
- OpenLogi uses HID++ feature 0x2111 (Reprogrammable Controls) as the transport mechanism for SmartShift configuration.
- Task ID 0x9D and control ID 0xC4 are the specific identifiers within feature 0x2111 that activate SmartShift wheel mode.
- The
SmartShiftConfigstruct bridges user TOML configuration and binary HID++ packets. - The
write_smart_shiftfunction incrates/openlogi-device/src/write/smartshift.rsexecutes the final device write operation.
Frequently Asked Questions
What is HID++ feature 0x2111?
HID++ feature 0x2111 is the Reprogrammable Controls feature in Logitech's HID++ protocol. It allows runtime modification of button and wheel behaviors. OpenLogi uses this feature to send SmartShift configuration commands that change how the mouse wheel operates (ratchet vs. freespin modes).
How does OpenLogi convert TOML settings to HID++ commands?
OpenLogi parses the TOML configuration into a SmartShiftConfig struct, then serializes this into a binary payload. The core layer maps this payload to task 0x9D and control 0xC4 within feature 0x2111, creating a HID++ packet that the device firmware interprets as a wheel mode change command.
Why does SmartShift use task 0x9D and control 0xC4 specifically?
These identifiers are defined in the Logitech HID++ protocol specification for the Reprogrammable Controls feature (0x2111). Task 0x9D designates the SmartShift functionality, while control 0xC4 specifically addresses the wheel mechanism, distinguishing it from other reprogrammable controls like buttons or DPI switches.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →