chore: remove research docs from git tracking, add to .gitignore
This commit is contained in:
parent
0833327cea
commit
15498d025a
14 changed files with 9 additions and 2778 deletions
|
|
@ -1,499 +0,0 @@
|
|||
# ESP32-PICO-D4 (M5Stack Atom Lite) Port — Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Port the Sylvia Touch Relay project from ESP32-S3-Pico to ESP32-PICO-D4 (Atom Lite) with relay on G32, touch on G33 (pullup), SK6812 LED on G27, CDC-class USB detection in the Android app, and deploy via ADB wireless.
|
||||
|
||||
**Architecture:** Create side branch `esp32picod4` via git worktree. Replace platformio.ini S3 config with `m5stack-atom` board + FastLED library. Update pin definitions and LED code in main.cpp. Replace Android USB VID filter with CDC-ACM class filter. No DTR/RTS changes needed — the esp32-flash-lib handles it correctly.
|
||||
|
||||
**Tech Stack:** C++/Arduino (FastLED), PlatformIO (espressif32@6.7.0), Android/Kotlin (AGP 8.5.2, Gradle 8.14), ADB (wireless debugging)
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Create sidebranch using git worktree
|
||||
|
||||
**Files:**
|
||||
- Create: `.worktrees/esp32picod4/` (git worktree directory)
|
||||
|
||||
- [ ] **Step 1: Create and switch to sidebranch in worktree**
|
||||
|
||||
```bash
|
||||
git worktree add -b esp32picod4 .worktrees/esp32picod4
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Verify branch is active**
|
||||
|
||||
```bash
|
||||
git -C .worktrees/esp32picod4 branch --show-current
|
||||
```
|
||||
Expected: `esp32picod4`
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Update PlatformIO configuration for PICO-D4
|
||||
|
||||
**Files:**
|
||||
- Modify: `platformio.ini`
|
||||
|
||||
**Worktree path:** `.worktrees/esp32picod4/platformio.ini`
|
||||
|
||||
- [ ] **Step 1: Replace entire platformio.ini content**
|
||||
|
||||
```ini
|
||||
[env:m5stack-atom]
|
||||
platform = espressif32@6.7.0
|
||||
board = m5stack-atom
|
||||
framework = arduino
|
||||
build_flags =
|
||||
-DESP32
|
||||
-DCORE_DEBUG_LEVEL=5
|
||||
lib_deps =
|
||||
fastled/FastLED@^3.7.0
|
||||
upload_port = /dev/ttyUSB0
|
||||
upload_speed = 115200
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Verify m5stack-atom board exists in PlatformIO**
|
||||
|
||||
```bash
|
||||
pio boards --json-output 2>/dev/null | python3 -c "import json,sys; boards=[b['id'] for b in json.load(sys.stdin) if 'm5stack-atom' in b['id']]; print('\n'.join(boards) if boards else 'NOT FOUND')"
|
||||
```
|
||||
Expected: `m5stack-atom` (or similar variant)
|
||||
|
||||
- [ ] **Step 3: Commit platformio.ini**
|
||||
|
||||
```bash
|
||||
git -C .worktrees/esp32picod4 add platformio.ini
|
||||
git -C .worktrees/esp32picod4 commit -m "feat: switch platformio config to m5stack-atom (ESP32-PICO-D4)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Update firmware for Atom Lite (pins, LED, BLE name)
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/main.cpp`
|
||||
|
||||
**Worktree path:** `.worktrees/esp32picod4/src/main.cpp`
|
||||
|
||||
- [ ] **Step 1: Replace pin definitions (lines 10-12)**
|
||||
|
||||
Replace:
|
||||
```cpp
|
||||
#define SENSOR_PIN 38
|
||||
#define RELAY_PIN 1
|
||||
#define LED_PIN 46
|
||||
```
|
||||
|
||||
With:
|
||||
```cpp
|
||||
#include <FastLED.h>
|
||||
|
||||
#define SENSOR_PIN 33
|
||||
#define RELAY_PIN 32
|
||||
#define LED_PIN 27
|
||||
#define NUM_LEDS 1
|
||||
|
||||
CRGB leds[NUM_LEDS];
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Replace setup() LED init and blink code (lines 139-149)**
|
||||
|
||||
Replace:
|
||||
```cpp
|
||||
pinMode(SENSOR_PIN, INPUT_PULLUP);
|
||||
pinMode(RELAY_PIN, OUTPUT);
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
delay(200);
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
delay(200);
|
||||
}
|
||||
Serial.println("LED blink done, starting BLE...");
|
||||
```
|
||||
|
||||
With:
|
||||
```cpp
|
||||
pinMode(SENSOR_PIN, INPUT_PULLUP);
|
||||
pinMode(RELAY_PIN, OUTPUT);
|
||||
|
||||
FastLED.addLeds<SK6812, LED_PIN, GRB>(leds, NUM_LEDS);
|
||||
FastLED.setBrightness(32);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
leds[0] = CRGB::Green;
|
||||
FastLED.show();
|
||||
delay(200);
|
||||
leds[0] = CRGB::Black;
|
||||
FastLED.show();
|
||||
delay(200);
|
||||
}
|
||||
Serial.println("LED blink done, starting BLE...");
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Replace Serial banner and BLE device name**
|
||||
|
||||
Replace (line 125):
|
||||
```cpp
|
||||
Serial.println("=== Atom VoiceS3R BLE Relay ===");
|
||||
```
|
||||
|
||||
With:
|
||||
```cpp
|
||||
Serial.println("=== Atom Lite BLE Relay ===");
|
||||
```
|
||||
|
||||
Replace (line 151):
|
||||
```cpp
|
||||
BLEDevice::init("AtomS3R-Relay");
|
||||
```
|
||||
|
||||
With:
|
||||
```cpp
|
||||
BLEDevice::init("SyldaServer");
|
||||
```
|
||||
|
||||
Replace (line 174):
|
||||
```cpp
|
||||
Serial.println("BLE: advertising started as 'AtomS3R-Relay'");
|
||||
```
|
||||
|
||||
With:
|
||||
```cpp
|
||||
Serial.println("BLE: advertising started as 'SyldaServer'");
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Verify main.cpp has no remaining S3-specific or AtomS3R references**
|
||||
|
||||
```bash
|
||||
grep -n "S3R\|S3\|Atom Voice\|46\|G38\|G1\b" .worktrees/esp32picod4/src/main.cpp
|
||||
```
|
||||
Expected: no output (no matches)
|
||||
|
||||
- [ ] **Step 5: Commit main.cpp**
|
||||
|
||||
```bash
|
||||
git -C .worktrees/esp32picod4 add src/main.cpp
|
||||
git -C .worktrees/esp32picod4 commit -m "feat: port firmware to Atom Lite (G32 relais, G33 touch, G27 SK6812 LED, SyldaServer BLE)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Update copy_firmware.sh for new environment name
|
||||
|
||||
**Files:**
|
||||
- Modify: `tools/copy_firmware.sh`
|
||||
|
||||
**Worktree path:** `.worktrees/esp32picod4/tools/copy_firmware.sh`
|
||||
|
||||
- [ ] **Step 1: Change environment directory name (line 4)**
|
||||
|
||||
Replace:
|
||||
```bash
|
||||
BINARY_DIR="$(cd "$(dirname "$0")/.." && pwd)/.pio/build/m5stack-atoms3r"
|
||||
```
|
||||
|
||||
With:
|
||||
```bash
|
||||
BINARY_DIR="$(cd "$(dirname "$0")/.." && pwd)/.pio/build/m5stack-atom"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git -C .worktrees/esp32picod4 add tools/copy_firmware.sh
|
||||
git -C .worktrees/esp32picod4 commit -m "chore: update copy_firmware.sh for m5stack-atom environment"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: Add CDC-class USB detection to UsbUtils.kt
|
||||
|
||||
**Files:**
|
||||
- Modify: `android/app/src/main/java/com/eddy/atomrelay/UsbUtils.kt`
|
||||
|
||||
**Worktree path:** `.worktrees/esp32picod4/android/app/src/main/java/com/eddy/atomrelay/UsbUtils.kt`
|
||||
|
||||
- [ ] **Step 1: Add hasCdcDataInterface function**
|
||||
|
||||
After the `findBulkEndpoint` function (before the closing `}` of `object UsbUtils`), add:
|
||||
|
||||
```kotlin
|
||||
fun hasCdcDataInterface(device: UsbDevice): Boolean {
|
||||
for (i in 0 until device.interfaceCount) {
|
||||
if (device.getInterface(i).interfaceClass == CDC_DATA_INTERFACE_CLASS) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git -C .worktrees/esp32picod4 add android/app/src/main/java/com/eddy/atomrelay/UsbUtils.kt
|
||||
git -C .worktrees/esp32picod4 commit -m "feat: add CDC-class USB detection for universal bridge support"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: Replace VID filter with CDC-class filter in SettingsActivity.kt
|
||||
|
||||
**Files:**
|
||||
- Modify: `android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt`
|
||||
|
||||
**Worktree path:** `.worktrees/esp32picod4/android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt`
|
||||
|
||||
- [ ] **Step 1: Remove ESP_VENDOR_ID constant (line 39)**
|
||||
|
||||
Delete:
|
||||
```kotlin
|
||||
private const val ESP_VENDOR_ID = 0x303a
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Replace VID check in usbAttachedReceiver (line 67)**
|
||||
|
||||
Replace:
|
||||
```kotlin
|
||||
if (device?.vendorId == ESP_VENDOR_ID) {
|
||||
```
|
||||
|
||||
With:
|
||||
```kotlin
|
||||
if (device != null && UsbUtils.hasCdcDataInterface(device)) {
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Replace VID check in usbPermissionReceiver (line 85)**
|
||||
|
||||
Replace:
|
||||
```kotlin
|
||||
val device = usbManager.deviceList.values.firstOrNull { it.vendorId == ESP_VENDOR_ID }
|
||||
```
|
||||
|
||||
With:
|
||||
```kotlin
|
||||
val device = usbManager.deviceList.values.firstOrNull { UsbUtils.hasCdcDataInterface(it) }
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Replace VID check in usbDetachedReceiver (line 101)**
|
||||
|
||||
Replace:
|
||||
```kotlin
|
||||
if (device?.vendorId == ESP_VENDOR_ID) {
|
||||
```
|
||||
|
||||
With:
|
||||
```kotlin
|
||||
if (device != null && UsbUtils.hasCdcDataInterface(device)) {
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Replace VID check in startKeyExchange (line 208)**
|
||||
|
||||
Replace:
|
||||
```kotlin
|
||||
val device = usbManager.deviceList.values.firstOrNull { it.vendorId == ESP_VENDOR_ID }
|
||||
```
|
||||
|
||||
With:
|
||||
```kotlin
|
||||
val device = usbManager.deviceList.values.firstOrNull { UsbUtils.hasCdcDataInterface(it) }
|
||||
```
|
||||
|
||||
- [ ] **Step 6: Replace VID check in startFlashing (line 256)**
|
||||
|
||||
Replace:
|
||||
```kotlin
|
||||
val device = usbManager.deviceList.values.firstOrNull { it.vendorId == ESP_VENDOR_ID }
|
||||
```
|
||||
|
||||
With:
|
||||
```kotlin
|
||||
val device = usbManager.deviceList.values.firstOrNull { UsbUtils.hasCdcDataInterface(it) }
|
||||
```
|
||||
|
||||
- [ ] **Step 7: Verify no remaining ESP_VENDOR_ID references**
|
||||
|
||||
```bash
|
||||
grep -n "ESP_VENDOR_ID\|vendorId.*==" .worktrees/esp32picod4/android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt
|
||||
```
|
||||
Expected: no output
|
||||
|
||||
- [ ] **Step 8: Commit**
|
||||
|
||||
```bash
|
||||
git -C .worktrees/esp32picod4 add android/app/src/main/java/com/eddy/atomrelay/SettingsActivity.kt
|
||||
git -C .worktrees/esp32picod4 commit -m "feat: replace USB VID filter with CDC-ACM class detection"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 7: Compile firmware
|
||||
|
||||
**Files:** N/A (build artifacts in `.pio/build/m5stack-atom/`)
|
||||
|
||||
**Work tree path:** `.worktrees/esp32picod4/`
|
||||
|
||||
- [ ] **Step 1: Clean and compile**
|
||||
|
||||
```bash
|
||||
pio run -d .worktrees/esp32picod4 -e m5stack-atom -t clean
|
||||
pio run -d .worktrees/esp32picod4 -e m5stack-atom
|
||||
```
|
||||
Expected: `SUCCESS` at end of output
|
||||
|
||||
- [ ] **Step 2: Verify build output files**
|
||||
|
||||
```bash
|
||||
ls -la .worktrees/esp32picod4/.pio/build/m5stack-atom/firmware.bin \
|
||||
.worktrees/esp32picod4/.pio/build/m5stack-atom/bootloader.bin \
|
||||
.worktrees/esp32picod4/.pio/build/m5stack-atom/partitions.bin
|
||||
```
|
||||
Expected: all 3 files exist with non-zero size
|
||||
|
||||
---
|
||||
|
||||
### Task 8: Copy firmware binaries to Android app assets
|
||||
|
||||
**Files:**
|
||||
- Modify: `android/app/src/main/assets/firmware/` (destination)
|
||||
|
||||
**Worktree path:** `.worktrees/esp32picod4/`
|
||||
|
||||
- [ ] **Step 1: Run copy script**
|
||||
|
||||
```bash
|
||||
bash .worktrees/esp32picod4/tools/copy_firmware.sh
|
||||
```
|
||||
Expected: lists 4 files (bootloader.bin, partitions.bin, firmware.bin, boot_app0.bin)
|
||||
|
||||
- [ ] **Step 2: Verify boot_app0.bin is also present**
|
||||
|
||||
```bash
|
||||
ls -la .worktrees/esp32picod4/android/app/src/main/assets/firmware/boot_app0.bin
|
||||
```
|
||||
Expected: file exists
|
||||
|
||||
- [ ] **Step 3: Commit binary assets**
|
||||
|
||||
```bash
|
||||
git -C .worktrees/esp32picod4 add android/app/src/main/assets/firmware/
|
||||
git -C .worktrees/esp32picod4 commit -m "feat: add Atom Lite firmware binaries to Android assets"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 9: Build Android APK
|
||||
|
||||
**Files:** N/A (build output `android/app/build/outputs/apk/debug/app-debug.apk`)
|
||||
|
||||
**Worktree path:** `.worktrees/esp32picod4/android/`
|
||||
|
||||
- [ ] **Step 1: Build debug APK**
|
||||
|
||||
```bash
|
||||
JAVA_HOME=/home/linuxbrew/.linuxbrew/opt/openjdk@21/libexec ./gradlew assembleDebug
|
||||
```
|
||||
Expected: `BUILD SUCCESSFUL`
|
||||
|
||||
- [ ] **Step 2: Verify APK exists**
|
||||
|
||||
```bash
|
||||
ls -la app/build/outputs/apk/debug/app-debug.apk
|
||||
```
|
||||
Expected: file exists with size > 1MB
|
||||
|
||||
---
|
||||
|
||||
### Task 10: Connect Android phone via ADB wireless
|
||||
|
||||
**Files:** N/A (ADB system tool)
|
||||
|
||||
- [ ] **Step 1: Load adb-wireless skill**
|
||||
|
||||
Use the `adb-wireless` skill to establish a wireless ADB connection to the Android phone.
|
||||
|
||||
- [ ] **Step 2: Verify ADB connection**
|
||||
|
||||
```bash
|
||||
adb devices
|
||||
```
|
||||
Expected: `<ip>:5555` listed as `device`
|
||||
|
||||
---
|
||||
|
||||
### Task 11: Install APK on phone
|
||||
|
||||
**Files:** N/A (app deployment)
|
||||
|
||||
- [ ] **Step 1: Install APK**
|
||||
|
||||
```bash
|
||||
adb install -r .worktrees/esp32picod4/android/app/build/outputs/apk/debug/app-debug.apk
|
||||
```
|
||||
Expected: `Success`
|
||||
|
||||
- [ ] **Step 2: Launch the app**
|
||||
|
||||
```bash
|
||||
adb shell am start -n com.eddy.atomrelay/.MainActivity
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 12: Flash firmware to Atom Lite via Android app
|
||||
|
||||
**Files:** N/A (manual device action)
|
||||
|
||||
- [ ] **Step 1: Connect Atom Lite via USB-OTG to the phone**
|
||||
- [ ] **Step 2: Open the app, tap settings gear → "Firmware Flashen"**
|
||||
- [ ] **Step 3: If app doesn't auto-detect, unplug/replug the Atom Lite while the dialog is open**
|
||||
- [ ] **Step 4: Wait for flash to complete (progress bar reaches 100%)**
|
||||
- [ ] **Step 5: After flash, disconnect USB — the Atom Lite should reboot with green LED blink 3x**
|
||||
|
||||
---
|
||||
|
||||
### Task 13: Provision HMAC key via app
|
||||
|
||||
**Files:** N/A (manual device action)
|
||||
|
||||
- [ ] **Step 1: Reconnect Atom Lite via USB-OTG to phone (NOT in download mode — just power on normally)**
|
||||
- [ ] **Step 2: Open app → Settings → "Sleutel Uitwisselen"**
|
||||
- [ ] **Step 3: Wait for toast "Beveiligingssleutel gelezen" or provisioning**
|
||||
- [ ] **Step 4: If key was newly generated, verify Serial monitor shows "HMAC key stored in NVS"**
|
||||
|
||||
---
|
||||
|
||||
### Task 14: Verify BLE connection and relay control
|
||||
|
||||
**Files:** N/A (manual verification)
|
||||
|
||||
- [ ] **Step 1: Power on the Atom Lite (with relay and touch sensor connected)**
|
||||
- [ ] **Step 2: Open the Android app — verify it auto-connects to "SyldaServer"**
|
||||
- [ ] **Step 3: Verify status shows "Connected"**
|
||||
- [ ] **Step 4: Hold HOLD button — verify relay activates (click or multimeter)**
|
||||
- [ ] **Step 5: Release — verify relay deactivates**
|
||||
- [ ] **Step 6: Touch sensor on G33 — verify relay also activates**
|
||||
|
||||
---
|
||||
|
||||
## Self-Review
|
||||
|
||||
**1. Spec coverage:**
|
||||
- Sidebranch `esp32picod4`: Task 1 ✓
|
||||
- Compile for ESP32-PICO-D4: Task 2 ✓
|
||||
- Pins G32/G33/G27: Task 3 ✓
|
||||
- SK6812 LED with FastLED: Task 3 ✓
|
||||
- BLE name "SyldaServer": Task 3 ✓
|
||||
- CDC-class USB detection: Tasks 5, 6 ✓
|
||||
- DTR/RTS no changes: Confirmed in research, no task needed ✓
|
||||
- Bundle binary with Android app: Task 8 ✓
|
||||
- Build APK: Task 9 ✓
|
||||
- ADB wireless deploy: Tasks 10, 11 ✓
|
||||
- Flash + provision + test: Tasks 12-14 ✓
|
||||
|
||||
**2. Placeholder scan:** No TBD, TODO, or incomplete sections. All commands are concrete with expected output.
|
||||
|
||||
**3. Type consistency:** `hasCdcDataInterface(device: UsbDevice): Boolean` defined in Task 5, used consistently in Task 6 with `UsbUtils.hasCdcDataInterface(device/it)`.
|
||||
Loading…
Reference in a new issue