Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/DebugConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ extern "C" void logLegacy(const char *level, const char *fmt, ...);
// Default Bluetooth PIN
#define defaultBLEPin 123456

#if HAS_ETHERNET && !defined(USE_WS5500)
#if HAS_ETHERNET && defined(PICO2_W5500_E22)
#include <Ethernet.h> // arduino-libraries/Ethernet — supports W5500 auto-detect
#elif HAS_ETHERNET && !defined(USE_WS5500)
#include <RAK13800_W5100S.h>
#endif // HAS_ETHERNET

Expand Down
6 changes: 5 additions & 1 deletion src/mesh/api/ethServerAPI.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#pragma once

#include "ServerAPI.h"
#ifndef USE_WS5500
#if !defined(USE_WS5500)
#if defined(PICO2_W5500_E22)
#include <Ethernet.h>
#else
#include <RAK13800_W5100S.h>
#endif

/**
* Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs
Expand Down
30 changes: 30 additions & 0 deletions src/mesh/eth/ethClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
#include "main.h"
#include "mesh/api/ethServerAPI.h"
#include "target_specific.h"
#ifdef PICO2_W5500_E22
#include <Ethernet.h> // arduino-libraries/Ethernet — supports W5100/W5200/W5500
// Shorter DHCP timeout so LoRa startup isn't blocked when no DHCP server is present.
#define ETH_DHCP_TIMEOUT_MS 10000
#else
#include <RAK13800_W5100S.h>
#endif
#include <SPI.h>

#if HAS_NETWORKING
Expand Down Expand Up @@ -69,17 +75,29 @@ static int32_t reconnectETH()
delay(100);
#endif

#ifdef PICO2_W5500_E22 // Re-configure SPI0 for the W5500 module
SPI.setRX(ETH_SPI0_MISO);
SPI.setSCK(ETH_SPI0_SCK);
SPI.setTX(ETH_SPI0_MOSI);
SPI.begin();
Ethernet.init(PIN_ETHERNET_SS);
#else
#ifdef RAK11310
ETH_SPI_PORT.setSCK(PIN_SPI0_SCK);
ETH_SPI_PORT.setTX(PIN_SPI0_MOSI);
ETH_SPI_PORT.setRX(PIN_SPI0_MISO);
ETH_SPI_PORT.begin();
#endif
Ethernet.init(ETH_SPI_PORT, PIN_ETHERNET_SS);
#endif

int status = 0;
if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_DHCP) {
#ifdef ETH_DHCP_TIMEOUT_MS
status = Ethernet.begin(expectedMac, ETH_DHCP_TIMEOUT_MS);
#else
status = Ethernet.begin(expectedMac);
#endif
} else if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC) {
Ethernet.begin(expectedMac, config.network.ipv4_config.ip, config.network.ipv4_config.dns,
config.network.ipv4_config.gateway, config.network.ipv4_config.subnet);
Expand Down Expand Up @@ -182,13 +200,21 @@ bool initEthernet()
digitalWrite(PIN_ETHERNET_RESET, HIGH); // Reset Time.
#endif

#ifdef PICO2_W5500_E22 // Configure SPI0 for the W5500 module
SPI.setRX(ETH_SPI0_MISO);
SPI.setSCK(ETH_SPI0_SCK);
SPI.setTX(ETH_SPI0_MOSI);
SPI.begin();
Ethernet.init(PIN_ETHERNET_SS);
#else
#ifdef RAK11310 // Initialize the SPI port
ETH_SPI_PORT.setSCK(PIN_SPI0_SCK);
ETH_SPI_PORT.setTX(PIN_SPI0_MOSI);
ETH_SPI_PORT.setRX(PIN_SPI0_MISO);
ETH_SPI_PORT.begin();
#endif
Ethernet.init(ETH_SPI_PORT, PIN_ETHERNET_SS);
#endif

uint8_t mac[6];

Expand All @@ -201,7 +227,11 @@ bool initEthernet()

if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_DHCP) {
LOG_INFO("Start Ethernet DHCP");
#ifdef ETH_DHCP_TIMEOUT_MS
status = Ethernet.begin(mac, ETH_DHCP_TIMEOUT_MS);
#else
status = Ethernet.begin(mac);
#endif
} else if (config.network.address_mode == meshtastic_Config_NetworkConfig_AddressMode_STATIC) {
Comment thread
cvaldess marked this conversation as resolved.
LOG_INFO("Start Ethernet Static");
Ethernet.begin(mac, config.network.ipv4_config.ip, config.network.ipv4_config.dns, config.network.ipv4_config.gateway,
Expand Down
2 changes: 2 additions & 0 deletions src/platform/rp2xx0/architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#define HW_VENDOR meshtastic_HardwareModel_RP2040_LORA
#elif defined(RP2040_FEATHER_RFM95)
#define HW_VENDOR meshtastic_HardwareModel_RP2040_FEATHER_RFM95
#elif defined(PICO2_W5500_E22)
#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
#elif defined(PRIVATE_HW)
#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
#endif
Expand Down
150 changes: 150 additions & 0 deletions variants/rp2350/pico2_w5500_e22/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# 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

```bash
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:

```bash
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% |
27 changes: 27 additions & 0 deletions variants/rp2350/pico2_w5500_e22/platformio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[env:pico2_w5500_e22]
extends = rp2350_base
board = rpipico2
board_level = community
upload_protocol = picotool

build_flags =
${rp2350_base.build_flags}
-ULED_BUILTIN # avoid "LED_BUILTIN redefined" warnings from framework common.h
-D PICO2_W5500_E22 # selects this variant's Ethernet/SPI0 init path
-I variants/rp2350/pico2_w5500_e22
-D DEBUG_RP2040_PORT=Serial
-D HW_SPI1_DEVICE
-D EBYTE_E22_900M30S # selects the EBYTE E22-900M30S module config, including TCXO voltage support and TX gain / max power settings

# Re-enable Ethernet and API source paths excluded in rp2350_base
build_src_filter = ${rp2350_base.build_src_filter} +<mesh/eth/> +<mesh/api/> +<mqtt/>

lib_deps =
${rp2350_base.lib_deps}
${networking_base.lib_deps}
${networking_extra.lib_deps}
# Standard WIZnet Ethernet library — supports W5100/W5200/W5500 auto-detect
arduino-libraries/Ethernet@^2.0.2

debug_build_flags = ${rp2350_base.build_flags}, -g
debug_tool = cmsis-dap
83 changes: 83 additions & 0 deletions variants/rp2350/pico2_w5500_e22/variant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Raspberry Pi Pico 2 + external W5500 Ethernet module + EBYTE E22-900M30S
// RP2350 (4 MB flash) — wire modules to the GPIO pins listed below
//
// LoRa (SX1262 / E22-900M30S) on SPI1:
// SCK=GP10 MOSI=GP11 MISO=GP12 CS=GP13
// RST=GP15 DIO1/IRQ=GP14 BUSY=GP2 RXEN=GP3
// TXEN: bridge E22_DIO2 → E22_TXEN on the module (no RP2350 GPIO needed)
//
// W5500 Ethernet on SPI0:
// MISO=GP16 CS=GP17 SCK=GP18 MOSI=GP19 RST=GP20
//
// See wiring.svg in this directory for a complete connection diagram.

#define ARDUINO_ARCH_AVR

// Onboard LED (GP25 on Pico 2)
#define LED_POWER PIN_LED

// Power monitoring
// GP24: VBUS sense – HIGH when USB is present (digital read)
// GP29: ADC3 measures VSYS/3 (200 kΩ / 100 kΩ divider, same as standard Pico 2)
#define EXT_PWR_DETECT 24
#define BATTERY_PIN 29
#define ADC_MULTIPLIER 3.0
#define BATTERY_SENSE_RESOLUTION_BITS 12
// No real battery — suppress false "battery at 100%" while USB powers VSYS
#define NO_BATTERY_LEVEL_ON_CHARGE

// Optional user button — connect a button between GP6 and GND
// #define BUTTON_PIN 6
// #define BUTTON_NEED_PULLUP

// GPS on UART1 (Serial2) — GP8 TX, GP9 RX
// GP8/GP9 belong to UART1, so we must use Serial2 (not the default Serial1/UART0).
// GP0/GP1 (UART0 defaults) are free but the firmware treats pin 0 as "not configured".
// GP4/GP5 occupied by I2C (SCL/SDA for BMP-280).
#define HAS_GPS 1
#define GPS_TX_PIN 8
#define GPS_RX_PIN 9
#define GPS_BAUDRATE 38400
#define GPS_SERIAL_PORT Serial2

// ---- EBYTE E22-900M30S on SPI1 -----------------------------------------
#define USE_SX1262

#undef LORA_SCK
#undef LORA_MISO
#undef LORA_MOSI
#undef LORA_CS

#define LORA_SCK 10
#define LORA_MOSI 11
#define LORA_MISO 12
#define LORA_CS 13

#define LORA_DIO0 RADIOLIB_NC
#define LORA_RESET 15
#define LORA_DIO1 14 // IRQ
#define LORA_DIO2 2 // BUSY
#define LORA_DIO3 RADIOLIB_NC

#ifdef USE_SX1262
#define SX126X_CS LORA_CS
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_DIO2
#define SX126X_RESET LORA_RESET
// GP3 = RXEN: driven HIGH at init and held there (LNA always enabled).
// SX1262 drives DIO2 HIGH during TX → TXEN via bridge on E22 module.
#define SX126X_ANT_SW 3
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#endif

// ---- W5500 Ethernet on SPI0 --------------------------------------------
#define HAS_ETHERNET 1

#define ETH_SPI0_MISO 16
#define ETH_SPI0_SCK 18
#define ETH_SPI0_MOSI 19

#define PIN_ETHERNET_RESET 20
#define PIN_ETHERNET_SS 17
#define ETH_SPI_PORT SPI
Loading