RNode on OS3: a Minimal Reticulum Firmware for the CH32V003

I wanted to know how small a useful Reticulum transport could get.

Not a mock-up. Not a “Hello World over LoRa”. Not a proof of concept that only works in a lab once. A real firmware image that can be flashed onto a cheap microcontroller board, detected by rnsd, and used with tools like Sideband and NomadNet.

This release is the result: a small RNode-compatible firmware image based on OS3, targeting the CH32V003 and an E22-900M22S LoRa module built around the SX1262.

The hardware budget is unusually tight:

  • 16 KB flash
  • 2 KB RAM

That is exactly why this firmware is interesting.

CH32V003 development board wired to an E22-900M22S SX1262 LoRa module

The current hardware setup: CH32V003 dev board, E22-900M22S radio module, and direct wiring during validation.

What This Firmware Is

This is a minimal RNode-style modem firmware for the Reticulum ecosystem.

It provides:

  • a UART host interface compatible with the expected RNode framing model
  • SX1262 radio control over SPI
  • LoRa TX/RX for Reticulum traffic
  • correct RNode packet handling up to the upstream logical MTU
  • interoperability with rnsd, Sideband, and NomadNet in the current release configuration

It is intentionally narrow in scope. There is no display stack, no BLE, no Wi-Fi, no GPS, no PMU layer, and no device-side application environment.

This firmware is meant to do one job well: act as a small, understandable, event-driven Reticulum transport.

Reticulum Is Bigger Than LoRa

It is worth being precise here:

  • Reticulum is the networking stack
  • RNode is one modem/interface model used by parts of the ecosystem
  • LoRa is only one physical transport

So this firmware should not be read as “Reticulum on LoRa and nothing else”. It is one transport target, implemented on very constrained hardware, using the RNode model that existing Reticulum-side software already understands.

That makes it useful in two ways:

  • as a practical radio modem firmware you can actually flash and use
  • as a lower-bound demonstration of what a tiny event-driven system can still do correctly

Target Platform

The current target is:

  • MCU: CH32V003
  • Core: QingKe V2A / RV32EC
  • Flash: 16 KB
  • RAM: 2 KB
  • Radio module: E22-900M22S
  • Radio chipset: SX1262
  • Host link: UART

Current linked image size:

  • Flash (.text): 10277 bytes
  • RAM (.bss): 1848 bytes

The RAM headroom is small, but the firmware is stable and functional in that footprint.

Hardware Setup

The firmware-side wiring is fixed and should be followed by signal name, not guesswork.

CH32V003 to E22-900M22S

CH32V003 <-> E22-900M22S
------------------------------------------------
CH32 pin    Role in firmware    E22 signal
------------------------------------------------
PC0         LoRa reset          NRST
PC1         LoRa busy           BUSY
PC2         LoRa IRQ            DIO1
PC3         RX path enable      RXEN
PC4         SPI chip select     NSS / CS
PC5         SPI clock           SCK
PC6         SPI MOSI            MOSI
PC7         SPI MISO            MISO
3V3         Power               VCC
GND         Ground              GND
ANT         RF                  Antenna

Important Notes

  • Both boards must share 3.3V logic
  • All grounds must be connected
  • The E22 module must have an antenna attached before RF testing
  • RXEN must be wired, otherwise receive behavior will be incorrect
  • TXEN is driven by DIO2, with DIO2 directly wired to TXEN

The current design relies on the SX1262/E22 behavior where:

  • DIO2 is configured as the TX enable drive and is wired directly to TXEN
  • RXEN is still driven explicitly by the MCU
  • DIO3 is used internally by the E22 TCXO path

Practical unused or implicit signals:

Signal      Status
-----------------------------------------------
TXEN        Driven directly by DIO2
DIO2        Directly wired to TXEN
DIO3        Used internally for the E22 TCXO path

Host UART, LEDs, and Reset

CH32 pin    Function
-----------------------------------------------
PD5         USART1 TX
PD6         USART1 RX
PD4         Heartbeat LED
PD2         Radio activity LED
PD0         NRST

Indicator behavior:

  • PD4: heartbeat
  • PD2: radio activity pulse on completed logical TX and RX events

Flashing the Binary Release

This firmware is meant to be distributed and used as a prebuilt binary image.

Download:

After downloading the firmware binary, flash it directly:

minichlink -w ch32v003-rnode-os3.bin flash -b

Flash and reset:

minichlink -w ch32v003-rnode-os3.bin flash -b -r

Released binary filename:

ch32v003-rnode-os3.bin

For end users, the setup flow is simple:

  1. Wire the CH32V003 board and the E22 module exactly as shown above.
  2. Download ch32v003-rnode-os3.bin.
  3. Flash it with minichlink.
  4. Connect the UART host interface to the machine running Reticulum software.
  5. Start rnsd, Sideband, or another compatible host-side tool.

Host Configuration with rnsd

On the host side, this firmware is intended to be used through the regular Reticulum daemon.

A minimal ~/.reticulum/config looks like this:

[reticulum]
  enable_transport = False
  share_instance = Yes

[interfaces]
  [[CH32RNode]]
    type = RNodeInterface
    enabled = yes
    port = /dev/ttyACM0
    frequency = 868000000
    bandwidth = 125000
    txpower = 2
    spreadingfactor = 7
    codingrate = 5

Adjust the serial device and radio parameters to match your hardware and regional band plan.

Then start the daemon:

rnsd

Once the interface is up, tools such as Sideband and NomadNet can use the running Reticulum instance through the normal host-side path.

Why This Took More Than Basic RF Bring-Up

Getting a radio to emit packets is easy compared to making a device behave like a real RNode modem.

The hard part was protocol fidelity:

  • correct RNode detection and startup probing
  • correct reporting of radio parameters
  • correct handling of the RNode modem header
  • surviving a 2 KB RAM budget without corrupting the host-facing path
  • implementing split-packet TX and RX behavior that matches the expected RNode model

This is what turns a board from “it can send LoRa” into “it can interoperate with existing Reticulum software without surprises”.

The 508-Byte RNode Limit

One of the key implementation details is the classic RNode logical MTU.

The packet limit is 508 bytes, and that is a hard limit in this framing model:

  • raw LoRa frame maximum: 255 bytes
  • modem header: 1 byte
  • useful payload per raw frame: 254 bytes
  • maximum fragments per logical packet: 2
  • logical payload maximum: 254 + 254 = 508

This firmware implements that behavior correctly:

  • host packets up to 508 bytes are accepted
  • larger logical packets are not treated as a third-fragment case, because that case does not exist in classic RNode framing
  • TX is fragmented internally into two raw LoRa frames when needed
  • RX is reassembled internally before the packet is forwarded to the host

That behavior matters in practice. Without it, announces may appear to work while larger real-world traffic fails or becomes invalid.

Release Status

The current binary release has been validated as follows:

  • rnsd detects the device
  • host-side radio configuration succeeds
  • announce traffic works
  • short messages work
  • longer messages using the split-packet path work
  • Sideband and NomadNet interoperate with the firmware

rnstatus showing the CH32 RNode interface up on the host system

rnstatus reporting the CH32-based RNode interface as up and operational on the host.

Sideband conversation carried over the CH32-based RNode link

Bidirectional message exchange validated through the CH32-based RNode link.

This is no longer just a radio bring-up milestone. It is a functional RNode-compatible LoRa modem release on top of OS3.

Why I Think This Matters

To me, the interesting part is not simply that a cheap microcontroller can now participate in the Reticulum ecosystem.

The more interesting part is what this says about the design space:

  • a real external protocol can be implemented cleanly on extremely small hardware
  • architectural discipline still matters even when memory is scarce
  • “small” does not have to mean sloppy
  • an event-driven system can remain understandable while still being practically useful

In other words, this firmware is not only a release artifact. It is also a statement about lower bounds.

It shows that a meaningful Reticulum transport can exist much lower in the hardware stack than many people would assume.

Closing

This is not the final form of a user-facing Reticulum device.

It is something narrower: a small, focused, flashable firmware image that does one job correctly.

On a CH32V003 paired with an E22-900M22S, OS3 now provides a working RNode-compatible modem for the Reticulum ecosystem.

For a microcontroller with 2 KB of RAM, that is a satisfying result.