Cluster: AtomS3 Lite co-processors on the Grove port, with our own link protocol #18

Open
opened 2026-10-05 16:15:39 +00:00 by twisla · 0 comments
Owner

Idea

Connect one or two M5Stack AtomS3 Lite modules directly to the Cardputer: one on the Cardputer's Grove HY2.0-4P port, one on the Cap LoRa-1262's. Each Atom runs its own roro9stack firmware and takes work off the Cardputer: network connections, TLS, radio scans, or anything else that is heavy on RAM or CPU. They talk over a custom protocol on the Grove wires. The Cardputer stays the screen, keyboard and storage. The Atoms are its co-processors, and the system works the same, only with more room, when they're plugged in.

This idea already has a footnote in the project's history: M1's Q46 says "keep the AtomS3 Wi-Fi co-processor in mind" as the fallback if RAM ran short.

Why

  • Memory. With IRC connected, the Cardputer has about 68 KB free. TLS alone takes about 45 KB per connection, and G1 had to accept a dip to 13 KB. An AtomS3 Lite is an ESP32-S3 with its own 512 KB of SRAM and nothing to draw. Moving Wi-Fi, TLS and the network services there would free most of the Cardputer's heap for the UI, Lua Apps (#13), audio (#14) and so on.
  • Parallelism. For example, one Atom scans with Wi-Fi Tools while the Cardputer stays connected. Or an Atom handles BLE while another holds Wi-Fi.
  • And it's a fun architecture: a pocket cluster.

What's known

  • The hardware.
    • AtomS3 Lite: an ESP32-S3FN8 (8 MB flash, no PSRAM), an RGB LED, a button, an IR LED, and a Grove port on GPIO 1 and 2.
    • Two Grove ports, one Atom on each. The Cardputer ADV has its own Grove HY2.0-4P port (5 V, GND and two GPIOs), and the Cap LoRa-1262 has a second one. Each Atom gets a direct, point-to-point link to the Cardputer: no chain and no shared bus.
    • The Cap's Grove GPIOs need checking against its schematic. They must not clash with the LoRa radio's SPI (GPIO 5, 14, 39, 40), the GNSS UART (GPIO 13 and 15) or the keyboard's I2C (GPIO 8 and 9).
    • UARTs. The ESP32-S3 has three. GNSS uses UART1 (Serial1). The console runs on USB CDC, so UART0 is free to route to any pin, and UART2 is free. That's exactly one UART per Atom, and none left over for another serial device.
    • Power. The Atoms draw their 5 V from the Cardputer's battery. An ESP32-S3 with Wi-Fi active averages around 100 mA, with peaks of 300 mA or more. Two Atoms would shorten battery life noticeably, and the Grove 5 V supply's current limit has to be checked.
  • The link.
    • UART on each port's two wires: full duplex, point to point, and a few Mbaud on a short cable (to be measured on both ports). ESP32-S3 UARTs have DMA, but there are no wires left for RTS/CTS, so flow control has to be in the protocol.
    • Each Atom has its own link, so they don't share bandwidth, and a fault on one doesn't affect the other.
    • I2C would also work on two wires, but it's slow (400 kHz to 1 MHz), half duplex, and ESP32 I2C slave mode is awkward for streams. With a port per Atom, there's no reason to use a bus.
  • The protocol (custom). What it needs:
    • Framing (COBS or SLIP), a CRC on each frame, and sequence numbers with acks and retries.
    • Multiplexed channels: control, plus one stream per connection (an IRC socket, a Gemini fetch, an SSH session).
    • A handshake with a protocol version and capabilities ("I have Wi-Fi, TLS, BLE…"), and heartbeats to detect an unplugged or crashed Atom.
    • Credit-based flow control per channel, so a slow consumer doesn't drop data.
    • Encoding and decoding are pure logic and can be host-tested both ways, with fault injection (lost, corrupted and reordered frames).
  • Existing alternatives to weigh before writing our own:
    • Espressif's ESP-Hosted, an ESP as a Wi-Fi co-processor for a host. Its supported transports need checking against two wires.
    • esp-at, AT commands over UART: simple, but slow and clumsy for TLS streams.
    • PPP over UART: lwIP supports it, so the Atom becomes an IP router. Then every existing service works unchanged, but TLS still runs on the Cardputer, which saves no memory.
    • The real memory win comes from socket-level or service-level offload (the Atom runs TLS, or even the IRC client), which is what a custom protocol allows.
  • The software.
    • A new PlatformIO environment for the AtomS3 Lite in the same repo, sharing the lib/ code (TLS settings, Gemini, IRC, the protocol).
    • Updating the Atoms: the Cardputer pushes signed Update Files over the link, with the same signing, Probation and rollback as its own OTA. A matching CI build is needed (#5).
    • Debugging: the Atoms' logs and crash reports are forwarded to the Cardputer and its Debug Console.
    • Fallback: if no Atom is present, or one disappears, the Cardputer does the work itself, as today, or says the feature needs an Atom.
  • Security. It's a physical link, so trust is mostly physical. But the Atom holding Wi-Fi passwords and TLS sessions means secrets live on another device. Decide what is sent over the link, and whether an Atom must be paired before it's trusted.

Questions for the design round

  1. What does an Atom do: a network co-processor (Wi-Fi, TLS, sockets), a service host (it runs IRC and Gemini, the Cardputer is a terminal), or a general job runner?
  2. One Atom first, or both from the start? Do the two Atoms have fixed roles per port (for example network on the Cardputer's port, radios on the Cap's), or are they interchangeable?
  3. Link speed: what UART rate holds up on each Grove cable, measured?
  4. Our own protocol, or ESP-Hosted or PPP for the network part and our own for the rest?
  5. How are Atoms updated and debugged: through the Cardputer (signed images over the link)?
  6. What happens when an Atom is unplugged mid-session?
  7. How much battery is it worth? Should an Atom be powered down when idle?
  8. Pairing: should an Atom be trusted the first time it's plugged in, or paired explicitly?
  9. Does this deserve an ADR for the architecture before any code?

Related

docs/milestones/M1.md (Q46), docs/milestones/G1.md (Q86 memory floors), ADR 0006 (TLS buffers), lib/ota and UpdateService (signed updates), #5 (CI for a second target), #13, #14.

## Idea Connect one or two M5Stack AtomS3 Lite modules directly to the Cardputer: one on the Cardputer's Grove HY2.0-4P port, one on the Cap LoRa-1262's. Each Atom runs its own roro9stack firmware and takes work off the Cardputer: network connections, TLS, radio scans, or anything else that is heavy on RAM or CPU. They talk over a custom protocol on the Grove wires. The Cardputer stays the screen, keyboard and storage. The Atoms are its co-processors, and the system works the same, only with more room, when they're plugged in. This idea already has a footnote in the project's history: M1's Q46 says "keep the AtomS3 Wi-Fi co-processor in mind" as the fallback if RAM ran short. ## Why - **Memory.** With IRC connected, the Cardputer has about 68 KB free. TLS alone takes about 45 KB per connection, and G1 had to accept a dip to 13 KB. An AtomS3 Lite is an ESP32-S3 with its own 512 KB of SRAM and nothing to draw. Moving Wi-Fi, TLS and the network services there would free most of the Cardputer's heap for the UI, Lua Apps (#13), audio (#14) and so on. - **Parallelism.** For example, one Atom scans with Wi-Fi Tools while the Cardputer stays connected. Or an Atom handles BLE while another holds Wi-Fi. - **And it's a fun architecture:** a pocket cluster. ## What's known - **The hardware.** - AtomS3 Lite: an ESP32-S3FN8 (8 MB flash, no PSRAM), an RGB LED, a button, an IR LED, and a Grove port on GPIO 1 and 2. - **Two Grove ports, one Atom on each.** The Cardputer ADV has its own Grove HY2.0-4P port (5 V, GND and two GPIOs), and the Cap LoRa-1262 has a second one. Each Atom gets a direct, point-to-point link to the Cardputer: no chain and no shared bus. - The Cap's Grove GPIOs need checking against its schematic. They must not clash with the LoRa radio's SPI (GPIO 5, 14, 39, 40), the GNSS UART (GPIO 13 and 15) or the keyboard's I2C (GPIO 8 and 9). - **UARTs.** The ESP32-S3 has three. GNSS uses UART1 (`Serial1`). The console runs on USB CDC, so UART0 is free to route to any pin, and UART2 is free. That's exactly one UART per Atom, and none left over for another serial device. - **Power.** The Atoms draw their 5 V from the Cardputer's battery. An ESP32-S3 with Wi-Fi active averages around 100 mA, with peaks of 300 mA or more. Two Atoms would shorten battery life noticeably, and the Grove 5 V supply's current limit has to be checked. - **The link.** - UART on each port's two wires: full duplex, point to point, and a few Mbaud on a short cable (to be measured on both ports). ESP32-S3 UARTs have DMA, but there are no wires left for RTS/CTS, so flow control has to be in the protocol. - Each Atom has its own link, so they don't share bandwidth, and a fault on one doesn't affect the other. - I2C would also work on two wires, but it's slow (400 kHz to 1 MHz), half duplex, and ESP32 I2C slave mode is awkward for streams. With a port per Atom, there's no reason to use a bus. - **The protocol (custom). What it needs:** - Framing (COBS or SLIP), a CRC on each frame, and sequence numbers with acks and retries. - Multiplexed channels: control, plus one stream per connection (an IRC socket, a Gemini fetch, an SSH session). - A handshake with a protocol version and capabilities ("I have Wi-Fi, TLS, BLE…"), and heartbeats to detect an unplugged or crashed Atom. - Credit-based flow control per channel, so a slow consumer doesn't drop data. - Encoding and decoding are pure logic and can be host-tested both ways, with fault injection (lost, corrupted and reordered frames). - **Existing alternatives to weigh before writing our own:** - Espressif's ESP-Hosted, an ESP as a Wi-Fi co-processor for a host. Its supported transports need checking against two wires. - esp-at, AT commands over UART: simple, but slow and clumsy for TLS streams. - PPP over UART: lwIP supports it, so the Atom becomes an IP router. Then every existing service works unchanged, but TLS still runs on the Cardputer, which saves no memory. - The real memory win comes from **socket-level or service-level offload** (the Atom runs TLS, or even the IRC client), which is what a custom protocol allows. - **The software.** - A new PlatformIO environment for the AtomS3 Lite in the same repo, sharing the `lib/` code (TLS settings, Gemini, IRC, the protocol). - Updating the Atoms: the Cardputer pushes signed Update Files over the link, with the same signing, Probation and rollback as its own OTA. A matching CI build is needed (#5). - Debugging: the Atoms' logs and crash reports are forwarded to the Cardputer and its Debug Console. - Fallback: if no Atom is present, or one disappears, the Cardputer does the work itself, as today, or says the feature needs an Atom. - **Security.** It's a physical link, so trust is mostly physical. But the Atom holding Wi-Fi passwords and TLS sessions means secrets live on another device. Decide what is sent over the link, and whether an Atom must be paired before it's trusted. ## Questions for the design round 1. What does an Atom do: a network co-processor (Wi-Fi, TLS, sockets), a service host (it runs IRC and Gemini, the Cardputer is a terminal), or a general job runner? 2. One Atom first, or both from the start? Do the two Atoms have fixed roles per port (for example network on the Cardputer's port, radios on the Cap's), or are they interchangeable? 3. Link speed: what UART rate holds up on each Grove cable, measured? 4. Our own protocol, or ESP-Hosted or PPP for the network part and our own for the rest? 5. How are Atoms updated and debugged: through the Cardputer (signed images over the link)? 6. What happens when an Atom is unplugged mid-session? 7. How much battery is it worth? Should an Atom be powered down when idle? 8. Pairing: should an Atom be trusted the first time it's plugged in, or paired explicitly? 9. Does this deserve an ADR for the architecture before any code? ## Related `docs/milestones/M1.md` (Q46), `docs/milestones/G1.md` (Q86 memory floors), ADR 0006 (TLS buffers), `lib/ota` and UpdateService (signed updates), #5 (CI for a second target), #13, #14.
twisla added this to the P1 Platform milestone 2026-10-05 20:14:11 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: twisla/roro9stack#18