mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-01 22:38:19 +00:00
thinknode m6 port
This commit is contained in:
@@ -210,7 +210,7 @@ set(ZEPHCORE_COMMON_CONF "${CMAKE_CURRENT_SOURCE_DIR}/boards/common/zephcore_com
|
||||
# Detect platform from board name and add platform-specific common config
|
||||
# For boards with qualifiers like "wio_tracker_l1/nrf52840", check both the full BOARD
|
||||
# string and the BOARD_QUALIFIERS which contains just the qualifier (e.g., "nrf52840")
|
||||
if(BOARD MATCHES ".*nrf52.*" OR BOARD MATCHES "rak4631" OR BOARD MATCHES "rak_wismesh_tag" OR BOARD MATCHES "wio_tracker" OR BOARD MATCHES "ikoka_nano" OR BOARD MATCHES "t1000_e" OR BOARD MATCHES "thinknode_m1" OR BOARD MATCHES "thinknode_m3")
|
||||
if(BOARD MATCHES ".*nrf52.*" OR BOARD MATCHES "rak4631" OR BOARD MATCHES "rak_wismesh_tag" OR BOARD MATCHES "wio_tracker" OR BOARD MATCHES "ikoka_nano" OR BOARD MATCHES "t1000_e" OR BOARD MATCHES "thinknode_m1" OR BOARD MATCHES "thinknode_m3" OR BOARD MATCHES "thinknode_m6")
|
||||
set(ZEPHCORE_PLATFORM_CONF "${CMAKE_CURRENT_SOURCE_DIR}/boards/common/nrf52_common.conf")
|
||||
elseif(DEFINED BOARD_QUALIFIERS AND BOARD_QUALIFIERS MATCHES ".*nrf52.*")
|
||||
set(ZEPHCORE_PLATFORM_CONF "${CMAKE_CURRENT_SOURCE_DIR}/boards/common/nrf52_common.conf")
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Use THIS file instead of sdv7 when the board's UF2 bootloader
|
||||
* bundles SoftDevice s140 v6.x (app starts at 0x26000).
|
||||
*
|
||||
* Boards: RAK4631
|
||||
* Boards: RAK4631, ThinkNode M6
|
||||
*
|
||||
* Usage in board overlay:
|
||||
* /delete-node/ &boot_partition;
|
||||
@@ -22,6 +22,18 @@
|
||||
* 0xF4000 - 0x100000 (48KB) UF2 bootloader (reserved)
|
||||
*/
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
/* nRF52840 SoC DTSI defines sram0 but does NOT set zephyr,sram
|
||||
* in chosen. The upstream nrf52840_partition.dtsi provides it,
|
||||
* but custom boards that include this file directly (without
|
||||
* nrf52840_partition.dtsi) would get RAM = 0 in the linker
|
||||
* script, causing "region RAM overflowed" on the first build.
|
||||
* Set it here so all boards using this DTSI get it for free. */
|
||||
zephyr,sram = &sram0;
|
||||
};
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* │ - SD v7: Application starts at 0x27000 (156KB reserved) │
|
||||
* │ Boards: T1000-E, Ikoka Nano 30dBm, Wio Tracker L1 │
|
||||
* │ - SD v6: Application starts at 0x26000 (152KB reserved) │
|
||||
* │ Boards: RAK4631 │
|
||||
* │ Boards: RAK4631, ThinkNode M6 │
|
||||
* │ │
|
||||
* │ USAGE IN BOARD DTS (if base includes nrf52840_partition.dtsi): │
|
||||
* │ /delete-node/ &boot_partition; │
|
||||
@@ -51,6 +51,18 @@
|
||||
* 0xF4000 - 0x100000 (48KB) UF2 bootloader (reserved)
|
||||
*/
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
/* nRF52840 SoC DTSI defines sram0 but does NOT set zephyr,sram
|
||||
* in chosen. The upstream nrf52840_partition.dtsi provides it,
|
||||
* but custom boards that include this file directly (without
|
||||
* nrf52840_partition.dtsi) would get RAM = 0 in the linker
|
||||
* script, causing "region RAM overflowed" on the first build.
|
||||
* Set it here so all boards using this DTSI get it for free. */
|
||||
zephyr,sram = &sram0;
|
||||
};
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
|
||||
@@ -14,6 +14,7 @@ Supported Boards
|
||||
| T1000-E | `west build -b t1000_e zephcore` | UF2 drag-drop or `west flash` |
|
||||
| ThinkNode M1 | `west build -b thinknode_m1 zephcore` | UF2 drag-drop or `west flash` |
|
||||
| ThinkNode M3 | `west build -b thinknode_m3 zephcore` | UF2 drag-drop or `west flash` |
|
||||
| ThinkNode M6 | `west build -b thinknode_m6 zephcore` | UF2 drag-drop or `west flash` |
|
||||
| RAK WisMesh Tag | `west build -b rak_wismesh_tag zephcore` | UF2 drag-drop or `west flash` |
|
||||
| Ikoka Nano 30dBm | `west build -b ikoka_nano_30dbm zephcore` | UF2 drag-drop |
|
||||
|
||||
@@ -136,6 +137,25 @@ A full custom board includes:
|
||||
<board>_<soc>_defconfig — Minimal defconfig
|
||||
board.cmake — Flash runner config
|
||||
|
||||
**Critical: `zephyr,sram` in the chosen node (nRF52840 only)**
|
||||
|
||||
The nRF52840 SoC DTSI defines `sram0` but does NOT set `zephyr,sram` in
|
||||
the chosen node. Without it, the linker gets `RAM size = 0` and every
|
||||
build fails with "region 'RAM' overflowed" regardless of actual RAM use.
|
||||
|
||||
Boards that include `<nordic/nrf52840_partition.dtsi>` get this for free.
|
||||
Boards that use `nrf52_partitions_sdv6.dtsi` or `nrf52_partitions_sdv7.dtsi`
|
||||
directly (without the upstream include) also get it now — those DTSIs set
|
||||
`zephyr,sram = &sram0` themselves.
|
||||
|
||||
If you write a fully custom DTS that includes neither, add it yourself:
|
||||
|
||||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,code-partition = &code_partition;
|
||||
...
|
||||
};
|
||||
|
||||
|
||||
What Goes in board.conf
|
||||
-----------------------
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Copyright (c) 2025 ZephCore
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BOARD_THINKNODE_M6
|
||||
select SOC_NRF52840_QIAA
|
||||
@@ -0,0 +1,13 @@
|
||||
# Copyright (c) 2025 ZephCore
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
board_runner_args(jlink "--device=nRF52840_xxAA" "--speed=4000")
|
||||
board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000")
|
||||
|
||||
set(OPENOCD_NRF5_SUBFAMILY "nrf52")
|
||||
|
||||
include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake)
|
||||
include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake)
|
||||
@@ -0,0 +1,23 @@
|
||||
# Elecrow ThinkNode M6 (nRF52840 + SX1262)
|
||||
# Board-specific configuration
|
||||
#
|
||||
# Hardware:
|
||||
# - nRF52840 SoC with BLE (DCDC regulator)
|
||||
# - SX1262 LoRa radio (DIO2 RF switch, DIO3 TCXO 3.3V, 22dBm)
|
||||
# - GPS L76K on UART0 (9600 baud, NMEA)
|
||||
# - Battery ADC on AIN4 (P0.28), 1.75:1 voltage divider, ADC_CTRL=P0.11
|
||||
# - LEDs: RED=P0.12, BLUE=P0.07 (active-HIGH), TX LED = BLUE
|
||||
# - Button on P0.17 (active-low, pull-up)
|
||||
# - QSPI Flash MX25R1635F 2MB
|
||||
|
||||
# Board identification (matches Arduino MeshCore variant name)
|
||||
CONFIG_ZEPHCORE_BOARD_NAME="ThinkNode M6"
|
||||
|
||||
# Device Information Service model name
|
||||
CONFIG_BT_DIS_MODEL_NUMBER_STR="Elecrow ThinkNode-M6"
|
||||
|
||||
# SoftDevice firmware ID (ThinkNode M6 bootloader uses S140 v6, same as M1/M3)
|
||||
CONFIG_ZEPHCORE_SD_FWID=0x00B6
|
||||
|
||||
# Contacts — QSPI (2MB) provides ample storage for more contacts
|
||||
CONFIG_ZEPHCORE_MAX_CONTACTS=510
|
||||
@@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2025 ZephCore
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
board:
|
||||
name: thinknode_m6
|
||||
full_name: Elecrow ThinkNode M6 (nRF52840 + SX1262)
|
||||
vendor: elecrow
|
||||
socs:
|
||||
- name: nrf52840
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Elecrow ThinkNode M6 - Pin Control
|
||||
* Copyright (c) 2025 ZephCore
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Pin assignments from Arduino variant.h and platformio.ini:
|
||||
* - SPI1 (LoRa SX1262): SCK=P1.13, MOSI=P1.14, MISO=P1.15, NSS=P1.12
|
||||
* - I2C0 (sensors): SDA=P1.09, SCL=P0.08
|
||||
* - UART0 (GPS 9600): TX=P0.02 (→GPS RX), RX=P0.03 (←GPS TX)
|
||||
* - QSPI (MX25R1635F): SCK=P1.03, CS=P0.23, IO0=P1.01, IO1=P1.02,
|
||||
* IO2=P1.04, IO3=P1.05
|
||||
*/
|
||||
|
||||
&pinctrl {
|
||||
/* GPS UART0 - 9600 baud
|
||||
* Note: PIN_GPS_TX/RX naming is from GPS module's perspective in variant.h.
|
||||
* nRF UART TX → P0.02 (PIN_GPS_RX), nRF UART RX ← P0.03 (PIN_GPS_TX). */
|
||||
uart0_default: uart0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(UART_TX, 0, 2)>;
|
||||
};
|
||||
group2 {
|
||||
psels = <NRF_PSEL(UART_RX, 0, 3)>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
uart0_sleep: uart0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(UART_TX, 0, 2)>,
|
||||
<NRF_PSEL(UART_RX, 0, 3)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
/* I2C0 for on-board sensors */
|
||||
i2c0_default: i2c0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(TWIM_SDA, 1, 9)>,
|
||||
<NRF_PSEL(TWIM_SCL, 0, 8)>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c0_sleep: i2c0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(TWIM_SDA, 1, 9)>,
|
||||
<NRF_PSEL(TWIM_SCL, 0, 8)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
/* SPI1 for SX1262 LoRa - CS controlled manually (P1.12) */
|
||||
spi1_default: spi1_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 1, 13)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 1, 14)>,
|
||||
<NRF_PSEL(SPIM_MISO, 1, 15)>;
|
||||
};
|
||||
};
|
||||
|
||||
spi1_sleep: spi1_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 1, 13)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 1, 14)>,
|
||||
<NRF_PSEL(SPIM_MISO, 1, 15)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
/* QSPI for MX25R1635F 2MB external flash */
|
||||
qspi_default: qspi_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(QSPI_SCK, 1, 3)>,
|
||||
<NRF_PSEL(QSPI_IO0, 1, 1)>,
|
||||
<NRF_PSEL(QSPI_IO1, 1, 2)>,
|
||||
<NRF_PSEL(QSPI_IO2, 1, 4)>,
|
||||
<NRF_PSEL(QSPI_IO3, 1, 5)>,
|
||||
<NRF_PSEL(QSPI_CSN, 0, 23)>;
|
||||
};
|
||||
};
|
||||
|
||||
qspi_sleep: qspi_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(QSPI_SCK, 1, 3)>,
|
||||
<NRF_PSEL(QSPI_IO0, 1, 1)>,
|
||||
<NRF_PSEL(QSPI_IO1, 1, 2)>,
|
||||
<NRF_PSEL(QSPI_IO2, 1, 4)>,
|
||||
<NRF_PSEL(QSPI_IO3, 1, 5)>;
|
||||
low-power-enable;
|
||||
};
|
||||
group2 {
|
||||
psels = <NRF_PSEL(QSPI_CSN, 0, 23)>;
|
||||
low-power-enable;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Elecrow ThinkNode M6 — nRF52840 + SX1262
|
||||
* Copyright (c) 2025 ZephCore
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Hardware (from Arduino variant.h / platformio.ini):
|
||||
* - nRF52840 SoC with BLE (DCDC regulator, NRF52BoardDCDC)
|
||||
* - SX1262 LoRa radio on SPI1 (DIO2 RF switch, DIO3 TCXO 3.3V, 22dBm)
|
||||
* NSS=P1.12, DIO1=P1.06, RESET=P1.10, BUSY=P1.11
|
||||
* - GPS L76K on UART0 (9600 baud, generic NMEA)
|
||||
* Control: GPS_EN=P0.06 (active-HIGH), GPS_RESET=P0.29 (active-LOW),
|
||||
* GPS_STANDBY=P0.30, GPS_PPS=P0.31
|
||||
* - Battery ADC on AIN4 (P0.28), 1.75:1 voltage divider
|
||||
* ADC_CTRL enable pin: P0.11 (gpio-hog, always HIGH)
|
||||
* - LEDs: RED=P0.12, BLUE=P0.07 (both active-HIGH, LED_STATE_ON=HIGH)
|
||||
* TX LED = BLUE (P_LORA_TX_LED = PIN_LED_BLUE)
|
||||
* - Button on P0.17 (active-low, pull-up)
|
||||
* - I2C on P1.09/P0.08 for on-board sensors
|
||||
* - QSPI Flash MX25R1635F (2MB): SCK=P1.03, CS=P0.23, IO0=P1.01,
|
||||
* IO1=P1.02, IO2=P1.04, IO3=P1.05, enable=P0.21
|
||||
* - Power enable: PIN_PWR_EN=P0.27 (regulator-boot-on)
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <nordic/nrf52840_qiaa.dtsi>
|
||||
#include <zephyr/dt-bindings/lora/sx126x.h>
|
||||
#include <zephyr/dt-bindings/adc/nrf-saadc.h>
|
||||
#include <zephyr/dt-bindings/input/input-event-codes.h>
|
||||
#include "thinknode_m6-pinctrl.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Elecrow ThinkNode M6";
|
||||
compatible = "elecrow,thinknode-m6";
|
||||
|
||||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,code-partition = &code_partition;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zephyr,shell-uart = &cdc_acm_uart;
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_red: led_0 {
|
||||
/* Active-high (LED_STATE_ON = HIGH in variant.h) */
|
||||
gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
|
||||
label = "Red LED";
|
||||
};
|
||||
|
||||
led_blue: led_1 {
|
||||
/* Active-high, also used as LoRa TX LED (P_LORA_TX_LED) */
|
||||
gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
|
||||
label = "Blue LED";
|
||||
};
|
||||
};
|
||||
|
||||
buttons: buttons {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
user_button: button_0 {
|
||||
/* Active-low, internal pull-up */
|
||||
gpios = <&gpio0 17 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||
zephyr,code = <INPUT_KEY_0>;
|
||||
label = "User Button";
|
||||
};
|
||||
};
|
||||
|
||||
/* Long-press detection (1000ms) */
|
||||
user_btn_longpress {
|
||||
compatible = "zephyr,input-longpress";
|
||||
input = <&buttons>;
|
||||
input-codes = <INPUT_KEY_0>;
|
||||
short-codes = <INPUT_KEY_A>;
|
||||
long-codes = <INPUT_KEY_F>;
|
||||
long-delay-ms = <1000>;
|
||||
};
|
||||
|
||||
/* Multi-tap detection
|
||||
* 1 tap → KEY_1 = page next
|
||||
* 2 taps → KEY_B = flood advert
|
||||
* 3 taps → KEY_D = buzzer mute toggle
|
||||
* 4 taps → KEY_C = GPS on/off */
|
||||
user_btn_multitap {
|
||||
compatible = "zephcore,input-multi-tap";
|
||||
input-codes = <INPUT_KEY_A>;
|
||||
tap-codes = <INPUT_KEY_1 INPUT_KEY_B INPUT_KEY_D INPUT_KEY_C>;
|
||||
tap-delay-ms = <400>;
|
||||
};
|
||||
|
||||
/* Battery ADC on AIN4 (P0.28), 1.75:1 voltage divider.
|
||||
* With GAIN_1_6 + internal ref (3600mV full scale) × 1.75 = 6300 multiplier. */
|
||||
zephyr,user {
|
||||
io-channels = <&adc 4>;
|
||||
vbat-mv-multiplier = <6300>;
|
||||
};
|
||||
|
||||
/* Board power enable (PIN_PWR_EN = P0.27) — must be HIGH for peripherals */
|
||||
pwr_enable: pwr-enable {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "pwr-enable";
|
||||
enable-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
/* QSPI flash enable (QSPI_FLASH_EN = P0.21) — must be HIGH before flash responds.
|
||||
* WARNING: Nordic QSPI NOR driver hangs forever if flash doesn't respond.
|
||||
* This regulator ensures flash is powered before driver init (priority 41). */
|
||||
qspi_flash_enable: qspi-flash-enable {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "qspi-flash-enable";
|
||||
enable-gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>;
|
||||
regulator-boot-on;
|
||||
startup-delay-us = <1000>;
|
||||
};
|
||||
|
||||
/* GPS enable (GPS_EN = P0.06, active-HIGH) — managed by ZephyrGPSManager */
|
||||
gps_en: gps-enable {
|
||||
compatible = "gpio-leds";
|
||||
gps_enable_pin: gps_enable {
|
||||
gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
|
||||
label = "GPS Enable";
|
||||
};
|
||||
};
|
||||
|
||||
/* GPS hardware reset (GPS_RESET = P0.29, active-LOW) */
|
||||
gps_rst: gps-reset {
|
||||
compatible = "gpio-leds";
|
||||
gps_reset_pin: gps_reset {
|
||||
gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
|
||||
label = "GPS Reset";
|
||||
};
|
||||
};
|
||||
|
||||
/* GPS standby (GPS_STANDBY = P0.30, active-HIGH = standby) */
|
||||
gps_stby: gps-standby {
|
||||
compatible = "gpio-leds";
|
||||
gps_standby_pin: gps_standby {
|
||||
gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
|
||||
label = "GPS Standby";
|
||||
};
|
||||
};
|
||||
|
||||
aliases {
|
||||
led0 = &led_red;
|
||||
led1 = &led_blue;
|
||||
lora-tx-led = &led_blue;
|
||||
sw0 = &user_button;
|
||||
watchdog0 = &wdt0;
|
||||
lora0 = &lora;
|
||||
gps-enable = &gps_enable_pin;
|
||||
gps-reset = &gps_reset_pin;
|
||||
gps-sleep-int = &gps_standby_pin;
|
||||
};
|
||||
};
|
||||
|
||||
®0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
®1 {
|
||||
regulator-initial-mode = <NRF5X_REG_MODE_DCDC>;
|
||||
};
|
||||
|
||||
&adc {
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/* Battery voltage on P0.28 (AIN4) — 1.75:1 voltage divider */
|
||||
channel@4 {
|
||||
reg = <4>;
|
||||
zephyr,gain = "ADC_GAIN_1_6";
|
||||
zephyr,reference = "ADC_REF_INTERNAL";
|
||||
zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10)>;
|
||||
zephyr,input-positive = <NRF_SAADC_AIN4>;
|
||||
zephyr,resolution = <12>;
|
||||
};
|
||||
};
|
||||
|
||||
&uicr {
|
||||
nfct-pins-as-gpios;
|
||||
};
|
||||
|
||||
&gpiote {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
status = "okay";
|
||||
|
||||
/* ADC control (PIN_ADC_CTRL = P0.11) — always HIGH to enable battery ADC.
|
||||
* Arduino code toggles this before/after ADC reads; keeping it permanently
|
||||
* HIGH is safe and avoids needing custom ADC ctrl support in ZephCore. */
|
||||
adc-ctrl-hog {
|
||||
gpio-hog;
|
||||
gpios = <11 GPIO_ACTIVE_HIGH>;
|
||||
output-high;
|
||||
line-name = "ADC Ctrl";
|
||||
};
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* GPS on UART0 (9600 baud)
|
||||
*
|
||||
* L76K GPS module (generic NMEA, multi-constellation).
|
||||
* Control pins managed by ZephyrGPSManager via aliases:
|
||||
* gps-enable (GPS_EN = P0.06): HIGH = GPS powered/active
|
||||
* gps-reset (GPS_RESET = P0.29): LOW = reset asserted
|
||||
* gps-sleep-int (GPS_STANDBY = P0.30): HIGH = standby
|
||||
*
|
||||
* zephyr,deferred-init: GPS must be powered (GPS_EN HIGH) before NMEA
|
||||
* output begins. ZephyrGPSManager asserts GPS_EN then calls device_init(). */
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
status = "okay";
|
||||
current-speed = <9600>;
|
||||
pinctrl-0 = <&uart0_default>;
|
||||
pinctrl-1 = <&uart0_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
|
||||
gnss: gnss {
|
||||
compatible = "gnss-nmea-generic";
|
||||
zephyr,deferred-init;
|
||||
};
|
||||
};
|
||||
|
||||
/* I2C0 for on-board sensors */
|
||||
&i2c0 {
|
||||
compatible = "nordic,nrf-twim";
|
||||
status = "okay";
|
||||
clock-frequency = <I2C_BITRATE_FAST>;
|
||||
pinctrl-0 = <&i2c0_default>;
|
||||
pinctrl-1 = <&i2c0_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
|
||||
/* All supported environment & power sensors — auto-detected at runtime */
|
||||
#include "../../common/sensors-i2c.dtsi"
|
||||
};
|
||||
|
||||
/* SPI1 for SX1262 LoRa */
|
||||
&spi1 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
status = "okay";
|
||||
cs-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
|
||||
pinctrl-0 = <&spi1_default>;
|
||||
pinctrl-1 = <&spi1_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
|
||||
lora: lora@0 {
|
||||
compatible = "semtech,sx1262";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <8000000>;
|
||||
|
||||
reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
|
||||
busy-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
|
||||
dio1-gpios = <&gpio1 6 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>;
|
||||
|
||||
/* DIO2 drives the RF switch for TX/RX selection */
|
||||
dio2-tx-enable;
|
||||
|
||||
/* DIO3 provides TCXO reference voltage at 3.3V */
|
||||
dio3-tcxo-voltage = <SX126X_DIO3_TCXO_3V3>;
|
||||
tcxo-power-startup-delay-ms = <10>;
|
||||
|
||||
/* RX boosted mode for better sensitivity (SX126X_RX_BOOSTED_GAIN=1) */
|
||||
rx-boosted;
|
||||
};
|
||||
};
|
||||
|
||||
/* QSPI Flash — MX25R1635F 2MB */
|
||||
&qspi {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&qspi_default>;
|
||||
pinctrl-1 = <&qspi_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
|
||||
qspi_flash: qspi_flash@0 {
|
||||
compatible = "nordic,qspi-nor";
|
||||
reg = <0>;
|
||||
writeoc = "pp";
|
||||
readoc = "fastread";
|
||||
sck-frequency = <16000000>;
|
||||
jedec-id = [c2 28 15]; /* MX25R1635F */
|
||||
size = <16777216>; /* 2MB = 16Mbit */
|
||||
has-dpd;
|
||||
t-enter-dpd = <10000>;
|
||||
t-exit-dpd = <35000>;
|
||||
};
|
||||
};
|
||||
|
||||
/* USB CDC for console/CLI */
|
||||
zephyr_udc0: &usbd {
|
||||
compatible = "nordic,nrf-usbd";
|
||||
status = "okay";
|
||||
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
/* SoftDevice v6 partition layout (S140 v6 — Adafruit nRF52 bootloader) */
|
||||
#include "../../common/nrf52_partitions_sdv6.dtsi"
|
||||
|
||||
/* External QSPI flash partitions */
|
||||
&qspi_flash {
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
/* Full 2MB for LittleFS storage */
|
||||
qspi_storage_partition: partition@0 {
|
||||
label = "qspi_storage";
|
||||
reg = <0x00000000 0x00200000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* External QSPI /ext automount */
|
||||
#include "../../common/qspi-ext.dtsi"
|
||||
@@ -0,0 +1,20 @@
|
||||
identifier: thinknode_m6
|
||||
name: Elecrow ThinkNode M6 (nRF52840 + SX1262)
|
||||
type: mcu
|
||||
arch: arm
|
||||
ram: 256
|
||||
flash: 1024
|
||||
toolchain:
|
||||
- zephyr
|
||||
- gnuarmemb
|
||||
- xtools
|
||||
supported:
|
||||
- adc
|
||||
- ble
|
||||
- gpio
|
||||
- i2c
|
||||
- nvs
|
||||
- spi
|
||||
- usb_device
|
||||
- watchdog
|
||||
vendor: elecrow
|
||||
@@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2025 ZephCore
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Enable MPU
|
||||
CONFIG_ARM_MPU=y
|
||||
|
||||
# Enable hardware stack protection
|
||||
CONFIG_HW_STACK_PROTECTION=y
|
||||
|
||||
# Enable GPIO
|
||||
CONFIG_GPIO=y
|
||||
|
||||
# Enable UART driver
|
||||
CONFIG_SERIAL=y
|
||||
|
||||
# Enable console
|
||||
CONFIG_CONSOLE=y
|
||||
|
||||
# Build UF2 by default
|
||||
CONFIG_BUILD_OUTPUT_UF2=y
|
||||
CONFIG_USE_DT_CODE_PARTITION=y
|
||||
@@ -0,0 +1,12 @@
|
||||
# ThinkNode M6 formatter config
|
||||
# Disable subsystems auto-enabled by M6 DTS nodes that bloat RAM:
|
||||
# CONFIG_INPUT — gpio-keys + input-longpress + zephcore,input-multi-tap nodes
|
||||
# CONFIG_ADC — battery ADC channel node
|
||||
# CONFIG_REGULATOR — regulator-fixed nodes (replaced by gpio-hogs in board.overlay)
|
||||
CONFIG_INPUT=n
|
||||
CONFIG_ADC=n
|
||||
CONFIG_REGULATOR=n
|
||||
|
||||
# QSPI flash present — enable driver to erase /ext partition
|
||||
CONFIG_NORDIC_QSPI_NOR=y
|
||||
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* ThinkNode M6 formatter overlay — minimal drivers, single LittleFS instance.
|
||||
*
|
||||
* The M6 main DTS includes both filesystem.dtsi (/lfs) and qspi-ext.dtsi
|
||||
* (/ext), giving two LittleFS instances. Each needs ~8-10KB RAM for block
|
||||
* caches; two instances overflow the formatter's RAM budget. Drop /ext here
|
||||
* — the QSPI storage partition node remains so main.c can still erase it via
|
||||
* FIXED_PARTITION_EXISTS(qspi_storage_partition).
|
||||
*
|
||||
* Also replace regulator-fixed power-enable nodes with gpio-hogs so
|
||||
* CONFIG_REGULATOR is not forced on by regulator-boot-on.
|
||||
*/
|
||||
|
||||
/* Remove /ext LittleFS fstab — formatter only needs one LittleFS instance */
|
||||
/delete-node/ &qspi_lfs;
|
||||
|
||||
/* Remove regulator-fixed nodes and replace with gpio-hogs */
|
||||
/delete-node/ &pwr_enable;
|
||||
/delete-node/ &qspi_flash_enable;
|
||||
|
||||
&gpio0 {
|
||||
/* Board power enable (PIN_PWR_EN = P0.27) */
|
||||
pwr-en-hog {
|
||||
gpio-hog;
|
||||
gpios = <27 GPIO_ACTIVE_HIGH>;
|
||||
output-high;
|
||||
line-name = "PWR Enable";
|
||||
};
|
||||
|
||||
/* QSPI flash enable (QSPI_FLASH_EN = P0.21) — must be HIGH before flash responds */
|
||||
qspi-flash-en-hog {
|
||||
gpio-hog;
|
||||
gpios = <21 GPIO_ACTIVE_HIGH>;
|
||||
output-high;
|
||||
line-name = "QSPI Flash Enable";
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user