mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-05 22:03:56 +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 init -l zephcore
|
||||||
west update
|
west update
|
||||||
|
|
||||||
# Companion (with logging)
|
# Companion (production — default, no extra conf needed)
|
||||||
west build -b wio_tracker_l1 zephcore --pristine
|
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 -- \
|
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 -- \
|
west build -b rak4631 zephcore --pristine -- \
|
||||||
-DEXTRA_CONF_FILE="boards/common/repeater.conf"
|
-DEXTRA_CONF_FILE="boards/common/repeater.conf"
|
||||||
|
|
||||||
# Repeater (production)
|
# Repeater (debug logging)
|
||||||
west build -b rak4631 zephcore --pristine -- \
|
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)
|
# Repeater with packet logging (clean RAW/RX/TX lines only, no debug spam)
|
||||||
west build -b rak4631 zephcore --pristine -- \
|
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.
|
- **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).
|
- **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
|
- **GPIO-gated GPS**: Powered on only during fix acquisition
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|||||||
@@ -37,19 +37,19 @@ if [[ $1 == "nrf" ]]; then
|
|||||||
for board in "${nRF_boards[@]}"; do
|
for board in "${nRF_boards[@]}"; do
|
||||||
board_clean_for_path=$(echo "$board" | sed -e 's/\//-/g')
|
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"
|
echo "Now building $board companion"
|
||||||
if [[ $board == "wio_tracker_l1" ]]; then
|
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
|
else
|
||||||
west build -b "$board" zephcore --pristine -- -DEXTRA_CONF_FILE="boards/common/prod.conf"
|
west build -b "$board" zephcore --pristine
|
||||||
fi
|
fi
|
||||||
mv build/zephyr/zephyr.uf2 firmware/"$board"-companion-"$COMMIT_HASH".uf2
|
mv build/zephyr/zephyr.uf2 firmware/"$board"-companion-"$COMMIT_HASH".uf2
|
||||||
mv build/zephyr/zephyr.zip firmware/"$board"-companion-"$COMMIT_HASH".zip
|
mv build/zephyr/zephyr.zip firmware/"$board"-companion-"$COMMIT_HASH".zip
|
||||||
|
|
||||||
# build nRF repeaters
|
# build nRF repeaters
|
||||||
echo "Now building $board repeater"
|
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.uf2 firmware/"$board"-repeater-"$COMMIT_HASH".uf2
|
||||||
mv build/zephyr/zephyr.zip firmware/"$board"-repeater-"$COMMIT_HASH".zip
|
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.
|
# Heltec_t114_without_display_* PIO envs.
|
||||||
if [[ $board == "heltec_t114" ]]; then
|
if [[ $board == "heltec_t114" ]]; then
|
||||||
echo "Now building $board companion (noscreen)"
|
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.uf2 firmware/"$board"-companion-noscreen-"$COMMIT_HASH".uf2
|
||||||
mv build/zephyr/zephyr.zip firmware/"$board"-companion-noscreen-"$COMMIT_HASH".zip
|
mv build/zephyr/zephyr.zip firmware/"$board"-companion-noscreen-"$COMMIT_HASH".zip
|
||||||
|
|
||||||
echo "Now building $board repeater (noscreen)"
|
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.uf2 firmware/"$board"-repeater-noscreen-"$COMMIT_HASH".uf2
|
||||||
mv build/zephyr/zephyr.zip firmware/"$board"-repeater-noscreen-"$COMMIT_HASH".zip
|
mv build/zephyr/zephyr.zip firmware/"$board"-repeater-noscreen-"$COMMIT_HASH".zip
|
||||||
fi
|
fi
|
||||||
@@ -82,9 +82,9 @@ if [[ $1 == "esp32" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $2 == "companions" ]]; then
|
if [[ $2 == "companions" ]]; then
|
||||||
# build ESP32 companions
|
# build ESP32 companions (production is the default)
|
||||||
echo "Now building $board companion"
|
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=$(
|
FLASH_SIZE=$(
|
||||||
python3 -c '
|
python3 -c '
|
||||||
import re
|
import re
|
||||||
@@ -127,7 +127,7 @@ print(str(size // 1048576) + "MB")
|
|||||||
if [[ $2 == "repeaters" ]]; then
|
if [[ $2 == "repeaters" ]]; then
|
||||||
# build ESP32 repeaters
|
# build ESP32 repeaters
|
||||||
echo "Now building $board repeater"
|
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=$(
|
FLASH_SIZE=$(
|
||||||
python3 -c '
|
python3 -c '
|
||||||
import re
|
import re
|
||||||
|
|||||||
@@ -511,11 +511,11 @@ Wolf3D-style raycaster on OLED: textured walls, 2 enemy types, shooting, HUD. By
|
|||||||
### 9.1 Config Layering
|
### 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/zephcore_common.conf (ALL boards: BLE, crypto, FS, LoRa, sensors)
|
||||||
→ boards/common/<platform>_common.conf (nrf52/esp32/nrf54l/mg24 specifics)
|
→ boards/common/<platform>_common.conf (nrf52/esp32/nrf54l/mg24 specifics)
|
||||||
→ boards/<mcu>/<board>/board.conf (board-specific pins, features)
|
→ 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
|
### 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}")
|
zephcore_auto_pair_overlay("${ZEPHCORE_BOARD_CONF}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Include logging tuning only for debug builds (when prod.conf is NOT active).
|
# Production is the default. Debug logging is opt-in via debug.conf.
|
||||||
# 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()
|
|
||||||
|
|
||||||
# Auto-include WiFi OTA for ESP32 repeater builds.
|
# Auto-include WiFi OTA for ESP32 repeater builds.
|
||||||
# Enables WiFi AP + HTTP server + MCUboot image management.
|
# 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.
|
BLE companion device that connects to ZephCore mobile app.
|
||||||
Includes BLE stack, contact management, offline queue, channels.
|
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
|
config ZEPHCORE_ROLE_REPEATER
|
||||||
bool "Repeater"
|
bool "Repeater"
|
||||||
help
|
help
|
||||||
|
|||||||
@@ -122,6 +122,44 @@ static int64_t ble_tx_start_time = 0;
|
|||||||
/* Active interface tracking */
|
/* Active interface tracking */
|
||||||
static enum zephcore_iface active_iface = ZEPHCORE_IFACE_NONE;
|
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 */
|
/* DLE tracking — set after successful DLE request to avoid double-request */
|
||||||
static bool dle_requested;
|
static bool dle_requested;
|
||||||
|
|
||||||
@@ -298,6 +336,16 @@ static void connected(struct bt_conn *conn, uint8_t err)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_INF("connected: %s", addr);
|
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);
|
current_conn = bt_conn_ref(conn);
|
||||||
|
|
||||||
/* Zephyr stops advertising internally when the conn slot is consumed
|
/* 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;
|
conn_params_pending = false;
|
||||||
|
|
||||||
/* Clear interface state if BLE was active */
|
/* Clear interface state if BLE was active */
|
||||||
if (active_iface == ZEPHCORE_IFACE_BLE) {
|
iface_release(ZEPHCORE_IFACE_BLE);
|
||||||
active_iface = ZEPHCORE_IFACE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear queues, retry state, and congestion */
|
/* Clear queues, retry state, and congestion */
|
||||||
k_msgq_purge(&ble_send_queue);
|
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) {
|
if (level >= BT_SECURITY_L2 && !ble_tx_ready) {
|
||||||
LOG_INF("security established, enabling TX");
|
LOG_INF("security established, enabling TX");
|
||||||
ble_tx_ready = true;
|
ble_tx_ready = true;
|
||||||
active_iface = ZEPHCORE_IFACE_BLE;
|
ble_claim_iface_if_idle();
|
||||||
|
|
||||||
/* If CCC was already subscribed (bonded reconnect — phone writes
|
/* If CCC was already subscribed (bonded reconnect — phone writes
|
||||||
* CCC before security_changed fires), kick TX now. On fresh
|
* 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);
|
ARG_UNUSED(conn);
|
||||||
LOG_INF("pairing complete: bonded=%d", bonded);
|
LOG_INF("pairing complete: bonded=%d", bonded);
|
||||||
|
|
||||||
/* Switch to BLE interface (fresh pairing only).
|
if (ble_claim_iface_if_idle()) {
|
||||||
* Conn params and TX enable are handled in security_changed(),
|
LOG_INF("pairing complete, activating BLE interface");
|
||||||
* which fires for both fresh pairing and bonded reconnects. */
|
} else {
|
||||||
if (active_iface == ZEPHCORE_IFACE_USB) {
|
LOG_INF("pairing complete, %s already active — BLE paired but not promoted",
|
||||||
LOG_INF("switching from USB to BLE");
|
active_iface == ZEPHCORE_IFACE_USB ? "USB" : "BLE");
|
||||||
/* Main handles USB state clearing via on_connected callback */
|
|
||||||
}
|
}
|
||||||
active_iface = ZEPHCORE_IFACE_BLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
|
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)
|
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)
|
void zephcore_ble_set_active_iface(enum zephcore_iface iface)
|
||||||
{
|
{
|
||||||
|
k_mutex_lock(&ble_iface_lock, K_FOREVER);
|
||||||
active_iface = iface;
|
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)
|
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);
|
void zephcore_ble_set_passkey(uint32_t passkey);
|
||||||
uint32_t zephcore_ble_get_passkey(void);
|
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);
|
enum zephcore_iface zephcore_ble_get_active_iface(void);
|
||||||
void zephcore_ble_set_active_iface(enum zephcore_iface iface);
|
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. */
|
/** Get recv/send queues for USB path sharing. */
|
||||||
struct k_msgq *zephcore_ble_get_recv_queue(void);
|
struct k_msgq *zephcore_ble_get_recv_queue(void);
|
||||||
struct k_msgq *zephcore_ble_get_send_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
|
* is actually CMD_SEND_CHANNEL_TXT_MSG and meant the USB
|
||||||
* handshake silently dropped the app's first frame.) */
|
* handshake silently dropped the app's first frame.) */
|
||||||
if (payload_len >= 1 && payload[0] == 0x01 /* CMD_APP_START */) {
|
if (payload_len >= 1 && payload[0] == 0x01 /* CMD_APP_START */) {
|
||||||
if (zephcore_ble_get_active_iface() == ZEPHCORE_IFACE_BLE &&
|
/* Atomically claim the interface for USB unless BLE
|
||||||
zephcore_ble_is_connected()) {
|
* already owns it. try_claim succeeds when idle or
|
||||||
LOG_INF("usb_rx: CMD_APP_START, disconnecting BLE");
|
* already USB (reconnect) and fails only while a BLE
|
||||||
zephcore_ble_disconnect();
|
* 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 */
|
/* Only process if USB is active interface */
|
||||||
@@ -155,9 +159,21 @@ static void on_dtr_change(bool dtr_active)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_INF("usb_dtr: DTR dropped, USB disconnected");
|
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) {
|
if (zephcore_ble_get_active_iface() == ZEPHCORE_IFACE_USB) {
|
||||||
zephcore_ble_set_active_iface(ZEPHCORE_IFACE_NONE);
|
if (zephcore_ble_is_connected()) {
|
||||||
LOG_INF("usb_dtr: active_iface = IFACE_NONE");
|
/* 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);
|
ring_buf_reset(&usb_ring_buf);
|
||||||
usb_frame_len = 0;
|
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
|
# Controller assert handler — without this, a controller assert silently
|
||||||
# freezes the CPU at highest IRQ priority with zero log output.
|
# 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
|
CONFIG_BT_CTLR_ASSERT_HANDLER=y
|
||||||
|
|
||||||
# ========== Debug ==========
|
# ========== 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 ==========
|
# ========== Heap ==========
|
||||||
# Silabs BLE stack requires larger heap (override zephcore_common 2KB default)
|
# 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).
|
# Silently ignored when QSPI is not present (Kconfig guard: if NORDIC_QSPI_NOR).
|
||||||
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
|
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 ==========
|
# ========== 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
|
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)
|
# Coded PHY — enable in nRF LL controller (host auto-request in zephcore_common.conf)
|
||||||
CONFIG_BT_CTLR_PHY_CODED=y
|
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 ==========
|
# ========== 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
|
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 ==========
|
# ========== Stack Protection ==========
|
||||||
CONFIG_HW_STACK_PROTECTION=y
|
CONFIG_HW_STACK_PROTECTION=y
|
||||||
CONFIG_THREAD_NAME=y
|
|
||||||
|
|
||||||
# ========== Hardware Basics ==========
|
# ========== Hardware Basics ==========
|
||||||
CONFIG_ADC=y
|
CONFIG_ADC=y
|
||||||
@@ -195,10 +194,7 @@ CONFIG_INPUT_EVENT_DUMP=n
|
|||||||
CONFIG_INPUT_MODE_SYNCHRONOUS=y
|
CONFIG_INPUT_MODE_SYNCHRONOUS=y
|
||||||
|
|
||||||
# ========== Logging ==========
|
# ========== Logging ==========
|
||||||
# RTT log backend: DROP mode (not BLOCK) — when no RTT host is connected the
|
# Log backend tuning lives in boards/common/debug.conf (opt-in).
|
||||||
# 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
|
|
||||||
|
|
||||||
# Silence USB CH9 control-transfer spam (dozens of INF lines during enumeration).
|
# Silence USB CH9 control-transfer spam (dozens of INF lines during enumeration).
|
||||||
# WRN keeps real USB errors visible.
|
# WRN keeps real USB errors visible.
|
||||||
|
|||||||
@@ -101,3 +101,6 @@
|
|||||||
|
|
||||||
/* LittleFS auto-mount — standard /lfs mount point */
|
/* LittleFS auto-mount — standard /lfs mount point */
|
||||||
#include "../../common/filesystem.dtsi"
|
#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 */
|
/* LittleFS auto-mount — standard /lfs mount point */
|
||||||
#include "../../common/filesystem.dtsi"
|
#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 */
|
/* LittleFS auto-mount — standard /lfs mount point */
|
||||||
#include "../../common/filesystem.dtsi"
|
#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 */
|
/* LittleFS auto-mount — standard /lfs mount point */
|
||||||
#include "../../common/filesystem.dtsi"
|
#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
|
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
|
# 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).
|
# 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).
|
# 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_UART_INTERRUPT_DRIVEN=y
|
||||||
CONFIG_RING_BUFFER=y
|
CONFIG_RING_BUFFER=y
|
||||||
|
|
||||||
# Logging subsystem — enabled by default (prod.conf disables with CONFIG_LOG=n).
|
# Production by default — add boards/common/debug.conf to enable logging.
|
||||||
# Log tuning (buffer size, backends, etc.) is in boards/common/logging.conf,
|
CONFIG_LOG=n
|
||||||
# which CMake auto-includes only when prod.conf is NOT active.
|
CONFIG_ASSERT=n
|
||||||
CONFIG_LOG=y
|
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 ==========
|
# ========== Power Management ==========
|
||||||
# Note: nRF52840 automatically uses WFI (Wait For Interrupt) in idle thread.
|
# 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>
|
#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 <ZephyrCompanionUSB.h>
|
||||||
#include <ZephyrUSBCDC.h>
|
#include <ZephyrUSBCDC.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -181,7 +187,7 @@ static void ble_on_connected(void)
|
|||||||
/* BLE disconnected callback — clean up state and notify UI */
|
/* BLE disconnected callback — clean up state and notify UI */
|
||||||
static void ble_on_disconnected(void)
|
static void ble_on_disconnected(void)
|
||||||
{
|
{
|
||||||
#if IS_ENABLED(CONFIG_LOG)
|
#if ZEPHCORE_USB_STACK
|
||||||
zephcore_usb_companion_reset_rx();
|
zephcore_usb_companion_reset_rx();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ZEPHCORE_LORA
|
#ifdef ZEPHCORE_LORA
|
||||||
@@ -562,8 +568,8 @@ int main(void)
|
|||||||
/* USB CDC init up front so the host can enumerate, then block until the
|
/* 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
|
* host opens the port (DTR-high) — event-driven via the shared usbd
|
||||||
* message callback. Unplugged → 1 s timeout, banner is buffered for any
|
* message callback. Unplugged → 1 s timeout, banner is buffered for any
|
||||||
* later attach. CONFIG_LOG=n prod builds skip the whole stack. */
|
* later attach. */
|
||||||
#if IS_ENABLED(CONFIG_LOG) && DT_HAS_COMPAT_STATUS_OKAY(zephyr_cdc_acm_uart) && \
|
#if ZEPHCORE_USB_STACK && DT_HAS_COMPAT_STATUS_OKAY(zephyr_cdc_acm_uart) && \
|
||||||
!IS_ENABLED(CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT)
|
!IS_ENABLED(CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT)
|
||||||
zephcore_usbd_init();
|
zephcore_usbd_init();
|
||||||
zephcore_usbd_wait_dtr(1000);
|
zephcore_usbd_wait_dtr(1000);
|
||||||
@@ -780,10 +786,11 @@ int main(void)
|
|||||||
zephcore_ble_init(&ble_cbs);
|
zephcore_ble_init(&ble_cbs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* USB CDC ACM - only enabled when logging is enabled (debug builds).
|
* USB CDC ACM companion transport.
|
||||||
* Production builds (CONFIG_LOG=n) skip USB entirely, saving ~2-5mA.
|
* 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,
|
zephcore_usb_companion_init(&mesh_events, &rx_process_work, MESH_EVENT_BLE_RX,
|
||||||
&zephyr_board);
|
&zephyr_board);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user