# Power Usage and Power Saving Plan

## Status

Power has not been measured on hardware yet. This document describes expected power behavior based on the current firmware and the display/touch datasheets.

## Current power behavior

The current app is optimized for bring-up and UI demo behavior, not battery life.

Current firmware behavior:

- CPU runs at max clock (`CpuClock::max()`, 160 MHz on ESP32-C6).
- Main loop wakes every 25 ms.
- FT6336U touch is polled over I2C every loop.
- Front light starts enabled.
- Front light off currently toggles GPIO14, but the LM3630A driver is not put into sleep mode.
- Display GPIO diagnostics run on every boot.
- I2C bus scan runs on every boot.
- SSD1677 display controller is not explicitly put into low power mode after UI updates.

Expected display-side numbers from the GDEQ0426T82-FT01C datasheet:

- Panel operation: about 8 mA / 26.4 mW typical.
- Sleep mode: 40-70 uA.
- Deep sleep: 2-6 uA.

The front light is likely the largest power draw whenever enabled. Exact current depends on LM3630A full-scale current, brightness setting, LED string configuration, and GPIO14 enable behavior.

## Highest impact changes

### 1. Start with front light off

The demo currently initializes the front light as on. For battery use, default it off.

Implementation targets:

- `src/ui/screens/demo.rs`: initialize `light_on` to `false`.
- `src/bin/main.rs`: initialize GPIO14 low.
- Only enable LM3630A outputs when the UI light button turns the light on.

Expected impact: high when the device is idle or used in ambient light.

### 2. Put LM3630A into sleep when light is off

GPIO14 low may reduce power, but the LM3630A should also be commanded into sleep.

When light is off:

- Set brightness to 0.
- Disable bank A and bank B.
- Set `ControlConfig { sleep: true, ... }`.

When light is on:

- Clear sleep.
- Enable the needed banks.
- Restore brightness.

Expected impact: high if the backlight IC otherwise remains active.

### 3. Lower CPU clock

The UI demo does not need 160 MHz.

Change:

- Replace `CpuClock::max()` with `CpuClock::_80MHz` in `src/bin/main.rs`.

Expected impact: moderate for active and idle runtime.

### 4. Stop polling touch every 25 ms

The FT6336U has an `INT` pin according to the datasheet. If it is wired to the MCU, use it.

Preferred approach:

- Configure touch `INT` as a GPIO input interrupt.
- Only read FT6336U coordinates after an interrupt.
- Use the same interrupt as a wake source for sleep modes if supported.

Fallback if `INT` is not wired:

- Slow touch polling to 100-200 ms while idle.
- Poll faster only briefly after a touch or button input.

Expected impact: moderate. It cuts frequent I2C transactions and wakeups.

### 5. Power off the SSD1677 after updates

The SSD1677 driver already exposes:

- `power_off(...)`
- `deep_sleep(...)`

After each display update, explicitly power down the display controller when no further update is pending.

Suggested behavior:

- After full or partial refresh: `display.power_off(&mut Delay)`.
- After a longer idle timeout: `display.deep_sleep(&mut Delay)`.
- Before the next update after deep sleep: reinitialize the display.

Expected impact: high for display-controller idle current.

### 6. Remove boot diagnostics from normal builds

Current boot does extra diagnostics:

- Display GPIO diagnostics.
- I2C bus scan.

These are useful during bring-up but should be behind a debug feature or removed from production builds.

Expected impact: improves boot time and boot energy.

### 7. Add inactivity sleep

After a period with no touch or button input:

1. Turn front light off.
2. Put LM3630A into sleep.
3. Power off or deep sleep SSD1677.
4. Put ESP32-C6 into light sleep or deep sleep.
5. Wake from button GPIO or FT6336U INT.

Suggested timeouts:

- 10-30 seconds: front light off.
- 30-120 seconds: display controller deep sleep.
- Longer idle: MCU sleep.

Expected impact: highest for real battery use.

## Suggested implementation order

1. Measure current draw in current firmware.
2. Default front light off.
3. Add LM3630A sleep/on command handling.
4. Switch CPU to 80 MHz.
5. Disable boot diagnostics outside debug builds.
6. Power off SSD1677 after updates.
7. Use touch INT instead of polling, or slow polling if INT is unavailable.
8. Add inactivity sleep and wake sources.
9. Measure again after each change.

## Measurement plan

Measure at least these states:

1. Boot until first screen shown.
2. Idle with front light on.
3. Idle with front light off.
4. Touch interaction and partial refresh.
5. Full refresh.
6. SSD1677 powered off after refresh.
7. SSD1677 deep sleep.
8. MCU light sleep or deep sleep.

Record:

- Battery/input voltage.
- Average current.
- Peak current during refresh/front-light startup.
- Firmware commit.
- Front light brightness and current limit.
- Whether USB serial/debugger is connected.

## Open hardware questions

- Is FT6336U `INT` connected to an ESP32-C6 GPIO?
- Is FT6336U `RST` connected to an ESP32-C6 GPIO?
- Does GPIO14 fully cut LM3630A power/enable, or only gate an enable pin?
- Are both LM3630A banks needed for the light, or can one bank be disabled?
- What is the target battery capacity and desired runtime?
