Files
otbr/boards/xiao_nrf54l15_nrf54l15_cpuapp.overlay
Timo a0f6e875be Slow the spinel link down so it survives traffic bursts
otbr-agent ran for hours, then died on a burst of Matter traffic:

  [W] P-RadioSpinel-: radio tx timeout
  [C] P-RadioSpinel-: Failed to communicate with RCP
  otbr-agent exited with code 6

The RCP itself was fine -- its frame timestamps showed 18 hours of
uninterrupted uptime across the crash, so nothing on the device reset.
The host simply lost bytes and desynchronised.

Nordic's nrf54l15dk overlay runs uart20 at 1 Mbaud, and this board's
overlay copied that, but the DK pairs it with hw-flow-control. The XIAO
cannot: uart20's pinctrl defines only TX and RX, and the CMSIS-DAP
bridge carries no RTS/CTS. Without back-pressure a single late RX
interrupt drops a byte, and a dropped byte corrupts the HDLC frame
around it.

460800 keeps roughly 4x headroom over peak 802.15.4 throughput while
widening the per-byte service window from 10 us to 21.7 us. The receive
queue goes to 8192 bytes for the same reason -- with no flow control,
whatever does not fit is lost rather than deferred.

The RadioURL on the border router host must set the matching
uart-baudrate=460800.
2026-08-22 14:20:57 +02:00

56 lines
2.0 KiB
Plaintext

/*
* OpenThread RCP on the Seeed XIAO nRF54L15.
*
* uart20 (P1.09 TX / P1.08 RX) is wired to the onboard CMSIS-DAP USB-serial
* bridge, so it is both the board's default console and the only UART that
* reaches the host over USB. The RCP needs that link for spinel, so:
*
* - zephyr,ot-uart -> uart20 (spinel to otbr-agent on the host)
* - zephyr,console -> uart21 (moved off, or console output would corrupt
* the spinel byte stream)
*
* uart21 (P2.08 TX / P2.07 RX) is exposed on the XIAO edge pads. Nothing needs
* to be attached; hook up a USB-UART adapter there if you want boot logs.
*
* Unlike Nordic's nrf54l15dk overlay, hw-flow-control is NOT set: the XIAO's
* pinctrl only defines TX and RX for uart20, and the CMSIS-DAP bridge does not
* carry RTS/CTS.
*
* That missing back-pressure is why the spinel link runs at 460800 rather than
* the 1000000 Nordic uses. Bandwidth was never the constraint -- 802.15.4 tops
* out around 250 kbps -- but without RTS/CTS a single late RX interrupt loses a
* byte outright, and a lost byte corrupts the HDLC frame around it. At 1 Mbaud
* the driver has 10 us to service each byte; the radio ISR can hold it off
* longer than that during a burst. 460800 widens the window to 21.7 us while
* still leaving roughly 4x headroom over peak Thread throughput.
*
* The symptom this fixes: otbr-agent runs for hours, then a traffic burst
* desynchronises the stream, the next transmit gets no response, and
* HandleRcpTimeout aborts the agent with exit code 6.
*
* [W] P-RadioSpinel-: radio tx timeout
* [C] P-RadioSpinel-: Failed to communicate with RCP - no response from RCP
*
* The host must agree on the rate. In the RadioURL on the border router host:
*
* spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=460800
*/
/ {
chosen {
zephyr,ot-uart = &uart20;
zephyr,console = &uart21;
zephyr,shell-uart = &uart21;
};
};
&uart20 {
status = "okay";
current-speed = <460800>;
};
&uart21 {
status = "okay";
current-speed = <115200>;
};