Initial import: keyrelay, a WiFi-controlled USB HID keyboard
Browser or terminal controller drives an ESP32-S3 that acts as a Logitech G815 into a target machine running no software. Disarmed by default; arming requires the passphrase, the board button, or the serial console, and every fail-safe path cancels in-flight work. - src/: firmware with pure, host-testable modules (keystate, proto, text, ws_codec, sha1), the WebSocket control server, and the served page - tests/: host suites for the pure modules, relayctl parity, and page JS - tools/: relayctl terminal controller, serial console, bootloader helper, and an evdev target watcher - platformio.ini: bridge (USB HID) and console (no-HID) environments - README.md: single source of truth for behaviour, protocol and safety LLM-Generated: true
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
; keyrelay -- WiFi-controlled USB HID keyboard bridge for the M5Stack AtomS3 Lite.
|
||||
;
|
||||
; The board is an ESP32-S3FN8 (8 MB flash, no PSRAM) with NO USB-to-UART bridge:
|
||||
; the USB-C connector is wired straight to the ESP32-S3 native USB (GPIO19/20), and
|
||||
; those pads belong to ONE peripheral at a time:
|
||||
;
|
||||
; ARDUINO_USB_MODE=1 -> built-in USB-Serial/JTAG (console only, cannot type)
|
||||
; ARDUINO_USB_MODE=0 -> USB-OTG + TinyUSB (HID keyboard + CDC console)
|
||||
;
|
||||
; That single-port fact is the whole reason the control path is WiFi: the board can
|
||||
; be attached to exactly one machine over USB, so the controller on the laptop has to
|
||||
; reach it over the network instead. See README "Why the control path is WiFi".
|
||||
;
|
||||
; Datasheet: https://docs.m5stack.com/en/core/AtomS3-Lite
|
||||
|
||||
[platformio]
|
||||
default_envs = bridge
|
||||
|
||||
[usb]
|
||||
; The core USB library compiles its MSC/FS sources together with the HID ones, and
|
||||
; those include FS.h / vfs_api.h, which LDF will not resolve by itself (it tries the
|
||||
; registry and fails). Only the include path is needed: nothing here references the
|
||||
; MSC/FS symbols, so the linker drops those objects again. Carried over from the
|
||||
; jiggle firmware on the same board.
|
||||
fs_include = -I${platformio.packages_dir}/framework-arduinoespressif32/libraries/FS/src
|
||||
|
||||
[env]
|
||||
platform = espressif32@8.0.0
|
||||
board = esp32-s3-devkitc-1
|
||||
framework = arduino
|
||||
|
||||
; Nominal for USB CDC (the USB link ignores baud); 921600 is what this board takes.
|
||||
upload_speed = 921600
|
||||
monitor_speed = 115200
|
||||
monitor_filters = esp32_exception_decoder, time
|
||||
|
||||
; WiFi + TinyUSB + the embedded controller page do not fit the default 1.3 MB app
|
||||
; slot of the standard two-OTA layout. This board has no OTA path in this project --
|
||||
; it is reflashed over USB, always -- so one 3 MB app partition is the right trade.
|
||||
board_build.partitions = huge_app.csv
|
||||
|
||||
lib_deps =
|
||||
adafruit/Adafruit NeoPixel@^1.15.0
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Default: the full bridge. The board is a composite USB HID keyboard + USB serial
|
||||
; on the target, a web server and WebSocket endpoint on the network.
|
||||
; ---------------------------------------------------------------------------
|
||||
[env:bridge]
|
||||
build_flags =
|
||||
${usb.fs_include}
|
||||
-DARDUINO_USB_MODE=0
|
||||
; CDC_ON_BOOT=0 is what makes the Logitech identity possible: with 1,
|
||||
; cores/esp32/main.cpp calls USB.begin() from app_main() before setup() runs, the
|
||||
; first tinyusb_init() fixes the VID/PID/strings as Espressif's, and every
|
||||
; USB.VID()/productName() setter afterwards is a no-op. With 0 this environment
|
||||
; starts the stack itself, after setting the identity (src/main.cpp: kUsb*). The
|
||||
; console is unaffected: main.cpp owns a USBCDC instance, so /dev/ttyACM0 works.
|
||||
-DARDUINO_USB_CDC_ON_BOOT=0
|
||||
; Optional build-time station credentials, so a first bring-up can skip the serial
|
||||
; console. Quoting is part of the macro: -D KR_STA_SSID='"MyNet"'.
|
||||
; Prefer the `wifi <ssid> <pass>` console command: it stores into NVS and keeps
|
||||
; the passphrase out of the image and out of shell history.
|
||||
; -D KR_STA_SSID='" ssid "'
|
||||
; -D KR_STA_PASS='" passphrase "'
|
||||
build_unflags =
|
||||
; esp32-s3-devkitc-1 pins ARDUINO_USB_MODE=1 in its board JSON; drop it so the
|
||||
; value above is the only one on the command line.
|
||||
-DARDUINO_USB_MODE=1
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Diagnostic: no USB-OTG, so no HID -- the board cannot type, but the whole control
|
||||
; plane (WiFi, page, passphrase, WebSocket, LED, button) is live. Use it to separate
|
||||
; "the network side is broken" from "the HID side is broken" without rebuilding.
|
||||
; Arming refuses with E5 here, on purpose.
|
||||
; ---------------------------------------------------------------------------
|
||||
[env:console]
|
||||
build_flags =
|
||||
${usb.fs_include}
|
||||
-DARDUINO_USB_MODE=1
|
||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||
Reference in New Issue
Block a user