Files
2026-07-21 22:49:48 +02:00

110 lines
5.9 KiB
Plaintext

# ESP32 Platform Configuration
# Included by all ESP32-based boards (XIAO ESP32-C3, XIAO ESP32-C6, etc.)
# Only contains ESP32-specific settings — common BLE/Storage/Input is in zephcore_common.conf
#
# Include order: prj.conf → zephcore_common.conf → esp32_common.conf → <board>/board.conf
# ========== BLE: ESP32-specific controller settings ==========
# DLE managed internally by Espressif blob — no CONFIG_BT_CTLR_DATA_LENGTH_MAX
# TX power managed internally by Espressif blob — no CONFIG_BT_CTLR_TX_PWR_*
# Host privacy: ESP32-only override. Load-bearing for iOS on the Espressif
# controller (Zephyr #84182-class). nRF/MG24 keep privacy OFF.
#
# Root cause pinned 2026-06-15 by firmware BLE/SMP debug capture on shipping
# blob 19f979cfe6 (xiao_esp32s3, real iOS): with privacy OFF the SC pairing
# completes the full passkey + DHKey-check phase, the host hands the controller
# a valid LTK (HCI LTK Request Reply, status 0x00), then the controller fails
# to start link encryption — HCI Disconnect reason 0x3d (MIC failure), Encrypt
# Change status 0x1f. It is a bug in the Espressif controller's privacy-OFF
# Secure-Connections path (closed blob); the host did everything right (nRF runs
# the identical host SMP code and bonds with iOS privacy-OFF fine). Privacy ON
# keeps the controller on its working privacy-enabled SC path.
#
# Android "connect from app" is NOT sacrificed: ZephyrBLE advertises with
# BT_LE_ADV_OPT_USE_IDENTITY, so even with privacy ON we expose the stable
# identity address (no RPA) — the thing the Android companion needs. HW-
# confirmed: iOS pairs + syncs, normal disconnect 0x13.
CONFIG_BT_PRIVACY=y
# BLE thread stacks — ESP32 software BLE controller needs larger stacks.
# Zephyr 2026-Q1 added a synchronous sc_store() on the RX WQ in the
# identity-resolved path (commit 2c6c80ddf65) which pushes the LittleFS
# settings write onto the SMP callback chain. Default 2048 overflowed.
CONFIG_BT_TX_PROCESSOR_STACK_SIZE=4096
CONFIG_BT_RX_STACK_SIZE=4096
# Stack-overflow detection — xtensa has no MPU stack guard in Zephyr, so
# use the software sentinel. ARM boards rely on MPU_STACK_GUARD (already
# on via HW_STACK_PROTECTION) which is incompatible with this symbol.
CONFIG_STACK_SENTINEL=y
# BLE TX buffers — the Espressif BLE controller blob bursts more aggressively
# than the nRF softdevice and will deadlock the system workqueue if ACL TX
# buffers run dry (bt_hci_cmd_alloc(K_FOREVER) blocks the cooperative syswq).
# EVT_RX must strictly exceed ACL_TX (enforced by BUILD_ASSERT in buf.h).
CONFIG_BT_BUF_ACL_TX_COUNT=12
CONFIG_BT_L2CAP_TX_BUF_COUNT=12
CONFIG_BT_CONN_TX_MAX=12
CONFIG_BT_BUF_EVT_RX_COUNT=14
# BLE controller link-layer encryption — Zephyr 4.4.1 (commit 7f01467, "align
# esp32 controller knobs") re-gated this vendor default from unconditional
# `default y` to `default y if BT_CTLR_LE_ENC`. ESP32 BLE uses the EXTERNAL
# Espressif controller over HCI (BT_ESP32=y, BT_CTLR unset), so that gate is
# never satisfied -> the controller's LE encryption gets compiled out while host
# BT_SMP stays on. The controller then asserts (ke_event.c) the moment a peer
# begins pairing: advertising works, connect never completes (GH #34). Restore
# the pre-4.4.1 default. (Classic ESP32 / S3 / C3 controller; the C2/C5/C6/H2
# controller uses ESP32_BT_LE_SECURITY_ENABLE instead — set in those board.conf.)
CONFIG_ESP32_BT_CTLR_LE_SECURITY_ENABLE=y
# ========== Heap ==========
# ESP32 BLE stack requires larger heap (override zephcore_common 2KB default).
#
# 32768 was NOT enough and failed non-obviously. The Espressif controller
# allocates its exchange memory through esp_bt_malloc_func(), which the Zephyr
# port maps to k_malloc() (esp_heap_adapter.h, CONFIG_ESP_BT_HEAP_SYSTEM=y) —
# i.e. straight out of this pool. esp_bt_controller_init() asks for 0x7800 =
# 30720 bytes in ONE allocation: 93.75% of a 32 KB pool, leaving 2 KB for block
# overhead and every other k_malloc user that ran before bt_enable(). Boards
# that allocated little before BLE init happened to fit; ThinkNode M9 (display +
# colour overlay, STC8H keypad, LR1110) did not, and the blob asserted inside
# its own allocator instead of returning ESP_ERR_NO_MEM:
#
# BLE assert emi.c 164, param 00000000 00007800 <- (NULL, requested size)
#
# Zephyr's own driver anticipates this and prints "Consider increasing
# CONFIG_HEAP_MEM_POOL_SIZE" (drivers/bluetooth/hci/hci_esp32.c) — but only on
# the graceful path the blob does not take. Every ESP32 board was one
# allocation away from the same failure, so this is raised platform-wide.
#
# Headroom verified by build on all 12 shipped ESP32 boards: the S3/C3/C6 boards
# have 66-135 KB free internal DRAM and absorb this easily. ttgo_tbeam is the
# sole exception (99.45% DRAM, 768 B free) and overrides it back in its
# board.conf — see the note there.
CONFIG_HEAP_MEM_POOL_SIZE=65536
# ========== Flash ==========
# 4MB is standard for XIAO/LilyGo RISC-V boards.
# Station G2 (16MB) overrides in board.conf.
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# ========== BLE bonds: dedicated NVS partition (not /lfs) ==========
# Bonds live in their own `storage_partition` NVS region (defined per board in
# board.overlay), isolated from the /lfs LittleFS volume that holds identity/
# prefs/contacts. This overrides the file-backed default in zephcore_common.conf
# (loaded earlier): a busy bond store can no longer corrupt /lfs. Every ESP32
# board.overlay defines a storage_partition, so this is safe platform-wide.
CONFIG_SETTINGS_FILE=n
CONFIG_NVS=y
CONFIG_SETTINGS_NVS=y
# ========== Debug ==========
# CONFIG_ASSERT disabled for ESP32: Espressif's closed-source BLE controller
# blob leaves IRQs in a state that triggers false "Context switching while
# holding lock!" assertions in kswap.h. The BLE stack works correctly — the
# blob manages its own IRQ state internally. nRF52/nRF54L boards keep asserts
# via their platform configs; ESP32 relies on logging for debug.
# CONFIG_ASSERT=n (Zephyr default)