From 61909c62de7f53d700f6fae9e5448bbb4b4f0fb6 Mon Sep 17 00:00:00 2001 From: liquidraver <504870+liquidraver@users.noreply.github.com> Date: Tue, 10 Mar 2026 16:09:10 +0100 Subject: [PATCH] update readme --- README.md | 17 +-- zephcore/boards/example_board/README.md | 171 +++++++++++++++++------- 2 files changed, 134 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 82809ea..9c5d611 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,8 @@ west build -b rak4631/nrf52840 zephcore --pristine -- -DCONFIG_ZEPHCORE_BLE_LOG_ Output binaries are in `build/zephyr/` -- `.hex`, `.uf2`, and DFU `.zip` as applicable. +For exact `west build -b` board strings, flash methods, and special setup (MG24 pyocd, nRF54L15 `--no-sysbuild`), see the [Board Porting Guide](zephcore/boards/example_board/README.md). + ## Architecture Overview ``` @@ -107,13 +109,12 @@ All code paths are event-driven. The CPU sleeps in WFI between events. | | Arduino | Zephyr | |---|---------|--------| -| Main loop | 50ms polling | `k_event_wait()` (blocks until event) | -| LoRa TX | Blocking `transmit()` | Async thread with `k_poll()` | -| BLE queues | Ring buffer + mutex | `k_msgq` (lock-free, ISR-safe) | -| Drivers | Arduino libraries | Zephyr subsystem drivers | -| Configuration | `#define` constants | Kconfig + devicetree | -| Threading | Single-threaded `loop()` | Multi-threaded with explicit sync | -| Power | Always-on loop | WFI sleep between events | +| Idle behavior | Cooperative loop; CPU busy-waits unless `board.sleep()` called explicitly | `k_event_wait(K_FOREVER)` yields to idle thread → WFI between events | +| LoRa TX completion | ISR sets flag, polled in `loop()` via `isSendComplete()` | ISR signals `k_poll_signal`, dedicated thread blocks on `k_poll()` | +| BLE transport | Platform-specific (ESP-IDF BLE, Adafruit nRF52 lib) | Unified `bt_gatt` API across all SoCs | +| LoRa driver | RadioLib (userspace SPI bit-bang) | Zephyr subsystem driver (DTS-configured, kernel-managed SPI) | +| Configuration | `platformio.ini` + `variant.h` per board | Kconfig + devicetree overlays, hierarchical config inheritance | +| Threading | Single `loop()` + ISRs | Explicit threads (main mesh, TX wait) + system work queue | ## Power Saving @@ -131,7 +132,7 @@ Key Kconfig options (set in board configs or via `-D` flags): | `CONFIG_ZEPHCORE_ROLE_REPEATER` | n | USB CLI repeater mode | | `CONFIG_ZEPHCORE_RADIO_NATIVE` | y | SX126x, SX127x, LLCC68, STM32WL | | `CONFIG_ZEPHCORE_RADIO_LR1110` | n | LR1110/LR1120/LR1121 (custom driver) | -| `CONFIG_ZEPHCORE_LORA_RX_DUTY_CYCLE` | n | CAD-based RX power saving (enabled on WisMesh Tag, ThinkNode M1) | +| `CONFIG_ZEPHCORE_LORA_RX_DUTY_CYCLE` | auto | CAD-based RX power saving (auto ON for companion+SX1262, OFF for LR1110/repeater) | | `CONFIG_ZEPHCORE_MAX_CONTACTS` | 350 | Contact storage slots (companion) | | `CONFIG_ZEPHCORE_MAX_CHANNELS` | 40 | Channel slots (companion) | | `CONFIG_ZEPHCORE_BLE_PASSKEY` | 123456 | BLE pairing PIN | diff --git a/zephcore/boards/example_board/README.md b/zephcore/boards/example_board/README.md index 14ddb18..f920f79 100644 --- a/zephcore/boards/example_board/README.md +++ b/zephcore/boards/example_board/README.md @@ -1,12 +1,95 @@ ZephCore — Adding a New Board ============================= + +Supported Boards +---------------- + +### nRF52840 + +| Board | Build string | Flash | +|----------------------|-------------------------------------------|-------------------------------| +| RAK4631 | `west build -b rak4631 zephcore` | UF2 drag-drop or `west flash` | +| Wio Tracker L1 | `west build -b wio_tracker_l1 zephcore` | UF2 drag-drop or `west flash` | +| 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` | +| 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 | + +UF2 flash: Double-tap reset button, drag `build/zephyr/zephyr.uf2` to the USB drive. +SWD flash: `west flash` (requires J-Link, pyocd, or nrfjprog connected). + +### ESP32 + +| Board | Build string | Flash | +|----------------------|---------------------------------------------|-----------------| +| XIAO ESP32-C3 | `west build -b xiao_esp32c3 zephcore` | `west flash` | +| XIAO ESP32-C6 | `west build -b xiao_esp32c6 zephcore` | `west flash` | +| LilyGo TLoRa C6 | `west build -b lilygo_tlora_c6 zephcore` | `west flash` | +| Station G2 | `west build -b station_g2 zephcore` | `west flash` | + +ESP32 flash uses esptool over USB. Hold BOOT button if device doesn't enter download mode. + +### nRF54L15 + +| Board | Build string | Flash | +|----------------------|------------------------------------------------------------------------|-----------------| +| XIAO nRF54L15 | `west build -b xiao_nrf54l15/nrf54l15/cpuapp zephcore --no-sysbuild` | `west flash` | + +Requires J-Link or CMSIS-DAP (built into XIAO board via SAMD11 bridge). +The `--no-sysbuild` flag is required (no MCUboot support yet). + +### MG24 (Silicon Labs) + +| Board | Build string | Flash | +|----------------------|-------------------------------------------|-----------------| +| XIAO MG24 | `west build -b xiao_mg24 zephcore` | `west flash` | + +**First-time setup required:** + +``` +# Download Silicon Labs BLE controller blob +west blobs fetch hal_silabs + +# Install pyocd + Silicon Labs device pack (if using pyocd) +pip install pyocd +pyocd pack install EFR32MG24B220F1536IM48 +``` + +Flash with: `west flash --runner pyocd` + +### Building for Repeater Role + +Append `-- -DEXTRA_CONF_FILE="boards/common/repeater.conf"` to any build command: + +``` +west build -b rak4631 zephcore -- -DEXTRA_CONF_FILE="boards/common/repeater.conf" +``` + +### Production Build (logging disabled) + +``` +west build -b rak4631 zephcore -- -DEXTRA_CONF_FILE="boards/common/prod.conf" +``` + +### Repeater + Production + +``` +west build -b rak4631 zephcore -- -DEXTRA_CONF_FILE="boards/common/repeater.conf;boards/common/prod.conf" +``` + +All build commands should include `--pristine` when switching between roles or boards. + + +Adding a New Board +------------------ + There are TWO ways to add a board, depending on whether Zephyr already has a board definition for your hardware. -PATTERN 1: Existing Zephyr Board (overlay only) ------------------------------------------------- +### PATTERN 1: Existing Zephyr Board (overlay only) Use this when your board already exists in Zephyr's tree. You only need TWO files: board.conf + board.overlay @@ -14,29 +97,23 @@ You only need TWO files: board.conf + board.overlay Examples: XIAO nRF54L15, XIAO MG24, XIAO ESP32-C3, RAK4631 Directory structure: - zephcore/boards/// - board.conf — Kconfig (name, radio type) - board.overlay — DT overlay (LoRa SPI, partitions, peripherals) + + zephcore/boards/// + board.conf — Kconfig (name, radio type) + board.overlay — DT overlay (LoRa SPI, partitions, peripherals) Steps: - 1. Create directory: boards/// + 1. Create directory: `boards///` Platform folders: nrf52840, nrf54l, mg24, esp32 2. Copy board.conf and board.overlay from THIS directory 3. Uncomment the sections matching your platform 4. Fill in YOUR pin numbers and partition layout 5. Add board detection to CMakeLists.txt (~line 60-75): - Add BOARD MATCHES "your_board" to the correct platform line + Add `BOARD MATCHES "your_board"` to the correct platform line 6. Build and iterate! -Build commands: - nRF52840: west build -b zephcore --pristine - nRF54L15: west build -b /nrf54l15/cpuapp zephcore --pristine --no-sysbuild - MG24: west blobs fetch hal_silabs && west build -b zephcore --pristine - ESP32-C3: west build -b zephcore --pristine - -PATTERN 2: Fully Custom Board (new DTS) ------------------------------------------ +### PATTERN 2: Fully Custom Board (new DTS) Use this when your board does NOT exist in Zephyr's tree. You need a full board definition: .dts, pinctrl, Kconfig, etc. @@ -44,18 +121,20 @@ You need a full board definition: .dts, pinctrl, Kconfig, etc. Examples: Ikoka Nano 30dBm, ThinkNode M1 (custom nRF52840 designs) Look at existing custom boards as templates: - zephcore/boards/nrf52840/ikoka_nano_30dbm/ — minimal (LoRa only) - zephcore/boards/nrf52840/thinknode_m1/ — full-featured (EPD, GPS, QSPI, buzzer) + + zephcore/boards/nrf52840/ikoka_nano_30dbm/ — minimal (LoRa only) + zephcore/boards/nrf52840/thinknode_m1/ — full-featured (EPD, GPS, QSPI, buzzer) A full custom board includes: - board.conf — Kconfig (name, radio, overrides) - board.overlay — DT overlay (usually empty if DTS is complete) - _.dts — Full device tree - _-pinctrl.dtsi — Pin control definitions - board.yml — Board metadata (name, arch, SoC) - Kconfig. — SoC selection - __defconfig — Minimal defconfig - board.cmake — Flash runner config + + board.conf — Kconfig (name, radio, overrides) + board.overlay — DT overlay (usually empty if DTS is complete) + _.dts — Full device tree + _-pinctrl.dtsi — Pin control definitions + board.yml — Board metadata (name, arch, SoC) + Kconfig. — SoC selection + __defconfig — Minimal defconfig + board.cmake — Flash runner config What Goes in board.conf @@ -92,17 +171,17 @@ should ONLY contain settings that can't be inferred from hardware: Config Inheritance ------------------ - prj.conf Always loaded first - | - zephcore_common.conf BLE, storage, input, LoRa, crypto, sensors - | - _common.conf Platform-specific overrides only - | nrf52_common.conf — UF2, USB CDC, DLE, GNSS, RTT - | nrf54l_common.conf — DLE, RTT - | mg24_common.conf — SiLabs blob stacks, heap - | esp32_common.conf — Espressif blob stacks, heap - | - board.conf Board name, radio type, board-specific + prj.conf Always loaded first + | + zephcore_common.conf BLE, storage, input, LoRa, crypto, sensors + | + _common.conf Platform-specific overrides only + | nrf52_common.conf — UF2, USB CDC, DLE, RTT + | nrf54l_common.conf — DLE, RTT + | mg24_common.conf — SiLabs blob stacks, heap + | esp32_common.conf — Espressif blob stacks, heap + | + board.conf Board name, radio type, board-specific DO NOT duplicate settings from parent configs in board.conf! @@ -112,16 +191,16 @@ Quick Reference: Wio-SX1262 XIAO Pin Mapping All XIAO boards use the same D-pin assignment for Wio-SX1262: - Signal | XIAO Pin | nRF52840 | nRF54L15 | MG24 | ESP32-C3 - -------|----------|-----------|-----------|-----------|-------- - DIO1 | D1 | P0.03 | P1.05 | PC01 | GPIO3 - RESET | D2 | P0.28 | P1.06 | PC02 | GPIO4 - BUSY | D3 | P0.05 | P1.07 | PC03 | GPIO5 - NSS | D4 | P0.04 | P1.10 | PC04 | GPIO6 - RXEN | D5 | P0.29 | P1.11 | PC05 | GPIO7 - SCK | D8 | P1.13 | P2.01 | PA03 | GPIO8 - MISO | D9 | P1.14 | P2.04 | PA04 | GPIO9 - MOSI | D10 | P1.15 | P2.02 | PA05 | GPIO10 + Signal | XIAO Pin | nRF52840 | nRF54L15 | MG24 | ESP32-C3 + -------|----------|-----------|-----------|-----------|-------- + DIO1 | D1 | P0.03 | P1.05 | PC01 | GPIO3 + RESET | D2 | P0.28 | P1.06 | PC02 | GPIO4 + BUSY | D3 | P0.05 | P1.07 | PC03 | GPIO5 + NSS | D4 | P0.04 | P1.10 | PC04 | GPIO6 + RXEN | D5 | P0.29 | P1.11 | PC05 | GPIO7 + SCK | D8 | P1.13 | P2.01 | PA03 | GPIO8 + MISO | D9 | P1.14 | P2.04 | PA04 | GPIO9 + MOSI | D10 | P1.15 | P2.02 | PA05 | GPIO10 Note: nRF52840 D-pin mapping varies by board (XIAO nRF52840 shown). RAK4631 has SX1262 integrated — different pinout entirely.