diff --git a/components/bt/common/ble_log/Kconfig.in b/components/bt/common/ble_log/Kconfig.in index f3a5e5348a72..2bb05ede5af5 100644 --- a/components/bt/common/ble_log/Kconfig.in +++ b/components/bt/common/ble_log/Kconfig.in @@ -7,6 +7,8 @@ config BLE_LOG_ENABLED if BLE_LOG_ENABLED config BLE_LOG_TASK_STACK_SIZE int "Stack size for BLE Log Task" + default 1024 if IDF_TARGET_ARCH_RISCV + default 2048 if IDF_TARGET_ARCH_XTENSA default 1024 help Stack size for BLE Log Task 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 79c0087226a8..bff68af46bb7 100644 --- a/components/bt/common/ble_log/ble_log_spi_out.c +++ b/components/bt/common/ble_log/ble_log_spi_out.c @@ -41,7 +41,14 @@ #define SPI_OUT_LOG_STR_BUF_SIZE (100) #define SPI_OUT_MALLOC(size) heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #define SPI_OUT_TASK_PRIORITY (ESP_TASK_PRIO_MAX - 1) + +#if CONFIG_IDF_TARGET_ARCH_RISCV #define SPI_OUT_TASK_STACK_SIZE (1024) +#elif CONFIG_IDF_TARGET_ARCH_XTENSA +#define SPI_OUT_TASK_STACK_SIZE (2048) +#else +static_assert(false, "BLE Log SPI Out: Unsupported target architecture"); +#endif /* CONFIG_IDF_TARGET_ARCH_RISCV */ #if SPI_OUT_TS_SYNC_ENABLED #define SPI_OUT_TS_SYNC_TIMEOUT_MS (1000) diff --git a/components/bt/common/btc/core/btc_alarm.c b/components/bt/common/btc/core/btc_alarm.c index 6c6177f7a351..67604332c13e 100644 --- a/components/bt/common/btc/core/btc_alarm.c +++ b/components/bt/common/btc/core/btc_alarm.c @@ -12,7 +12,7 @@ void btc_alarm_handler(btc_msg_t *msg) { btc_alarm_args_t *arg = (btc_alarm_args_t *)msg->arg; - BTC_TRACE_DEBUG("%s act %d\n", __FUNCTION__, msg->act); + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); if (arg->cb) { arg->cb(arg->cb_data); diff --git a/components/bt/common/include/bt_common.h b/components/bt/common/include/bt_common.h index 300bbc6d8513..d8fb107878ea 100644 --- a/components/bt/common/include/bt_common.h +++ b/components/bt/common/include/bt_common.h @@ -238,6 +238,7 @@ typedef uint64_t UINT64; typedef bool BOOLEAN; /* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */ #define MAX_UUID_SIZE 16 +#define MAX_UUID_NUM 32 typedef struct { #define LEN_UUID_16 2 diff --git a/components/bt/common/osi/allocator.c b/components/bt/common/osi/allocator.c index 86fb705b071d..0293daa8c4e0 100644 --- a/components/bt/common/osi/allocator.c +++ b/components/bt/common/osi/allocator.c @@ -241,8 +241,5 @@ void *osi_calloc_func(size_t size) void osi_free_func(void *ptr) { -#if HEAP_MEMORY_DEBUG - osi_mem_dbg_clean(ptr, __func__, __LINE__); -#endif - free(ptr); + osi_free(ptr); } diff --git a/components/bt/controller/esp32c6/Kconfig.in b/components/bt/controller/esp32c6/Kconfig.in index 93ba37845426..a2f5ec997b10 100644 --- a/components/bt/controller/esp32c6/Kconfig.in +++ b/components/bt/controller/esp32c6/Kconfig.in @@ -977,3 +977,11 @@ menu "Scheduling Priority Level Config" default 2 if BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL default 1 endmenu + +config BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN + bool "Enable Peripheral fast PDU reception during latency" + default n + help + When this option is enabled, the Controller continues receiving PDUs + In the next connection event instead of entering latency + After a data packet is received. diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index 9d09f014442e..f65766be14fa 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -170,7 +170,7 @@ extern void esp_unregister_npl_funcs (void); extern void npl_freertos_mempool_deinit(void); extern uint32_t r_os_cputime_get32(void); extern uint32_t r_os_cputime_ticks_to_usecs(uint32_t ticks); -extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, +extern void r_ble_lll_sleep_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, void *w_arg, uint32_t us_to_enabled); extern void r_ble_rtc_wake_up_state_clr(void); extern int os_msys_init(void); @@ -851,10 +851,10 @@ esp_err_t controller_sleep_init(void) #ifdef CONFIG_BT_LE_SLEEP_ENABLE ESP_LOGW(NIMBLE_PORT_LOG_TAG, "BLE modem sleep is enabled"); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE - r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, + r_ble_lll_sleep_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, BLE_RTC_DELAY_US_LIGHT_SLEEP); #else - r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, + r_ble_lll_sleep_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, BLE_RTC_DELAY_US_MODEM_SLEEP); #endif /* FREERTOS_USE_TICKLESS_IDLE */ #endif // CONFIG_BT_LE_SLEEP_ENABLE diff --git a/components/bt/controller/esp32c6/esp_bt_cfg.h b/components/bt/controller/esp32c6/esp_bt_cfg.h index 2586976c90d5..71f7f9d19404 100644 --- a/components/bt/controller/esp32c6/esp_bt_cfg.h +++ b/components/bt/controller/esp32c6/esp_bt_cfg.h @@ -212,6 +212,12 @@ extern "C" { #define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (0) #endif +#if defined(CONFIG_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN) +#define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (CONFIG_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN) +#else +#define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (0) +#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/controller/esp32h2/Kconfig.in b/components/bt/controller/esp32h2/Kconfig.in index 17a1d9abf2ce..00ae776c2d78 100644 --- a/components/bt/controller/esp32h2/Kconfig.in +++ b/components/bt/controller/esp32h2/Kconfig.in @@ -981,3 +981,11 @@ menu "Scheduling Priority Level Config" default 2 if BT_LE_SYNC_SCHED_PRIO_HIGH_LEVEL default 1 endmenu + +config BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN + bool "Enable Peripheral fast PDU reception during latency" + default n + help + When this option is enabled, the Controller continues receiving PDUs + In the next connection event instead of entering latency + After a data packet is received. diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 4daa9d3fbeba..6ea4185a2712 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -159,7 +159,7 @@ extern void esp_unregister_npl_funcs (void); extern void npl_freertos_mempool_deinit(void); extern uint32_t r_os_cputime_get32(void); extern uint32_t r_os_cputime_ticks_to_usecs(uint32_t ticks); -extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, +extern void r_ble_lll_sleep_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, void *w_arg, uint32_t us_to_enabled); extern void r_ble_rtc_wake_up_state_clr(void); extern int os_msys_init(void); @@ -816,10 +816,10 @@ esp_err_t controller_sleep_init(void) #ifdef CONFIG_BT_LE_SLEEP_ENABLE ESP_LOGW(NIMBLE_PORT_LOG_TAG, "BLE modem sleep is enabled"); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE - r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, + r_ble_lll_sleep_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, BLE_RTC_DELAY_US_LIGHT_SLEEP); #else - r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, + r_ble_lll_sleep_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, BLE_RTC_DELAY_US_MODEM_SLEEP); #endif /* FREERTOS_USE_TICKLESS_IDLE */ #endif // CONFIG_BT_LE_SLEEP_ENABLE diff --git a/components/bt/controller/esp32h2/esp_bt_cfg.h b/components/bt/controller/esp32h2/esp_bt_cfg.h index e79eb742e2dd..4dbe2f2fe89b 100644 --- a/components/bt/controller/esp32h2/esp_bt_cfg.h +++ b/components/bt/controller/esp32h2/esp_bt_cfg.h @@ -209,6 +209,12 @@ extern "C" { #define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (0) #endif +#if defined(CONFIG_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN) +#define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (CONFIG_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN) +#else +#define DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN (0) +#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/controller/lib_esp32 b/components/bt/controller/lib_esp32 index 45910ee1e502..06dc466733e3 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit 45910ee1e50236e9d7219429666d7be7965427aa +Subproject commit 06dc466733e3e8738c6c638615e6f04e52ca1aa7 diff --git a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib index c82c623de457..7c104a8d09e3 160000 --- a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib +++ b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib @@ -1 +1 @@ -Subproject commit c82c623de457e1b06cf0dad5c963d023dbb6fe76 +Subproject commit 7c104a8d09e35f3244636fcf01004d5c767f12c2 diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index 1495595b82f5..cf7c287226c2 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit 1495595b82f5423d12b325960ae89bc604ebdcd4 +Subproject commit cf7c287226c2c8575dc1cb9896d54a14a18d1dd4 diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index 9cfbeb5f1637..a568fa5a0354 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit 9cfbeb5f163788174073da19b3cd09c4d00cc860 +Subproject commit a568fa5a03545dd133a301ccdbae99afa3692923 diff --git a/components/bt/host/bluedroid/api/esp_hidd_api.c b/components/bt/host/bluedroid/api/esp_hidd_api.c index d7c043666d15..483ba4129196 100644 --- a/components/bt/host/bluedroid/api/esp_hidd_api.c +++ b/components/bt/host/bluedroid/api/esp_hidd_api.c @@ -133,7 +133,7 @@ esp_err_t esp_bt_hid_device_send_report(esp_hidd_report_type_t type, uint8_t id, args.send_report.data = data; bt_status_t stat = btc_transfer_context(&msg, &args, sizeof(btc_hidd_args_t), - btc_hd_arg_deep_copy, btc_hd_cb_arg_deep_free); + btc_hd_arg_deep_copy, btc_hd_call_arg_deep_free); return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } diff --git a/components/bt/host/bluedroid/api/esp_hidh_api.c b/components/bt/host/bluedroid/api/esp_hidh_api.c index e029ee654a0b..f1c39bded884 100644 --- a/components/bt/host/bluedroid/api/esp_hidh_api.c +++ b/components/bt/host/bluedroid/api/esp_hidh_api.c @@ -117,7 +117,7 @@ esp_err_t esp_bt_hid_host_set_info(esp_bd_addr_t bd_addr, esp_hidh_hid_info_t *h arg.set_info.hid_info = hid_info; bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), - btc_hh_arg_deep_copy, btc_hh_cb_arg_deep_free); + btc_hh_arg_deep_copy, btc_hh_call_arg_deep_free); return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } @@ -224,7 +224,7 @@ esp_err_t esp_bt_hid_host_set_report(esp_bd_addr_t bd_addr, esp_hidh_report_type arg.set_report.report = report; bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), - btc_hh_arg_deep_copy, btc_hh_cb_arg_deep_free); + btc_hh_arg_deep_copy, btc_hh_call_arg_deep_free); return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } @@ -243,7 +243,7 @@ esp_err_t esp_bt_hid_host_send_data(esp_bd_addr_t bd_addr, uint8_t *data, size_t arg.send_data.data = data; bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hidh_args_t), - btc_hh_arg_deep_copy, btc_hh_cb_arg_deep_free); + btc_hh_arg_deep_copy, btc_hh_call_arg_deep_free); return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } diff --git a/components/bt/host/bluedroid/api/esp_spp_api.c b/components/bt/host/bluedroid/api/esp_spp_api.c index 5c01aeb2e511..18ef661c165c 100644 --- a/components/bt/host/bluedroid/api/esp_spp_api.c +++ b/components/bt/host/bluedroid/api/esp_spp_api.c @@ -145,22 +145,34 @@ esp_err_t esp_spp_disconnect(uint32_t handle) esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t local_scn, const char *name) +{ + esp_spp_start_srv_cfg_t cfg = {0}; + + cfg.local_scn = local_scn; + cfg.sec_mask = sec_mask; + cfg.role = role; + cfg.create_spp_record = true; + cfg.name = name; + return esp_spp_start_srv_with_cfg(&cfg); +} + +esp_err_t esp_spp_start_srv_with_cfg(const esp_spp_start_srv_cfg_t *cfg) { btc_msg_t msg; btc_spp_args_t arg; ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); - if (name == NULL || strlen(name) > ESP_SPP_SERVER_NAME_MAX) { + if (cfg == NULL || cfg->name == NULL || strlen(cfg->name) > ESP_SPP_SERVER_NAME_MAX) { LOG_ERROR("Invalid server name!\n"); return ESP_ERR_INVALID_ARG; } - if (sec_mask != ESP_SPP_SEC_NONE && - sec_mask != ESP_SPP_SEC_AUTHENTICATE && - sec_mask != (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) && - sec_mask != ESP_SPP_SEC_IN_16_DIGITS && - sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE) && - sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)) { + if (cfg->sec_mask != ESP_SPP_SEC_NONE && + cfg->sec_mask != ESP_SPP_SEC_AUTHENTICATE && + cfg->sec_mask != (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) && + cfg->sec_mask != ESP_SPP_SEC_IN_16_DIGITS && + cfg->sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE) && + cfg->sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)) { LOG_WARN("Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHENTICATE," "(ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)," "ESP_SPP_SEC_IN_16_DIGITS, (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE), or" @@ -171,11 +183,12 @@ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, msg.pid = BTC_PID_SPP; msg.act = BTC_SPP_ACT_START_SRV; - arg.start_srv.sec_mask = sec_mask; - arg.start_srv.role = role; - arg.start_srv.local_scn = local_scn; + arg.start_srv.sec_mask = cfg->sec_mask; + arg.start_srv.role = cfg->role; + arg.start_srv.local_scn = cfg->local_scn; + arg.start_srv.create_spp_record = cfg->create_spp_record; arg.start_srv.max_session = ESP_SPP_MAX_SESSION; - strcpy(arg.start_srv.name, name); + strcpy(arg.start_srv.name, cfg->name); return (btc_transfer_context(&msg, &arg, sizeof(btc_spp_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } diff --git a/components/bt/host/bluedroid/api/include/api/esp_spp_api.h b/components/bt/host/bluedroid/api/include/api/esp_spp_api.h index 40788667c027..e6cdf2fc6928 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_spp_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_spp_api.h @@ -74,7 +74,7 @@ typedef enum { } esp_spp_mode_t; /** - * @brief SPP configuration parameters + * @brief SPP initialization configuration parameters. */ typedef struct { esp_spp_mode_t mode; /*!< Choose the mode of SPP, ESP_SPP_MODE_CB or ESP_SPP_MODE_VFS. */ @@ -82,6 +82,17 @@ typedef struct { uint16_t tx_buffer_size; /*!< Tx buffer size for a new SPP channel. A smaller setting can save memory, but may incur a decrease in throughput. Only for ESP_SPP_MODE_VFS mode. */ } esp_spp_cfg_t; +/** + * @brief SPP start server configuration parameters. + */ +typedef struct { + uint8_t local_scn; /*!< The specific channel you want to get. If channel is 0, means get any channel. */ + bool create_spp_record; /*!< Specifies whether to create the SPP record */ + esp_spp_sec_t sec_mask; /*!< Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only */ + esp_spp_role_t role; /*!< Master or slave. */ + const char *name; /*!< Server's name. */ +} esp_spp_start_srv_cfg_t; + /** * @brief SPP callback function events */ @@ -368,6 +379,19 @@ esp_err_t esp_spp_disconnect(uint32_t handle); */ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, esp_spp_role_t role, uint8_t local_scn, const char *name); +/** + * @brief This function is similar to `esp_spp_start_srv`. + * The only difference is that it adds a parameter to specify whether to create the SPP record. + * @note If the SPP record is not created, it is suggested to use it together with the SDP API. + * + * @param[in] cfg: Configuration parameters for starting the server. + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_spp_start_srv_with_cfg(const esp_spp_start_srv_cfg_t *cfg); + /** * @brief This function stops all SPP servers. * The operation will close all active SPP connection first, then the callback function will be called diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 857ca6676f97..f04dca0f41af 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -2056,7 +2056,7 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data) #endif UINT32 num_uuids = 0; - UINT8 uuid_list[32][MAX_UUID_SIZE]; // assuming a max of 32 services + UINT8 uuid_list[MAX_UUID_NUM][MAX_UUID_SIZE]; // assuming a max of MAX_UUID_NUM services if ((p_data->sdp_event.sdp_result == SDP_SUCCESS) || (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH) @@ -2119,8 +2119,12 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data) (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index - 1)); tmp_svc = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1]; /* Add to the list of UUIDs */ - sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]); - num_uuids++; + if (num_uuids < MAX_UUID_NUM) { + sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]); + num_uuids++; + } else { + APPL_TRACE_WARNING("only process the first %d records\n", MAX_UUID_NUM); + } } } } @@ -2154,8 +2158,13 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data) p_sdp_rec = SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec); if (p_sdp_rec) { if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) { - memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE); - num_uuids++; + if (num_uuids < MAX_UUID_NUM) { + memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE); + num_uuids++; + } else { + APPL_TRACE_WARNING("only process the first %d records\n", MAX_UUID_NUM); + break; + } } } } while (p_sdp_rec); diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c index 5c7ee9bdede2..085697acb90c 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c @@ -63,7 +63,15 @@ void bta_dm_co_security_param_init(void) bte_appl_cfg.ble_min_key_size = BTM_BLE_MIN_KEY_SIZE; bte_appl_cfg.ble_accept_auth_enable = BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE; bte_appl_cfg.oob_support = BTM_BLE_OOB_DISABLE; -}; + + APPL_TRACE_DEBUG("%s: auth_req=%u, io_cap=%u, init_key=%u, resp_key=%u, " + "max_key_size=%u, min_key_size=%u, accept_auth=%u, oob=%u", + __func__, + bte_appl_cfg.ble_auth_req, bte_appl_cfg.ble_io_cap, + bte_appl_cfg.ble_init_key, bte_appl_cfg.ble_resp_key, + bte_appl_cfg.ble_max_key_size, bte_appl_cfg.ble_min_key_size, + bte_appl_cfg.ble_accept_auth_enable, bte_appl_cfg.oob_support); +} #endif #if (defined CLASSIC_BT_INCLUDED && CLASSIC_BT_INCLUDED == TRUE) @@ -379,6 +387,7 @@ void bta_dm_co_ble_set_io_cap(UINT8 ble_io_cap) #if (SMP_INCLUDED == TRUE) if(ble_io_cap < BTM_IO_CAP_MAX ) { bte_appl_cfg.ble_io_cap = ble_io_cap; + APPL_TRACE_DEBUG("%s: ble_io_cap set to %u", __func__, ble_io_cap); } else { APPL_TRACE_ERROR("%s error:Invalid io cap value.",__func__); } @@ -389,22 +398,25 @@ void bta_dm_co_ble_set_auth_req(UINT8 ble_auth_req) { #if (SMP_INCLUDED == TRUE) bte_appl_cfg.ble_auth_req = ble_auth_req; -#endif ///SMP_INCLUDED == TRUE + APPL_TRACE_DEBUG("%s: ble_auth_req set to %u", __func__, ble_auth_req); +#endif } void bta_dm_co_ble_set_init_key_req(UINT8 init_key) { #if (SMP_INCLUDED == TRUE) - init_key &= 0x0f; // 4~7bit reservd, only used the 0~3bit + init_key &= 0x0f; // 4~7bit reserved, only used the 0~3bit bte_appl_cfg.ble_init_key = init_key; -#endif ///SMP_INCLUDED == TRUE + APPL_TRACE_DEBUG("%s: init_key set to 0x%x", __func__, init_key); +#endif } void bta_dm_co_ble_set_rsp_key_req(UINT8 rsp_key) { #if (SMP_INCLUDED == TRUE) - rsp_key &= 0x0f; // 4~7bit reservd, only used the 0~3bit + rsp_key &= 0x0f; // 4~7bit reserved, only used the 0~3bit bte_appl_cfg.ble_resp_key = rsp_key; + APPL_TRACE_DEBUG("%s: rsp_key set to 0x%x", __func__, rsp_key); #endif ///SMP_INCLUDED == TRUE } @@ -413,6 +425,7 @@ void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size) #if (SMP_INCLUDED == TRUE) if(ble_key_size >= bte_appl_cfg.ble_min_key_size && ble_key_size <= BTM_BLE_MAX_KEY_SIZE) { bte_appl_cfg.ble_max_key_size = ble_key_size; + APPL_TRACE_DEBUG("%s: max_key_size set to %d", __func__, ble_key_size); } else { APPL_TRACE_ERROR("%s error:Invalid key size value, key_size =%d",__func__, ble_key_size); } @@ -424,6 +437,7 @@ void bta_dm_co_ble_set_min_key_size(UINT8 ble_key_size) #if (SMP_INCLUDED == TRUE) if(ble_key_size >= BTM_BLE_MIN_KEY_SIZE && ble_key_size <= bte_appl_cfg.ble_max_key_size) { bte_appl_cfg.ble_min_key_size = ble_key_size; + APPL_TRACE_DEBUG("%s: min_key_size set to %u", __func__, ble_key_size); } else { APPL_TRACE_ERROR("%s error:Invalid key size value, key_size =%d",__func__, ble_key_size); } @@ -437,6 +451,7 @@ void bta_dm_co_ble_set_accept_auth_enable(UINT8 enable) enable = BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_ENABLE; } bte_appl_cfg.ble_accept_auth_enable = enable; + APPL_TRACE_DEBUG("%s: accept_auth_enable set to %u", __func__, enable); #endif ///SMP_INCLUDED == TRUE } @@ -464,6 +479,7 @@ void bta_dm_co_ble_oob_support(UINT8 enable) } else { bte_appl_cfg.oob_support = BTM_BLE_OOB_DISABLE; } + APPL_TRACE_DEBUG("%s: oob_support set to %u", __func__, bte_appl_cfg.oob_support); #endif ///SMP_INCLUDED == TRUE } diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c index b47a9d973345..18632d2dfa7c 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c @@ -523,7 +523,8 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) cmd_data->api_write.p_value = (UINT8 *)(cmd_data + 1); memcpy(cmd_data->api_write.p_value, p_data->api_write.p_value, len); } else { - APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__); + APPL_TRACE_ERROR("%s(), line = %d, alloc fail, size %d, no memory. free=%d, largest_block=%d", __func__, __LINE__, + sizeof(tBTA_GATTC_DATA) + len, heap_caps_get_free_size(MALLOC_CAP_DEFAULT), heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT)); return FALSE; } } else { diff --git a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c index f20a7241e174..aef3863111f5 100644 --- a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c @@ -16,7 +16,7 @@ #if (SMP_INCLUDED == TRUE) //the maximum number of bonded devices -#define BONED_DEVICES_MAX_COUNT (BTM_SEC_MAX_DEVICE_RECORDS) +#define BONED_DEVICES_MAX_COUNT (BTM_SEC_MAX_BONDS) static void _btc_storage_save(void) { diff --git a/components/bt/host/bluedroid/btc/core/btc_dev.c b/components/bt/host/bluedroid/btc/core/btc_dev.c index 18cda3e0d864..424dfe93e59f 100644 --- a/components/bt/host/bluedroid/btc/core/btc_dev.c +++ b/components/bt/host/bluedroid/btc/core/btc_dev.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 */ diff --git a/components/bt/host/bluedroid/btc/core/btc_dm.c b/components/bt/host/bluedroid/btc/core/btc_dm.c index 782569c2993e..02b5a16ef4c3 100644 --- a/components/bt/host/bluedroid/btc/core/btc_dm.c +++ b/components/bt/host/bluedroid/btc/core/btc_dm.c @@ -784,6 +784,7 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg) ble_msg->pid = BTC_PID_GAP_BLE; // tBTA_SERVICE_MASK service_mask; BTC_TRACE_DEBUG("btc_dm_upstreams_cback ev: %d\n", msg->act); + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); switch (msg->act) { case BTA_DM_ENABLE_EVT: { diff --git a/components/bt/host/bluedroid/btc/core/btc_main.c b/components/bt/host/bluedroid/btc/core/btc_main.c index d7330cc6f7d7..593bb99e0710 100644 --- a/components/bt/host/bluedroid/btc/core/btc_main.c +++ b/components/bt/host/bluedroid/btc/core/btc_main.c @@ -97,7 +97,7 @@ static void btc_deinit_bluetooth(void) void btc_main_call_handler(btc_msg_t *msg) { - BTC_TRACE_DEBUG("%s act %d\n", __func__, msg->act); + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); switch (msg->act) { case BTC_MAIN_ACT_INIT: @@ -127,101 +127,132 @@ uint32_t btc_get_ble_status(void) return status; } - #if (BLE_INCLUDED == TRUE) +#if (BLE_INCLUDED == TRUE) // Number of active advertising extern uint8_t btm_ble_adv_active_count(void); - if (btm_ble_adv_active_count()) { + uint8_t adv_cnt = btm_ble_adv_active_count(); + if (adv_cnt) { + BTC_TRACE_WARNING("%s advertising active, cnt %d", __func__, adv_cnt); status |= BIT(BTC_BLE_STATUS_ADV); } // Number of active scanning extern uint8_t btm_ble_scan_active_count(void); - if (btm_ble_scan_active_count()) { + uint8_t scan_cnt = btm_ble_scan_active_count(); + if (scan_cnt) { + BTC_TRACE_WARNING("%s scan active, cnt %d", __func__, scan_cnt); status |= BIT(BTC_BLE_STATUS_SCAN); } // Number of active GATT tcb extern uint8_t gatt_tcb_active_count(void); - if (gatt_tcb_active_count()) { + uint8_t gatt_tcb_cnt = gatt_tcb_active_count(); + if (gatt_tcb_cnt) { + BTC_TRACE_WARNING("%s gatt tcb active, cnt %d", __func__, gatt_tcb_cnt); status |= BIT(BTC_BLE_STATUS_CONN); } // Number of active ACL connection extern uint8_t btm_ble_acl_active_count(void); - if (btm_ble_acl_active_count()) { + uint8_t acl_cnt = btm_ble_acl_active_count(); + if (acl_cnt) { + BTC_TRACE_WARNING("%s acl connection active, cnt %d", __func__, acl_cnt); status |= BIT(BTC_BLE_STATUS_CONN); } // Number of active L2C plcb extern uint8_t l2cu_ble_plcb_active_count(void); - if (l2cu_ble_plcb_active_count()) { + uint8_t plcb_cnt = l2cu_ble_plcb_active_count(); + if (plcb_cnt) { + BTC_TRACE_WARNING("%s l2c plcb active, cnt %d", __func__, plcb_cnt); status |= BIT(BTC_BLE_STATUS_CONN); } // Address resolve status extern uint8_t btm_get_ble_addr_resolve_disable_status(void); - if (btm_get_ble_addr_resolve_disable_status()) { + uint8_t addr_resolve_disable = btm_get_ble_addr_resolve_disable_status(); + if (addr_resolve_disable) { + BTC_TRACE_WARNING("%s address resolve disabled", __func__); status |= BIT(BTC_BLE_STATUS_ADDR_RESOLVE_DISABLE); } - #if (SMP_INCLUDED == TRUE) +#if (SMP_INCLUDED == TRUE) // Number of recorded devices extern uint8_t btm_ble_sec_dev_record_count(void); - if (btm_ble_sec_dev_record_count()) { + uint8_t sec_dev_cnt = btm_ble_sec_dev_record_count(); + if (sec_dev_cnt) { + BTC_TRACE_WARNING("%s security device record count %d", __func__, sec_dev_cnt); status |= BIT(BTC_BLE_STATUS_DEVICE_REC); } // Number of saved bonded devices - if (btc_storage_get_num_ble_bond_devices()) { + int bond_cnt = btc_storage_get_num_ble_bond_devices(); + if (bond_cnt) { + BTC_TRACE_WARNING("%s bonded devices count %d", __func__, bond_cnt); status |= BIT(BTC_BLE_STATUS_BOND); } - #endif +#endif // SMP_INCLUDED - #if (BLE_PRIVACY_SPT == TRUE) +#if (BLE_PRIVACY_SPT == TRUE) // Privacy enabled extern uint8_t btm_ble_privacy_is_enabled(void); - if (btm_ble_privacy_is_enabled()) { + uint8_t privacy_en = btm_ble_privacy_is_enabled(); + if (privacy_en) { + BTC_TRACE_WARNING("%s privacy enabled", __func__); status |= BIT(BTC_BLE_STATUS_PRIVACY); } - #endif - #endif +#endif // BLE_PRIVACY_SPT + +#endif // BLE_INCLUDED - #if (BLE_50_EXTEND_ADV_EN == TRUE) +#if (BLE_50_EXTEND_ADV_EN == TRUE) // Number of active extended advertsing extern uint8_t btm_ble_ext_adv_active_count(void); - if (btm_ble_ext_adv_active_count()) { + uint8_t ext_adv_cnt = btm_ble_ext_adv_active_count(); + if (ext_adv_cnt) { + BTC_TRACE_WARNING("%s extended advertising active, cnt %d", __func__, ext_adv_cnt); status |= BIT(BTC_BLE_STATUS_EXT_ADV); } - #endif +#endif // (BLE_50_EXTEND_ADV_EN == TRUE) - #if (GATTC_INCLUDED == TRUE) +#if (GATTC_INCLUDED == TRUE) // Number of registered GATTC APP extern uint8_t bta_gattc_cl_rcb_active_count(void); - if (bta_gattc_cl_rcb_active_count()) { + uint8_t gattc_app_cnt = bta_gattc_cl_rcb_active_count(); + if (gattc_app_cnt) { + BTC_TRACE_WARNING("%s GATTC app active, cnt %d", __func__, gattc_app_cnt); status |= BIT(BTC_BLE_STATUS_GATTC_APP); } // Number of saved GATTC cache extern UINT8 bta_gattc_co_get_addr_num(void); - if (bta_gattc_co_get_addr_num()) { + uint8_t gattc_cache_cnt = bta_gattc_co_get_addr_num(); + if (gattc_cache_cnt) { + BTC_TRACE_WARNING("%s GATTC cache count %d", __func__, gattc_cache_cnt); status |= BIT(BTC_BLE_STATUS_GATTC_CACHE); } - #endif +#endif // GATTC_INCLUDED - #if (GATTS_INCLUDED == TRUE) +#if (GATTS_INCLUDED == TRUE) // Number of registered GATTS service extern uint8_t bta_gatts_srvc_active_count(void); - if (bta_gatts_srvc_active_count()) { + uint8_t gatts_srvc_cnt = bta_gatts_srvc_active_count(); + if (gatts_srvc_cnt) { + BTC_TRACE_WARNING("%s GATTS service active, cnt %d", __func__, gatts_srvc_cnt); status |= BIT(BTC_BLE_STATUS_GATTS_SRVC); } - #endif +#endif // GATTS_INCLUDED - #if SMP_INCLUDED == TRUE +#if (SMP_INCLUDED == TRUE) extern uint8_t smp_get_state(void); - if (smp_get_state()) { + uint8_t smp_state = smp_get_state(); + if (smp_state) { + BTC_TRACE_WARNING("%s SMP state active, state=%d", __func__, smp_state); status |= BIT(BTC_BLE_STATUS_SMP_STATE); } - #endif +#endif // SMP_INCLUDED + + BTC_TRACE_WARNING("%s exit, final status=0x%x", __func__, status); return status; } diff --git a/components/bt/host/bluedroid/btc/core/btc_profile_queue.c b/components/bt/host/bluedroid/btc/core/btc_profile_queue.c index 4f359030434d..5e63dfe54c4e 100644 --- a/components/bt/host/bluedroid/btc/core/btc_profile_queue.c +++ b/components/bt/host/bluedroid/btc/core/btc_profile_queue.c @@ -62,6 +62,9 @@ static void queue_int_advance(void) void btc_profile_queue_handler(btc_msg_t *msg) { btc_prf_que_args_t *arg = (btc_prf_que_args_t *)(msg->arg); + + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (msg->act) { case BTC_PRF_QUE_CONNECT: queue_int_add(&(arg->connect_node)); diff --git a/components/bt/host/bluedroid/btc/core/btc_storage.c b/components/bt/host/bluedroid/btc/core/btc_storage.c index 1923dea0da63..bee44e18d383 100644 --- a/components/bt/host/bluedroid/btc/core/btc_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_storage.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 */ @@ -40,7 +40,7 @@ bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr, bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); /* device not in bond list and exceed the maximum number of bonded devices, delete the inactive bonded device */ - if (btc_storage_get_num_all_bond_devices() >= BTM_SEC_MAX_DEVICE_RECORDS && !btc_config_has_section(bdstr)) { + if (btc_storage_get_num_all_bond_devices() >= BTM_SEC_MAX_BONDS && !btc_config_has_section(bdstr)) { const btc_config_section_iter_t *iter = btc_config_section_begin(); const btc_config_section_iter_t *remove_iter = iter; /* find the first device(the last node) */ @@ -57,7 +57,7 @@ bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr, // delete config info if (btc_config_remove_section(remove_section)) { - BTC_TRACE_WARNING("exceeded the maximum nubmer of bonded devices, delete the first device info : %02x:%02x:%02x:%02x:%02x:%02x", + BTC_TRACE_WARNING("exceeded the maximum number of bonded devices, delete the first device info : %02x:%02x:%02x:%02x:%02x:%02x", bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]); } } @@ -141,8 +141,8 @@ static bt_status_t btc_in_fetch_bonded_devices(int add) continue; } dev_cnt ++; - /* if the number of device stored in nvs not exceed to BTM_SEC_MAX_DEVICE_RECORDS, load it */ - if (dev_cnt <= BTM_SEC_MAX_DEVICE_RECORDS) { + /* if the number of device stored in nvs not exceed to BTM_SEC_MAX_BONDS, load it */ + if (dev_cnt <= BTM_SEC_MAX_BONDS) { if (btc_config_exist(name, BTC_STORAGE_LINK_KEY_TYPE_STR) && btc_config_exist(name, BTC_STORAGE_PIN_LENGTH_STR) && btc_config_exist(name, BTC_STORAGE_SC_SUPPORT) && btc_config_exist(name, BTC_STORAGE_LINK_KEY_STR)) { /* load bt device */ diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index b74ffa00f1a7..001bb74b2278 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -61,6 +61,7 @@ static inline void btc_gap_ble_cb_to_app(esp_gap_ble_cb_event_t event, esp_ble_g esp_gap_ble_cb_t btc_gap_ble_cb = (esp_gap_ble_cb_t)btc_profile_cb_get(BTC_PID_GAP_BLE); if (btc_gap_ble_cb) { btc_gap_ble_cb(event, param); + BTC_TRACE_DEBUG("btc_gap_ble_cb_to_app, event=%d", event); } } @@ -1768,6 +1769,8 @@ void btc_gap_ble_cb_handler(btc_msg_t *msg) { esp_ble_gap_cb_param_t *param = (esp_ble_gap_cb_param_t *)msg->arg; + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + if (msg->act < ESP_GAP_BLE_EVT_MAX) { btc_gap_ble_cb_to_app(msg->act, param); } else { @@ -2177,7 +2180,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) btc_ble_5_gap_args_t *arg_5 = (btc_ble_5_gap_args_t *)msg->arg; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) - BTC_TRACE_DEBUG("%s act %d\n", __FUNCTION__, msg->act); + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); switch (msg->act) { #if (BLE_42_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c index e1278954c4ee..4d5e7a497aef 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c @@ -1063,7 +1063,9 @@ void btc_gap_bt_arg_deep_free(btc_msg_t *msg) void btc_gap_bt_call_handler(btc_msg_t *msg) { btc_gap_bt_args_t *arg = (btc_gap_bt_args_t *)msg->arg; - BTC_TRACE_DEBUG("%s act %d\n", __func__, msg->act); + + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (msg->act) { case BTC_GAP_BT_ACT_SET_SCAN_MODE: { btc_bt_set_scan_mode(arg->set_scan_mode.c_mode, arg->set_scan_mode.d_mode); diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_common.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_common.c index 45a2b834b52f..754878f0cb5a 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_common.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_common.c @@ -23,7 +23,8 @@ static void btc_set_local_mtu(uint16_t mtu) void btc_gatt_com_call_handler(btc_msg_t *msg) { - BTC_TRACE_DEBUG("%s act %d\n", __func__, msg->act); + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (msg->act) { case BTC_GATT_ACT_SET_LOCAL_MTU: { diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c index 86221e3c895e..e8f7444368ea 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.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,7 @@ static inline void btc_gattc_cb_to_app(esp_gattc_cb_event_t event, esp_gatt_if_t esp_gattc_cb_t btc_gattc_cb = (esp_gattc_cb_t )btc_profile_cb_get(BTC_PID_GATTC); if (btc_gattc_cb) { btc_gattc_cb(event, gattc_if, param); + BTC_TRACE_DEBUG("btc_gattc_cb_to_app, gattc_if %d, event=%d", gattc_if, event); } } @@ -714,6 +715,9 @@ static void btc_gattc_unreg_for_notify(btc_ble_gattc_args_t *arg) void btc_gattc_call_handler(btc_msg_t *msg) { btc_ble_gattc_args_t *arg = (btc_ble_gattc_args_t *)(msg->arg); + + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (msg->act) { case BTC_GATTC_ACT_APP_REGISTER: btc_gattc_app_register(arg); @@ -803,6 +807,8 @@ void btc_gattc_cb_handler(btc_msg_t *msg) memset(¶m, 0, sizeof(esp_ble_gattc_cb_param_t)); + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (msg->act) { case BTA_GATTC_REG_EVT: { tBTA_GATTC_REG *reg_oper = &arg->reg_oper; diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c index 7eab806e2f54..e1b06cffbae7 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.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 */ @@ -37,6 +37,7 @@ static inline void btc_gatts_cb_to_app(esp_gatts_cb_event_t event, esp_gatt_if_t { esp_gatts_cb_t btc_gatts_cb = (esp_gatts_cb_t)btc_profile_cb_get(BTC_PID_GATTS); if (btc_gatts_cb) { + BTC_TRACE_DEBUG("btc_gatts_cb_to_app, gatts_if %d, event=%d", gatts_if, event); btc_gatts_cb(event, gatts_if, param); } } @@ -616,6 +617,8 @@ void btc_gatts_call_handler(btc_msg_t *msg) { btc_ble_gatts_args_t *arg = (btc_ble_gatts_args_t *)msg->arg; + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (msg->act) { case BTC_GATTS_ACT_APP_REGISTER: { tBT_UUID uuid; @@ -764,6 +767,8 @@ void btc_gatts_cb_handler(btc_msg_t *msg) tBTA_GATTS *p_data = (tBTA_GATTS *)msg->arg; esp_gatt_if_t gatts_if; + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (msg->act) { case BTA_GATTS_REG_EVT: { gatts_if = p_data->reg_oper.server_if; diff --git a/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c b/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c index c7fa57f0b06b..66162261fd01 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c +++ b/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c @@ -1097,6 +1097,8 @@ void btc_hf_call_handler(btc_msg_t *msg) { btc_hf_args_t *arg = (btc_hf_args_t *)(msg->arg); + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (msg->act) { case BTC_HF_INIT_EVT: { diff --git a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c index 82ff2b8d5c8e..5986943bfa4a 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c +++ b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c @@ -75,6 +75,8 @@ btc_hd_cb_t btc_hd_cb = {0}; typedef void (bt_hid_copy_cb_t)(btc_msg_t *msg, void *p_dest, void *p_src); +static void btc_hd_cb_arg_deep_free(btc_msg_t *msg); + static inline void btc_hd_cb_to_app(esp_hidd_cb_event_t event, esp_hidd_cb_param_t *param) { esp_hd_cb_t btc_hd_cb = (esp_hd_cb_t)btc_profile_cb_get(BTC_PID_HD); @@ -705,7 +707,7 @@ static void btc_hd_virtual_cable_unplug(void) } } -static void btc_hd_call_arg_deep_free(btc_msg_t *msg) +void btc_hd_call_arg_deep_free(btc_msg_t *msg) { btc_hidd_args_t *arg = (btc_hidd_args_t *)msg->arg; @@ -721,6 +723,9 @@ static void btc_hd_call_arg_deep_free(btc_msg_t *msg) void btc_hd_call_handler(btc_msg_t *msg) { btc_hidd_args_t *arg = (btc_hidd_args_t *)(msg->arg); + + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (msg->act) { case BTC_HD_INIT_EVT: btc_hd_init(); @@ -756,7 +761,7 @@ void btc_hd_call_handler(btc_msg_t *msg) btc_hd_call_arg_deep_free(msg); } -void btc_hd_cb_arg_deep_free(btc_msg_t *msg) +static void btc_hd_cb_arg_deep_free(btc_msg_t *msg) { tBTA_HD *arg = (tBTA_HD *)msg->arg; @@ -779,6 +784,8 @@ void btc_hd_cb_handler(btc_msg_t *msg) esp_hidd_cb_param_t param = {0}; BTC_TRACE_API("%s: event=%s", __func__, dump_hd_event(event)); + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (event) { case BTA_HD_ENABLE_EVT: BTC_TRACE_DEBUG("%s: status=%d", __func__, p_data->status); diff --git a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c index 55fe3f69b379..dda5d0bf9d1d 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c +++ b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c @@ -64,6 +64,8 @@ static bdstr_t bdstr; #define is_hidh_init() (btc_hh_cb.status > BTC_HH_DISABLED) #define BTC_TIMEOUT_VUP_MS (3 * 1000) +static void btc_hh_cb_arg_deep_free(btc_msg_t *msg); + static inline void btc_hh_cb_to_app(esp_hidh_cb_event_t event, esp_hidh_cb_param_t *param) { esp_hh_cb_t btc_hh_cb = (esp_hh_cb_t)btc_profile_cb_get(BTC_PID_HH); @@ -1097,7 +1099,7 @@ static void btc_hh_set_idle_time(btc_hidh_args_t *arg) } } -static void btc_hh_call_arg_deep_free(btc_msg_t *msg) +void btc_hh_call_arg_deep_free(btc_msg_t *msg) { btc_hidh_args_t *arg = (btc_hidh_args_t *)msg->arg; @@ -1119,6 +1121,8 @@ static void btc_hh_call_arg_deep_free(btc_msg_t *msg) void btc_hh_call_handler(btc_msg_t *msg) { btc_hidh_args_t *arg = (btc_hidh_args_t *)(msg->arg); + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (msg->act) { case BTC_HH_INIT_EVT: btc_hh_init(); @@ -1166,7 +1170,7 @@ void btc_hh_call_handler(btc_msg_t *msg) btc_hh_call_arg_deep_free(msg); } -void btc_hh_cb_arg_deep_free(btc_msg_t *msg) +static void btc_hh_cb_arg_deep_free(btc_msg_t *msg) { tBTA_HH *arg = (tBTA_HH *)msg->arg; @@ -1227,6 +1231,7 @@ void btc_hh_cb_handler(btc_msg_t *msg) btc_hh_device_t *p_dev = NULL; int len, i; BTC_TRACE_DEBUG("%s: event=%s dereg = %d", __func__, dump_hh_event(msg->act), btc_hh_cb.service_dereg_active); + switch (msg->act) { case BTA_HH_ENABLE_EVT: if (p_data->status == BTA_HH_OK) { diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h index 15b59393a327..fa01953e8426 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h @@ -99,7 +99,7 @@ void btc_hd_call_handler(btc_msg_t *msg); void btc_hd_cb_handler(btc_msg_t *msg); void btc_hd_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); -void btc_hd_cb_arg_deep_free(btc_msg_t *msg); +void btc_hd_call_arg_deep_free(btc_msg_t *msg); void btc_hd_get_profile_status(esp_hidd_profile_status_t *param); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h index f1158c6fddf7..827cd095c752 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h @@ -181,8 +181,7 @@ void btc_hh_call_handler(btc_msg_t *msg); void btc_hh_cb_handler(btc_msg_t *msg); void btc_hh_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); - -void btc_hh_cb_arg_deep_free(btc_msg_t *msg); +void btc_hh_call_arg_deep_free(btc_msg_t *msg); bool btc_hh_add_added_dev(BD_ADDR bd_addr, uint16_t attr_mask); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_spp.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_spp.h index 5082a135e13c..fd349c7de68b 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_spp.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_spp.h @@ -67,6 +67,7 @@ typedef union { esp_spp_sec_t sec_mask; esp_spp_role_t role; UINT8 local_scn; + bool create_spp_record; UINT8 max_session; char name[ESP_SPP_SERVER_NAME_MAX + 1]; } start_srv; diff --git a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c index 9155784fb852..63477d6ce544 100644 --- a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c +++ b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c @@ -300,6 +300,7 @@ static inline void btc_l2cap_cb_to_app(esp_bt_l2cap_cb_event_t event, esp_bt_l2c { esp_bt_l2cap_cb_t btc_l2cap_cb = (esp_bt_l2cap_cb_t)btc_profile_cb_get(BTC_PID_L2CAP); if (btc_l2cap_cb) { + BTC_TRACE_DEBUG("btc_l2cap_cb_to_app, event=%d", event); btc_l2cap_cb(event, param); } } @@ -772,6 +773,7 @@ static void btc_l2cap_disconnect(uint32_t handle) void btc_l2cap_call_handler(btc_msg_t *msg) { btc_l2cap_args_t *arg = (btc_l2cap_args_t *)(msg->arg); + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); switch (msg->act) { case BTC_L2CAP_ACT_INIT: btc_l2cap_init(); @@ -809,6 +811,8 @@ void btc_l2cap_cb_handler(btc_msg_t *msg) uint8_t serial = 0; uint32_t count = 0; + BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); + switch (event) { case BTA_JV_ENABLE_EVT: param.init.status = p_data->status; diff --git a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c index bb142531a3e9..8607e4219121 100644 --- a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c +++ b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c @@ -50,6 +50,7 @@ typedef struct { bool connected; bool is_server; bool is_writing; + bool create_spp_record; uint8_t serial; uint8_t scn; uint8_t max_session; @@ -143,6 +144,7 @@ static spp_slot_t *spp_malloc_slot(void) (*slot)->rfc_port_handle = 0; (*slot)->fd = -1; (*slot)->connected = false; + (*slot)->create_spp_record = false; (*slot)->is_server = false; (*slot)->mtu = 0; (*slot)->credit_rx = BTA_JV_MAX_CREDIT_NUM; @@ -378,6 +380,7 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u strcpy(slot_new->service_name, slot->service_name); slot_new->sdp_handle = slot->sdp_handle; slot_new->mtu = p_data->rfc_srv_open.peer_mtu; + slot_new->create_spp_record = slot->create_spp_record; slot_new->rfc_handle = p_data->rfc_srv_open.handle; slot_new->rfc_port_handle = BTA_JvRfcommGetPortHdl(slot_new->rfc_handle); BTA_JvSetPmProfile(p_data->rfc_srv_open.handle, BTA_JV_PM_ALL, BTA_JV_CONN_OPEN); @@ -482,7 +485,14 @@ static void btc_spp_dm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_d } slot->scn = p_data->scn; - BTA_JvCreateRecordByUser(slot->service_name, slot->scn, (void *)slot->id); + if (slot->create_spp_record) { + BTA_JvCreateRecordByUser(slot->service_name, slot->scn, (void *)slot->id); + } else { + slot->sdp_handle = 0xffff; + BTA_JvRfcommStartServer(slot->security, slot->role, slot->scn, + slot->max_session, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)slot->id); + } + osi_mutex_unlock(&spp_local_param.spp_slot_mutex); break; case BTA_JV_CREATE_RECORD_EVT: @@ -748,6 +758,7 @@ static void btc_spp_start_srv(btc_spp_args_t *arg) * make this slot become a listening slot */ slot->is_server = true; + slot->create_spp_record = arg->start_srv.create_spp_record; slot->security = arg->start_srv.sec_mask; slot->role = arg->start_srv.role; slot->scn = arg->start_srv.local_scn; @@ -832,7 +843,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg) if (spp_local_param.spp_slots[i] != NULL && spp_local_param.spp_slots[i]->is_server && spp_local_param.spp_slots[i]->sdp_handle > 0 && spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) { - if (spp_local_param.spp_slots[i]->sdp_handle > 0) { + if (spp_local_param.spp_slots[i]->sdp_handle > 0 && spp_local_param.spp_slots[i]->create_spp_record) { BTA_JvDeleteRecord(spp_local_param.spp_slots[i]->sdp_handle); } diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index 3d9e1dd5715c..6c90e4aa4909 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -1070,11 +1070,11 @@ /* The number of security records for peer devices. 15 AS Default*/ #ifndef BTM_SEC_MAX_DEVICE_RECORDS -#if (UC_BT_SMP_MAX_BONDS < UC_BT_ACL_CONNECTIONS) -#define BTM_SEC_MAX_DEVICE_RECORDS UC_BT_ACL_CONNECTIONS -#else -#define BTM_SEC_MAX_DEVICE_RECORDS UC_BT_SMP_MAX_BONDS +#define BTM_SEC_MAX_DEVICE_RECORDS (UC_BT_SMP_MAX_BONDS + UC_BT_ACL_CONNECTIONS) #endif + +#ifndef BTM_SEC_MAX_BONDS +#define BTM_SEC_MAX_BONDS UC_BT_SMP_MAX_BONDS #endif #if BTA_SDP_INCLUDED diff --git a/components/bt/host/bluedroid/hci/hci_layer.c b/components/bt/host/bluedroid/hci/hci_layer.c index e5cd263fbc19..59b69bc0a718 100644 --- a/components/bt/host/bluedroid/hci/hci_layer.c +++ b/components/bt/host/bluedroid/hci/hci_layer.c @@ -614,3 +614,96 @@ const hci_t *hci_layer_get_interface(void) init_layer_interface(); return &interface; } + +#if !UC_BT_STACK_NO_LOG +/******************************************************************************* +** +** Function hci_status_code_to_string +** +** Description Converts an HCI status code to a human-readable string. +** If the code is not defined in the specification, the +** function returns "Unknown Status (0xXX)" where XX is the +** actual code value. +** Reference: BLUETOOTH CORE SPECIFICATION Version 5.4, +** Vol 1, Part F, p. 376 +** +** Parameters status : HCI status code +** +** Returns const char* : readable description of the status +** +*******************************************************************************/ +const char *hci_status_code_to_string(uint8_t status) +{ + switch (status) { + case HCI_SUCCESS: return "Success"; /* 0x00 */ + case HCI_ERR_ILLEGAL_COMMAND: return "Illegal Command"; /* 0x01 */ + case HCI_ERR_NO_CONNECTION: return "No Connection"; /* 0x02 */ + case HCI_ERR_HW_FAILURE: return "HW Failure"; /* 0x03 */ + case HCI_ERR_PAGE_TIMEOUT: return "Page Timeout"; /* 0x04 */ + case HCI_ERR_AUTH_FAILURE: return "Auth Failure"; /* 0x05 */ + case HCI_ERR_KEY_MISSING: return "Key Missing"; /* 0x06 */ + case HCI_ERR_MEMORY_FULL: return "Memory Full"; /* 0x07 */ + case HCI_ERR_CONNECTION_TOUT: return "Conn Timeout"; /* 0x08 */ + case HCI_ERR_MAX_NUM_OF_CONNECTIONS: return "Conn Limit Exceeded"; /* 0x09 */ + case HCI_ERR_MAX_NUM_OF_SCOS: return "Sync Conn Limit Exceeded"; /* 0x0A */ + case HCI_ERR_CONNECTION_EXISTS: return "Conn Exists"; /* 0x0B */ + case HCI_ERR_COMMAND_DISALLOWED: return "Cmd Disallowed"; /* 0x0C */ + case HCI_ERR_HOST_REJECT_RESOURCES: return "Rejected: Resources"; /* 0x0D */ + case HCI_ERR_HOST_REJECT_SECURITY: return "Rejected: Security"; /* 0x0E */ + case HCI_ERR_HOST_REJECT_DEVICE: return "Rejected: BD_ADDR"; /* 0x0F */ + case HCI_ERR_HOST_TIMEOUT: return "Accept Timeout"; /* 0x10 */ + case HCI_ERR_UNSUPPORTED_VALUE: return "Unsupported Value"; /* 0x11 */ + case HCI_ERR_ILLEGAL_PARAMETER_FMT: return "Invalid Param"; /* 0x12 */ + case HCI_ERR_PEER_USER: return "Terminated by Peer"; /* 0x13 */ + case HCI_ERR_PEER_LOW_RESOURCES: return "Peer Low Resources"; /* 0x14 */ + case HCI_ERR_PEER_POWER_OFF: return "Peer Power Off"; /* 0x15 */ + case HCI_ERR_CONN_CAUSE_LOCAL_HOST: return "Terminated by Host"; /* 0x16 */ + case HCI_ERR_REPEATED_ATTEMPTS: return "Repeated Attempts"; /* 0x17 */ + case HCI_ERR_PAIRING_NOT_ALLOWED: return "Pairing Not Allowed"; /* 0x18 */ + case HCI_ERR_UNKNOWN_LMP_PDU: return "Unknown LMP PDU"; /* 0x19 */ + case HCI_ERR_UNSUPPORTED_REM_FEATURE: return "Unsupported Remote Feature"; /* 0x1A */ + case HCI_ERR_SCO_OFFSET_REJECTED: return "SCO Offset Rejected"; /* 0x1B */ + case HCI_ERR_SCO_INTERVAL_REJECTED: return "SCO Interval Rejected"; /* 0x1C */ + case HCI_ERR_SCO_AIR_MODE: return "SCO Air Mode Rejected"; /* 0x1D */ + case HCI_ERR_INVALID_LMP_PARAM: return "Invalid LMP/LL Param"; /* 0x1E */ + case HCI_ERR_UNSPECIFIED: return "Unspecified Error"; /* 0x1F */ + case HCI_ERR_UNSUPPORTED_LMP_PARAMETERS: return "Unsupported LMP/LL"; /* 0x20 */ + case HCI_ERR_ROLE_CHANGE_NOT_ALLOWED: return "Role Change Not Allowed"; /* 0x21 */ + case HCI_ERR_LMP_RESPONSE_TIMEOUT: return "LMP/LL Response Timeout"; /* 0x22 */ + case HCI_ERR_LMP_ERR_TRANS_COLLISION: return "Transaction Collision"; /* 0x23 */ + case HCI_ERR_LMP_PDU_NOT_ALLOWED: return "LMP PDU Not Allowed"; /* 0x24 */ + case HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE: return "Encryption Not Acceptable"; /* 0x25 */ + case HCI_ERR_UNIT_KEY_USED: return "Link Key Used"; /* 0x26 */ + case HCI_ERR_QOS_NOT_SUPPORTED: return "QoS Not Supported"; /* 0x27 */ + case HCI_ERR_INSTANT_PASSED: return "Instant Passed"; /* 0x28 */ + case HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED: return "Pairing w/ Unit Key Not Supported"; /* 0x29 */ + case HCI_ERR_DIFF_TRANSACTION_COLLISION: return "Transaction Collision"; /* 0x2A */ + case HCI_ERR_UNDEFINED_0x2B: return "Reserved"; /* 0x2B */ + case HCI_ERR_QOS_UNACCEPTABLE_PARAM: return "QoS Unacceptable"; /* 0x2C */ + case HCI_ERR_QOS_REJECTED: return "QoS Rejected"; /* 0x2D */ + case HCI_ERR_CHAN_CLASSIF_NOT_SUPPORTED: return "Chan Classif Not Supported"; /* 0x2E */ + case HCI_ERR_INSUFFCIENT_SECURITY: return "Insufficient Security"; /* 0x2F */ + case HCI_ERR_PARAM_OUT_OF_RANGE: return "Param Out of Range"; /* 0x30 */ + case HCI_ERR_UNDEFINED_0x31: return "Reserved"; /* 0x31 */ + case HCI_ERR_ROLE_SWITCH_PENDING: return "Role Switch Pending"; /* 0x32 */ + case HCI_ERR_UNDEFINED_0x33: return "Reserved"; /* 0x33 */ + case HCI_ERR_RESERVED_SLOT_VIOLATION: return "Slot Violation"; /* 0x34 */ + case HCI_ERR_ROLE_SWITCH_FAILED: return "Role Switch Failed"; /* 0x35 */ + case HCI_ERR_INQ_RSP_DATA_TOO_LARGE: return "Inquiry Response Too Large"; /* 0x36 */ + case HCI_ERR_SIMPLE_PAIRING_NOT_SUPPORTED: return "Simple Pairing Not Supported"; /* 0x37 */ + case HCI_ERR_HOST_BUSY_PAIRING: return "Host Busy"; /* 0x38 */ + case HCI_ERR_REJ_NO_SUITABLE_CHANNEL: return "No Suitable Channel"; /* 0x39 */ + case HCI_ERR_CONTROLLER_BUSY: return "Controller Busy"; /* 0x3A */ + case HCI_ERR_UNACCEPT_CONN_INTERVAL: return "Unacceptable Conn Interval"; /* 0x3B */ + case HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT: return "Adv Timeout"; /* 0x3C */ + case HCI_ERR_CONN_TOUT_DUE_TO_MIC_FAILURE: return "MIC Failure"; /* 0x3D */ + case HCI_ERR_CONN_FAILED_ESTABLISHMENT: return "Conn Failed"; /* 0x3E */ + case HCI_ERR_MAC_CONNECTION_FAILED: return "Previously Used"; /* 0x3F */ + default: { + static char buf[24]; + snprintf(buf, sizeof(buf), "Unknown Status (0x%02X)", status); + return buf; + } + } +} +#endif diff --git a/components/bt/host/bluedroid/hci/include/hci/hci_layer.h b/components/bt/host/bluedroid/hci/include/hci/hci_layer.h index c48d05655e6a..356f2c044b57 100644 --- a/components/bt/host/bluedroid/hci/include/hci/hci_layer.h +++ b/components/bt/host/bluedroid/hci/include/hci/hci_layer.h @@ -112,3 +112,5 @@ int hci_adv_credits_force_release(uint16_t num); #endif #endif // #if (BLE_42_SCAN_EN == TRUE) #endif /* _HCI_LAYER_H_ */ + +const char *hci_status_code_to_string(uint8_t status); diff --git a/components/bt/host/bluedroid/hci/packet_fragmenter.c b/components/bt/host/bluedroid/hci/packet_fragmenter.c index d8f2ff918fa3..dff48be0a318 100644 --- a/components/bt/host/bluedroid/hci/packet_fragmenter.c +++ b/components/bt/host/bluedroid/hci/packet_fragmenter.c @@ -26,7 +26,7 @@ #include "osi/hash_map.h" #include "osi/hash_functions.h" #include "common/bt_trace.h" - +#include "esp_log.h" #define APPLY_CONTINUATION_FLAG(handle) (((handle) & 0xCFFF) | 0x1000) #define APPLY_START_FLAG(handle) (((handle) & 0xCFFF) | 0x2000) @@ -173,7 +173,8 @@ static void reassemble_and_dispatch(BT_HDR *packet) partial_packet = (BT_HDR *)osi_calloc(full_length + sizeof(BT_HDR)); if (partial_packet == NULL) { - HCI_TRACE_WARNING("%s full_length %d no memory.\n", __func__, full_length); + HCI_TRACE_WARNING("%s full_length %d no memory, free=%d, largest_block=%d", __func__, full_length, + heap_caps_get_free_size(MALLOC_CAP_DEFAULT), heap_caps_get_largest_free_block(MALLOC_CAP_DEFAULT)); assert(0); } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index 8f676a655a6d..454ebc722e48 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -1704,6 +1704,9 @@ tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk) #if (SMP_INCLUDED == TRUE) void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable) { +#if BLE_INCLUDED == TRUE + l2cble_notify_le_connection(bd_addr); +#endif // BLE_INCLUDED == TRUE tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr); BOOLEAN enc_cback; @@ -2956,6 +2959,15 @@ uint8_t btm_ble_sec_dev_record_count(void) for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { p_dev_rec = list_node(p_node); if (p_dev_rec && (p_dev_rec->sec_flags & BTM_SEC_IN_USE) && (p_dev_rec->ble.key_type != BTM_LE_KEY_NONE)) { + BTM_TRACE_DEBUG("%s BLE security device #%d: bd_addr=%02X:%02X:%02X:%02X:%02X:%02X", + __func__, + count, + p_dev_rec->bd_addr[0], + p_dev_rec->bd_addr[1], + p_dev_rec->bd_addr[2], + p_dev_rec->bd_addr[3], + p_dev_rec->bd_addr[4], + p_dev_rec->bd_addr[5]); count++; } } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 76fe63c08a9e..764ca477bfed 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -1390,6 +1390,12 @@ uint8_t btm_ble_ext_adv_active_count(void) for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) { if (adv_record[i].enabled == true) { + BTM_TRACE_DEBUG("%s EXT ADV active #%d: instance=%d, duration=%d, max_events=%d", + __func__, + count, + adv_record[i].instance, + adv_record[i].duration, + adv_record[i].max_events); count++; } } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c index 39784bb11ad2..16617f3bd033 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c @@ -984,6 +984,10 @@ BOOLEAN btm_ble_resolving_list_load_dev(tBTM_SEC_DEV_REC *p_dev_rec) *******************************************************************************/ void btm_ble_resolving_list_remove_dev(tBTM_SEC_DEV_REC *p_dev_rec) { + BTM_TRACE_EVENT ("%s - bd_addr=%02x:%02x:%02x:%02x:%02x:%02x", __func__, + p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2], + p_dev_rec->bd_addr[3], p_dev_rec->bd_addr[4], p_dev_rec->bd_addr[5]); + UINT8 rl_mask = btm_cb.ble_ctr_cb.rl_state; BTM_TRACE_EVENT ("%s\n", __func__); diff --git a/components/bt/host/bluedroid/stack/btm/btm_dev.c b/components/bt/host/bluedroid/stack/btm/btm_dev.c index 7e1095f4a51d..1784d4a35356 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_dev.c +++ b/components/bt/host/bluedroid/stack/btm/btm_dev.c @@ -335,7 +335,8 @@ tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr) BOOLEAN new_entry_found = FALSE; BOOLEAN old_entry_found = FALSE; BOOLEAN malloc_new_entry = FALSE; - BTM_TRACE_EVENT ("btm_sec_alloc_dev\n"); + BTM_TRACE_EVENT ("btm_sec_alloc_dev - start alloc for device %02x:%02x:%02x:%02x:%02x:%02x", + bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]); for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { p_dev_old_rec = list_node(p_node); /* look for old entry which match the bd_addr and the BTM_SEC_IN_USE is cleared */ @@ -691,6 +692,14 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) old_ts = p_dev_rec->timestamp; } } + + if (p_oldest) { + BTM_TRACE_EVENT("oldest paired device found: bd_addr=%02x:%02x:%02x:%02x:%02x:%02x, timestamp=%u", + p_oldest->bd_addr[0], p_oldest->bd_addr[1], p_oldest->bd_addr[2], + p_oldest->bd_addr[3], p_oldest->bd_addr[4], p_oldest->bd_addr[5], + p_oldest->timestamp); + } + return (p_oldest); } /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/btm/btm_inq.c b/components/bt/host/bluedroid/stack/btm/btm_inq.c index 4456140df93f..41a47300e729 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/components/bt/host/bluedroid/stack/btm/btm_inq.c @@ -240,13 +240,6 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter scan_mode |= HCI_PAGE_SCAN_ENABLED; } - if (btsnd_hcic_write_scan_enable (scan_mode)) { - btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_DISCOVERABLE_MASK); - btm_cb.btm_inq_vars.discoverable_mode |= inq_mode; - } else { - return (BTM_NO_RESOURCES); - } - /* Change the service class bit if mode has changed */ p_cod = BTM_ReadDeviceClass(); BTM_COD_SERVICE_CLASS(service_class, p_cod); @@ -266,6 +259,13 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter (void) BTM_SetDeviceClass (cod); } + if (btsnd_hcic_write_scan_enable (scan_mode)) { + btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_DISCOVERABLE_MASK); + btm_cb.btm_inq_vars.discoverable_mode |= inq_mode; + } else { + return (BTM_NO_RESOURCES); + } + return (BTM_SUCCESS); } diff --git a/components/bt/host/bluedroid/stack/btm/btm_main.c b/components/bt/host/bluedroid/stack/btm/btm_main.c index 67882af0efce..b109e5395b6c 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_main.c +++ b/components/bt/host/bluedroid/stack/btm/btm_main.c @@ -136,6 +136,15 @@ uint8_t btm_ble_acl_active_count(void) for (p_node = list_begin(btm_cb.p_acl_db_list); p_node; p_node = list_next(p_node)) { p_acl_conn = list_node(p_node); if (p_acl_conn && p_acl_conn->in_use && p_acl_conn->transport == BT_TRANSPORT_LE) { + BTM_TRACE_DEBUG("%s LE ACL active #%d: remote_addr=%02X:%02X:%02X:%02X:%02X:%02X", + __func__, + count, + p_acl_conn->remote_addr[0], + p_acl_conn->remote_addr[1], + p_acl_conn->remote_addr[2], + p_acl_conn->remote_addr[3], + p_acl_conn->remote_addr[4], + p_acl_conn->remote_addr[5]); count++; } } diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index eb2995b958d1..c9891b66b410 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1128,7 +1128,9 @@ static void btu_hcif_esco_connection_chg_evt (UINT8 *p) static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_len, void *p_cplt_cback) { +#if (BLE_INCLUDED == TRUE) uint8_t status; +#endif // (BLE_INCLUDED == TRUE) switch (opcode) { #if (CLASSIC_BT_INCLUDED == TRUE) case HCI_INQUIRY_CANCEL: @@ -1395,10 +1397,6 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l if ((opcode & HCI_GRP_VENDOR_SPECIFIC) == HCI_GRP_VENDOR_SPECIFIC) { btm_vsc_complete (p, opcode, evt_len, (tBTM_CMPL_CB *)p_cplt_cback); } - STREAM_TO_UINT8 (status, p); - if(status != HCI_SUCCESS) { - HCI_TRACE_ERROR("CC evt: op=0x%x, status=0x%x", opcode, status); - } break; } } @@ -1421,6 +1419,10 @@ static void btu_hcif_command_complete_evt_on_task(BT_HDR *event) uint8_t *stream = hack->response->data + hack->response->offset + 3; // 2 to skip the event headers, 1 to skip the command credits STREAM_TO_UINT16(opcode, stream); + if (*stream != HCI_SUCCESS) { + HCI_TRACE_WARNING("opcode=0x%04x, status= %02x: %s", opcode, *stream, hci_status_code_to_string(*stream)); + } + btu_hcif_hdl_command_complete( opcode, stream, @@ -1506,7 +1508,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c void *p_vsc_status_cback) { if (status != HCI_SUCCESS){ - HCI_TRACE_WARNING("%s,opcode:0x%04x,status:0x%02x", __func__, opcode,status); + HCI_TRACE_WARNING("opcode=0x%04x, status= %02x: %s", opcode, status, hci_status_code_to_string(status)); } BD_ADDR bd_addr; UINT16 handle; diff --git a/components/bt/host/bluedroid/stack/hid/hidd_conn.c b/components/bt/host/bluedroid/stack/hid/hidd_conn.c index 5a8e36ee599c..5c9164c2c539 100644 --- a/components/bt/host/bluedroid/stack/hid/hidd_conn.c +++ b/components/bt/host/bluedroid/stack/hid/hidd_conn.c @@ -775,6 +775,7 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param } return HID_SUCCESS; } + osi_free(p_buf); return HID_ERR_NO_CONNECTION; } #ifdef REPORT_TRANSFER_TIMESTAMP diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index 64ebcbd4363c..97cae231f780 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -25,7 +25,6 @@ #include #include -#include "osi/allocator.h" #include "device/controller.h" #include "stack/bt_types.h" #include "stack/hcimsgs.h" @@ -36,6 +35,7 @@ #include "stack/btm_api.h" #include "btm_int.h" #include "stack/hcidefs.h" +#include "bt_common.h" #include "osi/allocator.h" #include "osi/list.h" @@ -345,6 +345,15 @@ uint8_t l2cu_ble_plcb_active_count(void) for (p_node = list_begin(l2cb.p_lcb_pool); p_node; p_node = list_next(p_node)) { p_lcb = list_node(p_node); if (p_lcb && p_lcb->in_use && p_lcb->transport == BT_TRANSPORT_LE) { + L2CAP_TRACE_DEBUG("%s LE PLCB active #%d: remote_addr=%02X:%02X:%02X:%02X:%02X:%02X", + __func__, + active_count, + p_lcb->remote_bd_addr[0], + p_lcb->remote_bd_addr[1], + p_lcb->remote_bd_addr[2], + p_lcb->remote_bd_addr[3], + p_lcb->remote_bd_addr[4], + p_lcb->remote_bd_addr[5]); active_count ++; } } diff --git a/components/bt/host/bluedroid/stack/smp/smp_main.c b/components/bt/host/bluedroid/stack/smp/smp_main.c index 512aca0a8c5c..fa4d5ffbe323 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_main.c +++ b/components/bt/host/bluedroid/stack/smp/smp_main.c @@ -388,7 +388,7 @@ static const UINT8 smp_master_wait_dhk_check_table[][SMP_SM_NUM_COLS] = { static const UINT8 smp_master_dhk_check_table[][SMP_SM_NUM_COLS] = { /* Event Action Next State */ - /* locally calculated peer dhkey check is ready -> compare it withs DHKey Check actually received from peer */ + /* locally calculated peer dhkey check is ready -> compare it with DHKey Check actually received from peer */ /* SC_KEY_READY */{SMP_MATCH_DHKEY_CHECKS, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK}, /* locally calculated peer dhkey check is ready -> calculate STK, go to sending */ /* HCI LE Start Encryption command */ @@ -580,7 +580,7 @@ static const UINT8 smp_slave_wait_dhk_check_table[][SMP_SM_NUM_COLS] = { static const UINT8 smp_slave_dhk_check_table[][SMP_SM_NUM_COLS] = { /* Event Action Next State */ - /* locally calculated peer dhkey check is ready -> compare it withs DHKey Check */ + /* locally calculated peer dhkey check is ready -> compare it with DHKey Check */ /* actually received from peer */ /* SC_KEY_READY */{SMP_MATCH_DHKEY_CHECKS, SMP_SM_NO_ACTION, SMP_STATE_DHK_CHECK}, @@ -771,6 +771,8 @@ void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data) /* execute action functions */ for (i = 0; i < SMP_NUM_ACTIONS; i++) { if ((action = state_table[entry - 1][i]) != SMP_SM_NO_ACTION && smp_sm_action[action] != NULL) { + SMP_TRACE_DEBUG("smp action %d for state %s, event %s", + action, smp_get_state_name(curr_state), smp_get_event_name(event)); (*smp_sm_action[action])(p_cb, (tSMP_INT_DATA *)p_data); } else { break; diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index a5f56692f6c8..18b1bdef4e04 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -485,6 +485,26 @@ menu "Memory Settings" default 1 help This is the service data unit buffer count for l2cap coc. + + config BT_NIMBLE_MEMPOOL_RUNTIME_ALLOC + bool "Support on-demand runtime memory allocation for mempool" + depends on BT_NIMBLE_ENABLED && !SOC_ESP_NIMBLE_CONTROLLER + default n + help + When this option is enabled, mempool does not require pre-allocating memory. + Instead, memory for each block will be dynamically allocated and released + during mempool usage. This can significantly reduce memory consumption + after mempool initialization, but may have some impact on performance. + + config BT_NIMBLE_MEMPOOL_BLOCK_REUSED + bool "Support block reuse for mempool runtime memory allocation" + depends on BT_NIMBLE_MEMPOOL_RUNTIME_ALLOC + default n + help + When this option is enabled, dynamically allocated blocks will not be freed + but will be reused instead. This ensures virtually no impact on performance + while reducing the memory consumption of the mempool. + endmenu #Memory menu "BLE 5.x Features" 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 04778593cafb..bffd7ee14039 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 @@ -96,7 +96,11 @@ int ble_hci_trans_hs_cmd_tx(uint8_t *cmd) rc = BLE_HS_ETIMEOUT_HCI; } +#if MYNEWT_VAL(MP_RUNTIME_ALLOC) + ble_transport_free(BLE_HCI_CMD, cmd); +#else ble_transport_free(cmd); +#endif return rc; } diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 8fd41d86c4ed..6f9ff29d2619 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 8fd41d86c4ed8657e6c97d6da8b3d214622db737 +Subproject commit 6f9ff29d261939945c4f2fa74c01763009cb2cd0 diff --git a/components/bt/host/nimble/port/include/esp_nimble_cfg.h b/components/bt/host/nimble/port/include/esp_nimble_cfg.h index 0d063aeca40e..445c0e295725 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/components/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -2214,4 +2214,20 @@ #endif #endif +#ifndef MYNEWT_VAL_MP_RUNTIME_ALLOC +#ifdef CONFIG_BT_NIMBLE_MEMPOOL_RUNTIME_ALLOC +#define MYNEWT_VAL_MP_RUNTIME_ALLOC (1) +#else +#define MYNEWT_VAL_MP_RUNTIME_ALLOC (0) +#endif +#endif + +#ifndef MYNEWT_VAL_MP_BLOCK_REUSED +#ifdef CONFIG_BT_NIMBLE_MEMPOOL_BLOCK_REUSED +#define MYNEWT_VAL_MP_BLOCK_REUSED (1) +#else +#define MYNEWT_VAL_MP_BLOCK_REUSED (0) +#endif +#endif + #endif diff --git a/components/bt/include/esp32c6/include/esp_bt.h b/components/bt/include/esp32c6/include/esp_bt.h index 2621f3fb52bf..974cfd433a33 100644 --- a/components/bt/include/esp32c6/include/esp_bt.h +++ b/components/bt/include/esp32c6/include/esp_bt.h @@ -156,7 +156,7 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type */ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -#define CONFIG_VERSION 0x20251022 +#define CONFIG_VERSION 0x20251104 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -233,6 +233,7 @@ typedef struct { uint8_t adv_rsv_cnt; /*!< BLE adv state machine reserve count number */ uint8_t conn_rsv_cnt; /*!< BLE conn state machine reserve count number */ uint8_t priority_level_cfg; /*!< The option for priority level configuration */ + uint8_t slv_fst_rx_lat_en; /*!< The option for enabling slave fast PDU reception during latency. */ uint32_t config_magic; /*!< Magic number for configuration validation */ } esp_bt_controller_config_t; @@ -297,6 +298,7 @@ typedef struct { .adv_rsv_cnt = BLE_LL_ADV_SM_RESERVE_CNT_N, \ .conn_rsv_cnt = BLE_LL_CONN_SM_RESERVE_CNT_N, \ .priority_level_cfg = BT_LL_CTRL_PRIO_LVL_CFG, \ + .slv_fst_rx_lat_en = DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN, \ .config_magic = CONFIG_MAGIC, \ } #elif CONFIG_IDF_TARGET_ESP32C61 @@ -359,6 +361,7 @@ typedef struct { .adv_rsv_cnt = BLE_LL_ADV_SM_RESERVE_CNT_N, \ .conn_rsv_cnt = BLE_LL_CONN_SM_RESERVE_CNT_N, \ .priority_level_cfg = BT_LL_CTRL_PRIO_LVL_CFG, \ + .slv_fst_rx_lat_en = DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN, \ .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 b6bb5bfb23bd..a171b52a6b36 100644 --- a/components/bt/include/esp32h2/include/esp_bt.h +++ b/components/bt/include/esp32h2/include/esp_bt.h @@ -161,7 +161,7 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type */ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -#define CONFIG_VERSION 0x20251022 +#define CONFIG_VERSION 0x20251104 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -237,6 +237,7 @@ typedef struct { uint8_t adv_rsv_cnt; /*!< BLE adv state machine reserve count number */ uint8_t conn_rsv_cnt; /*!< BLE conn state machine reserve count number */ uint8_t priority_level_cfg; /*!< The option for priority level configuration */ + uint8_t slv_fst_rx_lat_en; /*!< The option for enabling slave fast PDU reception during latency. */ uint32_t config_magic; /*!< Configuration magic value */ } esp_bt_controller_config_t; @@ -300,6 +301,7 @@ typedef struct { .adv_rsv_cnt = BLE_LL_ADV_SM_RESERVE_CNT_N, \ .conn_rsv_cnt = BLE_LL_CONN_SM_RESERVE_CNT_N, \ .priority_level_cfg = BT_LL_CTRL_PRIO_LVL_CFG, \ + .slv_fst_rx_lat_en = DEFAULT_BT_LE_CTRL_SLV_FAST_RX_CONN_DATA_EN, \ .config_magic = CONFIG_MAGIC, \ } diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index a12c501177f2..be1104135594 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -25,7 +25,7 @@ menu "ESP-TLS" config ESP_TLS_USE_DS_PERIPHERAL bool "Use Digital Signature (DS) Peripheral with ESP-TLS" - depends on ESP_TLS_USING_MBEDTLS && SOC_DIG_SIGN_SUPPORTED + depends on ESP_TLS_USING_MBEDTLS && SOC_DIG_SIGN_SUPPORTED && MBEDTLS_PK_RSA_ALT_SUPPORT default y help Enable use of the Digital Signature Peripheral for ESP-TLS.The DS peripheral diff --git a/components/esp_driver_i2s/i2s_common.c b/components/esp_driver_i2s/i2s_common.c index 84eb46a5de55..a6ad14f15f21 100644 --- a/components/esp_driver_i2s/i2s_common.c +++ b/components/esp_driver_i2s/i2s_common.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 */ @@ -229,12 +229,6 @@ static inline bool i2s_take_available_channel(i2s_controller_t *i2s_obj, uint8_t { bool is_available = false; -#if SOC_I2S_HW_VERSION_1 - /* In ESP32 and ESP32-S2, tx channel and rx channel are not totally separated - * Take both two channels in case one channel can affect another - */ - chan_search_mask = I2S_DIR_RX | I2S_DIR_TX; -#endif portENTER_CRITICAL(&g_i2s.spinlock); if (!(chan_search_mask & i2s_obj->chan_occupancy)) { i2s_obj->chan_occupancy |= chan_search_mask; @@ -810,12 +804,12 @@ void i2s_gpio_check_and_set(i2s_chan_handle_t handle, int gpio, uint32_t signal_ if (gpio != (int)I2S_GPIO_UNUSED) { gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); if (is_input) { - /* Set direction, for some GPIOs, the input function are not enabled as default */ - gpio_set_direction(gpio, GPIO_MODE_INPUT); + /* Enable the input, for some GPIOs, the input function are not enabled as default */ + gpio_ll_input_enable(GPIO_HAL_GET_HW(GPIO_PORT_0), (gpio_num_t)gpio); esp_rom_gpio_connect_in_signal(gpio, signal_idx, is_invert); } else { i2s_output_gpio_reserve(handle, gpio); - gpio_set_direction(gpio, GPIO_MODE_OUTPUT); + /* output will be enabled in esp_rom_gpio_connect_out_signal */ esp_rom_gpio_connect_out_signal(gpio, signal_idx, is_invert, 0); } } @@ -826,7 +820,7 @@ void i2s_gpio_loopback_set(i2s_chan_handle_t handle, int gpio, uint32_t out_sig_ if (gpio != (int)I2S_GPIO_UNUSED) { i2s_output_gpio_reserve(handle, gpio); gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO); - gpio_set_direction(gpio, GPIO_MODE_INPUT_OUTPUT); + gpio_ll_input_enable(GPIO_HAL_GET_HW(GPIO_PORT_0), (gpio_num_t)gpio); esp_rom_gpio_connect_out_signal(gpio, out_sig_idx, 0, 0); esp_rom_gpio_connect_in_signal(gpio, in_sig_idx, 0); } @@ -1220,7 +1214,12 @@ esp_err_t i2s_channel_write(i2s_chan_handle_t handle, const void *src, size_t si ESP_RETURN_ON_FALSE(xSemaphoreTake(handle->binary, pdMS_TO_TICKS(timeout_ms)) == pdTRUE, ESP_ERR_INVALID_STATE, TAG, "The channel is not enabled"); src_byte = (char *)src; while (size > 0 && handle->state == I2S_CHAN_STATE_RUNNING) { - if (handle->dma.rw_pos == handle->dma.buf_size || handle->dma.curr_ptr == NULL) { + /* Acquire the new DMA buffer while: + * 1. The current buffer is fully filled + * 2. The current buffer is not set + * 3. The queue is almost full, i.e., the curr_ptr is nearly to be invalid + */ + if (handle->dma.rw_pos == handle->dma.buf_size || handle->dma.curr_ptr == NULL || uxQueueSpacesAvailable(handle->msg_queue) <= (handle->dma.desc_num > 2 ? 1 : 0)) { if (xQueueReceive(handle->msg_queue, &(handle->dma.curr_ptr), pdMS_TO_TICKS(timeout_ms)) == pdFALSE) { ret = ESP_ERR_TIMEOUT; break; @@ -1265,7 +1264,12 @@ esp_err_t i2s_channel_read(i2s_chan_handle_t handle, void *dest, size_t size, si /* The binary semaphore can only be taken when the channel has been enabled and no other reading operation in progress */ ESP_RETURN_ON_FALSE(xSemaphoreTake(handle->binary, pdMS_TO_TICKS(timeout_ms)) == pdTRUE, ESP_ERR_INVALID_STATE, TAG, "The channel is not enabled"); while (size > 0 && handle->state == I2S_CHAN_STATE_RUNNING) { - if (handle->dma.rw_pos == handle->dma.buf_size || handle->dma.curr_ptr == NULL) { + /* Acquire the new DMA buffer while: + * 1. The current buffer is fully filled + * 2. The current buffer is not set + * 3. The queue is almost full, i.e., the curr_ptr is nearly to be invalid + */ + if (handle->dma.rw_pos == handle->dma.buf_size || handle->dma.curr_ptr == NULL || uxQueueSpacesAvailable(handle->msg_queue) <= (handle->dma.desc_num > 2 ? 1 : 0)) { if (xQueueReceive(handle->msg_queue, &(handle->dma.curr_ptr), pdMS_TO_TICKS(timeout_ms)) == pdFALSE) { ret = ESP_ERR_TIMEOUT; break; diff --git a/components/esp_driver_i2s/i2s_private.h b/components/esp_driver_i2s/i2s_private.h index 6ae68a71fd7f..1675baf9f395 100644 --- a/components/esp_driver_i2s/i2s_private.h +++ b/components/esp_driver_i2s/i2s_private.h @@ -135,6 +135,7 @@ struct i2s_channel_obj_t { /* Stored configurations */ int intr_prio_flags;/*!< i2s interrupt priority flags */ void *mode_info; /*!< Slot, clock and gpio information of each mode */ + bool full_duplex_slave; /*!< whether the channel is forced to switch to slave role for full duplex */ #if SOC_I2S_SUPPORTS_APLL bool apll_en; /*!< Flag of whether APLL enabled */ #endif diff --git a/components/esp_driver_i2s/i2s_std.c b/components/esp_driver_i2s/i2s_std.c index 51fff5e9614a..9e3cc017cdc4 100644 --- a/components/esp_driver_i2s/i2s_std.c +++ b/components/esp_driver_i2s/i2s_std.c @@ -33,9 +33,10 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std uint32_t slot_bits = (slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO) || ((int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width) ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + slot_cfg->slot_bit_width = slot_bits; /* Calculate multiple * Fmclk = bck_div*fbck = fsclk/(mclk_div+b/a) */ - if (handle->role == I2S_ROLE_MASTER) { + if (handle->role == I2S_ROLE_MASTER || handle->full_duplex_slave) { clk_info->bclk = rate * handle->total_slot * slot_bits; clk_info->mclk = rate * clk_cfg->mclk_multiple; clk_info->bclk_div = clk_info->mclk / clk_info->bclk; @@ -111,18 +112,13 @@ static esp_err_t i2s_std_set_slot(i2s_chan_handle_t handle, const i2s_std_slot_c ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, buf_size), TAG, "allocate memory for dma descriptor failed"); } - bool is_slave = handle->role == I2S_ROLE_SLAVE; /* Share bck and ws signal in full-duplex mode */ if (handle->controller->full_duplex) { i2s_ll_share_bck_ws(handle->controller->hal.dev, true); - /* Since bck and ws are shared, only tx or rx can be master - Force to set rx as slave to avoid conflict of clock signal */ - if (handle->dir == I2S_DIR_RX) { - is_slave = true; - } } else { i2s_ll_share_bck_ws(handle->controller->hal.dev, false); } + bool is_slave = handle->role == I2S_ROLE_SLAVE; portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply STD format */ @@ -167,43 +163,101 @@ static esp_err_t i2s_std_set_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_c /* Set mclk pin */ ESP_RETURN_ON_ERROR(i2s_check_set_mclk(handle, id, gpio_cfg->mclk, std_cfg->clk_cfg.clk_src, gpio_cfg->invert_flags.mclk_inv), TAG, "mclk config failed"); - if (handle->role == I2S_ROLE_SLAVE) { - /* For "tx + slave" mode, select TX signal index for ws and bck */ - if (handle->dir == I2S_DIR_TX && !handle->controller->full_duplex) { #if SOC_I2S_HW_VERSION_2 + /* Bind the MCLK signal to the TX or RX clock source */ + if (!handle->controller->full_duplex) { + if (handle->dir == I2S_DIR_TX) { I2S_CLOCK_SRC_ATOMIC() { i2s_ll_mclk_bind_to_tx_clk(handle->controller->hal.dev); } -#endif - i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.ws_inv); - i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv); - /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ } else { - i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.ws_inv); - i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv); + I2S_CLOCK_SRC_ATOMIC() { + i2s_ll_mclk_bind_to_rx_clk(handle->controller->hal.dev); + } } - } else { - /* For "rx + master" mode, select RX signal index for ws and bck */ - if (handle->dir == I2S_DIR_RX && !handle->controller->full_duplex) { -#if SOC_I2S_HW_VERSION_2 + } else if (handle->role == I2S_ROLE_MASTER) { + if (handle->dir == I2S_DIR_TX) { + I2S_CLOCK_SRC_ATOMIC() { + i2s_ll_mclk_bind_to_tx_clk(handle->controller->hal.dev); + } + } else { I2S_CLOCK_SRC_ATOMIC() { i2s_ll_mclk_bind_to_rx_clk(handle->controller->hal.dev); } + } + } #endif - i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.ws_inv); - i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv); - /* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */ + + uint32_t ws_sig = 0; + uint32_t bck_sig = 0; + bool is_input = handle->role == I2S_ROLE_SLAVE; + if (handle->role == I2S_ROLE_SLAVE) { + // Assign slave signals + if (handle->dir == I2S_DIR_TX) { + ws_sig = i2s_periph_signal[id].s_tx_ws_sig; + bck_sig = i2s_periph_signal[id].s_tx_bck_sig; + } else { + ws_sig = i2s_periph_signal[id].s_rx_ws_sig; + bck_sig = i2s_periph_signal[id].s_rx_bck_sig; + } + } else { + // Assign master signals + if (handle->dir == I2S_DIR_TX) { + ws_sig = i2s_periph_signal[id].m_tx_ws_sig; + bck_sig = i2s_periph_signal[id].m_tx_bck_sig; } else { - i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.ws_inv); - i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv); + ws_sig = i2s_periph_signal[id].m_rx_ws_sig; + bck_sig = i2s_periph_signal[id].m_rx_bck_sig; } } + i2s_gpio_check_and_set(handle, gpio_cfg->ws, ws_sig, is_input, gpio_cfg->invert_flags.ws_inv); + i2s_gpio_check_and_set(handle, gpio_cfg->bclk, bck_sig, is_input, gpio_cfg->invert_flags.bclk_inv); + /* Update the mode info: gpio configuration */ memcpy(&(std_cfg->gpio_cfg), gpio_cfg, sizeof(i2s_std_gpio_config_t)); return ESP_OK; } +static esp_err_t s_i2s_channel_try_to_constitude_std_duplex(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg) +{ + /* Get another direction handle */ + i2s_chan_handle_t another_handle = handle->dir == I2S_DIR_RX ? handle->controller->tx_chan : handle->controller->rx_chan; + /* Condition: 1. Another direction channel is registered + * 2. Not a full-duplex channel yet + * 3. Another channel is initialized, try to compare the configurations */ + if (another_handle && another_handle->state >= I2S_CHAN_STATE_READY) { + /* Judge if the two channels can constitute full-duplex */ + if (!handle->controller->full_duplex) { + i2s_std_config_t curr_cfg = *std_cfg; + /* Override the slot bit width to the actual slot bit width */ + curr_cfg.slot_cfg.slot_bit_width = (int)curr_cfg.slot_cfg.slot_bit_width < (int)curr_cfg.slot_cfg.data_bit_width ? + curr_cfg.slot_cfg.data_bit_width : curr_cfg.slot_cfg.slot_bit_width; + /* Compare the hardware configurations of the two channels, constitute the full-duplex if they are the same */ + if (memcmp(another_handle->mode_info, &curr_cfg, sizeof(i2s_std_config_t)) == 0) { + handle->controller->full_duplex = true; + ESP_LOGD(TAG, "Constitude full-duplex on port %d", handle->controller->id); + } +#if SOC_I2S_HW_VERSION_1 + else { + ESP_LOGE(TAG, "Can't set different channel configurations on a same port"); + return ESP_ERR_INVALID_ARG; + } +#endif + } + /* Switch to the slave role if needed */ + if (handle->controller->full_duplex && + handle->role == I2S_ROLE_MASTER && + another_handle->role == I2S_ROLE_MASTER) { + /* The later initialized channel must be slave for full duplex */ + handle->role = I2S_ROLE_SLAVE; + handle->full_duplex_slave = true; + } + } + + return ESP_OK; +} + esp_err_t i2s_channel_init_std_mode(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg) { #if CONFIG_I2S_ENABLE_DEBUG_LOG @@ -221,6 +275,11 @@ esp_err_t i2s_channel_init_std_mode(i2s_chan_handle_t handle, const i2s_std_conf handle->mode_info = calloc(1, sizeof(i2s_std_config_t)); ESP_GOTO_ON_FALSE(handle->mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_REGISTER, ESP_ERR_INVALID_STATE, err, TAG, "the channel has initialized already"); + /* Try to constitute full-duplex mode if the STD configuration is totally same as another channel */ + ret = s_i2s_channel_try_to_constitude_std_duplex(handle, std_cfg); +#if SOC_I2S_HW_VERSION_1 + ESP_GOTO_ON_ERROR(ret, err, TAG, "Failed to constitute full-duplex mode"); +#endif /* i2s_set_std_slot should be called before i2s_set_std_clock while initializing, because clock is relay on the slot */ ESP_GOTO_ON_ERROR(i2s_std_set_slot(handle, &std_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); #if SOC_I2S_SUPPORTS_APLL diff --git a/components/esp_driver_i2s/i2s_tdm.c b/components/esp_driver_i2s/i2s_tdm.c index d3e5a60535a5..19ad9c977471 100644 --- a/components/esp_driver_i2s/i2s_tdm.c +++ b/components/esp_driver_i2s/i2s_tdm.c @@ -34,9 +34,10 @@ static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm uint32_t slot_bits = (slot_cfg->slot_bit_width == I2S_SLOT_BIT_WIDTH_AUTO) || ((int)slot_cfg->slot_bit_width < (int)slot_cfg->data_bit_width) ? slot_cfg->data_bit_width : slot_cfg->slot_bit_width; + slot_cfg->slot_bit_width = slot_bits; /* Calculate multiple * Fmclk = bck_div*fbck = fsclk/(mclk_div+b/a) */ - if (handle->role == I2S_ROLE_MASTER) { + if (handle->role == I2S_ROLE_MASTER || handle->full_duplex_slave) { clk_info->bclk = rate * handle->total_slot * slot_bits; clk_info->mclk = rate * clk_cfg->mclk_multiple; clk_info->bclk_div = clk_info->mclk / clk_info->bclk; @@ -119,18 +120,13 @@ static esp_err_t i2s_tdm_set_slot(i2s_chan_handle_t handle, const i2s_tdm_slot_c ESP_RETURN_ON_ERROR(i2s_alloc_dma_desc(handle, buf_size), TAG, "allocate memory for dma descriptor failed"); } - bool is_slave = handle->role == I2S_ROLE_SLAVE; /* Share bck and ws signal in full-duplex mode */ if (handle->controller->full_duplex) { i2s_ll_share_bck_ws(handle->controller->hal.dev, true); - /* Since bck and ws are shared, only tx or rx can be master - Force to set rx as slave to avoid conflict of clock signal */ - if (handle->dir == I2S_DIR_RX) { - is_slave = true; - } } else { i2s_ll_share_bck_ws(handle->controller->hal.dev, false); } + bool is_slave = handle->role == I2S_ROLE_SLAVE; portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply TDM format */ @@ -176,43 +172,92 @@ static esp_err_t i2s_tdm_set_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_c /* Set mclk pin */ ESP_RETURN_ON_ERROR(i2s_check_set_mclk(handle, id, gpio_cfg->mclk, tdm_cfg->clk_cfg.clk_src, gpio_cfg->invert_flags.mclk_inv), TAG, "mclk config failed"); - if (handle->role == I2S_ROLE_SLAVE) { - /* For "tx + slave" mode, select TX signal index for ws and bck */ - if (handle->dir == I2S_DIR_TX && !handle->controller->full_duplex) { #if SOC_I2S_HW_VERSION_2 + /* Bind the MCLK signal to the TX or RX clock source */ + if (!handle->controller->full_duplex) { + if (handle->dir == I2S_DIR_TX) { I2S_CLOCK_SRC_ATOMIC() { i2s_ll_mclk_bind_to_tx_clk(handle->controller->hal.dev); } -#endif - i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.ws_inv); - i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv); - /* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */ } else { - i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.ws_inv); - i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv); + I2S_CLOCK_SRC_ATOMIC() { + i2s_ll_mclk_bind_to_rx_clk(handle->controller->hal.dev); + } } - } else { - /* For "rx + master" mode, select RX signal index for ws and bck */ - if (handle->dir == I2S_DIR_RX && !handle->controller->full_duplex) { -#if SOC_I2S_HW_VERSION_2 + } else if (handle->role == I2S_ROLE_MASTER) { + if (handle->dir == I2S_DIR_TX) { + I2S_CLOCK_SRC_ATOMIC() { + i2s_ll_mclk_bind_to_tx_clk(handle->controller->hal.dev); + } + } else { I2S_CLOCK_SRC_ATOMIC() { i2s_ll_mclk_bind_to_rx_clk(handle->controller->hal.dev); } + } + } #endif - i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.ws_inv); - i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv); - /* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */ + + uint32_t ws_sig = 0; + uint32_t bck_sig = 0; + bool is_input = handle->role == I2S_ROLE_SLAVE; + if (handle->role == I2S_ROLE_SLAVE) { + // Assign slave signals + if (handle->dir == I2S_DIR_TX) { + ws_sig = i2s_periph_signal[id].s_tx_ws_sig; + bck_sig = i2s_periph_signal[id].s_tx_bck_sig; + } else { + ws_sig = i2s_periph_signal[id].s_rx_ws_sig; + bck_sig = i2s_periph_signal[id].s_rx_bck_sig; + } + } else { + // Assign master signals + if (handle->dir == I2S_DIR_TX) { + ws_sig = i2s_periph_signal[id].m_tx_ws_sig; + bck_sig = i2s_periph_signal[id].m_tx_bck_sig; } else { - i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.ws_inv); - i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv); + ws_sig = i2s_periph_signal[id].m_rx_ws_sig; + bck_sig = i2s_periph_signal[id].m_rx_bck_sig; } } + i2s_gpio_check_and_set(handle, gpio_cfg->ws, ws_sig, is_input, gpio_cfg->invert_flags.ws_inv); + i2s_gpio_check_and_set(handle, gpio_cfg->bclk, bck_sig, is_input, gpio_cfg->invert_flags.bclk_inv); + /* Update the mode info: gpio configuration */ memcpy(&(tdm_cfg->gpio_cfg), gpio_cfg, sizeof(i2s_tdm_gpio_config_t)); return ESP_OK; } +static void s_i2s_channel_try_to_constitude_tdm_duplex(i2s_chan_handle_t handle, const i2s_tdm_config_t *tdm_cfg) +{ + /* Get another direction handle */ + i2s_chan_handle_t another_handle = handle->dir == I2S_DIR_RX ? handle->controller->tx_chan : handle->controller->rx_chan; + /* Condition: 1. Another direction channel is registered + * 2. Not a full-duplex channel yet + * 3. Another channel is initialized, try to compare the configurations */ + if (another_handle && another_handle->state >= I2S_CHAN_STATE_READY) { + if (!handle->controller->full_duplex) { + i2s_tdm_config_t curr_cfg = *tdm_cfg; + /* Override the slot bit width to the actual slot bit width */ + curr_cfg.slot_cfg.slot_bit_width = (int)curr_cfg.slot_cfg.slot_bit_width < (int)curr_cfg.slot_cfg.data_bit_width ? + curr_cfg.slot_cfg.data_bit_width : curr_cfg.slot_cfg.slot_bit_width; + /* Compare the hardware configurations of the two channels, constitute the full-duplex if they are the same */ + if (memcmp(another_handle->mode_info, &curr_cfg, sizeof(i2s_tdm_config_t)) == 0) { + handle->controller->full_duplex = true; + ESP_LOGD(TAG, "Constitude full-duplex on port %d", handle->controller->id); + } + } + /* Switch to the slave role if needed */ + if (handle->controller->full_duplex && + handle->role == I2S_ROLE_MASTER && + another_handle->role == I2S_ROLE_MASTER) { + /* The later initialized channel must be slave for full duplex */ + handle->role = I2S_ROLE_SLAVE; + handle->full_duplex_slave = true; + } + } +} + esp_err_t i2s_channel_init_tdm_mode(i2s_chan_handle_t handle, const i2s_tdm_config_t *tdm_cfg) { #if CONFIG_I2S_ENABLE_DEBUG_LOG @@ -230,6 +275,8 @@ esp_err_t i2s_channel_init_tdm_mode(i2s_chan_handle_t handle, const i2s_tdm_conf } handle->mode_info = calloc(1, sizeof(i2s_tdm_config_t)); ESP_GOTO_ON_FALSE(handle->mode_info, ESP_ERR_NO_MEM, err, TAG, "no memory for storing the configurations"); + /* Try to constitute full-duplex mode if the TDM configuration is totally same as another channel */ + s_i2s_channel_try_to_constitude_tdm_duplex(handle, tdm_cfg); /* i2s_set_tdm_slot should be called before i2s_set_tdm_clock while initializing, because clock is relay on the slot */ ESP_GOTO_ON_ERROR(i2s_tdm_set_slot(handle, &tdm_cfg->slot_cfg), err, TAG, "initialize channel failed while setting slot"); #if SOC_I2S_SUPPORTS_APLL diff --git a/components/esp_driver_i2s/include/driver/i2s_std.h b/components/esp_driver_i2s/include/driver/i2s_std.h index 038ff2825a10..b039c9ce5719 100644 --- a/components/esp_driver_i2s/include/driver/i2s_std.h +++ b/components/esp_driver_i2s/include/driver/i2s_std.h @@ -296,6 +296,8 @@ typedef struct { * @brief Initialize I2S channel to standard mode * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) * and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED. + * @note When initialize the STD mode with a same configuration as another channel on a same port, + * these two channels can constitude as full-duplex mode automatically * * @param[in] handle I2S channel handler * @param[in] std_cfg Configurations for standard mode, including clock, slot and GPIO diff --git a/components/esp_driver_i2s/include/driver/i2s_tdm.h b/components/esp_driver_i2s/include/driver/i2s_tdm.h index ae07a244756d..b8db9cc138fc 100644 --- a/components/esp_driver_i2s/include/driver/i2s_tdm.h +++ b/components/esp_driver_i2s/include/driver/i2s_tdm.h @@ -196,6 +196,8 @@ typedef struct { * @brief Initialize I2S channel to TDM mode * @note Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) * and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED. + * @note When initialize the TDM mode with a same configuration as another channel on a same port, + * these two channels can constitude as full-duplex mode automatically * * @param[in] handle I2S channel handler * @param[in] tdm_cfg Configurations for TDM mode, including clock, slot and GPIO diff --git a/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c b/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c index cf39e5853b21..6339056686e5 100644 --- a/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c +++ b/components/esp_driver_i2s/test_apps/i2s/main/test_i2s.c @@ -217,6 +217,38 @@ TEST_CASE("I2S_basic_channel_allocation_reconfig_deleting_test", "[i2s]") TEST_ESP_OK(i2s_del_channel(tx_handle)); TEST_ESP_OK(i2s_del_channel(rx_handle)); + /* Lazy initialize std duplex test */ + chan_cfg.id = I2S_NUM_0; // Specify port id to I2S port 0 + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_channel_get_info(tx_handle, &chan_info)); + TEST_ASSERT(chan_info.pair_chan == NULL); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + TEST_ESP_OK(i2s_channel_get_info(tx_handle, &chan_info)); + TEST_ASSERT(chan_info.pair_chan == rx_handle); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); + +#if SOC_I2S_SUPPORTS_TDM + /* Lazy initialize tdm duplex test */ + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_channel_get_info(tx_handle, &chan_info)); + TEST_ASSERT(chan_info.pair_chan == NULL); + i2s_tdm_config_t tdm_cfg = { + .clk_cfg = I2S_TDM_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_TDM_PHILIPS_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO, 0x0F), + .gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN, + }; + TEST_ESP_OK(i2s_channel_init_tdm_mode(tx_handle, &tdm_cfg)); + TEST_ESP_OK(i2s_channel_init_tdm_mode(rx_handle, &tdm_cfg)); + TEST_ESP_OK(i2s_channel_get_info(tx_handle, &chan_info)); + TEST_ASSERT(chan_info.pair_chan == rx_handle); + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +#endif + /* Repeat to check if a same port can be allocated again */ TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); TEST_ESP_OK(i2s_del_channel(rx_handle)); @@ -232,6 +264,24 @@ TEST_CASE("I2S_basic_channel_allocation_reconfig_deleting_test", "[i2s]") static volatile bool task_run_flag; +#define TEST_I2S_DATA 0x78 + +static void i2s_read_check_task(void *args) +{ + i2s_chan_handle_t rx_handle = (i2s_chan_handle_t)args; + uint8_t *recv_buf = (uint8_t *)calloc(1, 2000); + TEST_ASSERT(recv_buf); + size_t recv_size = 0; + + while (task_run_flag) { + TEST_ASSERT_EQUAL(i2s_channel_read(rx_handle, recv_buf, 2000, &recv_size, 300), ESP_OK); + TEST_ASSERT_EQUAL(recv_buf[0], TEST_I2S_DATA); + } + + free(recv_buf); + vTaskDelete(NULL); +} + static void i2s_read_task(void *args) { i2s_chan_handle_t rx_handle = (i2s_chan_handle_t)args; @@ -257,6 +307,7 @@ static void i2s_write_task(void *args) i2s_chan_handle_t tx_handle = (i2s_chan_handle_t)args; uint8_t *send_buf = (uint8_t *)calloc(1, 2000); TEST_ASSERT(send_buf); + memset(send_buf, TEST_I2S_DATA, 2000); size_t send_size = 0; esp_err_t ret = ESP_OK; uint32_t cnt = 1; @@ -384,6 +435,65 @@ TEST_CASE("I2S_thread_concurrent_safety_test", "[i2s]") TEST_ESP_OK(i2s_del_channel(rx_handle)); } +TEST_CASE("I2S_lazy_duplex_test", "[i2s]") +{ + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), + .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = MASTER_MCK_IO, + .bclk = MASTER_BCK_IO, + .ws = MASTER_WS_IO, + .dout = DATA_OUT_IO, + .din = DATA_OUT_IO, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + printf("Enabled TX channel\n"); + + TEST_ESP_OK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + /* Enable the channels before creating reading/writing task*/ + TEST_ESP_OK(i2s_channel_enable(rx_handle)); + printf("Enabled RX channel\n"); + + task_run_flag = true; + /* writing task to keep writing */ + xTaskCreate(i2s_write_task, "i2s_write_task", 4096, tx_handle, 5, NULL); + printf("TX started\n"); + vTaskDelay(pdMS_TO_TICKS(1000)); + /* reading task to keep reading */ + xTaskCreate(i2s_read_check_task, "i2s_read_check_task", 4096, rx_handle, 5, NULL); + printf("RX started\n"); + + /* Wait 3 seconds to see if any failures occur */ + vTaskDelay(pdMS_TO_TICKS(1000)); + printf("Finished\n"); + + /* Stop those three tasks */ + task_run_flag = false; + + /* Wait for the three thread deleted */ + vTaskDelay(pdMS_TO_TICKS(1000)); + + /* Disable the channels, they will keep waiting until the current reading / writing finished */ + TEST_ESP_OK(i2s_channel_disable(tx_handle)); + TEST_ESP_OK(i2s_channel_disable(rx_handle)); + /* Delete the channels */ + TEST_ESP_OK(i2s_del_channel(tx_handle)); + TEST_ESP_OK(i2s_del_channel(rx_handle)); +} + static bool whether_contains_exapected_data(uint16_t *src, uint32_t src_len, uint32_t src_step, uint32_t start_val, uint32_t val_step) { uint32_t val = start_val; diff --git a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c index 4b41efb780e0..31cc08c75087 100644 --- a/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c +++ b/components/esp_driver_parlio/test_apps/parlio/main/test_parlio_rx.c @@ -293,7 +293,7 @@ static bool test_delimiter(parlio_rx_delimiter_handle_t deli, bool free_running_ static uint32_t task_flags = 0; xTaskCreate(sender_task_thread, "sender task", 4096, &task_flags, 5, &sender_task); // Waiting for the data ready on line - while ((task_flags & TEST_TASK_DATA_READY_BIT)) { + while (!(task_flags & TEST_TASK_DATA_READY_BIT)) { vTaskDelay(1); } diff --git a/components/esp_lcd/spi/esp_lcd_panel_io_spi.c b/components/esp_lcd/spi/esp_lcd_panel_io_spi.c index 768f0fe7b0cd..858ec3d759ca 100644 --- a/components/esp_lcd/spi/esp_lcd_panel_io_spi.c +++ b/components/esp_lcd/spi/esp_lcd_panel_io_spi.c @@ -408,6 +408,9 @@ IRAM_ATTR static void lcd_spi_pre_trans_cb(spi_transaction_t *trans) if (spi_panel_io->dc_gpio_num >= 0) { // set D/C line level if necessary // use ll function to speed up gpio_ll_set_level(&GPIO, spi_panel_io->dc_gpio_num, lcd_trans->flags.dc_gpio_level); + + // ensure the D/C output is enabled + gpio_ll_output_enable(&GPIO, spi_panel_io->dc_gpio_num); } } @@ -415,6 +418,12 @@ static void lcd_spi_post_trans_color_cb(spi_transaction_t *trans) { esp_lcd_panel_io_spi_t *spi_panel_io = trans->user; lcd_spi_trans_descriptor_t *lcd_trans = __containerof(trans, lcd_spi_trans_descriptor_t, base); + + // disable the D/C output as we no longer need it + if (spi_panel_io->dc_gpio_num >= 0) { + gpio_ll_output_disable(&GPIO, spi_panel_io->dc_gpio_num); + } + if (lcd_trans->flags.en_trans_done_cb) { if (spi_panel_io->on_color_trans_done) { spi_panel_io->on_color_trans_done(&spi_panel_io->base, NULL, spi_panel_io->user_ctx); diff --git a/components/esp_phy/lib b/components/esp_phy/lib index 4c2a23c8d2f6..fbc304747bc5 160000 --- a/components/esp_phy/lib +++ b/components/esp_phy/lib @@ -1 +1 @@ -Subproject commit 4c2a23c8d2f6ceaf462feeae31636251870713aa +Subproject commit fbc304747bc55b40ef7225130fcf87f43b981482 diff --git a/components/esp_rom/esp32/ld/esp32.rom.ld b/components/esp_rom/esp32/ld/esp32.rom.ld index 8fd3ab18c10a..6cca533158f7 100644 --- a/components/esp_rom/esp32/ld/esp32.rom.ld +++ b/components/esp_rom/esp32/ld/esp32.rom.ld @@ -1633,6 +1633,9 @@ PROVIDE ( ld_pscan_em_init = 0x4003e5e8 ); PROVIDE ( ld_acl_rsw_start = 0x40032e90 ); PROVIDE ( ld_acl_sniff_enter = 0x40031244 ); PROVIDE ( ld_acl_sniff_trans_sched = 0x40033734 ); +PROVIDE ( ld_acl_afh_apply = 0x40030e94 ); +PROVIDE ( ld_acl_afh_switch_on_cbk = 0x40030fa8 ); +PROVIDE ( ld_acl_afh_switch_off_cbk = 0x400310c4 ); PROVIDE ( lc_pwr_decr_ind_handler = 0x4002859c ); PROVIDE ( lc_pwr_incr_ind_handler = 0x400284a8 ); PROVIDE ( lc_pwr_max_ind_handler = 0x40028690 ); 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 02c7bb9e4873..f39bad25bda8 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ble-eco4.ld @@ -811,7 +811,7 @@ r_ble_lll_scan_sched_next_aux = 0x40001700; r_ble_lll_scan_sched_remove = 0x40001704; //r_ble_lll_scan_start = 0x40001708; //r_ble_lll_scan_start_rx = 0x4000170c; -r_ble_lll_scan_stop = 0x40001710; +//r_ble_lll_scan_stop = 0x40001710; r_ble_lll_scan_targeta_is_matched = 0x40001714; r_ble_lll_scan_timer_cb = 0x40001718; r_ble_lll_sched_adv_new = 0x4000171c; diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index 7c265458e705..59a0f93aad18 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -219,10 +219,13 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* For reason that only reset CPU, do not disable the clocks * that have been enabled before reset. */ + uint32_t hwcrypto_mask_in_perip1 = (SYSTEM_CRYPTO_HMAC_CLK_EN | SYSTEM_CRYPTO_DS_CLK_EN | SYSTEM_CRYPTO_RSA_CLK_EN | SYSTEM_CRYPTO_SHA_CLK_EN | SYSTEM_CRYPTO_AES_CLK_EN); + if (rst_reason == RESET_REASON_CPU0_MWDT0 || rst_reason == RESET_REASON_CPU0_SW || rst_reason == RESET_REASON_CPU0_RTC_WDT || rst_reason == RESET_REASON_CPU0_MWDT1) { common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG); - hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG); + common_perip_clk1 = (~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG)) & (~hwcrypto_mask_in_perip1); + hwcrypto_perip_clk = (~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG)) & hwcrypto_mask_in_perip1; wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG); } else { common_perip_clk = SYSTEM_WDG_CLK_EN | @@ -260,7 +263,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) * declare __DECLARE_RCC_ATOMIC_ENV here. */ int __DECLARE_RCC_ATOMIC_ENV __attribute__((unused)); // Disable USB-Serial-JTAG clock and it's pad if not used - usb_serial_jtag_ll_phy_enable_pad(false); + usb_serial_jtag_ll_phy_enable_pad(false); // should not reset USJ registers in the code below, otherwises, usb pad will be enabled again usb_serial_jtag_ll_enable_bus_clock(false); #endif } @@ -284,7 +287,8 @@ __attribute__((weak)) void esp_perip_clk_init(void) SYSTEM_I2S1_CLK_EN | SYSTEM_SPI2_DMA_CLK_EN | SYSTEM_SPI3_DMA_CLK_EN; - common_perip_clk1 = 0; + + common_perip_clk &= ~SYSTEM_USB_DEVICE_CLK_EN; // ignore USB-Serial-JTAG module, which has already been handled above (for non-CPU-reset cases) /* Change I2S clock to audio PLL first. Because if I2S uses 160MHz clock, * the current is not reduced when disable I2S clock. diff --git a/components/esp_system/port/soc/esp32s3/clk.c b/components/esp_system/port/soc/esp32s3/clk.c index 7e735c7c76be..9efad0687c21 100644 --- a/components/esp_system/port/soc/esp32s3/clk.c +++ b/components/esp_system/port/soc/esp32s3/clk.c @@ -26,6 +26,7 @@ #include "esp_private/esp_clk.h" #include "bootloader_clock.h" #include "soc/syscon_reg.h" +#include "hal/gpio_ll.h" static const char *TAG = "clk"; @@ -229,6 +230,8 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* For reason that only reset CPU, do not disable the clocks * that have been enabled before reset. */ + uint32_t hwcrypto_mask_in_perip1 = (SYSTEM_CRYPTO_HMAC_CLK_EN | SYSTEM_CRYPTO_DS_CLK_EN | SYSTEM_CRYPTO_RSA_CLK_EN | SYSTEM_CRYPTO_SHA_CLK_EN | SYSTEM_CRYPTO_AES_CLK_EN); + if ((rst_reas[0] == RESET_REASON_CPU0_MWDT0 || rst_reas[0] == RESET_REASON_CPU0_SW || rst_reas[0] == RESET_REASON_CPU0_RTC_WDT || rst_reas[0] == RESET_REASON_CPU0_MWDT1) #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE @@ -237,82 +240,91 @@ __attribute__((weak)) void esp_perip_clk_init(void) #endif ) { common_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN0_REG); - hwcrypto_perip_clk = ~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG); + common_perip_clk1 = (~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG)) & (~hwcrypto_mask_in_perip1); + hwcrypto_perip_clk = (~READ_PERI_REG(SYSTEM_PERIP_CLK_EN1_REG)) & hwcrypto_mask_in_perip1; wifi_bt_sdio_clk = ~READ_PERI_REG(SYSTEM_WIFI_CLK_EN_REG); } else { - common_perip_clk = SYSTEM_WDG_CLK_EN | - SYSTEM_I2S0_CLK_EN | + common_perip_clk = + SYSTEM_WDG_CLK_EN | + SYSTEM_I2S0_CLK_EN | #if CONFIG_ESP_CONSOLE_UART_NUM != 0 - SYSTEM_UART_CLK_EN | + SYSTEM_UART_CLK_EN | #endif #if CONFIG_ESP_CONSOLE_UART_NUM != 1 - SYSTEM_UART1_CLK_EN | + SYSTEM_UART1_CLK_EN | #endif + SYSTEM_USB_CLK_EN | + SYSTEM_SPI2_CLK_EN | + SYSTEM_I2C_EXT0_CLK_EN | + SYSTEM_UHCI0_CLK_EN | + SYSTEM_RMT_CLK_EN | + SYSTEM_PCNT_CLK_EN | + SYSTEM_LEDC_CLK_EN | + SYSTEM_TIMERGROUP1_CLK_EN | + SYSTEM_SPI3_CLK_EN | + SYSTEM_SPI4_CLK_EN | + SYSTEM_PWM0_CLK_EN | + SYSTEM_TWAI_CLK_EN | + SYSTEM_PWM1_CLK_EN | + SYSTEM_I2S1_CLK_EN | + SYSTEM_SPI2_DMA_CLK_EN | + SYSTEM_SPI3_DMA_CLK_EN | + SYSTEM_PWM2_CLK_EN | + SYSTEM_PWM3_CLK_EN; + common_perip_clk1 = #if CONFIG_ESP_CONSOLE_UART_NUM != 2 - SYSTEM_UART2_CLK_EN | + SYSTEM_UART2_CLK_EN | #endif - SYSTEM_USB_CLK_EN | - SYSTEM_SPI2_CLK_EN | - SYSTEM_I2C_EXT0_CLK_EN | - SYSTEM_UHCI0_CLK_EN | - SYSTEM_RMT_CLK_EN | - SYSTEM_PCNT_CLK_EN | - SYSTEM_LEDC_CLK_EN | - SYSTEM_TIMERGROUP1_CLK_EN | - SYSTEM_SPI3_CLK_EN | - SYSTEM_SPI4_CLK_EN | - SYSTEM_PWM0_CLK_EN | - SYSTEM_TWAI_CLK_EN | - SYSTEM_PWM1_CLK_EN | - SYSTEM_I2S1_CLK_EN | - SYSTEM_SPI2_DMA_CLK_EN | - SYSTEM_SPI3_DMA_CLK_EN | - SYSTEM_PWM2_CLK_EN | - SYSTEM_PWM3_CLK_EN; - common_perip_clk1 = 0; - hwcrypto_perip_clk = SYSTEM_CRYPTO_AES_CLK_EN | - SYSTEM_CRYPTO_SHA_CLK_EN | - SYSTEM_CRYPTO_RSA_CLK_EN; - wifi_bt_sdio_clk = SYSTEM_WIFI_CLK_WIFI_EN | - SYSTEM_WIFI_CLK_BT_EN_M | - SYSTEM_WIFI_CLK_I2C_CLK_EN | - SYSTEM_WIFI_CLK_UNUSED_BIT12 | - SYSTEM_WIFI_CLK_SDIO_HOST_EN; + 0; + hwcrypto_perip_clk = + SYSTEM_CRYPTO_AES_CLK_EN | + SYSTEM_CRYPTO_SHA_CLK_EN | + SYSTEM_CRYPTO_RSA_CLK_EN; + wifi_bt_sdio_clk = + SYSTEM_WIFI_CLK_WIFI_EN | + SYSTEM_WIFI_CLK_BT_EN_M | + SYSTEM_WIFI_CLK_I2C_CLK_EN | + SYSTEM_WIFI_CLK_UNUSED_BIT12 | + SYSTEM_WIFI_CLK_SDIO_HOST_EN; #if !CONFIG_USJ_ENABLE_USB_SERIAL_JTAG && !CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED /* This function only called on startup thus is thread safe. To avoid build errors/warnings * declare __DECLARE_RCC_ATOMIC_ENV here. */ int __DECLARE_RCC_ATOMIC_ENV __attribute__((unused)); // Disable USB-Serial-JTAG clock and it's pad if not used - usb_serial_jtag_ll_phy_enable_pad(false); + usb_serial_jtag_ll_phy_enable_pad(false); // should not reset USJ registers in the code below, otherwises, usb pad will be enabled again usb_serial_jtag_ll_enable_bus_clock(false); #endif } //Reset the communication peripherals like I2C, SPI, UART, I2S and bring them to known state. - common_perip_clk |= SYSTEM_I2S0_CLK_EN | + common_perip_clk |= + SYSTEM_I2S0_CLK_EN | #if CONFIG_ESP_CONSOLE_UART_NUM != 0 - SYSTEM_UART_CLK_EN | + SYSTEM_UART_CLK_EN | #endif #if CONFIG_ESP_CONSOLE_UART_NUM != 1 - SYSTEM_UART1_CLK_EN | + SYSTEM_UART1_CLK_EN | #endif + SYSTEM_USB_CLK_EN | + SYSTEM_SPI2_CLK_EN | + SYSTEM_I2C_EXT0_CLK_EN | + SYSTEM_UHCI0_CLK_EN | + SYSTEM_RMT_CLK_EN | + SYSTEM_UHCI1_CLK_EN | + SYSTEM_SPI3_CLK_EN | + SYSTEM_SPI4_CLK_EN | + SYSTEM_I2C_EXT1_CLK_EN | + SYSTEM_I2S1_CLK_EN | + SYSTEM_SPI2_DMA_CLK_EN | + SYSTEM_SPI3_DMA_CLK_EN; + common_perip_clk1 |= #if CONFIG_ESP_CONSOLE_UART_NUM != 2 - SYSTEM_UART2_CLK_EN | + SYSTEM_UART2_CLK_EN | #endif - SYSTEM_USB_CLK_EN | - SYSTEM_SPI2_CLK_EN | - SYSTEM_I2C_EXT0_CLK_EN | - SYSTEM_UHCI0_CLK_EN | - SYSTEM_RMT_CLK_EN | - SYSTEM_UHCI1_CLK_EN | - SYSTEM_SPI3_CLK_EN | - SYSTEM_SPI4_CLK_EN | - SYSTEM_I2C_EXT1_CLK_EN | - SYSTEM_I2S1_CLK_EN | - SYSTEM_SPI2_DMA_CLK_EN | - SYSTEM_SPI3_DMA_CLK_EN; - common_perip_clk1 = 0; + 0; + + common_perip_clk1 &= ~SYSTEM_USB_DEVICE_CLK_EN; // ignore USB-Serial-JTAG module, which has already been handled above (for non-CPU-reset cases) /* Disable some peripheral clocks. */ CLEAR_PERI_REG_MASK(SYSTEM_PERIP_CLK_EN0_REG, common_perip_clk); diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c index 866b4e4bba4a..ea6413883e39 100644 --- a/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c @@ -140,6 +140,9 @@ TEST_CASE("Task on specific core works", "[freertos][psram]") TEST_ASSERT_EQUAL((size_t) corenum, corenum_info.recorded_core_num); vTaskDelete(task_handle); + + // Add a short delay to allow the idle task to free any remaining task memory + vTaskDelay(10); } } #endif // !CONFIG_FREERTOS_UNICORE diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c b/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c index 97acb852571a..5bc1ae55b70c 100644 --- a/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_vTaskSuspendAll_xTaskResumeAll.c @@ -387,6 +387,7 @@ TEST_CASE("Test vTaskSuspendAll allows scheduling on other cores", "[freertos]") // Cleanup tasks vTaskDelete(a1_task_hdl); vTaskDelete(b1_task_hdl); + vTaskDelay(10); } vSemaphoreDelete(test_unblk_done_sem); diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_yielding.c b/components/freertos/test_apps/freertos/kernel/tasks/test_yielding.c index 6da218976f75..9d5d7b2c5e6a 100644 --- a/components/freertos/test_apps/freertos/kernel/tasks/test_yielding.c +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_yielding.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,6 +34,9 @@ static volatile uint32_t count; // Lock variable to create a blocked task scenario static volatile SemaphoreHandle_t task_mutex; +// Semaphore to synchronize yield test tasks +static SemaphoreHandle_t yield_sync_sem; + // This helper macro is used to store the task id atomically #define STORE_TASK_ID(task_id) ({ \ portENTER_CRITICAL(&idx_lock); \ @@ -56,10 +59,11 @@ static void yield_task1(void *arg) /* Store task_id in the sequence array */ STORE_TASK_ID(task_id); - /* Notify the yield_task2 to run */ - task_sequence_ready = true; + /* Give semaphore to unblock yield_task2, making it READY (not just setting a flag). + * This ensures task2 is in the ready queue when we yield. */ + xSemaphoreGive(yield_sync_sem); - /* Yield */ + /* Yield - now task2 is guaranteed to be READY and should run next */ taskYIELD(); /* Increment task count to notify unity task */ @@ -73,10 +77,9 @@ static void yield_task2(void *arg) { uint32_t task_id = (uint32_t)arg; - /* Wait for the other task to run for the test to begin */ - while (!task_sequence_ready) { - vTaskDelay(10); - }; + /* Block on semaphore - this ensures task1 runs first and we don't poll. + * When task1 gives the semaphore, we transition directly to READY state. */ + xSemaphoreTake(yield_sync_sem, portMAX_DELAY); /* Store task_id in the sequence array */ STORE_TASK_ID(task_id); @@ -108,9 +111,16 @@ TEST_CASE("Task yield must run the next ready task of the same priority", "[free /* Reset task sequence flag */ task_sequence_ready = false; - /* Create test tasks */ - xTaskCreatePinnedToCore(yield_task1, "yield_task1", 2048, (void *)1, UNITY_FREERTOS_PRIORITY - 1, NULL, UNITY_FREERTOS_CPU); + /* Create semaphore for synchronization - start empty so task2 blocks */ + yield_sync_sem = xSemaphoreCreateBinary(); + TEST_ASSERT_NOT_NULL(yield_sync_sem); + + /* Create test tasks - order matters! + * Task2 is created first and will immediately block on the semaphore. + * Task1 is created second and will run first since task2 is blocked. */ xTaskCreatePinnedToCore(yield_task2, "yield_task2", 2048, (void *)2, UNITY_FREERTOS_PRIORITY - 1, NULL, UNITY_FREERTOS_CPU); + vTaskDelay(1); /* Ensure task2 has blocked on semaphore before creating task1 */ + xTaskCreatePinnedToCore(yield_task1, "yield_task1", 2048, (void *)1, UNITY_FREERTOS_PRIORITY - 1, NULL, UNITY_FREERTOS_CPU); /* Wait for the tasks to finish up */ while (count != 2) { @@ -122,6 +132,9 @@ TEST_CASE("Task yield must run the next ready task of the same priority", "[free /* Verify that the yield is successful and the next ready task is run */ TEST_ASSERT_EQUAL(1, task_yield_sequence[idx++]); TEST_ASSERT_EQUAL(2, task_yield_sequence[idx++]); + + /* Clean up semaphore */ + vSemaphoreDelete(yield_sync_sem); } /* diff --git a/components/freertos/test_apps/freertos/misc/test_tickless_idle.c b/components/freertos/test_apps/freertos/misc/test_tickless_idle.c index 7ed64ddf354e..aa73b5346c5d 100644 --- a/components/freertos/test_apps/freertos/misc/test_tickless_idle.c +++ b/components/freertos/test_apps/freertos/misc/test_tickless_idle.c @@ -10,6 +10,7 @@ #include "freertos/semphr.h" #include "esp_pm.h" #include "esp_private/esp_clk.h" +#include "esp_clk_tree.h" #include "sdkconfig.h" @@ -66,9 +67,11 @@ static void consumer_task(void *arg) TEST_CASE("Test semaphore timeout during tickless idle", "[freertos]") { // Configure tickless idle + uint32_t xtal_hz = 0; + esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_XTAL, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &xtal_hz); esp_pm_config_t pm_config = { - .max_freq_mhz = esp_clk_cpu_freq() / MHZ, - .min_freq_mhz = esp_clk_cpu_freq() / MHZ, + .max_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, + .min_freq_mhz = xtal_hz / MHZ, .light_sleep_enable = true, }; TEST_ESP_OK(esp_pm_configure(&pm_config)); diff --git a/components/idf_test/include/esp32/idf_performance_target.h b/components/idf_test/include/esp32/idf_performance_target.h index c222734ef4b3..c7933cf59f71 100644 --- a/components/idf_test/include/esp32/idf_performance_target.h +++ b/components/idf_test/include/esp32/idf_performance_target.h @@ -22,11 +22,11 @@ #define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 4500 #define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 19000 -#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 450000 +#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 750000 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP 33000 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP 950000 #define IDF_PERFORMANCE_MAX_RSA_4096KEY_PUBLIC_OP 90000 -#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP 1900000 +#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP 3000000 // floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround) #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV 70 diff --git a/components/idf_test/include/esp32s2/idf_performance_target.h b/components/idf_test/include/esp32s2/idf_performance_target.h index 07baf2ca51d2..0d2b6f0dd36f 100644 --- a/components/idf_test/include/esp32s2/idf_performance_target.h +++ b/components/idf_test/include/esp32s2/idf_performance_target.h @@ -17,11 +17,11 @@ #define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900 #define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 13500 -#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 420000 +#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 650000 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP 36000 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP 960000 #define IDF_PERFORMANCE_MAX_RSA_4096KEY_PUBLIC_OP 62000 -#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP 1850000 +#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP 2850000 #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER 3 #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2 3 diff --git a/components/idf_test/include/esp32s3/idf_performance_target.h b/components/idf_test/include/esp32s3/idf_performance_target.h index 9f485b382c27..3b2bbe3b42f8 100644 --- a/components/idf_test/include/esp32s3/idf_performance_target.h +++ b/components/idf_test/include/esp32s3/idf_performance_target.h @@ -15,11 +15,11 @@ #define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900 #define IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP 18000 -#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 490000 +#define IDF_PERFORMANCE_MAX_RSA_2048KEY_PRIVATE_OP 700000 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP 45000 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP 1300000 #define IDF_PERFORMANCE_MAX_RSA_4096KEY_PUBLIC_OP 80000 -#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP 2500000 +#define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP 3500000 // floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround) #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV 70 diff --git a/components/ieee802154/driver/esp_ieee802154_debug.c b/components/ieee802154/driver/esp_ieee802154_debug.c index 21c315c4b9bf..8aa30f26cc3d 100644 --- a/components/ieee802154/driver/esp_ieee802154_debug.c +++ b/components/ieee802154/driver/esp_ieee802154_debug.c @@ -210,8 +210,8 @@ void ieee802154_record_print(void) #if CONFIG_IEEE802154_RECORD_STATE ESP_EARLY_LOGW(IEEE802154_TAG, "Print the record state, current state index: %d", g_ieee802154_probe.state_index); for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_STATE_SIZE; i++) { - ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: line:%5s, state:%10s, timestamp: %lld", - i, g_ieee802154_probe.state[i].line_str, + ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: line:%5lu, state:%10s, timestamp: %lld", + i, g_ieee802154_probe.state[i].line, ieee802154_state_string[g_ieee802154_probe.state[i].state], g_ieee802154_probe.state[i].timestamp); } @@ -221,8 +221,8 @@ void ieee802154_record_print(void) #if CONFIG_IEEE802154_RECORD_CMD ESP_EARLY_LOGW(IEEE802154_TAG, "Print the record cmd, current cmd index: %d", g_ieee802154_probe.cmd_index); for (uint8_t i = 0; i < IEEE802154_ASSERT_RECORD_CMD_SIZE; i++) { - ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: line:%5s, cmd:%10s, timestamp: %lld", - i, g_ieee802154_probe.cmd[i].line_str, + ESP_EARLY_LOGW(IEEE802154_TAG, "index %2d: line:%5lu, cmd:%10s, timestamp: %lld", + i, g_ieee802154_probe.cmd[i].line, ieee802154_get_cmd_string(g_ieee802154_probe.cmd[i].cmd), g_ieee802154_probe.cmd[i].timestamp); } diff --git a/components/ieee802154/private_include/esp_ieee802154_util.h b/components/ieee802154/private_include/esp_ieee802154_util.h index b323367b9ceb..5efdac1c26e2 100644 --- a/components/ieee802154/private_include/esp_ieee802154_util.h +++ b/components/ieee802154/private_include/esp_ieee802154_util.h @@ -78,7 +78,7 @@ typedef struct { #if CONFIG_IEEE802154_RECORD_STATE #define IEEE802154_ASSERT_RECORD_STATE_SIZE CONFIG_IEEE802154_RECORD_STATE_SIZE #define ieee802154_set_state(a) do { s_ieee802154_state = a; \ - sprintf(g_ieee802154_probe.state[g_ieee802154_probe.state_index].line_str, "%d", __LINE__); \ + g_ieee802154_probe.state[g_ieee802154_probe.state_index].line = __LINE__; \ g_ieee802154_probe.state[g_ieee802154_probe.state_index].timestamp = esp_timer_get_time(); \ g_ieee802154_probe.state[g_ieee802154_probe.state_index++].state = a; \ g_ieee802154_probe.state_index = \ @@ -89,7 +89,7 @@ typedef struct { * @brief The table of recording IEEE802154 state command. */ typedef struct { - char line_str[5]; /*!< record which line in esp_ieee802154_dev.c changes the state */ + uint32_t line; /*!< record which line in esp_ieee802154_dev.c changes the state */ ieee802154_state_t state; /*!< record current radio state */ uint64_t timestamp; /*!< record timestamp */ } ieee802154_state_info_t; @@ -100,7 +100,7 @@ typedef struct { #if CONFIG_IEEE802154_RECORD_CMD #define IEEE802154_ASSERT_RECORD_CMD_SIZE CONFIG_IEEE802154_RECORD_CMD_SIZE #define ieee802154_set_cmd(a) do { ieee802154_ll_set_cmd(a); \ - sprintf(g_ieee802154_probe.cmd[g_ieee802154_probe.cmd_index].line_str, "%d", __LINE__); \ + g_ieee802154_probe.cmd[g_ieee802154_probe.cmd_index].line = __LINE__; \ g_ieee802154_probe.cmd[g_ieee802154_probe.cmd_index].timestamp = esp_timer_get_time(); \ g_ieee802154_probe.cmd[g_ieee802154_probe.cmd_index++].cmd = a; \ g_ieee802154_probe.cmd_index = \ @@ -111,7 +111,7 @@ typedef struct { * @brief The table of recording IEEE802154 radio command. */ typedef struct { - char line_str[5]; /*!< record which line in esp_ieee802154_dev.c set the command */ + uint32_t line; /*!< record which line in esp_ieee802154_dev.c set the command */ ieee802154_ll_cmd_t cmd; /*!< record current command */ uint64_t timestamp; /*!< record timestamp */ } ieee802154_cmd_info_t; diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index b5d87eaa6748..ffb280bb63c7 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit b5d87eaa6748b7a6fa70593178c08b4480e9b71e +Subproject commit ffb280bb63c78bfec1e1ab55040671768c85c923 diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index b113cfd1f4c0..9b814a47fef0 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -430,7 +430,7 @@ menu "OpenThread" config OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT bool 'Allocate message pool buffer from PSRAM' - default n + default y help If enabled, the message pool is managed by platform defined logic. endmenu @@ -464,7 +464,8 @@ menu "OpenThread" config OPENTHREAD_NUM_MESSAGE_BUFFERS int "The number of openthread message buffers" - default 65 + default 65 if !OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT + default 1024 if OPENTHREAD_PLATFORM_MSGPOOL_MANAGEMENT config OPENTHREAD_XTAL_ACCURACY int "The accuracy of the XTAL" diff --git a/components/openthread/include/esp_radio_spinel.h b/components/openthread/include/esp_radio_spinel.h index 504eda1f4f82..18638b3275cb 100644 --- a/components/openthread/include/esp_radio_spinel.h +++ b/components/openthread/include/esp_radio_spinel.h @@ -18,10 +18,6 @@ extern "C" { #define ESP_SPINEL_LOG_TAG "ESP_RADIO_SPINEL" -#define SPINEL_PROP_VENDOR_ESP_SET_COORDINATOR (SPINEL_PROP_VENDOR_ESP__BEGIN + 1) /* Vendor command for coordinator.*/ - -#define SPINEL_PROP_VENDOR_ESP_SET_PENDINGMODE (SPINEL_PROP_VENDOR_ESP__BEGIN + 2) /* Vendor command for pending mode.*/ - typedef enum { ESP_RADIO_SPINEL_ZIGBEE = 0x0, /* The index of Zigbee.*/ ESP_RADIO_SPINEL_OPENTHREAD = 0x1, /* The index of OpenThread.*/ diff --git a/components/openthread/lib b/components/openthread/lib index b49c7a847142..3d2077e8dc36 160000 --- a/components/openthread/lib +++ b/components/openthread/lib @@ -1 +1 @@ -Subproject commit b49c7a8471427d5ec6ac79c9a5dc8489dac3b32e +Subproject commit 3d2077e8dc3627c772450403bd2da6a3b52bf1f6 diff --git a/components/openthread/private_include/esp_openthread_ncp.h b/components/openthread/private_include/esp_openthread_ncp.h index 65053bb56a8a..45b585cf33b8 100644 --- a/components/openthread/private_include/esp_openthread_ncp.h +++ b/components/openthread/private_include/esp_openthread_ncp.h @@ -4,19 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include #include -#if CONFIG_OPENTHREAD_NCP_VENDOR_HOOK - -#define SPINEL_PROP_VENDOR_ESP_SET_COORDINATOR (SPINEL_PROP_VENDOR_ESP__BEGIN + 1) - -#define SPINEL_PROP_VENDOR_ESP_SET_PENDINGMODE (SPINEL_PROP_VENDOR_ESP__BEGIN + 2) - -#define SPINEL_PROP_VENDOR_ESP_COEX_EVENT (SPINEL_PROP_VENDOR_ESP__BEGIN + 3) - -#endif - #ifdef __cplusplus extern "C" { #endif diff --git a/components/openthread/private_include/esp_spinel_ncp_vendor_macro.h b/components/openthread/private_include/esp_spinel_ncp_vendor_macro.h new file mode 100644 index 000000000000..3bd9f4fb8572 --- /dev/null +++ b/components/openthread/private_include/esp_spinel_ncp_vendor_macro.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "spinel.h" + +#define SPINEL_PROP_VENDOR_ESP_SET_COORDINATOR (SPINEL_PROP_VENDOR_ESP__BEGIN + 1) /* Vendor command for coordinator.*/ + +#define SPINEL_PROP_VENDOR_ESP_SET_PENDINGMODE (SPINEL_PROP_VENDOR_ESP__BEGIN + 2) /* Vendor command for pending mode.*/ + +#define SPINEL_PROP_VENDOR_ESP_COEX_EVENT (SPINEL_PROP_VENDOR_ESP__BEGIN + 3) diff --git a/components/openthread/src/ncp/esp_openthread_ncp.cpp b/components/openthread/src/ncp/esp_openthread_ncp.cpp index 94c31113dece..b6e70eca1fc3 100644 --- a/components/openthread/src/ncp/esp_openthread_ncp.cpp +++ b/components/openthread/src/ncp/esp_openthread_ncp.cpp @@ -7,6 +7,7 @@ #include "sdkconfig.h" #include "esp_ieee802154.h" #include "esp_openthread_ncp.h" +#include "esp_spinel_ncp_vendor_macro.h" #include "ncp_base.hpp" #if (CONFIG_ESP_COEX_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE) diff --git a/components/openthread/src/spinel/esp_radio_spinel.cpp b/components/openthread/src/spinel/esp_radio_spinel.cpp index bbcc8d2bea18..8d561d27043b 100644 --- a/components/openthread/src/spinel/esp_radio_spinel.cpp +++ b/components/openthread/src/spinel/esp_radio_spinel.cpp @@ -12,6 +12,7 @@ #include "esp_radio_spinel.h" #include "esp_radio_spinel_platform.h" #include "esp_radio_spinel_adapter.hpp" +#include "esp_spinel_ncp_vendor_macro.h" #include "esp_radio_spinel_uart_interface.hpp" #include "spinel_driver.hpp" #include "openthread/link.h" diff --git a/components/ulp/test_apps/ulp_fsm/main/test_ulp.c b/components/ulp/test_apps/ulp_fsm/main/test_ulp.c index ee4ae12f88bd..faa44964f6d0 100644 --- a/components/ulp/test_apps/ulp_fsm/main/test_ulp.c +++ b/components/ulp/test_apps/ulp_fsm/main/test_ulp.c @@ -362,7 +362,7 @@ TEST_CASE("ULP FSM I_WR_REG instruction test", "[ulp]") TEST_ESP_OK(ulp_run(0)); /* Wait for the ULP co-processor to finish up */ - vTaskDelay(10 / portTICK_PERIOD_MS); + vTaskDelay(50 / portTICK_PERIOD_MS); /* Verify the test results */ uint32_t clear = REG_READ(RTC_CNTL_STORE0_REG); diff --git a/docs/en/api-reference/peripherals/i2s.rst b/docs/en/api-reference/peripherals/i2s.rst index 5a60b0116c7f..e3afe2dcd9ad 100644 --- a/docs/en/api-reference/peripherals/i2s.rst +++ b/docs/en/api-reference/peripherals/i2s.rst @@ -815,7 +815,9 @@ Full-duplex mode registers TX and RX channel in an I2S port at the same time, an Note that one handle can only stand for one channel. Therefore, it is still necessary to configure the slot and clock for both TX and RX channels one by one. -Here is an example of how to allocate a pair of full-duplex channels: +There are two methods to allocate a pair of full-duplex channels: + +1. Allocate both TX and RX handles in a single call of :cpp:func:`i2s_new_channel`. .. code-block:: c @@ -855,6 +857,48 @@ Here is an example of how to allocate a pair of full-duplex channels: ... +2. Allocate TX and RX handles separately, and initialize them with the same configuration. + +.. code-block:: c + + #include "driver/i2s_std.h" + #include "driver/gpio.h" + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + /* Allocate a pair of I2S channels on a same port */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + /* Allocate for TX and RX channel separately, they are not full-duplex yet */ + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + + /* Set the configurations for BOTH TWO channels, they will constitute in full-duplex mode automatically */ + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(32000), + .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = GPIO_NUM_19, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle)); + // ... + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle)); + + ... + + .. only:: SOC_I2S_HW_VERSION_1 Simplex Mode @@ -871,7 +915,7 @@ Here is an example of how to allocate a pair of full-duplex channels: i2s_chan_handle_t rx_handle; i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); - i2s_new_channel(&chan_cfg, &tx_handle, NULL); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); i2s_std_config_t std_tx_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000), .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), @@ -889,12 +933,12 @@ Here is an example of how to allocate a pair of full-duplex channels: }, }; /* Initialize the channel */ - i2s_channel_init_std_mode(tx_handle, &std_tx_cfg); - i2s_channel_enable(tx_handle); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_tx_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle)); /* RX channel will be registered on another I2S, if no other available I2S unit found * it will return ESP_ERR_NOT_FOUND */ - i2s_new_channel(&chan_cfg, NULL, &rx_handle); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); i2s_std_config_t std_rx_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000), .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), @@ -911,8 +955,8 @@ Here is an example of how to allocate a pair of full-duplex channels: }, }, }; - i2s_channel_init_std_mode(rx_handle, &std_rx_cfg); - i2s_channel_enable(rx_handle); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_rx_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle)); .. only:: SOC_I2S_HW_VERSION_2 @@ -931,7 +975,7 @@ Here is an example of how to allocate a pair of full-duplex channels: i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - i2s_new_channel(&chan_cfg, &tx_handle, NULL); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); i2s_std_config_t std_tx_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000), .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), @@ -949,12 +993,12 @@ Here is an example of how to allocate a pair of full-duplex channels: }, }; /* Initialize the channel */ - i2s_channel_init_std_mode(tx_handle, &std_tx_cfg); - i2s_channel_enable(tx_handle); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_tx_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle)); /* RX channel will be registered on another I2S, if no other available I2S unit found * it will return ESP_ERR_NOT_FOUND */ - i2s_new_channel(&chan_cfg, NULL, &rx_handle); // Both RX and TX channel will be registered on I2S0, but they can work with different configurations. + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); // Both RX and TX channel will be registered on I2S0, but they can work with different configurations. i2s_std_config_t std_rx_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000), .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), @@ -971,8 +1015,8 @@ Here is an example of how to allocate a pair of full-duplex channels: }, }, }; - i2s_channel_init_std_mode(rx_handle, &std_rx_cfg); - i2s_channel_enable(rx_handle); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_rx_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle)); Application Notes diff --git a/docs/en/api-reference/protocols/mbedtls.rst b/docs/en/api-reference/protocols/mbedtls.rst index acacda2c1987..0bf916d918e4 100644 --- a/docs/en/api-reference/protocols/mbedtls.rst +++ b/docs/en/api-reference/protocols/mbedtls.rst @@ -118,5 +118,5 @@ Reducing Binary Size Under ``Component Config -> mbedTLS``, there are multiple Mbed TLS features which are enabled by default but can be disabled if not needed to save code size. More information can be about this can be found in :ref:`Minimizing Binary Size ` docs. -.. _`API Reference`: https://mbed-tls.readthedocs.io/projects/api/en/v3.6.4/ +.. _`API Reference`: https://mbed-tls.readthedocs.io/projects/api/en/v3.6.5/ .. _`Knowledge Base`: https://mbed-tls.readthedocs.io/en/latest/kb/ diff --git a/docs/zh_CN/api-reference/peripherals/i2s.rst b/docs/zh_CN/api-reference/peripherals/i2s.rst index 1c4103d0453e..6a0b8c6f8433 100644 --- a/docs/zh_CN/api-reference/peripherals/i2s.rst +++ b/docs/zh_CN/api-reference/peripherals/i2s.rst @@ -815,7 +815,9 @@ STD RX 模式 请注意,一个句柄只能代表一个通道,因此仍然需要对 TX 和 RX 通道逐个进行声道和时钟配置。 -以下示例展示了如何分配两个全双工通道: +驱动支持两种分配全双工通道的方法: + +1. 在调用 :cpp:func:`i2s_new_channel` 函数时,同时分配 TX 和 RX 通道两个通道。 .. code-block:: c @@ -855,6 +857,47 @@ STD RX 模式 ... +2. 调用两次 :cpp:func:`i2s_new_channel` 函数分别分配 TX 和 RX 通道,但使用相同配置初始化 TX 和 RX 通道。 + +.. code-block:: c + + #include "driver/i2s_std.h" + #include "driver/gpio.h" + + i2s_chan_handle_t tx_handle; + i2s_chan_handle_t rx_handle; + + /* 分配两个 I2S 通道 */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + /* 分别分配给 TX 和 RX 通道 */ + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); + + /* 为两个通道设置完全相同的配置,TX 和 RX 将自动组成全双工模式 */ + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(32000), + .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_4, + .ws = GPIO_NUM_5, + .dout = GPIO_NUM_18, + .din = GPIO_NUM_19, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle)); + // ... + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle)); + + ... + .. only:: SOC_I2S_HW_VERSION_1 单工模式 @@ -871,7 +914,7 @@ STD RX 模式 i2s_chan_handle_t rx_handle; i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); - i2s_new_channel(&chan_cfg, &tx_handle, NULL); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); i2s_std_config_t std_tx_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000), .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), @@ -889,12 +932,12 @@ STD RX 模式 }, }; /* 初始化通道 */ - i2s_channel_init_std_mode(tx_handle, &std_tx_cfg); - i2s_channel_enable(tx_handle); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_tx_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle)); /* 如果没有找到其他可用的 I2S 设备,RX 通道将被注册在另一个 I2S 上 * 并返回 ESP_ERR_NOT_FOUND */ - i2s_new_channel(&chan_cfg, NULL, &rx_handle); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); i2s_std_config_t std_rx_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000), .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), @@ -911,8 +954,8 @@ STD RX 模式 }, }, }; - i2s_channel_init_std_mode(rx_handle, &std_rx_cfg); - i2s_channel_enable(rx_handle); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_rx_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle)); .. only:: SOC_I2S_HW_VERSION_2 @@ -931,7 +974,7 @@ STD RX 模式 i2s_chan_handle_t tx_handle; i2s_chan_handle_t rx_handle; i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); - i2s_new_channel(&chan_cfg, &tx_handle, NULL); + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL)); i2s_std_config_t std_tx_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000), .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO), @@ -949,12 +992,12 @@ STD RX 模式 }, }; /* 初始化通道 */ - i2s_channel_init_std_mode(tx_handle, &std_tx_cfg); - i2s_channel_enable(tx_handle); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &std_tx_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle)); /* 如果没有找到其他可用的 I2S 设备,RX 通道将被注册在另一个 I2S 上 * 并返回 ESP_ERR_NOT_FOUND */ - i2s_new_channel(&chan_cfg, NULL, &rx_handle); // RX 和 TX 通道都将注册在 I2S0 上,但配置可以不同 + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_handle)); // RX 和 TX 通道都将注册在 I2S0 上,但配置可以不同 i2s_std_config_t std_rx_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000), .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), @@ -971,8 +1014,8 @@ STD RX 模式 }, }, }; - i2s_channel_init_std_mode(rx_handle, &std_rx_cfg); - i2s_channel_enable(rx_handle); + ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle, &std_rx_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle)); 应用注意事项 diff --git a/docs/zh_CN/api-reference/protocols/mbedtls.rst b/docs/zh_CN/api-reference/protocols/mbedtls.rst index 8bd28adfc6a6..4543e9afa1ba 100644 --- a/docs/zh_CN/api-reference/protocols/mbedtls.rst +++ b/docs/zh_CN/api-reference/protocols/mbedtls.rst @@ -118,5 +118,5 @@ ESP-IDF 中的示例使用 :doc:`/api-reference/protocols/esp_tls`,为访问 在 ``Component Config -> mbedTLS`` 中,有多个 Mbed TLS 功能默认为启用状态。如果不需要这些功能,可将其禁用以减小固件大小。要了解更多信息,请参考 :ref:`Minimizing Binary Size ` 文档。 -.. _`API Reference`: https://mbed-tls.readthedocs.io/projects/api/en/v3.6.4/ +.. _`API Reference`: https://mbed-tls.readthedocs.io/projects/api/en/v3.6.5/ .. _`Knowledge Base`: https://mbed-tls.readthedocs.io/en/latest/kb/ diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/src/gap.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/src/gap.c index 71e03ba7c2aa..8243ecf3341c 100644 --- a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/src/gap.c +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/src/gap.c @@ -51,7 +51,7 @@ static void start_advertising(void) { adv_fields.le_role = BLE_GAP_LE_ROLE_PERIPHERAL; adv_fields.le_role_is_present = 1; - /* Set advertiement fields */ + /* Set advertisement fields */ rc = ble_gap_adv_set_fields(&adv_fields); if (rc != 0) { ESP_LOGE(TAG, "failed to set advertising data, error code: %d", rc); @@ -74,7 +74,7 @@ static void start_advertising(void) { return; } - /* Set non-connetable and general discoverable mode to be a beacon */ + /* Set non-connectable and general discoverable mode to be a beacon */ adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/gap.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/gap.c index d2689f9230fa..d4d220d9fc17 100644 --- a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/gap.c +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/gap.c @@ -80,7 +80,7 @@ static void start_advertising(void) { adv_fields.le_role = BLE_GAP_LE_ROLE_PERIPHERAL; adv_fields.le_role_is_present = 1; - /* Set advertiement fields */ + /* Set advertisement fields */ rc = ble_gap_adv_set_fields(&adv_fields); if (rc != 0) { ESP_LOGE(TAG, "failed to set advertising data, error code: %d", rc); @@ -107,7 +107,7 @@ static void start_advertising(void) { return; } - /* Set non-connetable and general discoverable mode to be a beacon */ + /* Set undirected connectable and general discoverable mode */ adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gap.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gap.c index 8519028a5d0e..7c7b3dde2ade 100644 --- a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gap.c +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gap.c @@ -80,7 +80,7 @@ static void start_advertising(void) { adv_fields.le_role = BLE_GAP_LE_ROLE_PERIPHERAL; adv_fields.le_role_is_present = 1; - /* Set advertiement fields */ + /* Set advertisement fields */ rc = ble_gap_adv_set_fields(&adv_fields); if (rc != 0) { ESP_LOGE(TAG, "failed to set advertising data, error code: %d", rc); @@ -107,7 +107,7 @@ static void start_advertising(void) { return; } - /* Set non-connetable and general discoverable mode to be a beacon */ + /* Set undirected connectable and general discoverable mode */ adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gap.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gap.c index d4e7c249b68c..55c34487eb9d 100644 --- a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gap.c +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gap.c @@ -95,7 +95,7 @@ static void start_advertising(void) { adv_fields.le_role = BLE_GAP_LE_ROLE_PERIPHERAL; adv_fields.le_role_is_present = 1; - /* Set advertiement fields */ + /* Set advertisement fields */ rc = ble_gap_adv_set_fields(&adv_fields); if (rc != 0) { ESP_LOGE(TAG, "failed to set advertising data, error code: %d", rc); @@ -122,7 +122,7 @@ static void start_advertising(void) { return; } - /* Set non-connetable and general discoverable mode to be a beacon */ + /* Set undirected connectable and general discoverable mode */ adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; diff --git a/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py b/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py index 07e1e27f316b..a678f7e12c4d 100644 --- a/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py +++ b/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py @@ -150,8 +150,11 @@ def test_bt_l2cap(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: client = dut[1] server.expect_exact('ESP_BT_L2CAP_INIT_EVT: status:0', timeout=30) - server.expect_exact('ESP_BT_L2CAP_START_EVT: status:0', timeout=30) - server.expect_exact('ESP_SDP_CREATE_RECORD_COMP_EVT: status:0', timeout=30) + server.expect( + r'(?s)(ESP_BT_L2CAP_START_EVT: status:0.*ESP_SDP_CREATE_RECORD_COMP_EVT: status:0|' + r'ESP_SDP_CREATE_RECORD_COMP_EVT: status:0.*ESP_BT_L2CAP_START_EVT: status:0)', + timeout=30, + ) client.expect_exact('ESP_BT_L2CAP_INIT_EVT: status:0', timeout=30) client.expect_exact('ESP_SDP_SEARCH_COMP_EVT: status:0', timeout=30) client.expect_exact('ESP_BT_L2CAP_OPEN_EVT: status:0', timeout=30) diff --git a/examples/network/bridge/pytest_example_bridge.py b/examples/network/bridge/pytest_example_bridge.py index 09b94ce51361..073d4e9a7218 100644 --- a/examples/network/bridge/pytest_example_bridge.py +++ b/examples/network/bridge/pytest_example_bridge.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import base64 import io @@ -55,7 +55,7 @@ def exec_cmd(self, cmd: str) -> str: error = stderr.read().decode().strip() if error: out = '' - logging.error('ssh_endnode_exec error: {}'.format(error)) + logging.error(f'ssh_endnode_exec error: {error}') return out # type: ignore @@ -101,7 +101,7 @@ def exec_cmd(self, cmd: Union[str, List[str]]) -> str: error = stderr.read().decode().strip() if error != 'TSW Init OK!': - raise Exception('switch_5xp exec_cmd error: {}'.format(error)) + raise Exception(f'switch_5xp exec_cmd error: {error}') else: out = self.ssh_client.send_config_set(cmd, cmd_verify=False, exit_config_mode=False) return out # type: ignore @@ -158,7 +158,7 @@ def get_host_interface_name_in_same_net(ip_addr: str) -> str: def get_host_mac_by_interface(interface_name: str, addr_type: int = netifaces.AF_LINK) -> str: for _addr in netifaces.ifaddresses(interface_name)[addr_type]: - host_mac = _addr['addr'].replace('%{}'.format(interface_name), '') + host_mac = _addr['addr'].replace(f'%{interface_name}', '') assert isinstance(host_mac, str) return host_mac return '' @@ -166,7 +166,7 @@ def get_host_mac_by_interface(interface_name: str, addr_type: int = netifaces.AF def get_host_brcast_ip_by_interface(interface_name: str, ip_type: int = netifaces.AF_INET) -> str: for _addr in netifaces.ifaddresses(interface_name)[ip_type]: - host_ip = _addr['broadcast'].replace('%{}'.format(interface_name), '') + host_ip = _addr['broadcast'].replace(f'%{interface_name}', '') assert isinstance(host_ip, str) return host_ip return '' @@ -180,21 +180,31 @@ def run_iperf(proto: str, endnode: EndnodeSsh, server_ip: str, bandwidth_lim:int if ipaddress.ip_address(server_ip).is_multicast: # Configure Multicast Server - server_proc = subprocess.Popen(['iperf', '-u', '-s', '-i', '1', '-t', '%i' % interval, '-B', '%s%%%s' - % (server_ip, server_if)], text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + server_proc = subprocess.Popen( + ['iperf', '-u', '-s', '-i', '1', '-t', str(interval), '-B', f'{server_ip}%{server_if}'], + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) # Configure Multicast Client endnode_ip = get_endnode_ip_by_interface(endnode, client_if) if endnode_ip == '': raise RuntimeError('End node IP address not found') - client_res = endnode.exec_cmd('iperf -u -c %s -t %i -i 1 -b %iM --ttl 5 -B %s' % (server_ip, interval, bandwidth_lim, endnode_ip)) + client_res = endnode.exec_cmd( + f'iperf -u -c {server_ip} -t {interval} -i 1 -b {bandwidth_lim}M --ttl 5 -B {endnode_ip}' + ) if server_proc.wait(10) is None: # Process did not finish. server_proc.terminate() else: # Configure Server - server_proc = subprocess.Popen(['iperf', '%s' % proto, '-s', '-i', '1', '-t', '%i' % interval], text=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) + server_proc = subprocess.Popen( + ['iperf', proto, '-s', '-i', '1', '-t', str(interval)], + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) # Configure Client - client_res = endnode.exec_cmd('iperf %s -c %s -t %i -i 1 -b %iM' % (proto, server_ip, interval, bandwidth_lim)) + client_res = endnode.exec_cmd(f'iperf {proto} -c {server_ip} -t {interval} -i 1 -b {bandwidth_lim}M') if server_proc.wait(10) is None: # Process did not finish. server_proc.terminate() @@ -224,8 +234,8 @@ def send_brcast_msg_host_to_endnode(endnode: EndnodeSsh, host_brcast_ip: str, te try: sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) sock.sendto(test_msg.encode('utf-8'), (host_brcast_ip, 5100)) - except socket.error as e: - raise Exception('Host brcast send failed %s' % e) + except OSError as e: + raise Exception(f'Host brcast send failed {e}') nc_endnode_out = endnode.get_async_res() sock.close() @@ -234,18 +244,24 @@ def send_brcast_msg_host_to_endnode(endnode: EndnodeSsh, host_brcast_ip: str, te def send_brcast_msg_endnode_to_host(endnode: EndnodeSsh, host_brcast_ip: str, test_msg: str) -> str: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Allow binding if port still in TIME_WAIT sock.settimeout(5) try: sock.bind(('', 5100)) - except socket.error as e: - raise Exception('Host bind failed %s' % e) + # Give socket time to be fully ready to receive before we tell endnode to send. + # Even with SSH latency, there's a small window where a fast-received packet could be dropped. + time.sleep(0.1) + except OSError as e: + raise Exception(f'Host bind failed {e}') - endnode.exec_cmd('echo -n "%s" | nc -b -w0 -u %s 5100' % (test_msg, host_brcast_ip)) + endnode.exec_cmd(f'echo -n "{test_msg}" | nc -b -w0 -u {host_brcast_ip} 5100') try: nc_host_out = sock.recv(1500).decode('utf-8') - except socket.error as e: - raise Exception('Host recv failed %s', e) + except TimeoutError: + raise Exception('Host recv timed out after 5 seconds') + except OSError as e: + raise Exception(f'Host recv failed {e}') sock.close() return nc_host_out @@ -408,11 +424,17 @@ def test_esp_eth_bridge( logging.info('Multicast UDP average bandwidth: %s Mbits/s', bandwidth_mcast_udp) if bandwidth_udp < MIN_UDP_THROUGHPUT: - raise RuntimeError('Unicast UDP throughput expected %.2f, actual %.2f' % (MIN_UDP_THROUGHPUT, bandwidth_udp) + ' Mbits/s') + raise RuntimeError( + f'Unicast UDP throughput expected {MIN_UDP_THROUGHPUT:.2f}, actual {bandwidth_udp:.2f} Mbits/s' + ) if bandwidth_tcp < MIN_TCP_THROUGHPUT: - raise RuntimeError('Unicast TCP throughput expected %.2f, actual %.2f' % (MIN_TCP_THROUGHPUT, bandwidth_tcp) + ' Mbits/s') + raise RuntimeError( + f'Unicast TCP throughput expected {MIN_TCP_THROUGHPUT:.2f}, actual {bandwidth_tcp:.2f} Mbits/s' + ) if bandwidth_mcast_udp < MIN_UDP_THROUGHPUT: - raise RuntimeError('Multicast UDP throughput expected %.2f, actual %.2f' % (MIN_UDP_THROUGHPUT, bandwidth_mcast_udp) + ' Mbits/s') + raise RuntimeError( + f'Multicast UDP throughput expected {MIN_UDP_THROUGHPUT:.2f}, actual {bandwidth_mcast_udp:.2f} Mbits/s' + ) # ------------------------------------------------ # TEST Objective 4: adding/deleting entries in FDB @@ -465,7 +487,7 @@ def test_esp_eth_bridge( # try to add more FDB entries than configured max number for i in range(BR_PORTS_NUM + 1): - dut.write('add --addr=01:02:03:00:00:%02x' % i + ' -d') + dut.write(f'add --addr=01:02:03:00:00:{i:02x} -d') if i < BR_PORTS_NUM: dut.expect_exact('Bridge Config OK!') else: @@ -479,7 +501,7 @@ def test_esp_eth_bridge( # remove dummy entries for i in range(BR_PORTS_NUM): - dut.write('remove --addr=01:02:03:00:00:%02x' % i) + dut.write(f'remove --addr=01:02:03:00:00:{i:02x}') dut.expect_exact('Bridge Config OK!') # valid multiple ports at once diff --git a/examples/openthread/ot_ci_function.py b/examples/openthread/ot_ci_function.py index bc32af980cb7..25fd9cd556f1 100644 --- a/examples/openthread/ot_ci_function.py +++ b/examples/openthread/ot_ci_function.py @@ -141,11 +141,15 @@ def joinThreadNetwork(dut: IdfDut, thread: thread_parameter) -> None: def wait_for_join(dut: IdfDut, role: str) -> bool: + clean_buffer(dut) for _ in range(1, 30): - if getDeviceRole(dut) == role: - wait(dut, 5) + time.sleep(1) + execute_command(dut, 'state') + try: + dut.expect(re.compile(role), timeout=5) return True - wait(dut, 1) + except Exception: + continue return False diff --git a/examples/openthread/pytest_otbr.py b/examples/openthread/pytest_otbr.py index 670f6bd8eed1..1de1ccee26ec 100644 --- a/examples/openthread/pytest_otbr.py +++ b/examples/openthread/pytest_otbr.py @@ -234,11 +234,14 @@ def test_Bidirectional_IPv6_connectivity(Init_interface: bool, dut: Tuple[IdfDut onlinkprefix = ocf.get_onlinkprefix(br) pattern = rf'\W+({onlinkprefix}(?:\w+:){{3}}\w+)\W+' host_global_unicast_addr = re.findall(pattern, out_str) + logging.info(f'host_global_unicast_addr: {host_global_unicast_addr}') + if host_global_unicast_addr is None: + raise Exception(f'onlinkprefix: {onlinkprefix}, host_global_unicast_addr: {host_global_unicast_addr}') rx_nums = 0 for ip_addr in host_global_unicast_addr: txrx_nums = ocf.ot_ping(cli, str(ip_addr), count=10) rx_nums = rx_nums + int(txrx_nums[1]) - logging.debug(f'rx_nums: {rx_nums}') + logging.info(f'rx_nums: {rx_nums}') assert rx_nums != 0 finally: ocf.stop_thread(cli) diff --git a/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py b/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py index f774c175627d..87127c7b3178 100644 --- a/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py +++ b/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded.dut import Dut @@ -20,6 +19,6 @@ def test_rotary_encoder(dut: Dut) -> None: dut.expect_exact('add watch points and register callbacks') dut.expect_exact('clear pcnt unit') dut.expect_exact('start pcnt unit') - res = dut.expect(r'Pulse count: (\d+)') + res = dut.expect(r'(?:Pulse count|Watch point event, count): (-?\d+)') count_val = res.group(1).decode('utf8') assert -100 <= int(count_val) <= 100 diff --git a/tools/ci/idf_pytest/plugin.py b/tools/ci/idf_pytest/plugin.py index d3e39ea7d129..e551da13abe0 100644 --- a/tools/ci/idf_pytest/plugin.py +++ b/tools/ci/idf_pytest/plugin.py @@ -284,7 +284,7 @@ def pytest_runtest_makereport(self, item: Function, call: CallInfo[None]) -> Non res.extend( [ ChildCase( - format_case_id(target, config, case.name + f' {i}', is_qemu=is_qemu), + format_case_id(target, config, case.name, is_qemu=is_qemu), self.UNITY_RESULT_MAPPINGS[case.result], ) for case in _dut.testsuite.testcases