mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-22 20:11:33 +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:
1 parent
7d7a64ff5a
commit
553b71c44a
25 files changed
+332
-126
No files matched your search
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user