mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-10-17 02:45:05 +00:00
Compare commits
2 Commits
15735af476
...
2cf8beae7a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2cf8beae7a | ||
|
|
4022f206e4 |
7
.github/actions/build-simulator/action.yml
vendored
7
.github/actions/build-simulator/action.yml
vendored
@ -40,6 +40,13 @@ runs:
|
||||
uses: jwlawson/actions-setup-cmake@v2
|
||||
with:
|
||||
cmake-version: '3.31.x'
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install mbedtls codegen Python dependencies
|
||||
shell: bash
|
||||
run: pip install -r Libraries/mbedtls/scripts/driver.requirements.txt
|
||||
- name: "Prepare Project"
|
||||
shell: bash
|
||||
run: cmake -S ./ -B buildsim
|
||||
|
||||
@ -33,8 +33,15 @@ sdkconfig.CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
|
||||
sdkconfig.CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
|
||||
sdkconfig.CONFIG_SLAVE_IDF_TARGET_ESP32C6=y
|
||||
sdkconfig.CONFIG_ESP_HOSTED_HOST_TRANSPORT_BUS_SDIO=y
|
||||
# esp_hosted 3.x ships a native pin/reset-GPIO preset for this exact board.
|
||||
sdkconfig.CONFIG_ESP32P4_TAB5_C6_BOARD=y
|
||||
sdkconfig.CONFIG_ESP_HOSTED_MEMPOOL_PREFER_SPIRAM=y
|
||||
sdkconfig.CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_CLK_SLOT_1=12
|
||||
sdkconfig.CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_CMD_SLOT_1=13
|
||||
sdkconfig.CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_D0_SLOT_1=11
|
||||
sdkconfig.CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_D1_4BIT_BUS_SLOT_1=10
|
||||
sdkconfig.CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_D2_4BIT_BUS_SLOT_1=9
|
||||
sdkconfig.CONFIG_ESP_HOSTED_PRIV_SDIO_PIN_D3_4BIT_BUS_SLOT_1=8
|
||||
sdkconfig.CONFIG_ESP_HOSTED_SDIO_GPIO_RESET_SLAVE=15
|
||||
sdkconfig.CONFIG_ESP_SDIO_GPIO_RESET_SLAVE=15
|
||||
# ESP-NOW bridge (EspNowBackendHosted.cpp) registers 6 custom-RPC handlers (4 resp + 2 event); default cap is 3
|
||||
sdkconfig.CONFIG_ESP_HOSTED_HOST_FEAT_PEER_DATA_MAX_CUSTOM_MSG_HANDLERS=8
|
||||
# Performance: larger L2 cache reduces PSRAM stalls for draw/DPI buffers
|
||||
|
||||
@ -3,5 +3,5 @@ file(GLOB_RECURSE SOURCE_FILES source/*.c*)
|
||||
idf_component_register(
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS "source"
|
||||
REQUIRES TactilityKernel TactilityFreeRtos bq24295-module driver
|
||||
REQUIRES TactilityKernel TactilityFreeRtos bq24295-module driver esp_driver_gpio
|
||||
)
|
||||
|
||||
@ -156,19 +156,17 @@ static void getKey(uint8_t key[32]) {
|
||||
// psa_crypto_init() is safe to call more than once (subsequent calls are a cheap no-op); ESP-IDF
|
||||
// calls it during startup already, but the simulator has no equivalent, so call it here too
|
||||
// rather than depend on init order across callers.
|
||||
static void ensure_psa_crypto_init() {
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
psa_crypto_init();
|
||||
initialized = true;
|
||||
}
|
||||
static psa_status_t ensure_psa_crypto_init() {
|
||||
return psa_crypto_init();
|
||||
}
|
||||
|
||||
void crypt_get_iv(const void* data, size_t dataLength, uint8_t iv[16]) {
|
||||
ensure_psa_crypto_init();
|
||||
check(ensure_psa_crypto_init() == PSA_SUCCESS);
|
||||
uint8_t hash[32];
|
||||
size_t hash_length;
|
||||
psa_hash_compute(PSA_ALG_SHA_256, static_cast<const uint8_t*>(data), dataLength, hash, sizeof(hash), &hash_length);
|
||||
check(psa_hash_compute(PSA_ALG_SHA_256, static_cast<const uint8_t*>(data),
|
||||
dataLength, hash, sizeof(hash), &hash_length) == PSA_SUCCESS);
|
||||
check(hash_length == sizeof(hash));
|
||||
memcpy(iv, hash, 16);
|
||||
mbedtls_platform_zeroize(hash, sizeof(hash));
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ idf_component_register(
|
||||
|
||||
if (DEFINED ENV{ESP_IDF_VERSION})
|
||||
GET_PROPERTY_FILE_CONTENT("${CMAKE_CURRENT_LIST_DIR}/../../sdkconfig" sdkconfig_text)
|
||||
GET_PROPERTY_VALUE(sdkconfig_text "CONFIG_ESP_HOSTED_HOST" esp_host_enabled "n")
|
||||
GET_PROPERTY_VALUE(sdkconfig_text "CONFIG_ESP_HOSTED_ENABLED" esp_host_enabled "n")
|
||||
if (esp_host_enabled STREQUAL "y")
|
||||
idf_component_optional_requires(PRIVATE espressif__esp_hosted)
|
||||
endif ()
|
||||
|
||||
@ -3,5 +3,5 @@
|
||||
struct FirmwareOps;
|
||||
|
||||
/** @return the esp_hosted co-processor FirmwareOps implementation. Only declared/linked when
|
||||
* CONFIG_ESP_HOSTED_HOST - callers (esp32_wifi.cpp) must guard with the same #if. */
|
||||
* CONFIG_SLAVE_SOC_WIFI_SUPPORTED - callers (esp32_wifi.cpp) must guard with the same #if. */
|
||||
const FirmwareOps* esp32_esp_hosted_ota_get_ops();
|
||||
|
||||
@ -172,5 +172,18 @@ extern size_t active_hid_rpt_map_len; // esp32_ble_hid.cpp
|
||||
extern uint16_t hid_appearance; // esp32_ble_hid.cpp
|
||||
extern BleHidProfile current_hid_profile; // esp32_ble_hid.cpp
|
||||
|
||||
// ---- HCI gate (ble_hci_gate.c) — P4/esp-hosted only ----
|
||||
// Controls whether hci_rx_handler forwards packets to NimBLE.
|
||||
// Set true after nimble_port_init(), false before nimble_port_stop().
|
||||
#if defined(CONFIG_ESP_HOSTED_ENABLED)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void ble_hci_gate_set_active(bool active);
|
||||
bool ble_hci_gate_wait_idle(int max_ms);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // CONFIG_ESP_HOSTED_ENABLED
|
||||
|
||||
#endif // CONFIG_BT_NIMBLE_ENABLED
|
||||
|
||||
142
Platforms/platform-esp32/source/drivers/bluetooth/ble_hci_gate.c
Normal file
142
Platforms/platform-esp32/source/drivers/bluetooth/ble_hci_gate.c
Normal file
@ -0,0 +1,142 @@
|
||||
// ble_hci_gate.c — Strong override of the weak hci_rx_handler from vhci_drv.c.
|
||||
// Gates HCI packet delivery so packets are silently dropped when NimBLE is not
|
||||
// initialised, preventing null-npl_funcs crashes during radio teardown (P4 only).
|
||||
//
|
||||
// On ESP32-P4, sdio_process_rx_task runs independently of the NimBLE host and can
|
||||
// deliver an HCI packet after nimble_port_deinit() has zeroed npl_funcs.
|
||||
// dispatch_disable() calls ble_hci_gate_set_active(false) + ble_hci_gate_wait_idle()
|
||||
// before touching NimBLE, ensuring no in-flight or future hci_rx_handler call can
|
||||
// dereference NimBLE internals.
|
||||
|
||||
#include <sdkconfig.h>
|
||||
#if defined(CONFIG_BT_NIMBLE_ENABLED) && defined(CONFIG_ESP_HOSTED_ENABLED)
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdatomic.h>
|
||||
#include <string.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_err.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
// NimBLE transport + HCI
|
||||
#include <nimble/transport.h>
|
||||
#include <nimble/hci_common.h>
|
||||
#include <os/os_mbuf.h>
|
||||
|
||||
// H4 packet type indicators (same values used in vhci_drv.c)
|
||||
#define HCI_H4_EVT 0x04
|
||||
#define HCI_H4_ACL 0x02
|
||||
|
||||
// Local defines from vhci_drv.c (not exported by any header)
|
||||
#define BLE_HCI_EVENT_HDR_LEN (2)
|
||||
|
||||
static const char* TAG = "ble_hci_gate";
|
||||
|
||||
// ---- Gate state (zero-init = gate closed until dispatch_enable opens it) ----
|
||||
static atomic_bool s_hci_active = ATOMIC_VAR_INIT(false);
|
||||
static atomic_int s_hci_refcount = ATOMIC_VAR_INIT(0);
|
||||
|
||||
void ble_hci_gate_set_active(bool active) {
|
||||
atomic_store_explicit(&s_hci_active, active, memory_order_seq_cst);
|
||||
}
|
||||
|
||||
// Spin-wait until all in-flight hci_rx_handler calls complete (max_ms timeout).
|
||||
// Returns true if drained within the timeout.
|
||||
bool ble_hci_gate_wait_idle(int max_ms) {
|
||||
for (int elapsed = 0; elapsed < max_ms; elapsed++) {
|
||||
if (atomic_load_explicit(&s_hci_refcount, memory_order_acquire) == 0)
|
||||
return true;
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
return (atomic_load_explicit(&s_hci_refcount, memory_order_acquire) == 0);
|
||||
}
|
||||
|
||||
// Strong override — replaces the H_WEAK_REF hci_rx_handler in vhci_drv.c.
|
||||
// All four esp-hosted transport drivers (SDIO, SPI, SPI-HD, UART) call this symbol.
|
||||
int hci_rx_handler(uint8_t *buf, size_t buf_len) {
|
||||
// Fast path: gate closed — NimBLE not ready, drop silently
|
||||
if (!atomic_load_explicit(&s_hci_active, memory_order_acquire))
|
||||
return ESP_OK;
|
||||
|
||||
// Hold a reference so dispatch_disable() waits for us to finish
|
||||
atomic_fetch_add_explicit(&s_hci_refcount, 1, memory_order_acquire);
|
||||
|
||||
// Double-check: gate may have closed between the first check and the increment
|
||||
if (!atomic_load_explicit(&s_hci_active, memory_order_acquire)) {
|
||||
atomic_fetch_sub_explicit(&s_hci_refcount, 1, memory_order_release);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// ---- Original vhci_drv.c (NimBLE branch) logic ----
|
||||
uint8_t *data = buf;
|
||||
uint32_t len_total_read = buf_len;
|
||||
int rc;
|
||||
|
||||
if (data[0] == HCI_H4_EVT) {
|
||||
uint8_t *evbuf;
|
||||
int totlen = BLE_HCI_EVENT_HDR_LEN + data[2];
|
||||
|
||||
if (totlen > UINT8_MAX + BLE_HCI_EVENT_HDR_LEN) {
|
||||
ESP_LOGE(TAG, "Rx: len[%d] > max INT, drop", totlen);
|
||||
atomic_fetch_sub_explicit(&s_hci_refcount, 1, memory_order_release);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (totlen > MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE)) {
|
||||
ESP_LOGE(TAG, "Rx: len[%d] > max BLE, drop", totlen);
|
||||
atomic_fetch_sub_explicit(&s_hci_refcount, 1, memory_order_release);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (data[1] == BLE_HCI_EVCODE_HW_ERROR) {
|
||||
ESP_LOGE(TAG, "Rx: HW_ERROR");
|
||||
atomic_fetch_sub_explicit(&s_hci_refcount, 1, memory_order_release);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if ((data[1] == BLE_HCI_EVCODE_LE_META) &&
|
||||
(data[3] == BLE_HCI_LE_SUBEV_ADV_RPT ||
|
||||
data[3] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) {
|
||||
evbuf = ble_transport_alloc_evt(1);
|
||||
if (!evbuf) {
|
||||
ESP_LOGW(TAG, "Rx: Drop ADV Report: OOM (not fatal)");
|
||||
atomic_fetch_sub_explicit(&s_hci_refcount, 1, memory_order_release);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
} else {
|
||||
evbuf = ble_transport_alloc_evt(0);
|
||||
if (!evbuf) {
|
||||
ESP_LOGE(TAG, "Rx: transport_alloc_evt(0) failed");
|
||||
atomic_fetch_sub_explicit(&s_hci_refcount, 1, memory_order_release);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
memset(evbuf, 0, sizeof *evbuf);
|
||||
memcpy(evbuf, &data[1], totlen);
|
||||
rc = ble_transport_to_hs_evt(evbuf);
|
||||
if (rc) {
|
||||
ESP_LOGE(TAG, "Rx: transport_to_hs_evt failed");
|
||||
atomic_fetch_sub_explicit(&s_hci_refcount, 1, memory_order_release);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
} else if (data[0] == HCI_H4_ACL) {
|
||||
struct os_mbuf *m = ble_transport_alloc_acl_from_ll();
|
||||
if (!m) {
|
||||
ESP_LOGE(TAG, "Rx: alloc_acl_from_ll failed");
|
||||
atomic_fetch_sub_explicit(&s_hci_refcount, 1, memory_order_release);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if ((rc = os_mbuf_append(m, &data[1], len_total_read - 1)) != 0) {
|
||||
ESP_LOGE(TAG, "Rx: os_mbuf_append failed; rc=%d", rc);
|
||||
os_mbuf_free_chain(m);
|
||||
atomic_fetch_sub_explicit(&s_hci_refcount, 1, memory_order_release);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ble_transport_to_hs_acl(m);
|
||||
}
|
||||
|
||||
atomic_fetch_sub_explicit(&s_hci_refcount, 1, memory_order_release);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif // CONFIG_BT_NIMBLE_ENABLED && CONFIG_ESP_HOSTED_ENABLED
|
||||
@ -29,9 +29,11 @@ constexpr auto* TAG = "esp32_ble";
|
||||
#include <tactility/log.h>
|
||||
#include <esp_timer.h>
|
||||
|
||||
#if defined(CONFIG_ESP_HOSTED_HOST)
|
||||
#if defined(CONFIG_ESP_HOSTED_ENABLED)
|
||||
#include <esp_hosted.h>
|
||||
#include <esp_hosted_bt_host_stack.h>
|
||||
extern "C" {
|
||||
#include <esp_hosted_misc.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
// ble_store_config_init() is not declared in the public header in some IDF versions.
|
||||
@ -679,16 +681,15 @@ static void dispatch_enable(BleCtx* ctx) {
|
||||
ble_publish_event(ctx->device, e);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ESP_HOSTED_HOST)
|
||||
// Over esp_hosted, the co-processor's BT controller only comes up via
|
||||
// esp_hosted_bt_host_stack_setup() below, which needs the SDIO/SPI transport already up -
|
||||
// BT can auto-enable before Wi-Fi has driven that bring-up, so (re)connect here first.
|
||||
#if defined(CONFIG_ESP_HOSTED_ENABLED)
|
||||
if (esp_hosted_connect_to_slave() != ESP_OK) {
|
||||
LOG_W(TAG, "esp_hosted_connect_to_slave failed");
|
||||
}
|
||||
esp_hosted_bt_host_stack_cfg_t hosted_bt_cfg = ESP_HOSTED_BT_HOST_STACK_CONFIG_DEFAULT();
|
||||
if (esp_hosted_bt_host_stack_setup(&hosted_bt_cfg) != ESP_OK) {
|
||||
LOG_W(TAG, "esp_hosted_bt_host_stack_setup failed");
|
||||
if (esp_hosted_bt_controller_init() != ESP_OK) {
|
||||
LOG_W(TAG, "esp_hosted_bt_controller_init failed");
|
||||
}
|
||||
if (esp_hosted_bt_controller_enable() != ESP_OK) {
|
||||
LOG_W(TAG, "esp_hosted_bt_controller_enable failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -759,6 +760,9 @@ static void dispatch_enable(BleCtx* ctx) {
|
||||
ble_svc_gap_device_name_set(ctx->device_name);
|
||||
ble_att_set_preferred_mtu(BLE_ATT_MTU_MAX);
|
||||
|
||||
#if defined(CONFIG_ESP_HOSTED_ENABLED)
|
||||
ble_hci_gate_set_active(true); // Open gate: NimBLE transport pool is ready
|
||||
#endif
|
||||
// Drain any stale "done" signal left over from a previous cycle (e.g. if the
|
||||
// last dispatch_disable() timed out waiting on it — see xSemaphoreTake below
|
||||
// with pdMS_TO_TICKS(2000)) so dispatch_disable() only ever consumes the
|
||||
@ -789,9 +793,9 @@ static void dispatch_disable(BleCtx* ctx) {
|
||||
// Blocking: waits for nimble_port_run() to exit.
|
||||
// Do NOT call ble_gap_adv_stop()/disc_cancel() before — if controller is
|
||||
// unresponsive they generate more HCI timeouts before the stop takes effect.
|
||||
// The HCI link must stay bound here: nimble_port_stop() → ble_hs_stop() sends
|
||||
// The HCI gate must stay OPEN here: nimble_port_stop() → ble_hs_stop() sends
|
||||
// HCI commands and needs to receive the command-complete events back from the
|
||||
// controller. Unbinding before this point starves NimBLE of those events,
|
||||
// controller. Closing the gate before this point starves NimBLE of those events,
|
||||
// causing HCI timeouts and a cascade of resets that crash in ble_hs_timer_sched.
|
||||
nimble_port_stop();
|
||||
// nimble_port_stop()'s internal semaphore only confirms the stop sentinel event was
|
||||
@ -806,17 +810,27 @@ static void dispatch_disable(BleCtx* ctx) {
|
||||
LOG_W(TAG, "host task did not signal completion in time");
|
||||
}
|
||||
}
|
||||
#if defined(CONFIG_ESP_HOSTED_HOST)
|
||||
// Unbind before nimble_port_deinit() zeros npl_funcs. Unlike the old ble_hci_gate.c this
|
||||
// repo carried for esp_hosted 2.x, esp_hosted 3.x exposes no drain/wait-for-in-flight
|
||||
// primitive here, so a packet already inside the RX callback at this exact moment is a
|
||||
// small theoretical race this migration cannot close without patching esp_hosted itself.
|
||||
if (esp_hosted_bt_host_stack_teardown() != ESP_OK) {
|
||||
LOG_W(TAG, "esp_hosted_bt_host_stack_teardown failed");
|
||||
#if defined(CONFIG_ESP_HOSTED_ENABLED)
|
||||
// Close the gate NOW — after nimble_port_stop() returns the NimBLE host task has
|
||||
// exited and nimble_port_deinit() is about to zero npl_funcs. Any HCI packet
|
||||
// arriving after this point must not reach ble_transport_alloc_evt().
|
||||
ble_hci_gate_set_active(false);
|
||||
if (!ble_hci_gate_wait_idle(20)) {
|
||||
LOG_W(TAG, "HCI gate drain timed out");
|
||||
}
|
||||
#endif
|
||||
nimble_port_deinit();
|
||||
|
||||
#if defined(CONFIG_ESP_HOSTED_ENABLED)
|
||||
// Symmetric with the enable-side esp_hosted_bt_controller_init/enable() calls.
|
||||
if (esp_hosted_bt_controller_disable() != ESP_OK) {
|
||||
LOG_W(TAG, "esp_hosted_bt_controller_disable failed");
|
||||
}
|
||||
if (esp_hosted_bt_controller_deinit(true) != ESP_OK) {
|
||||
LOG_W(TAG, "esp_hosted_bt_controller_deinit failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
ctx->spp_conn_handle.store(BLE_HS_CONN_HANDLE_NONE);
|
||||
ctx->spp_active.store(false);
|
||||
ctx->midi_conn_handle.store(BLE_HS_CONN_HANDLE_NONE);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ESP_HOSTED_HOST)
|
||||
#if defined(CONFIG_SLAVE_SOC_WIFI_SUPPORTED)
|
||||
|
||||
#include <tactility/drivers/esp32_esp_hosted_ota.h>
|
||||
#include <tactility/drivers/wifi.h>
|
||||
@ -251,4 +251,4 @@ const FirmwareOps* esp32_esp_hosted_ota_get_ops() {
|
||||
return &firmwareOps;
|
||||
}
|
||||
|
||||
#endif // CONFIG_ESP_HOSTED_HOST
|
||||
#endif // CONFIG_SLAVE_SOC_WIFI_SUPPORTED
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
#include <TactilityCpp/Allocator.h>
|
||||
|
||||
#if defined(CONFIG_ESP_HOSTED_HOST)
|
||||
#if defined(CONFIG_SLAVE_SOC_WIFI_SUPPORTED)
|
||||
#include <tactility/drivers/esp32_esp_hosted_ota.h>
|
||||
#endif
|
||||
|
||||
@ -583,7 +583,7 @@ error_t api_get_firmware_ops(Device* /*device*/, const FirmwareOps** ops, void**
|
||||
if (ops == nullptr || ctx == nullptr) {
|
||||
return ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
#if defined(CONFIG_ESP_HOSTED_HOST)
|
||||
#if defined(CONFIG_SLAVE_SOC_WIFI_SUPPORTED)
|
||||
// Only meaningful on a hosted board (P4+C6/C5 etc.) - this wifi device is backed by a real
|
||||
// co-processor with its own updatable firmware there. On a native (non-hosted) chip, this
|
||||
// device's "radio" is the chip's own built-in WiFi, nothing to update via this interface.
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include <Tactility/file/File.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
@ -195,7 +196,10 @@ static bool findOrCreateDirectoryInternal(const std::string& path, mode_t mode)
|
||||
return S_ISDIR(dir_stat.st_mode);
|
||||
}
|
||||
|
||||
return mkdir(path.c_str(), mode) == 0;
|
||||
if (mkdir(path.c_str(), mode) == 0) {
|
||||
return true;
|
||||
}
|
||||
return errno == EEXIST && stat(path.c_str(), &dir_stat) == 0 && S_ISDIR(dir_stat.st_mode);
|
||||
}
|
||||
|
||||
std::string getLastPathSegment(const std::string& path) {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ESP_HOSTED_HOST)
|
||||
#if defined(CONFIG_SLAVE_SOC_WIFI_SUPPORTED)
|
||||
|
||||
#include <Tactility/service/espnow/EspNowBackend.h>
|
||||
#include <Tactility/service/espnow/EspNowHostedTransport.h>
|
||||
@ -310,4 +310,4 @@ uint32_t getVersion() {
|
||||
|
||||
}
|
||||
|
||||
#endif // CONFIG_ESP_HOSTED_HOST
|
||||
#endif // CONFIG_SLAVE_SOC_WIFI_SUPPORTED
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SOC_WIFI_SUPPORTED) && !defined(CONFIG_ESP_HOSTED_HOST)
|
||||
#if defined(CONFIG_SOC_WIFI_SUPPORTED) && !defined(CONFIG_SLAVE_SOC_WIFI_SUPPORTED)
|
||||
|
||||
#include <Tactility/service/espnow/EspNowBackend.h>
|
||||
#include <Tactility/service/wifi/Wifi.h>
|
||||
@ -205,4 +205,4 @@ uint32_t getVersion() {
|
||||
|
||||
}
|
||||
|
||||
#endif // CONFIG_SOC_WIFI_SUPPORTED && !CONFIG_ESP_HOSTED_HOST
|
||||
#endif // CONFIG_SOC_WIFI_SUPPORTED && !CONFIG_SLAVE_SOC_WIFI_SUPPORTED
|
||||
|
||||
@ -6,7 +6,7 @@ dependencies:
|
||||
rules:
|
||||
- if: "target in [esp32s3, esp32c6, esp32p4]"
|
||||
espressif/esp_hosted:
|
||||
version: "3.0.7"
|
||||
version: "2.12.11"
|
||||
rules:
|
||||
- if: "target == esp32p4"
|
||||
espressif/esp_wifi_remote:
|
||||
|
||||
@ -425,10 +425,7 @@ def write_bluetooth_variables(output_file, device_properties: dict):
|
||||
output_file.write("CONFIG_BT_NIMBLE_ENABLED=y\n")
|
||||
if idf_target == "esp32p4":
|
||||
output_file.write("CONFIG_BT_NIMBLE_TRANSPORT_UART=n\n")
|
||||
# esp_hosted 3.0 removed the legacy ESP_HOSTED_ENABLE_BT_NIMBLE knob in favor
|
||||
# of a stack-agnostic feature flag; the app binds NimBLE to it explicitly via
|
||||
# esp_hosted_bt_host_stack_setup() (see esp32_ble.cpp).
|
||||
output_file.write("CONFIG_ESP_HOSTED_HOST_FEAT_BT=y\n")
|
||||
output_file.write("CONFIG_ESP_HOSTED_ENABLE_BT_NIMBLE=y\n")
|
||||
# Move NimBLE host buffers to SPIRAM when available, regardless of target.
|
||||
# The default (INTERNAL) mode causes heap fragmentation after a disable+deinit
|
||||
# cycle, preventing a subsequent nimble_port_init() from allocating its buffers
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user