diff --git a/obu-firmware/FLASHING.md b/obu-firmware/FLASHING.md index 1ff6ef6..4279d83 100644 --- a/obu-firmware/FLASHING.md +++ b/obu-firmware/FLASHING.md @@ -35,23 +35,61 @@ C:\Espressif\frameworks\esp-idf-v6.0.2\export.ps1 idf.py --version # v6.0.2 ``` -## Going back to the previous firmware - -`firmware-backups/` in the repository root (gitignored) holds a full-flash image -of the COM3 board as it was before the port, with the esptool command to write -it back in its README.txt. - ## Build & flash +Flash over the board's **UART-bridge port** (CH343; COM3 for the production OBU +on the bench), not the native port the phone uses. + ```powershell cd C:\Users\Ashin\AndroidStudioProjects\MicrOBU\obu-firmware idf.py set-target esp32c5 # only needed once per clean build folder idf.py build -idf.py -p COM5 -b 921600 flash monitor +idf.py -p COM3 -b 921600 flash monitor ``` -Swap `COM5` for whatever port the ESP32-C5 enumerates as (Device Manager → +Swap `COM3` for whatever port the ESP32-C5's bridge enumerates as (Device Manager → Ports). `monitor` opens the serial console after flashing — `Ctrl+]` to exit. +Use `flash` (bootloader + partition table + app), not `app-flash`, whenever the +partition table may differ from what the board has. + +### First flash onto a board with the previous firmware + +The partition table changed with the port (NVS 24 KB → 80 KB, app 0x10000 → +0x20000), and the old NVS is full of Wi-Fi settings the previous firmware left +behind. Erase the whole new NVS range once, then do a full flash: + +```powershell +python -m esptool --chip esp32c5 -p COM3 -b 921600 erase-region 0x9000 0x15000 +idf.py -p COM3 -b 921600 flash +``` + +Without the erase, the board cannot store the BLE bond and the phone has to pair +on every connection (2026-09-23). After it: + +- the boot log shows `0 bonded phone(s) in NVS`, `BLE advertising started as + 'micrOBU-XXXX'` and `station task ready`; the radio stays off until the app + connects; +- on the first Connect the app provisions the demo credentials once (the card + says "Provisioning the demo credentials"); they stay in NVS from then on; +- a phone that was paired with the board before must forget `micrOBU-XXXX` in + Android's Bluetooth settings and pair again (passkey 123456). + +Erasing NVS later (e.g. after a partition change) has the same effects. + +## Going back to the previous firmware + +The previous, unsigned C firmware (frame types 0x01-0x05, CAM over USB only) +can come back two ways. The app detects it and falls back to its protocol. + +- **Image:** `firmware-backups/` in the repository root (gitignored, on the lab + laptop only) holds a full-flash image of the COM3 board as it was before the + port, with the esptool command in its README.txt. It restores the old + partition table and NVS too. +- **Source:** commit `7285fa1` is the last one before the port. Check it out in + a separate worktree and build it with the receiver firmware's IDF 6.1 + (`its-g5-receiver-firmware\esp-idf\export.ps1`). Erase the NVS range as above + first, then `flash` (full, since the partition table differs); erasing after + flashing would wipe the start of the old app, which sits at 0x10000. ## If the build fails @@ -71,9 +109,9 @@ Ports). `monitor` opens the serial console after flashing — `Ctrl+]` to exit. The board has two USB-C ports — use the right one: - **Native USB-C port** (labeled for JTAG/native USB, up to 12 Mbps) — this - is where the phone plugs in via USB-OTG. The CAM serial link - (`serial_link.c`) runs over the ESP32-C5's native USB Serial/JTAG - peripheral on this port, enumerating as a CDC-ACM device under Espressif's + is where the phone plugs in via USB-OTG. The station link + (`serial_link.cpp`: station-link messages as frame type 0x10 in the 0xAA55 + framing) runs over the ESP32-C5's native USB Serial/JTAG peripheral on this port, enumerating as a CDC-ACM device under Espressif's VID/PID (0x303A/0x1001). - **UART-bridge port** (labeled for flashing) — this is what you use for `idf.py flash monitor` from your PC. Leave the phone unplugged from this @@ -90,10 +128,10 @@ at all — that isolates a bad/charge-only OTG cable from an app-side issue. Work down this list — each step isolates the layer below it. -1. **Flash and install together.** `SERIAL_LINK_MAX_PAYLOAD` is 512 on both sides. - A phone at 512 talking to firmware still at 160 (or vice versa) silently - rejects every large frame at the `length exceeds max, resync` branch. Never - update one side alone. +1. **Flash and install together.** The app detects the firmware generation by + its heartbeat and speaks either protocol, but only an app from 2026-09-23 on + knows the station-link protocol; messages are at most 512 octets on both + sides. 2. **Does Android see the device at all?** Plug the phone into the **native** USB-C port, hit Connect, and read logcat for `UsbSerialTransport`. It logs every attached device *and* each device's interfaces. Empty list = cable / @@ -102,10 +140,12 @@ Work down this list — each step isolates the layer below it. composite device — expect CDC control (class 2) + CDC data (class 10) + vendor-specific JTAG (class 255) in that dump. Compare against the `ports=` count on the `matched device` line. -4. **Is the link alive?** The firmware sends a STATUS heartbeat at 1 Hz - regardless of radio traffic, and the app marks the link ERROR after ~3.5 s of - silence. Connected-and-staying-connected means device→host actually works. -5. **If it connects but no CAM_RX ever arrives** — suspect DTR. The app now +4. **Is the link alive?** The firmware sends a STATUS at 1 Hz regardless of + radio traffic, and the app marks the link ERROR after ~3.5 s of silence. + Connected-and-staying-connected means device→host actually works. The board + starts its radio only after the app's STATION_CONFIGURE, so nothing is + received before Connect. +5. **If it connects but no V2X_RX ever arrives** — suspect DTR. The app now asserts DTR/RTS on open (`openDevice()` in `UsbSerialTransport.kt`), because `CdcAcmSerialDriver` doesn't do it by default and the ESP32's USB Serial/JTAG endpoint may gate TX on the host opening the CDC line. **This is still @@ -114,9 +154,11 @@ Work down this list — each step isolates the layer below it. next to the VID/PID note, so nobody has to guess again. 6. **Watch the counters, not just "Sent: N".** The CAM Pinger card shows consecutive write failures (phone side) and the firmware's tx-failure / - oversize-drop / CRC-error totals from the heartbeat. A rising `tx fail` means - CAMs reach the ESP32 but `esp_wifi_80211_tx` rejects them — a radio problem, - not a link problem. + RX-queue-drop / CRC-error totals from the heartbeat; the connection card + shows tickets, signed and refused counts. A rising `tx fail` means messages + reach the ESP32 but the radio refuses them — a radio problem, not a link + problem. A rising `refused` with signing on usually means no ticket (NVS + erased: reconnect so the app provisions again). ## Connecting over Bluetooth instead