mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-02 03:38:18 +00:00
Make production the default build; decouple USB companion from CONFIG_LOG
Production (LOG=n, ASSERT=n, RTT=n, reboot-on-fatal) is now the prj.conf default; debug.conf is the opt-in bundle. Removed prod.conf and the logging.conf auto-include; relocated RTT/ASSERT out of the always-on platform confs so they no longer override the prod defaults. Add CONFIG_ZEPHCORE_COMPANION_USB so the USB CDC companion transport compiles independently of logging (default-y on USB-capable companions, opt-in on ESP32-S3 via esp32s3_usb.conf). Gate all USB sites behind one ZEPHCORE_USB_STACK macro. Rework BLE/USB interface arbitration to first-come-first-served: neither transport evicts a live session. Make active_iface mutation thread-safe (mutex + atomic claim) across the BLE callback thread and USB workqueue. Share the ESP32-S3 USB OTG / console DTS via common dtsi includes; enable uart0 (GPIO43/44) on station_g2 and xiao so the console reroute works.
This commit is contained in:
@@ -73,20 +73,20 @@ cd <cloned folder>
|
||||
west init -l zephcore
|
||||
west update
|
||||
|
||||
# Companion (with logging)
|
||||
# Companion (production — default, no extra conf needed)
|
||||
west build -b wio_tracker_l1 zephcore --pristine
|
||||
|
||||
# Companion (production, no logging, no USB)
|
||||
# Companion (debug logging)
|
||||
west build -b wio_tracker_l1 zephcore --pristine -- \
|
||||
-DEXTRA_CONF_FILE="boards/common/prod.conf"
|
||||
-DEXTRA_CONF_FILE="boards/common/debug.conf"
|
||||
|
||||
# Repeater (with logging)
|
||||
# Repeater
|
||||
west build -b rak4631 zephcore --pristine -- \
|
||||
-DEXTRA_CONF_FILE="boards/common/repeater.conf"
|
||||
|
||||
# Repeater (production)
|
||||
# Repeater (debug logging)
|
||||
west build -b rak4631 zephcore --pristine -- \
|
||||
-DEXTRA_CONF_FILE="boards/common/repeater.conf;boards/common/prod.conf"
|
||||
-DEXTRA_CONF_FILE="boards/common/repeater.conf;boards/common/debug.conf"
|
||||
|
||||
# Repeater with packet logging (clean RAW/RX/TX lines only, no debug spam)
|
||||
west build -b rak4631 zephcore --pristine -- \
|
||||
@@ -175,7 +175,7 @@ The old `txdelay`, `rxdelay`, and `direct.txdelay` commands are still accepted f
|
||||
|
||||
- **LoRa RX duty cycle**: CAD-based receive windowing reduces LoRa RX current from ~10-15mA to ~3-5mA. Auto-enabled for SX1262 companion and repeater builds (toggleable at runtime via `set rxduty on/off`). Disabled for LR1110 (mid-preamble lock issue) and SX127x.
|
||||
- **Adaptive Power Control (APC)**: compiled in by default but disabled at runtime. Enable per-node with `set tx apc` -- automatically reduces TX power when echo SNR shows excess margin, ramping back up if echoes drop. See [apc.md](zephcore/apc.md).
|
||||
- **USB disabled in production**: Saves ~2-5mA and 62KB flash when logging is off
|
||||
- **Production by default**: No logging, no asserts, reboot-on-fatal. Add `debug.conf` to enable logging.
|
||||
- **GPIO-gated GPS**: Powered on only during fix acquisition
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -37,19 +37,19 @@ if [[ $1 == "nrf" ]]; then
|
||||
for board in "${nRF_boards[@]}"; do
|
||||
board_clean_for_path=$(echo "$board" | sed -e 's/\//-/g')
|
||||
|
||||
# build nRF companions
|
||||
# build nRF companions (production is the default — no extra conf needed)
|
||||
echo "Now building $board companion"
|
||||
if [[ $board == "wio_tracker_l1" ]]; then
|
||||
west build -b "$board" zephcore --pristine -- -DEXTRA_CONF_FILE="boards/common/prod.conf" -DCONFIG_ZEPHCORE_EASTER_EGG_DOOM=y
|
||||
west build -b "$board" zephcore --pristine -- -DCONFIG_ZEPHCORE_EASTER_EGG_DOOM=y
|
||||
else
|
||||
west build -b "$board" zephcore --pristine -- -DEXTRA_CONF_FILE="boards/common/prod.conf"
|
||||
west build -b "$board" zephcore --pristine
|
||||
fi
|
||||
mv build/zephyr/zephyr.uf2 firmware/"$board"-companion-"$COMMIT_HASH".uf2
|
||||
mv build/zephyr/zephyr.zip firmware/"$board"-companion-"$COMMIT_HASH".zip
|
||||
|
||||
|
||||
# build nRF repeaters
|
||||
echo "Now building $board repeater"
|
||||
west build -b "$board" zephcore --pristine -- -DEXTRA_CONF_FILE="boards/common/repeater.conf;boards/common/prod.conf"
|
||||
west build -b "$board" zephcore --pristine -- -DEXTRA_CONF_FILE="boards/common/repeater.conf"
|
||||
mv build/zephyr/zephyr.uf2 firmware/"$board"-repeater-"$COMMIT_HASH".uf2
|
||||
mv build/zephyr/zephyr.zip firmware/"$board"-repeater-"$COMMIT_HASH".zip
|
||||
|
||||
@@ -58,12 +58,12 @@ if [[ $1 == "nrf" ]]; then
|
||||
# Heltec_t114_without_display_* PIO envs.
|
||||
if [[ $board == "heltec_t114" ]]; then
|
||||
echo "Now building $board companion (noscreen)"
|
||||
west build -b "$board" zephcore --pristine -- -DEXTRA_CONF_FILE="boards/common/prod.conf;boards/nrf52840/heltec_t114/no_display.conf"
|
||||
west build -b "$board" zephcore --pristine -- -DEXTRA_CONF_FILE="boards/nrf52840/heltec_t114/no_display.conf"
|
||||
mv build/zephyr/zephyr.uf2 firmware/"$board"-companion-noscreen-"$COMMIT_HASH".uf2
|
||||
mv build/zephyr/zephyr.zip firmware/"$board"-companion-noscreen-"$COMMIT_HASH".zip
|
||||
|
||||
echo "Now building $board repeater (noscreen)"
|
||||
west build -b "$board" zephcore --pristine -- -DEXTRA_CONF_FILE="boards/common/repeater.conf;boards/common/prod.conf;boards/nrf52840/heltec_t114/no_display.conf"
|
||||
west build -b "$board" zephcore --pristine -- -DEXTRA_CONF_FILE="boards/common/repeater.conf;boards/nrf52840/heltec_t114/no_display.conf"
|
||||
mv build/zephyr/zephyr.uf2 firmware/"$board"-repeater-noscreen-"$COMMIT_HASH".uf2
|
||||
mv build/zephyr/zephyr.zip firmware/"$board"-repeater-noscreen-"$COMMIT_HASH".zip
|
||||
fi
|
||||
@@ -82,9 +82,9 @@ if [[ $1 == "esp32" ]]; then
|
||||
fi
|
||||
|
||||
if [[ $2 == "companions" ]]; then
|
||||
# build ESP32 companions
|
||||
# build ESP32 companions (production is the default)
|
||||
echo "Now building $board companion"
|
||||
west build -b "$board" zephcore --pristine --sysbuild -- -DEXTRA_CONF_FILE="boards/common/prod.conf"
|
||||
west build -b "$board" zephcore --pristine --sysbuild
|
||||
FLASH_SIZE=$(
|
||||
python3 -c '
|
||||
import re
|
||||
@@ -127,7 +127,7 @@ print(str(size // 1048576) + "MB")
|
||||
if [[ $2 == "repeaters" ]]; then
|
||||
# build ESP32 repeaters
|
||||
echo "Now building $board repeater"
|
||||
west build -b "$board" zephcore --pristine --sysbuild -- -DEXTRA_CONF_FILE="boards/common/repeater.conf;boards/common/prod.conf"
|
||||
west build -b "$board" zephcore --pristine --sysbuild -- -DEXTRA_CONF_FILE="boards/common/repeater.conf"
|
||||
FLASH_SIZE=$(
|
||||
python3 -c '
|
||||
import re
|
||||
|
||||
@@ -511,11 +511,11 @@ Wolf3D-style raycaster on OLED: textured walls, 2 enemy types, shooting, HUD. By
|
||||
### 9.1 Config Layering
|
||||
|
||||
```
|
||||
prj.conf (base: console, logging)
|
||||
prj.conf (base: console; production defaults — LOG=n, ASSERT=n)
|
||||
→ boards/common/zephcore_common.conf (ALL boards: BLE, crypto, FS, LoRa, sensors)
|
||||
→ boards/common/<platform>_common.conf (nrf52/esp32/nrf54l/mg24 specifics)
|
||||
→ boards/<mcu>/<board>/board.conf (board-specific pins, features)
|
||||
→ [optional] repeater.conf, prod.conf (user extras, LAST = highest priority)
|
||||
→ [optional] repeater.conf, debug.conf (user extras, LAST = highest priority)
|
||||
```
|
||||
|
||||
### 9.2 Key Kconfig Choices
|
||||
|
||||
+1
-11
@@ -306,17 +306,7 @@ if(ZEPHCORE_BOARD_CONF AND EXISTS ${ZEPHCORE_BOARD_CONF})
|
||||
zephcore_auto_pair_overlay("${ZEPHCORE_BOARD_CONF}")
|
||||
endif()
|
||||
|
||||
# Include logging tuning only for debug builds (when prod.conf is NOT active).
|
||||
# This avoids Kconfig warnings from log settings that depend on CONFIG_LOG.
|
||||
set(ZEPHCORE_LOGGING_CONF "${CMAKE_CURRENT_SOURCE_DIR}/boards/common/logging.conf")
|
||||
if(EXTRA_CONF_FILE MATCHES "prod\\.conf")
|
||||
message(STATUS " Production build — skipping logging.conf")
|
||||
else()
|
||||
if(EXISTS ${ZEPHCORE_LOGGING_CONF})
|
||||
list(APPEND ZEPHCORE_CONF_FILES ${ZEPHCORE_LOGGING_CONF})
|
||||
zephcore_auto_pair_overlay("${ZEPHCORE_LOGGING_CONF}")
|
||||
endif()
|
||||
endif()
|
||||
# Production is the default. Debug logging is opt-in via debug.conf.
|
||||
|
||||
# Auto-include WiFi OTA for ESP32 repeater builds.
|
||||
# Enables WiFi AP + HTTP server + MCUboot image management.
|
||||
|
||||
@@ -66,6 +66,27 @@ config ZEPHCORE_ROLE_COMPANION
|
||||
BLE companion device that connects to ZephCore mobile app.
|
||||
Includes BLE stack, contact management, offline queue, channels.
|
||||
|
||||
config ZEPHCORE_COMPANION_USB
|
||||
bool "Enable USB CDC companion transport"
|
||||
depends on USB_DEVICE_STACK_NEXT
|
||||
default y if ZEPHCORE_ROLE_COMPANION
|
||||
help
|
||||
Compile and init the USB CDC-ACM companion protocol stack
|
||||
(ZephyrCompanionUSB / ZephyrUSBCDC) independently of CONFIG_LOG.
|
||||
The full ~60-opcode binary protocol is available over USB even in
|
||||
production builds (CONFIG_LOG=n). USB and BLE arbitrate the active
|
||||
interface first-come-first-served: CMD_APP_START claims it for USB only
|
||||
if no BLE session is already active (and is ignored while BLE is live);
|
||||
on USB unplug the interface is handed back to BLE or released to idle.
|
||||
|
||||
Enabled by default for all companion builds on platforms that already
|
||||
have CONFIG_USB_DEVICE_STACK_NEXT=y (all nRF52840 boards). On
|
||||
platforms without USB hardware (MG24, ESP32 classic, C3/C6) the
|
||||
depends forces this to n automatically — no conf change needed.
|
||||
|
||||
For ESP32-S3 boards, USB_DEVICE_STACK_NEXT must be enabled first via
|
||||
boards/common/esp32s3_usb.conf before this becomes active.
|
||||
|
||||
config ZEPHCORE_ROLE_REPEATER
|
||||
bool "Repeater"
|
||||
help
|
||||
|
||||
@@ -122,6 +122,44 @@ static int64_t ble_tx_start_time = 0;
|
||||
/* Active interface tracking */
|
||||
static enum zephcore_iface active_iface = ZEPHCORE_IFACE_NONE;
|
||||
|
||||
/* active_iface is mutated from two threads — the Bluetooth callback thread
|
||||
* (connect / security / pairing / disconnect) and the USB workqueue
|
||||
* (CMD_APP_START / DTR drop). This mutex makes the check-then-act claim and
|
||||
* release sequences atomic so the two transports can never both believe they
|
||||
* own the interface (or lose a write to it). */
|
||||
K_MUTEX_DEFINE(ble_iface_lock);
|
||||
|
||||
/* Atomically claim the interface for `who` iff it is currently idle.
|
||||
* Returns true only if this call performed the NONE -> who transition. */
|
||||
static bool iface_claim_if_idle(enum zephcore_iface who)
|
||||
{
|
||||
k_mutex_lock(&ble_iface_lock, K_FOREVER);
|
||||
bool claimed = (active_iface == ZEPHCORE_IFACE_NONE);
|
||||
if (claimed) {
|
||||
active_iface = who;
|
||||
}
|
||||
k_mutex_unlock(&ble_iface_lock);
|
||||
return claimed;
|
||||
}
|
||||
|
||||
/* Atomically release the interface if `who` currently owns it. */
|
||||
static void iface_release(enum zephcore_iface who)
|
||||
{
|
||||
k_mutex_lock(&ble_iface_lock, K_FOREVER);
|
||||
if (active_iface == who) {
|
||||
active_iface = ZEPHCORE_IFACE_NONE;
|
||||
}
|
||||
k_mutex_unlock(&ble_iface_lock);
|
||||
}
|
||||
|
||||
/* Claim the active interface for BLE, but only if nothing else owns it.
|
||||
* First-come-first-served: a live USB session must not be evicted by BLE
|
||||
* connecting/pairing in the background. Returns true if BLE now owns it. */
|
||||
static bool ble_claim_iface_if_idle(void)
|
||||
{
|
||||
return iface_claim_if_idle(ZEPHCORE_IFACE_BLE);
|
||||
}
|
||||
|
||||
/* DLE tracking — set after successful DLE request to avoid double-request */
|
||||
static bool dle_requested;
|
||||
|
||||
@@ -298,6 +336,16 @@ static void connected(struct bt_conn *conn, uint8_t err)
|
||||
return;
|
||||
}
|
||||
LOG_INF("connected: %s", addr);
|
||||
|
||||
/* Reject BLE connections while USB is the active transport.
|
||||
* The user connected via BLE expecting to exchange messages, but
|
||||
* USB owns the interface — they would get nothing and be confused. */
|
||||
if (active_iface == ZEPHCORE_IFACE_USB) {
|
||||
LOG_INF("connected: USB active — rejecting BLE connection from %s", addr);
|
||||
bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
|
||||
return;
|
||||
}
|
||||
|
||||
current_conn = bt_conn_ref(conn);
|
||||
|
||||
/* Zephyr stops advertising internally when the conn slot is consumed
|
||||
@@ -349,9 +397,7 @@ static void disconnected(struct bt_conn *conn, uint8_t reason)
|
||||
conn_params_pending = false;
|
||||
|
||||
/* Clear interface state if BLE was active */
|
||||
if (active_iface == ZEPHCORE_IFACE_BLE) {
|
||||
active_iface = ZEPHCORE_IFACE_NONE;
|
||||
}
|
||||
iface_release(ZEPHCORE_IFACE_BLE);
|
||||
|
||||
/* Clear queues, retry state, and congestion */
|
||||
k_msgq_purge(&ble_send_queue);
|
||||
@@ -397,7 +443,7 @@ static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_
|
||||
if (level >= BT_SECURITY_L2 && !ble_tx_ready) {
|
||||
LOG_INF("security established, enabling TX");
|
||||
ble_tx_ready = true;
|
||||
active_iface = ZEPHCORE_IFACE_BLE;
|
||||
ble_claim_iface_if_idle();
|
||||
|
||||
/* If CCC was already subscribed (bonded reconnect — phone writes
|
||||
* CCC before security_changed fires), kick TX now. On fresh
|
||||
@@ -532,14 +578,12 @@ static void pairing_complete(struct bt_conn *conn, bool bonded)
|
||||
ARG_UNUSED(conn);
|
||||
LOG_INF("pairing complete: bonded=%d", bonded);
|
||||
|
||||
/* Switch to BLE interface (fresh pairing only).
|
||||
* Conn params and TX enable are handled in security_changed(),
|
||||
* which fires for both fresh pairing and bonded reconnects. */
|
||||
if (active_iface == ZEPHCORE_IFACE_USB) {
|
||||
LOG_INF("switching from USB to BLE");
|
||||
/* Main handles USB state clearing via on_connected callback */
|
||||
if (ble_claim_iface_if_idle()) {
|
||||
LOG_INF("pairing complete, activating BLE interface");
|
||||
} else {
|
||||
LOG_INF("pairing complete, %s already active — BLE paired but not promoted",
|
||||
active_iface == ZEPHCORE_IFACE_USB ? "USB" : "BLE");
|
||||
}
|
||||
active_iface = ZEPHCORE_IFACE_BLE;
|
||||
}
|
||||
|
||||
static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
|
||||
@@ -985,12 +1029,28 @@ uint32_t zephcore_ble_get_passkey(void)
|
||||
|
||||
enum zephcore_iface zephcore_ble_get_active_iface(void)
|
||||
{
|
||||
return active_iface;
|
||||
k_mutex_lock(&ble_iface_lock, K_FOREVER);
|
||||
enum zephcore_iface iface = active_iface;
|
||||
k_mutex_unlock(&ble_iface_lock);
|
||||
return iface;
|
||||
}
|
||||
|
||||
void zephcore_ble_set_active_iface(enum zephcore_iface iface)
|
||||
{
|
||||
k_mutex_lock(&ble_iface_lock, K_FOREVER);
|
||||
active_iface = iface;
|
||||
k_mutex_unlock(&ble_iface_lock);
|
||||
}
|
||||
|
||||
bool zephcore_ble_iface_try_claim(enum zephcore_iface who)
|
||||
{
|
||||
k_mutex_lock(&ble_iface_lock, K_FOREVER);
|
||||
bool ok = (active_iface == ZEPHCORE_IFACE_NONE || active_iface == who);
|
||||
if (ok) {
|
||||
active_iface = who;
|
||||
}
|
||||
k_mutex_unlock(&ble_iface_lock);
|
||||
return ok;
|
||||
}
|
||||
|
||||
struct k_msgq *zephcore_ble_get_recv_queue(void)
|
||||
|
||||
@@ -65,10 +65,17 @@ bool zephcore_ble_is_advertising(void);
|
||||
void zephcore_ble_set_passkey(uint32_t passkey);
|
||||
uint32_t zephcore_ble_get_passkey(void);
|
||||
|
||||
/** Get/set active interface (BLE/USB coexistence). */
|
||||
/** Get/set active interface (BLE/USB coexistence). Both are thread-safe —
|
||||
* active_iface is mutated from the BLE callback thread and the USB workqueue. */
|
||||
enum zephcore_iface zephcore_ble_get_active_iface(void);
|
||||
void zephcore_ble_set_active_iface(enum zephcore_iface iface);
|
||||
|
||||
/** Atomically claim the active interface for `who` unless the other transport
|
||||
* already owns it. Succeeds (returns true) if the interface is idle or already
|
||||
* held by `who`; fails if a different interface is active. Thread-safe — use
|
||||
* this instead of a get-then-set sequence to avoid a check-then-act race. */
|
||||
bool zephcore_ble_iface_try_claim(enum zephcore_iface who);
|
||||
|
||||
/** Get recv/send queues for USB path sharing. */
|
||||
struct k_msgq *zephcore_ble_get_recv_queue(void);
|
||||
struct k_msgq *zephcore_ble_get_send_queue(void);
|
||||
|
||||
@@ -115,13 +115,17 @@ static void usb_rx_work_fn(struct k_work *work)
|
||||
* is actually CMD_SEND_CHANNEL_TXT_MSG and meant the USB
|
||||
* handshake silently dropped the app's first frame.) */
|
||||
if (payload_len >= 1 && payload[0] == 0x01 /* CMD_APP_START */) {
|
||||
if (zephcore_ble_get_active_iface() == ZEPHCORE_IFACE_BLE &&
|
||||
zephcore_ble_is_connected()) {
|
||||
LOG_INF("usb_rx: CMD_APP_START, disconnecting BLE");
|
||||
zephcore_ble_disconnect();
|
||||
/* Atomically claim the interface for USB unless BLE
|
||||
* already owns it. try_claim succeeds when idle or
|
||||
* already USB (reconnect) and fails only while a BLE
|
||||
* session is live, so USB can't steal it — and the
|
||||
* compare-and-set can't race a concurrent BLE claim. */
|
||||
if (zephcore_ble_iface_try_claim(ZEPHCORE_IFACE_USB)) {
|
||||
zephcore_ble_set_enabled(false);
|
||||
LOG_INF("usb_rx: CMD_APP_START → IFACE_USB");
|
||||
} else {
|
||||
LOG_INF("usb_rx: CMD_APP_START ignored, BLE is active");
|
||||
}
|
||||
zephcore_ble_set_active_iface(ZEPHCORE_IFACE_USB);
|
||||
LOG_INF("usb_rx: active_iface = IFACE_USB");
|
||||
}
|
||||
|
||||
/* Only process if USB is active interface */
|
||||
@@ -155,9 +159,21 @@ static void on_dtr_change(bool dtr_active)
|
||||
return;
|
||||
}
|
||||
LOG_INF("usb_dtr: DTR dropped, USB disconnected");
|
||||
/* While USB owns the interface, BLE claims are rejected (see connected()),
|
||||
* so this thread is the only writer of active_iface here — the get/set
|
||||
* pair below needs no extra locking beyond the thread-safe accessors. */
|
||||
if (zephcore_ble_get_active_iface() == ZEPHCORE_IFACE_USB) {
|
||||
zephcore_ble_set_active_iface(ZEPHCORE_IFACE_NONE);
|
||||
LOG_INF("usb_dtr: active_iface = IFACE_NONE");
|
||||
if (zephcore_ble_is_connected()) {
|
||||
/* BLE client is physically connected — hand off to it. */
|
||||
zephcore_ble_set_active_iface(ZEPHCORE_IFACE_BLE);
|
||||
LOG_INF("usb_dtr: → IFACE_BLE (BLE was connected)");
|
||||
} else {
|
||||
/* Nobody connected — go idle and restart advertising
|
||||
* so the phone can find the companion again. */
|
||||
zephcore_ble_set_active_iface(ZEPHCORE_IFACE_NONE);
|
||||
zephcore_ble_set_enabled(true);
|
||||
LOG_INF("usb_dtr: → IFACE_NONE, BLE advertising restarted");
|
||||
}
|
||||
}
|
||||
ring_buf_reset(&usb_ring_buf);
|
||||
usb_frame_len = 0;
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Debug Config — opt-in logging and diagnostics.
|
||||
#
|
||||
# Production is the default. Pass this conf to get the full debug experience:
|
||||
#
|
||||
# west build -b rak4631 zephcore --pristine -- \
|
||||
# -DEXTRA_CONF_FILE="boards/common/debug.conf"
|
||||
#
|
||||
# # With repeater role:
|
||||
# west build -b rak4631 zephcore --pristine -- \
|
||||
# -DEXTRA_CONF_FILE="boards/common/repeater.conf;boards/common/debug.conf"
|
||||
|
||||
# ========== Core debug features ==========
|
||||
CONFIG_LOG=y
|
||||
CONFIG_ASSERT=y
|
||||
CONFIG_USE_SEGGER_RTT=y
|
||||
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=4096
|
||||
CONFIG_THREAD_NAME=y
|
||||
|
||||
# Halt-and-inspect on fatal faults instead of the production reboot-on-fatal
|
||||
# (prj.conf sets CONFIG_RESET_ON_FATAL_ERROR=y). A debugger needs the core
|
||||
# stopped at the fault with a stack dump, not rebooted out from under it.
|
||||
CONFIG_RESET_ON_FATAL_ERROR=n
|
||||
|
||||
# ========== Log tuning ==========
|
||||
# ZephCore BLE modules at INF level (connection lifecycle, pairing, TX/RX).
|
||||
CONFIG_ZEPHCORE_BLE_LOG_LEVEL_INF=y
|
||||
|
||||
# Deferred logging — non-blocking so BLE/LoRa timing is not disturbed.
|
||||
CONFIG_LOG_BUFFER_SIZE=8192
|
||||
CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=1
|
||||
CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=2048
|
||||
|
||||
# RTT backend only — no UART backend on nRF52.
|
||||
# UART backend stalls on uart_poll_out() when the USB host disconnects;
|
||||
# RTT DROP mode discards messages without blocking.
|
||||
CONFIG_LOG_BACKEND_RTT=y
|
||||
CONFIG_LOG_BACKEND_RTT_MODE_DROP=y
|
||||
|
||||
# Silence noisy subsystems
|
||||
CONFIG_CFB_LOG_LEVEL_ERR=y
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Reroute console + shell off USB Serial/JTAG onto uart0 (physical TX/RX).
|
||||
*
|
||||
* ESP32-S3 USB Serial/JTAG shares the D+/D- pins with USB OTG and only one
|
||||
* controller can own the port at a time. Boards that default their console to
|
||||
* USB Serial/JTAG include this alongside esp32s3_usb_otg.dtsi so that, when
|
||||
* esp32s3_usb.conf disables USB Serial/JTAG and hands the port to USB OTG, the
|
||||
* console still has a home. Boards with a dedicated UART console (e.g. Heltec)
|
||||
* do not need this.
|
||||
*
|
||||
* uart0 is disabled by default in the ESP32-S3 SoC dtsi, so we enable it and
|
||||
* pin it to the chip's ROM-default UART0 pads (GPIO43 TX / GPIO44 RX) — the
|
||||
* same pins Heltec uses. Without this the console would point at a disabled,
|
||||
* un-pinned node and produce no output at all.
|
||||
*/
|
||||
#include <zephyr/dt-bindings/pinctrl/esp-pinctrl-common.h>
|
||||
#include <zephyr/dt-bindings/pinctrl/esp32s3-pinctrl.h>
|
||||
#include <zephyr/dt-bindings/pinctrl/esp32s3-gpio-sigmap.h>
|
||||
|
||||
&pinctrl {
|
||||
uart0_default: uart0_default {
|
||||
group1 {
|
||||
pinmux = <UART0_TX_GPIO43>;
|
||||
output-high;
|
||||
};
|
||||
group2 {
|
||||
pinmux = <UART0_RX_GPIO44>;
|
||||
bias-pull-up;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
pinctrl-0 = <&uart0_default>;
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
zephyr,console = &uart0;
|
||||
zephyr,shell-uart = &uart0;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
# ESP32-S3 USB CDC-ACM companion support
|
||||
#
|
||||
# ESP32-S3 has a DWC2 USB OTG peripheral (snps,dwc2 compatible) that supports
|
||||
# the Zephyr USB NEXT stack. This conf enables it and turns on the companion
|
||||
# USB transport on S3 boards. Do NOT use on ESP32 (original) or C3/C6 — those
|
||||
# chips have no DWC2 controller.
|
||||
#
|
||||
# Build with:
|
||||
# -DEXTRA_CONF_FILE="boards/common/esp32s3_usb.conf"
|
||||
#
|
||||
# Also add the cdc_acm_uart DTS node to the board overlay (the overlays include
|
||||
# boards/common/esp32s3_usb_otg.dtsi). Without the DT node,
|
||||
# DT_HAS_COMPAT_STATUS_OKAY(zephyr_cdc_acm_uart) is false and
|
||||
# zephcore_usbd_init() is compiled out at the #if check.
|
||||
|
||||
CONFIG_USB_DEVICE_STACK_NEXT=y
|
||||
CONFIG_ZEPHCORE_COMPANION_USB=y
|
||||
CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n
|
||||
CONFIG_UART_LINE_CTRL=y
|
||||
|
||||
# Disable USB Serial/JTAG so it doesn't fight USB OTG for the D+/D- pins.
|
||||
# ESP32-S3 has an internal mux — only one controller can own the port at a time.
|
||||
# With USB companion active, the port IS the companion protocol channel.
|
||||
CONFIG_ESP_USB_SERIAL_JTAG_ENABLED=n
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* ESP32-S3 USB OTG (DWC2) — companion USB transport.
|
||||
*
|
||||
* Enables the snps,dwc2 USB OTG controller and attaches a CDC-ACM UART node
|
||||
* for the binary companion protocol. The DWC2 driver is only compiled when
|
||||
* CONFIG_USB_DEVICE_STACK_NEXT=y (set by boards/common/esp32s3_usb.conf);
|
||||
* without that conf this node is inert.
|
||||
*
|
||||
* Boards whose default console rides USB Serial/JTAG (shares D+/D- with USB
|
||||
* OTG) must also reroute the console off the shared pins — see
|
||||
* esp32s3_console_uart0.dtsi.
|
||||
*/
|
||||
zephyr_udc0: &usb_otg {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&zephyr_udc0 {
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
# Logging Tuning — included automatically for debug builds only.
|
||||
# Prod builds (CONFIG_LOG=n via prod.conf) skip this file entirely,
|
||||
# avoiding Kconfig warnings from log settings that depend on CONFIG_LOG.
|
||||
|
||||
# ZephCore BLE modules at INF level (connection lifecycle, pairing, TX/RX)
|
||||
# Default level is WRN — this ensures our INF messages come through.
|
||||
# Avoid DBG level — it causes system workqueue stack overflow.
|
||||
CONFIG_ZEPHCORE_BLE_LOG_LEVEL_INF=y
|
||||
|
||||
# Deferred mode (non-blocking) — buffer/thread config
|
||||
CONFIG_LOG_BUFFER_SIZE=8192
|
||||
CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=1
|
||||
CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=2048
|
||||
|
||||
# Backends
|
||||
# NOTE: UART backend on nRF52 routes through USB CDC ACM (zephyr,console = &cdc_acm_uart).
|
||||
# There is no LOG_BACKEND_UART_MODE_DROP in Zephyr — if the USB host disconnects, the log
|
||||
# processing thread stalls on uart_poll_out(). Disable UART backend on nRF52 to avoid this;
|
||||
# RTT (below) is the reliable debug path and already configured with drop mode.
|
||||
CONFIG_LOG_BACKEND_RTT=y
|
||||
|
||||
# Suppress noisy subsystem logs
|
||||
CONFIG_CFB_LOG_LEVEL_ERR=y
|
||||
@@ -16,10 +16,13 @@ CONFIG_BT_TX_PROCESSOR_STACK_SIZE=2048
|
||||
|
||||
# Controller assert handler — without this, a controller assert silently
|
||||
# freezes the CPU at highest IRQ priority with zero log output.
|
||||
# Harmless when CONFIG_ASSERT=n, so it stays on for prod and debug.
|
||||
CONFIG_BT_CTLR_ASSERT_HANDLER=y
|
||||
|
||||
# ========== Debug ==========
|
||||
CONFIG_ASSERT=y
|
||||
# CONFIG_ASSERT is debug-only (boards/common/debug.conf, opt-in). Setting it
|
||||
# here would override the prj.conf production default (CONFIG_ASSERT=n) on every
|
||||
# MG24 build, since this file loads after prj.conf.
|
||||
|
||||
# ========== Heap ==========
|
||||
# Silabs BLE stack requires larger heap (override zephcore_common 2KB default)
|
||||
|
||||
@@ -44,11 +44,12 @@ CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE=y
|
||||
# Silently ignored when QSPI is not present (Kconfig guard: if NORDIC_QSPI_NOR).
|
||||
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
|
||||
|
||||
# ========== SEGGER RTT (J-Link debug) ==========
|
||||
# RTT log backend is in boards/common/logging.conf (only included for debug builds).
|
||||
CONFIG_USE_SEGGER_RTT=y
|
||||
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=4096
|
||||
|
||||
# ========== Debug ==========
|
||||
CONFIG_ASSERT=y
|
||||
# SEGGER RTT and CONFIG_ASSERT are debug-only and live in boards/common/debug.conf
|
||||
# (opt-in). Keeping them here would override the production defaults from
|
||||
# prj.conf (CONFIG_USE_SEGGER_RTT=n, CONFIG_ASSERT=n) on every nRF52 build,
|
||||
# since this file loads after prj.conf.
|
||||
#
|
||||
# BT_CTLR_ASSERT_HANDLER is harmless when CONFIG_ASSERT=n (no RAM/flash cost,
|
||||
# the handler is simply never invoked) so it stays on for both prod and debug.
|
||||
CONFIG_BT_CTLR_ASSERT_HANDLER=y
|
||||
|
||||
@@ -23,11 +23,9 @@ CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
|
||||
# Coded PHY — enable in nRF LL controller (host auto-request in zephcore_common.conf)
|
||||
CONFIG_BT_CTLR_PHY_CODED=y
|
||||
|
||||
# ========== SEGGER RTT (J-Link / CMSIS-DAP debug) ==========
|
||||
CONFIG_LOG_BACKEND_RTT=y
|
||||
CONFIG_USE_SEGGER_RTT=y
|
||||
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=4096
|
||||
|
||||
# ========== Debug ==========
|
||||
CONFIG_ASSERT=y
|
||||
# SEGGER RTT and CONFIG_ASSERT are debug-only and live in boards/common/debug.conf
|
||||
# (opt-in). Keeping them here would override the production defaults from
|
||||
# prj.conf on every nRF54L build, since this file loads after prj.conf.
|
||||
# BT_CTLR_ASSERT_HANDLER is harmless when CONFIG_ASSERT=n, so it stays on.
|
||||
CONFIG_BT_CTLR_ASSERT_HANDLER=y
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# Production Config - Common to ALL boards (Companion & Repeater)
|
||||
# Build: west build -b <board> zephcore --pristine -- \
|
||||
# -DEXTRA_CONF_FILE="boards/common/prod.conf"
|
||||
#
|
||||
# Disables logging for smaller binary and lower power consumption.
|
||||
# USB CDC still works for CLI commands on repeaters.
|
||||
|
||||
# Disable logging subsystem (saves ~62KB flash, ~2-5mA power)
|
||||
CONFIG_LOG=n
|
||||
|
||||
# Disable asserts (saves flash, removes CMake warning)
|
||||
CONFIG_ASSERT=n
|
||||
|
||||
# Disable SEGGER RTT (saves ~4KB RAM ring buffer + init code)
|
||||
CONFIG_USE_SEGGER_RTT=n
|
||||
|
||||
# Disable thread name strings (saves flash — only useful for debug)
|
||||
CONFIG_THREAD_NAME=n
|
||||
|
||||
# Max contacts: Kconfig default is 350 — fits nRF52840 RAM with ~10% headroom
|
||||
# and is safe for 100KB ExtraFS. RAM-limited boards (xiao_nrf54l15=450,
|
||||
# xiao_esp32c3=300) override in their own board.conf. Do not set here.
|
||||
@@ -29,7 +29,6 @@ CONFIG_PSA_WANT_KEY_TYPE_HMAC=y
|
||||
|
||||
# ========== Stack Protection ==========
|
||||
CONFIG_HW_STACK_PROTECTION=y
|
||||
CONFIG_THREAD_NAME=y
|
||||
|
||||
# ========== Hardware Basics ==========
|
||||
CONFIG_ADC=y
|
||||
@@ -195,10 +194,7 @@ CONFIG_INPUT_EVENT_DUMP=n
|
||||
CONFIG_INPUT_MODE_SYNCHRONOUS=y
|
||||
|
||||
# ========== Logging ==========
|
||||
# RTT log backend: DROP mode (not BLOCK) — when no RTT host is connected the
|
||||
# buffer is always full; BLOCK mode sleeps 20ms per message with irq_lock held,
|
||||
# disrupting BLE timing and cascading into buffer exhaustion deadlocks.
|
||||
CONFIG_LOG_BACKEND_RTT_MODE_DROP=y
|
||||
# Log backend tuning lives in boards/common/debug.conf (opt-in).
|
||||
|
||||
# Silence USB CH9 control-transfer spam (dozens of INF lines during enumeration).
|
||||
# WRN keeps real USB errors visible.
|
||||
|
||||
@@ -101,3 +101,6 @@
|
||||
|
||||
/* LittleFS auto-mount — standard /lfs mount point */
|
||||
#include "../../common/filesystem.dtsi"
|
||||
/* USB CDC-ACM — companion USB transport (esp32s3_usb.conf). Heltec has a
|
||||
* dedicated UART console, so no console reroute is needed. */
|
||||
#include "../../common/esp32s3_usb_otg.dtsi"
|
||||
|
||||
@@ -101,3 +101,6 @@
|
||||
|
||||
/* LittleFS auto-mount — standard /lfs mount point */
|
||||
#include "../../common/filesystem.dtsi"
|
||||
/* USB CDC-ACM — companion USB transport (esp32s3_usb.conf). Heltec has a
|
||||
* dedicated UART console, so no console reroute is needed. */
|
||||
#include "../../common/esp32s3_usb_otg.dtsi"
|
||||
|
||||
@@ -109,3 +109,8 @@
|
||||
|
||||
/* LittleFS auto-mount — standard /lfs mount point */
|
||||
#include "../../common/filesystem.dtsi"
|
||||
|
||||
/* USB OTG companion transport. station_g2 consoles over USB Serial/JTAG, which
|
||||
* shares D+/D- with USB OTG, so the console is rerouted to uart0. */
|
||||
#include "../../common/esp32s3_console_uart0.dtsi"
|
||||
#include "../../common/esp32s3_usb_otg.dtsi"
|
||||
|
||||
@@ -86,3 +86,8 @@
|
||||
|
||||
/* LittleFS auto-mount — standard /lfs mount point */
|
||||
#include "../../common/filesystem.dtsi"
|
||||
|
||||
/* USB OTG companion transport. Consoles over USB Serial/JTAG (shares D+/D-
|
||||
* with USB OTG), so the console is rerouted to uart0. */
|
||||
#include "../../common/esp32s3_console_uart0.dtsi"
|
||||
#include "../../common/esp32s3_usb_otg.dtsi"
|
||||
|
||||
@@ -7,7 +7,7 @@ CONFIG_BT_DIS_MODEL_NUMBER_STR="Seeed XIAO nRF52840"
|
||||
|
||||
CONFIG_ZEPHCORE_SD_FWID=0x0123
|
||||
|
||||
# Default debug (logging.conf) sends LOG_* to RTT only. Plain XIAO is usually
|
||||
# Default debug (debug.conf) sends LOG_* to RTT only. Plain XIAO is usually
|
||||
# flashed/debugged over USB without an SWD J-Link — enable UART backend so
|
||||
# LOG_* appears on the CDC ACM serial port (same as zephyr,console).
|
||||
# RTT remains enabled for J-Link; use DROP mode (see zephcore_common.conf).
|
||||
|
||||
+10
-4
@@ -16,10 +16,16 @@ CONFIG_UART_CONSOLE=y
|
||||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||
CONFIG_RING_BUFFER=y
|
||||
|
||||
# Logging subsystem — enabled by default (prod.conf disables with CONFIG_LOG=n).
|
||||
# Log tuning (buffer size, backends, etc.) is in boards/common/logging.conf,
|
||||
# which CMake auto-includes only when prod.conf is NOT active.
|
||||
CONFIG_LOG=y
|
||||
# Production by default — add boards/common/debug.conf to enable logging.
|
||||
CONFIG_LOG=n
|
||||
CONFIG_ASSERT=n
|
||||
CONFIG_USE_SEGGER_RTT=n
|
||||
CONFIG_THREAD_NAME=n
|
||||
|
||||
# Reboot on any fatal error (stack overflow, hard fault, etc.) instead of
|
||||
# spinning forever. Asserts are disabled so they won't reach here, but all
|
||||
# other fatal paths (k_panic, CPU exceptions) still get a clean reboot.
|
||||
CONFIG_RESET_ON_FATAL_ERROR=y
|
||||
|
||||
# ========== Power Management ==========
|
||||
# Note: nRF52840 automatically uses WFI (Wait For Interrupt) in idle thread.
|
||||
|
||||
@@ -34,7 +34,13 @@ LOG_MODULE_REGISTER(zephcore_main, CONFIG_ZEPHCORE_MAIN_LOG_LEVEL);
|
||||
|
||||
#include <ZephyrBLE.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_LOG)
|
||||
/* The USB CDC companion stack is compiled when either logging needs the CDC
|
||||
* console (debug builds) or the binary companion transport is explicitly
|
||||
* enabled (CONFIG_ZEPHCORE_COMPANION_USB, default-y on USB-capable boards). */
|
||||
#define ZEPHCORE_USB_STACK \
|
||||
(IS_ENABLED(CONFIG_LOG) || IS_ENABLED(CONFIG_ZEPHCORE_COMPANION_USB))
|
||||
|
||||
#if ZEPHCORE_USB_STACK
|
||||
#include <ZephyrCompanionUSB.h>
|
||||
#include <ZephyrUSBCDC.h>
|
||||
#endif
|
||||
@@ -181,7 +187,7 @@ static void ble_on_connected(void)
|
||||
/* BLE disconnected callback — clean up state and notify UI */
|
||||
static void ble_on_disconnected(void)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_LOG)
|
||||
#if ZEPHCORE_USB_STACK
|
||||
zephcore_usb_companion_reset_rx();
|
||||
#endif
|
||||
#ifdef ZEPHCORE_LORA
|
||||
@@ -562,8 +568,8 @@ int main(void)
|
||||
/* USB CDC init up front so the host can enumerate, then block until the
|
||||
* host opens the port (DTR-high) — event-driven via the shared usbd
|
||||
* message callback. Unplugged → 1 s timeout, banner is buffered for any
|
||||
* later attach. CONFIG_LOG=n prod builds skip the whole stack. */
|
||||
#if IS_ENABLED(CONFIG_LOG) && DT_HAS_COMPAT_STATUS_OKAY(zephyr_cdc_acm_uart) && \
|
||||
* later attach. */
|
||||
#if ZEPHCORE_USB_STACK && DT_HAS_COMPAT_STATUS_OKAY(zephyr_cdc_acm_uart) && \
|
||||
!IS_ENABLED(CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT)
|
||||
zephcore_usbd_init();
|
||||
zephcore_usbd_wait_dtr(1000);
|
||||
@@ -780,10 +786,11 @@ int main(void)
|
||||
zephcore_ble_init(&ble_cbs);
|
||||
|
||||
/*
|
||||
* USB CDC ACM - only enabled when logging is enabled (debug builds).
|
||||
* Production builds (CONFIG_LOG=n) skip USB entirely, saving ~2-5mA.
|
||||
* USB CDC ACM companion transport.
|
||||
* Enabled when logging is on (debug builds) OR when explicitly requested
|
||||
* via CONFIG_ZEPHCORE_COMPANION_USB (e.g. prod builds on USB-capable boards).
|
||||
*/
|
||||
#if IS_ENABLED(CONFIG_LOG)
|
||||
#if ZEPHCORE_USB_STACK
|
||||
zephcore_usb_companion_init(&mesh_events, &rx_process_work, MESH_EVENT_BLE_RX,
|
||||
&zephyr_board);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user