From 0b60af8090488cfcbd5f4a443d724ce53f7cc31f Mon Sep 17 00:00:00 2001 From: liquidraver <504870+liquidraver@users.noreply.github.com> Date: Sat, 22 Aug 2026 21:10:19 +0200 Subject: [PATCH] xiao_nrf54l15: catalog tile, verify board against schematics --- gen_provider_catalog.py | 5 ++ releasenotes/RELEASE_NOTES_1.17.2-zephcore.md | 5 ++ .../me25ls02/me25ls02_nrf54l15_cpuapp.dts | 18 +++- .../boards/nrf54l/xiao_nrf54l15/board.overlay | 88 ++++++++++++++++++- 4 files changed, 110 insertions(+), 6 deletions(-) diff --git a/gen_provider_catalog.py b/gen_provider_catalog.py index 6c64ff4..a46747a 100644 --- a/gen_provider_catalog.py +++ b/gen_provider_catalog.py @@ -95,6 +95,7 @@ MAKER_BY_DEVICE = { "RAK6421 WisMesh (Raspberry Pi 5)": "rak", "muzi works R1 Neo": "muziworks", "MinewSemi ME25LS02": "minewsemi", + "Seeed Studio Xiao nRF54L15": "seeed", } DESCRIPTION = ( @@ -211,6 +212,10 @@ BOARDS = [ # the .hex as a plain download and the user flashes it over SWD. dict(stem="me25ls02-nrf54l15-cpuapp", kind="nrf54l", device="MinewSemi ME25LS02", new=True, img="lora.svg"), + # Same story, except the XIAO carries a SAMD11 CMSIS-DAP bridge, so its own + # USB cable is enough (openocd/pyocd) -- still not a browser flash flow. + dict(stem="xiao_nrf54l15-nrf54l15-cpuapp", kind="nrf54l", + device="Seeed Studio Xiao nRF54L15", new=True, img="lora.svg"), # --- Native Linux (noflash, download only): new tiles ---------------- dict(stem="zephcore_linux_femtofox", kind="linux", device="Femtofox (Luckfox Pico Mini)", new=True, img="lora.svg"), diff --git a/releasenotes/RELEASE_NOTES_1.17.2-zephcore.md b/releasenotes/RELEASE_NOTES_1.17.2-zephcore.md index aebda9c..58b4aa5 100644 --- a/releasenotes/RELEASE_NOTES_1.17.2-zephcore.md +++ b/releasenotes/RELEASE_NOTES_1.17.2-zephcore.md @@ -245,6 +245,11 @@ Proposed by **bisbille** ([@bisbille](https://github.com/bisbille)) — Housekeeping, listed for completeness — nothing here changes how a node behaves day to day. +- **The XIAO nRF54L15 now ships firmware with every release.** The board has been supported for a + while but was never part of the published build, so it had to be compiled by hand. Companion and + repeater images are now built and listed alongside every other board. Like the ME25LS02 it is a + `.hex` flashed over SWD — though the XIAO's own USB cable is enough, since it has a debug bridge + built into the board. - **The Zephyr operating system underneath was updated** to a newer snapshot, and our radio patches were reorganised on top of it: five separate SX126x patches are now one. Same behaviour, fewer things to go wrong the next time Zephyr moves. diff --git a/zephcore/boards/nrf54l/me25ls02/me25ls02_nrf54l15_cpuapp.dts b/zephcore/boards/nrf54l/me25ls02/me25ls02_nrf54l15_cpuapp.dts index 9e23c3a..ee0486d 100644 --- a/zephcore/boards/nrf54l/me25ls02/me25ls02_nrf54l15_cpuapp.dts +++ b/zephcore/boards/nrf54l/me25ls02/me25ls02_nrf54l15_cpuapp.dts @@ -117,10 +117,14 @@ pinctrl-names = "default", "sleep"; /* - * The nRF54L SPIM applies an RX sample delay that the SX126x does not - * tolerate at these clock rates — MinewSemi drop it in their own sample - * and so do we. Symptom if left in: garbage on MISO, driver never sees - * the chip. + * MinewSemi delete the SoC's spi00 RX sample delay in their own working + * sample, so we do the same rather than diverge from the one + * configuration known to run on this module. + * + * Worth knowing: xiao_nrf54l15 is the same SoC driving the same radio at + * the same 8 MHz and keeps rx-delay = 1, so this is not a rule about the + * SoC — it is untested either way and each board keeps what its vendor + * shipped. If someone ever A/B's it on hardware, unify the two. */ /delete-property/ rx-delay-supported; /delete-property/ rx-delay; @@ -139,6 +143,12 @@ /* Crystal, not TCXO — do not add dio3-tcxo-voltage. */ + /* + * The module fits the SX1262's DC-DC inductor (L7 on DCC_SW), and + * the driver defaults to DC-DC regulator mode, so `regulator-ldo` + * must NOT be added here — it would force the lossier LDO path. + */ + rx-boosted; }; }; diff --git a/zephcore/boards/nrf54l/xiao_nrf54l15/board.overlay b/zephcore/boards/nrf54l/xiao_nrf54l15/board.overlay index 8f749d6..4c45a25 100644 --- a/zephcore/boards/nrf54l/xiao_nrf54l15/board.overlay +++ b/zephcore/boards/nrf54l/xiao_nrf54l15/board.overlay @@ -2,16 +2,45 @@ * SPDX-License-Identifier: MIT * XIAO nRF54L15 + Wio-SX1262 LoRa * + * Verified 2026-08-22 against primary sources (see datasheets/README.md): + * Seeed XIAO nRF54L15 schematic, the Wio-SX1262-for-XIAO carrier schematic, + * and the Wio-SX1262-N module datasheet. + * * Pin mapping (XIAO nRF54L15 connector → Wio-SX1262): * - D1 (P1.05) = DIO1 - D8 (P2.01) = SPI SCK (spi00) * - D2 (P1.06) = RESET - D9 (P2.04) = SPI MISO (spi00) * - D3 (P1.07) = BUSY - D10 (P2.02) = SPI MOSI (spi00) * - D4 (P1.10) = NSS * - D5 (P1.11) = RXEN + * The D-pin numbers come from the XIAO schematic's connector sheet, and the + * same D-pin assignment is used by our xiao_esp32c6 board on this same + * Wio-SX1262 carrier — two independent boards agreeing on the kit's wiring. + * + * Radio module facts, from the Wio-SX1262-N module datasheet: + * - RF_SW pin: "logic high level means enable receiver mode" → rx-enable-gpios + * is active high, which is what is set below. + * - DIO2 is internally connected to the RF switch, "logic high = enable + * transmitter" → dio2-tx-enable, no separate TXEN line. + * - DIO3 supplies the module's TCXO. Permitted 1.7–3.3 V, and it must stay at + * least 200 mV below VCC (3.3 V here), so the 1.8 V below is in range. + * - The module wires the SX1262 for DC-DC, not LDO. The Zephyr driver already + * defaults to DC-DC — `regulator-ldo` must NOT be added to the lora node. + * + * Clocks: the XIAO carries its own 32.768 kHz crystal (7 pF, 20 ppm), so the + * upstream board DTS enables LFXO and this node keeps accurate time. The + * ME25LS02, the other nRF54L board here, has no such crystal and runs the RC + * instead — do not copy clock settings between the two. * * Console: UART20 (P1.09 TX, P1.08 RX) via SAMD11 CMSIS-DAP bridge → USB CDC * Flash: RRAM (not traditional NV flash) - * Flash via: SWD through SAMD11 CMSIS-DAP (west flash / openocd) + * Flash via: SWD through SAMD11 CMSIS-DAP (west flash / openocd). The + * nRF54L15 has no USB peripheral, so there is no UF2 or DFU path — the + * published artifact is zephyr.hex, which links at RRAM base 0x0. + * + * Battery: the board has a charger (SGM40567, 200 mA) and a 2:1 divider on + * P1.14/AIN7, gated by P1.15/VBAT_EN (already a boot-on regulator in the + * upstream DTS). ZephCore does not read it yet — see the commented block at + * the bottom of this file for what is known and what still has to be measured. */ #include @@ -27,7 +56,16 @@ status = "disabled"; }; -/* SX1262 on spi00 (XIAO SPI bus — SCK/MISO/MOSI already in pinctrl) */ +/* + * SX1262 on spi00 (XIAO SPI bus — SCK/MISO/MOSI already in pinctrl). + * + * Note the divergence from the ME25LS02, which is the same SoC talking to the + * same radio: that board deletes `rx-delay-supported`/`rx-delay` from spi00 + * because MinewSemi's working sample does. This board keeps the SoC defaults + * (rx-delay = 1) and works. Neither setting has been A/B'd on hardware, so + * they are deliberately left as each board's known-good configuration rather + * than unified on a guess. + */ &spi00 { cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; /* D4 = P1.10 NSS */ @@ -89,3 +127,49 @@ /* LittleFS auto-mount — standard /lfs mount point */ #include "../../common/filesystem.dtsi" + +/* + * Battery voltage — NOT enabled, deliberately. + * + * The hardware is there: the schematic shows a 2:1 divider feeding P1.14/AIN7 + * ("battery voltage = ADC sampling voltage * 2.0"), enabled by P1.15/VBAT_EN, + * which the upstream board DTS already declares as `vbat_pwr` with + * regulator-boot-on. So a plain ADC read needs no extra power sequencing. + * + * What is missing is a trustworthy scale factor. ZephyrBoard computes + * `mV = raw * vbat-mv-multiplier / 4096`, so the multiplier has to encode the + * ADC's full-scale voltage, and the nRF54L15 SAADC is not the nRF52 part we + * have that number for: its internal reference is 0.9 V, not 0.6 V, and DS + * v1.0 §8.18.7 states the single-ended range as "± 0.5*VREF/GAIN" while the + * saturation condition two lines later implies a full span of VREF/GAIN. Those + * two readings differ by a factor of two — and getting it wrong by 2x means a + * healthy pack reports as flat and the node warns about a battery that is fine. + * + * To finish this, measure it: enable the block below on a board with a known + * cell voltage, read `raw`, and solve for the multiplier. With gain 1/4 and the + * 0.9 V reference the full scale is either 3.6 V (multiplier 7200 for the 2:1 + * divider) or 1.8 V (multiplier 3600). One measurement settles it. + * + * &adc { + * status = "okay"; + * + * #address-cells = <1>; + * #size-cells = <0>; + * + * channel@7 { + * reg = <7>; + * zephyr,gain = "ADC_GAIN_1_4"; + * zephyr,reference = "ADC_REF_INTERNAL"; + * zephyr,acquisition-time = ; + * zephyr,input-positive = ; + * zephyr,resolution = <12>; + * }; + * }; + * + * / { + * zephyr,user { + * io-channels = <&adc 7>; + * vbat-mv-multiplier = <7200>; + * }; + * }; + */