# Eye-Tracking System (BS2 Only)

The BS2 board revision includes an eye-tracking subsystem built around an FPGA that controls IR LEDs and interfaces with camera sensors. The MCU communicates with this FPGA over I2C.

## FPGA Interface

**I2C address:** `0x78`  
**Max transaction size:** 32 bytes  

### FPGA Register Map

| Address | Register | Purpose |
|---------|----------|---------|
| `0x00` | CAM_ADDR_HI | Camera sensor address (high byte) |
| `0x01` | CAM_ADDR_LO | Camera sensor address (low byte) |
| `0x02` | CAM_DATA | Camera sensor data read/write |
| `0x10` | PWM_HI | IR LED PWM duty cycle (high byte) |
| `0x11` | PWM_LO | IR LED PWM duty cycle (low byte) |
| `0x70` | IR_LEFT_RUN_MEAS_HI | Left IR LED current during run (high) |
| `0x71` | IR_LEFT_RUN_MEAS_LO | Left IR LED current during run (low) |
| `0x72` | IR_LEFT_IDLE_MEAS_HI | Left IR LED current during idle (high) |
| `0x73` | IR_LEFT_IDLE_MEAS_LO | Left IR LED current during idle (low) |
| `0x74` | IR_RIGHT_RUN_MEAS_HI | Right IR LED current during run (high) |
| `0x75` | IR_RIGHT_RUN_MEAS_LO | Right IR LED current during run (low) |
| `0x76` | IR_RIGHT_IDLE_MEAS_HI | Right IR LED current during idle (high) |
| `0x77` | IR_RIGHT_IDLE_MEAS_LO | Right IR LED current during idle (low) |
| `0x78` | IR_ERRORS | Latched overcurrent fault flags |
| `0xA0` | CONFIG_ID | FPGA configuration identifier |
| `0xA1` | SW_VER_HI | FPGA software version (high byte) |
| `0xA2` | SW_VER_LO | FPGA software version (low byte) |

Current measurement registers are 9 bytes total starting from `0x70`.

## HID FPGA Commands

Accessible via HID command `e` (0x65), BS2 only:

| Sub-command | Code | Description |
|-------------|------|-------------|
| Reset | `R` | Pulse the FPGA reset pin |
| Reconfig | `B` | Pulse the RECONFIGN pin to reload FPGA configuration |
| I2C Write | `I` | Write data to FPGA registers over I2C |
| I2C Read | `i` | Read data from FPGA registers over I2C (added v0.3.9) |

### I2C Write Format (PC -> HMD)
```
Byte 0: 'e'
Byte 1: 'I'
Byte 2: Length (including register address)
Byte 3: Register address
Byte 4+: Data bytes to write
```

### I2C Read Format (PC -> HMD)
```
Byte 0: 'e'
Byte 1: 'i'
Byte 2: Length of bytes to read (not including register address)
Byte 3: Register address
```

### I2C Read Response (HMD -> PC)
```
Byte 0: 'e'
Byte 1: Length of bytes read
Byte 2+: Data bytes read from FPGA
```

## FPGA Boot Mode Detection

On startup (DVT-2 boards and later), the MCU checks if the FPGA is in bootloader mode and automatically reconfigures it into application mode:

- **v0.3.9:** Added startup check for FPGA configuration state
- **v0.3.10:** Increased wait time from ~50 ms to 5 seconds — the FPGA configuration takes ~3 seconds to complete, and the MCU wasn't waiting long enough
- **v0.3.12:** Only performs one reconfig attempt; prevents locking up in reconfig cycles for ~3 minutes when no camera application config is loaded

## Overcurrent Protection (v0.3.11+)

The MCU continuously polls the FPGA error register (`0x78`) for latched overcurrent faults:

1. FPGA reports overcurrent via latched fault flags in the error register
2. MCU detects the fault and sends `VIDEOPROC_EYETRACKING_ERROR` notification to the video processing task
3. Displays begin flashing with inverted colors as a visual warning
4. When fault clears, `VIDEOPROC_EYETRACKING_ERROR_CLEAR` restores normal display

This protects against IR LED failures or short circuits in the eye-tracking illumination system.

**Source files:** `src/Devices/eyetrack_fpga.c/h`  
**Python tool:** `scripts/fpga_commands.py`
