# Factory and Test Support

## FATP Video Modes

**FATP** (Final Assembly Test Plan) modes provide special video configurations for factory testing. Entered via HID command `@` (0x40):

| Mode | Byte 1 | Description |
|------|--------|-------------|
| Mode 0 | 0x00 | Two non-DSC modes: 3840x1920 @60Hz + 5120x2560 @30Hz |
| Mode 1 | 0x01 | One non-DSC mode: 3840x1920 @60Hz (removes 2560@30Hz) |
| Mode 2 | 0x02 | One DSC mode: 5088x2544 @60Hz (requires VXR firmware v03+) |
| Normal | 0xFF | Return to normal operating mode |

FATP modes change the EDID to advertise only the factory-test resolutions, then trigger an HPD toggle to force the GPU to re-enumerate the display.

### FATP Dimming

- 30 Hz mode uses multi-pulse emission instead of black frame insertion (v0.2.12) — prevents obvious strobing at low frame rates
- 60 Hz mode uses pulsed emission (v0.2.25)

**Note:** Config tag `0x07` (FATP Mode) exists but is not used at boot. FATP modes must be entered via the HID command.

## Hardware Self-Test Suite

Seven tests accessible via HID command `J` or via serial UART (factory floor use, v0.2.0):

| Test | Sub-cmd | Validates |
|------|---------|-----------|
| USB Hub | `H` | I2C connectivity to USB3803 hub(s) |
| RGB LED | `L` | I2C connectivity to LED driver IC |
| USB-C Switch | `S` | I2C connectivity to USB-C crossbar mux |
| VXR7200 | `V` | I2C connectivity to Synaptics display SoC |
| Proximity | `P` | I2C connectivity to TMD2635 sensor |
| OLED | `O` | I2C connectivity + panel ID readback from both OLEDs |
| Fan | `F` | Fan spins when commanded (mechanical verification) |

Response: pass (1) or fail (0).

### Display Test Patterns

- **Colorbar pattern:** HID command `=` — shows standard color bars on both OLEDs
- **Vertical bars fix:** v0.3.4 fixed a vertical bar artifact specific to 90 Hz mode
- **Display test script:** `scripts/display_test_60Hz.py` generates test patterns from the host PC

## Serial Number Programming

Three serial numbers can be stored in the config region:

| Serial | Config Tag | Typical Source |
|--------|-----------|----------------|
| PCBA Serial | 0x01 | Factory (contract manufacturer) |
| HMD Serial | 0x08 | Assembly line (after headset built) |
| Tracking Serial | 0x09 | Assembly line (tracking module paired) |

### Programming Tools

| Tool | Description |
|------|-------------|
| `scripts/update_hmd_serial.py` | Command-line serial number programmer |
| `scripts/SNPatcher/` | PyInstaller-packaged GUI serial number patcher |
| `scripts/config_editor.py` | Full config editor (can also set serials) |

## Firmware Update Tools

### MCU Firmware

| Tool | Description |
|------|-------------|
| `scripts/syn_fw_loader.py` | Low-level bootloader firmware loader (page-by-page) |
| `scripts/usb_fw_updater.py` | Higher-level update utility with progress reporting |

**Process:**
1. Send `BOOTLOADER` HID command to enter bootloader mode
2. Wait for device to re-enumerate with PID `0x4004`
3. Erase application region
4. Program pages (512 bytes each)
5. Verify CRC
6. Boot into new application

### VXR7200 Firmware

Updated via HID commands while the main application is running:
1. `VXR_DELETE` — Erase target flash bank (requires "VXRDELETE" safety phrase)
2. `VXR_PROGRAM` — Write data in 32-byte chunks
3. `VXR_CHECKSUM` — Verify programmed data
4. `VXR_RESET` — Reboot VXR7200 with new firmware

Pre-built firmware images are in `vxr7200_firmware/`.

## Monitoring and Diagnostic Tools

| Tool | Purpose |
|------|---------|
| `scripts/live_data_viewer.py` | Real-time plotting of HID telemetry (temperature, proximity, fan, etc.) |
| `scripts/temp_monitor.py` | Temperature monitoring (board + both displays) |
| `scripts/temp_sense.py` | Temperature sensor utilities |
| `scripts/stack_monitor.py` | FreeRTOS task stack usage viewer |
| `scripts/prox_monitor.py` | Real-time proximity sensor value monitor |
| `scripts/prox_calibration.py` | Interactive proximity sensor calibration |
| `scripts/prox_config.py` | Proximity settings configuration GUI |
| `scripts/crash_handler.py` | Parse crash dump data |
| `scripts/dump_crash_info.py` | Read and display crash info from device |
| `scripts/get_hmd_info.py` | Query all device information |
| `scripts/get_sw_ver.py` | Quick firmware version check |
| `scripts/hid_lib.py` | Shared HID communication library |
| `scripts/hid_query.py` | Raw HID command sender |
| `scripts/fpga_commands.py` | FPGA register read/write utility |
| `scripts/fatp_switcher.py` | FATP mode switching tool |

### Python Dependencies

- `hid` — USB HID communication
- `PyQt5` — GUI framework (config_editor)
- `pyimgui` — Alternative GUI framework (config_editor_imgui)
- `crc` — CRC calculation library
- `pyinstaller` — Packaging SNPatcher as standalone executable

## Board Version Detection

The firmware auto-detects the hardware variant at startup:

| Variant | Enum | Detection Method |
|---------|------|------------------|
| BS1 | `board_ver_BS1` | Default (no USB2517 or triple USB3803 found) |
| BS2 | `board_ver_BS2` | Triple USB3803 hub configuration detected |
| BS2-EVT | `board_ver_BS2_evt` | Engineering validation variant |
| Unknown | `board_ver_unknown` | Initial state before detection |

Since v0.3.5, builds are unified — a single firmware binary runs on both BS1 and BS2 with runtime feature gating.
