# HID++ Feature Codes for DPI, SmartShift, Scroll, and Lighting in OpenLogi

> Discover OpenLogi HID++ feature codes for DPI, SmartShift, scroll, and lighting. Control your device with codes 0x2201, 0x2202, 0x2110, 0x2111, and 0x1000.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: api-reference
- Published: 2026-08-26

---

**OpenLogi uses HID++ feature codes 0x2201 and 0x2202 for DPI configuration, 0x2110 and 0x2111 for SmartShift and scroll wheel modes, and 0x1000 for per-key lighting control, all registered in the `openlogi-hidpp` crate.**

The AprilNEA/OpenLogi project implements a Rust-based driver stack for Logitech HID++ devices. Understanding the specific **HID++ feature codes** that map hardware capabilities—such as sensor resolution, wheel ratcheting, and RGB illumination—to protocol commands is essential for extending device support or debugging communication layers.

## DPI Control via Feature Codes 0x2201 and 0x2202

OpenLogi distinguishes between legacy and extended DPI configuration using two separate feature identifiers.

### Adjustable DPI (0x2201) and Extended DPI (0x2202)

In [`crates/openlogi-hidpp/src/feature/registry.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/registry.rs), the registry maps `0x2201` to `AdjustableDpiFeature` and `0x2202` to `ExtendedDpiFeature`. These structs handle reading and writing sensor resolution values, DPI ranges, lift-off distance, and DPI-LED status.

### Control IDs for DPI Operations

The [`reprog_controls/control_ids.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/reprog_controls/control_ids.rs) file defines low-level control IDs used within these features:

- `DPI_CHANGE = 0xED`
- `DPI_SWITCH = 0xFD`

These constants appear in lines 170–219 of the control IDs module and are referenced by the DPI write implementation in [`crates/openlogi-device/src/write/dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/write/dpi.rs).

## SmartShift and Scroll Wheel Control (0x2110 and 0x2111)

SmartShift functionality—toggling between freespin and ratchet scroll modes—uses dedicated feature codes that also encode the scroll wheel's operational state.

### SmartShift Wheel (0x2110) and Enhanced (0x2111)

The registry associates `0x2110` with `SmartShiftFeature` and `0x2111` with `SmartShiftEnhancedFeature`. The enhanced variant supports additional torque tuning and configurable auto-disengage thresholds, while the base feature handles basic mode switching.

### Scroll Mode Encoding

According to [`crates/openlogi-device/src/write/smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/write/smartshift.rs) (lines 84–95), the `WheelMode` enum converts between the hardware's scroll mode state and the SmartShift feature status. This effectively embeds scroll control within the SmartShift feature implementation, meaning the **scroll wheel mode** is not a separate HID++ feature code but rather a data field within the 0x2110/0x2111 feature reports.

## Lighting Control via Feature Code 0x1000

Per-key RGB lighting is managed through a distinct feature namespace separate from input controls.

### Per-Key Lighting Implementation

The [`per_key_lighting.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/per_key_lighting.rs) file implements the `0x1000` feature code for per-key lighting. This feature utilizes Report ID `0x12` to transmit 64-byte color data buffers, enabling configuration of solid colors, individual key RGB values, and lighting persistence settings across device power cycles.

## Practical Implementation Examples

The following Rust snippets demonstrate how OpenLogi's internal API interacts with these HID++ feature codes.

### Reading and Writing DPI

This example queries the current resolution using feature 0x2201 or 0x2202 and sets a new value:

```rust
use openlogi_core::hid::dpi::Dpi;

// Query current DPI (internally selects feature 0x2201 or 0x2202)
let dpi = client.get_dpi(route).await?;
println!("Current DPI: {}", dpi.current());

// Update sensor resolution (writes to the detected DPI feature)
client.set_dpi(route, Dpi::new(1200)).await?;

```

### Configuring SmartShift Modes

This snippet toggles SmartShift using feature 0x2110 or 0x2111 and configures the ratchet threshold:

```rust
use openlogi_core::hid::smartshift::{
    SmartShiftMode, SmartShiftStatus, SmartShiftAutoDisengage, SmartShiftThreshold, TunableTorque,
};

// Toggle between freespin and ratchet (uses feature 0x2110/0x2111)
let mode = client.toggle_smartshift(route).await?;
println!("SmartShift mode: {:?}", mode);

// Apply specific ratchet settings with torque control
let status = SmartShiftStatus {
    mode: SmartShiftMode::Ratchet,
    auto_disengage: SmartShiftAutoDisengage::Threshold(
        SmartShiftThreshold::try_new(16).unwrap(),
    ),
    tunable_torque: Some(TunableTorque::try_new(60).unwrap()),
};
client.set_smartshift(route, status).await?;

```

### Setting Per-Key Lighting

This example configures solid red lighting using feature 0x1000 and report 0x12:

```rust
use openlogi_core::hid::lighting::{Lighting, Color};

// Construct lighting configuration
let lighting = Lighting {
    enabled: true,
    color: Color::rgb(0xFF, 0x00, 0x00),
    brightness: 100,
    ..Default::default()
};

// Transmit via feature 0x1000 (report 0x12)
client.set_lighting(route, lighting).await?;

```

## Summary

- **DPI Management**: OpenLogi uses feature codes **0x2201** (Adjustable DPI) and **0x2202** (Extended DPI) to handle sensor resolution, with internal control IDs **0xED** and **0xFD** defined in [`control_ids.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/control_ids.rs).
- **SmartShift and Scroll**: Feature codes **0x2110** (SmartShift) and **0x2111** (SmartShift Enhanced) control freespin/ratchet behavior; scroll wheel mode state is encoded within these feature reports via the `WheelMode` enum in [`smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/smartshift.rs).
- **Lighting Control**: Feature code **0x1000** manages per-key RGB lighting, utilizing Report ID **0x12** for 64-byte color data payloads defined in [`per_key_lighting.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/per_key_lighting.rs).
- **Registry Location**: All feature code mappings are centralized in [`crates/openlogi-hidpp/src/feature/registry.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/registry.rs), which instantiates the appropriate feature structs based on device capability advertisements.

## Frequently Asked Questions

### What is the difference between feature code 0x2201 and 0x2202 in OpenLogi?

Code **0x2201** implements the legacy Adjustable DPI feature for basic sensor resolution control, while **0x2202** implements Extended DPI, which supports higher resolution tables and additional lift-off distance configuration. The [`registry.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/registry.rs) file maps these codes to `AdjustableDpiFeature` and `ExtendedDpiFeature` structs respectively, and the implementation in [`dpi.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/dpi.rs) selects the appropriate feature based on the device's advertised capabilities.

### How does OpenLogi handle scroll wheel mode changes via HID++?

OpenLogi maps scroll wheel modes (freespin versus ratchet) to the SmartShift feature codes **0x2110** and **0x2111**. The conversion logic resides in [`crates/openlogi-device/src/write/smartshift.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-device/src/write/smartshift.rs), where the `WheelMode` enum translates between raw HID++ status bytes and the internal SmartShift state, allowing scroll mode control without a separate dedicated feature code.

### Which HID++ feature code controls per-key RGB lighting in OpenLogi?

The feature code **0x1000** controls per-key lighting functionality. This feature uses Report ID **0x12** to transmit 64-byte color buffers to the device, as implemented in [`crates/openlogi-hidpp/src/feature/per_key_lighting.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/per_key_lighting.rs). This separation allows lighting configuration to operate independently of input feature codes like DPI or SmartShift.

### Where are the DPI control constants defined in the OpenLogi source code?

DPI-specific control constants such as `DPI_CHANGE = 0xED` and `DPI_SWITCH = 0xFD` are defined in [`crates/openlogi-hidpp/src/feature/reprog_controls/control_ids.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/reprog_controls/control_ids.rs) within lines 170–219. The high-level feature code registry that maps 0x2201 and 0x2202 to their respective implementation structs is located in [`crates/openlogi-hidpp/src/feature/registry.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/feature/registry.rs).