mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-17 11:19:55 +00:00
add seeed lvk + nrf54lm20a
This commit is contained in:
@@ -158,6 +158,7 @@ xiao_mg24
|
||||
```
|
||||
me25ls02/nrf54l15/cpuapp
|
||||
seeed_lr2021_evk/nrf54l15/cpuapp
|
||||
seeed_lr2021_evk_lm20a/nrf54lm20a/cpuapp # source-only, no published firmware
|
||||
xiao_nrf54l15/nrf54l15/cpuapp
|
||||
```
|
||||
<!-- /boards -->
|
||||
|
||||
@@ -175,6 +175,17 @@ static const struct device *const fuel_gauge_dev =
|
||||
#define HAS_FUEL_GAUGE 0
|
||||
#endif
|
||||
|
||||
/* nPM1300 charger (XIAO nRF54LM20A): the PMIC measures VBAT with its own ADC
|
||||
* and Zephyr exposes that through the sensor API, not the fuel-gauge one.
|
||||
* Voltage only; state of charge comes from the discharge curve. */
|
||||
#if !HAS_FUEL_GAUGE && DT_HAS_COMPAT_STATUS_OKAY(nordic_npm1300_charger)
|
||||
#define HAS_PMIC_CHARGER 1
|
||||
static const struct device *const pmic_charger_dev =
|
||||
DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(nordic_npm1300_charger));
|
||||
#else
|
||||
#define HAS_PMIC_CHARGER 0
|
||||
#endif
|
||||
|
||||
/* Initialize activity LED GPIO at boot */
|
||||
#if HAS_TX_LED
|
||||
/* Width of the receive blink. A transmit holds the LED for its whole airtime,
|
||||
@@ -255,6 +266,21 @@ uint16_t ZephyrBoard::readBattMilliVolts()
|
||||
LOG_WRN("Fuel gauge voltage read failed: %d", ret);
|
||||
}
|
||||
return 0;
|
||||
#elif HAS_PMIC_CHARGER
|
||||
if (device_is_ready(pmic_charger_dev)) {
|
||||
struct sensor_value v;
|
||||
int ret = sensor_sample_fetch(pmic_charger_dev);
|
||||
|
||||
if (ret == 0) {
|
||||
ret = sensor_channel_get(pmic_charger_dev,
|
||||
SENSOR_CHAN_GAUGE_VOLTAGE, &v);
|
||||
}
|
||||
if (ret == 0) {
|
||||
return (uint16_t)(v.val1 * 1000 + v.val2 / 1000); /* V -> mV */
|
||||
}
|
||||
LOG_WRN("PMIC battery voltage read failed: %d", ret);
|
||||
}
|
||||
return 0;
|
||||
#elif DT_NODE_EXISTS(DT_PATH(zephyr_user)) && \
|
||||
DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
|
||||
if (!adc_is_ready_dt(&vbat_adc)) {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# Copyright (c) 2026 ZephCore
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
if BOARD_SEEED_LR2021_EVK_LM20A_NRF54LM20A_CPUAPP
|
||||
|
||||
config HAS_BT_CTLR
|
||||
default BT
|
||||
|
||||
# nPM1300 init order, copied from upstream Zephyr's xiao_nrf54lm20a
|
||||
# Kconfig.defconfig. The charger driver raises the PMIC's VBUS current limit
|
||||
# from its 100 mA power-up default to 500 mA, and it lives under the sensor
|
||||
# subsystem (priority 90). The regulators must come up after it, or the LDO1
|
||||
# soft-start inrush trips over-current protection and the board brown-outs in a
|
||||
# boot loop. The 500 mA limit matters to us beyond boot: an LR2021 at +22 dBm
|
||||
# does not fit in 100 mA on a kit running from USB alone.
|
||||
|
||||
config SENSOR
|
||||
default y
|
||||
|
||||
config REGULATOR
|
||||
default y
|
||||
|
||||
if REGULATOR_NPM13XX
|
||||
|
||||
config REGULATOR_NPM13XX_COMMON_INIT_PRIORITY
|
||||
default 91
|
||||
|
||||
config REGULATOR_NPM13XX_INIT_PRIORITY
|
||||
default 92
|
||||
|
||||
endif # REGULATOR_NPM13XX
|
||||
|
||||
endif # BOARD_SEEED_LR2021_EVK_LM20A_NRF54LM20A_CPUAPP
|
||||
@@ -0,0 +1,6 @@
|
||||
# Semtech LR2021 LoRa Plus EVK on a XIAO nRF54LM20A — board configuration
|
||||
# Copyright (c) 2026 ZephCore
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
config BOARD_SEEED_LR2021_EVK_LM20A
|
||||
select SOC_NRF54LM20A_CPUAPP if BOARD_SEEED_LR2021_EVK_LM20A_NRF54LM20A_CPUAPP
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2026 ZephCore
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# Same flashing story as seeed_lr2021_evk: the XIAO's USB-C goes to a SAMD11
|
||||
# that presents CMSIS-DAP plus a USB CDC for the uart20 console. The nRF54LM20A
|
||||
# does have a USB peripheral, but this XIAO leaves D+/D- unconnected, so there
|
||||
# is no UF2 and no DFU.
|
||||
#
|
||||
# The openocd config is upstream Zephyr's for the XIAO nRF54LM20A, used in place
|
||||
# rather than copied: it sources boards/seeed/common/openocd_nrf54l.cfg by a
|
||||
# path relative to itself.
|
||||
|
||||
board_runner_args(openocd "--config=${ZEPHYR_BASE}/boards/seeed/xiao_nrf54lm20a/support/openocd.cfg"
|
||||
"--cmd-load=nrf54l_load" "--cmd-erase=nrf54l_mass_erase"
|
||||
"--cmd-verify=verify_image" -c "targets nrf54lm20a.cpu")
|
||||
board_runner_args(jlink "--device=nRF54LM20A_M33" "--speed=4000")
|
||||
|
||||
include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake)
|
||||
@@ -0,0 +1,22 @@
|
||||
# Semtech LR2021 LoRa Plus EVK (XIAO nRF54LM20A + Wio-LR2021)
|
||||
# Board-specific configuration
|
||||
|
||||
# Board identification
|
||||
CONFIG_ZEPHCORE_BOARD_NAME="LR2021 LoRa Plus EVK LM20A"
|
||||
|
||||
# Device Information Service model name
|
||||
CONFIG_BT_DIS_MODEL_NUMBER_STR="Seeed LR2021 LoRa Plus EVK LM20A"
|
||||
|
||||
# LR2021 radio driver
|
||||
CONFIG_ZEPHCORE_RADIO_LR2021=y
|
||||
|
||||
# 511 KB of RAM leaves room well past the defaults (350 / 256). 510 contacts is
|
||||
# the most the companion protocol can report to the app (one byte, doubled);
|
||||
# each contact costs 188 B of RAM and each queue slot 173 B.
|
||||
CONFIG_ZEPHCORE_MAX_CONTACTS=510
|
||||
CONFIG_ZEPHCORE_OFFLINE_QUEUE_SIZE=512
|
||||
|
||||
# /ext on the XIAO's SPI NOR: LittleFS takes its block size from the flash page
|
||||
# layout, and the SPI NOR driver's default page is the 64 KB block, not the
|
||||
# 4 KB sector (the QSPI driver's equivalent is set in nrf52_common.conf).
|
||||
CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2026 ZephCore
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
board:
|
||||
name: seeed_lr2021_evk_lm20a
|
||||
full_name: Semtech LR2021 LoRa Plus EVK (XIAO nRF54LM20A + Wio-LR2021)
|
||||
vendor: seeed
|
||||
socs:
|
||||
- name: nrf54lm20a
|
||||
@@ -0,0 +1,19 @@
|
||||
# LR2021 LoRa Plus EVK (XIAO nRF54LM20A) bring-up logging.
|
||||
#
|
||||
# west build -b seeed_lr2021_evk_lm20a/nrf54lm20a/cpuapp zephcore --pristine --no-sysbuild -- \
|
||||
# -DEXTRA_CONF_FILE="boards/common/debug.conf;boards/nrf54l/seeed_lr2021_evk_lm20a/bringup.conf"
|
||||
#
|
||||
# Same set, for the same reasons, as boards/nrf54l/seeed_lr2021_evk/bringup.conf.
|
||||
# Not for daily use.
|
||||
|
||||
CONFIG_LORA_LOG_LEVEL_DBG=y
|
||||
|
||||
CONFIG_I2C_LOG_LEVEL_INF=y
|
||||
CONFIG_DISPLAY_LOG_LEVEL_DBG=y
|
||||
|
||||
# One line per real input event: K1 reaches the XIAO through a pogo pin, and
|
||||
# whether it lands on this XIAO's D14 pad is a bench question.
|
||||
CONFIG_INPUT_LOG_LEVEL_INF=y
|
||||
CONFIG_INPUT_EVENT_DUMP=y
|
||||
|
||||
CONFIG_FS_LOG_LEVEL_DBG=y
|
||||
@@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Suppress "unique_unit_address_if_enabled" to handle some overlaps
|
||||
list(APPEND EXTRA_DTC_FLAGS "-Wno-unique_unit_address_if_enabled")
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Semtech LR2021 LoRa Plus EVK on a XIAO nRF54LM20A — pin control
|
||||
* Copyright (c) 2026 ZephCore
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Pin assignments are the XIAO nRF54LM20A's fixed connector mapping, copied
|
||||
* from Zephyr's xiao_nrf54lm20a_nrf54lm20a-pinctrl.dtsi. Only the three buses
|
||||
* this kit uses are declared:
|
||||
*
|
||||
* uart20 P1.11 TX / P1.10 RX — console, via the SAMD11 CMSIS-DAP bridge
|
||||
* i2c22 P1.03 SDA / P1.07 SCL — D4/D5: OLED + the two I2C Grove ports
|
||||
* spi23 P1.04 SCK / P1.06 MOSI / P1.05 MISO — D8/D10/D9: LR2021
|
||||
* spi00 P2.01 SCK / P2.02 MOSI / P2.04 MISO — the XIAO's 8 MB flash (/ext)
|
||||
*
|
||||
* uart21 (D6/D7) is deliberately absent — see the DIO7/DIO11 note in the .dts.
|
||||
*/
|
||||
|
||||
&pinctrl {
|
||||
/omit-if-no-ref/ uart20_default: uart20_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(UART_TX, 1, 11)>;
|
||||
};
|
||||
|
||||
group2 {
|
||||
psels = <NRF_PSEL(UART_RX, 1, 10)>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
/omit-if-no-ref/ uart20_sleep: uart20_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(UART_TX, 1, 11)>,
|
||||
<NRF_PSEL(UART_RX, 1, 10)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
/omit-if-no-ref/ i2c22_default: i2c22_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(TWIM_SDA, 1, 3)>,
|
||||
<NRF_PSEL(TWIM_SCL, 1, 7)>;
|
||||
};
|
||||
};
|
||||
|
||||
/omit-if-no-ref/ i2c22_sleep: i2c22_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(TWIM_SDA, 1, 3)>,
|
||||
<NRF_PSEL(TWIM_SCL, 1, 7)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
/omit-if-no-ref/ spi00_default: spi00_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 2, 1)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 2, 2)>,
|
||||
<NRF_PSEL(SPIM_MISO, 2, 4)>;
|
||||
};
|
||||
};
|
||||
|
||||
/omit-if-no-ref/ spi00_sleep: spi00_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 2, 1)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 2, 2)>,
|
||||
<NRF_PSEL(SPIM_MISO, 2, 4)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
/omit-if-no-ref/ spi23_default: spi23_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 1, 4)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 1, 6)>,
|
||||
<NRF_PSEL(SPIM_MISO, 1, 5)>;
|
||||
};
|
||||
};
|
||||
|
||||
/omit-if-no-ref/ spi23_sleep: spi23_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 1, 4)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 1, 6)>,
|
||||
<NRF_PSEL(SPIM_MISO, 1, 5)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
};
|
||||
+430
@@ -0,0 +1,430 @@
|
||||
/*
|
||||
* Semtech LR2021 LoRa Plus Evaluation Kit with a XIAO nRF54LM20A fitted
|
||||
* Copyright (c) 2026 ZephCore
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* The same three-board sandwich as boards/nrf54l/seeed_lr2021_evk, with the
|
||||
* MCU module swapped:
|
||||
*
|
||||
* Seeed XIAO nRF54LM20A — the MCU (2036 KB RRAM, 511 KB RAM, nPM1300)
|
||||
* LoRa Plus Expansion Board V2a — OLED, buttons, Grove, SMA, SWD
|
||||
* Wio-LR2021 module — LR2021WIO1XDCS, 868/915 MHz, switchless
|
||||
*
|
||||
* Everything about the carrier and the radio module is unchanged and is
|
||||
* explained in seeed_lr2021_evk_nrf54l15_cpuapp.dts; this file only records
|
||||
* what the other XIAO changes. Sources, in devdocs/seeed_lr2021_evk/assets/lm20a:
|
||||
* the XIAO nRF54LM20A schematic and Zephyr's own xiao_nrf54lm20a board.
|
||||
*
|
||||
* XIAO connector map (Zephyr seeed_xiao_connector.dtsi, schematic sheet 6):
|
||||
* D0 P1.00 LR2021 IRQ (chip DIO8) D8 P1.04 SPI SCK (spi23)
|
||||
* D1 P1.31 LR2021 BUSY D9 P1.05 SPI MISO (spi23)
|
||||
* D2 P1.30 LR2021 NRESET D10 P1.06 SPI MOSI (spi23)
|
||||
* D3 P1.29 LR2021 NSS
|
||||
* D4 P1.03 I2C SDA (i2c22) — OLED + 2x Grove
|
||||
* D5 P1.07 I2C SCL (i2c22) — OLED + 2x Grove
|
||||
* D6 P1.08 LR2021 DIO7 / uart21 TX / Grove UART
|
||||
* D7 P1.09 LR2021 DIO11 / uart21 RX / Grove UART
|
||||
* D16 P3.05 K1 user button on the expansion board (back pad TP16; the
|
||||
* expansion board calls this pogo "D14", which is the L15's map)
|
||||
*
|
||||
* What differs from the nRF54L15 XIAO, beyond the pin numbers:
|
||||
* - The radio is on spi23. spi00 belongs to the XIAO's own 8 MB flash on P2,
|
||||
* which is mounted as /ext.
|
||||
* - Every pin used here sits on a port with GPIOTE (P0, P1, P3), so the
|
||||
* buttons are interrupt-driven and the L15's polling workaround is gone.
|
||||
* - An nPM1300 PMIC makes the 3.3 V rail and charges the battery.
|
||||
* - No 2.4 GHz antenna switch: ANT goes through a fixed match to the
|
||||
* ceramic antenna (sheet 6). Seeed's pin sheet lists RF_SW_PWR/RF_SW_CTL
|
||||
* on P1.27/P1.28, but no such net exists in the schematic.
|
||||
* - The SoC has USB, the board does not use it: D+/D- are no-connects and
|
||||
* the VBUS link R23 is not fitted. Flashing and console stay on the SAMD11.
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <nordic/nrf54lm20a_cpuapp.dtsi>
|
||||
#include "seeed_lr2021_evk_lm20a-pinctrl.dtsi"
|
||||
#include <zephyr/dt-bindings/input/input-event-codes.h>
|
||||
#include <zephyr/dt-bindings/regulator/npm13xx.h>
|
||||
|
||||
/ {
|
||||
model = "Semtech LR2021 LoRa Plus EVK (XIAO nRF54LM20A)";
|
||||
compatible = "seeed,lr2021-evk-lm20a";
|
||||
|
||||
chosen {
|
||||
zephyr,sram = &cpuapp_sram_app;
|
||||
zephyr,flash = &cpuapp_rram;
|
||||
zephyr,flash-controller = &rram_controller;
|
||||
zephyr,console = &uart20;
|
||||
zephyr,shell-uart = &uart20;
|
||||
zephyr,bt-hci = &bt_hci_controller;
|
||||
zephyr,display = &ssd1306;
|
||||
/* No zephyr,code-partition: no bootloader, the image links at
|
||||
* RRAM base 0x0. Same choice as seeed_lr2021_evk. */
|
||||
};
|
||||
|
||||
aliases {
|
||||
lora0 = &lora;
|
||||
led0 = &blue_led;
|
||||
sw0 = &user_button;
|
||||
};
|
||||
|
||||
/* RGB LED on the XIAO core board. */
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
blue_led: led_0 {
|
||||
gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
|
||||
label = "Blue LED";
|
||||
};
|
||||
|
||||
red_led: led_1 {
|
||||
gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
|
||||
label = "Red LED";
|
||||
};
|
||||
|
||||
green_led: led_2 {
|
||||
gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
|
||||
label = "Green LED";
|
||||
};
|
||||
};
|
||||
|
||||
buttons: buttons {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
/*
|
||||
* K1 on the expansion board: a bare switch to GND, so the
|
||||
* internal pull-up is required.
|
||||
*
|
||||
* NOT this XIAO's D14. K1 reaches the MCU through a pogo pin
|
||||
* placed for the nRF54L15 XIAO's D14 back pad, and the two XIAOs
|
||||
* put different nets on the same eight pad positions (both KiCad
|
||||
* board files, devdocs/seeed_lr2021_evk/assets). The pad that
|
||||
* pogo touches here is TP16 = D16 = P3.05; D14 (P3.03, TP14) sits
|
||||
* in the other pad row. P3 has a GPIOTE instance (gpiote20), so
|
||||
* no polling as on the L15's P2.09.
|
||||
*
|
||||
* Derived from the board files, NOT confirmed on hardware: on the
|
||||
* one kit tried (2026-10-02) holding K1 pulled none of P3.00..07
|
||||
* low with pull-ups on all eight, i.e. the pogo pins made no
|
||||
* contact at all. The XIAO's own button below is the one that works.
|
||||
*/
|
||||
user_button: button_0 {
|
||||
gpios = <&gpio3 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
|
||||
zephyr,code = <INPUT_KEY_0>;
|
||||
label = "K1 (expansion board)";
|
||||
};
|
||||
|
||||
/* The XIAO core board's own USR button. Same key code as K1. */
|
||||
xiao_button: button_1 {
|
||||
gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
|
||||
zephyr,code = <INPUT_KEY_0>;
|
||||
label = "USR (XIAO core board)";
|
||||
};
|
||||
};
|
||||
|
||||
/* Button chain — same mapping as RAK4631 (rak4631/board.overlay). */
|
||||
user_btn_longpress {
|
||||
compatible = "zephyr,input-longpress";
|
||||
input = <&buttons>;
|
||||
input-codes = <INPUT_KEY_0>;
|
||||
short-codes = <INPUT_KEY_A>;
|
||||
long-codes = <INPUT_KEY_ENTER>;
|
||||
long-delay-ms = <1000>;
|
||||
};
|
||||
|
||||
page_btn_multitap {
|
||||
compatible = "zephcore,input-multi-tap";
|
||||
input-codes = <INPUT_KEY_A>;
|
||||
tap-codes = <INPUT_KEY_1 INPUT_KEY_LEFT>;
|
||||
tap-delay-ms = <400>;
|
||||
};
|
||||
|
||||
/*
|
||||
* nPM1300 on a bit-banged bus (P1.17 SCL / P1.18 SDA). Copied from
|
||||
* upstream Zephyr's xiao_nrf54lm20a; the init order it depends on is in
|
||||
* Kconfig.defconfig.
|
||||
*/
|
||||
pmic_i2c: pmic-i2c {
|
||||
compatible = "gpio-i2c";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
sda-gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
|
||||
scl-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>;
|
||||
clock-frequency = <100000>;
|
||||
status = "okay";
|
||||
|
||||
pmic: npm1300@6b {
|
||||
compatible = "nordic,npm1300";
|
||||
reg = <0x6b>;
|
||||
|
||||
pmic_charger: charger {
|
||||
compatible = "nordic,npm1300-charger";
|
||||
term-microvolt = <4200000>;
|
||||
term-warm-microvolt = <4000000>;
|
||||
current-microamp = <150000>;
|
||||
dischg-limit-microamp = <1000000>;
|
||||
vbus-limit-microamp = <500000>;
|
||||
thermistor-ohms = <10000>;
|
||||
thermistor-beta = <3380>;
|
||||
charging-enable;
|
||||
};
|
||||
|
||||
regulators {
|
||||
compatible = "nordic,npm1300-regulator";
|
||||
|
||||
/*
|
||||
* BUCK2 is VSYS_3V3: the nRF54, the SAMD11 debugger
|
||||
* and, through the expansion board, the LR2021.
|
||||
*/
|
||||
vsys_3v3: BUCK2 {
|
||||
regulator-always-on;
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
|
||||
/* IMU and microphone supply. */
|
||||
imu_vdd: LDO1 {
|
||||
regulator-init-microvolt = <3300000>;
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-initial-mode = <NPM13XX_LDSW_MODE_LDO>;
|
||||
regulator-allowed-modes = <NPM13XX_LDSW_MODE_LDO>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&cpuapp_sram {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&hfpll {
|
||||
clock-frequency = <DT_FREQ_M(128)>;
|
||||
};
|
||||
|
||||
&grtc {
|
||||
owned-channels = <0 1 2 3 4 5 6 7 8 9 10 11>;
|
||||
/* Channels 7-11 reserved for Zero Latency IRQs, 3-4 for FLPR */
|
||||
child-owned-channels = <3 4 7 8 9 10 11>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* Clock set as upstream's xiao_nrf54lm20a. */
|
||||
&clock {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&xo {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&lfclk {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&xo24m {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* Console: P1.11 TX / P1.10 RX -> SAMD11 CMSIS-DAP bridge -> USB CDC */
|
||||
&uart20 {
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
pinctrl-0 = <&uart20_default>;
|
||||
pinctrl-1 = <&uart20_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
/* D6/D7 are also the LR2021's DIO7/DIO11 — see seeed_lr2021_evk. */
|
||||
&uart21 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&i2c22 {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&i2c22_default>;
|
||||
pinctrl-1 = <&i2c22_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
clock-frequency = <400000>;
|
||||
|
||||
/* Mandatory for the SSD1306 on nrf-twim: 1 + 1024, rounded up. */
|
||||
zephyr,concat-buf-size = <1088>;
|
||||
|
||||
/* ZJY-2864KSWPG01 on the expansion board; settings as seeed_lr2021_evk. */
|
||||
ssd1306: ssd1306@3c {
|
||||
compatible = "solomon,ssd1306";
|
||||
reg = <0x3c>;
|
||||
width = <128>;
|
||||
height = <64>;
|
||||
segment-offset = <0>;
|
||||
page-offset = <0>;
|
||||
display-offset = <0>;
|
||||
multiplex-ratio = <63>;
|
||||
segment-remap;
|
||||
com-invdir;
|
||||
inversion-on;
|
||||
prechargep = <0x22>;
|
||||
};
|
||||
};
|
||||
|
||||
&spi23 {
|
||||
status = "okay";
|
||||
cs-gpios = <&gpio1 29 GPIO_ACTIVE_LOW>; /* D3 = P1.29 NSS */
|
||||
pinctrl-0 = <&spi23_default>;
|
||||
pinctrl-1 = <&spi23_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
|
||||
/* The bus must idle at the LR2021's NOP, not Nordic's 0xFF. */
|
||||
overrun-character = <0x00>;
|
||||
|
||||
lora: lora@0 {
|
||||
compatible = "semtech,lr2021";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <8000000>;
|
||||
|
||||
reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>; /* D2 = P1.30 */
|
||||
busy-gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>; /* D1 = P1.31 */
|
||||
irq-gpios = <&gpio1 0 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; /* D0 = P1.00 */
|
||||
irq-dio = <8>; /* chip DIO8 -> module pin 1 -> D0 */
|
||||
|
||||
/* No TCXO and no RF switch: both are properties of the Wio-LR2021
|
||||
* module, settled on hardware — see seeed_lr2021_evk. */
|
||||
rx-boosted;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* The XIAO's own 8 MB SPI NOR (PY25Q64HA) on P2, mounted as /ext by
|
||||
* qspi-ext.dtsi below: contacts, channels and blobs move there, and contact
|
||||
* saves become atomic. Flash parameters are upstream Zephyr's xiao_nrf54lm20a
|
||||
* node, except the clock: upstream gives the part's 133 MHz ceiling, this
|
||||
* stays at 8 MHz until a faster rate is measured to be worth having.
|
||||
*
|
||||
* The label is "qspi_flash" because that is the name qspi-ext.dtsi and
|
||||
* ZephyrFsFormat.c look for; the part is driven as plain single-line SPI.
|
||||
*/
|
||||
&spi00 {
|
||||
status = "okay";
|
||||
cs-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
|
||||
pinctrl-0 = <&spi00_default>;
|
||||
pinctrl-1 = <&spi00_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
|
||||
qspi_flash: py25q64ha@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <8000000>;
|
||||
jedec-id = [85 20 17];
|
||||
sfdp-bfp = [e5 20 f9 ff ff ff ff 03 44 eb 08 6b 08 3b 80 bb
|
||||
fe ff ff ff ff ff 00 ff ff ff 44 eb 0c 20 0f 52
|
||||
10 d8 00 81];
|
||||
size = <67108864>;
|
||||
has-dpd;
|
||||
t-enter-dpd = <3000>;
|
||||
requires-ulbpr;
|
||||
hold-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
|
||||
wp-gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
/* Full 8 MB for LittleFS storage */
|
||||
qspi_storage_partition: partition@0 {
|
||||
label = "qspi_storage";
|
||||
reg = <0x00000000 0x00800000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio3 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpiote20 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpiote30 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&vregmain {
|
||||
status = "okay";
|
||||
regulator-initial-mode = <NRF5X_REG_MODE_DCDC>;
|
||||
};
|
||||
|
||||
/* Crystal load capacitances as upstream's xiao_nrf54lm20a. */
|
||||
&lfxo {
|
||||
load-capacitors = "internal";
|
||||
load-capacitance-femtofarad = <17000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&hfxo {
|
||||
load-capacitors = "internal";
|
||||
load-capacitance-femtofarad = <15000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&radio {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&bt_hci_controller {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&temp {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* Default Nordic RRAM map, then re-carved below for ZephCore. */
|
||||
#include <vendor/nordic/nrf54lm20a_cpuapp_partition.dtsi>
|
||||
|
||||
/*
|
||||
* RRAM layout (2036 KB total, 0x1FD000; the last 96 KB are the FLPR core's).
|
||||
*
|
||||
* No bootloader: the application starts at 0x0, so the DFU slots are deleted.
|
||||
*
|
||||
* 0x000000 - 0x1C0000 (1792 KB) application (links from 0x0)
|
||||
* 0x1C0000 - 0x1E0000 (128 KB) LittleFS: identity, prefs, contacts,
|
||||
* channels, BLE bonds
|
||||
* 0x1E0000 - 0x1E5000 (20 KB) unused
|
||||
* 0x1E5000 - 0x1FD000 (96 KB) reserved for FLPR
|
||||
*/
|
||||
/delete-node/ &slot0_partition;
|
||||
/delete-node/ &slot1_partition;
|
||||
/delete-node/ &storage_partition;
|
||||
|
||||
&cpuapp_rram {
|
||||
partitions {
|
||||
lfs_partition: partition@1c0000 {
|
||||
compatible = "zephyr,mapped-partition";
|
||||
label = "lfs";
|
||||
reg = <0x1C0000 0x20000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* LittleFS auto-mount — standard /lfs mount point */
|
||||
#include "../../common/filesystem.dtsi"
|
||||
|
||||
/* /ext on the 8 MB SPI NOR: deferred init, mounted by the store on first use */
|
||||
#include "../../common/qspi-ext.dtsi"
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
# Semtech LR2021 LoRa Plus EVK (XIAO nRF54LM20A) default configuration
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
CONFIG_ARM_MPU=y
|
||||
CONFIG_HW_STACK_PROTECTION=y
|
||||
CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y
|
||||
|
||||
CONFIG_CACHE_MANAGEMENT=y
|
||||
CONFIG_EXTERNAL_CACHE=y
|
||||
|
||||
# Console on uart20 -> SAMD11 CMSIS-DAP bridge -> USB CDC
|
||||
# (the SoC's own USB is not routed to the connector on this XIAO)
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_UART_CONSOLE=y
|
||||
|
||||
CONFIG_GPIO=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_I2C=y
|
||||
|
||||
# RRAM + LittleFS
|
||||
CONFIG_FLASH=y
|
||||
CONFIG_FLASH_MAP=y
|
||||
|
||||
CONFIG_NRF_GRTC_START_SYSCOUNTER=y
|
||||
|
||||
# nPM1300 regulators; init order is in Kconfig.defconfig.
|
||||
CONFIG_REGULATOR=y
|
||||
@@ -0,0 +1,3 @@
|
||||
# ZephCore board manifest — schema in zephcore/scripts/board_manifest.py
|
||||
# No release: until validated on hardware.
|
||||
target: seeed_lr2021_evk_lm20a/nrf54lm20a/cpuapp
|
||||
@@ -1154,7 +1154,10 @@ static bool lr20xx_apply_rx_duty_cycle(struct lr20xx_data *data)
|
||||
* As on the LR11xx (DS §6.3.8 is word for word UM §7.2.6): any NSS edge in
|
||||
* the sleep phase ends the loop, and BUSY is high in sleep and in Rx alike.
|
||||
* So suspend = SetStandby (never an NSS poke: that caused the X1's CMD_PERR
|
||||
* storm), resume = re-arm. Caller holds spi_mutex. LLD 05 §13. */
|
||||
* storm), resume = re-arm. Resume expects the standby suspend left: the chip
|
||||
* answers SetRxDutyCycle with CMD_FAIL while in Rx (measured; DS §6.3.5 says
|
||||
* it of SetRx), so a caller that enters Rx in between leaves it again first.
|
||||
* Caller holds spi_mutex. LLD 05 §13. */
|
||||
static bool lr20xx_dc_suspend(struct lr20xx_data *data)
|
||||
{
|
||||
if (!data->rx_duty_cycle_enabled || !data->in_rx_mode) {
|
||||
@@ -2440,6 +2443,12 @@ int16_t lr20xx_get_rssi_inst(const struct device *dev)
|
||||
out = rssi;
|
||||
}
|
||||
|
||||
if (armed) {
|
||||
/* Leave the Rx entered above; dc_resume() re-arms from standby. */
|
||||
lr20xx_system_set_standby_mode(&data->hal_ctx,
|
||||
LR20XX_SYSTEM_STANDBY_MODE_RC);
|
||||
}
|
||||
|
||||
lr20xx_dc_resume(data, armed);
|
||||
k_mutex_unlock(&data->spi_mutex);
|
||||
|
||||
@@ -2529,6 +2538,10 @@ int lr20xx_get_rssi_burst(const struct device *dev, int16_t *out, int n,
|
||||
LR20XX_SYSTEM_IRQ_SYNC_WORD_HEADER_VALID))) {
|
||||
got = -EAGAIN;
|
||||
}
|
||||
|
||||
/* Leave the Rx entered above; dc_resume() re-arms from standby. */
|
||||
lr20xx_system_set_standby_mode(&data->hal_ctx,
|
||||
LR20XX_SYSTEM_STANDBY_MODE_RC);
|
||||
}
|
||||
|
||||
lr20xx_dc_resume(data, armed);
|
||||
|
||||
Reference in New Issue
Block a user