# **Project Plan: Rust-based OpenVR Haptic Stack (SAMD21 \+ DRV2605L)**

This document outlines the architectural phases and technical requirements for building a low-latency haptic interface using the Adafruit QT Py SAMD21, the DRV2605L driver, and a custom OpenVR driver.

## **Phase 1: Embedded Firmware (no\_std Rust)**

The firmware acts as the I2C master and USB HID device.

### **1.1 Toolchain Setup**

* **Target:** thumbv6m-none-eabi (Cortex-M0+).  
* **Key Crates:** \- atsamd-hal: Hardware abstraction for SERCOM (I2C) and USB.  
  * usb-device: For the USB stack.  
  * usbd-hid: To implement the HID class for deterministic 1ms polling.  
  * drv2605: (Or custom implementation) to handle the I2C register maps.

### **1.2 Core Logic**

* **Initialization:** Configure SERCOM2 for I2C (STEMMA QT pins PA08/PA09) and initialize the DRV2605L into Real-Time Playback (RTP) mode.  
* **USB Task:** Listen for HID "Output Reports" containing 8-bit intensity values.  
* **Haptic Loop:** Update the RTP\_INPUT register (0x02) on the DRV2605L immediately upon receiving a USB packet.

## **Phase 2: Host-Device Communication (USB HID)**

Standardize the "Language" between Windows and the Microcontroller.

### **2.1 HID Report Descriptor**

Define a simple protocol:

* **Byte 0:** Command ID (e.g., 0x01 for Set Intensity, 0x02 for Trigger ROM Effect).  
* **Byte 1:** Amplitude/Intensity (0-255).  
* **Bytes 2-3:** Optional Frequency/Duration data.

### **2.2 Host-Side Library**

* Use the hidapi crate in Rust to find the device by VID/PID and send raw bytes. This will be wrapped by the OpenVR DLL.

## **Phase 3: OpenVR Driver (Rust cdylib)**

The bridge between SteamVR and the USB hardware.

### **3.1 C++ ABI Emulation**

* **Challenge:** OpenVR is a C++ Virtual Function Table (vtable) API.  
* **Solution:** Manually construct Rust structs that mirror the C++ memory layout for:  
  * IServerTrackedDeviceProvider (Driver lifecycle).  
  * ITrackedDeviceServerDriver (The haptic device instance).

### **3.2 Haptic Event Handling**

* Implement the TriggerHapticVibration callback.  
* Convert the OpenVR float amplitude (0.0 \- 1.0) into an 8-bit integer.  
* Forward this data via the hidapi connection to the SAMD21.

## **Phase 4: Integration and Deployment**

### **4.1 Driver Manifest**

Create a driver.vrdrivermanifest so SteamVR recognizes your DLL.

{  
  "always\_activate": true,  
  "name": "rust\_haptic\_driver",  
  "resource\_directory": "resources"  
}

### **4.2 Registration**

Use the SteamVR vrpathreg tool to register the folder containing your .dll.

## **Technical Summary Table**

| Component | Language | Primary Goal | Key Dependency |
| :---- | :---- | :---- | :---- |
| **Firmware** | Rust (no\_std) | I2C Control / USB HID | atsamd-hal |
| **Protocol** | Binary | Low-latency packet delivery | USB HID Class |
| **OpenVR DLL** | Rust (cdylib) | Interface with vrserver.exe | hidapi, openvr-sys |
| **Hardware** | Hardware | Physical Actuation | DRV2605L / LRA Motor |

## **Next Steps**

1. **Initialize the Firmware:** Get the QT Py recognized as a HID device in Windows.  
2. **I2C Testing:** Use a simple Rust CLI tool on Windows to send "vibrate" commands to the device.  
3. **OpenVR Boilerplate:** Create a minimal "Null" driver in Rust that SteamVR can load without crashing.  
4. **Linkage:** Combine the CLI tool logic into the OpenVR driver callbacks.