Files
meshtastic_firmware/variants/rp2350/diy/pico2_w5500_e22
Carlos ValdesandClaude Opus 4.8 4f0e2dde98 feat: add Ethernet OTA support for RP2350/W5500 boards (#10136)
* feat: add Raspberry Pi Pico 2 + W5500 + E22-900M30S variant

Adds community variant for Raspberry Pi Pico 2 (RP2350, 4 MB flash)
with external WIZnet W5500 Ethernet module and EBYTE E22-900M30S LoRa
module (SX1262, 30 dBm PA, 868/915 MHz).

Key details:
- LoRa on SPI1: GP10/11/12/13 (SCK/MOSI/MISO/CS), RST=GP15,
  DIO1=GP14, BUSY=GP2, RXEN=GP3 (held HIGH via SX126X_ANT_SW)
- W5500 on SPI0: GP16/17/18/19/20 (MISO/CS/SCK/MOSI/RST)
- SX126X_DIO2_AS_RF_SWITCH: DIO2→TXEN bridge on module handles PA
- SX126X_DIO3_TCXO_VOLTAGE 1.8: TCXO support via EBYTE_E22 flags
- DHCP timeout reduced to 10 s to avoid blocking LoRa startup
- GPS on UART1/Serial2: GP8 TX, GP9 RX
- Reuses WIZNET_5500_EVB_PICO2 code paths for Ethernet init

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* pico2_w5500_e22: rename define and address review feedback

Rename WIZNET_5500_EVB_PICO2 to PICO2_W5500_E22 so the variant-specific
define matches the variant directory name and isn't confused with an
on-board EVB SKU.

Review fixes from PR #10135:
- Gate the 10 s Ethernet DHCP timeout behind PICO2_W5500_E22 so other
  Ethernet builds keep the default 60 s behavior; apply the same timeout
  to reconnectETH() for consistency.
- Drop the unused -D EBYTE_E22 flag; EBYTE_E22_900M30S already selects
  TX_GAIN_LORA / SX126X_MAX_POWER in src/configuration.h.
- Rewrite "on-board W5500" comments to describe the external module.
- Correct README TX_GAIN_LORA value (7, not 10) and drop the EBYTE_E22
  row.

* fix(pico2_w5500_e22): drop DEBUG_RP2040_PORT=Serial

The arduino-pico framework hooks _write() when DEBUG_RP2040_PORT=Serial
is set and dumps raw debug bytes onto USB CDC, corrupting any binary
protobuf stream sent through StreamAPI (e.g. `meshtastic --port COMx`).

The variant excludes BT and WiFi, so the primary client transport is
Ethernet TCP via ethServerAPI — unaffected — but users who configure
the node over USB serial would see protobuf decode failures from
debug-byte interleaving. Removing the flag restores clean USB CDC.

Debug output can still be enabled per-build by adding -D DEBUG_RP2040_PORT=Serial1
to redirect to UART0 instead of USB CDC.

* feat: add Ethernet OTA support for RP2350/W5500 boards

Adds over-the-air firmware update capability for RP2350-based boards
with a WIZnet W5500 Ethernet module (e.g. pico2_w5500_e22).

Protocol (MOTA):
- SHA256 challenge-response authentication with a configurable PSK
  (override via USERPREFS_OTA_PSK; default key ships in source)
- 12-byte header: magic "MOTA" + firmware size + CRC32
- Firmware received in 1 KB chunks, verified with CRC32, written via
  Updater (picoOTA), then device reboots to apply
- Constant-time hash comparison prevents timing attacks on auth
- 30s inactivity timeout + 5s cooldown after failed auth
- Response codes 0x00-0x08 map 1:1 to OTAResponse enum

Firmware side:
- ethOTA.cpp / ethOTA.h: OTA TCP server on port 4243
- ethClient.cpp: wire initEthOTA/ethOTALoop into reconnect loop
- main-rp2xx0.cpp: hardware watchdog (8s, paused during debug)
- pico2_w5500_e22/platformio.ini: HAS_ETHERNET_OTA flag,
  filesystem_size bumped to 0.75m for OTA staging

Host side:
- bin/eth-ota-upload.py: Python uploader with progress and full
  result-code mapping (matches OTAResponse 0x00-0x08)

* style(eth): clang-format ethOTA.cpp per repo .clang-format

Reformat to the repo trunk clang-format config (IndentWidth 4,
ColumnLimit 130). Resolves the Trunk Check 'Incorrect formatting'
failure on PR #10136.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 16:28:10 +02:00
..

Raspberry Pi Pico 2 + W5500 + E22-900M30S — Meshtastic Variant

Meshtastic support for a Raspberry Pi Pico 2 (RP2350, 4 MB flash) with an external W5500 Ethernet module and an EBYTE E22-900M30S LoRa module.


Required Hardware

Component Model Notes
MCU Raspberry Pi Pico 2 RP2350 @ 150 MHz, 512 KB RAM, 4 MB flash
Ethernet W5500 module Any WIZnet W5500 breakout board
LoRa EBYTE E22-900M30S SX1262 + 30 dBm PA, 868/915 MHz

Pinout

System pins (Pico 2, fixed)

GPIO Function
GP24 VBUS sense — HIGH when USB is connected
GP25 User LED (heartbeat)
GP29 ADC3 — VSYS/3, measures supply voltage

W5500 Ethernet (SPI0)

W5500 signal Pico 2 GPIO
MISO GP16
CS / SCS GP17
SCK GP18
MOSI GP19
RST GP20
INT — (nc)
VCC 3.3V
GND GND

SPI0 is reserved for the W5500.

E22-900M30S LoRa (SPI1)

E22 signal Pico 2 GPIO Notes
SCK GP10 SPI1 clock
MOSI GP11 SPI1 TX
MISO GP12 SPI1 RX
NSS / CS GP13 Chip select
RESET GP15 Active LOW reset
DIO1 GP14 IRQ interrupt
BUSY GP2 Module busy indicator
RXEN GP3 LNA enable — held HIGH permanently
TXEN ← DIO2 See wiring note below
VCC 3.3V Add a 100 µF capacitor close to the module
GND GND

See wiring.svg in this directory for the full connection diagram.


Special wiring: DIO2 → TXEN bridge on the E22 module

The E22-900M30S does not connect DIO2 to the TXEN pin of its PA internally. They must be bridged with a short wire or solder bridge on the module itself:

E22 DIO2 pin  ──┐
                ├── wire / solder bridge on the module
E22 TXEN pin  ──┘

With this bridge in place, SX126X_DIO2_AS_RF_SWITCH causes the SX1262 to drive DIO2 HIGH automatically during TX, enabling the PA without needing an RP2350 GPIO for TXEN.

Without this bridge the module will not transmit.


Build

pio run -e pico2_w5500_e22

Flash — BOOTSEL mode

  1. Hold the BOOTSEL button on the Pico 2.
  2. Connect USB to the PC — it appears as a RPI-RP2 storage drive.
  3. Copy the .uf2 file:
.pio/build/pico2_w5500_e22/firmware-pico2_w5500_e22-*.uf2

Or directly with picotool:

pio run -e pico2_w5500_e22 -t upload

Network usage

This board uses Ethernet (no Wi-Fi). From the Meshtastic app:

  • Enable Ethernet under Config → Network → Ethernet Enabled
  • DHCP by default; static IP can also be configured

Services available once connected:

Service Details
NTP Time synchronization
MQTT Messages to external broker
API TCP socket on port 4403
Syslog Remote logging (optional)

Technical notes

LoRa — RF control

Define Effect
SX126X_ANT_SW 3 GP3 (RXEN) driven HIGH at init and never toggled again
SX126X_DIO2_AS_RF_SWITCH SX1262 drives DIO2 HIGH during TX → enables TXEN via bridge
SX126X_DIO3_TCXO_VOLTAGE 1.8 E22 TCXO controlled by DIO3
-D EBYTE_E22_900M30S Sets TX_GAIN_LORA=7, max power 22 dBm

RXEN and TXEN may both be HIGH simultaneously during TX — this is safe for the E22 RF switch.

Ethernet

  • Library: arduino-libraries/Ethernet@^2.0.2 (supports W5100/W5200/W5500 auto-detection).
  • SPI0 is explicitly initialized with pins GP16/18/19 before Ethernet.init().
  • DHCP timeout is set to 10 s (instead of the default 60 s) to avoid blocking LoRa startup.

HW_VENDOR

Mapped to meshtastic_HardwareModel_PRIVATE_HW — no dedicated model exists in the Meshtastic protobuf for this hardware combination yet.


Memory usage (reference build)

Resource Used Total %
RAM 94 KB 512 KB 18%
Flash 964 KB 3.58 MB 26.3%