mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-01 20:09:17 +00:00
ditch arduino's hacky-hacky FS, back to zephyr native
mg24 fix dfu zip generation fix
This commit is contained in:
@@ -171,7 +171,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 "wio_tracker" OR BOARD MATCHES "ikoka_nano" OR BOARD MATCHES "t1000_e" OR BOARD MATCHES "thinknode_m1")
|
||||
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")
|
||||
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")
|
||||
@@ -396,7 +396,6 @@ else()
|
||||
src/main_companion.cpp
|
||||
adapters/ble/ZephyrBLE.cpp
|
||||
adapters/datastore/ZephyrDataStore.cpp
|
||||
adapters/datastore/lfs_128b_erase.c
|
||||
helpers/BaseChatMesh.cpp
|
||||
helpers/TransportKeyStore.cpp
|
||||
helpers/ui/ui_mesh_actions.cpp
|
||||
|
||||
+6
-6
@@ -443,14 +443,14 @@ config ZEPHCORE_UI_BUZZER
|
||||
|
||||
config ZEPHCORE_UI_DISPLAY
|
||||
bool "Enable display (OLED, LCD, e-ink)"
|
||||
default y
|
||||
depends on DISPLAY
|
||||
depends on CHARACTER_FRAMEBUFFER
|
||||
default y if $(dt_chosen_enabled,zephyr/display)
|
||||
select DISPLAY
|
||||
select CHARACTER_FRAMEBUFFER
|
||||
help
|
||||
Enable page-based UI on any Zephyr-supported display.
|
||||
Auto-detects display via "zephyr,display" chosen node or
|
||||
legacy nodelabels (sh1106, ssd1306). Resolution and font
|
||||
are queried at runtime — no hardcoded dimensions.
|
||||
Auto-enabled when "zephyr,display" chosen node exists in DT.
|
||||
Auto-detects display via chosen node or legacy nodelabels
|
||||
(sh1106, ssd1306). Resolution and font are queried at runtime.
|
||||
Supports OLED (SSD1306, SH1106), LCD, e-ink, etc.
|
||||
|
||||
config ZEPHCORE_UI_DISPLAY_AUTO_OFF_MS
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
*
|
||||
* Universal mount strategy:
|
||||
* nRF52: Manual mount /efs (ExtraFS, 100KB) + /ifs (InternalFS, 28KB)
|
||||
* with block_size=128 and custom erase for Arduino MeshCore compat.
|
||||
* using native Zephyr LittleFS (block_size=4096).
|
||||
* Others: DTS-automounted /lfs (single partition).
|
||||
* QSPI: /ext overrides contacts mount when available.
|
||||
*
|
||||
* Data format (all platforms):
|
||||
* contacts3 — 152-byte records (Arduino-compatible)
|
||||
* new_prefs — Arduino-compatible byte layout
|
||||
* channels2 — 68-byte records (identical to Arduino)
|
||||
* contacts3 — 152-byte records
|
||||
* new_prefs — byte layout
|
||||
* channels2 — 68-byte records
|
||||
* _main.id — identity blob
|
||||
* adv_blobs — fixed record array
|
||||
*/
|
||||
@@ -23,9 +23,6 @@
|
||||
#include <zephyr/device.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Custom 128B-block erase — defined in lfs_128b_erase.c */
|
||||
extern "C" int lfs_128b_erase(const struct lfs_config *c, lfs_block_t block);
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(zephcore_datastore, CONFIG_ZEPHCORE_DATASTORE_LOG_LEVEL);
|
||||
|
||||
@@ -56,27 +53,14 @@ static bool is_mounted(const char *mount_point)
|
||||
return fs_statvfs(mount_point, &stat) == 0;
|
||||
}
|
||||
|
||||
/* ── nRF52 dual-mount: ExtraFS + InternalFS (block_size=128) ───────── */
|
||||
/* ── nRF52 dual-mount: ExtraFS + InternalFS ────────────────────────── */
|
||||
|
||||
#if FIXED_PARTITION_EXISTS(extrafs_partition) && FIXED_PARTITION_EXISTS(internalfs_partition)
|
||||
#define HAS_NRF52_DUAL_MOUNT 1
|
||||
|
||||
/* Arduino-compatible LFS: block_size=128 */
|
||||
FS_LITTLEFS_DECLARE_CUSTOM_CONFIG(extrafs_data,
|
||||
4, /* alignment */
|
||||
16, /* read_size */
|
||||
16, /* prog_size */
|
||||
128, /* cache_size = block_size */
|
||||
128 /* lookahead_size */
|
||||
);
|
||||
|
||||
FS_LITTLEFS_DECLARE_CUSTOM_CONFIG(internalfs_data,
|
||||
4, /* alignment */
|
||||
16, /* read_size */
|
||||
16, /* prog_size */
|
||||
128, /* cache_size = block_size */
|
||||
128 /* lookahead_size */
|
||||
);
|
||||
/* Native Zephyr LFS — block_size derived from flash erase size (4096). */
|
||||
FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(extrafs_data);
|
||||
FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(internalfs_data);
|
||||
|
||||
static struct fs_mount_t extrafs_mnt = {
|
||||
.type = FS_LITTLEFS,
|
||||
@@ -94,53 +78,56 @@ static struct fs_mount_t internalfs_mnt = {
|
||||
.flags = 0,
|
||||
};
|
||||
|
||||
/* Mount a LittleFS partition, format if mount fails. Returns the mount rc. */
|
||||
static int mount_or_format(struct fs_mount_t *mnt, int partition_id)
|
||||
{
|
||||
int rc = fs_mount(mnt);
|
||||
|
||||
if (rc < 0) {
|
||||
LOG_WRN("%s: mount failed (%d) — formatting", mnt->mnt_point, rc);
|
||||
|
||||
/* A failed fs_mount may leave fs->backend set (flash_area
|
||||
* opened in littlefs_init_backend but lfs_mount failed).
|
||||
* Clear it so the retry doesn't hit -EBUSY. */
|
||||
struct fs_littlefs *fsd = (struct fs_littlefs *)mnt->fs_data;
|
||||
if (fsd->backend) {
|
||||
flash_area_close((const struct flash_area *)fsd->backend);
|
||||
fsd->backend = NULL;
|
||||
}
|
||||
|
||||
const struct flash_area *fap;
|
||||
if (flash_area_open(partition_id, &fap) == 0) {
|
||||
flash_area_flatten(fap, 0, fap->fa_size);
|
||||
flash_area_close(fap);
|
||||
}
|
||||
rc = fs_mount(mnt);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("%s: mount failed after format: %d",
|
||||
mnt->mnt_point, rc);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool try_mount_nrf52_dual()
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Set custom block_size and erase callback before mount.
|
||||
* The Zephyr LFS patch (0007) preserves pre-set erase callbacks. */
|
||||
extrafs_data.cfg.block_size = 128;
|
||||
extrafs_data.cfg.erase = lfs_128b_erase;
|
||||
|
||||
internalfs_data.cfg.block_size = 128;
|
||||
internalfs_data.cfg.erase = lfs_128b_erase;
|
||||
|
||||
/* Mount ExtraFS — contacts, channels, blobs */
|
||||
rc = fs_mount(&extrafs_mnt);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("ExtraFS mount failed: %d — formatting", rc);
|
||||
const struct flash_area *fap;
|
||||
if (flash_area_open(FIXED_PARTITION_ID(extrafs_partition), &fap) == 0) {
|
||||
flash_area_flatten(fap, 0, fap->fa_size);
|
||||
flash_area_close(fap);
|
||||
}
|
||||
rc = fs_mount(&extrafs_mnt);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("ExtraFS mount failed after format: %d", rc);
|
||||
return false;
|
||||
}
|
||||
if (mount_or_format(&extrafs_mnt,
|
||||
FIXED_PARTITION_ID(extrafs_partition)) < 0) {
|
||||
return false;
|
||||
}
|
||||
efs_mounted = true;
|
||||
LOG_INF("ExtraFS at /efs (100KB, 128B blocks)");
|
||||
LOG_INF("ExtraFS at /efs: blk_sz=%u blk_cnt=%u",
|
||||
extrafs_data.cfg.block_size, extrafs_data.cfg.block_count);
|
||||
|
||||
/* Mount InternalFS — prefs, identity, BLE settings */
|
||||
rc = fs_mount(&internalfs_mnt);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("InternalFS mount failed: %d — formatting", rc);
|
||||
const struct flash_area *fap;
|
||||
if (flash_area_open(FIXED_PARTITION_ID(internalfs_partition), &fap) == 0) {
|
||||
flash_area_flatten(fap, 0, fap->fa_size);
|
||||
flash_area_close(fap);
|
||||
}
|
||||
rc = fs_mount(&internalfs_mnt);
|
||||
if (rc < 0) {
|
||||
LOG_ERR("InternalFS mount failed after format: %d", rc);
|
||||
return false;
|
||||
}
|
||||
if (mount_or_format(&internalfs_mnt,
|
||||
FIXED_PARTITION_ID(internalfs_partition)) < 0) {
|
||||
return false;
|
||||
}
|
||||
ifs_mounted = true;
|
||||
LOG_INF("InternalFS at /ifs (28KB, 128B blocks)");
|
||||
LOG_INF("InternalFS at /ifs: blk_sz=%u blk_cnt=%u",
|
||||
internalfs_data.cfg.block_size, internalfs_data.cfg.block_count);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -158,7 +145,7 @@ bool ZephyrDataStore::mount()
|
||||
return true; /* already mounted */
|
||||
}
|
||||
|
||||
/* 1. Try nRF52 dual-mount (manual, block_size=128) */
|
||||
/* 1. Try nRF52 dual-mount (manual, native block_size) */
|
||||
if (try_mount_nrf52_dual()) {
|
||||
_contacts_mnt = "/efs";
|
||||
_prefs_mnt = "/ifs";
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* Zephyr DataStore - LittleFS-backed persistence with optional QSPI flash
|
||||
*
|
||||
* Universal across all platforms (nRF52, ESP32, MG24, nRF54L).
|
||||
* On nRF52, uses Arduino MeshCore-compatible dual-mount layout:
|
||||
* /efs (ExtraFS @ 0xD4000, 100KB, block_size=128) — contacts3, channels2, blobs
|
||||
* /ifs (InternalFS @ 0xED000, 28KB, block_size=128) — new_prefs, _main.id
|
||||
* On nRF52, uses dual-mount layout with native Zephyr LittleFS:
|
||||
* /efs (ExtraFS @ 0xD4000, 100KB) — contacts3, channels2, blobs
|
||||
* /ifs (InternalFS @ 0xED000, 28KB) — new_prefs, _main.id
|
||||
* On other platforms, uses DTS-automounted /lfs for everything.
|
||||
* QSPI /ext overrides contacts path when available (any platform).
|
||||
*/
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Custom LittleFS erase callback for 128-byte blocks on 4KB-erase flash.
|
||||
*
|
||||
* Arduino MeshCore uses LFS with block_size=128 on nRF52840 which has
|
||||
* 4096-byte erase granularity. The standard Zephyr erase callback calls
|
||||
* flash_area_flatten(fa, offset, 128) which fails because the flash driver
|
||||
* requires page-aligned (4096-byte) erases.
|
||||
*
|
||||
* This callback implements read-modify-erase-write:
|
||||
* 1. Read the entire 4KB page containing the 128B block
|
||||
* 2. Memset the 128B region to 0xFF (erased state)
|
||||
* 3. Hardware-erase the 4KB page
|
||||
* 4. Write back the modified page
|
||||
*/
|
||||
|
||||
#include <zephyr/storage/flash_map.h>
|
||||
#include <zephyr/drivers/flash.h>
|
||||
#include <lfs.h>
|
||||
#include <string.h>
|
||||
|
||||
#define HW_ERASE_SIZE 4096
|
||||
|
||||
/* Static 4KB buffer for read-modify-erase-write.
|
||||
* Both ExtraFS and InternalFS mounts are serialized by the Zephyr FS mutex,
|
||||
* so this is never accessed concurrently. */
|
||||
static uint8_t page_buf[HW_ERASE_SIZE];
|
||||
|
||||
int lfs_128b_erase(const struct lfs_config *c, lfs_block_t block)
|
||||
{
|
||||
const struct flash_area *fa = (const struct flash_area *)c->context;
|
||||
int rc;
|
||||
|
||||
/* Offset of this LFS block within the flash area */
|
||||
size_t block_offset = block * c->block_size;
|
||||
|
||||
/* Align down to the 4KB page boundary (within flash area) */
|
||||
size_t page_offset = block_offset & ~((size_t)HW_ERASE_SIZE - 1);
|
||||
size_t offset_in_page = block_offset - page_offset;
|
||||
|
||||
/* 1. Read entire 4KB page */
|
||||
rc = flash_area_read(fa, page_offset, page_buf, HW_ERASE_SIZE);
|
||||
if (rc < 0) {
|
||||
return LFS_ERR_IO;
|
||||
}
|
||||
|
||||
/* 2. Set the 128B block region to erased state (0xFF) */
|
||||
memset(&page_buf[offset_in_page], 0xFF, c->block_size);
|
||||
|
||||
/* 3. Hardware-erase the 4KB page */
|
||||
rc = flash_area_flatten(fa, page_offset, HW_ERASE_SIZE);
|
||||
if (rc < 0) {
|
||||
return LFS_ERR_IO;
|
||||
}
|
||||
|
||||
/* 4. Write back the modified page */
|
||||
rc = flash_area_write(fa, page_offset, page_buf, HW_ERASE_SIZE);
|
||||
if (rc < 0) {
|
||||
return LFS_ERR_IO;
|
||||
}
|
||||
|
||||
return LFS_ERR_OK;
|
||||
}
|
||||
@@ -267,12 +267,18 @@ void CompanionMesh::loop()
|
||||
|
||||
void CompanionMesh::markContactsDirty()
|
||||
{
|
||||
_dirty_contacts_expiry = _ms->getMillis() + LAZY_WRITE_DELAY_MS;
|
||||
/* Only set the timer on first dirty — don't keep pushing
|
||||
* the deadline forward or a busy mesh never flushes. */
|
||||
if (!_dirty_contacts_expiry) {
|
||||
_dirty_contacts_expiry = _ms->getMillis() + LAZY_WRITE_DELAY_MS;
|
||||
}
|
||||
}
|
||||
|
||||
void CompanionMesh::markChannelsDirty()
|
||||
{
|
||||
_dirty_channels_expiry = _ms->getMillis() + LAZY_WRITE_DELAY_MS;
|
||||
if (!_dirty_channels_expiry) {
|
||||
_dirty_channels_expiry = _ms->getMillis() + LAZY_WRITE_DELAY_MS;
|
||||
}
|
||||
}
|
||||
|
||||
void CompanionMesh::flushDirtyContacts()
|
||||
|
||||
@@ -137,7 +137,7 @@ uint8_t RepeaterMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t
|
||||
memcpy(client->shared_secret, secret, PUB_KEY_SIZE);
|
||||
|
||||
if (perms != PERM_ACL_GUEST) {
|
||||
dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
|
||||
if (!dirty_contacts_expiry) dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1018,7 +1018,7 @@ void RepeaterMesh::handleCommand(uint32_t sender_timestamp, char* command, char*
|
||||
if (hex_len > PUB_KEY_SIZE * 2) hex_len = PUB_KEY_SIZE * 2;
|
||||
if (mesh::Utils::fromHex(pubkey, hex_len / 2, hex)) {
|
||||
if (acl.applyPermissions(self_id, pubkey, hex_len / 2, perms)) {
|
||||
dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
|
||||
if (!dirty_contacts_expiry) dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Err - invalid params");
|
||||
|
||||
@@ -35,10 +35,9 @@ CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE=y
|
||||
# Boards with QSPI (Wio Tracker L1) override in board.conf.
|
||||
CONFIG_NORDIC_QSPI_NOR=n
|
||||
|
||||
# ========== Storage: Arduino MeshCore compatible layout ==========
|
||||
# ========== Storage ==========
|
||||
# BLE bonds via file-based settings on InternalFS (replaces NVS).
|
||||
# Required for Arduino MeshCore flash layout compatibility — the NVS region
|
||||
# (0xD4000-0xD6000) is now part of ExtraFS.
|
||||
# No NVS partition on nRF52 — ExtraFS occupies that region.
|
||||
CONFIG_NVS=n
|
||||
CONFIG_SETTINGS_NVS=n
|
||||
CONFIG_SETTINGS_FILE=y
|
||||
|
||||
@@ -39,12 +39,11 @@ CONFIG_LORA_MODULE_BACKEND_NATIVE=y
|
||||
CONFIG_REGULATOR=y
|
||||
|
||||
# ========== Display Subsystem ==========
|
||||
# When no display is in devicetree, no driver is instantiated — zero overhead.
|
||||
CONFIG_DISPLAY=y
|
||||
CONFIG_CHARACTER_FRAMEBUFFER=y
|
||||
# Display and CFB are auto-enabled by ZEPHCORE_UI_DISPLAY (Kconfig select)
|
||||
# when "zephyr,display" chosen node exists in the board's devicetree.
|
||||
# No need to set CONFIG_DISPLAY or CONFIG_CHARACTER_FRAMEBUFFER here.
|
||||
|
||||
# Heap for CFB framebuffer allocation (cfb_framebuffer_init uses k_malloc).
|
||||
# 2KB baseline — platforms with larger BLE stacks override this.
|
||||
# Heap baseline — display boards override for larger framebuffers.
|
||||
CONFIG_HEAP_MEM_POOL_SIZE=2048
|
||||
|
||||
# ========== Sensor Subsystem ==========
|
||||
@@ -156,7 +155,6 @@ CONFIG_FLASH_MAP=y
|
||||
CONFIG_NVS=y
|
||||
CONFIG_SETTINGS=y
|
||||
CONFIG_SETTINGS_NVS=y
|
||||
CONFIG_SETTINGS_NVS_SECTOR_COUNT=2
|
||||
CONFIG_FLASH_PAGE_LAYOUT=y
|
||||
|
||||
# LittleFS for DataStore
|
||||
|
||||
@@ -105,11 +105,11 @@ CONFIG_BT_DIS_MODEL_NUMBER_STR="My Board v1"
|
||||
# CRITICAL: SoftDevice version determines the app start address!
|
||||
# Check your board's Arduino platformio.ini for which linker script it uses:
|
||||
# nrf52840_s140_v6*.ld → s140 v6.1.1, app@0x26000, FWID=0x00B6
|
||||
# nrf52840_s140_v7*.ld → s140 v7.3.0, app@0x27000, FWID=0x0100
|
||||
# nrf52840_s140_v7*.ld → s140 v7.3.0, app@0x27000, FWID=0x0123
|
||||
# Your board.overlay partition table MUST match (see Section 4 in board.overlay).
|
||||
# Wrong address = bootloop / bricked device with no USB/BLE/logs.
|
||||
# CONFIG_ZEPHCORE_SD_FWID=0x00B6 # SoftDevice firmware ID (s140 v6.1.1)
|
||||
# CONFIG_ZEPHCORE_SD_FWID=0x0100 # SoftDevice firmware ID (s140 v7.3.0)
|
||||
# CONFIG_ZEPHCORE_SD_FWID=0x0123 # SoftDevice firmware ID (s140 v7.3.0)
|
||||
#
|
||||
# --- MG24 (Silicon Labs) ---
|
||||
# Requires: west blobs fetch hal_silabs (before first build)
|
||||
|
||||
@@ -82,6 +82,13 @@
|
||||
*/
|
||||
|
||||
/* --- Display (uncomment if board has OLED/LCD/e-paper) ---
|
||||
* Setting zephyr,display auto-enables CONFIG_DISPLAY,
|
||||
* CONFIG_CHARACTER_FRAMEBUFFER, and the UI page system.
|
||||
* No board.conf changes needed.
|
||||
* HEAP: 128x64 OLEDs fit in the default 2KB heap.
|
||||
* Larger displays need CONFIG_HEAP_MEM_POOL_SIZE
|
||||
* override in board.conf (e.g. 6144 for 200x200 EPD).
|
||||
*
|
||||
* zephyr,display = &oled; I2C OLED (SH1106, SSD1306)
|
||||
* zephyr,display = &epd; SPI e-paper (SSD1681, etc.)
|
||||
*/
|
||||
|
||||
@@ -8,5 +8,4 @@ CONFIG_ZEPHCORE_BOARD_NAME="XIAO MG24"
|
||||
# Device Information Service model name
|
||||
CONFIG_BT_DIS_MODEL_NUMBER_STR="XIAO MG24"
|
||||
|
||||
# RAM-limited: Silabs BLE blob needs 32KB heap, override prod.conf MAX_CONTACTS
|
||||
CONFIG_ZEPHCORE_MAX_CONTACTS=650
|
||||
# RAM-limited: Silabs BLE blob needs 32KB heap — use Kconfig default (350)
|
||||
|
||||
@@ -19,3 +19,6 @@ CONFIG_ZEPHCORE_BOARD_NAME="RAK 4631"
|
||||
# Device Information Service model name
|
||||
CONFIG_BT_DIS_MODEL_NUMBER_STR="RAK4631"
|
||||
|
||||
# SoftDevice firmware ID (s140 v6.1.1)
|
||||
CONFIG_ZEPHCORE_SD_FWID=0x00B6
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# RAK WisMesh Tag board configuration
|
||||
# Copyright (c) 2025 ZephCore
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config BOARD_RAK_WISMESH_TAG
|
||||
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,31 @@
|
||||
# RAK WisMesh Tag (nRF52840 + SX1262 GPS Tracker)
|
||||
# Board-specific configuration
|
||||
#
|
||||
# Hardware:
|
||||
# - nRF52840 SoC, SX1262 LoRa (22dBm, TCXO 1.8V)
|
||||
# - AT6558R GNSS on UART0 at 9600 baud
|
||||
# - LIS2DH accelerometer on I2C0
|
||||
# - 1000 mAh battery, ADC on AIN3 (P0.05)
|
||||
# - Buzzer on P0.21, user button on P0.09
|
||||
# - LEDs: GREEN=P1.03 (TX), BLUE=P1.04 (status)
|
||||
# - No display, no QSPI flash
|
||||
# - SoftDevice s140 v6.1.1, UF2 bootloader
|
||||
|
||||
# Board identification (matches Arduino MeshCore variant name)
|
||||
CONFIG_ZEPHCORE_BOARD_NAME="RAK WisMesh Tag"
|
||||
|
||||
# Device Information Service model name
|
||||
CONFIG_BT_DIS_MODEL_NUMBER_STR="RAK WisMesh Tag"
|
||||
|
||||
# SoftDevice firmware ID (s140 v6.1.1)
|
||||
CONFIG_ZEPHCORE_SD_FWID=0x00B6
|
||||
|
||||
# No display — enable LED heartbeat instead
|
||||
CONFIG_ZEPHCORE_UI_DISPLAY=n
|
||||
|
||||
# PWM for buzzer
|
||||
CONFIG_PWM=y
|
||||
|
||||
# RX duty cycle — safe on SX1262, extends battery life on this
|
||||
# card-sized tracker with 1000mAh battery
|
||||
CONFIG_ZEPHCORE_LORA_RX_DUTY_CYCLE=y
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2025 ZephCore
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
board:
|
||||
name: rak_wismesh_tag
|
||||
full_name: RAK WisMesh Tag (nRF52840 + SX1262 GPS Tracker)
|
||||
vendor: rak
|
||||
socs:
|
||||
- name: nrf52840
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* RAK WisMesh Tag pin control definitions
|
||||
* Copyright (c) 2025 ZephCore
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Pin mappings (from Arduino MeshCore variant.h):
|
||||
*
|
||||
* SPI2 (LoRa SX1262): SCK=P1.11, MOSI=P1.12, MISO=P1.13, CS=P1.10
|
||||
* I2C0 (sensors): SDA=P0.25, SCL=P0.24
|
||||
* UART0 (GPS 9600): TX=P0.16 (→GPS RX), RX=P0.15 (←GPS TX)
|
||||
* PWM0 (buzzer): P0.21
|
||||
*/
|
||||
|
||||
&pinctrl {
|
||||
/* UART0 for GPS module at 9600 baud */
|
||||
uart0_default: uart0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(UART_TX, 0, 16)>; /* P0.16 → GPS RX */
|
||||
};
|
||||
group2 {
|
||||
psels = <NRF_PSEL(UART_RX, 0, 15)>; /* P0.15 ← GPS TX */
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
|
||||
uart0_sleep: uart0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(UART_TX, 0, 16)>,
|
||||
<NRF_PSEL(UART_RX, 0, 15)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
/* I2C0 for sensors (LIS2DH, environment sensors) */
|
||||
i2c0_default: i2c0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(TWIM_SDA, 0, 25)>, /* P0.25 */
|
||||
<NRF_PSEL(TWIM_SCL, 0, 24)>; /* P0.24 */
|
||||
};
|
||||
};
|
||||
|
||||
i2c0_sleep: i2c0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(TWIM_SDA, 0, 25)>,
|
||||
<NRF_PSEL(TWIM_SCL, 0, 24)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
/* SPI2 for LoRa SX1262 */
|
||||
spi2_default: spi2_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 1, 11)>, /* P1.11 (Arduino 43) */
|
||||
<NRF_PSEL(SPIM_MOSI, 1, 12)>, /* P1.12 (Arduino 44) */
|
||||
<NRF_PSEL(SPIM_MISO, 1, 13)>; /* P1.13 (Arduino 45) */
|
||||
};
|
||||
};
|
||||
|
||||
spi2_sleep: spi2_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(SPIM_SCK, 1, 11)>,
|
||||
<NRF_PSEL(SPIM_MOSI, 1, 12)>,
|
||||
<NRF_PSEL(SPIM_MISO, 1, 13)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
|
||||
/* PWM0 for buzzer on P0.21 */
|
||||
pwm0_default: pwm0_default {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(PWM_OUT0, 0, 21)>;
|
||||
};
|
||||
};
|
||||
|
||||
pwm0_sleep: pwm0_sleep {
|
||||
group1 {
|
||||
psels = <NRF_PSEL(PWM_OUT0, 0, 21)>;
|
||||
low-power-enable;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* RAK WisMesh Tag — nRF52840 + SX1262 (card-sized GPS tracker)
|
||||
* Copyright (c) 2025 ZephCore
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Hardware:
|
||||
* - nRF52840 SoC with BLE 5
|
||||
* - SX1262 LoRa radio (DIO2 as RF switch, TCXO 1.8V via DIO3)
|
||||
* - AT6558R GNSS on UART0 at 9600 baud
|
||||
* - LIS2DH 3-axis accelerometer on I2C0
|
||||
* - 1000 mAh battery with ADC on AIN3 (P0.05)
|
||||
* - Buzzer on PWM0 (P0.21)
|
||||
* - LEDs: GREEN=P1.03 (TX, active HIGH), BLUE=P1.04 (status, active HIGH)
|
||||
* - User button on P0.09 (NFC1, active LOW)
|
||||
* - Board power enable on P0.12
|
||||
* - No display, no QSPI flash
|
||||
* - IP66 sealed, pogo-pin USB interface
|
||||
*
|
||||
* Pin mappings (from Arduino MeshCore variant.h):
|
||||
* - LoRa SPI: SCK=P1.11, MOSI=P1.12, MISO=P1.13, CS=P1.10
|
||||
* - LoRa ctl: DIO1=P1.15, BUSY=P1.14, RESET=P1.06, PWR_EN=P1.05
|
||||
* - I2C: SDA=P0.25, SCL=P0.24
|
||||
* - GPS: TX=P0.16, RX=P0.15, EN=P1.02, PPS=P0.17
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <nordic/nrf52840_qiaa.dtsi>
|
||||
#include "rak_wismesh_tag-pinctrl.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 <zephyr/dt-bindings/pwm/pwm.h>
|
||||
|
||||
/ {
|
||||
model = "RAK WisMesh Tag";
|
||||
compatible = "rak,wismesh-tag";
|
||||
|
||||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,code-partition = &code_partition;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zephyr,shell-uart = &cdc_acm_uart;
|
||||
};
|
||||
|
||||
aliases {
|
||||
lora0 = &lora;
|
||||
led0 = &led_green;
|
||||
led1 = &led_blue;
|
||||
lora-tx-led = &led_green;
|
||||
sw0 = &user_button;
|
||||
watchdog0 = &wdt0;
|
||||
buzzer = &buzzer;
|
||||
gps-enable = &gps_enable_pin;
|
||||
};
|
||||
|
||||
/* ---- LEDs (active HIGH per Arduino LED_STATE_ON=HIGH) ---- */
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_green: led_0 {
|
||||
gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
|
||||
label = "Green LED";
|
||||
};
|
||||
|
||||
led_blue: led_1 {
|
||||
gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
|
||||
label = "Blue LED";
|
||||
};
|
||||
};
|
||||
|
||||
/* ---- Button (P0.09/NFC1, active LOW with pull-up) ---- */
|
||||
buttons: buttons {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
user_button: button_0 {
|
||||
gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
|
||||
zephyr,code = <INPUT_KEY_0>;
|
||||
label = "User Button";
|
||||
};
|
||||
};
|
||||
|
||||
/* Input filter: long-press (1000ms) */
|
||||
user_btn_longpress {
|
||||
compatible = "zephyr,input-longpress";
|
||||
input = <&buttons>;
|
||||
input-codes = <INPUT_KEY_0>;
|
||||
short-codes = <INPUT_KEY_A>;
|
||||
long-codes = <INPUT_KEY_POWER>;
|
||||
long-delay-ms = <1000>;
|
||||
};
|
||||
|
||||
/* Input filter: multi-tap
|
||||
* 1 tap → KEY_1 = (reserved / next page if display added)
|
||||
* 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>;
|
||||
};
|
||||
|
||||
/* ---- Power control ---- */
|
||||
|
||||
/* Board power enable — must be HIGH for peripherals */
|
||||
pwr_enable: pwr-enable {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "pwr-enable";
|
||||
enable-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
/* LoRa radio power enable — must be HIGH before SX1262 can communicate */
|
||||
lora_pwr_enable: lora-pwr-enable {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "lora-pwr-enable";
|
||||
enable-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
|
||||
regulator-boot-on;
|
||||
startup-delay-us = <10000>;
|
||||
};
|
||||
|
||||
/* GPS power control */
|
||||
gps_en: gps-enable {
|
||||
compatible = "gpio-leds";
|
||||
gps_enable_pin: gps_enable {
|
||||
gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
|
||||
label = "GPS Enable";
|
||||
};
|
||||
};
|
||||
|
||||
/* ---- Battery ADC ---- */
|
||||
/* P0.05 (AIN3), same divider circuit as RAK4631 */
|
||||
zephyr,user {
|
||||
io-channels = <&adc 3>;
|
||||
vbat-mv-multiplier = <4216>;
|
||||
};
|
||||
|
||||
/* ---- Buzzer on PWM0 ---- */
|
||||
pwmbuzzer {
|
||||
compatible = "pwm-leds";
|
||||
buzzer: buzzer {
|
||||
pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* ---- SoC configuration ---- */
|
||||
|
||||
®0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
®1 {
|
||||
regulator-initial-mode = <NRF5X_REG_MODE_DCDC>;
|
||||
};
|
||||
|
||||
&adc {
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/* Battery voltage on P0.05 (AIN3) */
|
||||
channel@3 {
|
||||
reg = <3>;
|
||||
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_AIN3>;
|
||||
zephyr,resolution = <12>;
|
||||
};
|
||||
};
|
||||
|
||||
&uicr {
|
||||
nfct-pins-as-gpios;
|
||||
};
|
||||
|
||||
&gpiote {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* ---- PWM0 for buzzer ---- */
|
||||
&pwm0 {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&pwm0_default>;
|
||||
pinctrl-1 = <&pwm0_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
/* ---- GPS on UART0 (AT6558R, 9600 baud) ----
|
||||
* Uses luatos,air530z driver for NMEA with power control.
|
||||
* GPS power controlled via on-off-gpios (P1.02 = GPS_EN). */
|
||||
&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 = "luatos,air530z";
|
||||
on-off-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
/* ---- I2C0 for 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"
|
||||
};
|
||||
|
||||
/* ---- SPI2 for LoRa SX1262 ---- */
|
||||
&spi2 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
status = "okay";
|
||||
pinctrl-0 = <&spi2_default>;
|
||||
pinctrl-1 = <&spi2_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; /* P1.10 (Arduino 42) LORA_CS */
|
||||
|
||||
lora: lora@0 {
|
||||
compatible = "semtech,sx1262";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <8000000>;
|
||||
|
||||
/* LoRa control pins */
|
||||
reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; /* P1.06 (Arduino 38) */
|
||||
busy-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; /* P1.14 (Arduino 46) */
|
||||
dio1-gpios = <&gpio1 15 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; /* P1.15 (Arduino 47) */
|
||||
|
||||
/* DIO2 drives RF switch for TX */
|
||||
dio2-tx-enable;
|
||||
|
||||
/* TCXO voltage 1.8V via DIO3 */
|
||||
dio3-tcxo-voltage = <SX126X_DIO3_TCXO_1V8>;
|
||||
tcxo-power-startup-delay-ms = <5>;
|
||||
|
||||
/* RX boosted mode for better sensitivity */
|
||||
rx-boosted;
|
||||
};
|
||||
};
|
||||
|
||||
/* ---- QSPI Flash — not present on WisMesh Tag ---- */
|
||||
&qspi {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
/* ---- 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";
|
||||
};
|
||||
};
|
||||
|
||||
/* ---- Flash partitions (SoftDevice v6, app@0x26000) ---- */
|
||||
#include "../../common/nrf52_partitions_sdv6.dtsi"
|
||||
@@ -0,0 +1,29 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# RAK WisMesh Tag default configuration
|
||||
|
||||
# Enable MPU
|
||||
CONFIG_ARM_MPU=y
|
||||
CONFIG_HW_STACK_PROTECTION=y
|
||||
|
||||
# Enable GPIO
|
||||
CONFIG_GPIO=y
|
||||
|
||||
# Enable console on USB CDC
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_UART_CONSOLE=y
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_UART_LINE_CTRL=y
|
||||
|
||||
# Enable flash/NVS storage
|
||||
CONFIG_FLASH=y
|
||||
CONFIG_FLASH_MAP=y
|
||||
CONFIG_NVS=y
|
||||
|
||||
# Pinctrl
|
||||
CONFIG_PINCTRL=y
|
||||
|
||||
# SPI for LoRa
|
||||
CONFIG_SPI=y
|
||||
|
||||
# ADC for battery
|
||||
CONFIG_ADC=y
|
||||
@@ -13,6 +13,9 @@ CONFIG_ZEPHCORE_BOARD_NAME="T1000-E"
|
||||
# Device Information Service model name
|
||||
CONFIG_BT_DIS_MODEL_NUMBER_STR="Seeed T1000-E"
|
||||
|
||||
# SoftDevice firmware ID (s140 v7.3.0 — Seeed bootloader)
|
||||
CONFIG_ZEPHCORE_SD_FWID=0x0123
|
||||
|
||||
# Radio type (TCXO, RF switch, PA config in DTS)
|
||||
CONFIG_ZEPHCORE_RADIO_LR1110=y
|
||||
|
||||
|
||||
@@ -209,7 +209,8 @@
|
||||
reg = <0>;
|
||||
width = <200>;
|
||||
height = <200>;
|
||||
rotation = <270>;
|
||||
rotation = <0>;
|
||||
gate-inverted;
|
||||
busy-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
CONFIG_ZEPHCORE_BOARD_NAME="Wio Tracker L1"
|
||||
|
||||
# Device Information Service model name
|
||||
CONFIG_BT_DIS_MODEL_NUMBER_STR="Wio Tracker 1110"
|
||||
CONFIG_BT_DIS_MODEL_NUMBER_STR="Wio Tracker L1"
|
||||
|
||||
# SoftDevice firmware ID (s140 v7.3.0 — Seeed bootloader)
|
||||
CONFIG_ZEPHCORE_SD_FWID=0x0123
|
||||
|
||||
# QSPI flash present (overrides nrf52_common.conf default of =n)
|
||||
CONFIG_NORDIC_QSPI_NOR=y
|
||||
|
||||
@@ -73,9 +73,12 @@ static void auto_off_handler(struct k_work *work)
|
||||
return;
|
||||
}
|
||||
/* E-paper content persists without power — blanking wastes a full
|
||||
* refresh cycle (~2s) for no benefit. Just turn off the backlight. */
|
||||
* refresh cycle (~2s) for no benefit. Just turn off the backlight
|
||||
* and mark display "off" so the next button press triggers
|
||||
* mc_display_on() → backlight restore. */
|
||||
if (is_epd) {
|
||||
backlight_set(false);
|
||||
disp_on = false;
|
||||
return;
|
||||
}
|
||||
if (disp_on) {
|
||||
@@ -232,7 +235,11 @@ void mc_display_on(void)
|
||||
}
|
||||
|
||||
if (!disp_on) {
|
||||
display_blanking_off(disp_dev);
|
||||
/* EPD: content persists (bistable) — no need to unblank,
|
||||
* just restore backlight. OLED: actually unblank. */
|
||||
if (!is_epd) {
|
||||
display_blanking_off(disp_dev);
|
||||
}
|
||||
disp_on = true;
|
||||
}
|
||||
backlight_set(true);
|
||||
|
||||
@@ -114,7 +114,7 @@ static struct ui_state local_ui_state;
|
||||
/* ========== Constants ========== */
|
||||
#define SPLASH_DURATION_MS 3000
|
||||
#define RENDER_DEBOUNCE_MS 50
|
||||
#define RENDER_DEBOUNCE_EPD_MS 2500 /* e-paper: coalesce updates across full refresh (~2s) */
|
||||
#define RENDER_DEBOUNCE_EPD_MS 200 /* e-paper: coalesce rapid state updates, then refresh */
|
||||
|
||||
/* ========== State ========== */
|
||||
static bool ui_initialized;
|
||||
@@ -1038,6 +1038,7 @@ void ui_refresh_display(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ZEPHCORE_UI_DISPLAY
|
||||
/* EPD displays: skip periodic housekeeping renders.
|
||||
* Each full e-paper refresh takes ~2s and causes visible flashing.
|
||||
* All meaningful events (messages, BLE, GPS fix, button presses)
|
||||
@@ -1049,4 +1050,5 @@ void ui_refresh_display(void)
|
||||
}
|
||||
|
||||
schedule_render();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
diff --git a/subsys/fs/littlefs_fs.c b/subsys/fs/littlefs_fs.c
|
||||
index 6176d533e32..1ea405a3d1f 100644
|
||||
--- a/subsys/fs/littlefs_fs.c
|
||||
+++ b/subsys/fs/littlefs_fs.c
|
||||
@@ -901,7 +901,9 @@ static int littlefs_init_cfg(struct fs_littlefs *fs, int flags)
|
||||
#ifdef CONFIG_FS_LITTLEFS_FMP_DEV
|
||||
lcp->read = lfs_api_read;
|
||||
lcp->prog = lfs_api_prog;
|
||||
- lcp->erase = lfs_api_erase;
|
||||
+ if (!lcp->erase) {
|
||||
+ lcp->erase = lfs_api_erase;
|
||||
+ }
|
||||
#endif
|
||||
|
||||
lcp->read_size = read_size;
|
||||
@@ -485,6 +485,21 @@ int main(void)
|
||||
k_sleep(K_MSEC(100));
|
||||
LOG_INF("=== ZephCore starting ===");
|
||||
|
||||
/* Log reset reason so we can diagnose random reboots */
|
||||
{
|
||||
uint32_t cause;
|
||||
if (hwinfo_get_reset_cause(&cause) == 0) {
|
||||
LOG_INF("Reset cause: 0x%08x%s%s%s%s%s%s", cause,
|
||||
(cause & RESET_PIN) ? " PIN" : "",
|
||||
(cause & RESET_SOFTWARE) ? " SOFTWARE" : "",
|
||||
(cause & RESET_BROWNOUT) ? " BROWNOUT" : "",
|
||||
(cause & RESET_POR) ? " POR" : "",
|
||||
(cause & RESET_WATCHDOG) ? " WATCHDOG" : "",
|
||||
(cause & RESET_CPU_LOCKUP)? " LOCKUP" : "");
|
||||
hwinfo_clear_reset_cause();
|
||||
}
|
||||
}
|
||||
|
||||
if (!ZephyrDataStore::mount()) {
|
||||
LOG_ERR("LittleFS mount failed");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user