linux native Pi fixes

This commit is contained in:
liquidraver
2026-06-03 13:48:54 +02:00
parent d37b401033
commit a77e877ad8
9 changed files with 71 additions and 37 deletions
+44 -14
View File
@@ -176,12 +176,18 @@ same `-DEXTRA_CONF_FILE`.)
> initialised on Windows. `rm -rf build &&` is equivalent and works everywhere. (On a
> native-Linux build host, plain `--pristine` is fine.)
>
> **Status:** the RAK6421 presets are **build-verified but not yet hardware-tested** —
> only the Femtofox is confirmed end-to-end (2026-06-02). The same GPIO driver carries the
> fixes, so it *should* work; if the radio is dead, follow the "Radio does nothing"
> troubleshooting below. Note the RAK13300/RAK13302 preset assumes **no DIO3 TCXO** (XTAL +
> discrete RF switch); if your module has a TCXO, add `dio3-tcxo-voltage`/`tcxo-power-startup-delay-ms`
> to `boards/linux_native/rak6421.overlay` (and `rak6421_pi5.overlay`).
> **Status:** the RAK6421 preset (`rak6421.conf`, Pi Zero 2 W) is **hardware-verified
> end-to-end (2026-06-03)** — SX1262 init, SPI/CS, TCXO, radio-start, and over-the-air
> RX/TX all confirmed on real hardware, alongside the Femtofox (2026-06-02). The Pi 5
> preset (`rak6421_pi5.conf`) shares the same wiring (only the gpiochip differs) and is
> build-verified but not separately hardware-tested. If the radio is dead, follow the
> "Radio does nothing" troubleshooting below.
>
> The RAK13300/RAK13302 **does have a DIO3-powered TCXO and uses DIO2 as the RF
> switch** — both overlays set `dio3-tcxo-voltage`/`dio2-tx-enable` accordingly, and
> hold the module's two `Enable_Pins` (BCM 12 + 13) high via GPIO hogs
> (`CONFIG_GPIO_HOGS=y`). Pins and clock follow the RAK6421 IO Slot 1 reference
> wiring; see the wiring table below.
### 4. Repeater role (no companion)
@@ -220,16 +226,21 @@ Source: `github.com/femtofox/femtofox` → `foxbuntu/.../femtofox_SX1262_TCXO.ya
BCM GPIO numbers (Pi 2/3/4/Zero 2: `gpiochip0``rak6421.conf`; Pi 5: `gpiochip4``rak6421_pi5.conf`):
| Signal | BCM | WisBlock slot 1 pin |
| Signal | BCM | WisBlock IO slot 1 |
|---|---|---|
| SPI bus | `/dev/spidev0.0` (CE0 = GPIO 8) | 2528 |
| DIO1/IRQ | 17 | 29 |
| BUSY | 12 | 30 |
| RESET | 13 | 31 |
| SPI bus | `/dev/spidev0.0` (CE0 = GPIO 8) | |
| DIO1/IRQ | 22 | IO6 |
| RESET | 16 | IO4 |
| BUSY | 24 | IO5 |
| RX/TX enable | 12, 13 (`Enable_Pins`; 13 = IO3 antenna switch) | IO3 |
No DIO2 RF switch (RAK13300 has discrete switch), no DIO3 TCXO.
Source: RAK6421 datasheet IO slot table + RAKWireless `meshtastic-rak6421-guide`.
SX1262 extras: **DIO3 powers a 1.8 V TCXO** (`dio3-tcxo-voltage = <SX126X_DIO3_TCXO_1V8>`)
and **DIO2 drives the RF switch** (`dio2-tx-enable` / `DIO2_AS_RF_SWITCH: true`) —
same as the Femtofox. The two `Enable_Pins` (12, 13) are held high at boot via
GPIO hogs in the overlay (`CONFIG_GPIO_HOGS=y` in the `.conf`). The RAK13302 is the
1W SKY66122-boosted variant and additionally wants a per-step `TX_GAIN_LORA` PA
gain table; ZephCore's SX126x driver does not expose that, so this overlay drives
the 13300 fully and the 13302 at default (non-boosted) PA.
---
@@ -451,6 +462,24 @@ west build … -- -DCONFIG_ZEPHCORE_LINUX_TCP_PORT=15000
The transport expects raw NUS bytes with no length prefix. If the connection drops immediately, capture traffic with `tcpdump -i any -X port 5000` and verify the first bytes the app sends look like a MeshCore opcode (e.g. `0x01` = CMD_APP_START), not an HTTP request or other framed protocol.
### `Failed to request line 8` / `CS GPIO configure failed: -5` (Raspberry Pi)
```
<err> gpio_native_linux: Failed to request line 8 on host chip
<err> spi_native_linux: CS GPIO configure failed: -5
<err> sx126x_hal: SPI bus not ready
<err> sx126x: HAL init failed: -19
```
On the Pi, `dtparam=spi=on` binds the spi0 controller to GPIO 711 in ALT0, so
**CE0 = BCM GPIO 8 is owned by the SPI controller** and cannot also be requested
as a plain GPIO for chip-select — the request fails with `-EIO`. The fix is to let
spidev drive CE0 in **hardware** (it asserts CS on every transfer) and **not**
declare `cs-gpios` in the overlay. The `rak6421` / `rak6421_pi5` overlays do this
(fixed 2026-06-03). If you copy the Femtofox overlay for a Pi setup, remove its
`cs-gpios` line — that path
only works when CS is a free GPIO (as it is on the Luckfox, GPIO48 on gpiochip1).
### Radio does nothing (no RX, CAD always times out, TX never completes)
The interrupt path (DIO1) and BUSY readback are the spine of all radio ops. If
@@ -562,6 +591,7 @@ End-to-end verified under WSL Ubuntu 24.04 (gcc 13.3):
-`LinuxTCPTransport` listens on port 5000.
- ✅ TCP client connect/disconnect works; `SerialWifiInterface` (`<`/`>` + 2-byte LE length) framing parses correctly.
-**End-to-end on real Femtofox hardware (2026-06-02):** radio RX, CAD (LBT), and TX all working; companion app connects and meshes; settings persist across restarts. (Required fixing two bugs in the native GPIO driver — see "Known caveats" below.)
-**End-to-end on real Raspberry Pi Zero 2 W + RAK6421/RAK13300 hardware (2026-06-03):** SX1262 init, SPI with spidev hardware CS (CE0), DIO3 TCXO, DIO2 RF switch, and over-the-air RX/TX all confirmed. (Required dropping the GPIO chip-select from the Pi overlays — CE0 is owned by the kernel SPI controller; see the `Failed to request line 8` troubleshooting entry.)
Build command verified (run from inside WSL with workspace at `/mnt/d/zephcore`):
+1 -2
View File
@@ -5,7 +5,6 @@
# -DEXTRA_CONF_FILE="boards/linux_native/femtofox.conf"
# linux_common.conf/.overlay (platform base) is applied automatically.
#
# Source: github.com/femtofox/femtofox foxbuntu meshtasticd config
# (femtofox_SX1262_TCXO.yaml).
# Source: github.com/femtofox/femtofox foxbuntu (femtofox_SX1262_TCXO.yaml).
CONFIG_ZEPHCORE_BOARD_NAME="Femtofox"
@@ -5,7 +5,7 @@
* Auto-paired with femtofox.conf. Defines the native_linux SPI/GPIO controllers
* and the SX1262 radio node on top of the platform infra in linux_common.overlay.
*
* Pins match the meshtasticd Femtofox profile (femtofox_SX1262_TCXO.yaml):
* Pins match the Femtofox SX1262 TCXO profile (femtofox_SX1262_TCXO.yaml):
* gpiochip1, CS=16/GPIO48, BUSY=22/GPIO54, DIO1=23/GPIO55, RESET=25/GPIO57,
* RXEN=24/GPIO56. DIO2 drives the RF switch, DIO3 powers a 1.8V TCXO.
*/
+1 -4
View File
@@ -5,15 +5,12 @@
# Raspberry Pi 5 moved the header to gpiochip4 — use rak6421_pi5.conf for it
# (or pass --lora-gpio-chip=/dev/gpiochip4 at runtime).
#
# IO Slot 1 wiring (BCM GPIO numbers on gpiochip0), per meshtasticd
# lora-RAK6421-13300-slot1.yaml:
# IO Slot 1 wiring (BCM GPIO numbers on gpiochip0):
# SPI: /dev/spidev0.0 (CE0 = GPIO 8, hardware CS)
# DIO1/IRQ: GPIO 22 (IO6)
# RESET: GPIO 16 (IO4)
# BUSY: GPIO 24 (IO5)
# DIO2 = RF switch, DIO3 = 1.8V TCXO, Enable_Pins 12+13 held high (GPIO hogs).
#
# Source: github.com/meshtastic/firmware bin/config.d/lora-RAK6421-13300-slot1.yaml
CONFIG_ZEPHCORE_BOARD_NAME="RAK6421"
+12 -9
View File
@@ -8,8 +8,7 @@
* Works on any Pi that exposes the 40-pin header on gpiochip0 (Pi 2/3/4/Zero 2).
* Pi 5 moved it to gpiochip4 — use rak6421_pi5.overlay instead.
*
* Pins + clock mirror the authoritative meshtasticd config
* (bin/config.d/lora-RAK6421-13300-slot1.yaml), BCM numbering:
* Pins + clock per the RAK6421 IO Slot 1 reference wiring, BCM numbering:
* CS = GPIO 8 (spidev0.0 CE0, hardware CS)
* DIO1 = GPIO 22 (IO6)
* RESET = GPIO 16 (IO4)
@@ -19,10 +18,11 @@
* Enable_Pins 12 + 13 are held HIGH to enable the module's RF front-end
* (driven via GPIO hogs below — needs CONFIG_GPIO_HOGS=y, set in rak6421.conf).
*
* NOTE: hardware-untested in ZephCore (only the Femtofox is verified). The
* RAK13302 (1W SKY66122) additionally wants a PA gain table that ZephCore's
* SX126x driver does not expose; this overlay drives the 13300 correctly and
* the 13302 at default (non-boosted) PA.
* NOTE: hardware-verified end-to-end on a Pi Zero 2 W + RAK13300 (2026-06-03):
* RX/TX, TCXO, and DIO2 RF switch all confirmed. The RAK13302 (1W SKY66122)
* additionally wants a PA gain table that ZephCore's SX126x driver does not
* expose; this overlay drives the 13300 correctly and the 13302 at default
* (non-boosted) PA.
*/
#include <zephyr/dt-bindings/gpio/gpio.h>
@@ -41,7 +41,7 @@
ngpios = <64>;
#gpio-cells = <2>;
/* RAK6421 Enable_Pins (meshtasticd): held high at boot to enable
/* RAK6421 Enable_Pins: held high at boot to enable
* the module / RF front-end. */
rak6421_enable {
gpio-hog;
@@ -58,8 +58,11 @@
spi-mode = <0>;
#address-cells = <1>;
#size-cells = <0>;
/* SPI CE0 = BCM GPIO 8, driven as a regular GPIO. */
cs-gpios = <&zephcore_gpio0 8 GPIO_ACTIVE_LOW>;
/* CS is spidev0.0's HARDWARE CE0 (BCM GPIO 8). With dtparam=spi=on
* the kernel SPI controller owns that pin (ALT0), so it canNOT be
* grabbed as a GPIO — spidev asserts CE0 on every transfer instead.
* Do NOT declare cs-gpios here (that's the Femtofox path, where CS is
* a free GPIO). */
lora_sx1262: lora@0 {
compatible = "semtech,sx1262";
@@ -5,10 +5,12 @@
* Auto-paired with rak6421_pi5.conf. Identical to rak6421.overlay except the
* Pi 5 moved the 40-pin header GPIOs to /dev/gpiochip4.
*
* Pins + clock mirror meshtasticd (lora-RAK6421-13300-slot1.yaml), BCM numbering:
* Pins + clock per the RAK6421 IO Slot 1 reference wiring, BCM numbering:
* CS = GPIO 8 (spidev0.0 CE0), DIO1 = GPIO 22, RESET = GPIO 16, BUSY = GPIO 24,
* DIO2 = RF switch, DIO3 = 1.8V TCXO, Enable_Pins 12+13 held high (GPIO hogs;
* needs CONFIG_GPIO_HOGS=y in rak6421_pi5.conf). Hardware-untested in ZephCore.
* needs CONFIG_GPIO_HOGS=y in rak6421_pi5.conf). Same wiring as rak6421.overlay,
* which is hardware-verified on a Pi Zero 2 W (2026-06-03); the Pi 5 gpiochip4
* variant is build-verified but not separately hardware-tested.
*/
#include <zephyr/dt-bindings/gpio/gpio.h>
@@ -43,7 +45,11 @@
spi-mode = <0>;
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&zephcore_gpio0 8 GPIO_ACTIVE_LOW>;
/* CS is spidev0.0's HARDWARE CE0 (BCM GPIO 8). With dtparam=spi=on
* the kernel SPI controller owns that pin (ALT0), so it canNOT be
* grabbed as a GPIO — spidev asserts CE0 on every transfer instead.
* Do NOT declare cs-gpios here (that's the Femtofox path, where CS is
* a free GPIO). */
lora_sx1262: lora@0 {
compatible = "semtech,sx1262";
@@ -4,7 +4,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*
* Pin mappings (from Meshtastic/MeshCore variant.h):
* Pin mappings (from MeshCore variant.h):
*
* SPI1 (LoRa SX1262): SCK=P0.03, MISO=P0.29, MOSI=P0.30, CS=P0.26
* NOTE: These pins are shared with QSPI flash QSPI must be disabled.
@@ -15,7 +15,7 @@
* - QSPI flash disabled (pins conflict with LoRa SPI bus)
* - SoftDevice s140 v6.1.1, UF2 bootloader
*
* Pin mappings (from Meshtastic/MeshCore variant.h):
* Pin mappings (from MeshCore variant.h):
* - LoRa SPI: SCK=P0.03, MOSI=P0.30, MISO=P0.29, CS=P0.26
* - LoRa ctl: DIO1=P0.10 (NFC2), BUSY=P0.09 (NFC1), RESET=P0.04
* - FEM: SX126X_POWER_EN=P0.21 (SKY66122 CSD+CPS)
@@ -144,8 +144,7 @@ static uint64_t input_flags(bool pull_up, bool pull_down, bool active_low)
/* else: leave bias AS-IS (no flag). Forcing BIAS_DISABLED can turn off
* the pin's input path on some SoCs (e.g. Rockchip), making a
* push-pull-driven input (SX126x BUSY) read stuck-low. libgpiod
* defaults to AS-IS, which is what meshtasticd uses to read these pins
* correctly. */
* defaults to AS-IS, which reads these pins correctly. */
return flags;
}