# Feather S3 TFT Firmware This directory contains the ESP-IDF firmware for the Feather S3 TFT signer target. ## USB transport mode Firmware now runs in **TinyUSB composite mode** (single USB peripheral owned by TinyUSB), exposing: - CDC-ACM interface for Python/serial tooling (`/dev/ttyACM*`) - Vendor interface for WebUSB browser transport Expected runtime USB identity: - VID:PID `303a:4001` - Product string: `Feather S3 TFT n_signer` ## Flashing workflow (important) Because TinyUSB owns USB at runtime, normal app mode is not the ROM USB-Serial/JTAG flashing interface. Use this workflow for flashing: 1. Enter bootloader mode: hold **BOOT**, tap **RESET**, release **BOOT**. 2. Confirm bootloader USB device appears (typically `/dev/ttyACM0`). 3. Flash: ```bash cd firmware/feather_s3_tft idf.py -p /dev/ttyACM0 flash ``` 4. Exit bootloader and run app: ensure BOOT is released, then tap **RESET** once. 5. Confirm app USB identity: ```bash lsusb | grep -i 303a # expect: 303a:4001 n_signer Feather S3 TFT n_signer ``` ## Quick validation CDC path: ```bash ./.venv/bin/python ./examples/feather_get_public_key.py /dev/ttyACM0 ./.venv/bin/python ./examples/feather_sign_event.py /dev/ttyACM0 ``` WebUSB path: - Open [`examples/feather_webusb_demo.html`](../examples/feather_webusb_demo.html) - Connect in Chrome/Edge - Run `get_public_key` - Confirm pubkey matches CDC result ## Linux WebUSB host setup (one-time) Chrome and Edge need permission to open the device on Linux. Install a udev rule for the firmware VID:PID and reload rules: ```bash sudo tee /etc/udev/rules.d/99-nsigner-webusb.rules >/dev/null <<'EOF' SUBSYSTEM=="usb", ATTR{idVendor}=="303a", ATTR{idProduct}=="4001", MODE="0666", GROUP="plugdev", TAG+="uaccess" EOF sudo udevadm control --reload-rules sudo udevadm trigger ``` After installing the rule, unplug and replug the device once, then reload the demo page. ## Troubleshooting - If `lsusb` shows `303a:1001`, the board is still in ROM bootloader mode. Tap RESET with BOOT released. - If CDC command hangs, verify app-mode VID:PID is `303a:4001`, not `303a:1001`. - If no `/dev/ttyACM*` appears, unplug/replug after reset and re-check `lsusb`. - If WebUSB connect throws `SecurityError: Access denied`, install the Linux udev rule above and replug. ## CYD ESP32-2432S028 (CH340) serial-reset hardware note For the CYD board (`firmware/cyd_esp32_2432s028`), opening `/dev/ttyUSB0` can reset the ESP32 because CH340 DTR/RTS control lines are wired into the ESP32 auto-reset circuit. Symptoms: - Device returns to startup/menu when a host app opens serial - Browser/CLI connect appears to "knock" signer out of ready screen Field-proven mitigation: - Add a **10uF capacitor between EN and GND** on the CYD board - A practical solder point is across the board reset path (e.g. reset button EN/GND pads) - For polarized electrolytic caps: **negative leg to GND**, positive to EN Expected result after this hardware mod: - Serial open no longer triggers unwanted reset in normal host workflows - Signer remains in ready state across browser/CLI connect events Notes: - Typical working range is ~4.7uF to 22uF; 10uF is recommended - Keep leads short for best stability - Auto-reset behavior for flashing may still work, but if flashing ever becomes unreliable, enter bootloader manually