Public Access
Add serial dev commands and a serial log helper
The firmware accepts burst, key <name>, sound on|off and short|normal over serial, so UI behaviour can be reproduced on the device without the keyboard. scripts/serial_log.sh records (and drives) it in a named container that flash.sh removes before uploading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
@@ -36,3 +36,16 @@ This runs the host-side unit tests (`test/`, `native` environment), then builds
|
|||||||
```sh
|
```sh
|
||||||
sudo usermod -aG dialout "$USER"
|
sudo usermod -aG dialout "$USER"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Development aids
|
||||||
|
|
||||||
|
`scripts/serial_log.sh [seconds] [command…]` records the serial output, and can send commands to the firmware first. For example, `scripts/serial_log.sh 30 short sleep:12 burst` sets short screen timeouts, waits 12 s, then sends a burst of Toasts.
|
||||||
|
|
||||||
|
| Command | Effect |
|
||||||
|
|---|---|
|
||||||
|
| `burst` | Publishes 5 Notifications at once |
|
||||||
|
| `key up\|down\|left\|right\|select\|back\|home` | Injects a logical key press |
|
||||||
|
| `sound on` / `sound off` | Toggles the Sound setting (beep + LED) |
|
||||||
|
| `short` / `normal` | Screen timeouts 5 s / 10 s, or 30 s / 60 s |
|
||||||
|
|
||||||
|
`scripts/flash.sh` stops a running serial log first, since it would hold the port.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ set -euo pipefail
|
|||||||
PORT="${1:-$(readlink -f /dev/serial/by-id/*Espressif* 2>/dev/null | head -1)}"
|
PORT="${1:-$(readlink -f /dev/serial/by-id/*Espressif* 2>/dev/null | head -1)}"
|
||||||
[ -n "$PORT" ] || { echo "No Cardputer found on USB (is it plugged in / attached to the VM?)" >&2; exit 1; }
|
[ -n "$PORT" ] || { echo "No Cardputer found on USB (is it plugged in / attached to the VM?)" >&2; exit 1; }
|
||||||
source "$(dirname "$0")/_docker.sh"
|
source "$(dirname "$0")/_docker.sh"
|
||||||
|
docker rm -f roro9stack-serial >/dev/null 2>&1 || true # a serial log would hold the port
|
||||||
DOCKER_EXTRA=(--device "$PORT" --group-add "$(stat -c %g "$PORT")" -it)
|
DOCKER_EXTRA=(--device "$PORT" --group-add "$(stat -c %g "$PORT")" -it)
|
||||||
|
|
||||||
run_in_container bash -c "git config --global --add safe.directory /work && pio run -e cardputer-adv -t upload --upload-port $PORT && pio device monitor -p $PORT -b 115200"
|
run_in_container bash -c "git config --global --add safe.directory /work && pio run -e cardputer-adv -t upload --upload-port $PORT && pio device monitor -p $PORT -b 115200"
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Reads the Cardputer's serial port, reconnecting when it re-enumerates. Run via serial_log.sh.
|
||||||
|
import glob, os, sys, time
|
||||||
|
import serial
|
||||||
|
|
||||||
|
end = time.time() + float(sys.argv[1])
|
||||||
|
commands = sys.argv[2:] # sent once after connecting, e.g. "burst"
|
||||||
|
while time.time() < end:
|
||||||
|
ports = glob.glob('/dev/serial/by-id/*Espressif*')
|
||||||
|
if not ports:
|
||||||
|
time.sleep(1)
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
s = serial.Serial(os.path.realpath(ports[0]), 115200, timeout=0.2)
|
||||||
|
print('[connected]', flush=True)
|
||||||
|
for c in commands: # "sleep:N" waits N seconds between commands
|
||||||
|
if c.startswith('sleep:'):
|
||||||
|
time.sleep(float(c[6:]))
|
||||||
|
continue
|
||||||
|
time.sleep(1)
|
||||||
|
s.write((c + '\n').encode())
|
||||||
|
commands = []
|
||||||
|
buf = b''
|
||||||
|
while time.time() < end:
|
||||||
|
buf += s.read(512)
|
||||||
|
while b'\n' in buf:
|
||||||
|
line, buf = buf.split(b'\n', 1)
|
||||||
|
print(line.decode(errors='replace').rstrip(), flush=True)
|
||||||
|
except Exception as e:
|
||||||
|
print('[disconnected]', e, flush=True)
|
||||||
|
time.sleep(1)
|
||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Dev helper: record the Cardputer's serial output for N seconds (follows port changes).
|
||||||
|
# Usage: scripts/serial_log.sh [seconds] [command...] — stop early with: docker rm -f roro9stack-serial
|
||||||
|
set -euo pipefail
|
||||||
|
source "$(dirname "$0")/_docker.sh"
|
||||||
|
docker rm -f roro9stack-serial >/dev/null 2>&1 || true
|
||||||
|
DOCKER_EXTRA=(--name roro9stack-serial --group-add "$(getent group dialout | cut -d: -f3)" --privileged -v /dev:/dev)
|
||||||
|
run_in_container /pio/penv/bin/python scripts/serial_log.py "${1:-60}" "${@:2}"
|
||||||
@@ -99,11 +99,45 @@ void setup() {
|
|||||||
Serial.printf("%s %s ready, free heap %u\n", kProductName, versionString(), ESP.getFreeHeap());
|
Serial.printf("%s %s ready, free heap %u\n", kProductName, versionString(), ESP.getFreeHeap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dev aid: serial commands to drive the UI without the keyboard.
|
||||||
|
static void serialCommands() {
|
||||||
|
static String line;
|
||||||
|
while (Serial.available()) {
|
||||||
|
char c = Serial.read();
|
||||||
|
if (c != '\n') {
|
||||||
|
line += c;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
line.trim();
|
||||||
|
if (line == "burst")
|
||||||
|
for (int i = 1; i <= 5; i++)
|
||||||
|
bus.publish(Event::withText(EventType::Notification, ("Burst " + String(i)).c_str(), 0));
|
||||||
|
if (line.startsWith("key ")) { // key up|down|left|right|select|back|home
|
||||||
|
String k = line.substring(4);
|
||||||
|
Key key = k == "up" ? Key::Up : k == "down" ? Key::Down : k == "left" ? Key::Left
|
||||||
|
: k == "right" ? Key::Right : k == "back" ? Key::Back : k == "home" ? Key::Home : Key::Select;
|
||||||
|
if (!power->onKey(millis())) apps->handleKey(KeyEvent::of(key));
|
||||||
|
}
|
||||||
|
if (line == "sound off") settings.setBool(Setting::Sound, false);
|
||||||
|
if (line == "sound on") settings.setBool(Setting::Sound, true);
|
||||||
|
if (line == "short") {
|
||||||
|
settings.setInt(Setting::DimTimeoutS, 5);
|
||||||
|
settings.setInt(Setting::OffTimeoutS, 10);
|
||||||
|
}
|
||||||
|
if (line == "normal") {
|
||||||
|
settings.setInt(Setting::OffTimeoutS, 60);
|
||||||
|
settings.setInt(Setting::DimTimeoutS, 30);
|
||||||
|
}
|
||||||
|
line = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
static StatusInfo lastStatus;
|
static StatusInfo lastStatus;
|
||||||
static uint32_t lastLog = 0;
|
static uint32_t lastLog = 0;
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
|
|
||||||
|
serialCommands();
|
||||||
M5Cardputer.update();
|
M5Cardputer.update();
|
||||||
if (M5Cardputer.Keyboard.isChange()) {
|
if (M5Cardputer.Keyboard.isChange()) {
|
||||||
bool swallow = M5Cardputer.Keyboard.isPressed() && power->onKey(now); // only woke the screen
|
bool swallow = M5Cardputer.Keyboard.isPressed() && power->onKey(now); // only woke the screen
|
||||||
|
|||||||
Reference in New Issue
Block a user