Description
Intermittent [RadioIf] Can not send yet, busyRx errors on Raspberry Pi 5 with an SX1262-based LoRa HAT using TXen/RXen RF switching (PiMesh 1W V1 / MeshAdv Pi Hat with Ebyte E22-900M30S). The radio initializes successfully but intermittently gets stuck in RX state due to false preamble detection, preventing transmission.
Hardware
- Board: Raspberry Pi 5 Model B Rev 1.1
- OS: DietPi (Debian Trixie 13, kernel 6.12.75+rpt-rpi-2712)
- LoRa HAT: PiMesh 1W V1 (Ebyte E22-900M30S / SX1262, 1W with external PA)
- GPS: ATGM336H (UART on /dev/ttyAMA0)
- meshtasticd: 2.7.20 (016e68e, native-tft)
- Connection: SPI (spidev0.0), GPIO via RP1 (gpiochip4)
LoRa Config (config.d/lora-pimesh-1w-v1.yaml)
Lora:
Module: sx1262
CS: 21
IRQ: 16
Busy: 20
Reset: 18
TXen: 13
RXen: 12
DIO3_TCXO_VOLTAGE: true
SX126X_MAX_POWER: 22
spidev: spidev0.0
gpiochip: 4
config.txt (relevant lines)
dtparam=spi=on
enable_uart=1
dtoverlay=disable-bt
Note: dtoverlay=spi0-0cs must NOT be used on Pi 5 — it conflicts with the RP1 SPI controller and causes SX126x init result -2 (chip not found) followed by a crash.
Symptoms
- Radio initializes successfully (
SX126x init result 0)
- Some packets transmit fine (e.g., NodeInfo at 30s after startup)
- Other packets intermittently fail with
busyRx (e.g., HostMetrics at 60s, GPS position at ~28s)
- Debug log shows
Ignore false preamble detection immediately after the busyRx warnings
- Once stuck, the radio never recovers to transmit that packet — the queue fills and discards
Debug Log (verbose mode)
INFO | Set radio: region=US, name=LongFast, config=0, ch=19, power=30
INFO | Final Tx power: 22 dBm
INFO | SX126x init result 0
INFO | Frequency set to 906.875000
INFO | Bandwidth set to 250.000000
INFO | Power output set to 22
INFO | Set RX gain to boosted mode; result: 0
INFO | Applied SX1262 register 0x8B5 patch for RX improvement
INFO | sx1262 init success
...
INFO | [GPS] Send pos@...:6 to mesh (wantReplies=0)
DEBUG | [GPS] enqueue for send (id=... encrypted len=68 ...)
WARN | [RadioIf] Can not send yet, busyRx
WARN | [RadioIf] Can not send yet, busyRx
WARN | [RadioIf] Can not send yet, busyRx
DEBUG | [RadioIf] Ignore false preamble detection
After longer runs without recovery:
INFO | [RadioIf] tophone queue status queue is full, discard oldest
Findings
Pi 5 GPIO chip matters
gpiochip: 0 (default) → radio initializes but BUSY pin reads incorrectly, busyRx on every TX attempt
gpiochip: 4 → radio works, busyRx is intermittent rather than constant
- On Pi 5 DietPi/Trixie,
/dev/gpiochip4 symlinks to /dev/gpiochip0, but the RP1 GPIO driver behaves differently depending on which chip number is requested
SX126X_MAX_POWER: 22 reduces frequency
- Without
SX126X_MAX_POWER: 22: busyRx on nearly every TX attempt
- With
SX126X_MAX_POWER: 22: busyRx is intermittent (~1 in 3 TX attempts)
spi0-0cs overlay breaks SX1262 init on Pi 5
- With
dtoverlay=spi0-0cs: SX126x init result -2 → crash (free(): invalid pointer)
- Without it: init succeeds. Default Pi 5 SPI config works fine since meshtasticd manages CS via GPIO21
Likely Root Cause
The RP1 GPIO controller on Pi 5 has different interrupt/edge detection behavior than the BCM GPIO on Pi 4 and earlier. The SX1262's IRQ pin (GPIO16) edge detection or the BUSY pin (GPIO20) level reading appears to be unreliable through the RP1, causing false preamble detections that prevent the radio from transitioning out of RX mode.
This may be related to:
- How
libgpiod handles edge events on the RP1
- Timing of BUSY pin polling after an IRQ event
- The RP1's GPIO interrupt coalescing or debouncing behavior
Related Issues
Steps to Reproduce
- Raspberry Pi 5 with any SX1262 HAT using TXen/RXen (PiMesh 1W V1, MeshAdv, etc.)
- Install meshtasticd 2.7.20
- Configure with gpiochip: 4, SX126X_MAX_POWER: 22
- Set region, wait for GPS fix or HostMetrics timer (60s)
- Observe intermittent busyRx in logs:
journalctl -u meshtasticd -f
Description
Intermittent
[RadioIf] Can not send yet, busyRxerrors on Raspberry Pi 5 with an SX1262-based LoRa HAT using TXen/RXen RF switching (PiMesh 1W V1 / MeshAdv Pi Hat with Ebyte E22-900M30S). The radio initializes successfully but intermittently gets stuck in RX state due to false preamble detection, preventing transmission.Hardware
LoRa Config (
config.d/lora-pimesh-1w-v1.yaml)config.txt (relevant lines)
Note:
dtoverlay=spi0-0csmust NOT be used on Pi 5 — it conflicts with the RP1 SPI controller and causesSX126x init result -2(chip not found) followed by a crash.Symptoms
SX126x init result 0)busyRx(e.g., HostMetrics at 60s, GPS position at ~28s)Ignore false preamble detectionimmediately after the busyRx warningsDebug Log (verbose mode)
After longer runs without recovery:
Findings
Pi 5 GPIO chip matters
gpiochip: 0(default) → radio initializes but BUSY pin reads incorrectly, busyRx on every TX attemptgpiochip: 4→ radio works, busyRx is intermittent rather than constant/dev/gpiochip4symlinks to/dev/gpiochip0, but the RP1 GPIO driver behaves differently depending on which chip number is requestedSX126X_MAX_POWER: 22 reduces frequency
SX126X_MAX_POWER: 22: busyRx on nearly every TX attemptSX126X_MAX_POWER: 22: busyRx is intermittent (~1 in 3 TX attempts)spi0-0cs overlay breaks SX1262 init on Pi 5
dtoverlay=spi0-0cs:SX126x init result -2→ crash (free(): invalid pointer)Likely Root Cause
The RP1 GPIO controller on Pi 5 has different interrupt/edge detection behavior than the BCM GPIO on Pi 4 and earlier. The SX1262's IRQ pin (GPIO16) edge detection or the BUSY pin (GPIO20) level reading appears to be unreliable through the RP1, causing false preamble detections that prevent the radio from transitioning out of RX mode.
This may be related to:
libgpiodhandles edge events on the RP1Related Issues
Can not send yet, busyRx#9580 — Same busyRx freeze on RPi Zero 2W with identical hardware config (TXen/RXen, SX1262)Steps to Reproduce
journalctl -u meshtasticd -f