# GCU Flasher — User Guide

## Installation

**macOS:** Double-click "GCU Flasher.app" or run `wish flasher.tcl` from Terminal.

**Windows:** Double-click "GCU Flasher.bat" (includes a bundled Tcl runtime).

No installation required. The app, firmware files, and bossac flasher are all in the zip.

## Flashing Firmware

1. Connect the GCU via USB
2. Select the firmware file from the dropdown (CAN or KLine)
3. Select the serial port (click Refresh if it doesn't appear)
4. Click "Flash Firmware" — the GCU will reboot into bootloader mode automatically
5. Wait for "Flash complete" in the log

## Viewing the Console

Click "View Console" to connect to the GCU's serial output at 115200 baud. You'll see live log lines: heartbeats (HB), paddle events (PAD), shift events (SHIFT), and valve operations (VALVE).

When connected, the window splits into two panes:

- **Left:** Console log with filter checkboxes and a command input field
- **Right:** Three tabbed panels (Live Data, Diagnostics, Configuration)

### Filters

Message type toggles, all on by default. Uncheck to hide that type:

- **HB** — heartbeat lines (1Hz)
- **SHIFT** — shift start/success/fail/complete and countershift lines
- **PADDL** — paddle press/release events
- **VALVE** — valve open/close with attribution
- **Other** — everything else (MODE, WARN, ERR, protocol responses)

### Command Input

Type serial commands directly in the input field at the bottom of the console and press Enter. Commands are sent to the GCU exactly as typed. Use Up/Down arrow keys to recall previous commands.

## Auto-Discovery on Connect

When the flasher connects, it automatically sends:

1. `GET_MODE` — detect access level
2. `GET_VERSION` — show firmware version and git hash
3. `GET_CONSTS` — populate Configuration tab
4. `DUMP_STATUS` — show last reset cause (watchdog/brownout/power-on), uptime, and any queued log events from the RAM buffer

If the last reset was a watchdog timeout, the status bar turns red with a warning.

## Access Mode

The GCU starts in Racing Mode where all serial commands are read-only. To enable diagnostic commands (shifting, tuning constants, clearing logs):

1. Click "Enable Write Access" in the Diagnostics tab
2. The button sends `UNLOCK_ACCESS CONFIRM` to the GCU
3. Write buttons become active (blue instead of gray)

Access automatically locks after 5 minutes of no write commands, or when you disconnect. You can also lock manually by typing `LOCK_ACCESS` in the command input.

## Live Data Tab

Shows real-time telemetry parsed from heartbeat lines:

- **Drive:** Current gear, RPM, tank pressure (PSI), shift mode (MOTO/BTN), gear source (GP sensor, CAN, or fallback)
- **Shift State:** Current phase, whether a shift is active, last shift ID
- **Health:** Loop count, serial/paddle drops, ghost shifts, double shifts, uptime
- **CAN:** RPM and gear data validity flags

Values update every second with the heartbeat. Red values indicate anomalies (ghost shifts, invalid CAN data).

## Diagnostics Tab

Requires Access Mode. All buttons are grayed out in Racing Mode.

**Shifts:**

- **Upshift / Downshift** — triggers a real shift through the normal routing (safety checks, moto-mode logic, closed-loop validation all apply)
- **NT checkbox** — when checked, the next shift button sends a neutral shift command instead (NT+UP or NT+DOWN), then auto-unchecks

**Systems:**

- **WSS** toggle — starts/stops the wheel speed sensor emulation (needed to prevent ECU limp mode)
- **Compressor** toggle — manually controls the compressor relay

**Logs:**

- **Dump Rolling / Exception Log** — outputs the full log to the console (may take a few seconds)
- **Log Stats** — shows log file sizes and entry counts
- **Clear All Logs** — erases both logs (confirmation required)

## Configuration Tab

Requires Access Mode. Shows all 23 tunable constants with their current values, types, and valid ranges.

Each constant has an input field and an Apply button. Edit the value and click Apply to change it at runtime. The change takes effect immediately (or on the next shift, for shift-timing constants that are snapshotted at shift start).

**Types:**

- **int** — integer with min/max range shown
- **bool** — checkbox (0 or 1)
- **float** — decimal with min/max range (e.g., 0.80 to 1.00)
- **enum** — dropdown with named options (e.g., moto(1n2) or car(n12))

**Buttons:**

- **Reload All** — re-reads all constants from the GCU
- **Save to Flash** — persists current values to the GCU's flash memory (survives reboot)
- **Reset to Defaults** — restores all constants to their compile-time defaults and deletes the flash file (confirmation required)

## Serial Simulator

For testing without hardware:

```bash
python3 tools/sim-serial.py
```

This creates a virtual serial port. Connect the flasher to the PTY path printed on startup. The simulator responds to all commands and generates synthetic heartbeats and shift events.

## Troubleshooting

**Port not showing up:** Click Refresh. On macOS, the port is usually `/dev/cu.usbmodem*`. On Windows, check Device Manager for the COM port number.

**Flash fails / board never enters the bootloader:** Flash sends a 1200-baud reset and waits up to 10 seconds for the board to come back as the bootloader port. A few boards ignore it. Double-tap the RESET button on the Feather M4, click Refresh, pick the port that appears, and flash again.

**"WRITE_DENIED" errors:** You need to enable Access Mode first. Click "Enable Write Access" in the Diagnostics tab.

**Constants not saving across reboot:** After changing values with SET, click "Save to Flash" in the Configuration tab. Without saving, changes are lost on power cycle.

**WSS/limp mode:** If the ECU enters limp mode (low RPM cap, reduced power), toggle WSS On in the Diagnostics tab. The Suzuki ECU requires wheel speed sensor input.
