Skip to content

Fix SX1301 SPI bridge race causing PLL lock failures on faster hosts (all patch variants) - #219

Open
psych0d0g wants to merge 2 commits into
lorabasics:masterfrom
psych0d0g:fix/sx1301-spi-bridge-settling-delay
Open

psych0d0g wants to merge 2 commits into
lorabasics:masterfrom
psych0d0g:fix/sx1301-spi-bridge-settling-delay

Conversation

@psych0d0g

@psych0d0g psych0d0g commented Sep 11, 2026 •

Copy link
Copy Markdown

The vendored SX1301 HAL (Lora-net/lora_gateway v5.0.1) has a latent timing race in sx125x_read()/sx125x_write() (libloragw/src/loragw_radio.c):

the SX1301-to-SX1257/SX1255 radio bridge is a sequence of plain SX1301 register pokes (CS low, ADDR, DATA, CS high, CS low), and neither function leaves any settling time before the step that actually concludes the bridge transaction - the final CS pulse on write, the readback on read.

On a sufficiently fast host this bridge transaction hasn't finished before the next SPI transfer starts. Symptom: the SX1257 version register reads back 0x00 instead of the correct silicon revision, and the PLL retry loop in lgw_setup_sx125x() never locks - even though the SX1301 baseband chip itself responds correctly to direct register access the whole time. Confirmed via hardware testing: identical board works fine on a Raspberry Pi 3, fails 100% of the time on a Raspberry Pi 4.

A related but separate race exists in the calibration/AGC/ARB firmware load path in lgw_start(): the MCU reset registers are released and the firmware version is read back from MCU RAM with zero delay in between, which can spuriously fail the version check on the same class of host.

I checked, and this isn't specific to the RPi patch - v5.0.1-kerlink.patch and v5.0.1-linux.patch are byte-identical to v5.0.1-rpi.patch in both affected files (loragw_hal.c untouched by any of the three, loragw_radio.c only gets a logging include added in all three) - so Kerlink gateways and generic Linux hosts running this same SX1301 hardware on a fast enough CPU would hit the identical failure. This PR fixes all three.

Fix adds a 1ms settle before the concluding action in both sx125x functions, and a 100ms settle after each MCU reset release before its firmware version readback - negligible one-time added startup latency (tens of ms) against the ~2.3s calibration wait already in the same sequence, no impact on RX/TX runtime performance. Not board-specific either - both code paths are shared by every SX1301 design using SX1257/SX1255 radios, not just the board I tested on.

All three regenerated patch files (deps/lgw/v5.0.1-{rpi,kerlink,linux}.patch) were verified to apply cleanly to a pristine Lora-net/lora_gateway v5.0.1 checkout, independently of each other and of the existing patch content they build on - no dependency changes.

Also submitted the same fix upstream against brocaar/lora_gateway (used by chirpstack-concentratord)

Tested on: SX1301 + dual-SX1257 Raspberry Pi HAT (2018-12 Rev1 GW-01 RPI / wireless-road.com) on a Raspberry Pi 4. 10/10 clean cold-start successes after this fix, vs. 0 successes across 40+ attempts before it. Local build has ben verified against TTN successfully

Psych0D0g added 2 commits September 11, 2026 14:00
…(e.g. Raspberry Pi 4)

Signed-off-by: Psych0D0g <h@xx0r.eu>
… patch variants

Signed-off-by: Psych0D0g <h@xx0r.eu>
@psych0d0g
psych0d0g force-pushed the fix/sx1301-spi-bridge-settling-delay branch from c22e417 to 9b8ded9 Compare September 11, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant