127 lines
5.5 KiB
Markdown
127 lines
5.5 KiB
Markdown
# ESP32-PICO-D4 (M5Stack Atom Lite) Port — Design Spec
|
|
|
|
> **Goal:** Port the Sylvia Touch Relay project from ESP32-S3-Pico (Atom S3 Lite) to ESP32-PICO-D4 (Atom Lite), update the Android app for CDC-class USB detection, compile, bundle, and deploy via ADB wireless.
|
|
|
|
## Current State
|
|
|
|
The project targets the M5Stack Atom S3 Lite (ESP32-S3). The Android app filters USB devices by Espressif vendor ID (`0x303A`) for key exchange and firmware flashing. The `esp32-flash-lib` handles DTR/RTS via the `SerialTransport` interface implemented by `UsbSerialTransport`.
|
|
|
|
## Target Hardware
|
|
|
|
M5Stack Atom Lite with ESP32-PICO-D4:
|
|
- 4MB Flash (no PSRAM)
|
|
- FTDI FT2232C/D USB-to-UART bridge (VID `0x0403`) — appears as `/dev/ttyUSB0`
|
|
- SK6812 addressable RGB LED on GPIO27
|
|
- Relay on GPIO32 (G32)
|
|
- Touch sensor on GPIO33 (G33) — open-drain type, needs pullup
|
|
|
|
## Design Decisions
|
|
|
|
### 1. Side Branch & Git Worktree
|
|
|
|
Create branch `esp32picod4` via git worktree at `.worktrees/esp32picod4` to isolate the port from the main S3 variant.
|
|
|
|
### 2. Firmware (`platformio.ini` + `src/main.cpp`)
|
|
|
|
**New PlatformIO environment `m5stack-atom`:**
|
|
|
|
| Setting | Old (S3) | New (PICO-D4) | Reason |
|
|
|---------|----------|---------------|--------|
|
|
| `board` | `esp32-s3-devkitc-1` | `m5stack-atom` | PlatformIO board ID for M5Stack Atom Lite |
|
|
| `board_build.arduino.memory_type` | `qio_opi` | removed | Not needed for PICO-D4 |
|
|
| `-DESP32S3` | present | `-DESP32` | Correct chip family |
|
|
| `-DBOARD_HAS_PSRAM` | present | removed | Atom Lite has no PSRAM |
|
|
| `-mfix-esp32-psram-cache-issue` | present | removed | Only needed with PSRAM |
|
|
| `-DARDUINO_USB_CDC_ON_BOOT=1` | present | removed | No native USB on PICO-D4 |
|
|
| `-DARDUINO_USB_MODE=1` | present | removed | No native USB |
|
|
| `upload_port` | `/dev/ttyACM0` | `/dev/ttyUSB0` | FTDI serial device |
|
|
| `lib_deps` | (empty) | `fastled/FastLED@^3.7` | SK6812 Neopixel library |
|
|
|
|
**Pin definitions:**
|
|
|
|
| Constant | Old | New | Notes |
|
|
|----------|-----|-----|-------|
|
|
| `SENSOR_PIN` | 38 | 33 | G33, open-drain, `INPUT_PULLUP` unchanged |
|
|
| `RELAY_PIN` | 1 | 32 | G32 |
|
|
| `LED_PIN` | 27 | 27 | SK6812 Neopixel — replaces `digitalWrite` with FastLED API |
|
|
|
|
**BLE device name:** `"SylDa_Server"` (was `"SyldaServer"`)
|
|
|
|
**Serial banner:** `"Atom Lite BLE Relay"` (was `"SylDa BLE Relay"`)
|
|
|
|
**LED code change:** Replace `digitalWrite(LED_PIN, HIGH/LOW)` with FastLED:
|
|
- Include `FastLED.h`
|
|
- Define `#define NUM_LEDS 1`
|
|
- `CRGB leds[NUM_LEDS]`
|
|
- `FastLED.addLeds<SK6812, LED_PIN, GRB>(leds, NUM_LEDS)` in setup
|
|
- Startup blink: 3x green (`leds[0] = CRGB::Green; FastLED.show()`)
|
|
|
|
No other firmware logic changes — HMAC key exchange, BLE relay control, touch sensor logic remain identical.
|
|
|
|
### 3. Android USB Detection
|
|
|
|
**Problem:** The Atom Lite's FTDI bridge presents VID `0x0403`, not Espressif's `0x303A`. The app currently filters on VID and won't detect the device.
|
|
|
|
**Solution:** Replace VID (`0x303A`) filtering with CDC-ACM class filtering (interface class `0x0A`).
|
|
|
|
**Changes in `UsbUtils.kt`:**
|
|
- Add `hasCdcDataInterface(device: UsbDevice): Boolean` — iterates interfaces, returns true if any has `interfaceClass == 0x0A`
|
|
|
|
**Changes in `SettingsActivity.kt`:**
|
|
- Remove `ESP_VENDOR_ID` constant
|
|
- Replace all `device?.vendorId == ESP_VENDOR_ID` checks with `UsbUtils.hasCdcDataInterface(device)`
|
|
|
|
This detects all CDC-ACM serial devices including:
|
|
- FTDI FT2232C/D (Atom Lite)
|
|
- CP210x (some Atom Lite revisions)
|
|
- ESP32-S3 native USB (current hardware)
|
|
- CH340/CH9102 (other Atom variants)
|
|
|
|
### 4. DTR/RTS — No Changes Needed
|
|
|
|
**Research findings:**
|
|
|
|
The `esp32-flash-lib`'s `EspFlasherProtocol.enterBootLoader()` implements the standard DTR/RTS download-mode sequence:
|
|
|
|
```
|
|
setControlLines(true, false) // DTR=High → EN released, RTS=Low → GPIO0=Low (download mode)
|
|
delayMS(100)
|
|
setControlLines(false, true) // DTR=Low → reset pulse via capacitor, RTS=High → GPIO0=High
|
|
delayMS(100)
|
|
setControlLines(true, false) // DTR=High → release reset, RTS=Low → GPIO0=Low → boot in download mode
|
|
```
|
|
|
|
The `UsbSerialTransport.setControlLines()` implementation sends `CDC_SET_CONTROL_LINE_STATE` control transfers with correct DTR/RTS bit flags. This works for FTDI, CP2104, and native USB CDC-ACM.
|
|
|
|
The `SettingsActivity.setupCdcControl()` sets DTR|RTS both HIGH for normal serial operation (key exchange), which is correct for all bridge types.
|
|
|
|
**Verdict: No changes to `EspFlasher.kt`, `UsbSerialTransport.kt`, or key exchange logic.**
|
|
|
|
### 5. Build, Bundle & Deploy
|
|
|
|
1. `pio run -e m5stack-atom` to compile firmware
|
|
2. `tools/copy_firmware.sh` to copy binaries to `android/app/src/main/assets/firmware/` (environment dir is now `m5stack-atom`)
|
|
3. `./gradlew assembleDebug` in `android/` to build APK
|
|
4. ADB wireless to connect phone (`adb-wireless` skill)
|
|
5. `adb install -r app-debug.apk` to deploy
|
|
|
|
## Files Changed
|
|
|
|
| File | Change |
|
|
|------|--------|
|
|
| `platformio.ini` | New environment `m5stack-atom` replacing S3 config |
|
|
| `src/main.cpp` | New pin definitions, BLE name, FastLED LED code |
|
|
| `android/.../UsbUtils.kt` | Add `hasCdcDataInterface()` |
|
|
| `android/.../SettingsActivity.kt` | VID filter → CDC class filter |
|
|
| `tools/copy_firmware.sh` | Environment name → `s3lite-server` |
|
|
|
|
## Files Not Changed
|
|
|
|
| File | Reason |
|
|
|------|--------|
|
|
| `EspFlasher.kt` | DTR/RTS handled by library |
|
|
| `UsbSerialTransport.kt` | Correct implementation |
|
|
| `MainActivity.kt` | No BLE changes beyond device name (auto-discovered) |
|
|
| `PrefsHelper.kt` | No changes |
|
|
| `AndroidManifest.xml` | No changes |
|
|
| `build.gradle` | No dependency changes |
|