# Power Management

## Power Rail Control

The MCU manages multiple voltage rails for the display system and peripherals:

| Rail | Voltage | Supplies | BS1 | BS2 |
|------|---------|----------|-----|-----|
| Core | 1.0V | VXR7200 | Switchable | Switchable (VXR power gating) |
| OLED/IO | 1.8V | OLED panels, VXR7200 I/O | Switchable | Always on |
| Logic | 3.3V | MCU, sensors, USB hubs, LED | Always on | Always on |
| OLED Power | — | OLED panel bias supplies | Switchable (BS1 only) | Tied to 1.8V |

### Power-On Sequence

1. 3.3V rail is always on when USB power is present
2. 1.0V rail enabled -> `VIDEOPROC_NOTIFY_1V0_READY`
3. 1.8V + OLED power enabled -> `VIDEOPROC_NOTIFY_1V8_AND_OLED_PWR_READY`
4. Wait 275 ms for VXR7200 to initialize after reset
5. Access VXR7200 Remote Control interface
6. Load EDID, configure display parameters

### OLED Power Control (BS1 only)

On BS1 hardware, the 1.8V supply can be individually controlled:
- `OLED_POWER_DISABLE` (`-` HID command): Turns off 1.8V rail
- `OLED_POWER_ENABLE` (`+` HID command): Turns on 1.8V rail

**Warning from v0.3.7C:** A bug was fixed where the BS1 code path was incorrectly shutting down the 1.8V supply on BS2, which doesn't support individual control of that rail.

### VXR7200 Power Gating (BS2)

The VXR7200 can be independently power-gated by controlling its 1.0V rail:
- Power down: `VIDEOPROC_VXR_POWER_DOWN` task notification
- Power up: `VIDEOPROC_VXR_POWER_UP` task notification
- Auto-shutdown (sleep mode) configurable as a nonvolatile option

**Source files:** `src/Drivers/power_control.c/h`

## Temperature Monitoring

Three temperature sensors are continuously monitored:

| Sensor | Location | Units | Reporting |
|--------|----------|-------|-----------|
| Board | Main PCB | Kelvin | 4-byte packed float in telemetry |
| Left Display | Left OLED panel | Celsius | 4-byte packed float in telemetry |
| Right Display | Right OLED panel | Celsius | 4-byte packed float in telemetry |

- Board temperature measured via on-chip ADC
- Display temperatures read via I2C from OLED panel registers
- Temperature compensation applied during OLED initialization (v0.2.20)

**Source files:** `src/Drivers/temp_sense.c/h`  
**Python tools:** `scripts/temp_monitor.py`, `scripts/temp_sense.py`

## USB-C Detection

### CC Pin Monitoring

The MCU reads the USB-C CC1 and CC2 pins via ADC to determine:
- Cable orientation (which CC pin is connected)
- Power delivery capability
- Raw ADC values reported in periodic telemetry (bytes 6–9)

### Hot Plug Detect (HPD)

The DisplayPort HPD line is monitored to detect display connection state:
- Normal polarity for standard Linkbox
- Inverted polarity for Linkbox V1 (configured via deprecated config tag `0x05`)

**Source files:** `src/Devices/linkbox_hpd.c/h`, `src/Drivers/adc.c/h`

## Fan Control

PWM-based fan speed control with a three-state state machine (v0.3.14):

### Fan States

| State | Behavior |
|-------|----------|
| **Idle** | Fan off unless overtemperature threshold exceeded. Deferred speed (`f`) only stored for later. |
| **Video** | Fan runs at preset speed (from config or deferred HID command). Either `F` or `f` changes speed immediately. Exits to Idle when video stops. |
| **Debug** | Fan speed set directly by immediate HID command (`F`). Exits on video start, deferred command (`f`), or speed set to 0. |

### Features

| Feature | Description |
|---------|-------------|
| Range | 0–100% duty cycle |
| Soft start | Gradual ramp-up instead of instant jump (v0.2.4) |
| Immediate mode | `F` HID command — takes effect now, enters Debug state if in Idle |
| Deferred mode | `f` HID command — preset stored, applied when video turns on (v0.3.1) |
| Default speed | Stored in config tag `0x03`, loaded at startup |
| Display-linked | Fan turns on/off with video signal (v0.2.6) |
| Overtemperature auto-fan | Three-level automatic fan control with hysteresis, active even in Idle (v0.3.14) |

### Overtemperature Protection (v0.3.14)

When video is off (Idle state), the fan still activates if board temperature exceeds thresholds:

| Level | Condition | Action |
|-------|-----------|--------|
| None | Below threshold 1 | Fan off |
| Level 1 | Above threshold 1 | Fan at level 1 speed |
| Level 2 | Above threshold 2 | Fan at level 2 speed |
| Level 3 | Above threshold 3 | Fan at level 3 speed |

Each level has hysteresis — the fan steps down only when temperature drops below (threshold - hysteresis), preventing rapid on/off cycling.

**Source files:** `src/test_and_debug.c` (fan task), `src/Devices/fan_motor_control.c/h`

## RGB LED

Indicator LED controlled via I2C LED driver:

- 24-bit color (R, G, B each 0–255)
- Three animation modes selectable via byte 4 of the HID `L` command (v0.3.19):
  - **Static** (mode 1): Solid color at fixed brightness
  - **Breathing** (mode 2): Smooth fade in/out cycle (tweaked in v0.2.6)
  - **Blinking** (mode 3): On/off toggle at ~5-tick interval
  - Mode 0 or omitted: Set color only, keep current animation mode
- Turns on/off with video signal (v0.2.6)
- Default color stored in config tag `0x02`
- Set via HID `L` command

**Source files:** `src/Devices/rgb_led.c/h`, `src/test_and_debug.c/h`

## VBUS Monitoring

- GPIO-based detection of USB VBUS presence
- Determines if the headset is connected to a powered USB host
- Used for power management decisions

**Source files:** `src/main.c` (`vbus_monitor_start()`, `vbus_is_present()`)
