From 41a33fcd46a8110a2c2a5af1e34e1ac373986f37 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Fri, 21 Feb 2025 11:54:02 +0800 Subject: [PATCH 01/17] feat(ble): add printf and write with timestamp interface for ble log spi out (cherry picked from commit f8efa4cd80690579c0e4893d6c596f0cb2bacd7c) Co-authored-by: Zhou Xiao --- .../bt/common/ble_log/ble_log_spi_out.c | 56 +++++++++++++++++-- .../ble_log/include/ble_log/ble_log_spi_out.h | 2 + 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/components/bt/common/ble_log/ble_log_spi_out.c b/components/bt/common/ble_log/ble_log_spi_out.c index b9e4bf02f8..06a24c682d 100644 --- a/components/bt/common/ble_log/ble_log_spi_out.c +++ b/components/bt/common/ble_log/ble_log_spi_out.c @@ -176,8 +176,7 @@ IRAM_ATTR static void esp_timer_cb_flushout(void) if (trans_head->trans.length) { spi_out_append_trans(); } - } - else { + } else { // Restart flushout timer esp_timer_start_once(flushout_timer_handle, SPI_OUT_FLUSHOUT_TIMEOUT); } @@ -374,8 +373,7 @@ IRAM_ATTR void ble_log_spi_out_write(uint8_t source, const uint8_t *addr, uint16 const uint8_t tail = SPI_OUT_TAIL; // Write frame head first, then payload, finally frame tail - do - { + do { if (spi_out_write(head, 4) != 0) { loss_frame_cnt++; break; @@ -398,4 +396,54 @@ IRAM_ATTR void ble_log_spi_out_write(uint8_t source, const uint8_t *addr, uint16 return; } +IRAM_ATTR int ble_log_spi_out_printf(uint8_t source, const char *format, ...) +{ + // Get esp timestamp + uint32_t esp_ts = esp_timer_get_time(); + + // Get arguments + va_list args; + va_start(args, format); + + // Get len as ref to allocate heap memory + va_list args_copy; + va_copy(args_copy, args); + int len = vsnprintf(NULL, 0, format, args_copy); + va_end(args_copy); + + // Length validation + if ((len < 0) || (len > 0xFFFF)) { + va_end(args); + return -1; + } + + // Allocate memory + uint8_t *buffer = malloc(len + 1); + if (!buffer) { + va_end(args); + return -1; + } + + // Generate string + vsnprintf((char *)buffer, len + 1, format, args); + va_end(args); + + // Write to SPI + ble_log_spi_out_write(source, (const uint8_t *)&esp_ts, 4); + ble_log_spi_out_write(source, (const uint8_t *)buffer, len); + + // Release + free(buffer); + return 0; +} + +IRAM_ATTR void ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len) +{ + // Get esp timestamp + uint32_t esp_ts = esp_timer_get_time(); + + // Write to SPI + ble_log_spi_out_write(source, (const uint8_t *)&esp_ts, 4); + ble_log_spi_out_write(source, addr, len); +} #endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED diff --git a/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h b/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h index c2b5f8d8f3..7e3ad16624 100644 --- a/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h +++ b/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h @@ -29,5 +29,7 @@ void ble_log_spi_out_write(uint8_t source, const uint8_t *addr, uint16_t len); void ble_log_spi_out_write_esp(uint32_t len, const uint8_t *addr, bool end); void ble_log_spi_out_ts_sync_start(void); void ble_log_spi_out_ts_sync_stop(void); +int ble_log_spi_out_printf(uint8_t source, const char *format, ...); +void ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len); #endif // __BT_SPI_OUT_H__ From 231bf742b028fe7882b73e8fe98b7b7241b9bb7f Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Fri, 21 Feb 2025 16:55:11 +0800 Subject: [PATCH 02/17] fix(ble/bluedroid): Support SPI log output options for HCI --- components/bt/common/Kconfig.in | 7 +++++++ components/bt/common/include/bt_common.h | 9 ++++++++- components/bt/common/include/bt_user_config.h | 7 +++++++ .../bt/host/bluedroid/api/esp_bluedroid_hci.c | 9 ++++++++- components/bt/host/bluedroid/hci/hci_hal_h4.c | 7 +++++++ .../bt/host/nimble/esp-hci/src/esp_nimble_hci.c | 13 ++++++++++++- 6 files changed, 49 insertions(+), 3 deletions(-) diff --git a/components/bt/common/Kconfig.in b/components/bt/common/Kconfig.in index 74b201b12a..aeca13f266 100644 --- a/components/bt/common/Kconfig.in +++ b/components/bt/common/Kconfig.in @@ -12,6 +12,13 @@ config BT_BLE_LOG_SPI_OUT_ENABLED help Output ble logs to SPI bus +config BT_BLE_LOG_SPI_OUT_HCI_ENABLED + bool "Enable HCI log output to SPI" + depends on BT_BLE_LOG_SPI_OUT_ENABLED + default n + help + Enable logging of HCI packets to the SPI bus when BLE SPI log output is enabled. + config BT_BLE_LOG_SPI_OUT_QUEUE_SIZE int "Number of ble log async SPI output queues" depends on BT_BLE_LOG_SPI_OUT_ENABLED diff --git a/components/bt/common/include/bt_common.h b/components/bt/common/include/bt_common.h index 09e7fa50d0..6c3d1569eb 100644 --- a/components/bt/common/include/bt_common.h +++ b/components/bt/common/include/bt_common.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -84,6 +84,13 @@ #define BT_HCI_LOG_INCLUDED FALSE #endif +// HCI LOG TO SPI +#if UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED +#define BT_BLE_LOG_SPI_OUT_HCI_ENABLED UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED +#else +#define BT_BLE_LOG_SPI_OUT_HCI_ENABLED FALSE +#endif + #if UC_BT_HCI_LOG_DATA_BUFFER_SIZE #define HCI_LOG_DATA_BUFFER_SIZE UC_BT_HCI_LOG_DATA_BUFFER_SIZE #else diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index da153405ed..b76d4d3917 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -126,6 +126,13 @@ #define UC_BT_HCI_LOG_DEBUG_EN FALSE #endif +//HCI LOG TO SPI +#ifdef CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED +#define UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED TRUE +#else +#define UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED FALSE +#endif + #ifdef CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE #define UC_BT_HCI_LOG_DATA_BUFFER_SIZE CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE #else diff --git a/components/bt/host/bluedroid/api/esp_bluedroid_hci.c b/components/bt/host/bluedroid/api/esp_bluedroid_hci.c index 1676ae8824..0e6baf1118 100644 --- a/components/bt/host/bluedroid/api/esp_bluedroid_hci.c +++ b/components/bt/host/bluedroid/api/esp_bluedroid_hci.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,10 @@ #define LOG_TAG "HCI_API" +#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED + static esp_bluedroid_hci_driver_operations_t s_hci_driver_ops = { 0 }; esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *p_ops) @@ -63,6 +67,9 @@ void hci_host_send_packet(uint8_t *data, uint16_t len) #if (BT_HCI_LOG_INCLUDED == TRUE) bt_hci_log_record_hci_data(data[0], &data[1], len - 1); #endif +#if (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) + ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM, data, len); +#endif // (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) #if (BT_CONTROLLER_INCLUDED == TRUE) esp_vhci_host_send_packet(data, len); #else /* BT_CONTROLLER_INCLUDED == TRUE */ diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index 4c23f71bf9..a5b90a6901 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -41,6 +41,10 @@ #include "stack/hcimsgs.h" #include "hci_log/bt_hci_log.h" +#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED + #define HCI_BLE_EVENT 0x3e #define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2) #define PACKET_TYPE_TO_INDEX(type) ((type) - 1) @@ -567,6 +571,9 @@ void bt_record_hci_data(uint8_t *data, uint16_t len) static int host_recv_pkt_cb(uint8_t *data, uint16_t len) { +#if (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) + ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM, data, len); +#endif // (BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) //Target has packet to host, malloc new buffer for packet BT_HDR *pkt = NULL; #if (BLE_42_SCAN_EN == TRUE) diff --git a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c index 3c21ba9081..bc263d4b74 100644 --- a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c +++ b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,6 +24,10 @@ #include "bt_common.h" #include "hci_log/bt_hci_log.h" +#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED + #define NIMBLE_VHCI_TIMEOUT_MS 2000 #define BLE_HCI_EVENT_HDR_LEN (2) #define BLE_HCI_CMD_HDR_LEN (3) @@ -68,6 +72,9 @@ void esp_vhci_host_send_packet_wrapper(uint8_t *data, uint16_t len) #if (BT_HCI_LOG_INCLUDED == TRUE) bt_hci_log_record_hci_data(data[0], &data[1], len - 1); #endif +#if (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) + ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM, data, len); +#endif // (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) esp_vhci_host_send_packet(data, len); } @@ -219,6 +226,10 @@ static int dummy_host_rcv_pkt(uint8_t *data, uint16_t len) */ static int host_rcv_pkt(uint8_t *data, uint16_t len) { +#if (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) + ble_log_spi_out_write_with_ts(BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM, data, len); +#endif // (CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER) + bt_record_hci_data(data, len); if(!ble_hs_enabled_state) { From e323d22353b57dfbf8f1af1682bcf9c3206b31a7 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Sun, 23 Feb 2025 16:13:26 +0800 Subject: [PATCH 03/17] fix(ble/bluedroid): Added SPI output support for Bluedroid host log --- components/bt/common/Kconfig.in | 8 + .../bt/common/ble_log/ble_log_spi_out.c | 47 ++++++ .../ble_log/include/ble_log/ble_log_spi_out.h | 10 ++ components/bt/common/include/bt_common.h | 7 + components/bt/common/include/bt_user_config.h | 9 +- .../common/include/common/bt_trace.h | 154 ++++++++++++++++++ 6 files changed, 234 insertions(+), 1 deletion(-) diff --git a/components/bt/common/Kconfig.in b/components/bt/common/Kconfig.in index aeca13f266..08ae449869 100644 --- a/components/bt/common/Kconfig.in +++ b/components/bt/common/Kconfig.in @@ -19,6 +19,14 @@ config BT_BLE_LOG_SPI_OUT_HCI_ENABLED help Enable logging of HCI packets to the SPI bus when BLE SPI log output is enabled. +config BT_BLE_LOG_SPI_OUT_HOST_ENABLED + bool "Enable Host log output to SPI" + depends on BT_BLE_LOG_SPI_OUT_ENABLED + default n + help + This configuration applies to the logs of both Bluedroid Host and NimBLE Host. + When BLE SPI log output is enabled, this option allows host logs to be transmitted via SPI. + config BT_BLE_LOG_SPI_OUT_QUEUE_SIZE int "Number of ble log async SPI output queues" depends on BT_BLE_LOG_SPI_OUT_ENABLED diff --git a/components/bt/common/ble_log/ble_log_spi_out.c b/components/bt/common/ble_log/ble_log_spi_out.c index 06a24c682d..885fee17a8 100644 --- a/components/bt/common/ble_log/ble_log_spi_out.c +++ b/components/bt/common/ble_log/ble_log_spi_out.c @@ -437,6 +437,53 @@ IRAM_ATTR int ble_log_spi_out_printf(uint8_t source, const char *format, ...) return 0; } +IRAM_ATTR int ble_log_spi_out_printf_enh(uint8_t source, uint8_t level, const char *tag, const char *format, ...) +{ + // Get ESP timestamp + uint32_t esp_ts = esp_timer_get_time(); + + // Create log prefix in the format: "[level][tag] " + char prefix[32]; + int prefix_len = snprintf(prefix, sizeof(prefix), "[%d][%s] ", level, tag ? tag : "NULL"); + + // Compute the length of the formatted log message + va_list args; + va_start(args, format); + va_list args_copy; + va_copy(args_copy, args); + int log_len = vsnprintf(NULL, 0, format, args_copy); + va_end(args_copy); + + // Validate length + if (log_len < 0 || log_len > 0xFFFF) { + va_end(args); + return -1; + } + + // Compute total log length (prefix + formatted message) + int total_len = prefix_len + log_len; + + // Allocate memory for the complete log message + uint8_t *buffer = malloc(total_len + 1); + if (!buffer) { + va_end(args); + return -1; + } + + // Construct the final log message + memcpy(buffer, prefix, prefix_len); // Copy the prefix + vsnprintf((char *)(buffer + prefix_len), log_len + 1, format, args); + va_end(args); + + // Transmit log data via SPI + ble_log_spi_out_write(source, (const uint8_t *)&esp_ts, 4); + ble_log_spi_out_write(source, buffer, total_len); + + // Free allocated memory + free(buffer); + return 0; +} + IRAM_ATTR void ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len) { // Get esp timestamp diff --git a/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h b/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h index 7e3ad16624..ca167f8fb9 100644 --- a/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h +++ b/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h @@ -22,6 +22,15 @@ #define BLE_LOG_SPI_OUT_SOURCE_SYNC 0xFE #define BLE_LOG_SPI_OUT_SOURCE_LOSS 0xFF +// SPI Log Level Definitions +#define BLE_LOG_SPI_OUT_LEVEL_NONE 0 /*!< No log output */ +#define BLE_LOG_SPI_OUT_LEVEL_ERROR 1 /*!< Critical errors that SPI driver cannot recover from */ +#define BLE_LOG_SPI_OUT_LEVEL_WARN 2 /*!< Recoverable error conditions in SPI communication */ +#define BLE_LOG_SPI_OUT_LEVEL_INFO 3 /*!< Informational messages about SPI transactions */ +#define BLE_LOG_SPI_OUT_LEVEL_DEBUG 4 /*!< Detailed debug information, such as SPI register values */ +#define BLE_LOG_SPI_OUT_LEVEL_VERBOSE 5 /*!< Very detailed debugging logs, potentially flooding output */ +#define BLE_LOG_SPI_OUT_LEVEL_MAX 6 /*!< Number of SPI log levels supported */ + // Public functions void ble_log_spi_out_init(void); void ble_log_spi_out_deinit(void); @@ -30,6 +39,7 @@ void ble_log_spi_out_write_esp(uint32_t len, const uint8_t *addr, bool end); void ble_log_spi_out_ts_sync_start(void); void ble_log_spi_out_ts_sync_stop(void); int ble_log_spi_out_printf(uint8_t source, const char *format, ...); +int ble_log_spi_out_printf_enh(uint8_t source, uint8_t level, const char *tag, const char *format, ...); void ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len); #endif // __BT_SPI_OUT_H__ diff --git a/components/bt/common/include/bt_common.h b/components/bt/common/include/bt_common.h index 6c3d1569eb..300bbc6d85 100644 --- a/components/bt/common/include/bt_common.h +++ b/components/bt/common/include/bt_common.h @@ -91,6 +91,13 @@ #define BT_BLE_LOG_SPI_OUT_HCI_ENABLED FALSE #endif +// BLURDROID LOG TO SPI +#if UC_BT_BLE_LOG_SPI_OUT_HOST_ENABLED +#define BT_BLE_LOG_SPI_OUT_HOST_ENABLED UC_BT_BLE_LOG_SPI_OUT_HOST_ENABLED +#else +#define BT_BLE_LOG_SPI_OUT_HOST_ENABLED FALSE +#endif + #if UC_BT_HCI_LOG_DATA_BUFFER_SIZE #define HCI_LOG_DATA_BUFFER_SIZE UC_BT_HCI_LOG_DATA_BUFFER_SIZE #else diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index b76d4d3917..5632b5fe22 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -133,6 +133,13 @@ #define UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED FALSE #endif +//BLUEDROID LOG TO SPI +#ifdef CONFIG_BT_BLE_LOG_SPI_OUT_HOST_ENABLED +#define UC_BT_BLE_LOG_SPI_OUT_HOST_ENABLED TRUE +#else +#define UC_BT_BLE_LOG_SPI_OUT_HOST_ENABLED FALSE +#endif + #ifdef CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE #define UC_BT_HCI_LOG_DATA_BUFFER_SIZE CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE #else diff --git a/components/bt/host/bluedroid/common/include/common/bt_trace.h b/components/bt/host/bluedroid/common/include/common/bt_trace.h index 74b7f10574..8a115ae02a 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_trace.h +++ b/components/bt/host/bluedroid/common/include/common/bt_trace.h @@ -25,6 +25,9 @@ #include "stack/bt_types.h" #include "bt_common.h" +#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) +#include "ble_log/ble_log_spi_out.h" +#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t len) { uint16_t i; @@ -217,20 +220,83 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l /* Define tracing for BTM */ +#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) + +#define BTM_TRACE_ERROR(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_ERROR, "BT_BTM", fmt, ## args); \ + if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTM, ERROR)) BT_PRINT_E("BT_BTM", fmt, ## args); \ +} + +#define BTM_TRACE_WARNING(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_WARN, "BT_BTM", fmt, ## args); \ + if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTM, WARNING)) BT_PRINT_W("BT_BTM", fmt, ## args); \ +} + +#define BTM_TRACE_API(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_BTM", fmt, ## args); \ + if (btm_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTM, API)) BT_PRINT_I("BT_BTM", fmt, ## args); \ +} + +#define BTM_TRACE_EVENT(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_BTM", fmt, ## args); \ + if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTM, EVENT)) BT_PRINT_D("BT_BTM", fmt, ## args); \ +} + +#define BTM_TRACE_DEBUG(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_BTM", fmt, ## args); \ + if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTM, DEBUG)) BT_PRINT_D("BT_BTM", fmt, ## args); \ +} + +#else + #define BTM_TRACE_ERROR(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(BTM, ERROR)) BT_PRINT_E("BT_BTM", fmt, ## args);} #define BTM_TRACE_WARNING(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(BTM, WARNING)) BT_PRINT_W("BT_BTM", fmt, ## args);} #define BTM_TRACE_API(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(BTM,API)) BT_PRINT_I("BT_BTM", fmt, ## args);} #define BTM_TRACE_EVENT(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(BTM,EVENT)) BT_PRINT_D("BT_BTM", fmt, ## args);} #define BTM_TRACE_DEBUG(fmt, args...) {if (btm_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(BTM,DEBUG)) BT_PRINT_D("BT_BTM", fmt, ## args);} +#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) + /* Define tracing for the L2CAP unit */ +#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) + +#define L2CAP_TRACE_ERROR(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_ERROR, "BT_L2CAP", fmt, ## args); \ + if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(L2CAP, ERROR)) BT_PRINT_E("BT_L2CAP", fmt, ## args); \ +} + +#define L2CAP_TRACE_WARNING(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_WARN, "BT_L2CAP", fmt, ## args); \ + if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(L2CAP, WARNING)) BT_PRINT_W("BT_L2CAP", fmt, ## args); \ +} + +#define L2CAP_TRACE_API(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_L2CAP", fmt, ## args); \ + if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(L2CAP, API)) BT_PRINT_I("BT_L2CAP", fmt, ## args); \ +} + +#define L2CAP_TRACE_EVENT(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_L2CAP", fmt, ## args); \ + if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(L2CAP, EVENT)) BT_PRINT_D("BT_L2CAP", fmt, ## args); \ +} + +#define L2CAP_TRACE_DEBUG(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_L2CAP", fmt, ## args); \ + if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(L2CAP, DEBUG)) BT_PRINT_D("BT_L2CAP", fmt, ## args); \ +} + +#else + #define L2CAP_TRACE_ERROR(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(L2CAP, ERROR)) BT_PRINT_E("BT_L2CAP", fmt, ## args);} #define L2CAP_TRACE_WARNING(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(L2CAP, WARNING)) BT_PRINT_W("BT_L2CAP", fmt, ## args);} #define L2CAP_TRACE_API(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(L2CAP,API)) BT_PRINT_I("BT_L2CAP", fmt, ## args);} #define L2CAP_TRACE_EVENT(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(L2CAP,EVENT)) BT_PRINT_D("BT_L2CAP", fmt, ## args);} #define L2CAP_TRACE_DEBUG(fmt, args...) {if (l2cb.l2cap_trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(L2CAP,DEBUG)) BT_PRINT_D("BT_L2CAP", fmt, ## args);} +#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) + + /* Define tracing for the SDP unit */ #define SDP_TRACE_ERROR(fmt, args...) {if (sdp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SDP, ERROR)) BT_PRINT_E("BT_SDP", fmt, ## args);} @@ -248,11 +314,38 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l #define RFCOMM_TRACE_DEBUG(fmt, args...) {if (rfc_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(RFCOMM,DEBUG)) BT_PRINT_D("BT_RFCOMM", fmt, ## args);} /* Generic Access Profile traces */ +#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) + +#define GAP_TRACE_ERROR(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_ERROR, "BT_GAP", fmt, ## args); \ + if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GAP, ERROR)) BT_PRINT_E("BT_GAP", fmt, ## args); \ +} + +#define GAP_TRACE_WARNING(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_WARN, "BT_GAP", fmt, ## args); \ + if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GAP, WARNING)) BT_PRINT_W("BT_GAP", fmt, ## args); \ +} + +#define GAP_TRACE_API(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_GAP", fmt, ## args); \ + if (gap_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GAP, API)) BT_PRINT_I("BT_GAP", fmt, ## args); \ +} + +#define GAP_TRACE_EVENT(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_GAP", fmt, ## args); \ + if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GAP, EVENT)) BT_PRINT_D("BT_GAP", fmt, ## args); \ +} + +#else + #define GAP_TRACE_ERROR(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GAP, ERROR)) BT_PRINT_E("BT_GAP", fmt, ## args);} #define GAP_TRACE_API(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GAP,API)) BT_PRINT_I("BT_GAP", fmt, ## args);} #define GAP_TRACE_EVENT(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GAP,EVENT)) BT_PRINT_D("BT_GAP", fmt, ## args);} #define GAP_TRACE_WARNING(fmt, args...) {if (gap_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GAP, WARNING)) BT_PRINT_W("BT_GAP", fmt, ## args);} +#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) + + /* define traces for HID Host */ #define HIDH_TRACE_ERROR(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(HIDH, ERROR)) BT_PRINT_E("BT_HIDH", fmt, ## args);} #define HIDH_TRACE_WARNING(fmt, args...) {if (hh_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(HIDH, WARNING)) BT_PRINT_W("BT_HIDH", fmt, ## args);} @@ -347,20 +440,81 @@ static inline void trc_dump_buffer(const char *prefix, uint8_t *data, uint16_t l /* Define tracing for the ATT/GATT unit */ +#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) + +#define GATT_TRACE_ERROR(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_ERROR, "BT_GATT", fmt, ## args); \ + if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GATT, ERROR)) BT_PRINT_E("BT_GATT", fmt, ## args); \ +} + +#define GATT_TRACE_WARNING(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_WARN, "BT_GATT", fmt, ## args); \ + if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GATT, WARNING)) BT_PRINT_W("BT_GATT", fmt, ## args); \ +} + +#define GATT_TRACE_API(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_GATT", fmt, ## args); \ + if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GATT, API)) BT_PRINT_I("BT_GATT", fmt, ## args); \ +} + +#define GATT_TRACE_EVENT(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_GATT", fmt, ## args); \ + if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GATT, EVENT)) BT_PRINT_D("BT_GATT", fmt, ## args); \ +} + +#define GATT_TRACE_DEBUG(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_GATT", fmt, ## args); \ + if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(GATT, DEBUG)) BT_PRINT_D("BT_GATT", fmt, ## args); \ +} + +#else + #define GATT_TRACE_ERROR(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(GATT, ERROR)) BT_PRINT_E("BT_GATT", fmt, ## args);} #define GATT_TRACE_WARNING(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(GATT, WARNING)) BT_PRINT_W("BT_GATT", fmt, ## args);} #define GATT_TRACE_API(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(GATT,API)) BT_PRINT_I("BT_GATT", fmt, ## args);} #define GATT_TRACE_EVENT(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(GATT,EVENT)) BT_PRINT_D("BT_GATT", fmt, ## args);} #define GATT_TRACE_DEBUG(fmt, args...) {if (gatt_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(GATT,DEBUG)) BT_PRINT_D("BT_GATT", fmt, ## args);} +#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) + /* Define tracing for the SMP unit */ +#if (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) + +#define SMP_TRACE_ERROR(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_ERROR, "BT_SMP", fmt, ## args); \ + if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SMP, ERROR)) BT_PRINT_E("BT_SMP", fmt, ## args); \ +} + +#define SMP_TRACE_WARNING(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_WARN, "BT_SMP", fmt, ## args); \ + if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(SMP, WARNING)) BT_PRINT_W("BT_SMP", fmt, ## args); \ +} + +#define SMP_TRACE_API(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_INFO, "BT_SMP", fmt, ## args); \ + if (smp_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(SMP, API)) BT_PRINT_I("BT_SMP", fmt, ## args); \ +} + +#define SMP_TRACE_EVENT(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_SMP", fmt, ## args); \ + if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(SMP, EVENT)) BT_PRINT_D("BT_SMP", fmt, ## args); \ +} + +#define SMP_TRACE_DEBUG(fmt, args...) { \ + ble_log_spi_out_printf_enh(BLE_LOG_SPI_OUT_SOURCE_BLUEDROID, BLE_LOG_SPI_OUT_LEVEL_DEBUG, "BT_SMP", fmt, ## args); \ + if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(SMP, DEBUG)) BT_PRINT_D("BT_SMP", fmt, ## args); \ +} + +#else + #define SMP_TRACE_ERROR(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_ERROR && BT_LOG_LEVEL_CHECK(SMP, ERROR)) BT_PRINT_E("BT_SMP", fmt, ## args);} #define SMP_TRACE_WARNING(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_WARNING && BT_LOG_LEVEL_CHECK(SMP, WARNING)) BT_PRINT_W("BT_SMP", fmt, ## args);} #define SMP_TRACE_API(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_API && BT_LOG_LEVEL_CHECK(SMP,API)) BT_PRINT_I("BT_SMP", fmt, ## args);} #define SMP_TRACE_EVENT(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_EVENT && BT_LOG_LEVEL_CHECK(SMP,EVENT)) BT_PRINT_D("BT_SMP", fmt, ## args);} #define SMP_TRACE_DEBUG(fmt, args...) {if (smp_cb.trace_level >= BT_TRACE_LEVEL_DEBUG && BT_LOG_LEVEL_CHECK(SMP,DEBUG)) BT_PRINT_D("BT_SMP", fmt, ## args);} +#endif // (BT_BLE_LOG_SPI_OUT_HOST_ENABLED && !CLASSIC_BT_INCLUDED) extern UINT8 btif_trace_level; From 3051078939e2715b66a1efcd1efff24654019260 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Wed, 26 Feb 2025 12:27:22 +0800 Subject: [PATCH 04/17] fix(ble): fix flushout and sync issues --- components/bt/common/ble_log/ble_log_spi_out.c | 18 ++++++++++++------ .../ble_log/include/ble_log/ble_log_spi_out.h | 2 ++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/components/bt/common/ble_log/ble_log_spi_out.c b/components/bt/common/ble_log/ble_log_spi_out.c index 885fee17a8..a85fc3bfc2 100644 --- a/components/bt/common/ble_log/ble_log_spi_out.c +++ b/components/bt/common/ble_log/ble_log_spi_out.c @@ -176,8 +176,10 @@ IRAM_ATTR static void esp_timer_cb_flushout(void) if (trans_head->trans.length) { spi_out_append_trans(); } - } else { - // Restart flushout timer + } + + // Restart flushout timer if not active + if (!esp_timer_is_active(flushout_timer_handle)) { esp_timer_start_once(flushout_timer_handle, SPI_OUT_FLUSHOUT_TIMEOUT); } @@ -193,6 +195,9 @@ IRAM_ATTR static void esp_timer_cb_ts_sync(void) uint32_t lc_ts = 0; uint32_t esp_ts = 0; + // Toggle sync IO + sync_io_level = !sync_io_level; + // Enter critical portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; portENTER_CRITICAL_SAFE(&spinlock); @@ -205,7 +210,7 @@ IRAM_ATTR static void esp_timer_cb_ts_sync(void) lc_ts = r_os_cputime_get32(); #endif // CONFIG_IDF_TARGET_ESP32C2 - // Toggle Sync IO + // Set sync IO level gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, (uint32_t)sync_io_level); // Get ESP timestamp @@ -219,9 +224,6 @@ IRAM_ATTR static void esp_timer_cb_ts_sync(void) memcpy(sync_frame + 1, &lc_ts, sizeof(lc_ts)); memcpy(sync_frame + 5, &esp_ts, sizeof(esp_ts)); ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_SYNC, sync_frame, 9); - - // Update IO level - sync_io_level = !sync_io_level; } #endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED @@ -351,6 +353,10 @@ void ble_log_spi_out_ts_sync_stop(void) if (esp_timer_is_active(ts_sync_timer_handle)) { esp_timer_stop(ts_sync_timer_handle); } + + // Set sync IO to low level + sync_io_level = 0; + gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, (uint32_t)sync_io_level); } } #endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED diff --git a/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h b/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h index ca167f8fb9..c1a4506637 100644 --- a/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h +++ b/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h @@ -6,6 +6,7 @@ #ifndef __BT_SPI_OUT_H__ #define __BT_SPI_OUT_H__ +#include #include #include "driver/spi_master.h" #include "driver/gpio.h" @@ -19,6 +20,7 @@ #define BLE_LOG_SPI_OUT_SOURCE_NIMBLE 3 #define BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM 4 #define BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM 5 +#define BLE_LOG_SPI_OUT_SOURCE_USER 0x10 #define BLE_LOG_SPI_OUT_SOURCE_SYNC 0xFE #define BLE_LOG_SPI_OUT_SOURCE_LOSS 0xFF From cda345ffc72633000758e08e63f8fafb1cde7416 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Tue, 25 Feb 2025 17:57:15 +0800 Subject: [PATCH 05/17] fix(ble): add feed wdts during ble log dump for ESP32-C2 --- components/bt/controller/esp32c2/bt.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index 7d3c1b349d..4881f819b1 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -394,11 +394,11 @@ void esp_bt_read_ctrl_log_from_flash(bool output) portENTER_CRITICAL_SAFE(&spinlock); esp_panic_handler_feed_wdts(); ble_log_async_output_dump_all(true); - stop_write = true; esp_bt_ontroller_log_deinit(); - portEXIT_CRITICAL_SAFE(&spinlock); + stop_write = true; buffer = (const uint8_t *)mapped_ptr; + esp_panic_handler_feed_wdts(); if (is_filled) { read_index = next_erase_index; } else { @@ -410,7 +410,7 @@ void esp_bt_read_ctrl_log_from_flash(bool output) while (read_index != write_index) { esp_rom_printf("%02x ", buffer[read_index]); if (print_len > max_print_len) { - vTaskDelay(2); + esp_panic_handler_feed_wdts(); print_len = 0; } @@ -418,6 +418,7 @@ void esp_bt_read_ctrl_log_from_flash(bool output) read_index = (read_index + 1) % MAX_STORAGE_SIZE; } esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); esp_partition_munmap(mmap_handle); err = esp_bt_controller_log_init(log_output_mode); assert(err == ESP_OK); @@ -431,6 +432,9 @@ static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, b esp_bt_controller_log_storage(len, addr, end); #endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); for (int i = 0; i < len; i++) { esp_rom_printf("%02x ", addr[i]); } @@ -438,6 +442,7 @@ static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, b if (end) { esp_rom_printf("\n"); } + portEXIT_CRITICAL_SAFE(&spinlock); } } From 8eb051cb30ac9997f862007fff272cc9ed5fb4f3 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Thu, 13 Mar 2025 11:40:01 +0800 Subject: [PATCH 06/17] feat(ble): support ble log simple output via SPI interface for ESP32-C2 --- components/bt/controller/esp32c2/bt.c | 201 ++++++++++++-------------- 1 file changed, 92 insertions(+), 109 deletions(-) diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index 4881f819b1..2364eeb3a0 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -65,11 +65,9 @@ #include "hal/efuse_ll.h" #include "soc/rtc.h" -#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED #include "ble_log/ble_log_spi_out.h" -#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED -#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED /* Macro definition ************************************************************************ @@ -119,7 +117,7 @@ struct ext_funcs_t { }; #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); +typedef void (*interface_func_t) (uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* External functions or variables @@ -128,8 +126,10 @@ typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); extern int ble_controller_init(esp_bt_controller_config_t *cfg); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int ble_log_init_async(interface_func_t interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); extern int ble_log_deinit_async(void); +extern int ble_log_init_simple(interface_func_t interface, void *handler); +extern void ble_log_deinit_simple(void); extern void ble_log_async_output_dump_all(bool output); extern void esp_panic_handler_feed_wdts(void); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED @@ -198,10 +198,12 @@ static int esp_ecc_gen_key_pair(uint8_t *pub, uint8_t *priv); static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); -#endif // #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** @@ -211,50 +213,29 @@ void *g_ble_lll_rfmgmt_env_p; #endif /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; + #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; -enum log_out_mode { - LOG_DUMP_MEMORY, - LOG_ASYNC_OUT, - LOG_STORAGE_TO_FLASH, - LOG_SPI_OUT, -}; +static bool log_is_inited = false; -bool log_is_inited = false; -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY -uint8_t log_output_mode = LOG_DUMP_MEMORY; -#else -#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE -uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; -#elif CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED -uint8_t log_output_mode = LOG_SPI_OUT; -#else -uint8_t log_output_mode = LOG_ASYNC_OUT; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE -#endif // CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - -void esp_bt_log_output_mode_set(uint8_t output_mode) +esp_err_t esp_bt_controller_log_init(void) { - log_output_mode = output_mode; -} - -uint8_t esp_bt_log_output_mode_get(void) -{ - return log_output_mode; -} - -esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) -{ - esp_err_t ret = ESP_OK; - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - bool task_create; - uint8_t buffers = 0; - if (log_is_inited) { - return ret; + return ESP_OK; } +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + if (ble_log_spi_out_init() != 0) { + goto spi_out_init_failed; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + if (ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) { + goto log_init_failed; + } +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + uint8_t buffers = 0; #if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED buffers |= ESP_BLE_LOG_BUF_CONTROLLER; #endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED @@ -262,44 +243,41 @@ esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) buffers |= ESP_BLE_LOG_BUF_HCI; #endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - switch (log_output_mode) { - case LOG_DUMP_MEMORY: - task_create = false; - break; - case LOG_ASYNC_OUT: - case LOG_STORAGE_TO_FLASH: - task_create = true; -#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - if (log_output_mode == LOG_STORAGE_TO_FLASH) { - esp_bt_ctrl_log_partition_get_and_erase_first_block(); - } -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - break; - case LOG_SPI_OUT: - task_create = true; -#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - ble_log_spi_out_init(); - bt_controller_log_interface = ble_log_spi_out_write_esp; + bool task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + task_create = false; +#elif CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_ctrl_log_partition_get_and_erase_first_block(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - break; - default: - assert(0); - } - ret = ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); - if (ret == ESP_OK) { - log_is_inited = true; + if (ble_log_init_async(esp_bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size) != 0) { + goto log_init_failed; } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - return ret; + log_is_inited = true; + return ESP_OK; + +log_init_failed: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +spi_out_init_failed: +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + return ESP_FAIL; } -void esp_bt_ontroller_log_deinit(void) +void esp_bt_controller_log_deinit(void) { - ble_log_deinit_async(); -#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED ble_log_spi_out_deinit(); -#endif +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + log_is_inited = false; } @@ -394,7 +372,7 @@ void esp_bt_read_ctrl_log_from_flash(bool output) portENTER_CRITICAL_SAFE(&spinlock); esp_panic_handler_feed_wdts(); ble_log_async_output_dump_all(true); - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); stop_write = true; buffer = (const uint8_t *)mapped_ptr; @@ -420,48 +398,53 @@ void esp_bt_read_ctrl_log_from_flash(bool output) esp_rom_printf(":DUMP_END]\r\n"); portEXIT_CRITICAL_SAFE(&spinlock); esp_partition_munmap(mmap_handle); - err = esp_bt_controller_log_init(log_output_mode); + err = esp_bt_controller_log_init(); assert(err == ESP_OK); } #endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) -{ - if (log_output_mode == LOG_STORAGE_TO_FLASH) { -#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - esp_bt_controller_log_storage(len, addr, end); -#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - } else { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_feed_wdts(); - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); - } - if (end) { - esp_rom_printf("\n"); - } - portEXIT_CRITICAL_SAFE(&spinlock); +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag) +{ + bool end = flag ? true : false; +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); } + + if (end) { + esp_rom_printf("\n"); + } + portEXIT_CRITICAL_SAFE(&spinlock); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE } +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED void esp_ble_controller_log_dump_all(bool output) { - if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_dump_all(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - esp_bt_read_ctrl_log_from_flash(output); -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - } else { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_feed_wdts(); - BT_ASSERT_PRINT("\r\n[DUMP_START:"); - ble_log_async_output_dump_all(output); - BT_ASSERT_PRINT(":DUMP_END]\r\n"); - portEXIT_CRITICAL_SAFE(&spinlock); - } + esp_bt_read_ctrl_log_from_flash(output); +#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + BT_ASSERT_PRINT("\r\n[DUMP_START:"); + ble_log_async_output_dump_all(output); + BT_ASSERT_PRINT(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); +#endif } + #if CONFIG_BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE void esp_task_wdt_isr_user_handler(void) { @@ -881,7 +864,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble rom commit:[%s]", r_ble_controller_get_rom_compile_version()); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ret = esp_bt_controller_log_init(log_output_mode); + ret = esp_bt_controller_log_init(); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto controller_init_err; @@ -922,7 +905,7 @@ free_controller: controller_sleep_deinit(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED controller_init_err: - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED ble_controller_deinit(); modem_deint: @@ -951,7 +934,7 @@ esp_err_t esp_bt_controller_deinit(void) controller_sleep_deinit(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED ble_controller_deinit(); From 9a3b5e8393a9772672c0fe15da09a9e822501b79 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Thu, 13 Mar 2025 11:40:25 +0800 Subject: [PATCH 07/17] feat(ble): support ble log simple output via SPI interface for ESP32-H2 --- components/bt/controller/esp32h2/bt.c | 191 ++++++++++++-------------- 1 file changed, 89 insertions(+), 102 deletions(-) diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 147f1818e7..e5894ecd22 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -54,11 +54,9 @@ #include "esp_sleep.h" #include "soc/rtc.h" -#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED #include "ble_log/ble_log_spi_out.h" -#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED -#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED /* Macro definition ************************************************************************ @@ -103,7 +101,7 @@ struct ext_funcs_t { }; #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); +typedef void (*interface_func_t) (uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* External functions or variables ************************************************************************ @@ -112,8 +110,10 @@ extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); extern int r_ble_controller_init(esp_bt_controller_config_t *cfg); extern void esp_ble_controller_info_capture(uint32_t cycle_times); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int r_ble_log_init_async(interface_func_t interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); extern int r_ble_log_deinit_async(void); +extern int r_ble_log_init_simple(interface_func_t interface, void *handler); +extern void r_ble_log_deinit_simple(void); extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); extern void r_ble_log_async_output_dump_all(bool output); extern void esp_panic_handler_feed_wdts(void); @@ -185,60 +185,41 @@ static int esp_ecc_gen_key_pair(uint8_t *pub, uint8_t *priv); static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); -#endif // #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** */ /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; + #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; -enum log_out_mode { - LOG_DUMP_MEMORY, - LOG_ASYNC_OUT, - LOG_STORAGE_TO_FLASH, - LOG_SPI_OUT, -}; +static bool log_is_inited = false; -bool log_is_inited = false; -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY -uint8_t log_output_mode = LOG_DUMP_MEMORY; -#else -#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE -uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; -#elif CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED -uint8_t log_output_mode = LOG_SPI_OUT; -#else -uint8_t log_output_mode = LOG_ASYNC_OUT; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE -#endif // CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - -void esp_bt_log_output_mode_set(uint8_t output_mode) +esp_err_t esp_bt_controller_log_init(void) { - log_output_mode = output_mode; -} - -uint8_t esp_bt_log_output_mode_get(void) -{ - return log_output_mode; -} - -esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) -{ - esp_err_t ret = ESP_OK; - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - bool task_create; - uint8_t buffers = 0; - if (log_is_inited) { - return ret; + return ESP_OK; } +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + if (ble_log_spi_out_init() != 0) { + goto spi_out_init_failed; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + if (r_ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) { + goto log_init_failed; + } +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + uint8_t buffers = 0; #if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED buffers |= ESP_BLE_LOG_BUF_CONTROLLER; #endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED @@ -246,48 +227,50 @@ esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) buffers |= ESP_BLE_LOG_BUF_HCI; #endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - switch (log_output_mode) { - case LOG_DUMP_MEMORY: - task_create = false; - break; - case LOG_ASYNC_OUT: - case LOG_STORAGE_TO_FLASH: - task_create = true; -#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - if (log_output_mode == LOG_STORAGE_TO_FLASH) { - esp_bt_ctrl_log_partition_get_and_erase_first_block(); - } -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - break; - case LOG_SPI_OUT: - task_create = true; -#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - ble_log_spi_out_init(); - bt_controller_log_interface = ble_log_spi_out_write_esp; + bool task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + task_create = false; +#elif CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_ctrl_log_partition_get_and_erase_first_block(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - break; - default: - assert(0); - } - ret = r_ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); - if (ret != ESP_OK) { - return ret; + if (r_ble_log_init_async(esp_bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size) != 0) { + goto log_init_failed; } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - ret = r_ble_log_ctrl_level_and_mod(CONFIG_BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL, CONFIG_BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH); - if (ret == ESP_OK) { - log_is_inited = true; + if (r_ble_log_ctrl_level_and_mod(CONFIG_BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL, CONFIG_BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH) != ESP_OK) { + goto ctrl_level_init_failed; } - return ret; + log_is_inited = true; + return ESP_OK; + +ctrl_level_init_failed: +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +log_init_failed: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +spi_out_init_failed: +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + return ESP_FAIL; } -void esp_bt_ontroller_log_deinit(void) +void esp_bt_controller_log_deinit(void) { - r_ble_log_deinit_async(); -#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED ble_log_spi_out_deinit(); -#endif +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + log_is_inited = false; } @@ -381,7 +364,7 @@ void esp_bt_read_ctrl_log_from_flash(bool output) portENTER_CRITICAL_SAFE(&spinlock); esp_panic_handler_feed_wdts(); r_ble_log_async_output_dump_all(true); - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); stop_write = true; buffer = (const uint8_t *)mapped_ptr; @@ -408,7 +391,7 @@ void esp_bt_read_ctrl_log_from_flash(bool output) esp_rom_printf(":DUMP_END]\r\n"); portEXIT_CRITICAL_SAFE(&spinlock); esp_partition_munmap(mmap_handle); - err = esp_bt_controller_log_init(log_output_mode); + err = esp_bt_controller_log_init(); assert(err == ESP_OK); } #endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE @@ -929,7 +912,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif // CONFIG_SW_COEXIST_ENABLE #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ret = esp_bt_controller_log_init(log_output_mode); + ret = esp_bt_controller_log_init(); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto modem_deint; @@ -1001,7 +984,7 @@ free_controller: modem_deint: esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); @@ -1036,7 +1019,7 @@ esp_err_t esp_bt_controller_deinit(void) r_ble_controller_deinit(); esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED #if CONFIG_BT_NIMBLE_ENABLED @@ -1384,41 +1367,45 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po } #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag) { - if (log_output_mode == LOG_STORAGE_TO_FLASH) { + bool end = flag ? true : false; #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - esp_bt_controller_log_storage(len, addr, end); -#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - } else { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_feed_wdts(); - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); - } - - if (end) { - esp_rom_printf("\n"); - } - portEXIT_CRITICAL_SAFE(&spinlock); + esp_bt_controller_log_storage(len, addr, end); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); } + + if (end) { + esp_rom_printf("\n"); + } + portEXIT_CRITICAL_SAFE(&spinlock); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE } +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED void esp_ble_controller_log_dump_all(bool output) { +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_dump_all(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE esp_bt_read_ctrl_log_from_flash(output); -#else +#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL_SAFE(&spinlock); esp_panic_handler_feed_wdts(); BT_ASSERT_PRINT("\r\n[DUMP_START:"); r_ble_log_async_output_dump_all(output); BT_ASSERT_PRINT(":DUMP_END]\r\n"); portEXIT_CRITICAL_SAFE(&spinlock); -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif } #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED From 8e036761ed743cf9147591a26a824a259e6299ae Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Thu, 13 Mar 2025 11:40:50 +0800 Subject: [PATCH 08/17] feat(ble): support ble log simple output via SPI interface for ESP32-C5 --- components/bt/controller/esp32c5/bt.c | 196 +++++++++++++------------- 1 file changed, 101 insertions(+), 95 deletions(-) diff --git a/components/bt/controller/esp32c5/bt.c b/components/bt/controller/esp32c5/bt.c index 9dd91b04bd..c9fdc89100 100644 --- a/components/bt/controller/esp32c5/bt.c +++ b/components/bt/controller/esp32c5/bt.c @@ -54,6 +54,11 @@ #include "hal/efuse_hal.h" #include "soc/rtc.h" + +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + /* Macro definition ************************************************************************ */ @@ -97,7 +102,7 @@ struct ext_funcs_t { }; #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); +typedef void (*interface_func_t) (uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* External functions or variables @@ -107,8 +112,10 @@ extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); extern int r_ble_controller_init(esp_bt_controller_config_t *cfg); extern void esp_ble_controller_info_capture(uint32_t cycle_times); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int r_ble_log_init_async(interface_func_t interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); extern int r_ble_log_deinit_async(void); +extern int r_ble_log_init_simple(interface_func_t interface, void *handler); +extern void r_ble_log_deinit_simple(void); extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); extern void r_ble_log_async_output_dump_all(bool output); extern void esp_panic_handler_feed_wdts(void); @@ -177,57 +184,41 @@ static int esp_ecc_gen_key_pair(uint8_t *pub, uint8_t *priv); static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); -#endif // #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** */ /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; + #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; -enum log_out_mode { - LOG_DUMP_MEMORY, - LOG_ASYNC_OUT, - LOG_STORAGE_TO_FLASH, -}; +static bool log_is_inited = false; -bool log_is_inited = false; -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY -uint8_t log_output_mode = LOG_DUMP_MEMORY; -#else -#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE -uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; -#else -uint8_t log_output_mode = LOG_ASYNC_OUT; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE -#endif // CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - -void esp_bt_log_output_mode_set(uint8_t output_mode) +esp_err_t esp_bt_controller_log_init(void) { - log_output_mode = output_mode; -} - -uint8_t esp_bt_log_output_mode_get(void) -{ - return log_output_mode; -} - -esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) -{ - esp_err_t ret = ESP_OK; - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - bool task_create; - uint8_t buffers = 0; - if (log_is_inited) { - return ret; + return ESP_OK; } +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + if (ble_log_spi_out_init() != 0) { + goto spi_out_init_failed; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + if (r_ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) { + goto log_init_failed; + } +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + uint8_t buffers = 0; #if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED buffers |= ESP_BLE_LOG_BUF_CONTROLLER; #endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED @@ -235,38 +226,50 @@ esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) buffers |= ESP_BLE_LOG_BUF_HCI; #endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - switch (log_output_mode) { - case LOG_DUMP_MEMORY: - task_create = false; - break; - case LOG_ASYNC_OUT: - case LOG_STORAGE_TO_FLASH: - task_create = true; -#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - if (log_output_mode == LOG_STORAGE_TO_FLASH) { - esp_bt_ctrl_log_partition_get_and_erase_first_block(); - } -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - break; - default: - assert(0); - } + bool task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + task_create = false; +#elif CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_ctrl_log_partition_get_and_erase_first_block(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - ret = r_ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); - if (ret != ESP_OK) { - return ret; + if (r_ble_log_init_async(esp_bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size) != 0) { + goto log_init_failed; } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - ret = r_ble_log_ctrl_level_and_mod(CONFIG_BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL, CONFIG_BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH); - if (ret == ESP_OK) { - log_is_inited = true; + if (r_ble_log_ctrl_level_and_mod(CONFIG_BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL, CONFIG_BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH) != ESP_OK) { + goto ctrl_level_init_failed; } - return ret; + log_is_inited = true; + return ESP_OK; + +ctrl_level_init_failed: +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +log_init_failed: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +spi_out_init_failed: +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + return ESP_FAIL; } -void esp_bt_ontroller_log_deinit(void) +void esp_bt_controller_log_deinit(void) { +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + log_is_inited = false; } @@ -360,7 +363,7 @@ void esp_bt_read_ctrl_log_from_flash(bool output) portENTER_CRITICAL_SAFE(&spinlock); esp_panic_handler_feed_wdts(); r_ble_log_async_output_dump_all(true); - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); stop_write = true; buffer = (const uint8_t *)mapped_ptr; @@ -387,7 +390,7 @@ void esp_bt_read_ctrl_log_from_flash(bool output) esp_rom_printf(":DUMP_END]\r\n"); portEXIT_CRITICAL_SAFE(&spinlock); esp_partition_munmap(mmap_handle); - err = esp_bt_controller_log_init(log_output_mode); + err = esp_bt_controller_log_init(); assert(err == ESP_OK); } #endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE @@ -915,7 +918,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif // CONFIG_SW_COEXIST_ENABLE #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ret = esp_bt_controller_log_init(log_output_mode); + ret = esp_bt_controller_log_init(); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto modem_deint; @@ -984,7 +987,7 @@ free_controller: modem_deint: esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED esp_phy_modem_deinit(); // modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); @@ -1021,7 +1024,7 @@ esp_err_t esp_bt_controller_deinit(void) r_ble_controller_deinit(); esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED #if CONFIG_BT_NIMBLE_ENABLED @@ -1369,42 +1372,45 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po } #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag) { - if (log_output_mode == LOG_STORAGE_TO_FLASH) { + bool end = flag ? true : false; #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - esp_bt_controller_log_storage(len, addr, end); -#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - } else { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_feed_wdts(); - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); - } - - if (end) { - esp_rom_printf("\n"); - } - portEXIT_CRITICAL_SAFE(&spinlock); + esp_bt_controller_log_storage(len, addr, end); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); } + + if (end) { + esp_rom_printf("\n"); + } + portEXIT_CRITICAL_SAFE(&spinlock); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE } +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED void esp_ble_controller_log_dump_all(bool output) { - if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_dump_all(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - esp_bt_read_ctrl_log_from_flash(output); -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - } else { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_feed_wdts(); - BT_ASSERT_PRINT("\r\n[DUMP_START:"); - r_ble_log_async_output_dump_all(output); - BT_ASSERT_PRINT(":DUMP_END]\r\n"); - portEXIT_CRITICAL_SAFE(&spinlock); - } + esp_bt_read_ctrl_log_from_flash(output); +#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + BT_ASSERT_PRINT("\r\n[DUMP_START:"); + r_ble_log_async_output_dump_all(output); + BT_ASSERT_PRINT(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); +#endif } #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED From b7bffc84f95a021e30d1335e0be1fb55cd5f339f Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Thu, 13 Mar 2025 11:41:09 +0800 Subject: [PATCH 09/17] feat(ble): support ble log simple output via SPI interface for ESP32-C6 --- components/bt/controller/esp32c6/bt.c | 206 ++++++++++++-------------- 1 file changed, 96 insertions(+), 110 deletions(-) diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index 291fc2a2ad..9e3253d4c6 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -58,11 +58,9 @@ #include "hal/efuse_hal.h" #include "soc/rtc.h" -#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED #include "ble_log/ble_log_spi_out.h" -#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED -#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED /* Macro definition ************************************************************************ @@ -107,7 +105,7 @@ struct ext_funcs_t { }; #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); +typedef void (*interface_func_t) (uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* External functions or variables @@ -117,8 +115,10 @@ extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); extern int r_ble_controller_init(esp_bt_controller_config_t *cfg); extern void esp_ble_controller_info_capture(uint32_t cycle_times); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int r_ble_log_init_async(interface_func_t interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); extern int r_ble_log_deinit_async(void); +extern int r_ble_log_init_simple(interface_func_t interface, void *handler); +extern void r_ble_log_deinit_simple(void); extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); extern void r_ble_log_async_output_dump_all(bool output); extern void esp_panic_handler_feed_wdts(void); @@ -187,60 +187,41 @@ static int esp_ecc_gen_key_pair(uint8_t *pub, uint8_t *priv); static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); -#endif // #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** */ /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; + #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; -enum log_out_mode { - LOG_DUMP_MEMORY, - LOG_ASYNC_OUT, - LOG_STORAGE_TO_FLASH, - LOG_SPI_OUT, -}; +static bool log_is_inited = false; -bool log_is_inited = false; -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY -uint8_t log_output_mode = LOG_DUMP_MEMORY; -#else -#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE -uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; -#elif CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED -uint8_t log_output_mode = LOG_SPI_OUT; -#else -uint8_t log_output_mode = LOG_ASYNC_OUT; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE -#endif // CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - -void esp_bt_log_output_mode_set(uint8_t output_mode) +esp_err_t esp_bt_controller_log_init(void) { - log_output_mode = output_mode; -} - -uint8_t esp_bt_log_output_mode_get(void) -{ - return log_output_mode; -} - -esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) -{ - esp_err_t ret = ESP_OK; - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - bool task_create; - uint8_t buffers = 0; - if (log_is_inited) { - return ret; + return ESP_OK; } +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + if (ble_log_spi_out_init() != 0) { + goto spi_out_init_failed; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + if (r_ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) { + goto log_init_failed; + } +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + uint8_t buffers = 0; #if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED buffers |= ESP_BLE_LOG_BUF_CONTROLLER; #endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED @@ -248,48 +229,50 @@ esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) buffers |= ESP_BLE_LOG_BUF_HCI; #endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - switch (log_output_mode) { - case LOG_DUMP_MEMORY: - task_create = false; - break; - case LOG_ASYNC_OUT: - case LOG_STORAGE_TO_FLASH: - task_create = true; -#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - if (log_output_mode == LOG_STORAGE_TO_FLASH) { - esp_bt_ctrl_log_partition_get_and_erase_first_block(); - } -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - break; - case LOG_SPI_OUT: - task_create = true; -#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - ble_log_spi_out_init(); - bt_controller_log_interface = ble_log_spi_out_write_esp; + bool task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + task_create = false; +#elif CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_ctrl_log_partition_get_and_erase_first_block(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - break; - default: - assert(0); - } - ret = r_ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); - if (ret != ESP_OK) { - return ret; + if (r_ble_log_init_async(esp_bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size) != 0) { + goto log_init_failed; } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED - ret = r_ble_log_ctrl_level_and_mod(CONFIG_BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL, CONFIG_BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH); - if (ret == ESP_OK) { - log_is_inited = true; + if (r_ble_log_ctrl_level_and_mod(CONFIG_BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL, CONFIG_BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH) != ESP_OK) { + goto ctrl_level_init_failed; } - return ret; + log_is_inited = true; + return ESP_OK; + +ctrl_level_init_failed: +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +log_init_failed: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +spi_out_init_failed: +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + return ESP_FAIL; } -void esp_bt_ontroller_log_deinit(void) +void esp_bt_controller_log_deinit(void) { - r_ble_log_deinit_async(); -#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED ble_log_spi_out_deinit(); -#endif +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + log_is_inited = false; } @@ -383,7 +366,7 @@ void esp_bt_read_ctrl_log_from_flash(bool output) portENTER_CRITICAL_SAFE(&spinlock); esp_panic_handler_feed_wdts(); r_ble_log_async_output_dump_all(true); - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); stop_write = true; buffer = (const uint8_t *)mapped_ptr; @@ -953,7 +936,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif // CONFIG_SW_COEXIST_ENABLE #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ret = esp_bt_controller_log_init(log_output_mode); + ret = esp_bt_controller_log_init(); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto modem_deint; @@ -1025,7 +1008,7 @@ free_controller: modem_deint: esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED esp_phy_modem_deinit(); modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); @@ -1062,7 +1045,7 @@ esp_err_t esp_bt_controller_deinit(void) r_ble_controller_deinit(); esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - esp_bt_ontroller_log_deinit(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED #if CONFIG_BT_NIMBLE_ENABLED @@ -1410,42 +1393,45 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po } #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag) { - if (log_output_mode == LOG_STORAGE_TO_FLASH) { + bool end = flag ? true : false; #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - esp_bt_controller_log_storage(len, addr, end); -#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - } else { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_feed_wdts(); - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); - } - - if (end) { - esp_rom_printf("\n"); - } - portEXIT_CRITICAL_SAFE(&spinlock); + esp_bt_controller_log_storage(len, addr, end); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); } + + if (end) { + esp_rom_printf("\n"); + } + portEXIT_CRITICAL_SAFE(&spinlock); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE } +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED void esp_ble_controller_log_dump_all(bool output) { - if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_dump_all(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - esp_bt_read_ctrl_log_from_flash(output); -#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE - } else { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_feed_wdts(); - BT_ASSERT_PRINT("\r\n[DUMP_START:"); - r_ble_log_async_output_dump_all(output); - BT_ASSERT_PRINT(":DUMP_END]\r\n"); - portEXIT_CRITICAL_SAFE(&spinlock); - } + esp_bt_read_ctrl_log_from_flash(output); +#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + BT_ASSERT_PRINT("\r\n[DUMP_START:"); + r_ble_log_async_output_dump_all(output); + BT_ASSERT_PRINT(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); +#endif } #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED From c93081cec4a97aa3dd3e9d8414fb7edf9ba12309 Mon Sep 17 00:00:00 2001 From: zwl Date: Tue, 11 Feb 2025 17:00:30 +0800 Subject: [PATCH 10/17] feat(ble): add enhanced connect function on ESP32-C2 --- components/bt/controller/esp32c2/Kconfig.in | 30 +++++++++++++++++++ components/bt/controller/esp32c2/esp_bt_cfg.h | 26 ++++++++++++++++ .../bt/include/esp32c2/include/esp_bt.h | 5 ++++ .../esp32c2/ld/esp32c2.rom.ble-eco4.ld | 12 ++++---- .../esp_rom/esp32c2/ld/esp32c2.rom.ble.ld | 10 +++---- 5 files changed, 72 insertions(+), 11 deletions(-) diff --git a/components/bt/controller/esp32c2/Kconfig.in b/components/bt/controller/esp32c2/Kconfig.in index 7c17fe7562..00ea9b04bb 100644 --- a/components/bt/controller/esp32c2/Kconfig.in +++ b/components/bt/controller/esp32c2/Kconfig.in @@ -689,3 +689,33 @@ config BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS Enabling this option will add stricter verification of the Access Address in the CONNECT_IND PDU. This improves security by ensuring that only connection requests with valid Access Addresses are accepted. If disabled, only basic checks are applied, improving compatibility. + +menu "BLE disconnects when Instant Passed (0x28) occurs" + config BT_LE_CTRL_LLCP_CONN_UPDATE + bool "BLE ACL connection update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs during connection update procedure. + + config BT_LE_CTRL_LLCP_CHAN_MAP_UPDATE + bool "BLE ACL channel map update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in channel map update procedure. + + config BT_LE_CTRL_LLCP_PHY_UPDATE + bool "BLE ACL PHY update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in PHY update procedure. +endmenu + +config BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX + int "The value of upperlimitmax during scan backoff procedure" + range 1 256 + default 32 + help + The value of upperlimitmax needs to be a power of 2. diff --git a/components/bt/controller/esp32c2/esp_bt_cfg.h b/components/bt/controller/esp32c2/esp_bt_cfg.h index 74d226a609..95a3c6b2f6 100644 --- a/components/bt/controller/esp32c2/esp_bt_cfg.h +++ b/components/bt/controller/esp32c2/esp_bt_cfg.h @@ -226,6 +226,32 @@ extern "C" { #define DEFAULT_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS (0) #endif +#ifdef CONFIG_BT_LE_CTRL_LLCP_CONN_UPDATE +#define BT_CTRL_BLE_LLCP_CONN_UPDATE (1<<0) +#else +#define BT_CTRL_BLE_LLCP_CONN_UPDATE (0<<0) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_CHAN_MAP_UPDATE +#define BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE (1<<1) +#else +#define BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE (0<<1) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_PHY_UPDATE +#define BT_CTRL_BLE_LLCP_PHY_UPDATE (1<<2) +#else +#define BT_CTRL_BLE_LLCP_PHY_UPDATE (0<<2) +#endif + +#define BT_LE_CTRL_LLCP_DISC_FLAG (BT_CTRL_BLE_LLCP_CONN_UPDATE | BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE | BT_CTRL_BLE_LLCP_PHY_UPDATE) + +#ifdef CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX +#define BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX (CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX) +#else +#define BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX (256) +#endif + #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART #else diff --git a/components/bt/include/esp32c2/include/esp_bt.h b/components/bt/include/esp32c2/include/esp_bt.h index 3b4d5973a7..262c411470 100644 --- a/components/bt/include/esp32c2/include/esp_bt.h +++ b/components/bt/include/esp32c2/include/esp_bt.h @@ -228,6 +228,9 @@ typedef struct { uint8_t ignore_wl_for_direct_adv; /*!< Ignore the white list for directed advertising */ uint8_t csa2_select; /*!< Select CSA#2 */ uint8_t ble_aa_check; /*!< True if adds a verification step for the Access Address within the CONNECT_IND PDU; false otherwise. Configurable in menuconfig */ + uint8_t ble_llcp_disc_flag; /*!< Flag indicating whether the Controller disconnects after Instant Passed (0x28) error occurs. Configurable in menuconfig. + - The Controller does not disconnect after Instant Passed (0x28) by default. */ + uint16_t scan_backoff_upperlimitmax; /*!< The value of upperlimitmax is 2^n, The maximum value is 256 */ uint8_t vhci_enabled; /*!< VHCI mode is enabled */ uint32_t config_magic; /*!< Configuration magic value */ } esp_bt_controller_config_t; @@ -276,6 +279,8 @@ typedef struct { .ignore_wl_for_direct_adv = 0, \ .csa2_select = DEFAULT_BT_LE_50_FEATURE_SUPPORT, \ .ble_aa_check = DEFAULT_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS, \ + .ble_llcp_disc_flag = BT_LE_CTRL_LLCP_DISC_FLAG, \ + .scan_backoff_upperlimitmax = BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX, \ .vhci_enabled = DEFAULT_BT_LE_VHCI_ENABLED, \ .config_magic = CONFIG_MAGIC, \ } diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld index ed08b1a83c..c94f6afa13 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld @@ -257,7 +257,7 @@ r_ble_ll_conn_tx_pkt_in = 0x40000e4c; r_ble_ll_conn_update_eff_data_len = 0x40000e50; r_ble_ll_ctrl_chanmap_req_make = 0x40000e54; r_ble_ll_ctrl_chk_proc_start = 0x40000e58; -r_ble_ll_ctrl_conn_param_pdu_make = 0x40000e5c; +//r_ble_ll_ctrl_conn_param_pdu_make = 0x40000e5c; r_ble_ll_ctrl_conn_param_pdu_proc = 0x40000e60; r_ble_ll_ctrl_conn_param_reply = 0x40000e64; r_ble_ll_ctrl_conn_upd_make = 0x40000e68; @@ -284,7 +284,7 @@ r_ble_ll_ctrl_proc_unk_rsp = 0x40000eb8; r_ble_ll_ctrl_proc_with_instant_initiated = 0x40000ebc; r_ble_ll_ctrl_rej_ext_ind_make = 0x40000ec0; r_ble_ll_ctrl_reject_ind_send = 0x40000ec4; -r_ble_ll_ctrl_rx_chanmap_req = 0x40000ec8; +//r_ble_ll_ctrl_rx_chanmap_req = 0x40000ec8; r_ble_ll_ctrl_rx_conn_param_req = 0x40000ecc; //r_ble_ll_ctrl_rx_conn_param_rsp = 0x40000ed0; //r_ble_ll_ctrl_rx_conn_update = 0x40000ed4; @@ -298,7 +298,7 @@ r_ble_ll_ctrl_rx_pdu = 0x40000ef0; r_ble_ll_ctrl_rx_periodic_sync_ind = 0x40000ef4; r_ble_ll_ctrl_rx_phy_req = 0x40000ef8; r_ble_ll_ctrl_rx_phy_rsp = 0x40000efc; -r_ble_ll_ctrl_rx_phy_update_ind = 0x40000f00; +//r_ble_ll_ctrl_rx_phy_update_ind = 0x40000f00; r_ble_ll_ctrl_rx_ping_rsp = 0x40000f04; r_ble_ll_ctrl_rx_reject_ind = 0x40000f08; r_ble_ll_ctrl_rx_sca_req = 0x40000f0c; @@ -346,7 +346,7 @@ r_ble_ll_hci_cmd_rx = 0x40000fb0; r_ble_ll_hci_ctlr_bb_cmd_proc = 0x40000fb4; r_ble_ll_hci_deinit = 0x40000fb8; r_ble_ll_hci_disconnect = 0x40000fbc; -r_ble_ll_hci_env_init = 0x40000fc0; +//r_ble_ll_hci_env_init = 0x40000fc0; r_ble_ll_hci_ev_conn_update = 0x40000fc4; r_ble_ll_hci_ev_databuf_overflow = 0x40000fc8; r_ble_ll_hci_ev_datalen_chg = 0x40000fcc; @@ -805,7 +805,7 @@ r_ble_lll_scan_npl_store = 0x400016dc; r_ble_lll_scan_period_timer_cb = 0x400016e0; r_ble_lll_scan_process_adv_in_isr = 0x400016e4; r_ble_lll_scan_process_rsp_in_isr = 0x400016e8; -r_ble_lll_scan_req_backoff = 0x400016ec; +//r_ble_lll_scan_req_backoff = 0x400016ec; r_ble_lll_scan_restart = 0x400016f0; r_ble_lll_scan_rx_isr_on_aux = 0x400016f4; r_ble_lll_scan_rx_isr_on_legacy = 0x400016f8; @@ -1216,7 +1216,7 @@ r_ble_lll_scan_filter_out_useless_adv = 0x40002ff4; r_ble_hw_whitelist_check_in_wl = 0x40002ff8; r_ble_phy_stats_reset = 0x40002ffc; r_ble_phy_ramup_time_set = 0x40003000; -r_ble_lll_rfmgmt_should_skip_light_sleep_check = 0x40003004; +//r_ble_lll_rfmgmt_should_skip_light_sleep_check = 0x40003004; r_ble_phy_rx_err_record = 0x40003008; r_ble_lll_rfmgmt_wake_up_overhead_set = 0x4000300c; //r_ble_lll_conn_event_delete_and_reschedule = 0x40003010; diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld index 71cc8a7744..2f30dd745a 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -202,7 +202,7 @@ r_ble_ll_conn_sm_get = 0x40000e3c; r_ble_ll_conn_tx_pkt_in = 0x40000e4c; r_ble_ll_conn_update_eff_data_len = 0x40000e50; r_ble_ll_ctrl_chanmap_req_make = 0x40000e54; -r_ble_ll_ctrl_conn_param_pdu_make = 0x40000e5c; +//r_ble_ll_ctrl_conn_param_pdu_make = 0x40000e5c; r_ble_ll_ctrl_conn_param_pdu_proc = 0x40000e60; r_ble_ll_ctrl_conn_param_reply = 0x40000e64; r_ble_ll_ctrl_datalen_upd_make = 0x40000e6c; @@ -224,7 +224,7 @@ r_ble_ll_ctrl_proc_stop = 0x40000eb4; r_ble_ll_ctrl_proc_with_instant_initiated = 0x40000ebc; r_ble_ll_ctrl_rej_ext_ind_make = 0x40000ec0; r_ble_ll_ctrl_reject_ind_send = 0x40000ec4; -r_ble_ll_ctrl_rx_chanmap_req = 0x40000ec8; +//r_ble_ll_ctrl_rx_chanmap_req = 0x40000ec8; r_ble_ll_ctrl_rx_conn_param_req = 0x40000ecc; r_ble_ll_ctrl_rx_enc_req = 0x40000ed8; r_ble_ll_ctrl_rx_enc_rsp = 0x40000edc; @@ -234,7 +234,7 @@ r_ble_ll_ctrl_rx_pause_enc_rsp = 0x40000eec; r_ble_ll_ctrl_rx_periodic_sync_ind = 0x40000ef4; r_ble_ll_ctrl_rx_phy_req = 0x40000ef8; r_ble_ll_ctrl_rx_phy_rsp = 0x40000efc; -r_ble_ll_ctrl_rx_phy_update_ind = 0x40000f00; +//r_ble_ll_ctrl_rx_phy_update_ind = 0x40000f00; r_ble_ll_ctrl_rx_ping_rsp = 0x40000f04; r_ble_ll_ctrl_rx_reject_ind = 0x40000f08; r_ble_ll_ctrl_rx_sca_req = 0x40000f0c; @@ -636,7 +636,7 @@ r_ble_lll_scan_npl_restore = 0x400016d8; r_ble_lll_scan_npl_store = 0x400016dc; r_ble_lll_scan_period_timer_cb = 0x400016e0; r_ble_lll_scan_process_adv_in_isr = 0x400016e4; -r_ble_lll_scan_req_backoff = 0x400016ec; +//r_ble_lll_scan_req_backoff = 0x400016ec; r_ble_lll_scan_sched_next_aux = 0x40001700; r_ble_lll_scan_sched_remove = 0x40001704; r_ble_lll_scan_start = 0x40001708; From 15d421c0602d7a2e3952704d072708de007b94df Mon Sep 17 00:00:00 2001 From: cjin Date: Fri, 21 Feb 2025 17:50:27 +0800 Subject: [PATCH 11/17] fix(ble): remove macro in lpclk src get api on ESP32-C5 --- components/bt/include/esp32c5/include/esp_bt.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/bt/include/esp32c5/include/esp_bt.h b/components/bt/include/esp32c5/include/esp_bt.h index fae1c316cc..d045553168 100644 --- a/components/bt/include/esp32c5/include/esp_bt.h +++ b/components/bt/include/esp32c5/include/esp_bt.h @@ -435,11 +435,9 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr); void esp_ble_controller_log_dump_all(bool output); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -#if CONFIG_PM_ENABLE modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void); void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src); -#endif // CONFIG_PM_ENABLE #ifdef __cplusplus } From 1848a85f99e5cfbfa468784f4478f3383ce7af26 Mon Sep 17 00:00:00 2001 From: cjin Date: Fri, 21 Feb 2025 17:50:47 +0800 Subject: [PATCH 12/17] fix(ble): remove macro in lpclk src get api on ESP32-C6 --- components/bt/include/esp32c6/include/esp_bt.h | 2 -- components/bt/include/esp32h2/include/esp_bt.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/components/bt/include/esp32c6/include/esp_bt.h b/components/bt/include/esp32c6/include/esp_bt.h index 1362f104a8..b3ada150c0 100644 --- a/components/bt/include/esp32c6/include/esp_bt.h +++ b/components/bt/include/esp32c6/include/esp_bt.h @@ -493,11 +493,9 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr); void esp_ble_controller_log_dump_all(bool output); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -#if CONFIG_PM_ENABLE modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void); void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src); -#endif // CONFIG_PM_ENABLE #ifdef __cplusplus } diff --git a/components/bt/include/esp32h2/include/esp_bt.h b/components/bt/include/esp32h2/include/esp_bt.h index 565f43f848..9a7545b25c 100644 --- a/components/bt/include/esp32h2/include/esp_bt.h +++ b/components/bt/include/esp32h2/include/esp_bt.h @@ -438,11 +438,9 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr); void esp_ble_controller_log_dump_all(bool output); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -#if CONFIG_PM_ENABLE modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void); void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src); -#endif // CONFIG_PM_ENABLE #ifdef __cplusplus } From 18725220d40007bfeaaa9039c75f32feca87e5e2 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Fri, 14 Mar 2025 11:23:35 +0800 Subject: [PATCH 13/17] fix(ble): fix ble log init failure mem leak for ESP32 --- components/bt/controller/esp32/bt.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/components/bt/controller/esp32/bt.c b/components/bt/controller/esp32/bt.c index 4daf277053..abf5c3d4d3 100644 --- a/components/bt/controller/esp32/bt.c +++ b/components/bt/controller/esp32/bt.c @@ -1699,7 +1699,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif #if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED - ble_log_spi_out_init(); + if (ble_log_spi_out_init() != 0) { + ESP_LOGE(BTDM_LOG_TAG, "BLE Log SPI output init failed"); + goto error; + } #endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED btdm_cfg_mask = btdm_config_mask_load(); @@ -1728,6 +1731,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) error: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + bt_controller_deinit_internal(); return err; From 94480cc0c04326eb66b2fe6618e13bfe12b54161 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Fri, 14 Mar 2025 15:42:34 +0800 Subject: [PATCH 14/17] feat(ble): support ble log simple output via SPI interface --- components/bt/common/Kconfig.in | 47 +- .../bt/common/ble_log/ble_log_spi_out.c | 994 +++++++++++++----- .../ble_log/include/ble_log/ble_log_spi_out.h | 15 +- 3 files changed, 777 insertions(+), 279 deletions(-) diff --git a/components/bt/common/Kconfig.in b/components/bt/common/Kconfig.in index 08ae449869..fb17bbb9ff 100644 --- a/components/bt/common/Kconfig.in +++ b/components/bt/common/Kconfig.in @@ -9,9 +9,18 @@ config BT_ALARM_MAX_NUM config BT_BLE_LOG_SPI_OUT_ENABLED bool "Output ble logs to SPI bus (Experimental)" default n + select SPI_MASTER_IN_IRAM help Output ble logs to SPI bus +config BT_BLE_LOG_SPI_OUT_UL_TASK_BUF_SIZE + int "SPI transaction buffer size for upper layer task logs" + depends on BT_BLE_LOG_SPI_OUT_ENABLED + default 512 + help + SPI transaction buffer size for upper layer task logs. + There will be 2 SPI DMA buffers with the same size. + config BT_BLE_LOG_SPI_OUT_HCI_ENABLED bool "Enable HCI log output to SPI" depends on BT_BLE_LOG_SPI_OUT_ENABLED @@ -27,51 +36,61 @@ config BT_BLE_LOG_SPI_OUT_HOST_ENABLED This configuration applies to the logs of both Bluedroid Host and NimBLE Host. When BLE SPI log output is enabled, this option allows host logs to be transmitted via SPI. -config BT_BLE_LOG_SPI_OUT_QUEUE_SIZE - int "Number of ble log async SPI output queues" +config BT_BLE_LOG_SPI_OUT_LL_ENABLED + bool "Enable Controller log output to SPI" depends on BT_BLE_LOG_SPI_OUT_ENABLED - default 4 + depends on BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + default n help - The number of ble log async SPI output queues + Enable controller log output to SPI bus. -config BT_BLE_LOG_SPI_OUT_TRANS_BUF_SIZE - int "Size of ble log async SPI output transaction buffer size" - depends on BT_BLE_LOG_SPI_OUT_ENABLED - default 2048 +config BT_BLE_LOG_SPI_OUT_LL_TASK_BUF_SIZE + int "SPI transaction buffer size for lower layer task logs" + depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED + default 1024 help - The size of ble log async SPI output transaction buffer size + SPI transaction buffer size for upper layer task logs. + There will be 2 SPI DMA buffers with the same size. + +config BT_BLE_LOG_SPI_OUT_LL_ISR_BUF_SIZE + int "SPI transaction buffer size for lower layer ISR logs" + depends on BT_BLE_LOG_SPI_OUT_LL_ENABLED + default 512 + help + SPI transaction buffer size for upper layer ISR logs. + There will be 2 SPI DMA buffers with the same size. config BT_BLE_LOG_SPI_OUT_MOSI_IO_NUM int "GPIO number of SPI MOSI" depends on BT_BLE_LOG_SPI_OUT_ENABLED default 0 help - GPIO number of SPI MOSI + GPIO number of SPI MOSI config BT_BLE_LOG_SPI_OUT_SCLK_IO_NUM int "GPIO number of SPI SCLK" depends on BT_BLE_LOG_SPI_OUT_ENABLED default 1 help - GPIO number of SPI SCLK + GPIO number of SPI SCLK config BT_BLE_LOG_SPI_OUT_CS_IO_NUM int "GPIO number of SPI CS" depends on BT_BLE_LOG_SPI_OUT_ENABLED default 2 help - GPIO number of SPI CS + GPIO number of SPI CS config BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED bool "Enable ble log & logic analyzer log time sync" depends on BT_BLE_LOG_SPI_OUT_ENABLED default y help - Enable ble log & logic analyzer log time sync + Enable ble log & logic analyzer log time sync config BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM int "GPIO number of SYNC IO" depends on BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED default 3 help - GPIO number of SYNC IO + GPIO number of SYNC IO diff --git a/components/bt/common/ble_log/ble_log_spi_out.c b/components/bt/common/ble_log/ble_log_spi_out.c index a85fc3bfc2..992df1cb7c 100644 --- a/components/bt/common/ble_log/ble_log_spi_out.c +++ b/components/bt/common/ble_log/ble_log_spi_out.c @@ -8,186 +8,575 @@ #if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED // Private defines +#define BLE_LOG_TAG "BLE_LOG" #define SPI_OUT_BUS SPI2_HOST -#define SPI_OUT_TAIL 0xAA +#define SPI_OUT_MAX_TRANSFER_SIZE 10240 +#define SPI_OUT_FRAME_HEAD_LEN 4 +#define SPI_OUT_FRAME_TAIL 0xAA +#define SPI_OUT_FRAME_TAIL_LEN 1 +#define SPI_OUT_FRAME_OVERHEAD (SPI_OUT_FRAME_HEAD_LEN + SPI_OUT_FRAME_TAIL_LEN) +#define SPI_OUT_RECYCLE_TIMEOUT 1000 +#define SPI_OUT_TRANS_CB_FLAG_AVAILABLE 0 +#define SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE 1 +#define SPI_OUT_TRANS_CB_FLAG_IN_QUEUE 2 #define SPI_OUT_FLUSHOUT_TIMEOUT (1000 * 1000) -#define SPI_OUT_TS_SYNC_TIMEOUT (1000 * 1000) - -// Private typedefs -typedef struct spi_out_trans { - spi_transaction_t trans; - struct spi_out_trans *next; -} spi_out_trans_t; - -// Private variables -static spi_device_handle_t spi_handle = NULL; -static spi_out_trans_t *trans_head = NULL; -static SemaphoreHandle_t mutex_handle = NULL; -static bool spi_out_inited = false; -static esp_timer_handle_t flushout_timer_handle = NULL; -static uint32_t loss_frame_cnt = 0; +#define SPI_OUT_PACKET_LOSS_UL 0 +#define SPI_OUT_PACKET_LOSS_LL_TASK 1 +#define SPI_OUT_PACKET_LOSS_LL_ISR 2 +#define SPI_OUT_PACKET_LOSS_FRAME_SIZE 6 +#define BLE_LOG_INTERFACE_FLAG_IN_ISR (1 << 3) #if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED -static bool sync_io_level = false; -static esp_timer_handle_t ts_sync_timer_handle = NULL; +#define SPI_OUT_TS_SYNC_TIMEOUT (1000 * 1000) #endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED -// Private function declarations -static void spi_out_init_trans(void); -static void spi_out_deinit_trans(void); -static void spi_out_recycle_trans(uint32_t ms_to_wait); -static void spi_out_append_trans(void); -static int spi_out_write(const uint8_t *addr, uint16_t len); -static void esp_timer_cb_flushout(void); -static void esp_timer_cb_ts_sync(void); +// Private typedefs +typedef struct { + // CRITICAL: 0 for available, 1 for need queue (ISR), 2 for in queue + // This flag is for multithreading, must be a word, do not modify + volatile uint32_t flag; + uint16_t buf_size; + uint16_t length; + spi_transaction_t trans; +} spi_out_trans_cb_t; + +typedef struct { + spi_out_trans_cb_t *trans_cb[2]; + uint8_t trans_cb_idx; + uint8_t frame_cnt; + uint32_t bytes_loss_cnt; + uint8_t trans_loss_cnt; +} spi_out_log_cb_t; + +// Private variables +static bool spi_out_inited = false; +static spi_device_handle_t spi_handle = NULL; +static bool timer_enabled = true; + +static bool ul_log_inited = false; +static SemaphoreHandle_t ul_log_mutex = NULL; +static spi_out_log_cb_t *ul_log_cb = NULL; +static esp_timer_handle_t ul_log_flushout_timer = NULL; + +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED +static bool ll_log_inited = false; +static bool ll_log_need_flushout = false; +static spi_out_log_cb_t *ll_task_log_cb = NULL; +static spi_out_log_cb_t *ll_isr_log_cb = NULL; +static esp_timer_handle_t ll_log_flushout_timer = NULL; +#endif // BT_BLE_LOG_SPI_OUT_LL_ENABLED #if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED -#if defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6) +static bool ts_sync_inited = false; +static bool sync_io_level = false; +static esp_timer_handle_t ts_sync_timer = NULL; +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED + +// Extern function declarations +extern void esp_panic_handler_feed_wdts(void); + +// Private function declarations +static int spi_out_init_trans(spi_out_trans_cb_t **trans_cb, uint16_t buf_size); +static void spi_out_deinit_trans(spi_out_trans_cb_t **trans_cb); +static void spi_out_tx_done_cb(spi_transaction_t *ret_trans); +static inline int spi_out_append_trans(spi_out_trans_cb_t *trans_cb); + +static int spi_out_log_cb_init(spi_out_log_cb_t **log_cb, uint16_t buf_size); +static void spi_out_log_cb_deinit(spi_out_log_cb_t **log_cb); +static inline int spi_out_log_cb_check_trans(spi_out_log_cb_t *log_cb, uint16_t len); +static inline void spi_out_log_cb_append_trans(spi_out_log_cb_t *log_cb, bool in_isr); +static inline void spi_out_log_cb_flush_trans(spi_out_log_cb_t *log_cb); +static void spi_out_log_cb_write(spi_out_log_cb_t *log_cb, const uint8_t *addr, uint16_t len, \ + const uint8_t *addr_append, uint16_t len_append, uint8_t source); +static inline void spi_out_log_cb_write_packet_loss(spi_out_log_cb_t *log_cb, uint8_t flag); +static void spi_out_log_cb_dump(spi_out_log_cb_t *log_cb); + +static int spi_out_ul_log_init(void); +static void spi_out_ul_log_deinit(void); +static void esp_timer_cb_ul_log_flushout(void); + +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED +static int spi_out_ll_log_init(void); +static void spi_out_ll_log_deinit(void); +static void spi_out_ll_log_ev_proc(void); +static void esp_timer_cb_ll_log_flushout(void); + +#if defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C5) ||\ + defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32H21) +extern void r_ble_log_simple_put_ev(void); +#define BLE_LOG_LL_PUT_EV r_ble_log_simple_put_ev() +#elif defined(CONFIG_IDF_TARGET_ESP32C2) +extern void ble_log_simple_put_ev(void); +#define BLE_LOG_LL_PUT_EV ble_log_simple_put_ev() +#else +#define BLE_LOG_LL_PUT_EV +#endif + +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + +#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED +static int spi_out_ts_sync_init(void); +static void spi_out_ts_sync_deinit(void); +static void esp_timer_cb_ts_sync(void); + +#if defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C5) ||\ + defined(CONFIG_IDF_TARGET_ESP32C61) || defined(CONFIG_IDF_TARGET_ESP32H21) extern uint32_t r_ble_lll_timer_current_tick_get(void); -#endif // CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6 -#if defined(CONFIG_IDF_TARGET_ESP32C2) +#define SPI_OUT_GET_LC_TIME r_ble_lll_timer_current_tick_get() +#elif defined(CONFIG_IDF_TARGET_ESP32C2) extern uint32_t r_os_cputime_get32(void); -#endif // CONFIG_IDF_TARGET_ESP32C2 +#define SPI_OUT_GET_LC_TIME r_os_cputime_get32() +#else +#define SPI_OUT_GET_LC_TIME 0 +#endif + #endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED // Private functions -static void spi_out_init_trans(void) +static int spi_out_init_trans(spi_out_trans_cb_t **trans_cb, uint16_t buf_size) { - for (int i = 0; i < CONFIG_BT_BLE_LOG_SPI_OUT_QUEUE_SIZE; i++) { - // Allocate memory for SPI transaction - uint8_t *buf = (uint8_t *)spi_bus_dma_memory_alloc(SPI_OUT_BUS, CONFIG_BT_BLE_LOG_SPI_OUT_TRANS_BUF_SIZE, 0); - assert(buf); - - // Initialize new trans - spi_out_trans_t *new_trans = (spi_out_trans_t *)malloc(sizeof(spi_out_trans_t)); - assert(new_trans); - memset(new_trans, 0, sizeof(spi_out_trans_t)); - new_trans->trans.tx_buffer = buf; - new_trans->trans.length = 0; - - // Append new trans to free trans list - new_trans->next = trans_head; - trans_head = new_trans; + // Memory allocations + *trans_cb = (spi_out_trans_cb_t *)malloc(sizeof(spi_out_trans_cb_t)); + if (!(*trans_cb)) { + return -1; } + uint8_t *buf = (uint8_t *)spi_bus_dma_memory_alloc(SPI_OUT_BUS, (size_t)buf_size, 0); + if (!buf) { + free(*trans_cb); + return -1; + } + + // Initialization + memset(*trans_cb, 0, sizeof(spi_out_trans_cb_t)); + (*trans_cb)->buf_size = buf_size; + (*trans_cb)->trans.tx_buffer = buf; + return 0; +} + +static void spi_out_deinit_trans(spi_out_trans_cb_t **trans_cb) +{ + if (!(*trans_cb)) { + return; + } + + free((uint8_t *)(*trans_cb)->trans.tx_buffer); + free(*trans_cb); + *trans_cb = NULL; return; } -static void spi_out_deinit_trans(void) +IRAM_ATTR static void spi_out_tx_done_cb(spi_transaction_t *ret_trans) { - // Wait up to QUEUE_SIZE * 100 ms for all transactions to complete and be recycled - spi_out_recycle_trans(100); - - // Release memory - spi_out_trans_t *next; - while (trans_head != NULL) { - next = trans_head->next; - free((uint8_t *)trans_head->trans.tx_buffer); - free(trans_head); - trans_head = next; - } - trans_head = NULL; - return; + spi_out_trans_cb_t *trans_cb = __containerof(ret_trans, spi_out_trans_cb_t, trans); + trans_cb->length = 0; + trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_AVAILABLE; } -// CRITICAL: Do not recycle trans when trans_head is not empty! -IRAM_ATTR static void spi_out_recycle_trans(uint32_t ms_to_wait) +IRAM_ATTR static inline int spi_out_append_trans(spi_out_trans_cb_t *trans_cb) { - // Try to recycle transaction - spi_transaction_t *ret_trans; - spi_out_trans_t *recycled_trans; - while (ESP_OK == spi_device_get_trans_result(spi_handle, &ret_trans, pdMS_TO_TICKS(ms_to_wait))) { - recycled_trans = __containerof(ret_trans, spi_out_trans_t, trans); - recycled_trans->next = trans_head; - trans_head = recycled_trans; - trans_head->trans.length = 0; - trans_head->trans.rxlength = 0; + if (trans_cb->flag != SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE) { + return -1; + } + + // CRITICAL: Length unit conversion from bytes to bits + trans_cb->trans.length = trans_cb->length * 8; + trans_cb->trans.rxlength = 0; + if (spi_device_queue_trans(spi_handle, &(trans_cb->trans), 0) == ESP_OK) { + trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_IN_QUEUE; + return 0; + } else { + return -1; } } -IRAM_ATTR static void spi_out_append_trans(void) +static int spi_out_log_cb_init(spi_out_log_cb_t **log_cb, uint16_t buf_size) { - // Stop flushout timer - esp_timer_stop(flushout_timer_handle); - - // Transaction head shall not be NULL for appending - if (trans_head) { - // Detach transaction head - spi_out_trans_t *trans_to_append = trans_head; - trans_head = trans_head->next; - trans_to_append->next = NULL; - - // CRITICAL: Length unit conversion from bytes to bits - trans_to_append->trans.length *= 8; - ESP_ERROR_CHECK(spi_device_queue_trans(spi_handle, &trans_to_append->trans, 0)); + // Initialize log control block + *log_cb = (spi_out_log_cb_t *)malloc(sizeof(spi_out_log_cb_t)); + if (!(*log_cb)) { + ESP_LOGE(BLE_LOG_TAG, "Failed to initialize log control block!"); + return -1; } + memset(*log_cb, 0, sizeof(spi_out_log_cb_t)); - // Try to recycle trans - spi_out_recycle_trans(0); - - // Restart flushout timer - esp_timer_start_once(flushout_timer_handle, SPI_OUT_FLUSHOUT_TIMEOUT); -} - -IRAM_ATTR static int spi_out_write(const uint8_t *addr, uint16_t len) -{ - // Recycle trans if free buffer list is empty - if (!trans_head) { - spi_out_recycle_trans(0); + // Initialize transactions + int ret = 0; + for (uint8_t i = 0; i < 2; i++) { + ret |= spi_out_init_trans(&((*log_cb)->trans_cb[i]), buf_size); } - - // Copy user data to buffer - uint16_t copy_buf_len; - uint16_t data_left_len = len; - uint16_t empty_buf_len = CONFIG_BT_BLE_LOG_SPI_OUT_TRANS_BUF_SIZE - trans_head->trans.length; - while (data_left_len) { - // There shall always be available buffer in free buffer list during write operation - if (!trans_head) { - return -1; - } - - // Copy data to buffer and update length - copy_buf_len = (data_left_len > empty_buf_len) ? empty_buf_len : data_left_len; - memcpy((uint8_t *)trans_head->trans.tx_buffer + trans_head->trans.length, addr + (len - data_left_len), copy_buf_len); - trans_head->trans.length += copy_buf_len; - data_left_len -= copy_buf_len; - - // If buffer is full, append transaction and reset buffer length - if (trans_head->trans.length == CONFIG_BT_BLE_LOG_SPI_OUT_TRANS_BUF_SIZE) { - spi_out_append_trans(); - empty_buf_len = CONFIG_BT_BLE_LOG_SPI_OUT_TRANS_BUF_SIZE; - } + if (ret != 0) { + ESP_LOGE(BLE_LOG_TAG, "Failed to initialize SPI transactions!"); + spi_out_log_cb_deinit(log_cb); + return -1; } return 0; } -// CRITICAL: This function is called in ESP Timer task -IRAM_ATTR static void esp_timer_cb_flushout(void) +static void spi_out_log_cb_deinit(spi_out_log_cb_t **log_cb) { - // Take semaphore - assert(xSemaphoreTakeRecursive(mutex_handle, portMAX_DELAY) == pdTRUE); - - // Flushout - if (trans_head) { - // Make sure there's enough space for loss frame counter - if (trans_head->next && loss_frame_cnt) { - ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_LOSS, (uint8_t *)&loss_frame_cnt, sizeof(loss_frame_cnt)); - loss_frame_cnt = 0; - } - if (trans_head->trans.length) { - spi_out_append_trans(); - } + if (!(*log_cb)) { + return; } - // Restart flushout timer if not active - if (!esp_timer_is_active(flushout_timer_handle)) { - esp_timer_start_once(flushout_timer_handle, SPI_OUT_FLUSHOUT_TIMEOUT); + for (uint8_t i = 0; i < 2; i++) { + if ((*log_cb)->trans_cb[i]) { + spi_out_deinit_trans(&((*log_cb)->trans_cb[i])); + } } - - // Release semaphore - xSemaphoreGiveRecursive(mutex_handle); + free(*log_cb); + return; } +IRAM_ATTR static inline int spi_out_log_cb_check_trans(spi_out_log_cb_t *log_cb, uint16_t len) +{ + spi_out_trans_cb_t *trans_cb; + uint16_t frame_len = len + SPI_OUT_FRAME_OVERHEAD; + for (uint8_t i = 0; i < 2; i++) { + trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx]; + if (frame_len > trans_cb->buf_size) { + goto failed; + } + if (trans_cb->flag == SPI_OUT_TRANS_CB_FLAG_AVAILABLE) { + if ((trans_cb->buf_size - trans_cb->length) >= (len + SPI_OUT_FRAME_OVERHEAD)) { + return 0; + } else { + trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE; + } + } + log_cb->trans_cb_idx = !(log_cb->trans_cb_idx); + } +failed: + log_cb->bytes_loss_cnt += len + SPI_OUT_FRAME_OVERHEAD; + log_cb->frame_cnt++; + return -1; +} + +IRAM_ATTR static inline void spi_out_log_cb_append_trans(spi_out_log_cb_t *log_cb, bool in_isr) +{ + spi_out_trans_cb_t *trans_cb; + uint8_t idx = !log_cb->trans_cb_idx; + for (uint8_t i = 0; i < 2; i++) { + trans_cb = log_cb->trans_cb[idx]; + if (trans_cb->flag == SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE) { + if (!in_isr) { + if (spi_out_append_trans(trans_cb) != 0) { + log_cb->trans_loss_cnt++; + } + } +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + else { + BLE_LOG_LL_PUT_EV; + return; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + } + idx = !idx; + } +} + +IRAM_ATTR static inline void spi_out_log_cb_flush_trans(spi_out_log_cb_t *log_cb) +{ + spi_out_trans_cb_t *trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx]; + if (trans_cb->length && (trans_cb->flag == SPI_OUT_TRANS_CB_FLAG_AVAILABLE)) { + trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE; + } +} + +IRAM_ATTR static void spi_out_log_cb_write(spi_out_log_cb_t *log_cb, const uint8_t *addr, uint16_t len, \ + const uint8_t *addr_append, uint16_t len_append, uint8_t source) +{ + spi_out_trans_cb_t *trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx]; + + uint8_t *buf = (uint8_t *)trans_cb->trans.tx_buffer + trans_cb->length; + uint16_t total_length = len + len_append; + const uint8_t head[4] = {total_length & 0xFF, (total_length >> 8) & 0xFF, source, log_cb->frame_cnt}; + + memcpy(buf, head, SPI_OUT_FRAME_HEAD_LEN); + memcpy(buf + SPI_OUT_FRAME_HEAD_LEN, addr, len); + if (len_append) { + memcpy(buf + SPI_OUT_FRAME_HEAD_LEN + len, addr_append, len_append); + } + buf[SPI_OUT_FRAME_HEAD_LEN + total_length] = SPI_OUT_FRAME_TAIL; + + trans_cb->length += total_length + SPI_OUT_FRAME_OVERHEAD; + log_cb->frame_cnt++; + if ((trans_cb->buf_size - trans_cb->length) <= SPI_OUT_FRAME_OVERHEAD) { + trans_cb->flag = SPI_OUT_TRANS_CB_FLAG_NEED_QUEUE; + } + return; +} + +IRAM_ATTR static inline void spi_out_log_cb_write_packet_loss(spi_out_log_cb_t *log_cb, uint8_t flag) +{ + if (log_cb->bytes_loss_cnt || log_cb->trans_loss_cnt) { + uint8_t packet_loss_frame[SPI_OUT_PACKET_LOSS_FRAME_SIZE]; + packet_loss_frame[0] = flag; + memcpy(packet_loss_frame + 1, (uint8_t *)&log_cb->bytes_loss_cnt, 4); + packet_loss_frame[5] = log_cb->trans_loss_cnt; + spi_out_log_cb_write(log_cb, packet_loss_frame, SPI_OUT_PACKET_LOSS_FRAME_SIZE, NULL, 0, BLE_LOG_SPI_OUT_SOURCE_LOSS); + log_cb->bytes_loss_cnt = 0; + log_cb->trans_loss_cnt = 0; + } +} + +static void spi_out_log_cb_dump(spi_out_log_cb_t *log_cb) +{ + spi_out_trans_cb_t *trans_cb; + uint8_t *buf; + for (uint8_t i = 0; i < 2; i++) { + // Dump the last transaction before dumping the current transaction + log_cb->trans_cb_idx = !(log_cb->trans_cb_idx); + trans_cb = log_cb->trans_cb[log_cb->trans_cb_idx]; + buf = (uint8_t *)trans_cb->trans.tx_buffer; + for (uint16_t j = 0; j < trans_cb->buf_size; j++) { + esp_rom_printf("%02x ", buf[j]); + + // Feed watchdogs periodically to avoid wdts timeout + if ((j % 100) == 0) { + esp_panic_handler_feed_wdts(); + } + } + } +} + +static int spi_out_ul_log_init(void) +{ + if (ul_log_inited) { + return 0; + } + + // Initialize mutex + ul_log_mutex = xSemaphoreCreateMutex(); + if (!ul_log_mutex) { + ESP_LOGE(BLE_LOG_TAG, "Failed to create mutex for upper layer task log!"); + goto mutex_init_failed; + } + + // Initialize flushout timer + esp_timer_create_args_t timer_args = { + .callback = (esp_timer_cb_t)esp_timer_cb_ul_log_flushout, + .dispatch_method = ESP_TIMER_TASK + }; + if (esp_timer_create(&timer_args, &ul_log_flushout_timer) != ESP_OK) { + ESP_LOGE(BLE_LOG_TAG, "Failed to initialize flushout timer upper layer task log!"); + goto timer_init_failed; + } + + // Initialize log control block + if (spi_out_log_cb_init(&ul_log_cb, CONFIG_BT_BLE_LOG_SPI_OUT_UL_TASK_BUF_SIZE) != 0) { + ESP_LOGE(BLE_LOG_TAG, "Failed to initialize log control blocks for upper layer task log!"); + goto log_cb_init_failed; + } + + // Initialization done + ESP_LOGI(BLE_LOG_TAG, "Succeeded to initialize upper layer task log!"); + ul_log_inited = true; + return 0; + +log_cb_init_failed: + esp_timer_delete(ul_log_flushout_timer); +timer_init_failed: + vSemaphoreDelete(ul_log_mutex); +mutex_init_failed: + return -1; +} + +static void spi_out_ul_log_deinit(void) +{ + if (!ul_log_inited) { + return; + } + + esp_timer_stop(ul_log_flushout_timer); + esp_timer_delete(ul_log_flushout_timer); + + xSemaphoreTake(ul_log_mutex, portMAX_DELAY); + spi_out_log_cb_deinit(&ul_log_cb); + xSemaphoreGive(ul_log_mutex); + + vSemaphoreDelete(ul_log_mutex); + ul_log_mutex = NULL; + + ESP_LOGI(BLE_LOG_TAG, "Succeeded to deinitialize upper layer log!"); + ul_log_inited = false; + return; +} + +IRAM_ATTR static void esp_timer_cb_ul_log_flushout(void) +{ + xSemaphoreTake(ul_log_mutex, portMAX_DELAY); + if (spi_out_log_cb_check_trans(ul_log_cb, SPI_OUT_PACKET_LOSS_FRAME_SIZE) == 0) { + spi_out_log_cb_write_packet_loss(ul_log_cb, SPI_OUT_PACKET_LOSS_UL); + } + spi_out_log_cb_flush_trans(ul_log_cb); + spi_out_log_cb_append_trans(ul_log_cb, false); + xSemaphoreGive(ul_log_mutex); + + if (timer_enabled) { + esp_timer_start_once(ul_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT); + } +} + +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED +static int spi_out_ll_log_init(void) +{ + if (ll_log_inited) { + return 0; + } + + // Initialize flushout timer + esp_timer_create_args_t timer_args = { + .callback = (esp_timer_cb_t)esp_timer_cb_ll_log_flushout, + .dispatch_method = ESP_TIMER_TASK + }; + if (esp_timer_create(&timer_args, &ll_log_flushout_timer) != ESP_OK) { + ESP_LOGE(BLE_LOG_TAG, "Failed to initialize flushout timer for controller log!"); + goto timer_init_failed; + } + + // Initialize log control blocks for controller task & ISR logs + if (spi_out_log_cb_init(&ll_task_log_cb, CONFIG_BT_BLE_LOG_SPI_OUT_LL_TASK_BUF_SIZE) != 0) { + ESP_LOGE(BLE_LOG_TAG, "Failed to initialize log control blocks for controller task!"); + goto task_log_cb_init_failed; + } + if (spi_out_log_cb_init(&ll_isr_log_cb, CONFIG_BT_BLE_LOG_SPI_OUT_LL_ISR_BUF_SIZE) != 0) { + ESP_LOGE(BLE_LOG_TAG, "Failed to initialize log control blocks for controller ISR!"); + goto isr_log_cb_init_failed; + } + + // Initialization done + ESP_LOGI(BLE_LOG_TAG, "Succeeded to initialize log control blocks for controller task & ISR!"); + ll_log_inited = true; + return 0; + +isr_log_cb_init_failed: + spi_out_log_cb_deinit(&ll_task_log_cb); +task_log_cb_init_failed: + esp_timer_delete(ll_log_flushout_timer); +timer_init_failed: + return -1; +} + +static void spi_out_ll_log_deinit(void) +{ + if (!ll_log_inited) { + return; + } + + esp_timer_stop(ll_log_flushout_timer); + esp_timer_delete(ll_log_flushout_timer); + + spi_out_log_cb_deinit(&ll_isr_log_cb); + spi_out_log_cb_deinit(&ll_task_log_cb); + + // Deinitialization done + ESP_LOGI(BLE_LOG_TAG, "Succeeded to deinitialize controller log!"); + ll_log_inited = false; + return; +} + +IRAM_ATTR static void spi_out_ll_log_ev_proc(void) +{ + // Request from LL ISR + if (!ll_log_need_flushout) { + esp_timer_stop(ll_log_flushout_timer); + spi_out_log_cb_append_trans(ll_isr_log_cb, false); + if (timer_enabled) { + esp_timer_start_once(ll_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT); + } + return; + } + + // Request from flushout timer + ll_log_need_flushout = false; + if (spi_out_log_cb_check_trans(ll_isr_log_cb, SPI_OUT_PACKET_LOSS_FRAME_SIZE) == 0) { + spi_out_log_cb_write_packet_loss(ll_isr_log_cb, SPI_OUT_PACKET_LOSS_LL_ISR); + } + spi_out_log_cb_flush_trans(ll_isr_log_cb); + spi_out_log_cb_append_trans(ll_isr_log_cb, false); + + if (spi_out_log_cb_check_trans(ll_task_log_cb, SPI_OUT_PACKET_LOSS_FRAME_SIZE) == 0) { + spi_out_log_cb_write_packet_loss(ll_task_log_cb, SPI_OUT_PACKET_LOSS_LL_TASK); + } + spi_out_log_cb_flush_trans(ll_task_log_cb); + spi_out_log_cb_append_trans(ll_task_log_cb, false); + if (timer_enabled) { + esp_timer_start_once(ll_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT); + } + return; +} + +IRAM_ATTR static void esp_timer_cb_ll_log_flushout(void) +{ + ll_log_need_flushout = true; + BLE_LOG_LL_PUT_EV; +} +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + #if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED +static int spi_out_ts_sync_init(void) +{ + if (ts_sync_inited) { + return 0; + } + + // Initialize sync timer + esp_timer_create_args_t timer_args = { + .callback = (esp_timer_cb_t)esp_timer_cb_ts_sync, + .dispatch_method = ESP_TIMER_TASK + }; + if (esp_timer_create(&timer_args, &ts_sync_timer) != ESP_OK) { + ESP_LOGE(BLE_LOG_TAG, "Failed to initialize timestamp synchronizer timer!"); + goto timer_init_failed; + } + + // Initialize sync IO + gpio_config_t io_conf = { + .intr_type = GPIO_INTR_DISABLE, + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = (1UL << CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM), + .pull_down_en = 0, + .pull_up_en = 0 + }; + if (gpio_config(&io_conf) != ESP_OK) { + ESP_LOGE(BLE_LOG_TAG, "Failed to initialize timestamp synchronizer IO!"); + goto gpio_init_failed; + } + + // Initialization done + ESP_LOGI(BLE_LOG_TAG, "Succeeded to initialize timestamp synchronizer!"); + sync_io_level = false; + gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, sync_io_level); + ts_sync_inited = true; + return 0; + +gpio_init_failed: + esp_timer_delete(ts_sync_timer); +timer_init_failed: + return -1; +} + +static void spi_out_ts_sync_deinit(void) +{ + if (!ts_sync_inited) { + return; + } + + // Deinitialize timestamp synchronizer + esp_timer_stop(ts_sync_timer); + esp_timer_delete(ts_sync_timer); + + // Deinitialize sync IO + sync_io_level = false; + gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, sync_io_level); + gpio_reset_pin(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM); + + // Deinitialization done + ESP_LOGI(BLE_LOG_TAG, "Succeeded to deinitialize timestamp synchronizer!"); + ts_sync_inited = false; + return; +} + // CRITICAL: This function is called in ESP Timer task IRAM_ATTR static void esp_timer_cb_ts_sync(void) { @@ -200,22 +589,17 @@ IRAM_ATTR static void esp_timer_cb_ts_sync(void) // Enter critical portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL_SAFE(&spinlock); + portENTER_CRITICAL(&spinlock); // Get LC timestamp -#if defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C6) - lc_ts = r_ble_lll_timer_current_tick_get(); -#endif // CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C6 -#if defined(CONFIG_IDF_TARGET_ESP32C2) - lc_ts = r_os_cputime_get32(); -#endif // CONFIG_IDF_TARGET_ESP32C2 + lc_ts = SPI_OUT_GET_LC_TIME; // Set sync IO level gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, (uint32_t)sync_io_level); // Get ESP timestamp esp_ts = esp_timer_get_time(); - portEXIT_CRITICAL_SAFE(&spinlock); + portEXIT_CRITICAL(&spinlock); // Exit critical // Write timestamp sync log @@ -228,16 +612,13 @@ IRAM_ATTR static void esp_timer_cb_ts_sync(void) #endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED // Public functions -void ble_log_spi_out_init(void) +int ble_log_spi_out_init(void) { // Avoid double init if (spi_out_inited) { - return; + return 0; } - // Initialize mutex - mutex_handle = xSemaphoreCreateRecursiveMutex(); - // Initialize SPI spi_bus_config_t bus_config = { .miso_io_num = -1, @@ -245,50 +626,69 @@ void ble_log_spi_out_init(void) .sclk_io_num = CONFIG_BT_BLE_LOG_SPI_OUT_SCLK_IO_NUM, .quadwp_io_num = -1, .quadhd_io_num = -1, - .max_transfer_sz = 10240 + .max_transfer_sz = SPI_OUT_MAX_TRANSFER_SIZE, + .intr_flags = ESP_INTR_FLAG_IRAM }; spi_device_interface_config_t dev_config = { .clock_speed_hz = SPI_MASTER_FREQ_20M, .mode = 0, .spics_io_num = CONFIG_BT_BLE_LOG_SPI_OUT_CS_IO_NUM, - .queue_size = CONFIG_BT_BLE_LOG_SPI_OUT_QUEUE_SIZE + .queue_size = 4 + 2, + .post_cb = (transaction_cb_t)spi_out_tx_done_cb, + .flags = SPI_DEVICE_NO_RETURN_RESULT }; - ESP_ERROR_CHECK(spi_bus_initialize(SPI_OUT_BUS, &bus_config, SPI_DMA_CH_AUTO)); - ESP_ERROR_CHECK(spi_bus_add_device(SPI_OUT_BUS, &dev_config, &spi_handle)); + if (spi_bus_initialize(SPI_OUT_BUS, &bus_config, SPI_DMA_CH_AUTO) != ESP_OK) { + ESP_LOGE(BLE_LOG_TAG, "Failed to initialize SPI bus!"); + goto spi_bus_init_failed; + } + if (spi_bus_add_device(SPI_OUT_BUS, &dev_config, &spi_handle) != ESP_OK) { + ESP_LOGE(BLE_LOG_TAG, "Failed to add device to SPI bus!"); + goto spi_device_add_failed; + } - // Initialize transaction link nodes - spi_out_init_trans(); + if (spi_out_ul_log_init() != 0) { + goto ul_log_init_failed; + } - // Initialize flushout timer - esp_timer_create_args_t timer_args = { - .callback = (esp_timer_cb_t)esp_timer_cb_flushout, - .dispatch_method = ESP_TIMER_TASK - }; - ESP_ERROR_CHECK(esp_timer_create(&timer_args, &flushout_timer_handle)); - esp_timer_start_once(flushout_timer_handle, SPI_OUT_FLUSHOUT_TIMEOUT); - loss_frame_cnt = 0; +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + if (spi_out_ll_log_init() != 0) { + goto ll_log_init_failed; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED #if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED - // Initialize timestamp synchronizer - gpio_config_t io_conf = { - .intr_type = GPIO_INTR_DISABLE, - .mode = GPIO_MODE_OUTPUT, - .pin_bit_mask = (1UL << CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM), - .pull_down_en = 0, - .pull_up_en = 0 - }; - ESP_ERROR_CHECK(gpio_config(&io_conf)); - sync_io_level = false; - gpio_set_level(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM, sync_io_level); - esp_timer_create_args_t ts_sync_timer_args = { - .callback = (esp_timer_cb_t)esp_timer_cb_ts_sync, - .dispatch_method = ESP_TIMER_TASK - }; - ESP_ERROR_CHECK(esp_timer_create(&ts_sync_timer_args, &ts_sync_timer_handle)); + if (spi_out_ts_sync_init() != 0) { + goto ts_sync_init_failed; + } #endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED - // Set init flag + // Initialization done + ESP_LOGI(BLE_LOG_TAG, "Succeeded to initialize BLE log SPI output interface!"); spi_out_inited = true; + + // Start flushout timer + esp_timer_start_once(ul_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT); + +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + esp_timer_start_once(ll_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + return 0; + +#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED +ts_sync_init_failed: +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + spi_out_ll_log_deinit(); +ll_log_init_failed: +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + spi_out_ul_log_deinit(); +ul_log_init_failed: + spi_bus_remove_device(spi_handle); + spi_handle = NULL; +spi_device_add_failed: + spi_bus_free(SPI_OUT_BUS); +spi_bus_init_failed: + return -1; } void ble_log_spi_out_deinit(void) @@ -299,27 +699,19 @@ void ble_log_spi_out_deinit(void) } #if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED - // Deinitialize timestamp synchronizer - esp_timer_stop(ts_sync_timer_handle); - esp_timer_delete(ts_sync_timer_handle); - gpio_reset_pin(CONFIG_BT_BLE_LOG_SPI_OUT_SYNC_IO_NUM); + spi_out_ts_sync_deinit(); #endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED - // Deinitialize flushout timer - esp_timer_stop(flushout_timer_handle); - esp_timer_delete(flushout_timer_handle); +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + spi_out_ll_log_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED - // Deinitialize transaction link nodes - spi_out_deinit_trans(); + spi_out_ul_log_deinit(); // Deinitialize SPI - ESP_ERROR_CHECK(spi_bus_remove_device(spi_handle)); - ESP_ERROR_CHECK(spi_bus_free(SPI_OUT_BUS)); + spi_bus_remove_device(spi_handle); spi_handle = NULL; - - // Deinitialize mutex - vSemaphoreDelete(mutex_handle); - mutex_handle = NULL; + spi_bus_free(SPI_OUT_BUS); // Reset init flag spi_out_inited = false; @@ -334,9 +726,9 @@ void ble_log_spi_out_ts_sync_start(void) } // Start timestamp sync timer - if (ts_sync_timer_handle) { - if (!esp_timer_is_active(ts_sync_timer_handle)) { - esp_timer_start_periodic(ts_sync_timer_handle, SPI_OUT_TS_SYNC_TIMEOUT); + if (ts_sync_timer) { + if (!esp_timer_is_active(ts_sync_timer)) { + esp_timer_start_periodic(ts_sync_timer, SPI_OUT_TS_SYNC_TIMEOUT); } } } @@ -349,9 +741,9 @@ void ble_log_spi_out_ts_sync_stop(void) } // Stop timestamp sync timer - if (ts_sync_timer_handle) { - if (esp_timer_is_active(ts_sync_timer_handle)) { - esp_timer_stop(ts_sync_timer_handle); + if (ts_sync_timer) { + if (esp_timer_is_active(ts_sync_timer)) { + esp_timer_stop(ts_sync_timer); } // Set sync IO to low level @@ -361,51 +753,56 @@ void ble_log_spi_out_ts_sync_stop(void) } #endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED -IRAM_ATTR void ble_log_spi_out_write_esp(uint32_t len, const uint8_t *addr, bool end) +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED +// Only LL task has access to this API +IRAM_ATTR void ble_log_spi_out_ll_write(uint32_t len, const uint8_t *addr, uint32_t len_append,\ + const uint8_t *addr_append, uint32_t flag) { - return ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_ESP, addr, len); + if (!ll_log_inited) { + return; + } + + bool in_isr = (bool)(flag & BLE_LOG_INTERFACE_FLAG_IN_ISR); + uint8_t source = in_isr ? BLE_LOG_SPI_OUT_SOURCE_ESP_ISR : BLE_LOG_SPI_OUT_SOURCE_ESP; + spi_out_log_cb_t *log_cb = in_isr ? ll_isr_log_cb : ll_task_log_cb; + uint16_t total_length = (uint16_t)(len + len_append); + if (spi_out_log_cb_check_trans(log_cb, total_length) == 0) { + spi_out_log_cb_write(log_cb, addr, (uint16_t)len, addr_append, (uint16_t)len_append, source); + } + spi_out_log_cb_append_trans(log_cb, in_isr); + return; } -IRAM_ATTR void ble_log_spi_out_write(uint8_t source, const uint8_t *addr, uint16_t len) +IRAM_ATTR void ble_log_spi_out_ll_log_ev_proc(void) { - // Initialize frame sequence number - static uint8_t frame_sn = 0; + if (!ll_log_inited) { + return; + } + return spi_out_ll_log_ev_proc(); +} +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED - // Take semaphore - assert(xSemaphoreTakeRecursive(mutex_handle, portMAX_DELAY) == pdTRUE); +IRAM_ATTR int ble_log_spi_out_write(uint8_t source, const uint8_t *addr, uint16_t len) +{ + if (!ul_log_inited) { + return -1; + } - // Prepare frame head and frame tail - const uint8_t head[4] = {len & 0xFF, (len >> 8) & 0xFF, (uint8_t)source, frame_sn}; - const uint8_t tail = SPI_OUT_TAIL; - - // Write frame head first, then payload, finally frame tail - do { - if (spi_out_write(head, 4) != 0) { - loss_frame_cnt++; - break; - } - if (spi_out_write(addr, len) != 0) { - loss_frame_cnt++; - break; - } - if (spi_out_write(&tail, 1) != 0) { - loss_frame_cnt++; - break; - } - } while (0); - - // Update frame sequence number - frame_sn++; - - // Release semaphore - xSemaphoreGiveRecursive(mutex_handle); - return; + xSemaphoreTake(ul_log_mutex, portMAX_DELAY); + int ret = spi_out_log_cb_check_trans(ul_log_cb, len); + if (ret == 0) { + spi_out_log_cb_write(ul_log_cb, addr, len, NULL, 0, source); + } + spi_out_log_cb_append_trans(ul_log_cb, false); + xSemaphoreGive(ul_log_mutex); + return ret; } IRAM_ATTR int ble_log_spi_out_printf(uint8_t source, const char *format, ...) { - // Get esp timestamp - uint32_t esp_ts = esp_timer_get_time(); + if (!ul_log_inited) { + return -1; + } // Get arguments va_list args; @@ -434,19 +831,25 @@ IRAM_ATTR int ble_log_spi_out_printf(uint8_t source, const char *format, ...) vsnprintf((char *)buffer, len + 1, format, args); va_end(args); - // Write to SPI - ble_log_spi_out_write(source, (const uint8_t *)&esp_ts, 4); - ble_log_spi_out_write(source, (const uint8_t *)buffer, len); + uint32_t esp_ts = esp_timer_get_time(); + xSemaphoreTake(ul_log_mutex, portMAX_DELAY); + int ret = spi_out_log_cb_check_trans(ul_log_cb, 4 + len); + if (ret == 0) { + spi_out_log_cb_write(ul_log_cb, (const uint8_t *)&esp_ts, 4, (const uint8_t *)buffer, len, source); + } + spi_out_log_cb_append_trans(ul_log_cb, false); + xSemaphoreGive(ul_log_mutex); // Release free(buffer); - return 0; + return ret; } IRAM_ATTR int ble_log_spi_out_printf_enh(uint8_t source, uint8_t level, const char *tag, const char *format, ...) { - // Get ESP timestamp - uint32_t esp_ts = esp_timer_get_time(); + if (!ul_log_inited) { + return -1; + } // Create log prefix in the format: "[level][tag] " char prefix[32]; @@ -481,22 +884,91 @@ IRAM_ATTR int ble_log_spi_out_printf_enh(uint8_t source, uint8_t level, const ch vsnprintf((char *)(buffer + prefix_len), log_len + 1, format, args); va_end(args); - // Transmit log data via SPI - ble_log_spi_out_write(source, (const uint8_t *)&esp_ts, 4); - ble_log_spi_out_write(source, buffer, total_len); - - // Free allocated memory - free(buffer); - return 0; -} - -IRAM_ATTR void ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len) -{ - // Get esp timestamp uint32_t esp_ts = esp_timer_get_time(); + xSemaphoreTake(ul_log_mutex, portMAX_DELAY); + int ret = spi_out_log_cb_check_trans(ul_log_cb, 4 + total_len); + if (ret == 0) { + spi_out_log_cb_write(ul_log_cb, (const uint8_t *)&esp_ts, 4, (const uint8_t *)buffer, total_len, source); + } + spi_out_log_cb_append_trans(ul_log_cb, false); + xSemaphoreGive(ul_log_mutex); - // Write to SPI - ble_log_spi_out_write(source, (const uint8_t *)&esp_ts, 4); - ble_log_spi_out_write(source, addr, len); + free(buffer); + return ret; } + +IRAM_ATTR int ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len) +{ + if (!ul_log_inited) { + return -1; + } + + uint32_t esp_ts = esp_timer_get_time(); + xSemaphoreTake(ul_log_mutex, portMAX_DELAY); + int ret = spi_out_log_cb_check_trans(ul_log_cb, 4 + len); + if (ret == 0) { + spi_out_log_cb_write(ul_log_cb, (const uint8_t *)&esp_ts, 4, addr, len, source); + } + spi_out_log_cb_append_trans(ul_log_cb, false); + xSemaphoreGive(ul_log_mutex); + return ret; +} + +void ble_log_spi_out_dump_all(void) +{ + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + if (ll_log_inited) { + // Dump lower layer log buffer + esp_rom_printf("[LL_ISR_LOG_DUMP_START:\n"); + spi_out_log_cb_dump(ll_isr_log_cb); + esp_rom_printf("\n:LL_ISR_LOG_DUMP_END]\n\n"); + + esp_rom_printf("[LL_TASK_LOG_DUMP_START:\n"); + spi_out_log_cb_dump(ll_task_log_cb); + esp_rom_printf("\n:LL_TASK_LOG_DUMP_END]\n\n"); + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + + if (ul_log_inited) { + // Dump upper layer log buffer + esp_rom_printf("[UL_LOG_DUMP_START:\n"); + spi_out_log_cb_dump(ul_log_cb); + esp_rom_printf("\n:UL_LOG_DUMP_END]\n\n"); + } + portEXIT_CRITICAL_SAFE(&spinlock); +} + +void ble_log_spi_out_timer_control(bool enable) +{ + timer_enabled = enable; + if (enable) { + if (!esp_timer_is_active(ul_log_flushout_timer)) { + esp_timer_start_once(ul_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT); + } + +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + if (!esp_timer_is_active(ll_log_flushout_timer)) { + esp_timer_start_once(ll_log_flushout_timer, SPI_OUT_FLUSHOUT_TIMEOUT); + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + +#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED + ble_log_spi_out_ts_sync_start(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED + } else { + esp_timer_stop(ul_log_flushout_timer); + +#if CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + esp_timer_stop(ll_log_flushout_timer); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_LL_ENABLED + +#if CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED + ble_log_spi_out_ts_sync_stop(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_TS_SYNC_ENABLED + } +} + #endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED diff --git a/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h b/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h index c1a4506637..1b22ad5f42 100644 --- a/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h +++ b/components/bt/common/ble_log/include/ble_log/ble_log_spi_out.h @@ -11,6 +11,7 @@ #include "driver/spi_master.h" #include "driver/gpio.h" #include "esp_timer.h" +#include "esp_log.h" #include "freertos/semphr.h" // Public typedefs @@ -20,6 +21,8 @@ #define BLE_LOG_SPI_OUT_SOURCE_NIMBLE 3 #define BLE_LOG_SPI_OUT_SOURCE_HCI_UPSTREAM 4 #define BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM 5 +#define BLE_LOG_SPI_OUT_SOURCE_ESP_ISR 6 +#define BLE_LOG_SPI_OUT_SOURCE_ESP_LEGACY_ISR 7 #define BLE_LOG_SPI_OUT_SOURCE_USER 0x10 #define BLE_LOG_SPI_OUT_SOURCE_SYNC 0xFE #define BLE_LOG_SPI_OUT_SOURCE_LOSS 0xFF @@ -34,14 +37,18 @@ #define BLE_LOG_SPI_OUT_LEVEL_MAX 6 /*!< Number of SPI log levels supported */ // Public functions -void ble_log_spi_out_init(void); +int ble_log_spi_out_init(void); void ble_log_spi_out_deinit(void); -void ble_log_spi_out_write(uint8_t source, const uint8_t *addr, uint16_t len); -void ble_log_spi_out_write_esp(uint32_t len, const uint8_t *addr, bool end); +void ble_log_spi_out_timer_control(bool enable); +int ble_log_spi_out_write(uint8_t source, const uint8_t *addr, uint16_t len); +void ble_log_spi_out_ll_write(uint32_t len, const uint8_t *addr, uint32_t len_append,\ + const uint8_t *addr_append, uint32_t flag); +void ble_log_spi_out_ll_log_ev_proc(void); void ble_log_spi_out_ts_sync_start(void); void ble_log_spi_out_ts_sync_stop(void); int ble_log_spi_out_printf(uint8_t source, const char *format, ...); int ble_log_spi_out_printf_enh(uint8_t source, uint8_t level, const char *tag, const char *format, ...); -void ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len); +int ble_log_spi_out_write_with_ts(uint8_t source, const uint8_t *addr, uint16_t len); +void ble_log_spi_out_dump_all(void); #endif // __BT_SPI_OUT_H__ From 0645197a460cf79f50e333dc434553687c766721 Mon Sep 17 00:00:00 2001 From: Geng Yuchao Date: Fri, 14 Mar 2025 16:40:49 +0800 Subject: [PATCH 15/17] fix(ble): Add link requires esp_phy for ble. --- components/bt/CMakeLists.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 0ee0335b20..52def1a1db 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -910,17 +910,21 @@ if(CONFIG_BT_ENABLED) endif() if(CONFIG_IDF_TARGET_ESP32C6) add_prebuilt_library(libble_app - "${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c6/libble_app.a") + "${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c6/libble_app.a" + REQUIRES esp_phy) elseif(CONFIG_IDF_TARGET_ESP32C61) add_prebuilt_library(libble_app - "${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c61/libble_app.a") + "${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c61/libble_app.a" + REQUIRES esp_phy) else() if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY AND CONFIG_IDF_TARGET_ESP32C2) add_prebuilt_library(libble_app - "controller/lib_${target_name}/${target_name}-bt-lib/libble_app_flash.a") + "controller/lib_${target_name}/${target_name}-bt-lib/libble_app_flash.a" + REQUIRES esp_phy) else() add_prebuilt_library(libble_app - "controller/lib_${target_name}/${target_name}-bt-lib/libble_app.a") + "controller/lib_${target_name}/${target_name}-bt-lib/libble_app.a" + REQUIRES esp_phy) endif() endif() target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app) From e1920ec42f19384905d42bffcc30e63c14acc3f7 Mon Sep 17 00:00:00 2001 From: Shen Weilong Date: Wed, 2 Apr 2025 10:34:06 +0800 Subject: [PATCH 16/17] feat(ble/controller): Added memory boundary check for ESP32-C6/C5/H2/C2/C61 --- components/bt/controller/esp32c2/ble.c | 15 ++++++++++++++- components/bt/controller/esp32c5/Kconfig.in | 4 ++++ components/bt/controller/esp32c5/ble.c | 7 +++++++ components/bt/controller/esp32c5/esp_bt_cfg.h | 6 ++++++ components/bt/controller/esp32c6/Kconfig.in | 5 ++++- components/bt/controller/esp32c6/ble.c | 13 +++++++++++++ components/bt/controller/esp32c6/esp_bt_cfg.h | 6 ++++++ components/bt/controller/esp32h2/Kconfig.in | 5 ++++- components/bt/controller/esp32h2/ble.c | 7 +++++++ components/bt/controller/esp32h2/esp_bt_cfg.h | 6 ++++++ .../bt/controller/lib_esp32c2/esp32c2-bt-lib | 2 +- .../bt/controller/lib_esp32c5/esp32c5-bt-lib | 2 +- .../bt/controller/lib_esp32c6/esp32c6-bt-lib | 2 +- .../bt/controller/lib_esp32h2/esp32h2-bt-lib | 2 +- components/bt/include/esp32c5/include/esp_bt.h | 2 ++ components/bt/include/esp32c6/include/esp_bt.h | 3 +++ components/bt/include/esp32h2/include/esp_bt.h | 2 ++ .../esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld | 4 ++-- components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld | 2 +- 19 files changed, 85 insertions(+), 10 deletions(-) diff --git a/components/bt/controller/esp32c2/ble.c b/components/bt/controller/esp32c2/ble.c index 9ea49196e5..dd6db35eed 100644 --- a/components/bt/controller/esp32c2/ble.c +++ b/components/bt/controller/esp32c2/ble.c @@ -12,9 +12,14 @@ ************************************************************************ */ #if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) -void adv_stack_enableClearLegacyAdvVsCmd(bool en); void scan_stack_enableAdvFlowCtrlVsCmd(bool en); +void adv_stack_enableClearLegacyAdvVsCmd(bool en); void chanSel_stack_enableSetCsaVsCmd(bool en); +void hci_stack_enableSetVsEvtMaskVsCmd(bool en); + +void adv_stack_enableScanReqRxdVsEvent(bool en); +void conn_stack_enableChanMapUpdCompVsEvent(bool en); +void sleep_stack_enableWakeupVsEvent(bool en); #endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) /* Local functions definition @@ -32,10 +37,18 @@ void ble_stack_enableVsCmds(bool en) #endif // DEFAULT_BT_LE_ROLE_OBSERVER chanSel_stack_enableSetCsaVsCmd(en); + hci_stack_enableSetVsEvtMaskVsCmd(en); } void ble_stack_enableVsEvents(bool en) { +#if DEFAULT_BT_LE_ROLE_BROADCASTER + adv_stack_enableScanReqRxdVsEvent(en); +#endif // DEFAULT_BT_LE_ROLE_BROADCASTER + conn_stack_enableChanMapUpdCompVsEvent(en); +#if CONFIG_BT_LE_SLEEP_ENABLE + sleep_stack_enableWakeupVsEvent(en); +#endif // CONFIG_BT_LE_SLEEP_ENABLE } #endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) diff --git a/components/bt/controller/esp32c5/Kconfig.in b/components/bt/controller/esp32c5/Kconfig.in index 5058bf0fb3..fbd1269355 100644 --- a/components/bt/controller/esp32c5/Kconfig.in +++ b/components/bt/controller/esp32c5/Kconfig.in @@ -402,6 +402,10 @@ menu "Controller debug features" default n help Retain scene with GDB to capture info, requires disabling WDT (CONFIG_ESP_INT_WDT, CONFIG_ESP_TASK_WDT_EN). + + config BT_LE_PTR_CHECK_ENABLED + bool "Enable boundary check for internal memory" + default n endmenu config BT_LE_LL_RESOLV_LIST_SIZE diff --git a/components/bt/controller/esp32c5/ble.c b/components/bt/controller/esp32c5/ble.c index 7b50ca8ce9..caa8d85543 100644 --- a/components/bt/controller/esp32c5/ble.c +++ b/components/bt/controller/esp32c5/ble.c @@ -38,9 +38,11 @@ void pcl_stack_enableSetRssiThreshVsCmd(bool en); void chanSel_stack_enableSetCsaVsCmd(bool en); void log_stack_enableLogsRelatedVsCmd(bool en); void hci_stack_enableSetVsEvtMaskVsCmd(bool en); +void winWiden_stack_enableSetConstPeerScaVsCmd(bool en); void adv_stack_enableScanReqRxdVsEvent(bool en); void conn_stack_enableChanMapUpdCompVsEvent(bool en); +void sleep_stack_enableWakeupVsEvent(bool en); #endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) /* Local functions definition @@ -57,12 +59,17 @@ void ble_stack_enableVsCmds(bool en) chanSel_stack_enableSetCsaVsCmd(en); log_stack_enableLogsRelatedVsCmd(en); hci_stack_enableSetVsEvtMaskVsCmd(en); + winWiden_stack_enableSetConstPeerScaVsCmd(en); } void ble_stack_enableVsEvents(bool en) { adv_stack_enableScanReqRxdVsEvent(en); conn_stack_enableChanMapUpdCompVsEvent(en); + +#if CONFIG_BT_LE_SLEEP_ENABLE + sleep_stack_enableWakeupVsEvent(en); +#endif // CONFIG_BT_LE_SLEEP_ENABLE } #endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) diff --git a/components/bt/controller/esp32c5/esp_bt_cfg.h b/components/bt/controller/esp32c5/esp_bt_cfg.h index 3d8edd55de..6621c28cb4 100644 --- a/components/bt/controller/esp32c5/esp_bt_cfg.h +++ b/components/bt/controller/esp32c5/esp_bt_cfg.h @@ -204,6 +204,12 @@ extern "C" { #define DEFAULT_BT_LE_VHCI_ENABLED (0) #endif +#ifdef CONFIG_BT_LE_PTR_CHECK_ENABLED +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (CONFIG_BT_LE_PTR_CHECK_ENABLED) +#else +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (0) +#endif + #ifdef CONFIG_BT_LE_SLEEP_ENABLE #define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE #else diff --git a/components/bt/controller/esp32c6/Kconfig.in b/components/bt/controller/esp32c6/Kconfig.in index 18b4039895..a9e59ae032 100644 --- a/components/bt/controller/esp32c6/Kconfig.in +++ b/components/bt/controller/esp32c6/Kconfig.in @@ -1,6 +1,5 @@ menu "HCI Config" - choice BT_LE_HCI_INTERFACE prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM @@ -444,6 +443,10 @@ menu "Controller debug features" default n help Retain scene with GDB to capture info, requires disabling WDT (CONFIG_ESP_INT_WDT, CONFIG_ESP_TASK_WDT_EN). + + config BT_LE_PTR_CHECK_ENABLED + bool "Enable boundary check for internal memory" + default n endmenu config BT_LE_LL_RESOLV_LIST_SIZE diff --git a/components/bt/controller/esp32c6/ble.c b/components/bt/controller/esp32c6/ble.c index 7b50ca8ce9..f93f15e9b8 100644 --- a/components/bt/controller/esp32c6/ble.c +++ b/components/bt/controller/esp32c6/ble.c @@ -38,9 +38,14 @@ void pcl_stack_enableSetRssiThreshVsCmd(bool en); void chanSel_stack_enableSetCsaVsCmd(bool en); void log_stack_enableLogsRelatedVsCmd(bool en); void hci_stack_enableSetVsEvtMaskVsCmd(bool en); +void winWiden_stack_enableSetConstPeerScaVsCmd(bool en); +#if CONFIG_IDF_TARGET_ESP32C61_ECO3 +void conn_stack_enableSetPrefTxRxCntVsCmd(bool en); +#endif // CONFIG_IDF_TARGET_ESP32C61_ECO3 void adv_stack_enableScanReqRxdVsEvent(bool en); void conn_stack_enableChanMapUpdCompVsEvent(bool en); +void sleep_stack_enableWakeupVsEvent(bool en); #endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) /* Local functions definition @@ -57,12 +62,20 @@ void ble_stack_enableVsCmds(bool en) chanSel_stack_enableSetCsaVsCmd(en); log_stack_enableLogsRelatedVsCmd(en); hci_stack_enableSetVsEvtMaskVsCmd(en); + winWiden_stack_enableSetConstPeerScaVsCmd(en); +#if CONFIG_IDF_TARGET_ESP32C61_ECO3 + conn_stack_enableSetPrefTxRxCntVsCmd(en); +#endif // CONFIG_IDF_TARGET_ESP32C61_ECO3 } void ble_stack_enableVsEvents(bool en) { adv_stack_enableScanReqRxdVsEvent(en); conn_stack_enableChanMapUpdCompVsEvent(en); + +#if CONFIG_BT_LE_SLEEP_ENABLE + sleep_stack_enableWakeupVsEvent(en); +#endif // CONFIG_BT_LE_SLEEP_ENABLE } #endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) diff --git a/components/bt/controller/esp32c6/esp_bt_cfg.h b/components/bt/controller/esp32c6/esp_bt_cfg.h index 3d8edd55de..6621c28cb4 100644 --- a/components/bt/controller/esp32c6/esp_bt_cfg.h +++ b/components/bt/controller/esp32c6/esp_bt_cfg.h @@ -204,6 +204,12 @@ extern "C" { #define DEFAULT_BT_LE_VHCI_ENABLED (0) #endif +#ifdef CONFIG_BT_LE_PTR_CHECK_ENABLED +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (CONFIG_BT_LE_PTR_CHECK_ENABLED) +#else +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (0) +#endif + #ifdef CONFIG_BT_LE_SLEEP_ENABLE #define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE #else diff --git a/components/bt/controller/esp32h2/Kconfig.in b/components/bt/controller/esp32h2/Kconfig.in index 858a772217..b07e4783a8 100644 --- a/components/bt/controller/esp32h2/Kconfig.in +++ b/components/bt/controller/esp32h2/Kconfig.in @@ -1,6 +1,5 @@ menu "HCI Config" - choice BT_LE_HCI_INTERFACE prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM @@ -438,6 +437,10 @@ menu "Controller debug features" default n help Retain scene with GDB to capture info, requires disabling WDT (CONFIG_ESP_INT_WDT, CONFIG_ESP_TASK_WDT_EN). + + config BT_LE_PTR_CHECK_ENABLED + bool "Enable boundary check for internal memory" + default n endmenu config BT_LE_LL_RESOLV_LIST_SIZE diff --git a/components/bt/controller/esp32h2/ble.c b/components/bt/controller/esp32h2/ble.c index 7b50ca8ce9..caa8d85543 100644 --- a/components/bt/controller/esp32h2/ble.c +++ b/components/bt/controller/esp32h2/ble.c @@ -38,9 +38,11 @@ void pcl_stack_enableSetRssiThreshVsCmd(bool en); void chanSel_stack_enableSetCsaVsCmd(bool en); void log_stack_enableLogsRelatedVsCmd(bool en); void hci_stack_enableSetVsEvtMaskVsCmd(bool en); +void winWiden_stack_enableSetConstPeerScaVsCmd(bool en); void adv_stack_enableScanReqRxdVsEvent(bool en); void conn_stack_enableChanMapUpdCompVsEvent(bool en); +void sleep_stack_enableWakeupVsEvent(bool en); #endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) /* Local functions definition @@ -57,12 +59,17 @@ void ble_stack_enableVsCmds(bool en) chanSel_stack_enableSetCsaVsCmd(en); log_stack_enableLogsRelatedVsCmd(en); hci_stack_enableSetVsEvtMaskVsCmd(en); + winWiden_stack_enableSetConstPeerScaVsCmd(en); } void ble_stack_enableVsEvents(bool en) { adv_stack_enableScanReqRxdVsEvent(en); conn_stack_enableChanMapUpdCompVsEvent(en); + +#if CONFIG_BT_LE_SLEEP_ENABLE + sleep_stack_enableWakeupVsEvent(en); +#endif // CONFIG_BT_LE_SLEEP_ENABLE } #endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) diff --git a/components/bt/controller/esp32h2/esp_bt_cfg.h b/components/bt/controller/esp32h2/esp_bt_cfg.h index 3d8edd55de..6621c28cb4 100644 --- a/components/bt/controller/esp32h2/esp_bt_cfg.h +++ b/components/bt/controller/esp32h2/esp_bt_cfg.h @@ -204,6 +204,12 @@ extern "C" { #define DEFAULT_BT_LE_VHCI_ENABLED (0) #endif +#ifdef CONFIG_BT_LE_PTR_CHECK_ENABLED +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (CONFIG_BT_LE_PTR_CHECK_ENABLED) +#else +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (0) +#endif + #ifdef CONFIG_BT_LE_SLEEP_ENABLE #define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE #else diff --git a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib index 1e88fa4606..c0d98a9a03 160000 --- a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib +++ b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib @@ -1 +1 @@ -Subproject commit 1e88fa4606b62faf7350ac12d4317ab4d1cd286d +Subproject commit c0d98a9a03c266828a25bed38c0174ecfc882aea diff --git a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib index a1edef01cb..4ff56a052a 160000 --- a/components/bt/controller/lib_esp32c5/esp32c5-bt-lib +++ b/components/bt/controller/lib_esp32c5/esp32c5-bt-lib @@ -1 +1 @@ -Subproject commit a1edef01cbbbc99126e8233a44e97f752bc93a0e +Subproject commit 4ff56a052ab888be3b4abe548f86052fa314d10c diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index b75747061f..246541ab93 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit b75747061f79a6eb070b5b0f96ebda79bffee485 +Subproject commit 246541ab93e853eba1591784a5253b219c0414f9 diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index cd36ec849c..a3192174a9 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit cd36ec849cbfc8cef8dd48228ca70fffc1e240a3 +Subproject commit a3192174a9aef015a9ceca983acdb9fd1a198445 diff --git a/components/bt/include/esp32c5/include/esp_bt.h b/components/bt/include/esp32c5/include/esp_bt.h index d045553168..ec292a573d 100644 --- a/components/bt/include/esp32c5/include/esp_bt.h +++ b/components/bt/include/esp32c5/include/esp_bt.h @@ -225,6 +225,7 @@ typedef struct { - 0 - Disable (default) - 1 - Enable */ uint8_t vhci_enabled; /*!< VHCI mode is enabled */ + uint8_t ptr_check_enabled; /*!< Enable boundary check for internal memory. */ uint32_t config_magic; /*!< Magic number for configuration validation */ } esp_bt_controller_config_t; @@ -279,6 +280,7 @@ typedef struct { .ble_chan_ass_en = DEFAULT_BT_LE_CTRL_CHAN_ASS_EN, \ .ble_data_lenth_zero_aux = DEFAULT_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX, \ .vhci_enabled = DEFAULT_BT_LE_VHCI_ENABLED, \ + .ptr_check_enabled = DEFAULT_BT_LE_PTR_CHECK_ENABLED, \ .config_magic = CONFIG_MAGIC, \ } diff --git a/components/bt/include/esp32c6/include/esp_bt.h b/components/bt/include/esp32c6/include/esp_bt.h index b3ada150c0..9da4cbe8f4 100644 --- a/components/bt/include/esp32c6/include/esp_bt.h +++ b/components/bt/include/esp32c6/include/esp_bt.h @@ -225,6 +225,7 @@ typedef struct { - 0 - Disable (default) - 1 - Enable */ uint8_t vhci_enabled; /*!< VHCI mode is enabled */ + uint8_t ptr_check_enabled; /*!< Enable boundary check for internal memory. */ uint32_t config_magic; /*!< Magic number for configuration validation */ } esp_bt_controller_config_t; @@ -282,6 +283,7 @@ typedef struct { .ble_chan_ass_en = DEFAULT_BT_LE_CTRL_CHAN_ASS_EN, \ .ble_data_lenth_zero_aux = DEFAULT_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX, \ .vhci_enabled = DEFAULT_BT_LE_VHCI_ENABLED, \ + .ptr_check_enabled = DEFAULT_BT_LE_PTR_CHECK_ENABLED, \ .config_magic = CONFIG_MAGIC, \ } #elif CONFIG_IDF_TARGET_ESP32C61 @@ -336,6 +338,7 @@ typedef struct { .ble_chan_ass_en = DEFAULT_BT_LE_CTRL_CHAN_ASS_EN, \ .ble_data_lenth_zero_aux = DEFAULT_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX, \ .vhci_enabled = DEFAULT_BT_LE_VHCI_ENABLED, \ + .ptr_check_enabled = DEFAULT_BT_LE_PTR_CHECK_ENABLED, \ .config_magic = CONFIG_MAGIC, \ } #endif diff --git a/components/bt/include/esp32h2/include/esp_bt.h b/components/bt/include/esp32h2/include/esp_bt.h index 9a7545b25c..6b412834c0 100644 --- a/components/bt/include/esp32h2/include/esp_bt.h +++ b/components/bt/include/esp32h2/include/esp_bt.h @@ -227,6 +227,7 @@ typedef struct { - 0 - Disable (default) - 1 - Enable */ uint8_t vhci_enabled; /*!< VHCI is enabled */ + uint8_t ptr_check_enabled; /*!< Enable boundary check for internal memory. */ uint32_t config_magic; /*!< Configuration magic value */ } esp_bt_controller_config_t; @@ -282,6 +283,7 @@ typedef struct { .ble_chan_ass_en = DEFAULT_BT_LE_CTRL_CHAN_ASS_EN, \ .ble_data_lenth_zero_aux = DEFAULT_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX, \ .vhci_enabled = DEFAULT_BT_LE_VHCI_ENABLED, \ + .ptr_check_enabled = DEFAULT_BT_LE_PTR_CHECK_ENABLED, \ .config_magic = CONFIG_MAGIC, \ } diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld index c94f6afa13..2281a139cc 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld @@ -144,7 +144,7 @@ r_ble_ll_adv_reset = 0x40000c88; r_ble_ll_adv_rpa_timeout = 0x40000c8c; r_ble_ll_adv_rpa_update = 0x40000c90; r_ble_ll_adv_rx_pkt_in = 0x40000c94; -r_ble_ll_adv_scan_req_rxd = 0x40000c98; +//r_ble_ll_adv_scan_req_rxd = 0x40000c98; r_ble_ll_adv_scan_rsp_legacy_pdu_make = 0x40000c9c; r_ble_ll_adv_scan_rsp_pdu_make = 0x40000ca0; r_ble_ll_adv_scheduled = 0x40000ca4; @@ -755,7 +755,7 @@ r_ble_lll_hci_dtm_tx_test_v2 = 0x40001614; r_ble_lll_hci_dtm_tx_test_v2_ext = 0x40001618; r_ble_lll_init = 0x4000161c; r_ble_lll_init_pre_process = 0x40001620; -r_ble_lll_init_rx_pkt_isr = 0x40001624; +//r_ble_lll_init_rx_pkt_isr = 0x40001624; r_ble_lll_per_adv_coex_dpc_calc_pti_update_itvl = 0x40001628; r_ble_lll_per_adv_coex_dpc_process = 0x4000162c; r_ble_lll_per_adv_coex_dpc_pti_get = 0x40001630; diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld index 2f30dd745a..1ff67da39f 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble.ld @@ -118,7 +118,7 @@ r_ble_ll_adv_rd_sup_adv_sets = 0x40000c7c; r_ble_ll_adv_read_txpwr = 0x40000c80; r_ble_ll_adv_rpa_timeout = 0x40000c8c; r_ble_ll_adv_rpa_update = 0x40000c90; -r_ble_ll_adv_scan_req_rxd = 0x40000c98; +//r_ble_ll_adv_scan_req_rxd = 0x40000c98; r_ble_ll_adv_scan_rsp_legacy_pdu_make = 0x40000c9c; r_ble_ll_adv_scan_rsp_pdu_make = 0x40000ca0; r_ble_ll_adv_scheduled = 0x40000ca4; From e3e91deca24484f653804da67dbb3ab5692e1ee8 Mon Sep 17 00:00:00 2001 From: Zhou Xiao Date: Fri, 14 Mar 2025 11:23:16 +0800 Subject: [PATCH 17/17] fix(ble): fix ble log init failure mem leak for ESP32-C3 --- components/bt/controller/esp32c3/bt.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/components/bt/controller/esp32c3/bt.c b/components/bt/controller/esp32c3/bt.c index 87ac7a1714..7ac3c09bf1 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -541,7 +541,7 @@ static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, b #if CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN static IRAM_ATTR void esp_bt_controller_spi_log_interface(uint32_t len, const uint8_t *addr, bool end) { - return ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_ESP_LEGACY, addr, len); + ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_ESP_LEGACY, addr, len); } #endif // CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN @@ -1757,7 +1757,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif #if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED - ble_log_spi_out_init(); + if (ble_log_spi_out_init() != 0) { + ESP_LOGE(BT_LOG_TAG, "BLE Log SPI output init failed"); + goto error; + } #endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED periph_module_enable(PERIPH_BT_MODULE); @@ -1792,6 +1795,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) error: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + bt_controller_deinit_internal(); return err;