diff --git a/zephcore/LINUX_NATIVE.md b/zephcore/LINUX_NATIVE.md index fa5e1e9..0bddc47 100644 --- a/zephcore/LINUX_NATIVE.md +++ b/zephcore/LINUX_NATIVE.md @@ -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) | 25–28 | -| 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 = `) +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) + +``` + gpio_native_linux: Failed to request line 8 on host chip + spi_native_linux: CS GPIO configure failed: -5 + sx126x_hal: SPI bus not ready + sx126x: HAL init failed: -19 +``` + +On the Pi, `dtparam=spi=on` binds the spi0 controller to GPIO 7–11 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`): diff --git a/zephcore/boards/linux_native/femtofox.conf b/zephcore/boards/linux_native/femtofox.conf index dc0eac5..ac34f14 100644 --- a/zephcore/boards/linux_native/femtofox.conf +++ b/zephcore/boards/linux_native/femtofox.conf @@ -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" diff --git a/zephcore/boards/linux_native/femtofox.overlay b/zephcore/boards/linux_native/femtofox.overlay index a079aac..a0dbb9d 100644 --- a/zephcore/boards/linux_native/femtofox.overlay +++ b/zephcore/boards/linux_native/femtofox.overlay @@ -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. */ diff --git a/zephcore/boards/linux_native/rak6421.conf b/zephcore/boards/linux_native/rak6421.conf index e6a1fad..f7ba5bf 100644 --- a/zephcore/boards/linux_native/rak6421.conf +++ b/zephcore/boards/linux_native/rak6421.conf @@ -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" diff --git a/zephcore/boards/linux_native/rak6421.overlay b/zephcore/boards/linux_native/rak6421.overlay index 8daf0cd..5e6972f 100644 --- a/zephcore/boards/linux_native/rak6421.overlay +++ b/zephcore/boards/linux_native/rak6421.overlay @@ -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 @@ -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"; diff --git a/zephcore/boards/linux_native/rak6421_pi5.overlay b/zephcore/boards/linux_native/rak6421_pi5.overlay index 66971b8..1525215 100644 --- a/zephcore/boards/linux_native/rak6421_pi5.overlay +++ b/zephcore/boards/linux_native/rak6421_pi5.overlay @@ -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 @@ -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"; diff --git a/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt-pinctrl.dtsi b/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt-pinctrl.dtsi index da80fc0..e5b38aa 100644 --- a/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt-pinctrl.dtsi +++ b/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt-pinctrl.dtsi @@ -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. diff --git a/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt.dts b/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt.dts index cd572d8..34eb9c3 100644 --- a/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt.dts +++ b/zephcore/boards/nrf52840/rak3401_1watt/rak3401_1watt.dts @@ -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) diff --git a/zephcore/patches/zephyr-new/drivers/gpio/gpio_native_linux_adapt.c b/zephcore/patches/zephyr-new/drivers/gpio/gpio_native_linux_adapt.c index 61b58b6..39a82cd 100644 --- a/zephcore/patches/zephyr-new/drivers/gpio/gpio_native_linux_adapt.c +++ b/zephcore/patches/zephyr-new/drivers/gpio/gpio_native_linux_adapt.c @@ -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; }