# QT Py SAMD21 Firmware: Flash + Smoke Test

## Current status

The firmware now builds for `thumbv6m-none-eabi` and includes:
- USB HID OUT report polling
- HID packet parser
- DRV2605L command dispatch over I2C

## Build

Use:
- `tools/scripts/build_firmware.ps1`

## Integrated UF2 workflow (recommended)

Use:
- `tools/scripts/build_and_make_uf2.ps1`

What it does:
1. Builds firmware for `thumbv6m-none-eabi`
2. Produces `build/firmware/qtpy-samd21-fw.bin`
3. Converts BIN to UF2 with `uf2conv.py` into `build/firmware/qtpy-samd21-fw.uf2`

Optional first-run tooling setup:
- add `-InstallTooling`

Optional auto-copy to mounted bootloader drive:
- add `-Deploy`

## Flashing options

### Option A (recommended for convenience): UF2 bootloader drag-and-drop

1. Double-tap reset on QT Py to mount `QTPYBOOT`.
2. Run `tools/scripts/build_and_make_uf2.ps1 -Deploy`.
3. Board reboots into application firmware automatically after copy.

### Option B: SWD + probe-rs

If you have SWD access, flash directly with probe tooling.

## Host smoke test

After board reconnects as USB HID, run:
- `tools/scripts/host_hid_smoke_test.ps1`

Default smoke packet:
- Command `0x01` (`SET_INTENSITY`)
- Intensity `64`
- VID/PID `0x35bd` / `0xfe01`

## Next recommended firmware increments

1. DRV2605L init sequence (mode exit standby, optional calibration)
2. Better error handling/recovery for I2C bus faults
3. Optional HID IN status report path (ack/error counters)
4. Real waveform/time semantics for ROM effect + duration handling
