diff --git a/.gitlab/ci/danger.yml b/.gitlab/ci/danger.yml index 1775d5f8c653..de4b1bc23824 100644 --- a/.gitlab/ci/danger.yml +++ b/.gitlab/ci/danger.yml @@ -1,4 +1,4 @@ -# Extenal DangerJS +# External DangerJS include: - project: espressif/shared-ci-dangerjs ref: master @@ -10,7 +10,6 @@ run-danger-mr-linter: GIT_STRATEGY: none # no repo checkout ENABLE_CHECK_AREA_LABELS: 'true' ENABLE_CHECK_DOCS_TRANSLATION: 'true' - ENABLE_CHECK_RELEASE_NOTES_DESCRIPTION: 'true' ENABLE_CHECK_UPDATED_CHANGELOG: 'false' before_script: [] cache: [] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 92c9949680b5..2c51140160b1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -236,6 +236,6 @@ repos: name: Lint rST files in docs folder using Sphinx Lint files: ^(docs/en|docs/zh_CN)/.*\.(rst|inc)$ - repo: https://github.com/espressif/esp-idf-kconfig.git - rev: v2.1.0 + rev: v2.3.0 hooks: - id: check-kconfig-files diff --git a/CMakeLists.txt b/CMakeLists.txt index 722b07b973e6..cf7e42c8b7ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang") list(APPEND compile_options "-Wno-pointer-bool-conversion") # mbedTLS md5.c triggers this warning in md5_test_buf (false positive) list(APPEND compile_options "-Wno-string-concatenation") - # multiple cases of implict convertions between unrelated enum types + # multiple cases of implicit conversions between unrelated enum types list(APPEND compile_options "-Wno-enum-conversion") # When IRAM_ATTR is specified both in function declaration and definition, # it produces different section names, since section names include __COUNTER__. @@ -215,8 +215,35 @@ endif() list(APPEND link_options "-fno-lto") if(CONFIG_IDF_TARGET_LINUX AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + # Not all versions of the MacOS linker support the -warn_commons flag. + # ld version 1053.12 (and above) have been tested to support it. + # Hence, we extract the version string from the linker output + # before including the flag. + + # Get the ld version, capturing both stdout and stderr + execute_process( + COMMAND ${CMAKE_LINKER} -v + OUTPUT_VARIABLE LD_VERSION_OUTPUT + ERROR_VARIABLE LD_VERSION_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE + ) + + # Combine stdout and stderr + set(LD_VERSION_OUTPUT "${LD_VERSION_OUTPUT}\n${LD_VERSION_ERROR}") + + # Extract the version string + string(REGEX MATCH "PROJECT:(ld|dyld)-([0-9]+)\\.([0-9]+)" LD_VERSION_MATCH "${LD_VERSION_OUTPUT}") + set(LD_VERSION_MAJOR_MINOR "${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + + message(STATUS "Linker Version: ${LD_VERSION_MAJOR_MINOR}") + + # Compare the version with 1053.12 + if(LD_VERSION_MAJOR_MINOR VERSION_GREATER_EQUAL "1053.12") + list(APPEND link_options "-Wl,-warn_commons") + endif() + list(APPEND link_options "-Wl,-dead_strip") - list(APPEND link_options "-Wl,-warn_commons") else() list(APPEND link_options "-Wl,--gc-sections") list(APPEND link_options "-Wl,--warn-common") diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 24e1517aa3ed..a56403fa5de1 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -661,6 +661,7 @@ if(CONFIG_BT_ENABLED) host/nimble/nimble/nimble/host/services/tps/include host/nimble/nimble/nimble/host/services/hid/include host/nimble/nimble/nimble/host/services/sps/include + host/nimble/nimble/nimble/host/services/cte/include host/nimble/nimble/nimble/host/util/include host/nimble/nimble/nimble/host/store/ram/include host/nimble/nimble/nimble/host/store/config/include @@ -683,6 +684,7 @@ if(CONFIG_BT_ENABLED) "host/nimble/nimble/nimble/host/services/cts/src/ble_svc_cts.c" "host/nimble/nimble/nimble/host/services/hid/src/ble_svc_hid.c" "host/nimble/nimble/nimble/host/services/sps/src/ble_svc_sps.c" + "host/nimble/nimble/nimble/host/services/cte/src/ble_svc_cte.c" "host/nimble/nimble/nimble/host/src/ble_hs_conn.c" "host/nimble/nimble/nimble/host/src/ble_store_util.c" "host/nimble/nimble/nimble/host/src/ble_sm.c" diff --git a/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c b/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c index 67a83951f0fc..7b7c32112725 100644 --- a/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c +++ b/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -124,7 +124,31 @@ static size_t write_value(uint16_t conn_handle, uint16_t attr_handle, } } - btc_blufi_recv_handler(&ctxt->om->om_data[0], ctxt->om->om_len); + /* Data may come in linked om. So retrieve all data */ + if (SLIST_NEXT(ctxt->om, om_next) != NULL) { + uint8_t *fw_buf = (uint8_t *)malloc(517 * sizeof(uint8_t)); + memset(fw_buf, 0x0, 517); + + memcpy(fw_buf, &ctxt->om->om_data[0], ctxt->om->om_len); + struct os_mbuf *last; + last = ctxt->om; + uint32_t offset = ctxt->om->om_len; + + while (SLIST_NEXT(last, om_next) != NULL) { + struct os_mbuf *temp = SLIST_NEXT(last, om_next); + memcpy(fw_buf + offset , &temp->om_data[0], temp->om_len); + offset += temp->om_len; + last = SLIST_NEXT(last, om_next); + temp = NULL; + } + btc_blufi_recv_handler(fw_buf, offset); + + free(fw_buf); + } + else { + btc_blufi_recv_handler(&ctxt->om->om_data[0], ctxt->om->om_len); + } + rc = ble_hs_mbuf_to_flat(ctxt->om, value->buf->om_data, value->buf->om_len, &len); if (rc != 0) { diff --git a/components/bt/common/include/bt_common.h b/components/bt/common/include/bt_common.h index f3c5ba0e0da5..09e7fa50d0b3 100644 --- a/components/bt/common/include/bt_common.h +++ b/components/bt/common/include/bt_common.h @@ -46,6 +46,7 @@ #define OSI_INITIAL_TRACE_LEVEL UC_BT_LOG_OSI_TRACE_LEVEL #define BLUFI_INITIAL_TRACE_LEVEL UC_BT_LOG_BLUFI_TRACE_LEVEL +// MEMORY #if UC_BT_BLE_DYNAMIC_ENV_MEMORY #define BT_BLE_DYNAMIC_ENV_MEMORY TRUE #define BTC_DYNAMIC_MEMORY TRUE @@ -64,6 +65,19 @@ #define BT_BLE_DYNAMIC_ENV_MEMORY FALSE #endif +#if UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST +#define HEAP_ALLOCATION_FROM_SPIRAM_FIRST TRUE +#else +#define HEAP_ALLOCATION_FROM_SPIRAM_FIRST FALSE +#endif + +#if UC_BT_ABORT_WHEN_ALLOCATION_FAILS +#define HEAP_ALLOCATION_FAILS_ABORT TRUE +#else +#define HEAP_ALLOCATION_FAILS_ABORT FALSE +#endif + +// HCI LOG #if UC_BT_HCI_LOG_DEBUG_EN #define BT_HCI_LOG_INCLUDED UC_BT_HCI_LOG_DEBUG_EN #else diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index 029766b7ee17..da153405ed36 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -100,13 +100,26 @@ #define UC_BT_BLUFI_ENABLE FALSE #endif -//MEMORY DEBUG +//MEMORY #ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG #define UC_BT_BLUEDROID_MEM_DEBUG TRUE #else #define UC_BT_BLUEDROID_MEM_DEBUG FALSE #endif +#ifdef CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST +#define UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST +#else +#define UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST FALSE +#endif + +#ifdef CONFIG_BT_ABORT_WHEN_ALLOCATION_FAILS +#define UC_BT_ABORT_WHEN_ALLOCATION_FAILS CONFIG_BT_ABORT_WHEN_ALLOCATION_FAILS +#else +#define UC_BT_ABORT_WHEN_ALLOCATION_FAILS FALSE +#endif + +//HCI LOG #ifdef CONFIG_BT_HCI_LOG_DEBUG_EN #define UC_BT_HCI_LOG_DEBUG_EN TRUE #else diff --git a/components/bt/common/osi/allocator.c b/components/bt/common/osi/allocator.c index 4d10e10f47eb..fba9cf0a9e01 100644 --- a/components/bt/common/osi/allocator.c +++ b/components/bt/common/osi/allocator.c @@ -213,48 +213,33 @@ char *osi_strdup(const char *str) void *osi_malloc_func(size_t size) { -#if HEAP_MEMORY_DEBUG - void *p; -#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST - p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); -#else - p = malloc(size); -#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ - osi_mem_dbg_record(p, size, __func__, __LINE__); + void *p = osi_malloc_base(size); + + if (size != 0 && p == NULL) { + OSI_TRACE_ERROR("malloc failed (caller=%p size=%u)\n", __builtin_return_address(0), size); +#if HEAP_ALLOCATION_FAILS_ABORT + assert(0); +#endif + } + return p; -#else -#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST - return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); -#else - return malloc(size); -#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ -#endif /* #if HEAP_MEMORY_DEBUG */ } void *osi_calloc_func(size_t size) { -#if HEAP_MEMORY_DEBUG - void *p; -#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST - p = heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); -#else - p = calloc(1, size); -#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ - osi_mem_dbg_record(p, size, __func__, __LINE__); + void *p = osi_calloc_base(size); + + if (size != 0 && p == NULL) { + OSI_TRACE_ERROR("calloc failed (caller=%p size=%u)\n", __builtin_return_address(0), size); +#if HEAP_ALLOCATION_FAILS_ABORT + assert(0); +#endif + } + return p; -#else -#if HEAP_ALLOCATION_FROM_SPIRAM_FIRST - return heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); -#else - return calloc(1, size); -#endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ -#endif /* #if HEAP_MEMORY_DEBUG */ } void osi_free_func(void *ptr) { -#if HEAP_MEMORY_DEBUG - osi_mem_dbg_clean(ptr, __func__, __LINE__); -#endif free(ptr); } diff --git a/components/bt/common/osi/include/osi/allocator.h b/components/bt/common/osi/include/osi/allocator.h index 579f2b2bb639..25eca3431b1f 100644 --- a/components/bt/common/osi/include/osi/allocator.h +++ b/components/bt/common/osi/include/osi/allocator.h @@ -122,13 +122,18 @@ do { \ #else +// Memory alloc function without print and assertion #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST -#define osi_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) -#define osi_calloc(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) +#define osi_malloc_base(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) +#define osi_calloc_base(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) #else -#define osi_malloc(size) malloc((size)) -#define osi_calloc(size) calloc(1, (size)) +#define osi_malloc_base(size) malloc((size)) +#define osi_calloc_base(size) calloc(1, (size)) #endif /* #if HEAP_ALLOCATION_FROM_SPIRAM_FIRST */ + +// Memory alloc function with print and assertion when fails +#define osi_malloc(size) osi_malloc_func((size)) +#define osi_calloc(size) osi_calloc_func((size)) #define osi_free(p) free((p)) #endif /* HEAP_MEMORY_DEBUG */ diff --git a/components/bt/common/osi/thread.c b/components/bt/common/osi/thread.c index f53eadb66593..91bc7906ceab 100644 --- a/components/bt/common/osi/thread.c +++ b/components/bt/common/osi/thread.c @@ -271,10 +271,10 @@ osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priorit } for (int i = 0; i < thread->work_queue_num; i++) { - if (thread->work_queues[i]) { + if (thread->work_queues && thread->work_queues[i]) { osi_work_queue_delete(thread->work_queues[i]); + thread->work_queues[i] = NULL; } - thread->work_queues[i] = NULL; } if (thread->work_queues) { diff --git a/components/bt/controller/esp32/bt.c b/components/bt/controller/esp32/bt.c index f26dd4bc26de..e655efec9865 100644 --- a/components/bt/controller/esp32/bt.c +++ b/components/bt/controller/esp32/bt.c @@ -96,6 +96,7 @@ do{\ #define OSI_VERSION 0x00010005 #define OSI_MAGIC_VALUE 0xFADEBEAD +#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL) /* Types definition ************************************************************************ */ @@ -868,7 +869,21 @@ static int IRAM_ATTR cause_sw_intr_to_core_wrapper(int core_id, int intr_no) static void *malloc_internal_wrapper(size_t size) { - return heap_caps_malloc(size, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); + return heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); +} + +void *malloc_ble_controller_mem(size_t size) +{ + void *p = heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); + if(p == NULL) { + ESP_LOGE(BTDM_LOG_TAG, "Malloc failed"); + } + return p; +} + +uint32_t get_ble_controller_free_heap_size(void) +{ + return heap_caps_get_free_size(BLE_CONTROLLER_MALLOC_CAPS); } static int32_t IRAM_ATTR read_mac_wrapper(uint8_t mac[6]) @@ -1432,6 +1447,14 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) .name = "BT Controller Data" }; + /* + * Free data and BSS section for Bluetooth controller ROM code. + * Note that rom mem release must be performed before section _bt_data_start to _bt_data_end is released, + * otherwise `btdm_dram_available_region` will no longer be available when performing rom mem release and + * thus causing heap corruption. + */ + ret = esp_bt_controller_rom_mem_release(mode); + if (mode == ESP_BT_MODE_BTDM) { /* Start by freeing Bluetooth BSS section */ if (ret == ESP_OK) { @@ -1444,11 +1467,6 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) } } - /* free data and BSS section for Bluetooth controller ROM code */ - if (ret == ESP_OK) { - ret = esp_bt_controller_rom_mem_release(mode); - } - return ret; } diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index 9f158e84c43e..2700a616244b 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -49,6 +49,7 @@ #if CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "esp_private/sleep_modem.h" #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE +#include "esp_private/esp_modem_clock.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -75,11 +76,6 @@ #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf -typedef enum ble_rtc_slow_clk_src { - BT_SLOW_CLK_SRC_MAIN_XTAL, - BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0, -} ble_rtc_slow_clk_src_t; - /* Types definition ************************************************************************ */ @@ -442,6 +438,7 @@ static bool s_ble_active = false; static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; #define BTDM_MIN_TIMER_UNCERTAINTY_US (200) #endif // CONFIG_PM_ENABLE +static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID; #define BLE_RTC_DELAY_US (1800) @@ -556,6 +553,20 @@ void sleep_modem_light_sleep_overhead_set(uint32_t overhead) } #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void) +{ + return s_bt_lpclk_src; +} + +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src) +{ + if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) { + return; + } + + s_bt_lpclk_src = clk_src; +} + IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) { if (!s_ble_active) { @@ -582,7 +593,7 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) s_ble_active = true; } -esp_err_t controller_sleep_init(ble_rtc_slow_clk_src_t slow_clk_src) +esp_err_t controller_sleep_init(modem_clock_lpclk_src_t slow_clk_src) { esp_err_t rc = 0; #ifdef CONFIG_BT_LE_SLEEP_ENABLE @@ -590,7 +601,7 @@ esp_err_t controller_sleep_init(ble_rtc_slow_clk_src_t slow_clk_src) r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, 500 + BLE_RTC_DELAY_US); #ifdef CONFIG_PM_ENABLE - if (slow_clk_src == BT_SLOW_CLK_SRC_MAIN_XTAL) { + if (slow_clk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON); } else { esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_AUTO); @@ -645,11 +656,11 @@ void controller_sleep_deinit(void) #endif //CONFIG_PM_ENABLE } -static void esp_bt_rtc_slow_clk_select(ble_rtc_slow_clk_src_t slow_clk_src) +static void esp_bt_rtc_slow_clk_select(modem_clock_lpclk_src_t slow_clk_src) { /* Select slow clock source for BT momdule */ switch (slow_clk_src) { - case BT_SLOW_CLK_SRC_MAIN_XTAL: + case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S); @@ -661,7 +672,7 @@ static void esp_bt_rtc_slow_clk_select(ble_rtc_slow_clk_src_t slow_clk_src) SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 249, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); #endif // CONFIG_XTAL_FREQ_26 break; - case BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0: + case MODEM_CLOCK_LPCLK_SRC_EXT32K: ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source"); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S); @@ -678,40 +689,39 @@ static void esp_bt_rtc_slow_clk_select(ble_rtc_slow_clk_src_t slow_clk_src) SET_PERI_REG_BITS(MODEM_CLKRST_ETM_CLK_CONF_REG, 1, 0, MODEM_CLKRST_ETM_CLK_SEL_S); } -static ble_rtc_slow_clk_src_t ble_rtc_clk_init(esp_bt_controller_config_t *cfg) +static modem_clock_lpclk_src_t ble_rtc_clk_init(esp_bt_controller_config_t *cfg) { - ble_rtc_slow_clk_src_t slow_clk_src; - + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) { #if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL -#ifdef CONFIG_XTAL_FREQ_26 - cfg->rtc_freq = 40000; + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; #else - cfg->rtc_freq = 32000; -#endif // CONFIG_XTAL_FREQ_26 - slow_clk_src = BT_SLOW_CLK_SRC_MAIN_XTAL; -#else - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; + } +#endif // CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL + } + + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) { cfg->rtc_freq = 32768; - slow_clk_src = BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0; - } else { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { #ifdef CONFIG_XTAL_FREQ_26 cfg->rtc_freq = 40000; #else cfg->rtc_freq = 32000; #endif // CONFIG_XTAL_FREQ_26 - slow_clk_src = BT_SLOW_CLK_SRC_MAIN_XTAL; } -#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ - esp_bt_rtc_slow_clk_select(slow_clk_src); - return slow_clk_src; + esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); + return s_bt_lpclk_src; } esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; - ble_rtc_slow_clk_src_t rtc_clk_src; + modem_clock_lpclk_src_t rtc_clk_src; uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); @@ -816,6 +826,9 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) uint8_t mac[6]; ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + swap_in_place(mac, 6); esp_ble_ll_set_public_addr(mac); diff --git a/components/bt/controller/esp32c3/bt.c b/components/bt/controller/esp32c3/bt.c index 0a461d071fbf..ca3766b1aa4d 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -118,6 +118,9 @@ do{\ #define OSI_VERSION 0x00010009 #define OSI_MAGIC_VALUE 0xFADEBEAD +#define BLE_PWR_HDL_INVL 0xFFFF +#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA) + /* Types definition ************************************************************************ */ @@ -254,8 +257,8 @@ extern bool API_vhci_host_check_send_available(void); extern void API_vhci_host_send_packet(uint8_t *data, uint16_t len); extern int API_vhci_host_register_callback(const vhci_host_callback_t *callback); /* TX power */ -extern int ble_txpwr_set(int power_type, int power_level); -extern int ble_txpwr_get(int power_type); +extern int ble_txpwr_set(int power_type, uint16_t handle, int power_level); +extern int ble_txpwr_get(int power_type, uint16_t handle); extern uint16_t l2c_ble_link_get_tx_buf_num(void); extern void coex_pti_v2(void); @@ -687,13 +690,27 @@ static bool IRAM_ATTR is_in_isr_wrapper(void) static void *malloc_internal_wrapper(size_t size) { - void *p = heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA); + void *p = heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); + if(p == NULL) { + ESP_LOGE(BT_LOG_TAG, "Malloc failed"); + } + return p; +} + +void *malloc_ble_controller_mem(size_t size) +{ + void *p = heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); if(p == NULL) { ESP_LOGE(BT_LOG_TAG, "Malloc failed"); } return p; } +uint32_t get_ble_controller_free_heap_size(void) +{ + return heap_caps_get_free_size(BLE_CONTROLLER_MALLOC_CAPS); +} + static int IRAM_ATTR read_mac_wrapper(uint8_t mac[6]) { int ret = esp_read_mac(mac, ESP_MAC_BT); @@ -1674,16 +1691,89 @@ esp_bt_controller_status_t esp_bt_controller_get_status(void) return btdm_controller_status; } +static int enh_power_type_get(esp_ble_power_type_t power_type) +{ + switch (power_type) { + case ESP_BLE_PWR_TYPE_ADV: + return ESP_BLE_ENHANCED_PWR_TYPE_ADV; + case ESP_BLE_PWR_TYPE_SCAN: + return ESP_BLE_ENHANCED_PWR_TYPE_SCAN; + case ESP_BLE_PWR_TYPE_CONN_HDL0: + case ESP_BLE_PWR_TYPE_CONN_HDL1: + case ESP_BLE_PWR_TYPE_CONN_HDL2: + case ESP_BLE_PWR_TYPE_CONN_HDL3: + case ESP_BLE_PWR_TYPE_CONN_HDL4: + case ESP_BLE_PWR_TYPE_CONN_HDL5: + case ESP_BLE_PWR_TYPE_CONN_HDL6: + case ESP_BLE_PWR_TYPE_CONN_HDL7: + case ESP_BLE_PWR_TYPE_CONN_HDL8: + return ESP_BLE_ENHANCED_PWR_TYPE_CONN; + case ESP_BLE_PWR_TYPE_DEFAULT: + return ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT; + default: + break; + } + + return power_type; +} + /* extra functions */ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level) +{ + esp_err_t stat = ESP_FAIL; + uint16_t handle = BLE_PWR_HDL_INVL; + int enh_pwr_type = enh_power_type_get(power_type); + + if (power_type > ESP_BLE_PWR_TYPE_DEFAULT) { + return ESP_ERR_NOT_SUPPORTED; + } + + if (enh_pwr_type == ESP_BLE_ENHANCED_PWR_TYPE_CONN) { + handle = power_type; + } + + if (ble_txpwr_set(enh_pwr_type, handle, power_level) == 0) { + stat = ESP_OK; + } + + return stat; +} + +esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) +{ + esp_power_level_t lvl; + uint16_t handle = BLE_PWR_HDL_INVL; + int enh_pwr_type = enh_power_type_get(power_type); + + if (power_type > ESP_BLE_PWR_TYPE_DEFAULT) { + return ESP_PWR_LVL_INVALID; + } + + if (enh_pwr_type == ESP_BLE_ENHANCED_PWR_TYPE_CONN) { + handle = power_type; + } + + lvl = (esp_power_level_t)ble_txpwr_get(power_type, handle); + + return lvl; +} + +esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle, + esp_power_level_t power_level) { esp_err_t stat = ESP_FAIL; switch (power_type) { - case ESP_BLE_PWR_TYPE_ADV: - case ESP_BLE_PWR_TYPE_SCAN: - case ESP_BLE_PWR_TYPE_DEFAULT: - if (ble_txpwr_set(power_type, power_level) == 0) { + case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: + case ESP_BLE_ENHANCED_PWR_TYPE_INIT: + if (ble_txpwr_set(power_type, BLE_PWR_HDL_INVL, power_level) == 0) { + stat = ESP_OK; + } + break; + case ESP_BLE_ENHANCED_PWR_TYPE_ADV: + case ESP_BLE_ENHANCED_PWR_TYPE_CONN: + if (ble_txpwr_set(power_type, handle, power_level) == 0) { stat = ESP_OK; } break; @@ -1695,33 +1785,26 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ return stat; } -esp_power_level_t esp_ble_tx_power_get(esp_ble_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) { - esp_power_level_t lvl; + int tx_level = 0; switch (power_type) { - case ESP_BLE_PWR_TYPE_ADV: - case ESP_BLE_PWR_TYPE_SCAN: - lvl = (esp_power_level_t)ble_txpwr_get(power_type); + case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: + case ESP_BLE_ENHANCED_PWR_TYPE_INIT: + tx_level = ble_txpwr_get(power_type, BLE_PWR_HDL_INVL); break; - case ESP_BLE_PWR_TYPE_CONN_HDL0: - case ESP_BLE_PWR_TYPE_CONN_HDL1: - case ESP_BLE_PWR_TYPE_CONN_HDL2: - case ESP_BLE_PWR_TYPE_CONN_HDL3: - case ESP_BLE_PWR_TYPE_CONN_HDL4: - case ESP_BLE_PWR_TYPE_CONN_HDL5: - case ESP_BLE_PWR_TYPE_CONN_HDL6: - case ESP_BLE_PWR_TYPE_CONN_HDL7: - case ESP_BLE_PWR_TYPE_CONN_HDL8: - case ESP_BLE_PWR_TYPE_DEFAULT: - lvl = (esp_power_level_t)ble_txpwr_get(ESP_BLE_PWR_TYPE_DEFAULT); + case ESP_BLE_ENHANCED_PWR_TYPE_ADV: + case ESP_BLE_ENHANCED_PWR_TYPE_CONN: + tx_level = ble_txpwr_get(power_type, handle); break; default: - lvl = ESP_PWR_LVL_INVALID; - break; + return ESP_PWR_LVL_INVALID; } - return lvl; + return (esp_power_level_t)tx_level; } esp_err_t esp_bt_sleep_enable (void) diff --git a/components/bt/controller/esp32c5/bt.c b/components/bt/controller/esp32c5/bt.c index 3d558b357d1a..2b28d8318e19 100644 --- a/components/bt/controller/esp32c5/bt.c +++ b/components/bt/controller/esp32c5/bt.c @@ -190,6 +190,7 @@ static bool s_ble_active = false; static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; #define BTDM_MIN_TIMER_UNCERTAINTY_US (200) #endif // CONFIG_PM_ENABLE +static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID; #define BLE_RTC_DELAY_US_LIGHT_SLEEP (2500) #define BLE_RTC_DELAY_US_MODEM_SLEEP (500) @@ -333,6 +334,20 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) // } } +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void) +{ + return s_bt_lpclk_src; +} + +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src) +{ + if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) { + return; + } + + s_bt_lpclk_src = clk_src; +} + IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) { if (!s_ble_active) { @@ -534,12 +549,51 @@ void ble_controller_scan_duplicate_config(void) ble_vhci_disc_duplicate_set_max_cache_size(cache_size); } +static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg) +{ + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) { +#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; +#else +#if CONFIG_RTC_CLK_SRC_INT_RC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW; +#elif CONFIG_RTC_CLK_SRC_EXT_CRYS + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; + } +#elif CONFIG_RTC_CLK_SRC_INT_RC32K + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K; +#elif CONFIG_RTC_CLK_SRC_EXT_OSC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K; +#else + ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); + assert(0); +#endif +#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + } + + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { + cfg->rtc_freq = 100000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) { + cfg->rtc_freq = 32768; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + cfg->rtc_freq = 30000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) { + cfg->rtc_freq = 32000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) { + cfg->rtc_freq = 32000; + } + esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); +} + esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { uint8_t mac[6]; esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; - uint32_t slow_clk_freq = 0; uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); @@ -592,33 +646,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) modem_clock_module_enable(PERIPH_BT_MODULE); modem_clock_module_mac_reset(PERIPH_BT_MODULE); /* Select slow clock source for BT momdule */ -#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; -#else -#if CONFIG_RTC_CLK_SRC_INT_RC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW); - slow_clk_freq = 30000; -#elif CONFIG_RTC_CLK_SRC_EXT_CRYS - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K); - slow_clk_freq = 32768; - } else { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; - } -#elif CONFIG_RTC_CLK_SRC_INT_RC32K - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K); - slow_clk_freq = 32000; -#elif CONFIG_RTC_CLK_SRC_EXT_OSC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K); - slow_clk_freq = 32000; -#else - ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); - assert(0); -#endif -#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + ble_rtc_clk_init(cfg); esp_phy_modem_init(); if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) { @@ -664,7 +692,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) } ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); - r_esp_ble_change_rtc_freq(slow_clk_freq); ble_controller_scan_duplicate_config(); @@ -680,6 +707,8 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_controller; } ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); swap_in_place(mac, 6); r_esp_ble_ll_set_public_addr(mac); diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index 2346cf0b3b83..b7cdbc5d2fcb 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -134,7 +134,7 @@ extern void r_ble_rtc_wake_up_state_clr(void); extern int os_msys_init(void); extern void os_msys_deinit(void); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); +extern sleep_retention_entries_config_t *r_esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ extern void r_esp_ble_change_rtc_freq(uint32_t freq); @@ -393,6 +393,7 @@ static bool s_ble_active = false; static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; #define BTDM_MIN_TIMER_UNCERTAINTY_US (200) #endif // CONFIG_PM_ENABLE +static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID; #define BLE_RTC_DELAY_US_LIGHT_SLEEP (2500) #define BLE_RTC_DELAY_US_MODEM_SLEEP (500) @@ -536,6 +537,20 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) } } +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void) +{ + return s_bt_lpclk_src; +} + +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src) +{ + if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) { + return; + } + + s_bt_lpclk_src = clk_src; +} + IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) { if (!s_ble_active) { @@ -569,7 +584,7 @@ static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) { uint8_t size; int extra = *(int *)arg; - const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); + sleep_retention_entries_config_t *ble_mac_modem_config = r_esp_ble_mac_retention_link_get(&size, extra); esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) { ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization"); @@ -759,12 +774,51 @@ void ble_controller_scan_duplicate_config(void) ble_vhci_disc_duplicate_set_max_cache_size(cache_size); } +static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg) +{ + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) { +#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; +#else +#if CONFIG_RTC_CLK_SRC_INT_RC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW; +#elif CONFIG_RTC_CLK_SRC_EXT_CRYS + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; + } +#elif CONFIG_RTC_CLK_SRC_INT_RC32K + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K; +#elif CONFIG_RTC_CLK_SRC_EXT_OSC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K; +#else + ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); + assert(0); +#endif +#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + } + + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { + cfg->rtc_freq = 100000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) { + cfg->rtc_freq = 32768; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + cfg->rtc_freq = 30000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) { + cfg->rtc_freq = 32000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) { + cfg->rtc_freq = 32000; + } + esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); +} + esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { uint8_t mac[6]; esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; - uint32_t slow_clk_freq = 0; uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); @@ -816,33 +870,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) modem_clock_module_enable(PERIPH_BT_MODULE); modem_clock_module_mac_reset(PERIPH_BT_MODULE); /* Select slow clock source for BT momdule */ -#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; -#else -#if CONFIG_RTC_CLK_SRC_INT_RC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW); - slow_clk_freq = 30000; -#elif CONFIG_RTC_CLK_SRC_EXT_CRYS - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K); - slow_clk_freq = 32768; - } else { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; - } -#elif CONFIG_RTC_CLK_SRC_INT_RC32K - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K); - slow_clk_freq = 32000; -#elif CONFIG_RTC_CLK_SRC_EXT_OSC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K); - slow_clk_freq = 32000; -#else - ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); - assert(0); -#endif -#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + ble_rtc_clk_init(cfg); esp_phy_modem_init(); if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) { @@ -875,7 +903,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) } ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); - r_esp_ble_change_rtc_freq(slow_clk_freq); ble_controller_scan_duplicate_config(); @@ -892,6 +919,8 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) } ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); swap_in_place(mac, 6); r_esp_ble_ll_set_public_addr(mac); diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 90b7530b2a1f..9a46b2ca6c2c 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -126,9 +126,12 @@ extern void r_ble_rtc_wake_up_state_clr(void); extern int os_msys_init(void); extern void os_msys_deinit(void); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); +extern sleep_retention_entries_config_t *r_esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#if CONFIG_PM_ENABLE +extern void r_esp_ble_stop_wakeup_timing(void); +#endif // CONFIG_PM_ENABLE extern void r_esp_ble_change_rtc_freq(uint32_t freq); extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, @@ -384,6 +387,7 @@ static bool s_ble_active = false; static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; #define BTDM_MIN_TIMER_UNCERTAINTY_US (200) #endif // CONFIG_PM_ENABLE +static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID; #define BLE_RTC_DELAY_US_LIGHT_SLEEP (5100) #define BLE_RTC_DELAY_US_MODEM_SLEEP (1500) @@ -522,6 +526,20 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) } } +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void) +{ + return s_bt_lpclk_src; +} + +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src) +{ + if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) { + return; + } + + s_bt_lpclk_src = clk_src; +} + IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) { if (!s_ble_active) { @@ -555,7 +573,7 @@ static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) { uint8_t size; int extra = *(int *)arg; - const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); + sleep_retention_entries_config_t *ble_mac_modem_config = r_esp_ble_mac_retention_link_get(&size, extra); esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) { ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization"); @@ -613,6 +631,9 @@ esp_err_t controller_sleep_init(void) if (rc != ESP_OK) { goto error; } + + rc = esp_deep_sleep_register_hook(&r_esp_ble_stop_wakeup_timing); + assert(rc == 0); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE /* Create a new regdma link for BLE related register restoration */ rc = sleep_modem_ble_mac_modem_state_init(0); @@ -633,6 +654,7 @@ esp_err_t controller_sleep_init(void) esp_sleep_disable_bt_wakeup(); esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ + esp_deep_sleep_deregister_hook(&r_esp_ble_stop_wakeup_timing); /*lock should release first and then delete*/ if (s_pm_lock != NULL) { esp_pm_lock_delete(s_pm_lock); @@ -652,6 +674,7 @@ void controller_sleep_deinit(void) esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ #ifdef CONFIG_PM_ENABLE + esp_deep_sleep_deregister_hook(&r_esp_ble_stop_wakeup_timing); /* lock should be released first */ esp_pm_lock_delete(s_pm_lock); s_pm_lock = NULL; @@ -729,12 +752,51 @@ void ble_controller_scan_duplicate_config(void) ble_vhci_disc_duplicate_set_max_cache_size(cache_size); } +static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg) +{ + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) { +#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; +#else +#if CONFIG_RTC_CLK_SRC_INT_RC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW; +#elif CONFIG_RTC_CLK_SRC_EXT_CRYS + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; + } +#elif CONFIG_RTC_CLK_SRC_INT_RC32K + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K; +#elif CONFIG_RTC_CLK_SRC_EXT_OSC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K; +#else + ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); + assert(0); +#endif +#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + } + + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { + cfg->rtc_freq = 100000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) { + cfg->rtc_freq = 32768; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + cfg->rtc_freq = 30000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) { + cfg->rtc_freq = 32000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) { + cfg->rtc_freq = 32000; + } + esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); +} + esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { uint8_t mac[6]; esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; - uint32_t slow_clk_freq = 0; uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); @@ -786,33 +848,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) modem_clock_module_enable(PERIPH_BT_MODULE); modem_clock_module_mac_reset(PERIPH_BT_MODULE); /* Select slow clock source for BT momdule */ -#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; -#else -#if CONFIG_RTC_CLK_SRC_INT_RC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW); - slow_clk_freq = 30000; -#elif CONFIG_RTC_CLK_SRC_EXT_CRYS - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K); - slow_clk_freq = 32768; - } else { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; - } -#elif CONFIG_RTC_CLK_SRC_INT_RC32K - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K); - slow_clk_freq = 32000; -#elif CONFIG_RTC_CLK_SRC_EXT_OSC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K); - slow_clk_freq = 32000; -#else - ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); - assert(0); -#endif -#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + ble_rtc_clk_init(cfg); if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "osi coex funcs reg failed"); @@ -844,7 +880,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) } ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); - r_esp_ble_change_rtc_freq(slow_clk_freq); ble_controller_scan_duplicate_config(); @@ -860,6 +895,8 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_controller; } ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); swap_in_place(mac, 6); r_esp_ble_ll_set_public_addr(mac); diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index 3bb36a79cdfa..8112ca2c575c 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit 3bb36a79cdfad65c656b9238e0d46b935775ed72 +Subproject commit 8112ca2c575c6feb32d755623f097f1b66759490 diff --git a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib index db84a7e4539c..e65262475034 160000 --- a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib +++ b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib @@ -1 +1 @@ -Subproject commit db84a7e4539c5d9e6b8ec882b82a5de0fb8400c7 +Subproject commit e652624750341aca124e9f850e261b0c1ac63529 diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family index bfdfe8f851c9..d874f55e1132 160000 --- a/components/bt/controller/lib_esp32c3_family +++ b/components/bt/controller/lib_esp32c3_family @@ -1 +1 @@ -Subproject commit bfdfe8f851c99ced8316b133b0b15521917ea049 +Subproject commit d874f55e1132416fe18293ae1aa9ac73c40b3261 diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index 3396205d4864..f95513f22be7 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit 3396205d48647372568ba67e41c4e08917ef1038 +Subproject commit f95513f22be7b21429b01ba05dbfbc98097b5e67 diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index 85174c19ced2..58a293a2b4c3 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit 85174c19ced288f48254b01957609b8423c757bf +Subproject commit 58a293a2b4c305157723908ea29c2776f5803bbc diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index f66333932d34..7720af43c1bf 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -1223,3 +1223,10 @@ config BT_BLE_HIGH_DUTY_ADV_INTERVAL default n help This enable BLE high duty advertising interval feature + +config BT_ABORT_WHEN_ALLOCATION_FAILS + bool "Abort when memory allocation fails in BT/BLE stack" + depends on BT_BLUEDROID_ENABLED + default n + help + This enables abort when memory allocation fails diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 1d2267e8bc7e..d37f3724be80 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -504,21 +504,37 @@ esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t return ESP_OK; } -uint8_t *esp_ble_resolve_adv_data( uint8_t *adv_data, uint8_t type, uint8_t *length) +uint8_t *esp_ble_resolve_adv_data_by_type( uint8_t *adv_data, uint16_t adv_data_len, esp_ble_adv_data_type type, uint8_t *length) { + if (length == NULL) { + return NULL; + } + if (((type < ESP_BLE_AD_TYPE_FLAG) || (type > ESP_BLE_AD_TYPE_128SERVICE_DATA)) && (type != ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE)) { - LOG_ERROR("the eir type not define, type = %x\n", type); + LOG_ERROR("The advertising data type is not defined, type = %x", type); + *length = 0; return NULL; } + if (adv_data_len == 0) { + *length = 0; + return NULL; + } if (adv_data == NULL) { - LOG_ERROR("Invalid p_eir data.\n"); + LOG_ERROR("Invalid advertising data."); + *length = 0; return NULL; } - return (BTM_CheckAdvData( adv_data, type, length)); + return (BTM_CheckAdvData( adv_data, adv_data_len, type, length)); +} + +uint8_t *esp_ble_resolve_adv_data( uint8_t *adv_data, uint8_t type, uint8_t *length) +{ + return esp_ble_resolve_adv_data_by_type( adv_data, ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX, (esp_ble_adv_data_type) type, length); } + #if (BLE_42_FEATURE_SUPPORT == TRUE) esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_len) { diff --git a/components/bt/host/bluedroid/api/esp_gap_bt_api.c b/components/bt/host/bluedroid/api/esp_gap_bt_api.c index 5973a663be3b..6eaa74d6ed72 100644 --- a/components/bt/host/bluedroid/api/esp_gap_bt_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_bt_api.c @@ -184,6 +184,7 @@ esp_err_t esp_bt_gap_set_cod(esp_bt_cod_t cod, esp_bt_cod_mode_t mode) } switch (mode) { + case ESP_BT_SET_COD_RESERVED_2: case ESP_BT_SET_COD_MAJOR_MINOR: case ESP_BT_SET_COD_SERVICE_CLASS: case ESP_BT_CLR_COD_SERVICE_CLASS: diff --git a/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h b/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h index 182f87600de4..6a247bbb7e5a 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h +++ b/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h @@ -110,6 +110,14 @@ typedef enum { ESP_BT_STATUS_HCI_CONN_TOUT_DUE_TO_MIC_FAILURE, ESP_BT_STATUS_HCI_CONN_FAILED_ESTABLISHMENT, ESP_BT_STATUS_HCI_MAC_CONNECTION_FAILED, + ESP_BT_STATUS_HCI_CCA_REJECTED, + ESP_BT_STATUS_HCI_TYPE0_SUBMAP_NOT_DEFINED, + ESP_BT_STATUS_HCI_UNKNOWN_ADV_ID, + ESP_BT_STATUS_HCI_LIMIT_REACHED, + ESP_BT_STATUS_HCI_OPT_CANCEL_BY_HOST, + ESP_BT_STATUS_HCI_PKT_TOO_LONG, + ESP_BT_STATUS_HCI_TOO_LATE, + ESP_BT_STATUS_HCI_TOO_EARLY, } esp_bt_status_t; diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 3e06258835f6..589945b3175a 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -631,6 +631,7 @@ typedef struct { esp_bd_addr_t bd_addr; /*!< peer address */ esp_ble_bond_key_info_t bond_key; /*!< the bond key information */ + esp_ble_addr_type_t bd_addr_type; /*!< peer address type */ } esp_ble_bond_dev_t; /*!< the ble bond device type */ @@ -1179,13 +1180,13 @@ typedef union { struct ble_update_conn_params_evt_param { esp_bt_status_t status; /*!< Indicate update connection parameters success status */ esp_bd_addr_t bda; /*!< Bluetooth device address */ - uint16_t min_int; /*!< Min connection interval */ - uint16_t max_int; /*!< Max connection interval */ + uint16_t min_int; /*!< Minimum connection interval. If the master initiates the connection parameter update, this value is not applicable for the slave and will be set to zero. */ + uint16_t max_int; /*!< Maximum connection interval. If the master initiates the connection parameter update, this value is not applicable for the slave and will be set to zero. */ uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */ - uint16_t conn_int; /*!< Current connection interval */ + uint16_t conn_int; /*!< Current connection interval in milliseconds, calculated as N × 1.25 ms */ uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80. - Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec */ - } update_conn_params; /*!< Event parameter of ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT */ + This value is calculated as N × 10 ms */ + } update_conn_params; /*!< Event parameter for ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT */ /** * @brief ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT */ @@ -1902,17 +1903,41 @@ esp_err_t esp_ble_gap_get_device_name(void); * */ esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t * addr_type); + /** * @brief This function is called to get ADV data for a specific type. * - * @param[in] adv_data - pointer of ADV data which to be resolved - * @param[in] type - finding ADV data type - * @param[out] length - return the length of ADV data not including type + * @note This is the recommended function to use for resolving ADV data by type. + * It improves upon the deprecated `esp_ble_resolve_adv_data` function by + * including an additional parameter to specify the length of the ADV data, + * thereby offering better safety and reliability. + * + * @param[in] adv_data - pointer of ADV data which to be resolved + * @param[in] adv_data_len - the length of ADV data which to be resolved. + * @param[in] type - finding ADV data type + * @param[out] length - return the length of ADV data not including type * - * @return pointer of ADV data + * @return pointer of ADV data + * + */ +uint8_t *esp_ble_resolve_adv_data_by_type( uint8_t *adv_data, uint16_t adv_data_len, esp_ble_adv_data_type type, uint8_t *length); + +/** + * @brief This function is called to get ADV data for a specific type. + * + * @note This function has been deprecated and will be removed in a future release. + * Please use `esp_ble_resolve_adv_data_by_type` instead, which provides + * better parameter validation and supports more accurate data resolution. + * + * @param[in] adv_data - pointer of ADV data which to be resolved + * @param[in] type - finding ADV data type + * @param[out] length - return the length of ADV data not including type + * + * @return pointer of ADV data * */ uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length); + #if (BLE_42_FEATURE_SUPPORT == TRUE) /** * @brief This function is called to set raw advertising data. User need to fill diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h index 7c75927f7fcd..cb1030bc5118 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h @@ -33,8 +33,9 @@ typedef enum { ESP_BT_SET_COD_MAJOR_MINOR = 0x01, /*!< overwrite major, minor class */ ESP_BT_SET_COD_SERVICE_CLASS = 0x02, /*!< set the bits in the input, the current bit will remain */ ESP_BT_CLR_COD_SERVICE_CLASS = 0x04, /*!< clear the bits in the input, others will remain */ - ESP_BT_SET_COD_ALL = 0x08, /*!< overwrite major, minor, set the bits in service class */ - ESP_BT_INIT_COD = 0x0a, /*!< overwrite major, minor, and service class */ + ESP_BT_SET_COD_ALL = 0x08, /*!< overwrite major, minor, set the bits in service class, reserved_2 remain unchanged */ + ESP_BT_INIT_COD = 0x0a, /*!< overwrite major, minor, and service class, reserved_2 remain unchanged */ + ESP_BT_SET_COD_RESERVED_2 = 0x10, /*!< overwrite the two least significant bits reserved_2 whose default value is 0b00; other values of reserved_2 are invalid according to Bluetooth Core Specification 5.4 */ } esp_bt_cod_mode_t; #define ESP_BT_GAP_AFH_CHANNELS_LEN 10 @@ -209,6 +210,28 @@ typedef enum { ESP_BT_COD_MAJOR_DEV_UNCATEGORIZED = 31, /*!< Uncategorized: device not specified */ } esp_bt_cod_major_dev_t; +/// Minor device class field of Class of Device for Peripheral Major Class +typedef enum { + ESP_BT_COD_MINOR_PERIPHERAL_KEYBOARD = 0x10, /*!< Keyboard */ + ESP_BT_COD_MINOR_PERIPHERAL_POINTING = 0x20, /*!< Pointing */ + ESP_BT_COD_MINOR_PERIPHERAL_COMBO = 0x30, /*!< Combo + ESP_BT_COD_MINOR_PERIPHERAL_KEYBOARD, ESP_BT_COD_MINOR_PERIPHERAL_POINTING + and ESP_BT_COD_MINOR_PERIPHERAL_COMBO can be OR'd with one of the + following values to identify a multifunctional device. e.g. + ESP_BT_COD_MINOR_PERIPHERAL_KEYBOARD | ESP_BT_COD_MINOR_PERIPHERAL_GAMEPAD + ESP_BT_COD_MINOR_PERIPHERAL_POINTING | ESP_BT_COD_MINOR_PERIPHERAL_SENSING_DEVICE + */ + ESP_BT_COD_MINOR_PERIPHERAL_JOYSTICK = 0x01, /*!< Joystick */ + ESP_BT_COD_MINOR_PERIPHERAL_GAMEPAD = 0x02, /*!< Gamepad */ + ESP_BT_COD_MINOR_PERIPHERAL_REMOTE_CONTROL = 0x03, /*!< Remote Control */ + ESP_BT_COD_MINOR_PERIPHERAL_SENSING_DEVICE = 0x04, /*!< Sensing Device */ + ESP_BT_COD_MINOR_PERIPHERAL_DIGITIZING_TABLET = 0x05, /*!< Digitizing Tablet */ + ESP_BT_COD_MINOR_PERIPHERAL_CARD_READER = 0x06, /*!< Card Reader */ + ESP_BT_COD_MINOR_PERIPHERAL_DIGITAL_PAN = 0x07, /*!< Digital Pan */ + ESP_BT_COD_MINOR_PERIPHERAL_HAND_SCANNER = 0x08, /*!< Hand Scanner */ + ESP_BT_COD_MINOR_PERIPHERAL_HAND_GESTURAL_INPUT = 0x09, /*!< Hand Gestural Input */ +} esp_bt_cod_minor_peripheral_t; + /// Bits of major device class field #define ESP_BT_COD_MAJOR_DEV_BIT_MASK (0x1f00) /*!< Major device bit mask */ #define ESP_BT_COD_MAJOR_DEV_BIT_OFFSET (8) /*!< Major device bit offset */ diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c index 4124a10f30bd..9fdefa97f575 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c @@ -413,7 +413,11 @@ static void bta_hf_client_api_enable(tBTA_HF_CLIENT_DATA *p_data) /* check if mSBC support enabled */ if (bta_hf_client_version >= HFP_HF_VERSION_1_6) { +#if (BTM_WBS_INCLUDED == TRUE) bta_hf_client_cb.msbc_enabled = TRUE; +#else + bta_hf_client_cb.msbc_enabled = FALSE; +#endif } else{ bta_hf_client_cb.msbc_enabled = FALSE; } diff --git a/components/bt/host/bluedroid/bta/include/bta/utl.h b/components/bt/host/bluedroid/bta/include/bta/utl.h index a140832f3227..9dd46a75e6a7 100644 --- a/components/bt/host/bluedroid/bta/include/bta/utl.h +++ b/components/bt/host/bluedroid/bta/include/bta/utl.h @@ -36,6 +36,7 @@ #define BTA_UTL_CLR_COD_SERVICE_CLASS 0x04 #define BTA_UTL_SET_COD_ALL 0x08 /* take service class as the input (may clear some set bits!!) */ #define BTA_UTL_INIT_COD 0x0a +#define BTA_UTL_SET_COD_RESERVED_2 0x10 /* overwrite the two least significant bits reserved_2 */ /***************************************************************************** ** Type Definitions @@ -43,6 +44,7 @@ /** for utl_set_device_class() **/ typedef struct { + UINT8 reserved_2; UINT8 minor; UINT8 major; UINT16 service; @@ -125,11 +127,12 @@ extern void utl_freebuf(void **p); ** p_cod - Pointer to the device class to set to ** ** cmd - the fields of the device class to update. +** BTA_UTL_SET_COD_RESERVED_2 - overwrite the two least significant bits reserved_2 ** BTA_UTL_SET_COD_MAJOR_MINOR, - overwrite major, minor class ** BTA_UTL_SET_COD_SERVICE_CLASS - set the bits in the input ** BTA_UTL_CLR_COD_SERVICE_CLASS - clear the bits in the input -** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class -** BTA_UTL_INIT_COD - overwrite major, minor, and service class +** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class, reserved_2 remain unchanged +** BTA_UTL_INIT_COD - overwrite major, minor, and service class, reserved_2 remain unchanged ** ** Returns TRUE if successful, Otherwise FALSE ** diff --git a/components/bt/host/bluedroid/bta/sys/utl.c b/components/bt/host/bluedroid/bta/sys/utl.c index c18567cd6d6b..94348e85f030 100644 --- a/components/bt/host/bluedroid/bta/sys/utl.c +++ b/components/bt/host/bluedroid/bta/sys/utl.c @@ -170,11 +170,12 @@ void utl_freebuf(void **p) ** p_cod - Pointer to the device class to set to ** ** cmd - the fields of the device class to update. +** BTA_UTL_SET_COD_RESERVED_2 - overwrite the two least significant bits reserved_2 ** BTA_UTL_SET_COD_MAJOR_MINOR, - overwrite major, minor class ** BTA_UTL_SET_COD_SERVICE_CLASS - set the bits in the input ** BTA_UTL_CLR_COD_SERVICE_CLASS - clear the bits in the input -** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class -** BTA_UTL_INIT_COD - overwrite major, minor, and service class +** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class, reserved_2 remain unchanged +** BTA_UTL_INIT_COD - overwrite major, minor, and service class, reserved_2 remain unchanged ** ** Returns TRUE if successful, Otherwise FALSE ** @@ -183,15 +184,19 @@ BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd) { UINT8 *dev; UINT16 service; - UINT8 minor, major; + UINT8 minor, major, reserved_2; DEV_CLASS dev_class; dev = BTM_ReadDeviceClass(); BTM_COD_SERVICE_CLASS( service, dev ); BTM_COD_MINOR_CLASS(minor, dev ); BTM_COD_MAJOR_CLASS(major, dev ); + BTM_COD_RESERVED_2(reserved_2, dev); switch (cmd) { + case BTA_UTL_SET_COD_RESERVED_2: + reserved_2 = p_cod->reserved_2 & BTM_COD_RESERVED_2_MASK; + break; case BTA_UTL_SET_COD_MAJOR_MINOR: minor = p_cod->minor & BTM_COD_MINOR_CLASS_MASK; major = p_cod->major & BTM_COD_MAJOR_CLASS_MASK; @@ -226,7 +231,7 @@ BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd) } /* convert the fields into the device class type */ - FIELDS_TO_COD(dev_class, minor, major, service); + FIELDS_TO_COD(dev_class, reserved_2, minor, major, service); if (BTM_SetDeviceClass(dev_class) == BTM_SUCCESS) { return TRUE; @@ -252,16 +257,18 @@ BOOLEAN utl_get_device_class(tBTA_UTL_COD *p_cod) { UINT8 *dev; UINT16 service; - UINT8 minor, major; + UINT8 minor, major, reserved_2; dev = BTM_ReadDeviceClass(); BTM_COD_SERVICE_CLASS( service, dev ); BTM_COD_MINOR_CLASS(minor, dev ); BTM_COD_MAJOR_CLASS(major, dev ); + BTM_COD_RESERVED_2(reserved_2, dev ); p_cod->minor = minor; p_cod->major = major; p_cod->service = service; + p_cod->reserved_2 = reserved_2; return TRUE; } 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 7df1bfe0e08d..f20a7241e174 100644 --- a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c @@ -15,7 +15,7 @@ #if (SMP_INCLUDED == TRUE) -//the maximum nubmer of bonded devices +//the maximum number of bonded devices #define BONED_DEVICES_MAX_COUNT (BTM_SEC_MAX_DEVICE_RECORDS) static void _btc_storage_save(void) @@ -58,7 +58,7 @@ static void _btc_storage_save(void) addr_section_count ++; iter = btc_config_section_next(iter); } - /*exceeded the maximum nubmer of bonded devices, delete them */ + /*exceeded the maximum number of bonded devices, delete them */ if (need_remove_iter) { while(need_remove_iter != btc_config_section_end()) { const char *need_remove_section = btc_config_section_name(need_remove_iter); @@ -954,6 +954,7 @@ bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd_addr, bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num) { bt_bdaddr_t bd_addr; + int addr_t; char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0}; btc_config_lock(); @@ -975,6 +976,14 @@ bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev string_to_bdaddr(name, &bd_addr); memcpy(bond_dev->bd_addr, bd_addr.address, sizeof(bt_bdaddr_t)); + //get address type + if (_btc_storage_get_remote_addr_type((bt_bdaddr_t *)bond_dev->bd_addr, &addr_t) == BT_STATUS_SUCCESS) { + bond_dev->bd_addr_type = (uint8_t) addr_t; + } else { + // Set an invalid address type + bond_dev->bd_addr_type = 0xFF; + BTC_TRACE_ERROR("%s, %s get address type fail", __func__, name); + } //resolve the peer device long term key if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PENC, buffer, sizeof(tBTM_LE_PENC_KEYS)) == BT_STATUS_SUCCESS) { bond_dev->bond_key.key_mask |= ESP_BLE_ENC_KEY_MASK; diff --git a/components/bt/host/bluedroid/btc/core/btc_util.c b/components/bt/host/bluedroid/btc/core/btc_util.c index 5e29aba8be83..7ae724bbabce 100644 --- a/components/bt/host/bluedroid/btc/core/btc_util.c +++ b/components/bt/host/bluedroid/btc/core/btc_util.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -352,7 +352,7 @@ esp_bt_status_t btc_hci_to_esp_status(uint8_t hci_status) esp_bt_status_t btc_btm_status_to_esp_status (uint8_t btm_status) { esp_bt_status_t esp_status = ESP_BT_STATUS_FAIL; - switch(btm_status){ + switch(btm_status) { case BTM_SUCCESS: esp_status = ESP_BT_STATUS_SUCCESS; break; @@ -381,7 +381,11 @@ esp_bt_status_t btc_btm_status_to_esp_status (uint8_t btm_status) esp_status = ESP_BT_STATUS_FAIL; break; default: - esp_status = ESP_BT_STATUS_FAIL; + if (btm_status & BTM_HCI_ERROR) { + esp_status = ESP_BT_STATUS_BASE_FOR_HCI_ERR | (btm_status & 0x7F); + } else { + esp_status = ESP_BT_STATUS_FAIL; + } break; } 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 9e9d7b015cdb..e8507b80b6f7 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 @@ -585,6 +585,7 @@ static void btc_gap_bt_set_cod(btc_gap_bt_args_t *arg) { tBTA_UTL_COD p_cod; esp_bt_cod_t *cod = &(arg->set_cod.cod); + p_cod.reserved_2 = cod->reserved_2; p_cod.minor = cod->minor << 2; p_cod.major = cod->major; p_cod.service = cod->service << 5; @@ -602,6 +603,7 @@ esp_err_t btc_gap_bt_get_cod(esp_bt_cod_t *cod) BTC_TRACE_ERROR("%s get class of device failed!",__func__); return ESP_BT_STATUS_FAIL; } + cod->reserved_2 = p_cod.reserved_2; cod->minor = p_cod.minor >> 2; cod->major = p_cod.major; cod->service = p_cod.service >> 5; diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index ee1f548db36d..15d2c55f09b6 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -381,20 +381,6 @@ * Memory reference **********************************************************/ -//MEMORY ALLOCATOR -#ifdef CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST -#define UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST -#else -#define UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST FALSE -#endif - -//MEMORY DEBUG -#ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG -#define UC_BT_BLUEDROID_MEM_DEBUG CONFIG_BT_BLUEDROID_MEM_DEBUG -#else -#define UC_BT_BLUEDROID_MEM_DEBUG FALSE -#endif - //ESP COEXIST VSC #ifdef CONFIG_BT_BLUEDROID_ESP_COEX_VSC #define UC_BT_BLUEDROID_ESP_COEX_VSC CONFIG_BT_BLUEDROID_ESP_COEX_VSC 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 34ff48bc929e..a18c7aadb155 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -2378,12 +2378,6 @@ The maximum number of payload octets that the local device can receive in a sing #define BTSNOOP_MEM FALSE #endif -#if UC_HEAP_ALLOCATION_FROM_SPIRAM_FIRST -#define HEAP_ALLOCATION_FROM_SPIRAM_FIRST TRUE -#else -#define HEAP_ALLOCATION_FROM_SPIRAM_FIRST FALSE -#endif - #include "common/bt_trace.h" #endif /* BT_TARGET_H */ diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index 47717803aea9..da3be907074b 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -593,7 +593,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) } #endif pkt_size = BT_PKT_LINKED_HDR_SIZE + BT_HDR_SIZE + len; - linked_pkt = (pkt_linked_item_t *) osi_calloc(pkt_size); + linked_pkt = (pkt_linked_item_t *) osi_calloc_base(pkt_size); if (!linked_pkt) { #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) hci_adv_credits_consumed(1); diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index 0d1e8fd6268b..a69c1f0f2fc9 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -2148,7 +2148,7 @@ void btm_ble_create_ll_conn_complete (UINT8 status) tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(l2cb.ble_connecting_bda, BT_TRANSPORT_LE); /* Do not remove lcb if an LE link is already up as a peripheral */ if (p_lcb != NULL && - !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_ACL_IS_CONNECTED(l2cb.ble_connecting_bda))) { + !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_LE_ACL_IS_CONNECTED(l2cb.ble_connecting_bda))) { p_lcb->disc_reason = L2CAP_CONN_CANCEL; l2cu_release_lcb (p_lcb); } 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 f595e3e6efbf..4e0f42f59ba0 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 @@ -249,10 +249,10 @@ tBTM_STATUS BTM_BleSetPreferDefaultPhy(UINT8 tx_phy_mask, UINT8 rx_phy_mask) if ((err = btsnd_hcic_ble_set_prefered_default_phy(all_phys, tx_phy_mask, rx_phy_mask)) != HCI_SUCCESS) { BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)", __func__, btm_ble_hci_status_to_str(err), err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } - cb_params.set_perf_def_phy.status = err; + cb_params.set_perf_def_phy.status = status; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT, &cb_params); @@ -330,7 +330,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr) if((err = btsnd_hcic_ble_set_extend_rand_address(instance, rand_addr)) != HCI_SUCCESS) { BTM_TRACE_ERROR("%s, fail to send the hci command, the error code = %s(0x%x)", __func__, btm_ble_hci_status_to_str(err), err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } else { // set random address success, update address info if(extend_adv_cb.inst[instance].configured && extend_adv_cb.inst[instance].connetable) { @@ -403,7 +403,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR params->primary_phy, params->max_skip, params->secondary_phy, params->sid, params->scan_req_notif)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; goto end; } @@ -414,7 +414,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR // update RPA address if((err = btsnd_hcic_ble_set_extend_rand_address(instance, rand_addr)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } else { // set addr success, update address info BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr); @@ -452,23 +452,25 @@ tBTM_STATUS BTM_BleConfigExtendedAdvDataRaw(BOOLEAN is_scan_rsp, UINT8 instance, } else if (rem_len <= BTM_BLE_EXT_ADV_DATA_LEN_MAX) { operation = BTM_BLE_ADV_DATA_OP_LAST_FRAG; } else { - operation = BTM_BLE_ADV_DATA_OP_INTERMEDIATE_FRAG; - } + operation = BTM_BLE_ADV_DATA_OP_INTERMEDIATE_FRAG; + } } if (!is_scan_rsp) { if ((err = btsnd_hcic_ble_set_ext_adv_data(instance, operation, 0, send_data_len, &data[data_offset])) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA SetAdvData: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; + break; } } else { if ((err = btsnd_hcic_ble_set_ext_adv_scan_rsp_data(instance, operation, 0, send_data_len, &data[data_offset])) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA SetScanRspData: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; + break; } } rem_len -= send_data_len; - data_offset += send_data_len; + data_offset += send_data_len; } while (rem_len); end: @@ -522,7 +524,7 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_ if ((err = btsnd_hcic_ble_ext_adv_enable(enable, num, instance, duration, max_events)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA En=%d: cmd err=0x%x", enable, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } osi_free(instance); @@ -533,7 +535,7 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_ if ((err = btsnd_hcic_ble_ext_adv_enable(enable, num, NULL, NULL, NULL)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EA En=%d: cmd err=0x%x", enable, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } goto end; } @@ -631,7 +633,7 @@ tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance) if ((err = btsnd_hcic_ble_remove_adv_set(instance)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EAS Rm: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } else { extend_adv_cb.inst[instance].configured = false; extend_adv_cb.inst[instance].legacy_pdu = false; @@ -659,7 +661,7 @@ tBTM_STATUS BTM_BleExtAdvSetClear(void) if ((err = btsnd_hcic_ble_clear_adv_set()) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE EAS Clr: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } else { for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) { extend_adv_cb.inst[i].configured = false; @@ -703,7 +705,7 @@ tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Pa if ((err= btsnd_hcic_ble_set_periodic_adv_params(instance, params->interval_min, params->interval_max, params->properties)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SetParams: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: @@ -756,10 +758,12 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data if ((err = btsnd_hcic_ble_set_periodic_adv_data(instance, operation, send_data_len, &data[data_offset])) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SetData: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; + break; } + rem_len -= send_data_len; - data_offset += send_data_len; + data_offset += send_data_len; } while(rem_len); end: @@ -785,7 +789,7 @@ tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, UINT8 enable) if ((err = btsnd_hcic_ble_periodic_adv_enable(enable, instance)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA En=%d: cmd err=0x%x", enable, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: @@ -860,6 +864,7 @@ tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params) return status; } + void btm_set_phy_callback(UINT8 status) { tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; @@ -868,6 +873,7 @@ void btm_set_phy_callback(UINT8 status) BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_SET_PREFERED_PHY_COMPLETE_EVT, &cb_params); } + void btm_create_sync_callback(UINT8 status) { tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; @@ -903,7 +909,7 @@ tBTM_STATUS BTM_BlePeriodicAdvSyncCancel(void) if ((err = btsnd_hcic_ble_periodic_adv_create_sync_cancel()) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SyncCancel, cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } cb_params.status = status; @@ -921,7 +927,7 @@ tBTM_STATUS BTM_BlePeriodicAdvSyncTerm(UINT16 sync_handle) if (( err = btsnd_hcic_ble_periodic_adv_term_sync(sync_handle)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SyncTerm: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } cb_params.status = status; @@ -945,7 +951,7 @@ tBTM_STATUS BTM_BlePeriodicAdvAddDevToList(tBLE_ADDR_TYPE addr_type, BD_ADDR add if ((err = btsnd_hcic_ble_add_dev_to_periodic_adv_list(addr_type, addr, sid)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA AddDevToList: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: @@ -969,7 +975,7 @@ tBTM_STATUS BTM_BlePeriodicAdvRemoveDevFromList(tBLE_ADDR_TYPE addr_type, BD_ADD if ((err = btsnd_hcic_ble_rm_dev_from_periodic_adv_list(addr_type, addr, sid)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA RmDevFromList: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: @@ -987,7 +993,7 @@ tBTM_STATUS BTM_BlePeriodicAdvClearDev(void) if ((err = btsnd_hcic_ble_clear_periodic_adv_list()) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA ClrDev: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } cb_params.status = status; @@ -1039,7 +1045,7 @@ tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params) if ((err = btsnd_hcic_ble_set_ext_scan_params(params->own_addr_type, params->filter_policy, phy_mask, phy_count, hci_params)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE ES SetParams: cmd err=0x%x", err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: @@ -1065,7 +1071,7 @@ tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period) if ((err = btsnd_hcic_ble_ext_scan_enable(enable, extend_adv_cb.scan_duplicate, duration, period)) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE ES En=%d: cmd err=0x%x", enable, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } end: @@ -1401,7 +1407,7 @@ void BTM_BlePeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable) if ((err = btsnd_hcic_ble_set_periodic_adv_recv_enable(sync_handle, enable)) != HCI_SUCCESS) { BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } cb_params.status = status; @@ -1460,7 +1466,7 @@ void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 sk tHCI_STATUS err = HCI_SUCCESS; if ((err = btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(mode, skip, sync_timeout, cte_type)) != HCI_SUCCESS) { BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); - status = BTM_ILLEGAL_VALUE; + status = BTM_HCI_ERROR | err; } cb_params.set_past_params.status = status; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 165a7893840e..a85f6a16112d 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -2101,7 +2101,7 @@ BOOLEAN BTM_BleGetCurrentAddress(BD_ADDR addr, uint8_t *addr_type) ** Returns pointer of ADV data ** *******************************************************************************/ -UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length) +UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT16 adv_data_len, UINT8 type, UINT8 *p_length) { UINT8 *p = p_adv; UINT8 length; @@ -2110,7 +2110,7 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length) STREAM_TO_UINT8(length, p); - while ( length && (p - p_adv < BTM_BLE_CACHE_ADV_DATA_MAX)) { + while ( length && (p - p_adv < adv_data_len)) { STREAM_TO_UINT8(adv_type, p); if ( adv_type == type ) { @@ -2123,7 +2123,7 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length) /* Break loop if advertising data is in an incorrect format, as it may lead to memory overflow */ - if (p >= p_adv + BTM_BLE_CACHE_ADV_DATA_MAX) { + if (p >= p_adv + adv_data_len) { break; } @@ -3176,7 +3176,7 @@ UINT8 btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p) } if (p_le_inq_cb->adv_len != 0) { - if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, + if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len, BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL) { flag = * p_flag; @@ -3392,7 +3392,7 @@ BOOLEAN btm_ble_update_inq_result(BD_ADDR bda, tINQ_DB_ENT *p_i, UINT8 addr_type p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */ if (p_le_inq_cb->adv_len != 0) { - if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, BTM_BLE_AD_TYPE_FLAG, &len)) != NULL) { + if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len, BTM_BLE_AD_TYPE_FLAG, &len)) != NULL) { p_cur->flag = * p_flag; } } @@ -3402,11 +3402,11 @@ BOOLEAN btm_ble_update_inq_result(BD_ADDR bda, tINQ_DB_ENT *p_i, UINT8 addr_type * then try to convert the appearance value to a class of device value Bluedroid can use. * Otherwise fall back to trying to infer if it is a HID device based on the service class. */ - p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, BTM_BLE_AD_TYPE_APPEARANCE, &len); + p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len, BTM_BLE_AD_TYPE_APPEARANCE, &len); if (p_uuid16 && len == 2) { btm_ble_appearance_to_cod((UINT16)p_uuid16[0] | (p_uuid16[1] << 8), p_cur->dev_class); } else { - if ((p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, + if ((p_uuid16 = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, p_le_inq_cb->adv_len, BTM_BLE_AD_TYPE_16SRV_CMPL, &len)) != NULL) { UINT8 i; for (i = 0; i + 2 <= len; i = i + 2) { @@ -3493,10 +3493,10 @@ void btm_send_sel_conn_callback(BD_ADDR remote_bda, UINT8 evt_type, UINT8 *p_dat /* get the device name if exist in ADV data */ if (data_len != 0) { - p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_CMPL, &len); + p_dev_name = BTM_CheckAdvData(p_data, data_len, BTM_BLE_AD_TYPE_NAME_CMPL, &len); if (p_dev_name == NULL) { - p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_SHORT, &len); + p_dev_name = BTM_CheckAdvData(p_data, data_len, BTM_BLE_AD_TYPE_NAME_SHORT, &len); } if (p_dev_name) { diff --git a/components/bt/host/bluedroid/stack/btm/btm_inq.c b/components/bt/host/bluedroid/stack/btm/btm_inq.c index b8da23279516..528c7a066f08 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/components/bt/host/bluedroid/stack/btm/btm_inq.c @@ -163,7 +163,7 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter UINT8 scan_mode = 0; UINT16 service_class; UINT8 *p_cod; - UINT8 major, minor; + UINT8 major, minor, reserved_2; DEV_CLASS cod; LAP temp_lap[2]; BOOLEAN is_limited; @@ -255,13 +255,14 @@ tBTM_STATUS BTM_SetDiscoverability (UINT16 inq_mode, UINT16 window, UINT16 inter if (is_limited ^ cod_limited) { BTM_COD_MINOR_CLASS(minor, p_cod ); BTM_COD_MAJOR_CLASS(major, p_cod ); + BTM_COD_RESERVED_2(reserved_2, p_cod); if (is_limited) { service_class |= BTM_COD_SERVICE_LMTD_DISCOVER; } else { service_class &= ~BTM_COD_SERVICE_LMTD_DISCOVER; } - FIELDS_TO_COD(cod, minor, major, service_class); + FIELDS_TO_COD(cod, reserved_2, minor, major, service_class); (void) BTM_SetDeviceClass (cod); } @@ -515,7 +516,7 @@ tBTM_STATUS BTM_SetPeriodicInquiryMode (tBTM_INQ_PARMS *p_inqparms, UINT16 max_d /* Before beginning the inquiry the current filter must be cleared, so initiate the command */ if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type, &p_inqparms->filter_cond)) != BTM_CMD_STARTED) { - /* If set filter command is not succesful reset the state */ + /* If set filter command is not successful reset the state */ p_inq->p_inq_results_cb = NULL; p_inq->state = BTM_INQ_INACTIVE_STATE; @@ -688,7 +689,7 @@ UINT16 BTM_ReadConnectability (UINT16 *p_window, UINT16 *p_interval) ** Description This function returns a bit mask of the current inquiry state ** ** Returns BTM_INQUIRY_INACTIVE if inactive (0) -** BTM_LIMITED_INQUIRY_ACTIVE if a limted inquiry is active +** BTM_LIMITED_INQUIRY_ACTIVE if a limited inquiry is active ** BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active ** BTM_PERIODIC_INQUIRY_ACTIVE if a periodic inquiry is active ** @@ -783,7 +784,7 @@ tBTM_STATUS BTM_CancelInquiry(void) ** Description This function is called to start an inquiry. ** ** Parameters: p_inqparms - pointer to the inquiry information -** mode - GENERAL or LIMITED inquiry, BR/LE bit mask seperately +** mode - GENERAL or LIMITED inquiry, BR/LE bit mask separately ** duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED) ** max_resps - maximum amount of devices to search for before ending the inquiry ** filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or @@ -1858,7 +1859,7 @@ void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode) #if BLE_INCLUDED == TRUE /* new device response */ && ( p_i == NULL || - /* exisiting device with BR/EDR info */ + /* existing device with BR/EDR info */ (p_i && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0) ) #endif diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 3d01a5c2d487..533e76ef5af3 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -50,6 +50,7 @@ typedef char tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1]; #endif #define BTM_ACL_IS_CONNECTED(bda) (btm_bda_to_acl (bda, BT_TRANSPORT_BR_EDR) != NULL) +#define BTM_LE_ACL_IS_CONNECTED(bda) (btm_bda_to_acl (bda, BT_TRANSPORT_LE) != NULL) /* Definitions for Server Channel Number (SCN) management */ diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 9da6b9d7a92d..44bb4fd3b9ab 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -2162,7 +2162,9 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len) { tBTM_BLE_EXT_ADV_REPORT ext_adv_report = {0}; UINT8 num_reports = {0}; +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) UINT8 *pp = p; +#endif //UINT8 legacy_event_type = 0; UINT16 evt_type = 0; uint8_t addr_type; diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_api.h index 32420f75e3bd..63a40ca088ff 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -75,6 +75,7 @@ enum { BTM_SET_STATIC_RAND_ADDR_FAIL, /* 25 Command failed */ BTM_INVALID_STATIC_RAND_ADDR, /* 26 invalid static rand addr */ BTM_SEC_DEV_REC_REMOVED, /* 27 Device record relate to the bd_addr is removed */ + BTM_HCI_ERROR = 128, /* 128 HCI error code from controller (0x80) */ }; typedef uint8_t tBTM_STATUS; @@ -456,22 +457,22 @@ typedef enum { #define BTM_COD_SERVICE_INFORMATION 0x8000 /* class of device field macros */ -#define BTM_COD_FORMAT_TYPE(u8, pd) {u8 = pd[2]&0x03;} +#define BTM_COD_RESERVED_2(u8, pd) {u8 = pd[2]&0x03;} #define BTM_COD_MINOR_CLASS(u8, pd) {u8 = pd[2]&0xFC;} #define BTM_COD_MAJOR_CLASS(u8, pd) {u8 = pd[1]&0x1F;} #define BTM_COD_SERVICE_CLASS(u16, pd) {u16 = pd[0]; u16<<=8; u16 += pd[1]&0xE0;} /* to set the fields (assumes that format type is always 0) */ -#define FIELDS_TO_COD(pd, mn, mj, sv) {pd[2] = mn; pd[1] = \ - mj+ ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \ - pd[0] = (sv) >> 8;} +#define FIELDS_TO_COD(pd, rs, mn, mj, sv) {pd[2] = (mn & BTM_COD_MINOR_CLASS_MASK) + (rs & BTM_COD_RESERVED_2_MASK); \ + pd[1] = mj+ ((sv)&BTM_COD_SERVICE_CLASS_LO_B); \ + pd[0] = (sv) >> 8;} /* the COD masks */ -#define BTM_COD_FORMAT_TYPE_MASK 0x03 #define BTM_COD_MINOR_CLASS_MASK 0xFC #define BTM_COD_MAJOR_CLASS_MASK 0x1F #define BTM_COD_SERVICE_CLASS_LO_B 0x00E0 #define BTM_COD_SERVICE_CLASS_MASK 0xFFE0 +#define BTM_COD_RESERVED_2_MASK 0x03 /* BTM service definitions ** Used for storing EIR data to bit mask diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index 1b3096428497..21d783dd2b10 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -2112,7 +2112,7 @@ void BTM_BleReadControllerFeatures(tBTM_BLE_CTRL_FEATURES_CBACK *p_vsc_cback); ** *******************************************************************************/ //extern -UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length); +UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT16 adv_data_len, UINT8 type, UINT8 *p_length); /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 956a4b7fb2cb..01edf9caf537 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -111,7 +111,7 @@ BOOLEAN L2CA_CancelBleConnectReq (BD_ADDR rem_bda) p_lcb = l2cu_find_lcb_by_bd_addr(rem_bda, BT_TRANSPORT_LE); /* Do not remove lcb if an LE link is already up as a peripheral */ if (p_lcb != NULL && - !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_ACL_IS_CONNECTED(rem_bda))) { + !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_LE_ACL_IS_CONNECTED(rem_bda))) { p_lcb->disc_reason = L2CAP_CONN_CANCEL; l2cu_release_lcb (p_lcb); } diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index 5bb08e5ac705..28b1eeaa91d6 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -646,6 +646,13 @@ config BT_NIMBLE_PERIODIC_ADV_ENH help Enable the periodic advertising enhancements +config BT_NIMBLE_AOA_AOD + bool "Direction Finding" + depends on BT_NIMBLE_50_FEATURE_SUPPORT && SOC_BLE_CTE_SUPPORTED + default n + help + Enable support for Connectionless and Connection Oriented Direction Finding + menuconfig BT_NIMBLE_GATT_CACHING bool "Enable GATT caching" depends on BT_NIMBLE_ENABLED && BT_NIMBLE_50_FEATURE_SUPPORT @@ -933,6 +940,12 @@ config BT_NIMBLE_HIGH_DUTY_ADV_ITVL help This enable BLE high duty advertising interval feature +config BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN + bool "Allow Connections with scanning in progress" + depends on BT_NIMBLE_ENABLED + help + This enables support for user to initiate a new connection with scan in progress + config BT_NIMBLE_HOST_QUEUE_CONG_CHECK bool "BLE queue congestion check" depends on BT_NIMBLE_ENABLED diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 2cf7edde6386..c55a6388a2c1 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 2cf7edde63866f5663bbcdfb8776cf29c0809456 +Subproject commit c55a6388a2c1d5984e3e7c489de5d0908af4d97c 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 9370be89b81d..78eab7c3d330 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/components/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -1824,7 +1824,7 @@ #ifdef CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK #define MYNEWT_VAL_BLE_QUEUE_CONG_CHECK CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK #else -#define MYNEWT_VAL_BLE_QUEUE_CONG_CHECK FALSE +#define MYNEWT_VAL_BLE_QUEUE_CONG_CHECK (0) #endif #endif @@ -1836,6 +1836,30 @@ #endif #endif +#ifndef MYNEWT_VAL_BLE_AOA_AOD +#ifdef CONFIG_BT_NIMBLE_AOA_AOD +#define MYNEWT_VAL_BLE_AOA_AOD CONFIG_BT_NIMBLE_AOA_AOD +#else +#define MYNEWT_VAL_BLE_AOA_AOD (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN +#ifdef CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN +#define MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN +#else +#define MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BT_HCI_LOG_INCLUDED +#ifdef CONFIG_BT_HCI_LOG_DEBUG_EN +#define MYNEWT_VAL_BT_HCI_LOG_INCLUDED CONFIG_BT_HCI_LOG_DEBUG_EN +#else +#define MYNEWT_VAL_BT_HCI_LOG_INCLUDED (0) +#endif +#endif + #if CONFIG_BT_CONTROLLER_DISABLED && CONFIG_BT_NIMBLE_TRANSPORT_UART #ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_PORT #define MYNEWT_VAL_BLE_TRANSPORT_UART_PORT CONFIG_BT_NIMBLE_TRANSPORT_UART_PORT @@ -1869,5 +1893,4 @@ #define MYNEWT_VAL_BLE_TRANSPORT_UART_STOP_BITS (1) #endif #endif - #endif diff --git a/components/bt/include/esp32c2/include/esp_bt.h b/components/bt/include/esp32c2/include/esp_bt.h index c73d4cb9243e..148f615b6d06 100644 --- a/components/bt/include/esp32c2/include/esp_bt.h +++ b/components/bt/include/esp32c2/include/esp_bt.h @@ -16,6 +16,7 @@ #include "nimble/nimble_npl.h" #include "../../../../controller/esp32c2/esp_bt_cfg.h" #include "hal/efuse_hal.h" +#include "esp_private/esp_modem_clock.h" #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #include "driver/uart.h" @@ -428,6 +429,12 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr); void esp_ble_controller_log_dump_all(bool output); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +#if CONFIG_PM_ENABLE +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void); + +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src); +#endif // CONFIG_PM_ENABLE + #ifdef __cplusplus } #endif diff --git a/components/bt/include/esp32c3/include/esp_bt.h b/components/bt/include/esp32c3/include/esp_bt.h index 8beb1d178c4b..7221e720a332 100644 --- a/components/bt/include/esp32c3/include/esp_bt.h +++ b/components/bt/include/esp32c3/include/esp_bt.h @@ -390,6 +390,18 @@ typedef enum { ESP_PWR_LVL_INVALID = 0xFF, /*!< Indicates an invalid value */ } esp_power_level_t; +/** + * @brief The enhanced type of which tx power, could set Advertising/Connection/Default and etc. + */ +typedef enum { + ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT = 0, + ESP_BLE_ENHANCED_PWR_TYPE_ADV, + ESP_BLE_ENHANCED_PWR_TYPE_SCAN, + ESP_BLE_ENHANCED_PWR_TYPE_INIT, + ESP_BLE_ENHANCED_PWR_TYPE_CONN, + ESP_BLE_ENHANCED_PWR_TYPE_MAX, +} esp_ble_enhanced_power_type_t; + /** * @brief Set BLE TX power * Connection Tx power should only be set after connection created. @@ -407,6 +419,25 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ */ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type); +/** + * @brief ENHANCED API for Setting BLE TX power + * Connection Tx power should only be set after connection created. + * @param power_type : The enhanced type of which tx power, could set Advertising/Connection/Default and etc. + * @param handle : The handle of Advertising or Connection and the value 0 for other enhanced power types. + * @param power_level: Power level(index) corresponding to absolute value(dbm) + * @return ESP_OK - success, other - failed + */ +esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle, esp_power_level_t power_level); + +/** + * @brief ENHANCED API of Getting BLE TX power + * Connection Tx power should only be get after connection created. + * @param power_type : The enhanced type of which tx power, could set Advertising/Connection/Default and etc + * @param handle : The handle of Advertising or Connection and the value 0 for other enhanced power types. + * @return >= 0 - Power level, < 0 - Invalid + */ +esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); + /** * @brief Initialize BT controller to allocate task and other resource. * This function should be called only once, before any other BT functions are called. diff --git a/components/bt/include/esp32c5/include/esp_bt.h b/components/bt/include/esp32c5/include/esp_bt.h index 37a70c2a40fa..5fdf462a001d 100644 --- a/components/bt/include/esp32c5/include/esp_bt.h +++ b/components/bt/include/esp32c5/include/esp_bt.h @@ -16,6 +16,7 @@ #include "nimble/nimble_npl.h" #include "../../../../controller/esp32c5/esp_bt_cfg.h" #include "hal/efuse_hal.h" +#include "esp_private/esp_modem_clock.h" #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #include "driver/uart.h" @@ -412,6 +413,12 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr); void esp_ble_controller_log_dump_all(bool output); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +#if CONFIG_PM_ENABLE +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void); + +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src); +#endif // CONFIG_PM_ENABLE + #ifdef __cplusplus } #endif diff --git a/components/bt/include/esp32c6/include/esp_bt.h b/components/bt/include/esp32c6/include/esp_bt.h index ea272287228d..f5ad1947f3fa 100644 --- a/components/bt/include/esp32c6/include/esp_bt.h +++ b/components/bt/include/esp32c6/include/esp_bt.h @@ -16,6 +16,7 @@ #include "nimble/nimble_npl.h" #include "../../../../controller/esp32c6/esp_bt_cfg.h" #include "hal/efuse_hal.h" +#include "esp_private/esp_modem_clock.h" #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #include "driver/uart.h" @@ -414,6 +415,12 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr); void esp_ble_controller_log_dump_all(bool output); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +#if CONFIG_PM_ENABLE +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void); + +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src); +#endif // CONFIG_PM_ENABLE + #ifdef __cplusplus } #endif diff --git a/components/bt/include/esp32h2/include/esp_bt.h b/components/bt/include/esp32h2/include/esp_bt.h index bbecb64072fb..95cf36cc58af 100644 --- a/components/bt/include/esp32h2/include/esp_bt.h +++ b/components/bt/include/esp32h2/include/esp_bt.h @@ -15,6 +15,7 @@ #include "nimble/nimble_npl.h" #include "../../../../controller/esp32h2/esp_bt_cfg.h" +#include "esp_private/esp_modem_clock.h" #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #include "driver/uart.h" @@ -418,6 +419,12 @@ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr); void esp_ble_controller_log_dump_all(bool output); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +#if CONFIG_PM_ENABLE +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void); + +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src); +#endif // CONFIG_PM_ENABLE + #ifdef __cplusplus } #endif diff --git a/components/bt/porting/transport/driver/vhci/hci_driver_standard.c b/components/bt/porting/transport/driver/vhci/hci_driver_standard.c index 2cdab4359e53..5e9d02af948d 100644 --- a/components/bt/porting/transport/driver/vhci/hci_driver_standard.c +++ b/components/bt/porting/transport/driver/vhci/hci_driver_standard.c @@ -139,6 +139,10 @@ esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) { + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + return; + } + hci_driver_vhci_tx(data[0], data, len, HCI_DRIVER_DIR_H2C); } diff --git a/components/bt/test_apps/memory_release/main/test_app_main.c b/components/bt/test_apps/memory_release/main/test_app_main.c index 562d1d97ddd6..909a730d4bc3 100644 --- a/components/bt/test_apps/memory_release/main/test_app_main.c +++ b/components/bt/test_apps/memory_release/main/test_app_main.c @@ -11,6 +11,7 @@ #include "nvs_flash.h" #include "multi_heap.h" +#include "esp_heap_caps.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -127,5 +128,7 @@ void app_main(void) } ESP_LOGI(tag, "Free heap size increased by %"PRIu32" bytes", free_after - free_before); - ESP_LOGI(tag, "SUCCESS"); + if (heap_caps_check_integrity_all(true)) { + ESP_LOGI(tag, "Comprehensive heap check: SUCCESS"); + } } diff --git a/components/bt/test_apps/memory_release/pytest_memory_release.py b/components/bt/test_apps/memory_release/pytest_memory_release.py index dbefc908a63c..fbb39169917b 100644 --- a/components/bt/test_apps/memory_release/pytest_memory_release.py +++ b/components/bt/test_apps/memory_release/pytest_memory_release.py @@ -12,4 +12,4 @@ def test_bt_memory_release(dut: Dut) -> None: dut.expect_exact('BLE Host Task Started', timeout=6) dut.expect_exact('BLE Host Task Stopped', timeout=8) - dut.expect_exact('SUCCESS', timeout=10) + dut.expect_exact('Comprehensive heap check: SUCCESS', timeout=10) diff --git a/components/bt/test_apps/memory_release/sdkconfig.defaults b/components/bt/test_apps/memory_release/sdkconfig.defaults index a22d8109d7d5..fc2b04c1aa1d 100644 --- a/components/bt/test_apps/memory_release/sdkconfig.defaults +++ b/components/bt/test_apps/memory_release/sdkconfig.defaults @@ -1,2 +1,4 @@ +CONFIG_HEAP_POISONING_COMPREHENSIVE=y + CONFIG_BT_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y diff --git a/components/efuse/esp32p4/esp_efuse_fields.c b/components/efuse/esp32p4/esp_efuse_fields.c index 20e614c26793..5bb0023b07f7 100644 --- a/components/efuse/esp32p4/esp_efuse_fields.c +++ b/components/efuse/esp32p4/esp_efuse_fields.c @@ -24,6 +24,7 @@ static __attribute__((unused)) const char *TAG = "efuse"; uint32_t esp_efuse_get_pkg_ver(void) { uint32_t pkg_ver = 0; + esp_efuse_read_field_blob(ESP_EFUSE_PKG_VERSION, &pkg_ver, ESP_EFUSE_PKG_VERSION[0]->bit_count); return pkg_ver; } diff --git a/components/esp_common/test_apps/.build-test-rules.yml b/components/esp_common/test_apps/.build-test-rules.yml index 04fd48936f06..c52d810e1520 100644 --- a/components/esp_common/test_apps/.build-test-rules.yml +++ b/components/esp_common/test_apps/.build-test-rules.yml @@ -3,3 +3,4 @@ components/esp_common/test_apps/esp_common: disable: - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "psram_noinit" and SOC_SPIRAM_SUPPORTED != 1 diff --git a/components/esp_common/test_apps/esp_common/main/CMakeLists.txt b/components/esp_common/test_apps/esp_common/main/CMakeLists.txt index 44a5ed32a21a..d1e953e63823 100644 --- a/components/esp_common/test_apps/esp_common/main/CMakeLists.txt +++ b/components/esp_common/test_apps/esp_common/main/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "test_app_main.c" "test_attr.c" INCLUDE_DIRS "." - PRIV_REQUIRES unity esp_psram + PRIV_REQUIRES unity esp_mm esp_psram WHOLE_ARCHIVE) diff --git a/components/esp_common/test_apps/esp_common/main/test_attr.c b/components/esp_common/test_apps/esp_common/main/test_attr.c index 49bce8c44911..0dad47c98238 100644 --- a/components/esp_common/test_apps/esp_common/main/test_attr.c +++ b/components/esp_common/test_apps/esp_common/main/test_attr.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,10 +10,17 @@ #include "esp_log.h" #include "soc/soc.h" #include "esp_system.h" +#include "hal/cache_ll.h" +#include "hal/cache_hal.h" +#include "esp_cache.h" #if CONFIG_IDF_TARGET_ESP32 #include "esp_private/esp_psram_extram.h" #endif +#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) + +static const char *TAG = "attr_test"; + extern int _rtc_noinit_start; extern int _rtc_noinit_end; extern int _rtc_data_start; @@ -44,6 +51,7 @@ static EXT_RAM_NOINIT_ATTR uint32_t s_noinit_ext; static bool data_in_segment(void *ptr, int *seg_start, int *seg_end) { + ESP_LOGV(TAG, "ptr:%p seg_start:%p seg_end:%p", ptr, seg_start, seg_end); return ((intptr_t)ptr < (intptr_t)seg_end) && \ ((intptr_t)ptr >= (intptr_t)seg_start); } @@ -94,7 +102,13 @@ static void write_spiram_and_reset(void) } printf("Flushing cache\n"); // Flush the cache out to SPIRAM before resetting. +#if CONFIG_IDF_TARGET_ESP32 esp_psram_extram_writeback_cache(); +#else + size_t psram_alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); + uint32_t ext_noinit_size = sizeof(s_noinit_buffer); + TEST_ESP_OK(esp_cache_msync(&s_noinit_buffer, ALIGN_UP(ext_noinit_size, psram_alignment), ESP_CACHE_MSYNC_FLAG_DIR_C2M)); +#endif printf("Restarting\n"); // Reset to test that noinit memory is left intact. diff --git a/components/esp_common/test_apps/esp_common/pytest_esp_common.py b/components/esp_common/test_apps/esp_common/pytest_esp_common.py index 1a31480cc2f6..45bac32d01e5 100644 --- a/components/esp_common/test_apps/esp_common/pytest_esp_common.py +++ b/components/esp_common/test_apps/esp_common/pytest_esp_common.py @@ -1,5 +1,7 @@ # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 +from typing import Any + import pytest from pytest_embedded import Dut @@ -19,6 +21,9 @@ def test_esp_common(dut: Dut) -> None: # psram noinit attr tests with psram enabled @pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -33,6 +38,9 @@ def test_esp_attr_psram_noinit(dut: Dut) -> None: # psram noinit memory tests with psram enabled @pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.supported_targets @pytest.mark.parametrize( @@ -42,8 +50,8 @@ def test_esp_attr_psram_noinit(dut: Dut) -> None: ], indirect=True, ) -def run_multiple_stages(dut: Dut, test_case_num: int, stages: int) -> None: - dut.run_all_single_board_cases() +def test_esp_attr_psram_noinit_multiple_stages(case_tester: Any) -> None: + case_tester.run_all_multi_stage_cases() # psram attr tests with psram enabled diff --git a/components/esp_common/test_apps/esp_common/sdkconfig.ci.psram_noinit b/components/esp_common/test_apps/esp_common/sdkconfig.ci.psram_noinit index b3e109b8af4e..dbbc267982b3 100644 --- a/components/esp_common/test_apps/esp_common/sdkconfig.ci.psram_noinit +++ b/components/esp_common/test_apps/esp_common/sdkconfig.ci.psram_noinit @@ -1,6 +1,5 @@ # For EXT_RAM_NOINIT_ATTR -CONFIG_IDF_TARGET="esp32" CONFIG_SPIRAM=y CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY=y CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y diff --git a/components/esp_common/test_apps/esp_common/sdkconfig.xip_psram_esp32p4 b/components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32p4 similarity index 61% rename from components/esp_common/test_apps/esp_common/sdkconfig.xip_psram_esp32p4 rename to components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32p4 index 706f080ca94a..0d33cfbf8f43 100644 --- a/components/esp_common/test_apps/esp_common/sdkconfig.xip_psram_esp32p4 +++ b/components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32p4 @@ -3,4 +3,6 @@ CONFIG_IDF_TARGET="esp32p4" CONFIG_SPIRAM=y CONFIG_SPIRAM_XIP_FROM_PSRAM=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY=y CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y diff --git a/components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32s2 b/components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32s2 index 0e7812b975e3..fd9b7e865c3c 100644 --- a/components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32s2 +++ b/components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32s2 @@ -3,5 +3,6 @@ CONFIG_IDF_TARGET="esp32s2" CONFIG_SPIRAM=y CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY=y CONFIG_SPIRAM_RODATA=y CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y diff --git a/components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32s3 b/components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32s3 index b774ddf1fd20..3b1db1f233fd 100644 --- a/components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32s3 +++ b/components/esp_common/test_apps/esp_common/sdkconfig.ci.xip_psram_esp32s3 @@ -3,5 +3,6 @@ CONFIG_IDF_TARGET="esp32s3" CONFIG_SPIRAM=y CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY=y CONFIG_SPIRAM_RODATA=y CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y diff --git a/components/esp_driver_gptimer/CMakeLists.txt b/components/esp_driver_gptimer/CMakeLists.txt index 9b0871a8f72f..fd39190998cf 100644 --- a/components/esp_driver_gptimer/CMakeLists.txt +++ b/components/esp_driver_gptimer/CMakeLists.txt @@ -1,8 +1,13 @@ +idf_build_get_property(target IDF_TARGET) +if(${target} STREQUAL "linux") + return() # This component is not supported by the POSIX/Linux simulator +endif() + set(srcs) set(public_include "include") if(CONFIG_SOC_GPTIMER_SUPPORTED) list(APPEND srcs "src/gptimer.c" - "src/gptimer_priv.c") + "src/gptimer_common.c") endif() if(CONFIG_SOC_TIMER_SUPPORT_ETM) diff --git a/components/esp_driver_gptimer/src/gptimer.c b/components/esp_driver_gptimer/src/gptimer.c index 6fd66b9b95a3..452f4a60f067 100644 --- a/components/esp_driver_gptimer/src/gptimer.c +++ b/components/esp_driver_gptimer/src/gptimer.c @@ -17,76 +17,14 @@ #include "esp_err.h" #include "esp_log.h" #include "esp_check.h" -#include "esp_pm.h" #include "driver/gptimer.h" -#include "hal/timer_types.h" -#include "hal/timer_hal.h" -#include "hal/timer_ll.h" -#include "soc/timer_periph.h" #include "esp_memory_utils.h" -#include "esp_private/periph_ctrl.h" -#include "esp_private/esp_clk.h" -#include "clk_ctrl_os.h" -#include "esp_clk_tree.h" #include "gptimer_priv.h" -#if GPTIMER_USE_RETENTION_LINK -#include "esp_private/sleep_retention.h" -#endif - static const char *TAG = "gptimer"; -#if SOC_PERIPH_CLK_CTRL_SHARED -#define GPTIMER_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() -#else -#define GPTIMER_CLOCK_SRC_ATOMIC() -#endif - -typedef struct gptimer_platform_t { - _lock_t mutex; // platform level mutex lock - gptimer_group_t *groups[SOC_TIMER_GROUPS]; // timer group pool - int group_ref_counts[SOC_TIMER_GROUPS]; // reference count used to protect group install/uninstall -} gptimer_platform_t; - -// gptimer driver platform, it's always a singleton -static gptimer_platform_t s_platform; - -static gptimer_group_t *gptimer_acquire_group_handle(int group_id); -static void gptimer_release_group_handle(gptimer_group_t *group); -static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t src_clk, uint32_t resolution_hz); static void gptimer_default_isr(void *args); -#if GPTIMER_USE_RETENTION_LINK -static esp_err_t sleep_tg_timer_retention_link_cb(void *arg) -{ - uint32_t group_id = *(uint32_t *)arg; - esp_err_t err = sleep_retention_entries_create(tg_timer_regs_retention[group_id].link_list, - tg_timer_regs_retention[group_id].link_num, - REGDMA_LINK_PRI_6, - (group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER); - if (err == ESP_OK) { - ESP_LOGD(TAG, "Timer group %ld retention initialization", group_id); - } - ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for timer group %ld", group_id); - return err; -} - -static void gptimer_create_retention_module(gptimer_group_t *group) -{ - _lock_acquire(&s_platform.mutex); - int group_id = group->group_id; - if ((group->sleep_retention_initialized == true) && (group->retention_link_created == false)) { - esp_err_t err = sleep_retention_module_allocate((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER); - if (err != ESP_OK) { - ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for timer group %d retention, power domain can't turn off", group_id); - } else { - group->retention_link_created = true; - } - } - _lock_release(&s_platform.mutex); -} -#endif - static esp_err_t gptimer_register_to_group(gptimer_t *timer) { gptimer_group_t *group = NULL; @@ -156,6 +94,10 @@ esp_err_t gptimer_new_timer(const gptimer_config_t *config, gptimer_handle_t *re TAG, "invalid interrupt priority:%d", config->intr_priority); } +#if !SOC_TIMER_SUPPORT_SLEEP_RETENTION + ESP_RETURN_ON_FALSE(config->flags.backup_before_sleep == 0, ESP_ERR_NOT_SUPPORTED, TAG, "register back up is not supported"); +#endif // SOC_TIMER_SUPPORT_SLEEP_RETENTION + timer = heap_caps_calloc(1, sizeof(gptimer_t), GPTIMER_MEM_ALLOC_CAPS); ESP_GOTO_ON_FALSE(timer, ESP_ERR_NO_MEM, err, TAG, "no mem for gptimer"); // register timer to the group (because one group can have several timers) @@ -392,8 +334,8 @@ esp_err_t gptimer_start(gptimer_handle_t timer) // the register used by the following LL functions are shared with other API, // which is possible to run along with this function, so we need to protect portENTER_CRITICAL_SAFE(&timer->spinlock); - timer_ll_enable_counter(timer->hal.dev, timer->timer_id, true); timer_ll_enable_alarm(timer->hal.dev, timer->timer_id, timer->flags.alarm_en); + timer_ll_enable_counter(timer->hal.dev, timer->timer_id, true); portEXIT_CRITICAL_SAFE(&timer->spinlock); } else { ESP_RETURN_ON_FALSE_ISR(false, ESP_ERR_INVALID_STATE, TAG, "timer is not enabled yet"); @@ -422,172 +364,6 @@ esp_err_t gptimer_stop(gptimer_handle_t timer) return ESP_OK; } -static gptimer_group_t *gptimer_acquire_group_handle(int group_id) -{ - bool new_group = false; - gptimer_group_t *group = NULL; - - // prevent install timer group concurrently - _lock_acquire(&s_platform.mutex); - if (!s_platform.groups[group_id]) { - group = heap_caps_calloc(1, sizeof(gptimer_group_t), GPTIMER_MEM_ALLOC_CAPS); - if (group) { - new_group = true; - s_platform.groups[group_id] = group; - // initialize timer group members - group->group_id = group_id; - group->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; - } - } else { - group = s_platform.groups[group_id]; - } - if (group) { - // someone acquired the group handle means we have a new object that refer to this group - s_platform.group_ref_counts[group_id]++; - } - - if (new_group) { - // !!! HARDWARE SHARED RESOURCE !!! - // the gptimer and watchdog reside in the same the timer group - // we need to increase/decrease the reference count before enable/disable/reset the peripheral - PERIPH_RCC_ACQUIRE_ATOMIC(timer_group_periph_signals.groups[group_id].module, ref_count) { - if (ref_count == 0) { - timer_ll_enable_bus_clock(group_id, true); - timer_ll_reset_register(group_id); - } - } - ESP_LOGD(TAG, "new group (%d) @%p", group_id, group); -#if GPTIMER_USE_RETENTION_LINK - if (group->sleep_retention_initialized != true) { - sleep_retention_module_init_param_t init_param = { - .cbs = { - .create = { - .handle = sleep_tg_timer_retention_link_cb, - .arg = &group_id - }, - }, - .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) - }; - esp_err_t err = sleep_retention_module_init((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER, &init_param); - - if (err == ESP_OK) { - group->sleep_retention_initialized = true; - } else { - ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for timer group %d retention", group_id); - } - } -#endif // GPTIMER_USE_RETENTION_LINK - } - _lock_release(&s_platform.mutex); - - return group; -} - -static void gptimer_release_group_handle(gptimer_group_t *group) -{ - int group_id = group->group_id; - bool do_deinitialize = false; - - _lock_acquire(&s_platform.mutex); - s_platform.group_ref_counts[group_id]--; - if (s_platform.group_ref_counts[group_id] == 0) { - assert(s_platform.groups[group_id]); - do_deinitialize = true; - s_platform.groups[group_id] = NULL; - } - - if (do_deinitialize) { - // disable bus clock for the timer group - PERIPH_RCC_RELEASE_ATOMIC(timer_group_periph_signals.groups[group_id].module, ref_count) { - if (ref_count == 0) { - timer_ll_enable_bus_clock(group_id, false); - } - } -#if GPTIMER_USE_RETENTION_LINK - if (group->retention_link_created) { - sleep_retention_module_free((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER); - } - if (group->sleep_retention_initialized) { - sleep_retention_module_deinit((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER : SLEEP_RETENTION_MODULE_TG1_TIMER); - } -#endif - free(group); - ESP_LOGD(TAG, "del group (%d)", group_id); - } - _lock_release(&s_platform.mutex); -} - -static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t src_clk, uint32_t resolution_hz) -{ - uint32_t counter_src_hz = 0; - int timer_id = timer->timer_id; - - // TODO: [clk_tree] to use a generic clock enable/disable or acquire/release function for all clock source -#if SOC_TIMER_GROUP_SUPPORT_RC_FAST - if (src_clk == GPTIMER_CLK_SRC_RC_FAST) { - // RC_FAST clock is not enabled automatically on start up, we enable it here manually. - // Note there's a ref count in the enable/disable function, we must call them in pair in the driver. - periph_rtc_dig_clk8m_enable(); - } -#endif // SOC_TIMER_GROUP_SUPPORT_RC_FAST - - // get clock source frequency - ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)src_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &counter_src_hz), - TAG, "get clock source frequency failed"); - -#if CONFIG_PM_ENABLE - bool need_pm_lock = true; - // to make the gptimer work reliable, the source clock must stay alive and unchanged - // driver will create different pm lock for that purpose, according to different clock source - esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP; - -#if SOC_TIMER_GROUP_SUPPORT_RC_FAST - if (src_clk == GPTIMER_CLK_SRC_RC_FAST) { - // RC_FAST won't be turn off in sleep and won't change its frequency during DFS - need_pm_lock = false; - } -#endif // SOC_TIMER_GROUP_SUPPORT_RC_FAST - -#if SOC_TIMER_GROUP_SUPPORT_APB - if (src_clk == GPTIMER_CLK_SRC_APB) { - // APB clock frequency can be changed during DFS - pm_lock_type = ESP_PM_APB_FREQ_MAX; - } -#endif // SOC_TIMER_GROUP_SUPPORT_APB - -#if CONFIG_IDF_TARGET_ESP32C2 - if (src_clk == GPTIMER_CLK_SRC_PLL_F40M) { - // although PLL_F40M clock is a fixed PLL clock, which is unchangeable - // on ESP32C2, PLL_F40M can be turned off even during DFS (unlike other PLL clocks) - // so we're acquiring a fake "APB" lock here to prevent the system from doing DFS - pm_lock_type = ESP_PM_APB_FREQ_MAX; - } -#endif // CONFIG_IDF_TARGET_ESP32C2 - - if (need_pm_lock) { - sprintf(timer->pm_lock_name, "gptimer_%d_%d", timer->group->group_id, timer_id); // e.g. gptimer_0_0 - ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_lock_type, 0, timer->pm_lock_name, &timer->pm_lock), - TAG, "create pm lock failed"); - } -#endif // CONFIG_PM_ENABLE - - // !!! HARDWARE SHARED RESOURCE !!! - // on some ESP chip, different peripheral's clock source setting are mixed in the same register - // so we need to make this done in an atomic way - GPTIMER_CLOCK_SRC_ATOMIC() { - timer_ll_set_clock_source(timer->hal.dev, timer_id, src_clk); - timer_ll_enable_clock(timer->hal.dev, timer_id, true); - } - timer->clk_src = src_clk; - uint32_t prescale = counter_src_hz / resolution_hz; // potential resolution loss here - timer_ll_set_clock_prescale(timer->hal.dev, timer_id, prescale); - timer->resolution_hz = counter_src_hz / prescale; // this is the real resolution - if (timer->resolution_hz != resolution_hz) { - ESP_LOGW(TAG, "resolution lost, expect %"PRIu32", real %"PRIu32, resolution_hz, timer->resolution_hz); - } - return ESP_OK; -} - static void gptimer_default_isr(void *args) { bool need_yield = false; diff --git a/components/esp_driver_gptimer/src/gptimer_common.c b/components/esp_driver_gptimer/src/gptimer_common.c new file mode 100644 index 000000000000..ea5bf5e8c146 --- /dev/null +++ b/components/esp_driver_gptimer/src/gptimer_common.c @@ -0,0 +1,228 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_check.h" +#include "esp_clk_tree.h" +#include "esp_private/gptimer.h" +#include "gptimer_priv.h" + +static const char *TAG = "gptimer"; + +typedef struct gptimer_platform_t { + _lock_t mutex; // platform level mutex lock + gptimer_group_t *groups[SOC_TIMER_GROUPS]; // timer group pool + int group_ref_counts[SOC_TIMER_GROUPS]; // reference count used to protect group install/uninstall +} gptimer_platform_t; + +// gptimer driver platform, it's always a singleton +static gptimer_platform_t s_platform; + +#if GPTIMER_USE_RETENTION_LINK +static esp_err_t gptimer_create_sleep_retention_link_cb(void *arg) +{ + gptimer_group_t *group = (gptimer_group_t *)arg; + int group_id = group->group_id; + sleep_retention_module_t module = group->sleep_retention_module; + esp_err_t err = sleep_retention_entries_create(tg_timer_reg_retention_info[group_id].regdma_entry_array, + tg_timer_reg_retention_info[group_id].array_size, + REGDMA_LINK_PRI_GPTIMER, module); + ESP_RETURN_ON_ERROR(err, TAG, "create retention link failed"); + return ESP_OK; +} + +void gptimer_create_retention_module(gptimer_group_t *group) +{ + sleep_retention_module_t module = group->sleep_retention_module; + _lock_acquire(&s_platform.mutex); + if (group->retention_link_created == false) { + if (sleep_retention_module_allocate(module) != ESP_OK) { + // even though the sleep retention module create failed, GPTimer driver should still work, so just warning here + ESP_LOGW(TAG, "create retention module for group %d retention, power domain can't turn off", group->group_id); + } else { + group->retention_link_created = true; + } + } + _lock_release(&s_platform.mutex); +} +#endif // GPTIMER_USE_RETENTION_LINK + +gptimer_group_t *gptimer_acquire_group_handle(int group_id) +{ + bool new_group = false; + gptimer_group_t *group = NULL; + + // prevent install timer group concurrently + _lock_acquire(&s_platform.mutex); + if (!s_platform.groups[group_id]) { + group = heap_caps_calloc(1, sizeof(gptimer_group_t), GPTIMER_MEM_ALLOC_CAPS); + if (group) { + new_group = true; + s_platform.groups[group_id] = group; + // initialize timer group members + group->group_id = group_id; + group->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; + } + } else { + group = s_platform.groups[group_id]; + } + if (group) { + // someone acquired the group handle means we have a new object that refer to this group + s_platform.group_ref_counts[group_id]++; + } + _lock_release(&s_platform.mutex); + + if (new_group) { + // !!! HARDWARE SHARED RESOURCE !!! + // the gptimer and watchdog reside in the same the timer group + // we need to increase/decrease the reference count before enable/disable/reset the peripheral + PERIPH_RCC_ACQUIRE_ATOMIC(timer_group_periph_signals.groups[group_id].module, ref_count) { + if (ref_count == 0) { + timer_ll_enable_bus_clock(group_id, true); + timer_ll_reset_register(group_id); + } + } +#if GPTIMER_USE_RETENTION_LINK + sleep_retention_module_t module = TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id); + sleep_retention_module_init_param_t init_param = { + .cbs = { + .create = { + .handle = gptimer_create_sleep_retention_link_cb, + .arg = group + }, + }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + if (sleep_retention_module_init(module, &init_param) == ESP_OK) { + group->sleep_retention_module = module; + } else { + // even though the sleep retention module init failed, RMT driver should still work, so just warning here + ESP_LOGW(TAG, "init sleep retention failed %d, power domain may be turned off during sleep", group_id); + } +#endif // GPTIMER_USE_RETENTION_LINK + ESP_LOGD(TAG, "new group (%d) @%p", group_id, group); + } + + return group; +} + +void gptimer_release_group_handle(gptimer_group_t *group) +{ + int group_id = group->group_id; + bool do_deinitialize = false; + + _lock_acquire(&s_platform.mutex); + s_platform.group_ref_counts[group_id]--; + if (s_platform.group_ref_counts[group_id] == 0) { + assert(s_platform.groups[group_id]); + do_deinitialize = true; + s_platform.groups[group_id] = NULL; + } + _lock_release(&s_platform.mutex); + + if (do_deinitialize) { + // disable bus clock for the timer group + PERIPH_RCC_RELEASE_ATOMIC(timer_group_periph_signals.groups[group_id].module, ref_count) { + if (ref_count == 0) { + timer_ll_enable_bus_clock(group_id, false); + } + } +#if GPTIMER_USE_RETENTION_LINK + if (group->sleep_retention_module) { + if (group->retention_link_created) { + sleep_retention_module_free(group->sleep_retention_module); + } + sleep_retention_module_deinit(group->sleep_retention_module); + } +#endif + free(group); + ESP_LOGD(TAG, "del group (%d)", group_id); + } +} + +esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t src_clk, uint32_t resolution_hz) +{ + uint32_t counter_src_hz = 0; + int timer_id = timer->timer_id; + + // TODO: [clk_tree] to use a generic clock enable/disable or acquire/release function for all clock source +#if SOC_TIMER_GROUP_SUPPORT_RC_FAST + if (src_clk == GPTIMER_CLK_SRC_RC_FAST) { + // RC_FAST clock is not enabled automatically on start up, we enable it here manually. + // Note there's a ref count in the enable/disable function, we must call them in pair in the driver. + periph_rtc_dig_clk8m_enable(); + } +#endif // SOC_TIMER_GROUP_SUPPORT_RC_FAST + + // get clock source frequency + ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)src_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &counter_src_hz), + TAG, "get clock source frequency failed"); + +#if CONFIG_PM_ENABLE + bool need_pm_lock = true; + // to make the gptimer work reliable, the source clock must stay alive and unchanged + // driver will create different pm lock for that purpose, according to different clock source + esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP; + +#if SOC_TIMER_GROUP_SUPPORT_RC_FAST + if (src_clk == GPTIMER_CLK_SRC_RC_FAST) { + // RC_FAST won't be turn off in sleep and won't change its frequency during DFS + need_pm_lock = false; + } +#endif // SOC_TIMER_GROUP_SUPPORT_RC_FAST + +#if SOC_TIMER_GROUP_SUPPORT_APB + if (src_clk == GPTIMER_CLK_SRC_APB) { + // APB clock frequency can be changed during DFS + pm_lock_type = ESP_PM_APB_FREQ_MAX; + } +#endif // SOC_TIMER_GROUP_SUPPORT_APB + +#if CONFIG_IDF_TARGET_ESP32C2 + if (src_clk == GPTIMER_CLK_SRC_PLL_F40M) { + // although PLL_F40M clock is a fixed PLL clock, which is unchangeable + // on ESP32C2, PLL_F40M can be turned off even during DFS (unlike other PLL clocks) + // so we're acquiring a fake "APB" lock here to prevent the system from doing DFS + pm_lock_type = ESP_PM_APB_FREQ_MAX; + } +#endif // CONFIG_IDF_TARGET_ESP32C2 + + if (need_pm_lock) { + sprintf(timer->pm_lock_name, "gptimer_%d_%d", timer->group->group_id, timer_id); // e.g. gptimer_0_0 + ESP_RETURN_ON_ERROR(esp_pm_lock_create(pm_lock_type, 0, timer->pm_lock_name, &timer->pm_lock), + TAG, "create pm lock failed"); + } +#endif // CONFIG_PM_ENABLE + + // !!! HARDWARE SHARED RESOURCE !!! + // on some ESP chip, different peripheral's clock source setting are mixed in the same register + // so we need to make this done in an atomic way + GPTIMER_CLOCK_SRC_ATOMIC() { + timer_ll_set_clock_source(timer->hal.dev, timer_id, src_clk); + timer_ll_enable_clock(timer->hal.dev, timer_id, true); + } + timer->clk_src = src_clk; + uint32_t prescale = counter_src_hz / resolution_hz; // potential resolution loss here + timer_ll_set_clock_prescale(timer->hal.dev, timer_id, prescale); + timer->resolution_hz = counter_src_hz / prescale; // this is the real resolution + if (timer->resolution_hz != resolution_hz) { + ESP_LOGW(TAG, "resolution lost, expect %"PRIu32", real %"PRIu32, resolution_hz, timer->resolution_hz); + } + return ESP_OK; +} + +esp_err_t gptimer_get_intr_handle(gptimer_handle_t timer, intr_handle_t *ret_intr_handle) +{ + ESP_RETURN_ON_FALSE(timer && ret_intr_handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + *ret_intr_handle = timer->intr; + return ESP_OK; +} + +esp_err_t gptimer_get_pm_lock(gptimer_handle_t timer, esp_pm_lock_handle_t *ret_pm_lock) +{ + ESP_RETURN_ON_FALSE(timer && ret_pm_lock, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + *ret_pm_lock = timer->pm_lock; + return ESP_OK; +} diff --git a/components/esp_driver_gptimer/src/gptimer_priv.c b/components/esp_driver_gptimer/src/gptimer_priv.c deleted file mode 100644 index bd834f20145c..000000000000 --- a/components/esp_driver_gptimer/src/gptimer_priv.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "esp_check.h" -#include "esp_private/gptimer.h" -#include "gptimer_priv.h" - -static const char *TAG = "gptimer"; - -esp_err_t gptimer_get_intr_handle(gptimer_handle_t timer, intr_handle_t *ret_intr_handle) -{ - ESP_RETURN_ON_FALSE(timer && ret_intr_handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - *ret_intr_handle = timer->intr; - return ESP_OK; -} - -esp_err_t gptimer_get_pm_lock(gptimer_handle_t timer, esp_pm_lock_handle_t *ret_pm_lock) -{ - ESP_RETURN_ON_FALSE(timer && ret_pm_lock, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - *ret_pm_lock = timer->pm_lock; - return ESP_OK; -} diff --git a/components/esp_driver_gptimer/src/gptimer_priv.h b/components/esp_driver_gptimer/src/gptimer_priv.h index fe072c85d43a..3c117af44f9d 100644 --- a/components/esp_driver_gptimer/src/gptimer_priv.h +++ b/components/esp_driver_gptimer/src/gptimer_priv.h @@ -9,13 +9,19 @@ #include #include #include "sdkconfig.h" +#include "soc/soc_caps.h" #include "freertos/FreeRTOS.h" #include "esp_err.h" #include "esp_intr_alloc.h" #include "esp_heap_caps.h" +#include "clk_ctrl_os.h" #include "esp_pm.h" -#include "soc/soc_caps.h" +#include "soc/timer_periph.h" +#include "hal/timer_types.h" #include "hal/timer_hal.h" +#include "hal/timer_ll.h" +#include "esp_private/sleep_retention.h" +#include "esp_private/periph_ctrl.h" #ifdef __cplusplus extern "C" { @@ -41,6 +47,12 @@ extern "C" { #define GPTIMER_USE_RETENTION_LINK (SOC_TIMER_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP) +#if SOC_PERIPH_CLK_CTRL_SHARED +#define GPTIMER_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define GPTIMER_CLOCK_SRC_ATOMIC() +#endif + typedef struct gptimer_t gptimer_t; typedef struct gptimer_group_t { @@ -48,8 +60,8 @@ typedef struct gptimer_group_t { portMUX_TYPE spinlock; // to protect per-group register level concurrent access gptimer_t *timers[SOC_TIMER_GROUP_TIMERS_PER_GROUP]; #if GPTIMER_USE_RETENTION_LINK - bool sleep_retention_initialized; // mark if the retention link is initialized - bool retention_link_created; // mark if the retention link is created + sleep_retention_module_t sleep_retention_module; // sleep retention module + bool retention_link_created; // mark if the retention link is created #endif } gptimer_group_t; @@ -87,6 +99,11 @@ struct gptimer_t { } flags; }; +gptimer_group_t *gptimer_acquire_group_handle(int group_id); +void gptimer_release_group_handle(gptimer_group_t *group); +esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_source_t src_clk, uint32_t resolution_hz); +void gptimer_create_retention_module(gptimer_group_t *group); + #ifdef __cplusplus } #endif diff --git a/components/esp_driver_gptimer/test_apps/gptimer/main/CMakeLists.txt b/components/esp_driver_gptimer/test_apps/gptimer/main/CMakeLists.txt index 2768a1f04e1c..39337b4ce696 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/main/CMakeLists.txt +++ b/components/esp_driver_gptimer/test_apps/gptimer/main/CMakeLists.txt @@ -5,6 +5,10 @@ if(CONFIG_GPTIMER_ISR_IRAM_SAFE) list(APPEND srcs "test_gptimer_iram.c") endif() +if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED AND CONFIG_PM_ENABLE) + list(APPEND srcs "test_gptimer_sleep.c") +endif() + # In order for the cases defined by `TEST_CASE` to be linked into the final elf, # the component can be registered as WHOLE_ARCHIVE idf_component_register(SRCS ${srcs} diff --git a/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c index 4d3e6b49878c..757c2f715c1c 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c +++ b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c @@ -13,15 +13,6 @@ #include "soc/soc_caps.h" #include "esp_attr.h" -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION -#include "esp_random.h" -#include "esp_rom_uart.h" -#include "esp_sleep.h" -#include "esp_private/esp_sleep_internal.h" -#include "esp_private/sleep_cpu.h" -#include "esp_private/esp_pmu.h" -#endif - #if CONFIG_GPTIMER_ISR_IRAM_SAFE #define TEST_ALARM_CALLBACK_ATTR IRAM_ATTR #else @@ -605,82 +596,3 @@ TEST_CASE("gptimer_trig_alarm_with_old_count", "[gptimer]") TEST_ESP_OK(gptimer_disable(timer)); TEST_ESP_OK(gptimer_del_timer(timer)); } - -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && SOC_TIMER_SUPPORT_SLEEP_RETENTION -static gptimer_handle_t timers[SOC_TIMER_GROUP_TOTAL_TIMERS]; -static uint32_t timer_resolution_hz[SOC_TIMER_GROUP_TOTAL_TIMERS]; - -static void test_gptimer_retention(gptimer_config_t *timer_config) -{ - for (int i = 0; i < SOC_TIMER_GROUP_TOTAL_TIMERS; i++) { - TEST_ESP_OK(gptimer_new_timer(timer_config, &timers[i])); - TEST_ESP_OK(gptimer_get_resolution(timers[i], &timer_resolution_hz[i])); - - unsigned long long count_start_value = 0, count_end_value = 0; - - // Let gptimer run for a while - TEST_ESP_OK(gptimer_enable(timers[i])); - TEST_ESP_OK(gptimer_start(timers[i])); - vTaskDelay((esp_random() % 500) / portTICK_PERIOD_MS); - TEST_ESP_OK(gptimer_stop(timers[i])); - TEST_ESP_OK(gptimer_disable(timers[i])); - TEST_ESP_OK(gptimer_get_raw_count(timers[i], &count_start_value)); - - esp_sleep_context_t sleep_ctx; - esp_sleep_set_sleep_context(&sleep_ctx); - TEST_ESP_OK(sleep_cpu_configure(true)); - esp_rom_output_tx_wait_idle(0); - esp_sleep_enable_timer_wakeup(50 * 1000); - esp_light_sleep_start(); - - if (timer_config->flags.backup_before_sleep) { - TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); - } else { - TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); - } - - TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); - - TEST_ESP_OK(gptimer_enable(timers[i])); - TEST_ESP_OK(gptimer_start(timers[i])); - - uint32_t random_time_ms = 500 + esp_random() % 2000; - vTaskDelay(random_time_ms / portTICK_PERIOD_MS); - TEST_ESP_OK(gptimer_get_raw_count(timers[i], &count_end_value)); - - // Error tolerance is 2% - TEST_ASSERT_UINT_WITHIN(random_time_ms / 50, random_time_ms, 1000 * (count_end_value - count_start_value) / (unsigned long long)timer_resolution_hz[i]); - - TEST_ESP_OK(gptimer_stop(timers[i])); - TEST_ESP_OK(gptimer_disable(timers[i])); - TEST_ESP_OK(gptimer_del_timer(timers[i])); - TEST_ESP_OK(sleep_cpu_configure(false)); - } -} - -TEST_CASE("gptimer context kept after peripheral powerdown lightsleep with backup_before_sleep enable", "[gptimer]") -{ - printf("install gptimer driver\r\n"); - gptimer_config_t timer_config = { - .resolution_hz = 10 * 1000, // 10KHz, 1 tick = 0.1ms - .clk_src = GPTIMER_CLK_SRC_DEFAULT, - .direction = GPTIMER_COUNT_UP, - .flags.backup_before_sleep = true - }; - - test_gptimer_retention(&timer_config); -} - -TEST_CASE("gptimer context kept after peripheral powerdown lightsleep with backup_before_sleep disable", "[gptimer]") -{ - printf("install gptimer driver\r\n"); - gptimer_config_t timer_config = { - .resolution_hz = 10 * 1000, // 10KHz, 1 tick = 0.1ms - .clk_src = GPTIMER_CLK_SRC_DEFAULT, - .direction = GPTIMER_COUNT_UP, - .flags.backup_before_sleep = false - }; - - test_gptimer_retention(&timer_config); -} -#endif diff --git a/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c new file mode 100644 index 000000000000..5e2e457bedcc --- /dev/null +++ b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_sleep.c @@ -0,0 +1,120 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "unity.h" +#include "driver/gptimer.h" +#include "soc/soc_caps.h" +#include "esp_sleep.h" +#include "esp_private/sleep_cpu.h" +#include "esp_private/esp_sleep_internal.h" +#include "esp_private/esp_pmu.h" + +static bool test_gptimer_alarm_stop_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data) +{ + TaskHandle_t task_handle = (TaskHandle_t)user_data; + BaseType_t high_task_wakeup; + gptimer_stop(timer); + vTaskNotifyGiveFromISR(task_handle, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +/** + * @brief Test the GPTimer driver can still work after light sleep + * + * @param back_up_before_sleep Whether to back up GPTimer registers before sleep + */ +static void test_gptimer_sleep_retention(bool back_up_before_sleep) +{ + TaskHandle_t task_handle = xTaskGetCurrentTaskHandle(); + gptimer_config_t timer_config = { + .resolution_hz = 10000, // 10KHz, 1 tick = 0.1ms + .clk_src = GPTIMER_CLK_SRC_DEFAULT, + .direction = GPTIMER_COUNT_UP, + .flags.backup_before_sleep = back_up_before_sleep, + }; + gptimer_handle_t timer = NULL; + TEST_ESP_OK(gptimer_new_timer(&timer_config, &timer)); + gptimer_event_callbacks_t cbs = { + .on_alarm = test_gptimer_alarm_stop_callback, + }; + TEST_ESP_OK(gptimer_register_event_callbacks(timer, &cbs, task_handle)); + + gptimer_alarm_config_t alarm_config = { + .alarm_count = 10000, // alarm period = 1s + .reload_count = 5000, + .flags.auto_reload_on_alarm = true, + }; + TEST_ESP_OK(gptimer_set_alarm_action(timer, &alarm_config)); + + TEST_ESP_OK(gptimer_enable(timer)); + TEST_ESP_OK(gptimer_start(timer)); + + /// counting from 0 to 10000, it's about 1 second + TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(1100))); + uint64_t count_value_before_sleep = 0; + TEST_ESP_OK(gptimer_get_raw_count(timer, &count_value_before_sleep)); + printf("count value before sleep: %llu\n", count_value_before_sleep); + // the count value should near the reload value + TEST_ASSERT_INT_WITHIN(1, 5000, count_value_before_sleep); + + // Note: don't enable the gptimer before going to sleep, ensure no power management lock is acquired by it + TEST_ESP_OK(gptimer_disable(timer)); + + esp_sleep_context_t sleep_ctx; + esp_sleep_set_sleep_context(&sleep_ctx); + printf("go to light sleep for 2 seconds\r\n"); +#if ESP_SLEEP_POWER_DOWN_CPU + TEST_ESP_OK(sleep_cpu_configure(true)); +#endif + TEST_ESP_OK(esp_sleep_enable_timer_wakeup(2 * 1000 * 1000)); + TEST_ESP_OK(esp_light_sleep_start()); + + printf("Waked up! Let's see if GPTimer driver can still work...\r\n"); +#if ESP_SLEEP_POWER_DOWN_CPU + TEST_ESP_OK(sleep_cpu_configure(false)); +#endif + + printf("check if the sleep happened as expected\r\n"); + TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); +#if SOC_TIMER_SUPPORT_SLEEP_RETENTION + if (back_up_before_sleep) { + TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); + } +#endif + esp_sleep_set_sleep_context(NULL); + + uint64_t count_value_after_sleep = 0; + TEST_ESP_OK(gptimer_get_raw_count(timer, &count_value_after_sleep)); + printf("count value after sleep wakeup: %llu\n", count_value_after_sleep); + TEST_ASSERT_EQUAL(count_value_before_sleep, count_value_after_sleep); + + // re-enable the timer and start it + TEST_ESP_OK(gptimer_enable(timer)); + TEST_ESP_OK(gptimer_start(timer)); + + /// this time, the timer should count from 5000 to 10000, it's about 0.5 second + TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdFALSE, pdMS_TO_TICKS(600))); + + TEST_ESP_OK(gptimer_get_raw_count(timer, &count_value_after_sleep)); + printf("gptimer count value: %llu\n", count_value_after_sleep); + // the count value should near the reload value + TEST_ASSERT_INT_WITHIN(1, 5000, count_value_after_sleep); + + TEST_ESP_OK(gptimer_disable(timer)); + TEST_ESP_OK(gptimer_del_timer(timer)); +} + +TEST_CASE("gptimer can work after light sleep", "[gptimer]") +{ + test_gptimer_sleep_retention(false); +#if SOC_TIMER_SUPPORT_SLEEP_RETENTION + test_gptimer_sleep_retention(true); +#endif +} diff --git a/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release index 05634936f485..1a87ebbb4af5 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release +++ b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release @@ -1,9 +1,7 @@ CONFIG_PM_ENABLE=y CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y CONFIG_PM_DFS_INIT_AUTO=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y -# For TASK WDT timer PD_TOP sleep retention test -CONFIG_ESP_SLEEP_DEBUG=y -CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y diff --git a/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.defaults b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.defaults index 1d96fcebe1f9..f365803cb010 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.defaults +++ b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.defaults @@ -5,3 +5,6 @@ CONFIG_FREERTOS_HZ=1000 # Disable nano printf, because we need to print the timer count in %llu format CONFIG_NEWLIB_NANO_FORMAT=n + +# primitives for checking sleep internal state +CONFIG_ESP_SLEEP_DEBUG=y diff --git a/components/esp_driver_i2s/i2s_common.c b/components/esp_driver_i2s/i2s_common.c index 55bb984661d4..e4b63a05f39e 100644 --- a/components/esp_driver_i2s/i2s_common.c +++ b/components/esp_driver_i2s/i2s_common.c @@ -25,6 +25,7 @@ #include "soc/soc_caps.h" #include "hal/gpio_hal.h" #include "hal/i2s_hal.h" +#include "hal/dma_types.h" #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #include "hal/cache_hal.h" #include "hal/cache_ll.h" @@ -62,8 +63,12 @@ #include "esp_memory_utils.h" /* The actual max size of DMA buffer is 4095 - * Set 4092 here to align with 4-byte, so that the position of the slot data in the buffer will be relatively fixed */ -#define I2S_DMA_BUFFER_MAX_SIZE (4092) + * Reserve several bytes for alignment, so that the position of the slot data in the buffer will be relatively fixed */ +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#define I2S_DMA_BUFFER_MAX_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_64B_ALIGNED +#else +#define I2S_DMA_BUFFER_MAX_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED +#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE static const char *TAG = "i2s_common"; @@ -357,7 +362,7 @@ uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uin for (int sign = 1; bufsize % alignment != 0; aligned_frame_num += sign) { bufsize = aligned_frame_num * bytes_per_frame; /* If the buffer size exceed the max dma size */ - if (bufsize > I2S_DMA_BUFFER_MAX_SIZE) { + if (bufsize > I2S_DMA_BUFFER_MAX_SIZE && sign == 1) { sign = -1; // toggle the search sign aligned_frame_num = dma_frame_num; // Reset the frame num bufsize = aligned_frame_num * bytes_per_frame; // Reset the bufsize @@ -368,7 +373,7 @@ uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uin ", bufsize = %"PRIu32, bufsize / bytes_per_frame, alignment, bufsize); } #endif - /* Limit DMA buffer size if it is out of range (DMA buffer limitation is 4092 bytes) */ + /* Limit DMA buffer size if it is out of range */ if (bufsize > I2S_DMA_BUFFER_MAX_SIZE) { uint32_t frame_num = I2S_DMA_BUFFER_MAX_SIZE / bytes_per_frame; bufsize = frame_num * bytes_per_frame; diff --git a/components/esp_driver_i2s/i2s_std.c b/components/esp_driver_i2s/i2s_std.c index c3ef0c0469c3..109aaa0bc51f 100644 --- a/components/esp_driver_i2s/i2s_std.c +++ b/components/esp_driver_i2s/i2s_std.c @@ -39,6 +39,9 @@ static esp_err_t i2s_std_calculate_clock(i2s_chan_handle_t handle, const i2s_std 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; + if (clk_info->mclk % clk_info->bclk != 0) { + ESP_LOGW(TAG, "the current mclk multiple cannot perform integer division (slot_num: %"PRIu32", slot_bits: %"PRIu32")", handle->total_slot, slot_bits); + } } else { /* For slave mode, mclk >= bclk * 8, so fix bclk_div to 2 first */ clk_info->bclk_div = 8; diff --git a/components/esp_driver_i2s/i2s_tdm.c b/components/esp_driver_i2s/i2s_tdm.c index 584e75881cf2..6d579105ed57 100644 --- a/components/esp_driver_i2s/i2s_tdm.c +++ b/components/esp_driver_i2s/i2s_tdm.c @@ -46,6 +46,9 @@ static esp_err_t i2s_tdm_calculate_clock(i2s_chan_handle_t handle, const i2s_tdm clk_info->mclk = clk_info->bclk * clk_info->bclk_div; ESP_LOGW(TAG, "the current mclk multiple is too small, adjust the mclk multiple to %"PRIu32, clk_info->mclk / rate); } + if (clk_info->mclk % clk_info->bclk != 0) { + ESP_LOGW(TAG, "the current mclk multiple cannot perform integer division (slot_num: %"PRIu32", slot_bits: %"PRIu32")", handle->total_slot, slot_bits); + } } else { if (clk_cfg->bclk_div < 8) { ESP_LOGW(TAG, "the current bclk division is too small, adjust the bclk division to 8"); 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 93aca31233a7..6a1f7d302d30 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 @@ -14,6 +14,7 @@ #include "sdkconfig.h" #include "driver/gpio.h" #include "hal/gpio_hal.h" +#include "hal/dma_types.h" #include "esp_err.h" #include "esp_attr.h" #include "unity.h" @@ -866,17 +867,25 @@ TEST_CASE("I2S_package_lost_test", "[i2s]") { /* Steps of calculate appropriate parameters of I2S buffer: * Known by user: sample_rate = 144k, data_bit_width = 32, slot_num = 2, polling_cycle = 10 ms - * 1. dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092 - * dma_frame_num <= 511, dma_frame_num is as big as possible. + * 1. dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= DMA_MAX_ALIGNED_SIZE + * dma_frame_num <= DMA_MAX_ALIGNED_SIZE / data_bit_width / slot_num * 8, dma_frame_num is as big as possible. * interrupt_interval = dma_frame_num / sample_rate = 3.549 ms * 2. dma_desc_num > polling_cycle / interrupt_interval = cell(2.818) = 3 - * 3. recv_buffer_size > dma_desc_num * dma_buffer_size = 3 * 4092 = 12276 bytes */ -#define TEST_RECV_BUF_LEN 12276 + * 3. recv_buffer_size > dma_desc_num * dma_buffer_size = 3 * DMA_MAX_ALIGNED_SIZE */ +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#define TEST_RECV_BUF_LEN (3 * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_64B_ALIGNED) +#else +#define TEST_RECV_BUF_LEN (3 * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) +#endif i2s_chan_handle_t rx_handle; i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); chan_cfg.dma_desc_num = 3; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + chan_cfg.dma_frame_num = 504; +#else chan_cfg.dma_frame_num = 511; +#endif i2s_std_config_t std_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), .slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO), diff --git a/components/esp_driver_mcpwm/include/driver/mcpwm_cap.h b/components/esp_driver_mcpwm/include/driver/mcpwm_cap.h index a32cfe40f414..6e2808608763 100644 --- a/components/esp_driver_mcpwm/include/driver/mcpwm_cap.h +++ b/components/esp_driver_mcpwm/include/driver/mcpwm_cap.h @@ -138,7 +138,7 @@ typedef struct { uint32_t prescale; /*!< Prescale of input signal, effective frequency = cap_input_clk/prescale */ /// Extra configuration flags for capture channel - struct extra_flags { + struct extra_capture_channel_flags { uint32_t pos_edge: 1; /*!< Whether to capture on positive edge */ uint32_t neg_edge: 1; /*!< Whether to capture on negative edge */ uint32_t pull_up: 1; /*!< Whether to pull up internally */ diff --git a/components/esp_driver_parlio/CMakeLists.txt b/components/esp_driver_parlio/CMakeLists.txt index 92a79049030b..d32994664dee 100644 --- a/components/esp_driver_parlio/CMakeLists.txt +++ b/components/esp_driver_parlio/CMakeLists.txt @@ -1,3 +1,8 @@ +idf_build_get_property(target IDF_TARGET) +if(${target} STREQUAL "linux") + return() # This component is not supported by the POSIX/Linux simulator +endif() + set(srcs) set(public_include "include") if(CONFIG_SOC_PARLIO_SUPPORTED) @@ -9,4 +14,5 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${public_include} PRIV_REQUIRES "esp_pm" "esp_driver_gpio" "esp_mm" + LDFRAGMENTS "linker.lf" ) diff --git a/components/esp_driver_parlio/linker.lf b/components/esp_driver_parlio/linker.lf new file mode 100644 index 000000000000..ecc7aa03721a --- /dev/null +++ b/components/esp_driver_parlio/linker.lf @@ -0,0 +1,6 @@ +[mapping:parlio_driver_gdma] +archive: libesp_hw_support.a +entries: + if PARLIO_ISR_IRAM_SAFE: + gdma_link: gdma_link_mount_buffers (noflash) + gdma_link: gdma_link_get_head_addr (noflash) diff --git a/components/esp_driver_parlio/src/parlio_private.h b/components/esp_driver_parlio/src/parlio_private.h index d728359b09eb..b33cace1a357 100644 --- a/components/esp_driver_parlio/src/parlio_private.h +++ b/components/esp_driver_parlio/src/parlio_private.h @@ -64,13 +64,6 @@ typedef dma_descriptor_align8_t parlio_dma_desc_t; #define PARLIO_MAX_ALIGNED_DMA_BUF_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED #endif -#ifdef CACHE_LL_L2MEM_NON_CACHE_ADDR -/* The descriptor address can be mapped by a fixed offset */ -#define PARLIO_GET_NON_CACHED_DESC_ADDR(desc) (desc ? (parlio_dma_desc_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(desc)) : NULL) -#else -#define PARLIO_GET_NON_CACHED_DESC_ADDR(desc) (desc) -#endif // CACHE_LL_L2MEM_NON_CACHE_ADDR - #if SOC_PERIPH_CLK_CTRL_SHARED #define PARLIO_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() #else diff --git a/components/esp_driver_parlio/src/parlio_tx.c b/components/esp_driver_parlio/src/parlio_tx.c index e27e2de320d5..2b94937c5a65 100644 --- a/components/esp_driver_parlio/src/parlio_tx.c +++ b/components/esp_driver_parlio/src/parlio_tx.c @@ -34,6 +34,7 @@ #include "esp_memory_utils.h" #include "esp_clk_tree.h" #include "esp_private/gdma.h" +#include "esp_private/gdma_link.h" static const char *TAG = "parlio-tx"; @@ -49,8 +50,7 @@ typedef struct parlio_tx_unit_t { intr_handle_t intr; // allocated interrupt handle esp_pm_lock_handle_t pm_lock; // power management lock gdma_channel_handle_t dma_chan; // DMA channel - parlio_dma_desc_t *dma_nodes; // DMA descriptor nodes - parlio_dma_desc_t *dma_nodes_nc;// non-cached DMA descriptor nodes + gdma_link_list_handle_t dma_link; // DMA link list handle size_t dma_nodes_num; // number of DMA descriptor nodes #if CONFIG_PM_ENABLE char pm_lock_name[PARLIO_PM_LOCK_NAME_LEN_MAX]; // pm lock name @@ -123,8 +123,8 @@ static esp_err_t parlio_destroy_tx_unit(parlio_tx_unit_t *tx_unit) // de-register from group parlio_unregister_unit_from_group(&tx_unit->base); } - if (tx_unit->dma_nodes) { - free(tx_unit->dma_nodes); + if (tx_unit->dma_link) { + ESP_RETURN_ON_ERROR(gdma_del_link_list(tx_unit->dma_link), TAG, "delete dma link list failed"); } free(tx_unit); return ESP_OK; @@ -191,11 +191,19 @@ static esp_err_t parlio_tx_unit_init_dma(parlio_tx_unit_t *tx_unit) }; gdma_apply_strategy(tx_unit->dma_chan, &gdma_strategy_conf); - // Link the descriptors + // create DMA link list size_t dma_nodes_num = tx_unit->dma_nodes_num; - for (int i = 0; i < dma_nodes_num; i++) { - tx_unit->dma_nodes_nc[i].next = (i == dma_nodes_num - 1) ? NULL : &(tx_unit->dma_nodes[i + 1]); - } + gdma_link_list_config_t dma_link_config = { + .buffer_alignment = 1, + .item_alignment = PARLIO_DMA_DESC_ALIGNMENT, + .num_items = dma_nodes_num, + .flags = { + .check_owner = true, + }, + }; + + // throw the error to the caller + ESP_RETURN_ON_ERROR(gdma_new_link_list(&dma_link_config, &tx_unit->dma_link), TAG, "create DMA link list failed"); return ESP_OK; } @@ -280,26 +288,9 @@ esp_err_t parlio_new_tx_unit(const parlio_tx_unit_config_t *config, parlio_tx_un // create DMA descriptors // DMA descriptors must be placed in internal SRAM - mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA; size_t dma_nodes_num = config->max_transfer_size / DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1; - uint32_t data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); - // the alignment should meet both the DMA and cache requirement - size_t alignment = MAX(data_cache_line_size, PARLIO_DMA_DESC_ALIGNMENT); - size_t dma_nodes_mem_size = ALIGN_UP(dma_nodes_num * sizeof(parlio_dma_desc_t), alignment); - parlio_dma_desc_t *dma_nodes = heap_caps_aligned_calloc(alignment, 1, dma_nodes_mem_size, mem_caps); - ESP_GOTO_ON_FALSE(dma_nodes, ESP_ERR_NO_MEM, err, TAG, "no memory for DMA nodes"); - unit->dma_nodes = dma_nodes; unit->dma_nodes_num = dma_nodes_num; - // write back and then invalidate the cached dma_nodes, we will skip the cache (by non-cacheable address) when access the dma_nodes - if (data_cache_line_size) { - ESP_GOTO_ON_ERROR(esp_cache_msync(dma_nodes, dma_nodes_mem_size, - ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_INVALIDATE), - err, TAG, "cache sync failed"); - } - // we will use the non-cached address to manipulate the DMA descriptor, for simplicity - unit->dma_nodes_nc = PARLIO_GET_NON_CACHED_DESC_ADDR(dma_nodes); - unit->max_transfer_bits = config->max_transfer_size * 8; unit->base.dir = PARLIO_DIR_TX; unit->data_width = data_width; @@ -385,27 +376,6 @@ esp_err_t parlio_del_tx_unit(parlio_tx_unit_handle_t unit) return parlio_destroy_tx_unit(unit); } -static void IRAM_ATTR parlio_tx_mount_dma_data(parlio_tx_unit_t *tx_unit, const void *buffer, size_t len) -{ - size_t prepared_length = 0; - uint8_t *data = (uint8_t *)buffer; - uint32_t mount_bytes = 0; - parlio_dma_desc_t *desc_nc = tx_unit->dma_nodes_nc; - - while (len) { - assert(desc_nc); - mount_bytes = len > PARLIO_MAX_ALIGNED_DMA_BUF_SIZE ? PARLIO_MAX_ALIGNED_DMA_BUF_SIZE : len; - len -= mount_bytes; - desc_nc->dw0.suc_eof = (len == 0); // whether the last frame - desc_nc->dw0.size = mount_bytes; - desc_nc->dw0.length = mount_bytes; - desc_nc->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - desc_nc->buffer = &data[prepared_length]; - desc_nc = PARLIO_GET_NON_CACHED_DESC_ADDR(desc_nc->next); - prepared_length += mount_bytes; - } -} - esp_err_t parlio_tx_unit_wait_all_done(parlio_tx_unit_handle_t tx_unit, int timeout_ms) { ESP_RETURN_ON_FALSE(tx_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); @@ -448,7 +418,15 @@ static void IRAM_ATTR parlio_tx_do_transaction(parlio_tx_unit_t *tx_unit, parlio tx_unit->cur_trans = t; // DMA transfer data based on bytes not bits, so convert the bit length to bytes, round up - parlio_tx_mount_dma_data(tx_unit, t->payload, (t->payload_bits + 7) / 8); + gdma_buffer_mount_config_t mount_config = { + .buffer = (void *)t->payload, + .length = (t->payload_bits + 7) / 8, + .flags = { + .mark_eof = true, + .mark_final = true, // singly link list, mark final descriptor + } + }; + gdma_link_mount_buffers(tx_unit->dma_link, 0, &mount_config, 1, NULL); parlio_ll_tx_reset_fifo(hal->regs); PARLIO_RCC_ATOMIC() { @@ -457,7 +435,7 @@ static void IRAM_ATTR parlio_tx_do_transaction(parlio_tx_unit_t *tx_unit, parlio parlio_ll_tx_set_idle_data_value(hal->regs, t->idle_value); parlio_ll_tx_set_trans_bit_len(hal->regs, t->payload_bits); - gdma_start(tx_unit->dma_chan, (intptr_t)tx_unit->dma_nodes); + gdma_start(tx_unit->dma_chan, gdma_link_get_head_addr(tx_unit->dma_link)); // wait until the data goes from the DMA to TX unit's FIFO while (parlio_ll_tx_is_ready(hal->regs) == false); // turn on the core clock after we start the TX unit diff --git a/components/esp_driver_rmt/include/driver/rmt_rx.h b/components/esp_driver_rmt/include/driver/rmt_rx.h index 243facf68f10..fdff6e456cc0 100644 --- a/components/esp_driver_rmt/include/driver/rmt_rx.h +++ b/components/esp_driver_rmt/include/driver/rmt_rx.h @@ -53,7 +53,7 @@ typedef struct { uint32_t signal_range_max_ns; /*!< RMT will stop receiving if one symbol level has kept more than `signal_range_max_ns` */ /// Receive specific flags - struct extra_flags { + struct extra_rmt_receive_flags { uint32_t en_partial_rx: 1; /*!< Set this flag if the incoming data is very long, and the driver can only receive the data piece by piece, because the user buffer is not sufficient to save all the data. */ } flags; /*!< Receive specific config flags */ diff --git a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/sdmmc_test_boards/Kconfig.projbuild b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/sdmmc_test_boards/Kconfig.projbuild index 49c0422d5a98..ab19c578a395 100644 --- a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/sdmmc_test_boards/Kconfig.projbuild +++ b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/sdmmc_test_boards/Kconfig.projbuild @@ -33,6 +33,10 @@ menu "SDMMC Test Board Configuration" bool "ESP32-P4 Function EV Board" depends on IDF_TARGET_ESP32P4 + config SDMMC_BOARD_ESP32P4_EV_BOARD_WITH_SDSPI + bool "ESP32-P4 Function EV Board with SDSPI breakout" + depends on IDF_TARGET_ESP32P4 + config SDMMC_BOARD_CUSTOM_SD depends on SOC_SDMMC_HOST_SUPPORTED bool "Custom SD (choose pins)" @@ -133,6 +137,8 @@ menu "SDMMC Test Board Configuration" config SDMMC_BOARD_CUSTOM_UNUSED int "GPIO not routed on the board" + default 34 if IDF_TARGET_ESP32P4 + default 8 if IDF_TARGET_ESP32C5 default -1 endmenu diff --git a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/sdmmc_test_boards/sdmmc_test_board_defs.c b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/sdmmc_test_boards/sdmmc_test_board_defs.c index 57079e3082d2..8cd43b7c51ae 100644 --- a/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/sdmmc_test_boards/sdmmc_test_board_defs.c +++ b/components/esp_driver_sdmmc/test_apps/sd_test_utils/components/sdmmc_test_boards/sdmmc_test_board_defs.c @@ -346,6 +346,34 @@ static const sdmmc_test_board_info_t s_board_info = { }, }; +#elif CONFIG_SDMMC_BOARD_ESP32P4_EV_BOARD_WITH_SDSPI + +static const sdmmc_test_board_info_t s_board_info = { + .name = "ESP32-P4 Function EV Board with SDSPI breakout", + .slot = { + { + .slot_exists = false + }, + { + .slot_exists = true, + .bus_width = 1, + .clk = 53, + .cmd_mosi = 36, + .d0_miso = 47, + .d1 = GPIO_NUM_NC, + .d2 = GPIO_NUM_NC, + .d3_cs = 33, + .d4 = GPIO_NUM_NC, + .d5 = GPIO_NUM_NC, + .d6 = GPIO_NUM_NC, + .d7 = GPIO_NUM_NC, + .cd = CONFIG_SDMMC_BOARD_CUSTOM_CD, + .wp = CONFIG_SDMMC_BOARD_CUSTOM_WP, + .unused_pin = CONFIG_SDMMC_BOARD_CUSTOM_UNUSED, + } + }, +}; + #elif CONFIG_SDMMC_BOARD_CUSTOM_SD static const sdmmc_test_board_info_t s_board_info = { diff --git a/components/esp_driver_sdspi/include/driver/sdspi_host.h b/components/esp_driver_sdspi/include/driver/sdspi_host.h index 85657a3ccb6f..0c7ac15371cd 100644 --- a/components/esp_driver_sdspi/include/driver/sdspi_host.h +++ b/components/esp_driver_sdspi/include/driver/sdspi_host.h @@ -54,6 +54,8 @@ typedef int sdspi_dev_handle_t; .get_real_freq = &sdspi_host_get_real_freq, \ .input_delay_phase = SDMMC_DELAY_PHASE_0, \ .set_input_delay = NULL, \ + .dma_aligned_buffer = NULL, \ + .pwr_ctrl_handle = NULL, \ .get_dma_info = &sdspi_host_get_dma_info, \ } diff --git a/components/esp_driver_sdspi/test_apps/.build-test-rules.yml b/components/esp_driver_sdspi/test_apps/.build-test-rules.yml index 9c1df73b2665..cc77e504728e 100644 --- a/components/esp_driver_sdspi/test_apps/.build-test-rules.yml +++ b/components/esp_driver_sdspi/test_apps/.build-test-rules.yml @@ -2,9 +2,8 @@ components/esp_driver_sdspi/test_apps/sdspi: disable: - if: SOC_GPSPI_SUPPORTED != 1 disable_test: - - if: SOC_GPSPI_SUPPORTED == 1 - temporary: true - reason: will add runners later # TODO: IDF-8747 + - if: IDF_TARGET not in ["esp32", "esp32s3", "esp32c3", "esp32p4"] + reason: needs special runner, select few typical targets for testing depends_components: - sdmmc - esp_driver_sdspi diff --git a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_cd_wp_spi.c b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_cd_wp_spi.c index 1787758eccf1..6a882ef2d132 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_cd_wp_spi.c +++ b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_cd_wp_spi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,8 @@ #include "sdmmc_test_board.h" #include "sdmmc_test_begin_end_spi.h" #include "sdmmc_test_cd_wp_common.h" +#include "sd_pwr_ctrl.h" +#include "sd_pwr_ctrl_by_on_chip_ldo.h" TEST_CASE("CD input works in SPI mode", "[sdspi]") { @@ -22,6 +24,18 @@ TEST_CASE("CD input works in SPI mode", "[sdspi]") sdmmc_test_board_get_config_sdspi(slot, &config, &bus_config, &dev_config); const int test_gpio = sdmmc_test_board_get_slot_info(slot)->unused_pin; dev_config.gpio_cd = test_gpio; + +#if SOC_SDMMC_IO_POWER_EXTERNAL +#define SDMMC_PWR_LDO_CHANNEL 4 + sd_pwr_ctrl_ldo_config_t ldo_config = { + .ldo_chan_id = SDMMC_PWR_LDO_CHANNEL, + }; + sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; + + TEST_ESP_OK(sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle)); + config.pwr_ctrl_handle = pwr_ctrl_handle; +#endif + sdmmc_test_board_card_power_set(true); TEST_ESP_OK(spi_bus_initialize(dev_config.host_id, &bus_config, SPI_DMA_CH_AUTO)); TEST_ESP_OK(sdspi_host_init()); @@ -34,6 +48,9 @@ TEST_CASE("CD input works in SPI mode", "[sdspi]") TEST_ESP_OK(sdspi_host_deinit()); TEST_ESP_OK(spi_bus_free(SDSPI_DEFAULT_HOST)); sdmmc_test_board_card_power_set(false); +#if SOC_SDMMC_IO_POWER_EXTERNAL + TEST_ESP_OK(sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle)); +#endif } TEST_CASE("WP input works in SPI mode", "[sdspi]") @@ -48,6 +65,16 @@ TEST_CASE("WP input works in SPI mode", "[sdspi]") dev_config.gpio_wp = test_gpio; sdmmc_test_board_card_power_set(true); TEST_ESP_OK(spi_bus_initialize(dev_config.host_id, &bus_config, SPI_DMA_CH_AUTO)); +#if SOC_SDMMC_IO_POWER_EXTERNAL +#define SDMMC_PWR_LDO_CHANNEL 4 + sd_pwr_ctrl_ldo_config_t ldo_config = { + .ldo_chan_id = SDMMC_PWR_LDO_CHANNEL, + }; + sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; + + TEST_ESP_OK(sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle)); + config.pwr_ctrl_handle = pwr_ctrl_handle; +#endif TEST_ESP_OK(sdspi_host_init()); TEST_ESP_OK(sdspi_host_init_device(&dev_config, &handle)); @@ -58,4 +85,7 @@ TEST_CASE("WP input works in SPI mode", "[sdspi]") TEST_ESP_OK(sdspi_host_deinit()); TEST_ESP_OK(spi_bus_free(SDSPI_DEFAULT_HOST)); sdmmc_test_board_card_power_set(false); +#if SOC_SDMMC_IO_POWER_EXTERNAL + TEST_ESP_OK(sd_pwr_ctrl_del_on_chip_ldo(pwr_ctrl_handle)); +#endif } diff --git a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_probe_spi.c b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_probe_spi.c index 42da8c1e93b4..f765e52a650d 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_probe_spi.c +++ b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_probe_spi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ static void do_one_sdspi_probe(int slot, int freq_khz) sdmmc_card_print_info(stdout, &card); uint8_t* buffer = heap_caps_calloc(512, 1, MALLOC_CAP_DMA); TEST_ESP_OK(sdmmc_read_sectors(&card, buffer, 0, 1)); + free(buffer); sdmmc_test_spi_end(slot, &card); } @@ -32,21 +33,16 @@ TEST_CASE("sdspi probe, slot 0, HS", "[sdspi]") do_one_sdspi_probe(SLOT_0, SDMMC_FREQ_HIGHSPEED); } -#if !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32S3 -//TODO: IDF-8750. Leaks too much memory, needs check TEST_CASE("sdspi probe, slot 1", "[sdspi]") { do_one_sdspi_probe(SLOT_1, SDMMC_FREQ_PROBING); do_one_sdspi_probe(SLOT_1, SDMMC_FREQ_DEFAULT); do_one_sdspi_probe(SLOT_1, SDMMC_FREQ_CUSTOM_10M); } -#endif -#if !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32S3 -//TODO: IDF-8749 -//here freq should be changed to SDMMC_FREQ_HIGHSPEED after fixing IDF-8749 TEST_CASE("sdspi probe, slot 1, HS", "[sdspi]") { + //TODO: IDF-8749 + //here freq should be changed to SDMMC_FREQ_HIGHSPEED after fixing IDF-8749 do_one_sdspi_probe(SLOT_1, SDMMC_FREQ_DEFAULT); } -#endif diff --git a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_rw_spi.c b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_rw_spi.c index a45e5f0c13b8..916498b3c919 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_rw_spi.c +++ b/components/esp_driver_sdspi/test_apps/sdspi/components/sdspi_tests/sdmmc_test_rw_spi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,14 +26,12 @@ TEST_CASE("sdspi read/write performance, slot 0", "[sdspi]") do_one_sdspi_perf_test(SLOT_0, SDMMC_FREQ_HIGHSPEED); } -#if !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32S3 -//TODO: IDF-8749 -//here freq should be changed to SDMMC_FREQ_HIGHSPEED after fixing IDF-8749 TEST_CASE("sdspi read/write performance, slot 1", "[sdspi]") { + //TODO: IDF-8749 + //here freq should be changed to SDMMC_FREQ_HIGHSPEED after fixing IDF-8749 do_one_sdspi_perf_test(SLOT_1, SDMMC_FREQ_DEFAULT); } -#endif /* ========== Read/write tests with offset, SPI ========== */ @@ -52,14 +50,12 @@ TEST_CASE("sdspi read/write performance with offset, slot 0", "[sdspi]") do_one_sdspi_rw_test_with_offset(SLOT_0, SDMMC_FREQ_HIGHSPEED); } -#if !CONFIG_IDF_TARGET_ESP32 && !CONFIG_IDF_TARGET_ESP32S3 -//TODO: IDF-8749 -//here freq should be changed to SDMMC_FREQ_HIGHSPEED after fixing IDF-8749 TEST_CASE("sdspi read/write performance with offset, slot 1", "[sdspi]") { + //TODO: IDF-8749 + //here freq should be changed to SDMMC_FREQ_HIGHSPEED after fixing IDF-8749 do_one_sdspi_rw_test_with_offset(SLOT_1, SDMMC_FREQ_DEFAULT); } -#endif /* ========== Read/write tests with unaligned source/destination buffer, SPI ========== */ diff --git a/components/esp_driver_sdspi/test_apps/sdspi/main/test_app_main.c b/components/esp_driver_sdspi/test_apps/sdspi/main/test_app_main.c index 274579059d17..b165025bc929 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/main/test_app_main.c +++ b/components/esp_driver_sdspi/test_apps/sdspi/main/test_app_main.c @@ -13,11 +13,13 @@ void setUp(void) { + printf("%s", ""); /* sneakily lazy-allocate the reent structure for this test task */ unity_utils_record_free_mem(); } void tearDown(void) { + esp_reent_cleanup(); unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD); } diff --git a/components/esp_driver_sdspi/test_apps/sdspi/pytest_sdspi.py b/components/esp_driver_sdspi/test_apps/sdspi/pytest_sdspi.py index f2d30a8c2d2c..dbc425b34b3a 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/pytest_sdspi.py +++ b/components/esp_driver_sdspi/test_apps/sdspi/pytest_sdspi.py @@ -1,8 +1,13 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - +import pytest from pytest_embedded_idf import IdfDut +@pytest.mark.esp32 +@pytest.mark.esp32c3 +@pytest.mark.esp32s3 +@pytest.mark.esp32p4 +@pytest.mark.sdcard_spimode def test_sdspi(dut: IdfDut) -> None: - dut.run_all_single_board_cases() + dut.run_all_single_board_cases(reset=True) diff --git a/components/esp_driver_sdspi/test_apps/sdspi/sdkconfig.defaults.esp32p4 b/components/esp_driver_sdspi/test_apps/sdspi/sdkconfig.defaults.esp32p4 new file mode 100644 index 000000000000..74592300eb55 --- /dev/null +++ b/components/esp_driver_sdspi/test_apps/sdspi/sdkconfig.defaults.esp32p4 @@ -0,0 +1,2 @@ +CONFIG_SDMMC_BOARD_ESP32P4_EV_BOARD_WITH_SDSPI=y +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y diff --git a/components/esp_driver_sdspi/test_apps/sdspi/sdkconfig.defaults.esp32s3 b/components/esp_driver_sdspi/test_apps/sdspi/sdkconfig.defaults.esp32s3 new file mode 100644 index 000000000000..6427c61d9235 --- /dev/null +++ b/components/esp_driver_sdspi/test_apps/sdspi/sdkconfig.defaults.esp32s3 @@ -0,0 +1,2 @@ +CONFIG_SDMMC_BOARD_ESP32S3_EMMC_TEST=y +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index 0cc45980621f..b749318fa17d 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -1149,15 +1149,22 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_host_t *host, spi_trans #endif } - if (rcv_ptr && bus_attr->dma_enabled && (!esp_ptr_dma_capable(rcv_ptr) || rx_unaligned)) { - ESP_RETURN_ON_FALSE(!(trans_desc->flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but RX buffer addr&len not align to %d, or not dma_capable", alignment); - //if rxbuf in the desc not DMA-capable, or not aligned to alignment, malloc a new one - ESP_EARLY_LOGD(SPI_TAG, "Allocate RX buffer for DMA"); - rx_byte_len = (rx_byte_len + alignment - 1) & (~(alignment - 1)); // up align alignment - rcv_ptr = heap_caps_aligned_alloc(alignment, rx_byte_len, MALLOC_CAP_DMA); - if (rcv_ptr == NULL) { - goto clean_up; + if (rcv_ptr && bus_attr->dma_enabled) { + if ((!esp_ptr_dma_capable(rcv_ptr) || rx_unaligned)) { + ESP_RETURN_ON_FALSE(!(trans_desc->flags & SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL), ESP_ERR_INVALID_ARG, SPI_TAG, "Set flag SPI_TRANS_DMA_BUFFER_ALIGN_MANUAL but RX buffer addr&len not align to %d, or not dma_capable", alignment); + //if rxbuf in the desc not DMA-capable, or not aligned to alignment, malloc a new one + ESP_EARLY_LOGD(SPI_TAG, "Allocate RX buffer for DMA"); + rx_byte_len = (rx_byte_len + alignment - 1) & (~(alignment - 1)); // up align alignment + rcv_ptr = heap_caps_aligned_alloc(alignment, rx_byte_len, MALLOC_CAP_DMA); + if (rcv_ptr == NULL) { + goto clean_up; + } } +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + // do invalid here to hold on cache status to avoid hardware auto write back during dma transaction + esp_err_t ret = esp_cache_msync((void *)rcv_ptr, rx_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(ret == ESP_OK); +#endif } priv_desc->buffer_to_send = send_ptr; priv_desc->buffer_to_rcv = rcv_ptr; diff --git a/components/esp_driver_spi/src/gpspi/spi_slave.c b/components/esp_driver_spi/src/gpspi/spi_slave.c index 8aa5e2beaeed..a4f081b54211 100644 --- a/components/esp_driver_spi/src/gpspi/spi_slave.c +++ b/components/esp_driver_spi/src/gpspi/spi_slave.c @@ -379,16 +379,20 @@ static esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_setup_priv_trans(spi_host_device_t esp_err_t ret = esp_cache_msync((void *)priv_trans->tx_buffer, buffer_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); ESP_RETURN_ON_FALSE_ISR(ESP_OK == ret, ESP_ERR_INVALID_STATE, SPI_TAG, "mem sync c2m(writeback) fail"); } - if (spihost[host]->dma_enabled && trans->rx_buffer && (!esp_ptr_dma_capable(trans->rx_buffer) || ((((uint32_t)trans->rx_buffer) | (trans->length + 7) / 8) & (alignment - 1)))) { - ESP_RETURN_ON_FALSE_ISR(trans->flags & SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, ESP_ERR_INVALID_ARG, SPI_TAG, "RX buffer addr&len not align to %d, or not dma_capable", alignment); - //if rxbuf in the desc not DMA-capable, or not align to "alignment", malloc a new one - ESP_EARLY_LOGD(SPI_TAG, "Allocate RX buffer for DMA"); - buffer_byte_len = (buffer_byte_len + alignment - 1) & (~(alignment - 1)); // up align to "alignment" - priv_trans->rx_buffer = heap_caps_aligned_alloc(alignment, buffer_byte_len, MALLOC_CAP_DMA); - if (priv_trans->rx_buffer == NULL) { - free(priv_trans->tx_buffer); - return ESP_ERR_NO_MEM; + if (spihost[host]->dma_enabled && trans->rx_buffer) { + if ((!esp_ptr_dma_capable(trans->rx_buffer) || ((((uint32_t)trans->rx_buffer) | (trans->length + 7) / 8) & (alignment - 1)))) { + ESP_RETURN_ON_FALSE_ISR(trans->flags & SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, ESP_ERR_INVALID_ARG, SPI_TAG, "RX buffer addr&len not align to %d, or not dma_capable", alignment); + //if rxbuf in the desc not DMA-capable, or not align to "alignment", malloc a new one + ESP_EARLY_LOGD(SPI_TAG, "Allocate RX buffer for DMA"); + buffer_byte_len = (buffer_byte_len + alignment - 1) & (~(alignment - 1)); // up align to "alignment" + priv_trans->rx_buffer = heap_caps_aligned_alloc(alignment, buffer_byte_len, MALLOC_CAP_DMA); + if (priv_trans->rx_buffer == NULL) { + free(priv_trans->tx_buffer); + return ESP_ERR_NO_MEM; + } } + esp_err_t ret = esp_cache_msync((void *)priv_trans->rx_buffer, buffer_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + ESP_RETURN_ON_FALSE_ISR(ESP_OK == ret, ESP_ERR_INVALID_STATE, SPI_TAG, "mem sync m2c(invalid) fail"); } #endif //SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE return ESP_OK; diff --git a/components/esp_driver_spi/src/gpspi/spi_slave_hd.c b/components/esp_driver_spi/src/gpspi/spi_slave_hd.c index c9518d70826f..c30f68b584b1 100644 --- a/components/esp_driver_spi/src/gpspi/spi_slave_hd.c +++ b/components/esp_driver_spi/src/gpspi/spi_slave_hd.c @@ -599,6 +599,9 @@ static esp_err_t s_spi_slave_hd_setup_priv_trans(spi_host_device_t host, spi_sla memcpy(priv_trans->aligned_buffer, orig_trans->data, orig_trans->len); esp_err_t ret = esp_cache_msync((void *)priv_trans->aligned_buffer, byte_len, ESP_CACHE_MSYNC_FLAG_DIR_C2M); ESP_RETURN_ON_FALSE(ESP_OK == ret, ESP_ERR_INVALID_STATE, TAG, "mem sync c2m(writeback) fail"); + } else { + esp_err_t ret = esp_cache_msync((void *)priv_trans->aligned_buffer, byte_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + ESP_RETURN_ON_FALSE(ESP_OK == ret, ESP_ERR_INVALID_STATE, TAG, "mem sync m2c(invalid) fail"); } #endif //SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE return ESP_OK; diff --git a/components/esp_eth/include/esp_eth_mac_esp.h b/components/esp_eth/include/esp_eth_mac_esp.h index 8c4909b8c559..14bb0d274a91 100644 --- a/components/esp_eth/include/esp_eth_mac_esp.h +++ b/components/esp_eth/include/esp_eth_mac_esp.h @@ -217,64 +217,64 @@ typedef enum { #error "Unsupported RMII clock mode" #endif // CONFIG_ETH_RMII_CLK_INPUT -#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \ - { \ - .smi_gpio = \ - { \ - .mdc_num = 23, \ - .mdio_num = 18 \ - }, \ - .interface = EMAC_DATA_INTERFACE_RMII, \ - .clock_config = \ - { \ - .rmii = \ - { \ - .clock_mode = DEFAULT_RMII_CLK_MODE, \ - .clock_gpio = DEFAULT_RMII_CLK_GPIO \ - } \ - }, \ - .dma_burst_len = ETH_DMA_BURST_LEN_32, \ - .intr_priority = 0, \ +#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \ + { \ + .smi_gpio = \ + { \ + .mdc_num = 23, \ + .mdio_num = 18 \ + }, \ + .interface = EMAC_DATA_INTERFACE_RMII, \ + .clock_config = \ + { \ + .rmii = \ + { \ + .clock_mode = DEFAULT_RMII_CLK_MODE, \ + .clock_gpio = (emac_rmii_clock_gpio_t) DEFAULT_RMII_CLK_GPIO \ + } \ + }, \ + .dma_burst_len = ETH_DMA_BURST_LEN_32, \ + .intr_priority = 0, \ } #elif CONFIG_IDF_TARGET_ESP32P4 -#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \ - { \ - .smi_gpio = \ - { \ - .mdc_num = 31, \ - .mdio_num = 27 \ - }, \ - .interface = EMAC_DATA_INTERFACE_RMII, \ - .clock_config = \ - { \ - .rmii = \ - { \ - .clock_mode = EMAC_CLK_EXT_IN, \ - .clock_gpio = 50 \ - } \ - }, \ - .clock_config_out_in = \ - { \ - .rmii = \ - { \ - .clock_mode = EMAC_CLK_EXT_IN, \ - .clock_gpio = -1 \ - } \ - }, \ - .dma_burst_len = ETH_DMA_BURST_LEN_32, \ - .intr_priority = 0, \ - .emac_dataif_gpio = \ - { \ - .rmii = \ - { \ - .tx_en_num = 49, \ - .txd0_num = 34, \ - .txd1_num = 35, \ - .crs_dv_num = 28, \ - .rxd0_num = 29, \ - .rxd1_num = 30 \ - } \ - }, \ +#define ETH_ESP32_EMAC_DEFAULT_CONFIG() \ + { \ + .smi_gpio = \ + { \ + .mdc_num = 31, \ + .mdio_num = 27 \ + }, \ + .interface = EMAC_DATA_INTERFACE_RMII, \ + .clock_config = \ + { \ + .rmii = \ + { \ + .clock_mode = EMAC_CLK_EXT_IN, \ + .clock_gpio = (emac_rmii_clock_gpio_t) 50 \ + } \ + }, \ + .clock_config_out_in = \ + { \ + .rmii = \ + { \ + .clock_mode = EMAC_CLK_EXT_IN, \ + .clock_gpio = (emac_rmii_clock_gpio_t) -1 \ + } \ + }, \ + .dma_burst_len = ETH_DMA_BURST_LEN_32, \ + .intr_priority = 0, \ + .emac_dataif_gpio = \ + { \ + .rmii = \ + { \ + .tx_en_num = 49, \ + .txd0_num = 34, \ + .txd1_num = 35, \ + .crs_dv_num = 28, \ + .rxd0_num = 29, \ + .rxd1_num = 30 \ + } \ + }, \ } #endif // CONFIG_IDF_TARGET_ESP32P4 diff --git a/components/esp_hid/src/bt_hidd.c b/components/esp_hid/src/bt_hidd.c index beb05a0eff1c..acf9d7e7ab3f 100644 --- a/components/esp_hid/src/bt_hidd.c +++ b/components/esp_hid/src/bt_hidd.c @@ -715,11 +715,9 @@ void bt_hidd_cb(esp_hidd_cb_event_t event, esp_hidd_cb_param_t *param) } case ESP_HIDD_SET_PROTOCOL_EVT: { if (param->set_protocol.protocol_mode != ESP_HIDD_UNSUPPORTED_MODE) { - if (s_hidd_param.dev->protocol_mode == param->set_protocol.protocol_mode) { - break; - } osi_mutex_lock(&s_hidd_param.mutex, OSI_MUTEX_MAX_TIMEOUT); - s_hidd_param.dev->protocol_mode = param->set_protocol.protocol_mode; + s_hidd_param.dev->protocol_mode = + param->set_protocol.protocol_mode ? ESP_HID_PROTOCOL_MODE_BOOT : ESP_HID_PROTOCOL_MODE_REPORT; osi_mutex_unlock(&s_hidd_param.mutex); cb_param.protocol_mode.dev = s_hidd_param.dev->dev; cb_param.protocol_mode.protocol_mode = s_hidd_param.dev->protocol_mode; diff --git a/components/esp_hid/src/esp_hidh.c b/components/esp_hid/src/esp_hidh.c index e1a38a34aca7..1e841cd663c9 100644 --- a/components/esp_hid/src/esp_hidh.c +++ b/components/esp_hid/src/esp_hidh.c @@ -536,7 +536,7 @@ esp_err_t esp_hidh_dev_report_maps_get(esp_hidh_dev_t *dev, size_t *num_maps, es * */ /** - * `lock_devices()` only protect the devices list, this mutex protect the single deivce instance. + * `lock_devices()` only protect the devices list, this mutex protect the single device instance. */ inline void esp_hidh_dev_lock(esp_hidh_dev_t *dev) { @@ -655,7 +655,12 @@ esp_hidh_dev_report_t *esp_hidh_dev_get_input_report_by_proto_and_data(esp_hidh_ } r = dev->reports; while (r) { - if (r->value_len == len - 1 && r->report_id == *data && (r->report_type & ESP_HID_REPORT_TYPE_INPUT) && + /** + * @note For some HID device, the input report length may exceed the length which is declared in HID + * descriptor, like Logitech K380 keyboard. So loose the check condition from `r->value_len == len - 1` to + * `r->value_len <= len - 1`. + */ + if (r->value_len <= len - 1 && r->report_id == *data && (r->report_type & ESP_HID_REPORT_TYPE_INPUT) && r->protocol_mode == protocol_mode) { *has_report_id = true; break; diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index c872e56b7166..7ede9c33d77a 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -38,6 +38,7 @@ if(NOT BOOTLOADER_BUILD) "port/${target}/esp_clk_tree.c" "port/esp_clk_tree_common.c" "dma/esp_dma_utils.c" + "dma/gdma_link.c" "spi_share_hw_ctrl.c" "spi_bus_lock.c") diff --git a/components/esp_hw_support/clk_ctrl_os.c b/components/esp_hw_support/clk_ctrl_os.c index a8b2560abb85..30842ff96468 100644 --- a/components/esp_hw_support/clk_ctrl_os.c +++ b/components/esp_hw_support/clk_ctrl_os.c @@ -142,7 +142,7 @@ esp_err_t periph_rtc_apll_freq_set(uint32_t expt_freq, uint32_t *real_freq) esp_err_t IRAM_ATTR periph_rtc_mpll_acquire(void) { // power up LDO for the MPLL -#if defined(CONFIG_ESP_LDO_CHAN_PSRAM_DOMAIN) && CONFIG_ESP_LDO_CHAN_PSRAM_DOMAIN != -1 +#if CONFIG_ESP_LDO_RESERVE_PSRAM esp_ldo_channel_config_t ldo_mpll_config = { .chan_id = CONFIG_ESP_LDO_CHAN_PSRAM_DOMAIN, .voltage_mv = CONFIG_ESP_LDO_VOLTAGE_PSRAM_DOMAIN, diff --git a/components/esp_hw_support/dma/dw_gdma.c b/components/esp_hw_support/dma/dw_gdma.c index 765d931c0dd7..f76f1245eb5c 100644 --- a/components/esp_hw_support/dma/dw_gdma.c +++ b/components/esp_hw_support/dma/dw_gdma.c @@ -381,7 +381,7 @@ esp_err_t dw_gdma_channel_continue(dw_gdma_channel_handle_t chan) esp_err_t dw_gdma_new_link_list(const dw_gdma_link_list_config_t *config, dw_gdma_link_list_handle_t *ret_list) { esp_err_t ret = ESP_OK; - ESP_RETURN_ON_FALSE(ret_list, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(config && ret_list, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); dw_gdma_link_list_item_t *items = NULL; dw_gdma_link_list_t *list = NULL; uint32_t num_items = config->num_items; @@ -531,7 +531,7 @@ esp_err_t dw_gdma_channel_set_block_markers(dw_gdma_channel_handle_t chan, dw_gd return ESP_OK; } -esp_err_t dw_gdma_lli_config_transfer(dw_gdma_lli_handle_t lli, dw_gdma_block_transfer_config_t *config) +esp_err_t dw_gdma_lli_config_transfer(dw_gdma_lli_handle_t lli, const dw_gdma_block_transfer_config_t *config) { ESP_RETURN_ON_FALSE(lli && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); diff --git a/components/esp_hw_support/dma/gdma_link.c b/components/esp_hw_support/dma/gdma_link.c new file mode 100644 index 000000000000..d13b62e64d24 --- /dev/null +++ b/components/esp_hw_support/dma/gdma_link.c @@ -0,0 +1,246 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "soc/soc_caps.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_memory_utils.h" +#include "esp_heap_caps.h" +#include "esp_private/gdma_link.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" +#include "esp_cache.h" + +static const char *TAG = "gdma"; + +#if SOC_NON_CACHEABLE_OFFSET +#define GDMA_CACHE_ADDR_TO_NON_CACHE_ADDR(addr) ((addr) + SOC_NON_CACHEABLE_OFFSET) +#else +#define GDMA_CACHE_ADDR_TO_NON_CACHE_ADDR(addr) (addr) +#endif + +#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) +#define ALIGN_DOWN(num, align) ((num) & ~((align) - 1)) + +// GDMA link list item definition +// TODO: this type will eventually become target specific, we need to move it to the LL layer or soc layer +typedef struct gdma_link_list_item_t gdma_link_list_item_t; +struct gdma_link_list_item_t { + struct { + uint32_t size : 12; /*!< Buffer size */ + uint32_t length : 12; /*!< Number of valid bytes in the buffer */ + uint32_t reversed24 : 4; /*!< Reserved */ + uint32_t err_eof : 1; /*!< Whether the received buffer contains error, the error was reported by the peripheral */ + uint32_t reserved29 : 1; /*!< Reserved */ + uint32_t suc_eof : 1; /*!< Whether the list item should notify the peripheral an "EOF" event */ + uint32_t owner : 1; /*!< Who is allowed to access the buffer */ + } dw0; /*!< list item Word 0 */ + void *buffer; /*!< Pointer to the buffer */ + gdma_link_list_item_t *next; /*!< Pointer to the next list item (set to NULL if the list item is the last one of the link) */ +}; + +///< Maximum size of the buffer that can be carried by a DMA link list item +#define GDMA_MAX_BUFFER_SIZE_PER_LINK_ITEM 4095 + +typedef struct gdma_link_list_t { + uint32_t num_items; // number of items in the link list + size_t item_size; // size of each item + size_t buffer_alignment; // Alignment of each buffer + uint8_t *items; // pointer to the link list items + uint8_t *items_nc; // pointer to the link list items, non-cached + struct { + uint32_t check_owner: 1; // Whether the link list is responsible for checking the ownership when mount data buffers + } flags; +} gdma_link_list_t; + +esp_err_t gdma_new_link_list(const gdma_link_list_config_t *config, gdma_link_list_handle_t *ret_list) +{ + esp_err_t ret = ESP_OK; + uint8_t *items = NULL; + gdma_link_list_t *list = NULL; + ESP_RETURN_ON_FALSE(config && ret_list, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(config->num_items, ESP_ERR_INVALID_ARG, TAG, "invalid number of items"); + size_t buffer_alignment = config->buffer_alignment; + if (buffer_alignment == 0) { + buffer_alignment = 1; + } + ESP_RETURN_ON_FALSE((buffer_alignment & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "invalid buffer alignment: %zu", buffer_alignment); + + // the link list container is allocated from internal memory + list = heap_caps_calloc(1, sizeof(gdma_link_list_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + ESP_GOTO_ON_FALSE(list, ESP_ERR_NO_MEM, err, TAG, "no mem for link list"); + + uint32_t num_items = config->num_items; + size_t item_alignment = config->item_alignment ? config->item_alignment : 4; + // each list item should align to the specified alignment + size_t item_size = ALIGN_UP(sizeof(gdma_link_list_item_t), item_alignment); + + uint32_t list_items_mem_caps = MALLOC_CAP_8BIT | MALLOC_CAP_DMA; + if (config->flags.items_in_ext_mem) { + list_items_mem_caps |= MALLOC_CAP_SPIRAM; + } else { + list_items_mem_caps |= MALLOC_CAP_INTERNAL; + } + items = heap_caps_aligned_calloc(item_alignment, num_items, item_size, list_items_mem_caps); + ESP_GOTO_ON_FALSE(items, ESP_ERR_NO_MEM, err, TAG, "no mem for link list items"); + + // do memory sync if the list items are in the cache + uint32_t data_cache_line_size = 0; + if (config->flags.items_in_ext_mem) { + data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); + } else { + data_cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + } + if (data_cache_line_size) { + // write back and then invalidate the cache, because later we will read/write the link list items by non-cached address + ESP_GOTO_ON_ERROR(esp_cache_msync(items, ALIGN_UP(num_items * item_size, data_cache_line_size), + ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_INVALIDATE), + err, TAG, "cache sync failed"); + } + + list->num_items = num_items; + list->item_size = item_size; + list->items = items; + // calculate the non-cached address + list->items_nc = GDMA_CACHE_ADDR_TO_NON_CACHE_ADDR(items); + list->buffer_alignment = buffer_alignment; + list->flags.check_owner = config->flags.check_owner; + + ESP_LOGD(TAG, "new link list @%p, items @%p", list, items); + *ret_list = list; + return ESP_OK; + +err: + if (list) { + free(list); + } + if (items) { + free(items); + } + return ret; +} + +esp_err_t gdma_del_link_list(gdma_link_list_handle_t list) +{ + ESP_RETURN_ON_FALSE(list, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_LOGD(TAG, "del link list at %p", list); + free(list->items); + free(list); + return ESP_OK; +} + +esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, uint32_t start_item_index, const gdma_buffer_mount_config_t *buf_config_array, size_t num_buf, uint32_t *end_item_index) +{ + ESP_RETURN_ON_FALSE(list && buf_config_array && num_buf, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(start_item_index < list->num_items, ESP_ERR_INVALID_ARG, TAG, "invalid start item index"); + size_t buffer_alignment = list->buffer_alignment; + size_t item_size = list->item_size; + uint32_t list_item_capacity = list->num_items; + size_t max_buffer_mount_length = ALIGN_DOWN(GDMA_MAX_BUFFER_SIZE_PER_LINK_ITEM, buffer_alignment); + uint32_t begin_item_idx = start_item_index; + gdma_link_list_item_t *lli_nc = NULL; + + uint32_t num_items_avail = 0; + // if the link list is responsible for checking the ownership, we need to skip the items that are owned by the DMA + if (list->flags.check_owner) { + for (uint32_t i = 0; i < list_item_capacity; i++) { + lli_nc = (gdma_link_list_item_t *)(list->items_nc + (i + start_item_index) % list_item_capacity * item_size); + if (lli_nc->dw0.owner == GDMA_LLI_OWNER_CPU) { + num_items_avail++; + } + } + } else { + num_items_avail = list_item_capacity; + } + + // check alignment and length for each buffer + for (size_t i = 0; i < num_buf; i++) { + const gdma_buffer_mount_config_t *config = &buf_config_array[i]; + uint8_t *buf = (uint8_t *)config->buffer; + size_t len = config->length; + // check the buffer alignment + ESP_RETURN_ON_FALSE(((uintptr_t)buf & (buffer_alignment - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "buffer not aligned to %zu", buffer_alignment); + uint32_t num_items_need = (len + max_buffer_mount_length - 1) / max_buffer_mount_length; + // check if there are enough link list items + ESP_RETURN_ON_FALSE((begin_item_idx + num_items_need) <= (start_item_index + num_items_avail), ESP_ERR_INVALID_ARG, TAG, "no more space for buffer mounting"); + begin_item_idx += num_items_need; + } + + // link_nodes[start_item_index-1] --> link_nodes[start_item_index] + lli_nc = (gdma_link_list_item_t *)(list->items_nc + (start_item_index + list_item_capacity - 1) % list_item_capacity * item_size); + lli_nc->next = (gdma_link_list_item_t *)(list->items + start_item_index * item_size); + + begin_item_idx = start_item_index; + for (size_t i = 0; i < num_buf; i++) { + const gdma_buffer_mount_config_t *config = &buf_config_array[i]; + uint8_t *buf = (uint8_t *)config->buffer; + size_t len = config->length; + // skip zero-length buffer + if (len == 0 || buf == NULL) { + continue; + } + uint32_t num_items_need = (len + max_buffer_mount_length - 1) / max_buffer_mount_length; + // mount the buffer to the link list + for (uint32_t i = 0; i < num_items_need; i++) { + lli_nc = (gdma_link_list_item_t *)(list->items_nc + (i + begin_item_idx) % list_item_capacity * item_size); + lli_nc->buffer = buf; + lli_nc->dw0.length = len > max_buffer_mount_length ? max_buffer_mount_length : len; + // in fact the DMA doesn't check the "size" field, but we still set it to "length" for consistency + // it's the user's responsibility to make sure the buffer size is sufficient + lli_nc->dw0.size = lli_nc->dw0.length; + // mark the EOF node + lli_nc->dw0.suc_eof = (config->flags.mark_eof == 1) && (i == num_items_need - 1); + // mark the final node + if ((config->flags.mark_final == 1) && (i == num_items_need - 1)) { + lli_nc->next = NULL; + } else { + lli_nc->next = (gdma_link_list_item_t *)(list->items + (i + begin_item_idx + 1) % list_item_capacity * item_size); + } + lli_nc->dw0.owner = GDMA_LLI_OWNER_DMA; + buf += max_buffer_mount_length; + len -= max_buffer_mount_length; + } + begin_item_idx += num_items_need; + } + + // return the index of the last modified list item + if (end_item_index) { + *end_item_index = (begin_item_idx - 1 + list_item_capacity) % list_item_capacity; + } + return ESP_OK; +} + +uintptr_t gdma_link_get_head_addr(gdma_link_list_handle_t list) +{ + ESP_RETURN_ON_FALSE(list, 0, TAG, "invalid argument"); + return (uintptr_t)(list->items); +} + +esp_err_t gdma_link_set_owner(gdma_link_list_handle_t list, int item_index, gdma_lli_owner_t owner) +{ + ESP_RETURN_ON_FALSE_ISR(list, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE_ISR(item_index < list->num_items, ESP_ERR_INVALID_ARG, TAG, "invalid item index"); + gdma_link_list_item_t *lli = (gdma_link_list_item_t *)(list->items_nc + item_index * list->item_size); + lli->dw0.owner = owner; + return ESP_OK; +} + +esp_err_t gdma_link_get_owner(gdma_link_list_handle_t list, int item_index, gdma_lli_owner_t *owner) +{ + ESP_RETURN_ON_FALSE_ISR(list && owner, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE_ISR(item_index < list->num_items, ESP_ERR_INVALID_ARG, TAG, "invalid item index"); + gdma_link_list_item_t *lli = (gdma_link_list_item_t *)(list->items_nc + item_index * list->item_size); + *owner = lli->dw0.owner; + return ESP_OK; +} diff --git a/components/esp_hw_support/dma/include/esp_private/dw_gdma.h b/components/esp_hw_support/dma/include/esp_private/dw_gdma.h index dd9105e9d36e..63518338464a 100644 --- a/components/esp_hw_support/dma/include/esp_private/dw_gdma.h +++ b/components/esp_hw_support/dma/include/esp_private/dw_gdma.h @@ -361,7 +361,7 @@ dw_gdma_lli_handle_t dw_gdma_link_list_get_item(dw_gdma_link_list_handle_t list, * - ESP_ERR_INVALID_ARG: Configure link list item block transfer failed because of invalid argument * - ESP_FAIL: Configure link list item block transfer failed because of other error */ -esp_err_t dw_gdma_lli_config_transfer(dw_gdma_lli_handle_t lli, dw_gdma_block_transfer_config_t *config); +esp_err_t dw_gdma_lli_config_transfer(dw_gdma_lli_handle_t lli, const dw_gdma_block_transfer_config_t *config); /** * @brief Set the next link list item for a given DMA link list item diff --git a/components/esp_hw_support/dma/include/esp_private/gdma_link.h b/components/esp_hw_support/dma/include/esp_private/gdma_link.h new file mode 100644 index 000000000000..94a13651c4ee --- /dev/null +++ b/components/esp_hw_support/dma/include/esp_private/gdma_link.h @@ -0,0 +1,144 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type of GDMA link list handle + */ +typedef struct gdma_link_list_t *gdma_link_list_handle_t; + +/** + * @brief DMA link list configurations + */ +typedef struct { + uint32_t num_items; //!< Number of nodes in the link list + size_t item_alignment; //!< Alignment of each list item required by the DMA. By default, it's 4 bytes alignment. + size_t buffer_alignment; //!< Alignment of each buffer required by the DMA. By default, it's 1 byte alignment. + struct gdma_link_list_flags { + uint32_t items_in_ext_mem: 1; //!< Whether the link list items are allocated from external memory + uint32_t check_owner: 1; //!< Whether the link list is responsible for checking the ownership when mount data buffers + } flags; +} gdma_link_list_config_t; + +/** + * @brief Create a DMA link list + * + * @note This function will allocate memory for the link list. + * + * @param[in] config Link list configurations + * @param[out] ret_list Returned link list handle + * @return + * - ESP_OK: Create DMA link list successfully + * - ESP_ERR_INVALID_ARG: Create DMA link list failed because of invalid argument + * - ESP_ERR_NO_MEM: Create DMA link list failed because out of memory + * - ESP_FAIL: Create DMA link list failed because of other error + */ +esp_err_t gdma_new_link_list(const gdma_link_list_config_t *config, gdma_link_list_handle_t *ret_list); + +/** + * @brief Delete a DMA link list + * + * @param[in] list Link list handle, allocated by `gdma_new_link_list` + * @return + * - ESP_OK: Delete DMA link list successfully + * - ESP_ERR_INVALID_ARG: Delete DMA link list failed because of invalid argument + * - ESP_FAIL: Delete DMA link list failed because of other error + */ +esp_err_t gdma_del_link_list(gdma_link_list_handle_t list); + +/** + * @brief DMA buffer mount configurations + */ +typedef struct { + void *buffer; //!< Buffer to be mounted to the DMA link list + size_t length; //!< Number of bytes that are expected to be transferred + struct gdma_buffer_mount_flags { + uint32_t mark_eof: 1; /*!< Whether to mark the list item as the "EOF" item. + Note, an "EOF" descriptor can be interrupted differently by peripheral. + But it doesn't mean to terminate a DMA link (use `mark_final` instead). + EOF link list item can also trigger an interrupt. */ + uint32_t mark_final: 1; /*!< Whether to terminate the DMA link list at this item. + Note, DMA engine will stop at this item and trigger an interrupt. + If `mark_final` is not set, this list item will point to the next item, and + wrap around to the head item if it's the one in the list. */ + } flags; //!< Flags for buffer mount configurations +} gdma_buffer_mount_config_t; + +/** + * @brief Mount one or more buffers to a given link list + * + * @note Different buffers won't be mounted to the same DMA link list item + * @note After mount to the last list item, the next list item will be the head item (wrap around) + * + * @param[in] list Link list handle, allocated by `gdma_new_link_list` + * @param[in] start_item_index Index of the first item in the link list to be mounted + * @param[in] buf_config_array Array of buffer mount configurations + * @param[in] num_buf Number of buffers to be mounted + * @param[out] end_item_index Index of the last item in the link list that has been mounted + * @return + * - ESP_OK: Mount the buffer successfully + * - ESP_ERR_INVALID_ARG: Mount the buffer failed because of invalid argument + * - ESP_FAIL: Mount the buffer failed because of other error + */ +esp_err_t gdma_link_mount_buffers(gdma_link_list_handle_t list, uint32_t start_item_index, const gdma_buffer_mount_config_t *buf_config_array, size_t num_buf, uint32_t *end_item_index); + +/** + * @brief Get the address of the head item in the link list + * + * @note The head address can be used to start a DMA transfer + * + * @param[in] list Link list handle, allocated by `gdma_new_link_list` + * @return + * - Address of the head item in the link list + * - NULL: Get the address failed + */ +uintptr_t gdma_link_get_head_addr(gdma_link_list_handle_t list); + +/** + * @brief GDMA link list item owner + */ +typedef enum { + GDMA_LLI_OWNER_CPU = 0, /*!< GDMA link list item is only allowed to be accessed by CPU */ + GDMA_LLI_OWNER_DMA = 1, /*!< GDMA link list item is only allowed to be accessed by DMA */ +} gdma_lli_owner_t; + +/** + * @brief Set the ownership for a DMA link list item + * + * @param[in] list Link list handle, allocated by `gdma_new_link_list` + * @param[in] item_index Index of the link list item + * @param[in] owner Ownership + * @return + * - ESP_OK: Set the ownership successfully + * - ESP_ERR_INVALID_ARG: Set the ownership failed because of invalid argument + * - ESP_FAIL: Set the ownership failed because of other error + */ +esp_err_t gdma_link_set_owner(gdma_link_list_handle_t list, int item_index, gdma_lli_owner_t owner); + +/** + * @brief Get the ownership of a DMA link list item + * + * @param[in] list Link list handle, allocated by `gdma_new_link_list` + * @param[in] item_index Index of the link list item + * @param[out] owner Ownership + * @return + * - ESP_OK: Get the ownership successfully + * - ESP_ERR_INVALID_ARG: Get the ownership failed because of invalid argument + * - ESP_FAIL: Get the ownership failed because of other error + */ +esp_err_t gdma_link_get_owner(gdma_link_list_handle_t list, int item_index, gdma_lli_owner_t *owner); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_cpu.h b/components/esp_hw_support/include/esp_cpu.h index c0b84749bf22..f0f441b713ea 100644 --- a/components/esp_hw_support/include/esp_cpu.h +++ b/components/esp_hw_support/include/esp_cpu.h @@ -578,6 +578,14 @@ FORCE_INLINE_ATTR void esp_cpu_branch_prediction_enable(void) { rv_utils_en_branch_predictor(); } + +/** + * @brief Disable branch prediction + */ +FORCE_INLINE_ATTR void esp_cpu_branch_prediction_disable(void) +{ + rv_utils_dis_branch_predictor(); +} #endif //#if SOC_BRANCH_PREDICTOR_SUPPORTED #ifdef __cplusplus diff --git a/components/esp_hw_support/ldo/esp_ldo_regulator.c b/components/esp_hw_support/ldo/esp_ldo_regulator.c index 97dcc6f4bb76..2a59dd6de57b 100644 --- a/components/esp_hw_support/ldo/esp_ldo_regulator.c +++ b/components/esp_hw_support/ldo/esp_ldo_regulator.c @@ -31,8 +31,8 @@ static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED; static const uint32_t s_ldo_channel_adjustable_mask = LDO_LL_ADJUSTABLE_CHAN_MASK; // each bit represents if the LDO channel is adjustable in hardware -static ldo_regulator_channel_t s_ldo_channels[LDO_LL_UNIT_NUM] = { - [0 ... LDO_LL_UNIT_NUM - 1] = { +static ldo_regulator_channel_t s_ldo_channels[LDO_LL_NUM_UNITS] = { + [0 ... LDO_LL_NUM_UNITS - 1] = { .chan_id = -1, .voltage_mv = 0, .ref_cnt = 0, @@ -43,7 +43,7 @@ static ldo_regulator_channel_t s_ldo_channels[LDO_LL_UNIT_NUM] = { esp_err_t esp_ldo_acquire_channel(const esp_ldo_channel_config_t *config, esp_ldo_channel_handle_t *out_handle) { ESP_RETURN_ON_FALSE(config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - ESP_RETURN_ON_FALSE(ldo_ll_is_valid_ldo_id(config->chan_id), ESP_ERR_INVALID_ARG, TAG, "invalid ldo channel ID"); + ESP_RETURN_ON_FALSE(ldo_ll_is_valid_ldo_channel(config->chan_id), ESP_ERR_INVALID_ARG, TAG, "invalid ldo channel ID"); ESP_RETURN_ON_FALSE(config->voltage_mv <= LDO_LL_MAX_VOLTAGE_MV, ESP_ERR_INVALID_ARG, TAG, "invalid voltage value: %d", config->voltage_mv); int unit_id = LDO_ID2UNIT(config->chan_id); @@ -78,8 +78,16 @@ esp_err_t esp_ldo_acquire_channel(const esp_ldo_channel_config_t *config, esp_ld } if (check_voltage_constraint_valid && check_adjustable_constraint_valid) { if (channel->ref_cnt == 0) { - // if the channel is not in use, we need to set the voltage and enable it - ldo_ll_set_output_voltage_mv(unit_id, config->voltage_mv); + // if the channel is not in use, we need to set the initial voltage and enable it + uint8_t dref = 0; + uint8_t mul = 0; + // calculate the dref and mul + ldo_ll_voltage_to_dref_mul(unit_id, config->voltage_mv, &dref, &mul); + ldo_ll_adjust_voltage(unit_id, dref, mul); + // set the ldo unit owner ship + ldo_ll_set_owner(unit_id, config->flags.owned_by_hw ? LDO_LL_UNIT_OWNER_HW : LDO_LL_UNIT_OWNER_SW); + // suppress voltage ripple + ldo_ll_enable_ripple_suppression(unit_id, true); ldo_ll_enable(unit_id, true); } // update the channel attributes @@ -143,7 +151,11 @@ esp_err_t esp_ldo_channel_adjust_voltage(esp_ldo_channel_handle_t chan, int volt // i.e., the handle is not shared between threads without mutex protection chan->voltage_mv = voltage_mv; int unit_id = LDO_ID2UNIT(chan->chan_id); - ldo_ll_set_output_voltage_mv(unit_id, voltage_mv); + uint8_t dref = 0; + uint8_t mul = 0; + // calculate the dref and mul + ldo_ll_voltage_to_dref_mul(unit_id, voltage_mv, &dref, &mul); + ldo_ll_adjust_voltage(unit_id, dref, mul); return ESP_OK; } @@ -153,7 +165,7 @@ esp_err_t esp_ldo_dump(FILE *stream) char line[100]; fprintf(stream, "ESP LDO Channel State:\n"); fprintf(stream, "%-5s %-5s %-10s %-12s %-5s\n", "Index", "ID", "ref_cnt", "voltage_mv", "adjustable"); - for (int i = 0; i < LDO_LL_UNIT_NUM; i++) { + for (int i = 0; i < LDO_LL_NUM_UNITS; i++) { char *buf = line; size_t len = sizeof(line); memset(line, 0x0, len); diff --git a/components/esp_hw_support/ldo/include/esp_ldo_regulator.h b/components/esp_hw_support/ldo/include/esp_ldo_regulator.h index 054054100328..868166acd5cb 100644 --- a/components/esp_hw_support/ldo/include/esp_ldo_regulator.h +++ b/components/esp_hw_support/ldo/include/esp_ldo_regulator.h @@ -30,6 +30,7 @@ typedef struct { /// Extra flags of a LDO channel struct ldo_extra_flags { uint32_t adjustable : 1; /*!< Whether the LDO channel is adjustable, and the voltage can be updated by `esp_ldo_channel_adjust_voltage` */ + uint32_t owned_by_hw: 1; /*!< If the LDO channel is owned by hardware, then software configurations will be overridden by hardware */ } flags; /*!< Flags for the LDO channel */ } esp_ldo_channel_config_t; diff --git a/components/esp_hw_support/port/esp32p4/Kconfig.ldo b/components/esp_hw_support/port/esp32p4/Kconfig.ldo index 6c0bea47edd1..0e5a20fdd8d4 100644 --- a/components/esp_hw_support/port/esp32p4/Kconfig.ldo +++ b/components/esp_hw_support/port/esp32p4/Kconfig.ldo @@ -1,19 +1,26 @@ menu "LDO Regulator Configurations" depends on SOC_GP_LDO_SUPPORTED + config ESP_LDO_RESERVE_SPI_NOR_FLASH + bool "Reserve one LDO regulator channel for SPI NOR Flash (READ HELP)" + default y + help + The LDO channel 1 can be used to power the SPI Flash chip, + because the channel 1 is enabled by default after power on reset. + If your SPI flash chip is not powered by ESP internal LDO, you can disable this option. + Then you will free up one LDO channel for other general purpose. + config ESP_LDO_CHAN_SPI_NOR_FLASH_DOMAIN int "LDO regulator channel that used to power SPI NOR Flash (READ HELP)" + depends on ESP_LDO_RESERVE_SPI_NOR_FLASH default 1 - range -1 4 + range 1 1 help - The internal LDO regulator can be used to power the SPI Flash specific power domain. - This option is to select which LDO channel to connect to that domain. - Please set this option correctly according to your schematic. - Set to -1 if the Flash is using any external power supply. + Select which LDO channel to connect to the SPI Flash chip. choice ESP_LDO_VOLTAGE_SPI_NOR_FLASH_DOMAIN prompt "SPI NOR Flash power domain voltage" - depends on ESP_LDO_CHAN_SPI_NOR_FLASH_DOMAIN != -1 + depends on ESP_LDO_RESERVE_SPI_NOR_FLASH default ESP_LDO_VOLTAGE_SPI_NOR_FLASH_3300_MV help Select the voltage used by the Flash power domain. @@ -26,19 +33,25 @@ menu "LDO Regulator Configurations" int default 3300 if ESP_LDO_VOLTAGE_SPI_NOR_FLASH_3300_MV + config ESP_LDO_RESERVE_PSRAM + bool "Reserve one LDO regulator channel for PSRAM (READ HELP)" + default y + help + The LDO channel 2 can be used to power the PSRAM chip. + If the PSRAM chip is not powered by ESP internal LDO, you can disable this option. + Then you will free up one LDO channel for other general purpose. + config ESP_LDO_CHAN_PSRAM_DOMAIN int "LDO regulator channel that used to power PSRAM and MPLL (READ HELP)" + depends on ESP_LDO_RESERVE_PSRAM default 2 - range -1 4 + range 2 2 help - The internal LDO regulator can be used to power the PSRAM specific power domain. - This option is to select which LDO channel to connect to that domain. - Please set this option correctly according to your schematic. - Set to -1 if the PSRAM is using any external power supply. + Select which LDO channel to connect to the PSRAM chip. choice ESP_LDO_VOLTAGE_PSRAM_DOMAIN prompt "PSRAM power domain voltage" - depends on ESP_LDO_CHAN_PSRAM_DOMAIN != -1 + depends on ESP_LDO_RESERVE_PSRAM default ESP_LDO_VOLTAGE_PSRAM_1900_MV help Select the voltage used by the PSRAM power domain. diff --git a/components/esp_hw_support/port/esp32p4/mspi_timing_config.c b/components/esp_hw_support/port/esp32p4/mspi_timing_config.c index 5c2db003e6df..ed209a88ada6 100644 --- a/components/esp_hw_support/port/esp32p4/mspi_timing_config.c +++ b/components/esp_hw_support/port/esp32p4/mspi_timing_config.c @@ -26,7 +26,8 @@ void mspi_timing_config_set_psram_clock(uint32_t psram_freq_mhz, mspi_timing_spe ESP_EARLY_LOGD(TAG, "psram_freq_mhz: %" PRIu32 " mhz, bus clock div: %" PRIu32, psram_freq_mhz, freqdiv); PERIPH_RCC_ATOMIC() { //MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here. - psram_ctrlr_ll_set_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, MSPI_TIMING_CORE_CLOCK_DIV); + psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true); + psram_ctrlr_ll_set_core_clock_div(PSRAM_CTRLR_LL_MSPI_ID_2, MSPI_TIMING_CORE_CLOCK_DIV); psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_3, freqdiv); psram_ctrlr_ll_set_bus_clock(PSRAM_CTRLR_LL_MSPI_ID_2, freqdiv); } diff --git a/components/esp_hw_support/port/esp32p4/pmu_sleep.c b/components/esp_hw_support/port/esp32p4/pmu_sleep.c index 0ac1107cc652..4beed8a3cb19 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32p4/pmu_sleep.c @@ -27,6 +27,7 @@ #include "hal/lp_aon_hal.h" #include "soc/lp_system_reg.h" #include "hal/pmu_hal.h" +#include "hal/psram_ctrlr_ll.h" #include "hal/lp_sys_ll.h" #include "esp_private/esp_pmu.h" #include "pmu_param.h" @@ -168,8 +169,8 @@ const pmu_sleep_config_t* pmu_sleep_config_default( // Get light sleep analog default pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags); #if CONFIG_SPIRAM - analog_default.hp_sys.analog.pd_cur = 1; - analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 1; + analog_default.hp_sys.analog.pd_cur = 0; + analog_default.lp_sys[PMU_MODE_LP_SLEEP].analog.pd_cur = 0; #endif #if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON @@ -290,11 +291,6 @@ void pmu_sleep_shutdown_ldo(void) { CLEAR_PERI_REG_MASK(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_XPD); } -FORCE_INLINE_ATTR void sleep_writeback_l1_dcache(void) { - Cache_WriteBack_All(CACHE_MAP_L1_DCACHE); - while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE)); -} - static TCM_DRAM_ATTR uint32_t s_mpll_freq_mhz_before_sleep = 0; TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) @@ -309,12 +305,28 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev); pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev); + // For the sleep where powered down the TOP domain, the L1 cache data memory will be lost and needs to be written back here. + // For the sleep without power down the TOP domain, regdma retention may still be enabled, and dirty data in the L1 cache needs + // to be written back so that regdma can get the correct link. So we always need to write back to L1 DCache here. // !!! Need to manually check that data in L2 memory will not be modified from now on. !!! - sleep_writeback_l1_dcache(); + Cache_WriteBack_All(CACHE_MAP_L1_DCACHE); - // !!! Need to manually check that data in PSRAM will not be accessed from now on. !!! +#if CONFIG_SPIRAM + psram_ctrlr_ll_wait_all_transaction_done(); +#endif s_mpll_freq_mhz_before_sleep = rtc_clk_mpll_get_freq(); if (s_mpll_freq_mhz_before_sleep) { +#if CONFIG_SPIRAM + _psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_XTAL); + _psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_XTAL); + if (!s_pmu_sleep_regdma_backup_enabled) { + // MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here. + // If it's a PD_TOP sleep, psram MSPI core clock will be disabled by REGDMA + // !!! Need to manually check that data in PSRAM will not be accessed from now on. !!! + _psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, false); + _psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, false); + } +#endif rtc_clk_mpll_disable(); } @@ -350,6 +362,16 @@ TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp) if (s_mpll_freq_mhz_before_sleep) { rtc_clk_mpll_enable(); rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), s_mpll_freq_mhz_before_sleep); +#if CONFIG_SPIRAM + if (!s_pmu_sleep_regdma_backup_enabled) { + // MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here. + // If it's a PD_TOP sleep, psram MSPI core clock will be enabled by REGDMA + _psram_ctrlr_ll_enable_core_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true); + _psram_ctrlr_ll_enable_module_clock(PSRAM_CTRLR_LL_MSPI_ID_2, true); + } + _psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_MPLL); + _psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_MPLL); +#endif } // Wait eFuse memory update done. diff --git a/components/esp_hw_support/port/linux/esp_random.c b/components/esp_hw_support/port/linux/esp_random.c index 19bed4dc65f3..9cd06df1d578 100644 --- a/components/esp_hw_support/port/linux/esp_random.c +++ b/components/esp_hw_support/port/linux/esp_random.c @@ -6,7 +6,13 @@ #include #include #include + +// getentropy live in different header files on Mac and Linux +#if (defined(__APPLE__) && defined(__MACH__)) +#include +#else #include +#endif #include "esp_log.h" diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index 1ef17e64c7c7..8c23325e9b12 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,11 +63,17 @@ void esp_sleep_config_gpio_isolate(void) } #if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM - gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_CS1), GPIO_PULLUP_ONLY); + int32_t mspi_io_cs1_io_num = esp_mspi_get_io(ESP_MSPI_IO_CS1); + if (GPIO_IS_VALID_GPIO(mspi_io_cs1_io_num)) { + gpio_sleep_set_pull_mode(mspi_io_cs1_io_num, GPIO_PULLUP_ONLY); + } #endif // CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM #if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND - gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_CS0), GPIO_PULLUP_ONLY); + int32_t mspi_io_cs0_io_num = esp_mspi_get_io(ESP_MSPI_IO_CS0); + if (GPIO_IS_VALID_GPIO(mspi_io_cs0_io_num)) { + gpio_sleep_set_pull_mode(esp_mspi_get_io(ESP_MSPI_IO_CS0), GPIO_PULLUP_ONLY); + } #endif // CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND #if CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index e30bc2038bc9..2e2b812b9bf1 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1322,8 +1322,21 @@ esp_err_t esp_light_sleep_start(void) #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT /* Cache Suspend 0: if CONFIG_PM_SLP_IRAM_OPT is enabled, suspend cache here so that the access to flash - during the sleep process can be explicitly exposed. */ - suspend_cache(); + * during the sleep process can be explicitly exposed. + * + * If we use EXTx wakeup, we must put related codes in IRAM, but The `rtc_io_desc` table + * consumes a significant amount of memory. For example, on the ESP32, its size is 1008 + * bytes. Therefore, when EXTx wakeup is enabled, we do not perform cache access checks here */ + uint32_t ignore_check_wakeup_triggers = 0; +#if SOC_PM_SUPPORT_EXT0_WAKEUP + ignore_check_wakeup_triggers |= RTC_EXT0_TRIG_EN; +#endif +#if SOC_PM_SUPPORT_EXT1_WAKEUP + ignore_check_wakeup_triggers |= RTC_EXT1_TRIG_EN; +#endif + if (!(s_config.wakeup_triggers & ignore_check_wakeup_triggers)) { + suspend_cache(); + } #endif // Decide which power domains can be powered down @@ -1463,7 +1476,9 @@ esp_err_t esp_light_sleep_start(void) #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION && CONFIG_PM_SLP_IRAM_OPT /* Cache Resume 0: sleep process done, resume cache for continue running */ - resume_cache(); + if (!(s_config.wakeup_triggers & ignore_check_wakeup_triggers)) { + resume_cache(); + } #endif #if !CONFIG_FREERTOS_UNICORE diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 97cbafd73b48..f3eb153a984c 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -73,14 +73,24 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_iomux_retention_init(v return ESP_OK; } -static __attribute__((unused)) esp_err_t sleep_sys_periph_spimem_retention_init(void *arg) +static __attribute__((unused)) esp_err_t sleep_sys_periph_flash_spimem_retention_init(void *arg) { - esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "SPI mem"); - ESP_LOGD(TAG, "SPI Mem sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(flash_spimem_regs_retention, ARRAY_SIZE(flash_spimem_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Flash SPI mem"); + ESP_LOGD(TAG, "Flash SPI Mem sleep retention initialization"); return ESP_OK; } +#if CONFIG_SPIRAM +static __attribute__((unused)) esp_err_t sleep_sys_periph_psram_spimem_retention_init(void *arg) +{ + esp_err_t err = sleep_retention_entries_create(psram_spimem_regs_retention, ARRAY_SIZE(psram_spimem_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "PSRAM SPI mem"); + ESP_LOGD(TAG, "PSRAM SPI Mem sleep retention initialization"); + return ESP_OK; +} +#endif + static __attribute__((unused)) esp_err_t sleep_sys_periph_systimer_retention_init(void *arg) { esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), REGDMA_LINK_PRI_SYS_PERIPH_LOW, SLEEP_RETENTION_MODULE_SYS_PERIPH); @@ -130,8 +140,12 @@ static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *a #endif err = sleep_sys_periph_iomux_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_spimem_retention_init(arg); + err = sleep_sys_periph_flash_spimem_retention_init(arg); + if(err) goto error; +#if CONFIG_SPIRAM + err = sleep_sys_periph_psram_spimem_retention_init(arg); if(err) goto error; +#endif err = sleep_sys_periph_systimer_retention_init(arg); if(err) goto error; #if SOC_PAU_IN_TOP_DOMAIN diff --git a/components/esp_hw_support/test_apps/dma/main/test_gdma.c b/components/esp_hw_support/test_apps/dma/main/test_gdma.c index d68d3a2ea0b0..b5638f6f5e64 100644 --- a/components/esp_hw_support/test_apps/dma/main/test_gdma.c +++ b/components/esp_hw_support/test_apps/dma/main/test_gdma.c @@ -13,6 +13,7 @@ #include "unity.h" #include "esp_heap_caps.h" #include "esp_private/gdma.h" +#include "esp_private/gdma_link.h" #include "hal/dma_types.h" #include "soc/soc_caps.h" #include "hal/gdma_ll.h" @@ -20,7 +21,6 @@ #include "hal/cache_hal.h" #include "esp_cache.h" #include "esp_memory_utils.h" -#include "soc/soc_caps.h" TEST_CASE("GDMA channel allocation", "[GDMA]") { @@ -155,8 +155,9 @@ static bool test_gdma_m2m_rx_eof_callback(gdma_channel_handle_t dma_chan, gdma_e return task_woken == pdTRUE; } -static void test_gdma_m2m_mode(gdma_channel_handle_t tx_chan, gdma_channel_handle_t rx_chan) +static void test_gdma_m2m_mode(gdma_channel_handle_t tx_chan, gdma_channel_handle_t rx_chan, bool dma_link_in_ext_mem) { + size_t sram_alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); gdma_rx_event_callbacks_t rx_cbs = { .on_recv_eof = test_gdma_m2m_rx_eof_callback, }; @@ -178,20 +179,37 @@ static void test_gdma_m2m_mode(gdma_channel_handle_t tx_chan, gdma_channel_handl TEST_ESP_OK(gdma_connect(tx_chan, m2m_trigger)); TEST_ESP_OK(gdma_connect(rx_chan, m2m_trigger)); - // allocate the source and destination buffer from SRAM - // |--------------------------------------------------| - // | 128 bytes DMA descriptor | 128 bytes data buffer | - // |--------------------------------------------------| - size_t sram_alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); - size_t alignment = MAX(sram_alignment, 8); - uint8_t *src_buf = heap_caps_aligned_calloc(alignment, 1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - uint8_t *dst_buf = heap_caps_aligned_calloc(alignment, 1, 384, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - TEST_ASSERT_NOT_NULL(src_buf); - TEST_ASSERT_NOT_NULL(dst_buf); - dma_descriptor_align8_t *tx_descs = (dma_descriptor_align8_t *) src_buf; - dma_descriptor_align8_t *rx_descs = (dma_descriptor_align8_t *) dst_buf; - uint8_t *src_data = src_buf + 128; - uint8_t *dst_data = dst_buf + 128; + // create DMA link list for TX channel (a singly link with 3 nodes) + gdma_link_list_config_t tx_link_list_config = { + .buffer_alignment = 1, + .item_alignment = 8, // 8-byte alignment required by the AXI-GDMA + .num_items = 3, + .flags = { + .items_in_ext_mem = dma_link_in_ext_mem, + .check_owner = true, + } + }; + gdma_link_list_handle_t tx_link_list = NULL; + TEST_ESP_OK(gdma_new_link_list(&tx_link_list_config, &tx_link_list)); + // allocate the source buffer from SRAM + uint8_t *src_data = heap_caps_calloc(1, 128, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(src_data); + + // create DMA link list for RX channel + gdma_link_list_config_t rx_link_list_config = { + .buffer_alignment = sram_alignment, // RX buffer should be aligned to the cache line size, because we will do cache invalidate later + .item_alignment = 8, // 8-byte alignment required by the AXI-GDMA + .num_items = 1, + .flags = { + .items_in_ext_mem = dma_link_in_ext_mem, + .check_owner = true, + }, + }; + gdma_link_list_handle_t rx_link_list = NULL; + TEST_ESP_OK(gdma_new_link_list(&rx_link_list_config, &rx_link_list)); + // allocate the destination buffer from SRAM + uint8_t *dst_data = heap_caps_calloc(1, 256, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + TEST_ASSERT_NOT_NULL(dst_data); // prepare the source data for (int i = 0; i < 128; i++) { @@ -199,64 +217,58 @@ static void test_gdma_m2m_mode(gdma_channel_handle_t tx_chan, gdma_channel_handl } if (sram_alignment) { // do write-back for the source data because it's in the cache - TEST_ESP_OK(esp_cache_msync((void *)src_data, 128, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + TEST_ESP_OK(esp_cache_msync(src_data, 128, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); } + // test DMA can read data from main flash #if SOC_DMA_CAN_ACCESS_FLASH - const char *src_string = "GDMA can fetch data from MSPI Flash"; + const char *src_string = "GDMA can read data from MSPI Flash"; size_t src_string_len = strlen(src_string); TEST_ASSERT_TRUE(esp_ptr_in_drom(src_string)); - // Only gonna copy length = src_string_len, set the character after to be 0xFF - // So that we can check if the copied length is correct + // Only gonna copy length = src_string_len, set the character after to be 0xFF as a canary dst_data[128 + src_string_len] = 0xFF; if (sram_alignment) { // do write-back for the dst data because it's in the cache - TEST_ESP_OK(esp_cache_msync((void *)dst_data, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); + TEST_ESP_OK(esp_cache_msync(dst_data, 256, ESP_CACHE_MSYNC_FLAG_DIR_C2M)); } #endif -#ifdef CACHE_LL_L2MEM_NON_CACHE_ADDR - dma_descriptor_align8_t *tx_descs_nc = (dma_descriptor_align8_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(tx_descs)); - dma_descriptor_align8_t *rx_descs_nc = (dma_descriptor_align8_t *)(CACHE_LL_L2MEM_NON_CACHE_ADDR(rx_descs)); -#else - dma_descriptor_align8_t *tx_descs_nc = tx_descs; - dma_descriptor_align8_t *rx_descs_nc = rx_descs; -#endif - - tx_descs_nc[0].buffer = src_data; - tx_descs_nc[0].dw0.size = 64; - tx_descs_nc[0].dw0.length = 64; - tx_descs_nc[0].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - tx_descs_nc[0].dw0.suc_eof = 0; - tx_descs_nc[0].next = &tx_descs[1]; // Note, the DMA doesn't recognize a non-cacheable address, here must be the cached address - - tx_descs_nc[1].buffer = src_data + 64; - tx_descs_nc[1].dw0.size = 64; - tx_descs_nc[1].dw0.length = 64; - tx_descs_nc[1].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + gdma_buffer_mount_config_t tx_buf_mount_config[] = { + [0] = { + .buffer = src_data, + .length = 64, + }, + [1] = { + .buffer = src_data + 64, + .length = 64, #if !SOC_DMA_CAN_ACCESS_FLASH - tx_descs_nc[1].dw0.suc_eof = 1; - tx_descs_nc[1].next = NULL; -#else - tx_descs_nc[1].dw0.suc_eof = 0; - tx_descs_nc[1].next = &tx_descs[2]; - - tx_descs_nc[2].buffer = (void *)src_string; - tx_descs_nc[2].dw0.size = src_string_len + 1; // +1 for '\0' - tx_descs_nc[2].dw0.length = src_string_len; - tx_descs_nc[2].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - tx_descs_nc[2].dw0.suc_eof = 1; - tx_descs_nc[2].next = NULL; + .flags = { + .mark_eof = true, + .mark_final = true, // using singly list, so terminate the link here + } +#endif + }, +#if SOC_DMA_CAN_ACCESS_FLASH + [2] = { + .buffer = (void *)src_string, + .length = src_string_len, + .flags = { + .mark_eof = true, + .mark_final = true, // using singly list, so terminate the link here + } + }, #endif + }; + TEST_ESP_OK(gdma_link_mount_buffers(tx_link_list, 0, tx_buf_mount_config, sizeof(tx_buf_mount_config) / sizeof(gdma_buffer_mount_config_t), NULL)); - rx_descs_nc->buffer = dst_data; - rx_descs_nc->dw0.size = 256; - rx_descs_nc->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - rx_descs_nc->dw0.suc_eof = 1; - rx_descs_nc->next = NULL; + gdma_buffer_mount_config_t rx_buf_mount_config = { + .buffer = dst_data, + .length = 256, + }; + TEST_ESP_OK(gdma_link_mount_buffers(rx_link_list, 0, &rx_buf_mount_config, 1, NULL)); - TEST_ESP_OK(gdma_start(rx_chan, (intptr_t)rx_descs)); - TEST_ESP_OK(gdma_start(tx_chan, (intptr_t)tx_descs)); + TEST_ESP_OK(gdma_start(rx_chan, gdma_link_get_head_addr(rx_link_list))); + TEST_ESP_OK(gdma_start(tx_chan, gdma_link_get_head_addr(tx_link_list))); xSemaphoreTake(done_sem, portMAX_DELAY); @@ -265,10 +277,14 @@ static void test_gdma_m2m_mode(gdma_channel_handle_t tx_chan, gdma_channel_handl TEST_ESP_OK(esp_cache_msync((void *)dst_data, 256, ESP_CACHE_MSYNC_FLAG_DIR_M2C)); } - // check the DMA descriptor write-back feature - TEST_ASSERT_EQUAL(DMA_DESCRIPTOR_BUFFER_OWNER_CPU, tx_descs_nc[0].dw0.owner); - TEST_ASSERT_EQUAL(DMA_DESCRIPTOR_BUFFER_OWNER_CPU, rx_descs_nc[0].dw0.owner); + // The owner bit should been written back by the DMA + gdma_lli_owner_t owner = GDMA_LLI_OWNER_DMA; + TEST_ESP_OK(gdma_link_get_owner(tx_link_list, 0, &owner)); + TEST_ASSERT_EQUAL(GDMA_LLI_OWNER_CPU, owner); + TEST_ESP_OK(gdma_link_get_owner(rx_link_list, 0, &owner)); + TEST_ASSERT_EQUAL(GDMA_LLI_OWNER_CPU, owner); + // validate the destination data for (int i = 0; i < 128; i++) { TEST_ASSERT_EQUAL(i, dst_data[i]); } @@ -277,8 +293,10 @@ static void test_gdma_m2m_mode(gdma_channel_handle_t tx_chan, gdma_channel_handl dst_data[128 + src_string_len] = '\0'; TEST_ASSERT_TRUE(strcmp(src_string, (const char *)((uint32_t)dst_data + 128)) == 0); #endif - free((void *)src_buf); - free((void *)dst_buf); + free(src_data); + free(dst_data); + TEST_ESP_OK(gdma_del_link_list(tx_link_list)); + TEST_ESP_OK(gdma_del_link_list(rx_link_list)); vSemaphoreDelete(done_sem); } @@ -301,7 +319,7 @@ TEST_CASE("GDMA M2M Mode", "[GDMA][M2M]") }; TEST_ESP_OK(gdma_new_ahb_channel(&rx_chan_alloc_config, &rx_chan)); - test_gdma_m2m_mode(tx_chan, rx_chan); + test_gdma_m2m_mode(tx_chan, rx_chan, false); TEST_ESP_OK(gdma_del_channel(tx_chan)); TEST_ESP_OK(gdma_del_channel(rx_chan)); @@ -319,7 +337,8 @@ TEST_CASE("GDMA M2M Mode", "[GDMA][M2M]") }; TEST_ESP_OK(gdma_new_axi_channel(&rx_chan_alloc_config, &rx_chan)); - test_gdma_m2m_mode(tx_chan, rx_chan); + // the AXI GDMA allows to put the DMA link list in the external memory + test_gdma_m2m_mode(tx_chan, rx_chan, true); TEST_ESP_OK(gdma_del_channel(tx_chan)); TEST_ESP_OK(gdma_del_channel(rx_chan)); diff --git a/components/esp_lcd/CMakeLists.txt b/components/esp_lcd/CMakeLists.txt index 3365a205ce52..c85bb0026ff4 100644 --- a/components/esp_lcd/CMakeLists.txt +++ b/components/esp_lcd/CMakeLists.txt @@ -26,13 +26,17 @@ if(CONFIG_SOC_GPSPI_SUPPORTED) list(APPEND srcs "spi/esp_lcd_panel_io_spi.c") endif() -if(CONFIG_SOC_I2S_LCD_I80_VARIANT) +if(CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA) list(APPEND srcs "i80/esp_lcd_panel_io_i2s.c") endif() -if(CONFIG_SOC_LCDCAM_SUPPORTED) +if(CONFIG_SOC_LCDCAM_I80_LCD_SUPPORTED) + list(APPEND srcs "i80/esp_lcd_panel_io_i80.c") +endif() + +if(CONFIG_SOC_LCDCAM_RGB_LCD_SUPPORTED) list(APPEND includes "rgb/include") - list(APPEND srcs "i80/esp_lcd_panel_io_i80.c" "rgb/esp_lcd_panel_rgb.c") + list(APPEND srcs "rgb/esp_lcd_panel_rgb.c") endif() if(CONFIG_SOC_MIPI_DSI_SUPPORTED) diff --git a/components/esp_lcd/Kconfig b/components/esp_lcd/Kconfig index 1f93e5e03615..c014ec2e4226 100644 --- a/components/esp_lcd/Kconfig +++ b/components/esp_lcd/Kconfig @@ -2,14 +2,6 @@ menu "LCD and Touch Panel" comment "LCD Touch Drivers are maintained in the IDF Component Registry" menu "LCD Peripheral Configuration" - config LCD_PANEL_IO_FORMAT_BUF_SIZE - depends on SOC_LCD_I80_SUPPORTED - int "LCD panel io format buffer size" - default 32 - help - LCD driver allocates an internal buffer to transform the data into a proper format, because of - the endian order mismatch. This option is to set the size of the buffer, in bytes. - config LCD_ENABLE_DEBUG_LOG bool "Enable debug log" default n diff --git a/components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h b/components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h index 0977468d2212..657f71583db3 100644 --- a/components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h +++ b/components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h @@ -88,7 +88,7 @@ typedef struct { By default (set to either 0 or 1) only one frame buffer will be created */ esp_lcd_video_timing_t video_timing; /*!< Video timing */ /// Extra configuration flags for MIPI DSI DPI panel - struct extra_flags { + struct extra_dpi_panel_flags { uint32_t use_dma2d: 1; /*!< Use DMA2D to copy user buffer to the frame buffer when necessary */ } flags; /*!< Extra configuration flags */ } esp_lcd_dpi_panel_config_t; diff --git a/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c b/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c index 68db94d8b34d..12199e3f6eb5 100644 --- a/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c @@ -33,17 +33,20 @@ #include "esp_lcd_common.h" #include "esp_rom_gpio.h" #include "soc/soc_caps.h" -#include "hal/dma_types.h" #include "hal/gpio_hal.h" #include "driver/gpio.h" #include "esp_clk_tree.h" #include "esp_private/periph_ctrl.h" #include "esp_private/i2s_platform.h" +#include "esp_private/gdma_link.h" #include "soc/lcd_periph.h" #include "hal/i2s_hal.h" #include "hal/i2s_ll.h" #include "hal/i2s_types.h" +// the DMA descriptor used by esp32 and esp32s2, each descriptor can carry 4095 bytes at most +#define LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE 4095 + static const char *TAG = "lcd_panel.io.i80"; typedef struct esp_lcd_i80_bus_t esp_lcd_i80_bus_t; @@ -71,6 +74,7 @@ struct esp_lcd_i80_bus_t { intr_handle_t intr; // LCD peripheral interrupt handle esp_pm_lock_handle_t pm_lock; // lock APB frequency when necessary size_t num_dma_nodes; // Number of DMA descriptors + gdma_link_list_handle_t dma_link; // DMA link list handle uint8_t *format_buffer;// The driver allocates an internal buffer for DMA to do data format transformer unsigned long resolution_hz; // LCD_CLK resolution, determined by selected clock source lcd_i80_trans_descriptor_t *cur_trans; // Current transaction @@ -79,7 +83,6 @@ struct esp_lcd_i80_bus_t { struct { unsigned int exclusive: 1; // Indicate whether the I80 bus is owned by one device (whose CS GPIO is not assigned) exclusively } flags; - dma_descriptor_t dma_nodes[]; // DMA descriptor pool, the descriptors are shared by all i80 devices }; struct lcd_i80_trans_descriptor_t { @@ -137,18 +140,28 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc // because one I2S FIFO (4 bytes) will only contain two bytes of valid data max_transfer_bytes = max_transfer_bytes * 16 / bus_config->bus_width + 4; #endif - size_t num_dma_nodes = max_transfer_bytes / DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1; - // DMA descriptors must be placed in internal SRAM - bus = heap_caps_calloc(1, sizeof(esp_lcd_i80_bus_t) + num_dma_nodes * sizeof(dma_descriptor_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + // allocate i80 bus memory + bus = heap_caps_calloc(1, sizeof(esp_lcd_i80_bus_t), LCD_I80_MEM_ALLOC_CAPS); ESP_GOTO_ON_FALSE(bus, ESP_ERR_NO_MEM, err, TAG, "no mem for i80 bus"); - bus->num_dma_nodes = num_dma_nodes; + size_t num_dma_nodes = max_transfer_bytes / LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1; + // create DMA link list + gdma_link_list_config_t dma_link_config = { + .buffer_alignment = 1, // no special buffer alignment for LCD TX buffer + .item_alignment = 4, // 4 bytes alignment for each DMA descriptor + .num_items = num_dma_nodes, + .flags = { + .check_owner = true, + }, + }; + ESP_GOTO_ON_ERROR(gdma_new_link_list(&dma_link_config, &bus->dma_link), err, TAG, "create DMA link list failed"); bus->bus_id = -1; + bus->num_dma_nodes = num_dma_nodes; #if SOC_I2S_TRANS_SIZE_ALIGN_WORD // transform format for LCD commands, parameters and color data, so we need a big buffer - bus->format_buffer = heap_caps_calloc(1, max_transfer_bytes, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + bus->format_buffer = heap_caps_calloc(1, max_transfer_bytes, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); #else // only transform format for LCD parameters, buffer size depends on specific LCD, set at compile time - bus->format_buffer = heap_caps_calloc(1, CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + bus->format_buffer = heap_caps_calloc(1, LCD_I80_IO_FORMAT_BUF_SIZE, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT | MALLOC_CAP_DMA); #endif // SOC_I2S_TRANS_SIZE_ALIGN_WORD ESP_GOTO_ON_FALSE(bus->format_buffer, ESP_ERR_NO_MEM, err, TAG, "no mem for format buffer"); // LCD mode can't work with other modes at the same time, we need to register the driver object to the I2S platform @@ -173,7 +186,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc // install interrupt service, (I2S LCD mode only uses the "TX Unit", which leaves "RX Unit" for other purpose) // So the interrupt should also be able to share with other functionality int isr_flags = LCD_I80_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED; - ret = esp_intr_alloc_intrstatus(lcd_periph_signals.buses[bus->bus_id].irq_id, isr_flags, + ret = esp_intr_alloc_intrstatus(lcd_periph_i2s_signals.buses[bus->bus_id].irq_id, isr_flags, (uint32_t)i2s_ll_get_intr_status_reg(bus->hal.dev), I2S_LL_EVENT_TX_EOF, lcd_default_isr_handler, bus, &bus->intr); ESP_GOTO_ON_ERROR(ret, err, TAG, "install interrupt failed"); @@ -207,11 +220,14 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc bus->dc_gpio_num = bus_config->dc_gpio_num; bus->wr_gpio_num = bus_config->wr_gpio_num; *ret_bus = bus; - ESP_LOGD(TAG, "new i80 bus(%d) @%p, %zu dma nodes, resolution %luHz", bus->bus_id, bus, bus->num_dma_nodes, bus->resolution_hz); + ESP_LOGD(TAG, "new i80 bus(%d) @%p, %zu dma nodes, resolution %luHz", bus->bus_id, bus, num_dma_nodes, bus->resolution_hz); return ESP_OK; err: if (bus) { + if (bus->dma_link) { + gdma_del_link_list(bus->dma_link); + } if (bus->intr) { esp_intr_free(bus->intr); } @@ -241,6 +257,7 @@ esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus) esp_pm_lock_delete(bus->pm_lock); } free(bus->format_buffer); + gdma_del_link_list(bus->dma_link); free(bus); ESP_LOGD(TAG, "del i80 bus(%d)", bus_id); err: @@ -497,8 +514,8 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons esp_lcd_i80_bus_t *bus = next_device->bus; lcd_panel_io_i80_t *cur_device = bus->cur_device; lcd_i80_trans_descriptor_t *trans_desc = NULL; - assert(param_size <= (bus->num_dma_nodes * DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && "parameter bytes too long, enlarge max_transfer_bytes"); - assert(param_size <= CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE && "format buffer too small, increase CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE"); + assert(param_size <= (bus->num_dma_nodes * LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && "parameter bytes too long, enlarge max_transfer_bytes"); + assert(param_size <= LCD_I80_IO_FORMAT_BUF_SIZE && "format buffer too small, increase LCD_I80_IO_FORMAT_BUF_SIZE"); size_t num_trans_inflight = next_device->num_trans_inflight; // before issue a polling transaction, need to wait queued transactions finished for (size_t i = 0; i < num_trans_inflight; i++) { @@ -507,6 +524,13 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons next_device->num_trans_inflight--; } + gdma_buffer_mount_config_t mount_config = { + .flags = { + .mark_eof = true, + .mark_final = true, // singly link list, mark final descriptor + } + }; + i2s_ll_clear_intr_status(bus->hal.dev, I2S_LL_EVENT_TX_EOF); // switch devices if necessary lcd_i80_switch_devices(cur_device, next_device); @@ -519,7 +543,9 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons i2s_ll_tx_set_bits_mod(bus->hal.dev, 32); #endif i2s_lcd_prepare_cmd_buffer(trans_desc, &lcd_cmd); - lcd_com_mount_dma_data(bus->dma_nodes, trans_desc->data, trans_desc->data_length); + mount_config.buffer = (void *)trans_desc->data; + mount_config.length = trans_desc->data_length; + gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL); gpio_set_level(bus->dc_gpio_num, next_device->dc_levels.dc_cmd_level); i2s_ll_tx_stop(bus->hal.dev); i2s_ll_tx_reset(bus->hal.dev); // reset TX engine first @@ -539,7 +565,9 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons if (param && param_size) { i2s_ll_clear_intr_status(bus->hal.dev, I2S_LL_EVENT_TX_EOF); i2s_lcd_prepare_param_buffer(trans_desc, param, param_size * 8 / next_device->lcd_param_bits); - lcd_com_mount_dma_data(bus->dma_nodes, trans_desc->data, trans_desc->data_length); + mount_config.buffer = (void *)trans_desc->data; + mount_config.length = trans_desc->data_length; + gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL); gpio_set_level(bus->dc_gpio_num, next_device->dc_levels.dc_data_level); i2s_ll_tx_stop(bus->hal.dev); i2s_ll_tx_reset(bus->hal.dev); // reset TX engine first @@ -563,7 +591,7 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons esp_lcd_i80_bus_t *bus = next_device->bus; lcd_panel_io_i80_t *cur_device = bus->cur_device; lcd_i80_trans_descriptor_t *trans_desc = NULL; - assert(color_size <= (bus->num_dma_nodes * DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && "color bytes too long, enlarge max_transfer_bytes"); + assert(color_size <= (bus->num_dma_nodes * LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && "color bytes too long, enlarge max_transfer_bytes"); size_t num_trans_inflight = next_device->num_trans_inflight; // before issue a polling transaction, need to wait queued transactions finished for (size_t i = 0; i < num_trans_inflight; i++) { @@ -572,6 +600,13 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons next_device->num_trans_inflight--; } + gdma_buffer_mount_config_t mount_config = { + .flags = { + .mark_eof = true, + .mark_final = true, // singly link list, mark final descriptor + } + }; + i2s_ll_clear_intr_status(bus->hal.dev, I2S_LL_EVENT_TX_EOF); // switch devices if necessary lcd_i80_switch_devices(cur_device, next_device); @@ -584,7 +619,9 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons i2s_ll_tx_set_bits_mod(bus->hal.dev, 32); #endif i2s_lcd_prepare_cmd_buffer(trans_desc, &lcd_cmd); - lcd_com_mount_dma_data(bus->dma_nodes, trans_desc->data, trans_desc->data_length); + mount_config.buffer = (void *)trans_desc->data; + mount_config.length = trans_desc->data_length; + gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL); gpio_set_level(bus->dc_gpio_num, next_device->dc_levels.dc_cmd_level); i2s_ll_tx_stop(bus->hal.dev); i2s_ll_tx_reset(bus->hal.dev); // reset TX engine first @@ -640,15 +677,10 @@ static esp_err_t i2s_lcd_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c static esp_err_t i2s_lcd_init_dma_link(esp_lcd_i80_bus_handle_t bus) { - for (int i = 0; i < bus->num_dma_nodes; i++) { - bus->dma_nodes[i].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_CPU; - bus->dma_nodes[i].next = &bus->dma_nodes[i + 1]; - } - bus->dma_nodes[bus->num_dma_nodes - 1].next = NULL; // one-off DMA chain i2s_ll_dma_enable_eof_on_fifo_empty(bus->hal.dev, true); i2s_ll_dma_enable_owner_check(bus->hal.dev, true); i2s_ll_dma_enable_auto_write_back(bus->hal.dev, true); - i2s_ll_set_out_link_addr(bus->hal.dev, (uint32_t)bus->dma_nodes); + i2s_ll_set_out_link_addr(bus->hal.dev, gdma_link_get_head_addr(bus->dma_link)); i2s_ll_enable_dma(bus->hal.dev, true); return ESP_OK; } @@ -669,15 +701,15 @@ static esp_err_t i2s_lcd_configure_gpio(esp_lcd_i80_bus_handle_t bus, const esp_ for (size_t i = 0; i < bus_config->bus_width; i++) { gpio_set_direction(bus_config->data_gpio_nums[i], GPIO_MODE_OUTPUT); #if SOC_I2S_TRANS_SIZE_ALIGN_WORD - esp_rom_gpio_connect_out_signal(bus_config->data_gpio_nums[i], lcd_periph_signals.buses[bus_id].data_sigs[i + 8], false, false); + esp_rom_gpio_connect_out_signal(bus_config->data_gpio_nums[i], lcd_periph_i2s_signals.buses[bus_id].data_sigs[i + 8], false, false); #else - esp_rom_gpio_connect_out_signal(bus_config->data_gpio_nums[i], lcd_periph_signals.buses[bus_id].data_sigs[i + SOC_LCD_I80_BUS_WIDTH - bus_config->bus_width], false, false); + esp_rom_gpio_connect_out_signal(bus_config->data_gpio_nums[i], lcd_periph_i2s_signals.buses[bus_id].data_sigs[i + SOC_I2S_MAX_DATA_WIDTH - bus_config->bus_width], false, false); #endif gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[bus_config->data_gpio_nums[i]], PIN_FUNC_GPIO); } // WR signal (pclk) gpio_set_direction(bus_config->wr_gpio_num, GPIO_MODE_OUTPUT); - esp_rom_gpio_connect_out_signal(bus_config->wr_gpio_num, lcd_periph_signals.buses[bus_id].wr_sig, true, false); + esp_rom_gpio_connect_out_signal(bus_config->wr_gpio_num, lcd_periph_i2s_signals.buses[bus_id].wr_sig, true, false); gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[bus_config->wr_gpio_num], PIN_FUNC_GPIO); // DC signal is controlled by software, set as general purpose IO gpio_set_direction(bus_config->dc_gpio_num, GPIO_MODE_OUTPUT); @@ -691,7 +723,15 @@ static void i2s_lcd_trigger_quick_trans_done_event(esp_lcd_i80_bus_handle_t bus) // next time when esp_intr_enable is invoked, we can go into interrupt handler immediately // where we dispatch transactions for i80 devices static uint32_t fake_trigger = 0; - lcd_com_mount_dma_data(bus->dma_nodes, &fake_trigger, 4); + gdma_buffer_mount_config_t mount_config = { + .buffer = &fake_trigger, + .length = 4, + .flags = { + .mark_eof = true, // mark the "EOF" flag to trigger I2S EOF interrupt + .mark_final = true, // singly link list, mark final descriptor + } + }; + gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL); i2s_ll_start_out_link(bus->hal.dev); i2s_ll_tx_start(bus->hal.dev); while (!(i2s_ll_get_intr_status(bus->hal.dev) & I2S_LL_EVENT_TX_EOF)) {} @@ -712,7 +752,7 @@ static void lcd_i80_switch_devices(lcd_panel_io_i80_t *cur_device, lcd_panel_io_ } // the WR signal (a.k.a the PCLK) generated by I2S is low level in idle stage // but most of 8080 LCDs require the WR line to be in high level during idle stage - esp_rom_gpio_connect_out_signal(bus->wr_gpio_num, lcd_periph_signals.buses[bus->bus_id].wr_sig, !next_device->flags.pclk_idle_low, false); + esp_rom_gpio_connect_out_signal(bus->wr_gpio_num, lcd_periph_i2s_signals.buses[bus->bus_id].wr_sig, !next_device->flags.pclk_idle_low, false); } bus->cur_device = next_device; } @@ -769,7 +809,15 @@ static IRAM_ATTR void lcd_default_isr_handler(void *args) bus->cur_trans = trans_desc; gpio_set_level(bus->dc_gpio_num, trans_desc->flags.dc_level); // mount data to DMA links - lcd_com_mount_dma_data(bus->dma_nodes, trans_desc->data, trans_desc->data_length); + gdma_buffer_mount_config_t mount_config = { + .buffer = (void *)trans_desc->data, + .length = trans_desc->data_length, + .flags = { + .mark_eof = true, + .mark_final = true, // singly link list, mark final descriptor + } + }; + gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL); #if SOC_I2S_TRANS_SIZE_ALIGN_WORD // switch to I2S 16bits mode, two WS cycle <=> one I2S FIFO i2s_ll_tx_set_bits_mod(bus->hal.dev, 16); diff --git a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c index 8e7e50ed6f0f..99af62c9c261 100644 --- a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c @@ -28,18 +28,37 @@ #include "esp_clk_tree.h" #include "esp_memory_utils.h" #include "esp_cache.h" -#include "hal/dma_types.h" -#include "hal/gpio_hal.h" -#include "esp_private/gdma.h" #include "driver/gpio.h" +#include "esp_private/gpio.h" +#include "esp_private/gdma.h" +#include "esp_private/gdma_link.h" #include "esp_private/periph_ctrl.h" #include "esp_lcd_common.h" #include "soc/lcd_periph.h" +#include "soc/io_mux_reg.h" +#include "soc/gpio_sig_map.h" #include "hal/lcd_ll.h" #include "hal/lcd_hal.h" +#include "hal/cache_ll.h" +#include "hal/cache_hal.h" + +#define LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE 4095 + +#if defined(SOC_GDMA_TRIG_PERIPH_LCD0_BUS) && (SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AHB) +#define LCD_GDMA_NEW_CHANNEL gdma_new_ahb_channel +#define LCD_GDMA_DESCRIPTOR_ALIGN 4 +#elif defined(SOC_GDMA_TRIG_PERIPH_LCD0_BUS) && (SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AXI) +#define LCD_GDMA_NEW_CHANNEL gdma_new_axi_channel +#define LCD_GDMA_DESCRIPTOR_ALIGN 8 +#else +#error "Unsupported GDMA bus type for LCD i80" +#endif -#define ALIGN_UP(size, align) (((size) + (align) - 1) & ~((align) - 1)) -#define ALIGN_DOWN(size, align) ((size) & ~((align) - 1)) +#if SOC_NON_CACHEABLE_OFFSET +#define LCD_CACHE_ADDR_TO_NON_CACHE_ADDR(addr) ((addr) + SOC_NON_CACHEABLE_OFFSET) +#else +#define LCD_CACHE_ADDR_TO_NON_CACHE_ADDR(addr) (addr) +#endif static const char *TAG = "lcd_panel.io.i80"; @@ -66,19 +85,20 @@ struct esp_lcd_i80_bus_t { size_t bus_width; // Number of data lines intr_handle_t intr; // LCD peripheral interrupt handle esp_pm_lock_handle_t pm_lock; // Power management lock - size_t num_dma_nodes; // Number of DMA descriptors uint8_t *format_buffer; // The driver allocates an internal buffer for DMA to do data format transformer + uint8_t *format_buffer_nc; // Non-cacheable version of format buffer size_t resolution_hz; // LCD_CLK resolution, determined by selected clock source + size_t num_dma_nodes; // Number of DMA nodes (descriptors) gdma_channel_handle_t dma_chan; // DMA channel handle + gdma_link_list_handle_t dma_link; // DMA link list handle size_t int_mem_align; // Alignment for internal memory size_t ext_mem_align; // Alignment for external memory lcd_i80_trans_descriptor_t *cur_trans; // Current transaction lcd_panel_io_i80_t *cur_device; // Current working device LIST_HEAD(i80_device_list, lcd_panel_io_i80_t) device_list; // Head of i80 device list struct { - unsigned int exclusive: 1; // Indicate whether the I80 bus is owned by one device (whose CS GPIO is not assigned) exclusively + uint32_t exclusive: 1; // Indicate whether the I80 bus is owned by one device (whose CS GPIO is not assigned) exclusively } flags; - dma_descriptor_t dma_nodes[]; // DMA descriptor pool, the descriptors are shared by all i80 devices }; struct lcd_i80_trans_descriptor_t { @@ -133,20 +153,39 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc // although LCD_CAM can support up to 24 data lines, we restrict users to only use 8 or 16 bit width ESP_RETURN_ON_FALSE(bus_config->bus_width == 8 || bus_config->bus_width == 16, ESP_ERR_INVALID_ARG, TAG, "invalid bus width:%d", bus_config->bus_width); - size_t num_dma_nodes = bus_config->max_transfer_bytes / DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1; - // DMA descriptors must be placed in internal SRAM - bus = heap_caps_calloc(1, sizeof(esp_lcd_i80_bus_t) + num_dma_nodes * sizeof(dma_descriptor_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + // allocate i80 bus memory + bus = heap_caps_calloc(1, sizeof(esp_lcd_i80_bus_t), LCD_I80_MEM_ALLOC_CAPS); ESP_GOTO_ON_FALSE(bus, ESP_ERR_NO_MEM, err, TAG, "no mem for i80 bus"); + size_t num_dma_nodes = bus_config->max_transfer_bytes / LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE + 1; + // create DMA link list + gdma_link_list_config_t dma_link_config = { + .buffer_alignment = 1, // no special buffer alignment for LCD TX buffer + .item_alignment = LCD_GDMA_DESCRIPTOR_ALIGN, + .num_items = num_dma_nodes, + .flags = { + .check_owner = true, + }, + }; + ESP_GOTO_ON_ERROR(gdma_new_link_list(&dma_link_config, &bus->dma_link), err, TAG, "create DMA link list failed"); bus->num_dma_nodes = num_dma_nodes; + bus->bus_width = bus_config->bus_width; bus->bus_id = -1; - bus->format_buffer = heap_caps_calloc(1, CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); + // allocate the format buffer from internal memory, with DMA capability + bus->format_buffer = heap_caps_calloc(1, LCD_I80_IO_FORMAT_BUF_SIZE, + MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA); ESP_GOTO_ON_FALSE(bus->format_buffer, ESP_ERR_NO_MEM, err, TAG, "no mem for format buffer"); + // if the buffer is behind the cache, write it back to the underlying memory + if (cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA) > 0) { + esp_cache_msync(bus->format_buffer, LCD_I80_IO_FORMAT_BUF_SIZE, + ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); + } + bus->format_buffer_nc = LCD_CACHE_ADDR_TO_NON_CACHE_ADDR(bus->format_buffer); // register to platform int bus_id = lcd_com_register_device(LCD_COM_DEVICE_TYPE_I80, bus); ESP_GOTO_ON_FALSE(bus_id >= 0, ESP_ERR_NOT_FOUND, err, TAG, "no free i80 bus slot"); bus->bus_id = bus_id; // enable APB to access LCD registers - PERIPH_RCC_ACQUIRE_ATOMIC(lcd_periph_signals.panels[bus_id].module, ref_count) { + PERIPH_RCC_ACQUIRE_ATOMIC(lcd_periph_i80_signals.buses[bus_id].module, ref_count) { if (ref_count == 0) { lcd_ll_enable_bus_clock(bus_id, true); lcd_ll_reset_register(bus_id); @@ -166,14 +205,13 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc // install interrupt service, (LCD peripheral shares the same interrupt source with Camera peripheral with different mask) // interrupt is disabled by default int isr_flags = LCD_I80_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED; - ret = esp_intr_alloc_intrstatus(lcd_periph_signals.buses[bus_id].irq_id, isr_flags, + ret = esp_intr_alloc_intrstatus(lcd_periph_i80_signals.buses[bus_id].irq_id, isr_flags, (uint32_t)lcd_ll_get_interrupt_status_reg(bus->hal.dev), LCD_LL_EVENT_TRANS_DONE, lcd_default_isr_handler, bus, &bus->intr); ESP_GOTO_ON_ERROR(ret, err, TAG, "install interrupt failed"); lcd_ll_enable_interrupt(bus->hal.dev, LCD_LL_EVENT_TRANS_DONE, false); // disable all interrupts lcd_ll_clear_interrupt_status(bus->hal.dev, UINT32_MAX); // clear pending interrupt // install DMA service - bus->bus_width = bus_config->bus_width; ret = lcd_i80_init_dma_link(bus, bus_config); ESP_GOTO_ON_ERROR(ret, err, TAG, "install DMA failed"); // disable RGB-LCD mode @@ -210,8 +248,11 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc gdma_disconnect(bus->dma_chan); gdma_del_channel(bus->dma_chan); } + if (bus->dma_link) { + gdma_del_link_list(bus->dma_link); + } if (bus->bus_id >= 0) { - PERIPH_RCC_RELEASE_ATOMIC(lcd_periph_signals.panels[bus->bus_id].module, ref_count) { + PERIPH_RCC_RELEASE_ATOMIC(lcd_periph_i80_signals.buses[bus->bus_id].module, ref_count) { if (ref_count == 0) { lcd_ll_enable_bus_clock(bus->bus_id, false); } @@ -236,7 +277,7 @@ esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus) ESP_GOTO_ON_FALSE(LIST_EMPTY(&bus->device_list), ESP_ERR_INVALID_STATE, err, TAG, "device list not empty"); int bus_id = bus->bus_id; lcd_com_remove_device(LCD_COM_DEVICE_TYPE_I80, bus_id); - PERIPH_RCC_RELEASE_ATOMIC(lcd_periph_signals.panels[bus_id].module, ref_count) { + PERIPH_RCC_RELEASE_ATOMIC(lcd_periph_i80_signals.buses[bus_id].module, ref_count) { if (ref_count == 0) { lcd_ll_enable_bus_clock(bus_id, false); } @@ -248,6 +289,7 @@ esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus) if (bus->pm_lock) { esp_pm_lock_delete(bus->pm_lock); } + gdma_del_link_list(bus->dma_link); free(bus); ESP_LOGD(TAG, "del i80 bus(%d)", bus_id); err: @@ -314,7 +356,7 @@ esp_err_t esp_lcd_new_panel_io_i80(esp_lcd_i80_bus_handle_t bus, const esp_lcd_p if (io_config->cs_gpio_num >= 0) { gpio_set_level(io_config->cs_gpio_num, !io_config->flags.cs_active_high); gpio_set_direction(io_config->cs_gpio_num, GPIO_MODE_OUTPUT); - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[io_config->cs_gpio_num], PIN_FUNC_GPIO); + gpio_func_sel(io_config->cs_gpio_num, PIN_FUNC_GPIO); } *ret_io = &(i80_device->base); ESP_LOGD(TAG, "new i80 lcd panel io @%p on bus(%d)", i80_device, bus->bus_id); @@ -393,7 +435,8 @@ static uint32_t i80_lcd_prepare_param_buffer(esp_lcd_i80_bus_t *bus, lcd_panel_i int param_per_size = i80_device->lcd_param_bits / 8; int param_num = param_size / param_per_size; const uint8_t *from = (const uint8_t *)lcd_param; - uint8_t *to = bus->format_buffer; + // we use non-cacheable address to write to the format buffer, for simplicity + uint8_t *to = bus->format_buffer_nc; uint8_t step = bus->bus_width / 8; int param_cycle = i80_device->lcd_param_bits / bus->bus_width; // in case bus_width=16 and param_bits=8, we still need 1 param_cycle @@ -410,7 +453,7 @@ static uint32_t i80_lcd_prepare_param_buffer(esp_lcd_i80_bus_t *bus, lcd_panel_i } to += step; } - return to - bus->format_buffer; + return to - bus->format_buffer_nc; } static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, const void *param, size_t param_size) @@ -419,8 +462,8 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons esp_lcd_i80_bus_t *bus = next_device->bus; lcd_panel_io_i80_t *cur_device = bus->cur_device; lcd_i80_trans_descriptor_t *trans_desc = NULL; - assert(param_size <= (bus->num_dma_nodes * DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && "parameter bytes too long, enlarge max_transfer_bytes"); - assert(param_size <= CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE && "format buffer too small, increase CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE"); + assert(param_size <= (bus->num_dma_nodes * LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && "parameter bytes too long, enlarge max_transfer_bytes"); + assert(param_size <= LCD_I80_IO_FORMAT_BUF_SIZE && "format buffer too small, increase LCD_I80_IO_FORMAT_BUF_SIZE"); uint32_t cmd_cycles = next_device->lcd_cmd_bits / bus->bus_width; // in case bus_width=16 and cmd_bits=8, we still need 1 cmd_cycle if (cmd_cycles * bus->bus_width < next_device->lcd_cmd_bits) { @@ -456,7 +499,15 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons trans_desc->data_length = trans_desc->data ? param_len : 0; trans_desc->trans_done_cb = NULL; // no callback for parameter transaction // mount data to DMA links - lcd_com_mount_dma_data(bus->dma_nodes, trans_desc->data, trans_desc->data_length); + gdma_buffer_mount_config_t mount_config = { + .buffer = (void *)trans_desc->data, + .length = trans_desc->data_length, + .flags = { + .mark_eof = true, + .mark_final = true, // singly link list, mark final descriptor + } + }; + gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL); // increase the pm lock reference count before starting a new transaction if (bus->pm_lock) { esp_pm_lock_acquire(bus->pm_lock); @@ -476,17 +527,22 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons lcd_panel_io_i80_t *i80_device = __containerof(io, lcd_panel_io_i80_t, base); esp_lcd_i80_bus_t *bus = i80_device->bus; lcd_i80_trans_descriptor_t *trans_desc = NULL; - assert(color_size <= (bus->num_dma_nodes * DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && "color bytes too long, enlarge max_transfer_bytes"); + assert(color_size <= (bus->num_dma_nodes * LCD_DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && "color bytes too long, enlarge max_transfer_bytes"); + uint32_t cache_line_size = 0; if (esp_ptr_external_ram(color)) { // check alignment ESP_RETURN_ON_FALSE(((uint32_t)color & (bus->ext_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color address not aligned"); ESP_RETURN_ON_FALSE((color_size & (bus->ext_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color size not aligned"); - // flush frame buffer from cache to the physical PSRAM - esp_cache_msync((void *)color, color_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); + cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_DATA); } else { // check alignment ESP_RETURN_ON_FALSE(((uint32_t)color & (bus->int_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color address not aligned"); ESP_RETURN_ON_FALSE((color_size & (bus->int_mem_align - 1)) == 0, ESP_ERR_INVALID_ARG, TAG, "color size not aligned"); + cache_line_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + } + if (cache_line_size > 0) { + // flush data from cache to the physical memory + esp_cache_msync((void *)color, color_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); } // in case bus_width=16 and cmd_bits=8, we still need 1 cmd_cycle @@ -546,21 +602,11 @@ static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c static esp_err_t lcd_i80_init_dma_link(esp_lcd_i80_bus_handle_t bus, const esp_lcd_i80_bus_config_t *bus_config) { esp_err_t ret = ESP_OK; - // chain DMA descriptors - for (int i = 0; i < bus->num_dma_nodes; i++) { - bus->dma_nodes[i].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_CPU; - bus->dma_nodes[i].next = &bus->dma_nodes[i + 1]; - } - bus->dma_nodes[bus->num_dma_nodes - 1].next = NULL; // one-off DMA chain // alloc DMA channel and connect to LCD peripheral gdma_channel_alloc_config_t dma_chan_config = { .direction = GDMA_CHANNEL_DIRECTION_TX, }; -#if SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AHB - ret = gdma_new_ahb_channel(&dma_chan_config, &bus->dma_chan); -#elif SOC_GDMA_TRIG_PERIPH_LCD0_BUS == SOC_GDMA_BUS_AXI - ret = gdma_new_axi_channel(&dma_chan_config, &bus->dma_chan); -#endif + ret = LCD_GDMA_NEW_CHANNEL(&dma_chan_config, &bus->dma_chan); ESP_GOTO_ON_ERROR(ret, err, TAG, "alloc DMA channel failed"); gdma_connect(bus->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_LCD, 0)); gdma_strategy_config_t strategy_config = { @@ -614,15 +660,15 @@ static esp_err_t lcd_i80_bus_configure_gpio(esp_lcd_i80_bus_handle_t bus, const // connect peripheral signals via GPIO matrix for (size_t i = 0; i < bus_config->bus_width; i++) { gpio_set_direction(bus_config->data_gpio_nums[i], GPIO_MODE_OUTPUT); - esp_rom_gpio_connect_out_signal(bus_config->data_gpio_nums[i], lcd_periph_signals.buses[bus_id].data_sigs[i], false, false); - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[bus_config->data_gpio_nums[i]], PIN_FUNC_GPIO); + esp_rom_gpio_connect_out_signal(bus_config->data_gpio_nums[i], lcd_periph_i80_signals.buses[bus_id].data_sigs[i], false, false); + gpio_func_sel(bus_config->data_gpio_nums[i], PIN_FUNC_GPIO); } gpio_set_direction(bus_config->dc_gpio_num, GPIO_MODE_OUTPUT); - esp_rom_gpio_connect_out_signal(bus_config->dc_gpio_num, lcd_periph_signals.buses[bus_id].dc_sig, false, false); - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[bus_config->dc_gpio_num], PIN_FUNC_GPIO); + esp_rom_gpio_connect_out_signal(bus_config->dc_gpio_num, lcd_periph_i80_signals.buses[bus_id].dc_sig, false, false); + gpio_func_sel(bus_config->dc_gpio_num, PIN_FUNC_GPIO); gpio_set_direction(bus_config->wr_gpio_num, GPIO_MODE_OUTPUT); - esp_rom_gpio_connect_out_signal(bus_config->wr_gpio_num, lcd_periph_signals.buses[bus_id].wr_sig, false, false); - gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[bus_config->wr_gpio_num], PIN_FUNC_GPIO); + esp_rom_gpio_connect_out_signal(bus_config->wr_gpio_num, lcd_periph_i80_signals.buses[bus_id].wr_sig, false, false); + gpio_func_sel(bus_config->wr_gpio_num, PIN_FUNC_GPIO); return ESP_OK; } @@ -649,8 +695,11 @@ static void lcd_start_transaction(esp_lcd_i80_bus_t *bus, lcd_i80_trans_descript lcd_ll_set_phase_cycles(bus->hal.dev, cmd_cycles, dummy_cycles, data_cycles); lcd_ll_set_blank_cycles(bus->hal.dev, 1, 1); + // reset FIFO before starting a new transaction + lcd_ll_fifo_reset(bus->hal.dev); + if (trans_desc->data) { // some specific LCD commands can have no parameters - gdma_start(bus->dma_chan, (intptr_t)(bus->dma_nodes)); + gdma_start(bus->dma_chan, gdma_link_get_head_addr(bus->dma_link)); // delay 1us is sufficient for DMA to pass data to LCD FIFO // in fact, this is only needed when LCD pixel clock is set too high esp_rom_delay_us(1); @@ -676,7 +725,7 @@ static void lcd_i80_switch_devices(lcd_panel_io_i80_t *cur_device, lcd_panel_io_ } if (next_device->cs_gpio_num >= 0) { // connect CS signal to the new device - esp_rom_gpio_connect_out_signal(next_device->cs_gpio_num, lcd_periph_signals.buses[bus->bus_id].cs_sig, + esp_rom_gpio_connect_out_signal(next_device->cs_gpio_num, lcd_periph_i80_signals.buses[bus->bus_id].cs_sig, next_device->flags.cs_active_high, false); } } @@ -738,7 +787,15 @@ IRAM_ATTR static void lcd_default_isr_handler(void *args) bus->cur_trans = trans_desc; bus->cur_device = next_device; // mount data to DMA links - lcd_com_mount_dma_data(bus->dma_nodes, trans_desc->data, trans_desc->data_length); + gdma_buffer_mount_config_t mount_config = { + .buffer = (void *)trans_desc->data, + .length = trans_desc->data_length, + .flags = { + .mark_eof = true, + .mark_final = true, // singly link list, mark final descriptor + } + }; + gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL); // enable interrupt again, because the new transaction can trigger new trans done event esp_intr_enable(bus->intr); // increase the pm lock reference count before starting a new transaction diff --git a/components/esp_lcd/priv_include/esp_lcd_common.h b/components/esp_lcd/priv_include/esp_lcd_common.h index ecce3c62d9b7..a7b8ae6161ef 100644 --- a/components/esp_lcd/priv_include/esp_lcd_common.h +++ b/components/esp_lcd/priv_include/esp_lcd_common.h @@ -19,6 +19,9 @@ extern "C" { #endif +// size of the internal buffer to transform the data into a proper format (e.g. data endian) +#define LCD_I80_IO_FORMAT_BUF_SIZE 32 + #define LCD_I80_INTR_ALLOC_FLAGS ESP_INTR_FLAG_INTRDISABLED #define LCD_I80_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT diff --git a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c index a12f244229dc..f34bb2d2e37b 100644 --- a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c @@ -196,7 +196,7 @@ static esp_err_t lcd_rgb_panel_destroy(esp_rgb_panel_t *rgb_panel) lcd_ll_enable_clock(rgb_panel->hal.dev, false); } if (rgb_panel->panel_id >= 0) { - PERIPH_RCC_RELEASE_ATOMIC(lcd_periph_signals.panels[rgb_panel->panel_id].module, ref_count) { + PERIPH_RCC_RELEASE_ATOMIC(lcd_periph_rgb_signals.panels[rgb_panel->panel_id].module, ref_count) { if (ref_count == 0) { lcd_ll_enable_bus_clock(rgb_panel->panel_id, false); } @@ -306,7 +306,7 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf rgb_panel->panel_id = panel_id; // enable APB to access LCD registers - PERIPH_RCC_ACQUIRE_ATOMIC(lcd_periph_signals.panels[panel_id].module, ref_count) { + PERIPH_RCC_ACQUIRE_ATOMIC(lcd_periph_rgb_signals.panels[panel_id].module, ref_count) { if (ref_count == 0) { lcd_ll_enable_bus_clock(panel_id, true); lcd_ll_reset_register(panel_id); @@ -332,7 +332,7 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf } // install interrupt service, (LCD peripheral shares the interrupt source with Camera by different mask) int isr_flags = LCD_RGB_INTR_ALLOC_FLAGS | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED; - ret = esp_intr_alloc_intrstatus(lcd_periph_signals.panels[panel_id].irq_id, isr_flags, + ret = esp_intr_alloc_intrstatus(lcd_periph_rgb_signals.panels[panel_id].irq_id, isr_flags, (uint32_t)lcd_ll_get_interrupt_status_reg(rgb_panel->hal.dev), LCD_LL_EVENT_VSYNC_END, lcd_default_isr_handler, rgb_panel, &rgb_panel->intr); ESP_GOTO_ON_ERROR(ret, err, TAG, "install interrupt failed"); @@ -801,7 +801,7 @@ static esp_err_t rgb_panel_invert_color(esp_lcd_panel_t *panel, bool invert_colo // inverting the data line by GPIO matrix for (int i = 0; i < rgb_panel->data_width; i++) { if (rgb_panel->data_gpio_nums[i] >= 0) { - esp_rom_gpio_connect_out_signal(rgb_panel->data_gpio_nums[i], lcd_periph_signals.panels[panel_id].data_sigs[i], + esp_rom_gpio_connect_out_signal(rgb_panel->data_gpio_nums[i], lcd_periph_rgb_signals.panels[panel_id].data_sigs[i], invert_color_data, false); } } @@ -857,34 +857,34 @@ static esp_err_t lcd_rgb_panel_configure_gpio(esp_rgb_panel_t *panel, const esp_ gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[panel_config->data_gpio_nums[i]], PIN_FUNC_GPIO); gpio_set_direction(panel_config->data_gpio_nums[i], GPIO_MODE_OUTPUT); esp_rom_gpio_connect_out_signal(panel_config->data_gpio_nums[i], - lcd_periph_signals.panels[panel_id].data_sigs[i], false, false); + lcd_periph_rgb_signals.panels[panel_id].data_sigs[i], false, false); } } if (panel_config->hsync_gpio_num >= 0) { gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[panel_config->hsync_gpio_num], PIN_FUNC_GPIO); gpio_set_direction(panel_config->hsync_gpio_num, GPIO_MODE_OUTPUT); esp_rom_gpio_connect_out_signal(panel_config->hsync_gpio_num, - lcd_periph_signals.panels[panel_id].hsync_sig, false, false); + lcd_periph_rgb_signals.panels[panel_id].hsync_sig, false, false); } if (panel_config->vsync_gpio_num >= 0) { gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[panel_config->vsync_gpio_num], PIN_FUNC_GPIO); gpio_set_direction(panel_config->vsync_gpio_num, GPIO_MODE_OUTPUT); esp_rom_gpio_connect_out_signal(panel_config->vsync_gpio_num, - lcd_periph_signals.panels[panel_id].vsync_sig, false, false); + lcd_periph_rgb_signals.panels[panel_id].vsync_sig, false, false); } // PCLK may not be necessary in some cases (i.e. VGA output) if (panel_config->pclk_gpio_num >= 0) { gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[panel_config->pclk_gpio_num], PIN_FUNC_GPIO); gpio_set_direction(panel_config->pclk_gpio_num, GPIO_MODE_OUTPUT); esp_rom_gpio_connect_out_signal(panel_config->pclk_gpio_num, - lcd_periph_signals.panels[panel_id].pclk_sig, false, false); + lcd_periph_rgb_signals.panels[panel_id].pclk_sig, false, false); } // DE signal might not be necessary for some RGB LCD if (panel_config->de_gpio_num >= 0) { gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[panel_config->de_gpio_num], PIN_FUNC_GPIO); gpio_set_direction(panel_config->de_gpio_num, GPIO_MODE_OUTPUT); esp_rom_gpio_connect_out_signal(panel_config->de_gpio_num, - lcd_periph_signals.panels[panel_id].de_sig, false, false); + lcd_periph_rgb_signals.panels[panel_id].de_sig, false, false); } // disp enable GPIO is optional if (panel_config->disp_gpio_num >= 0) { diff --git a/components/esp_lcd/src/esp_async_fbcpy.c b/components/esp_lcd/src/esp_async_fbcpy.c index 4f1c6e1fe817..b206303ba150 100644 --- a/components/esp_lcd/src/esp_async_fbcpy.c +++ b/components/esp_lcd/src/esp_async_fbcpy.c @@ -192,13 +192,13 @@ esp_err_t esp_async_fbcpy(esp_async_fbcpy_handle_t mcp, esp_async_fbcpy_trans_de async_memcpy_setup_dma2d_descriptor(mcp, transaction); // submit the DMA2D request - dma2d_trans_config_t dma2d_trans_conf = { + static dma2d_trans_config_t dma2d_trans_conf = { .tx_channel_num = 1, .rx_channel_num = 1, .channel_flags = DMA2D_CHANNEL_FUNCTION_FLAG_SIBLING, .on_job_picked = dma2d_job_picked_cb, - .user_config = mcp, }; + dma2d_trans_conf.user_config = mcp; ESP_RETURN_ON_ERROR(dma2d_enqueue(mcp->client, &dma2d_trans_conf, mcp->trans_desc), TAG, "DMA2D enqueue failed"); return ESP_OK; } diff --git a/components/esp_lcd/src/esp_lcd_common.c b/components/esp_lcd/src/esp_lcd_common.c index f9716b7854e2..07ee21a98e23 100644 --- a/components/esp_lcd/src/esp_lcd_common.c +++ b/components/esp_lcd/src/esp_lcd_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,8 +14,8 @@ typedef struct esp_lcd_platform_t { portMUX_TYPE spinlock; // spinlock used to protect platform level resources union { - void *panels[SOC_LCD_RGB_PANELS]; // array of RGB LCD panel instances - void *buses[SOC_LCD_I80_BUSES]; // array of i80 bus instances + void *panels[SOC_LCDCAM_RGB_NUM_PANELS]; // array of RGB LCD panel instances + void *buses[SOC_LCDCAM_I80_NUM_BUSES]; // array of i80 bus instances }; // LCD peripheral can only work under either RGB mode or intel 8080 mode } esp_lcd_platform_t; @@ -30,7 +30,7 @@ int lcd_com_register_device(lcd_com_device_type_t device_type, void *device_obj) switch (device_type) { case LCD_COM_DEVICE_TYPE_I80: // search for a bus slot then register to platform - for (int i = 0; (i < SOC_LCD_I80_BUSES) && (member_id == -1); i++) { + for (int i = 0; (i < SOC_LCDCAM_I80_NUM_BUSES) && (member_id == -1); i++) { portENTER_CRITICAL(&s_lcd_platform.spinlock); if (!s_lcd_platform.buses[i]) { s_lcd_platform.buses[i] = device_obj; @@ -41,7 +41,7 @@ int lcd_com_register_device(lcd_com_device_type_t device_type, void *device_obj) break; case LCD_COM_DEVICE_TYPE_RGB: // search for a panel slot then register to platform - for (int i = 0; (i < SOC_LCD_RGB_PANELS) && (member_id == -1); i++) { + for (int i = 0; (i < SOC_LCDCAM_RGB_NUM_PANELS) && (member_id == -1); i++) { portENTER_CRITICAL(&s_lcd_platform.spinlock); if (!s_lcd_platform.panels[i]) { s_lcd_platform.panels[i] = device_obj; diff --git a/components/esp_lcd/test_apps/i80_lcd/README.md b/components/esp_lcd/test_apps/i80_lcd/README.md index c6425abb4e4c..9db70ca5b652 100644 --- a/components/esp_lcd/test_apps/i80_lcd/README.md +++ b/components/esp_lcd/test_apps/i80_lcd/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | This test app is used to test LCDs with intel 8080 interface. diff --git a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_board.h b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_board.h index 0e44ac9a1079..ce03b3841829 100644 --- a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_board.h +++ b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_board.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,7 @@ extern "C" { #define TEST_LCD_H_RES (240) #define TEST_LCD_V_RES (280) -#if CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4 #define TEST_LCD_BK_LIGHT_GPIO (1) #define TEST_LCD_RST_GPIO (2) #define TEST_LCD_CS_GPIO (3) diff --git a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c index e2f6e2cf1823..11a7feb828a6 100644 --- a/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c +++ b/components/esp_lcd/test_apps/i80_lcd/main/test_i80_lcd_panel.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -18,7 +18,7 @@ #include "driver/gpio.h" #include "test_i80_board.h" -#if SOC_I2S_LCD_I80_VARIANT +#if SOC_I2S_SUPPORTS_LCD_CAMERA #include "driver/i2s_std.h" TEST_CASE("i80_and_i2s_driver_co-existence", "[lcd][i2s]") @@ -49,9 +49,9 @@ TEST_CASE("i80_and_i2s_driver_co-existence", "[lcd][i2s]") TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, i2s_new_channel(&chan_cfg, &tx_handle, NULL)); TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); } -#endif // SOC_I2S_LCD_I80_VARIANT +#endif // SOC_I2S_SUPPORTS_LCD_CAMERA -#if SOC_LCDCAM_SUPPORTED +#if SOC_LCDCAM_I80_LCD_SUPPORTED TEST_CASE("lcd_i80_device_swap_color_bytes", "[lcd]") { esp_lcd_i80_bus_handle_t i80_bus = NULL; @@ -173,11 +173,16 @@ TEST_CASE("lcd_i80_device_clock_mode", "[lcd]") } TEST_ESP_OK(esp_lcd_del_i80_bus(i80_bus)); } -#endif // SOC_LCDCAM_SUPPORTED +#endif // SOC_LCDCAM_I80_LCD_SUPPORTED TEST_CASE("lcd_i80_bus_and_device_allocation", "[lcd]") { - esp_lcd_i80_bus_handle_t i80_buses[SOC_LCD_I80_BUSES] = {}; +#if SOC_I2S_SUPPORTS_LCD_CAMERA +#define TEST_NUM_LCD_I80_BUSES SOC_LCD_I80_BUSES +#elif SOC_LCDCAM_I80_LCD_SUPPORTED +#define TEST_NUM_LCD_I80_BUSES SOC_LCDCAM_I80_NUM_BUSES +#endif + esp_lcd_i80_bus_handle_t i80_buses[TEST_NUM_LCD_I80_BUSES] = {}; esp_lcd_i80_bus_config_t bus_config = { .dc_gpio_num = TEST_LCD_DC_GPIO, .wr_gpio_num = TEST_LCD_PCLK_GPIO, @@ -195,7 +200,7 @@ TEST_CASE("lcd_i80_bus_and_device_allocation", "[lcd]") .bus_width = 8, .max_transfer_bytes = TEST_LCD_H_RES * 40 * sizeof(uint16_t) }; - for (int i = 0; i < SOC_LCD_I80_BUSES; i++) { + for (int i = 0; i < TEST_NUM_LCD_I80_BUSES; i++) { TEST_ESP_OK(esp_lcd_new_i80_bus(&bus_config, &i80_buses[i])); } TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, esp_lcd_new_i80_bus(&bus_config, &i80_buses[0])); @@ -215,7 +220,7 @@ TEST_CASE("lcd_i80_bus_and_device_allocation", "[lcd]") for (int i = 0; i < 10; i++) { TEST_ESP_OK(esp_lcd_panel_io_del(io_handles[i])); } - for (int i = 0; i < SOC_LCD_I80_BUSES; i++) { + for (int i = 0; i < TEST_NUM_LCD_I80_BUSES; i++) { TEST_ESP_OK(esp_lcd_del_i80_bus(i80_buses[i])); } } @@ -455,7 +460,7 @@ TEST_CASE("lcd_panel_with_i80_interface_(st7789, 8bits)", "[lcd]") } // TODO: support the test on I2S LCD (IDF-7202) -#if !SOC_I2S_LCD_I80_VARIANT +#if !SOC_I2S_SUPPORTS_LCD_CAMERA TEST_CASE("i80_lcd_send_colors_to_fixed_region", "[lcd]") { int x_start = 100; diff --git a/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.py b/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.py index 718a445c40f1..78d8b7df5fd4 100644 --- a/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.py +++ b/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.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 import Dut @@ -8,6 +7,7 @@ @pytest.mark.esp32 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', diff --git a/components/esp_netif/Kconfig b/components/esp_netif/Kconfig index c4117e0e6e72..6d4681ce1733 100644 --- a/components/esp_netif/Kconfig +++ b/components/esp_netif/Kconfig @@ -9,7 +9,7 @@ menu "ESP NETIF Adapter" The IP address may be lost because of some reasons, e.g. when the station disconnects from soft-AP, or when DHCP IP renew fails etc. If the IP lost timer is enabled, it will - be started everytime the IP is lost. Event SYSTEM_EVENT_STA_LOST_IP will be raised if + be started every time the IP is lost. Event SYSTEM_EVENT_STA_LOST_IP will be raised if the timer expires. The IP lost timer is stopped if the station get the IP again before the timer expires. @@ -76,5 +76,16 @@ menu "ESP NETIF Adapter" default n help Enable LwIP IEEE 802.1D bridge support in ESP-NETIF. Note that "Number of clients store data in netif" - (LWIP_NUM_NETIF_CLIENT_DATA) option needs to be properly configured to be LwIP bridge avaiable! + (LWIP_NUM_NETIF_CLIENT_DATA) option needs to be properly configured to be LwIP bridge available! + + config ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF + bool "Enable DNS server per interface" + default n + select LWIP_DNS_SETSERVER_WITH_NETIF + help + Enable this option to use the DNS server which belongs to the selected default network interface. + This feature collects DNS server and netif information from LWIP core modules. + Whenever a new default netif is selected, global DNS servers in LWIP are updated with the netif + related servers. + endmenu diff --git a/components/esp_netif/include/esp_netif.h b/components/esp_netif/include/esp_netif.h index 6dd66015095b..e44c5ba168a1 100644 --- a/components/esp_netif/include/esp_netif.h +++ b/components/esp_netif/include/esp_netif.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -112,7 +112,7 @@ esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle dri * to TCP/IP stack. Similarly esp_netif_transmit is called from the TCP/IP stack whenever * a packet ought to output to the communication media. * - * @note These IO functions are registerd (installed) automatically for default interfaces + * @note These IO functions are registered (installed) automatically for default interfaces * (interfaces with the keys such as WIFI_STA_DEF, WIFI_AP_DEF, ETH_DEF). Custom interface * has to register these IO functions when creating interface using @ref esp_netif_new * @@ -715,6 +715,11 @@ esp_err_t esp_netif_dhcps_get_clients_by_mac(esp_netif_t *esp_netif, int num, es * and is designed to be set via this API. * If DHCP client is disabled, all DNS server types can be set via this API only. * + * Note that LWIP stores DNS server information globally, not per interface, so the first parameter is unused + * in the default LWIP configuration. + * If CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF=1 this API sets internal DNS server information per + * netif. It's also possible to set the global DNS server info by supplying esp_netif=NULL + * * If DHCP server is enabled, the Main DNS Server setting is used by the DHCP server to provide a DNS Server option * to DHCP clients (Wi-Fi stations). * - The default Main DNS server is typically the IP of the DHCP server itself. @@ -740,6 +745,11 @@ esp_err_t esp_netif_set_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t ty * This may be result of a previous call to esp_netif_set_dns_info(). If the interface's DHCP client is enabled, * the Main or Backup DNS Server may be set by the current DHCP lease. * + * Note that LWIP stores DNS server information globally, not per interface, so the first parameter is unused + * in the default LWIP configuration. + * If CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF=1 this API returns internally saved DNS server information per + * netif. It's also possible to ask for the global DNS server info by supplying esp_netif=NULL + * * @param[in] esp_netif Handle to esp-netif instance * @param[in] type Type of DNS Server to get: ESP_NETIF_DNS_MAIN, ESP_NETIF_DNS_BACKUP, ESP_NETIF_DNS_FALLBACK * @param[out] dns DNS Server result is written here on success @@ -898,7 +908,7 @@ esp_err_t esp_netif_str_to_ip4(const char *src, esp_ip4_addr_t *dst); /** * @brief Converts Ascii internet IPv6 address into esp_ip4_addr_t - * Zeros in the IP address can be stripped or completely ommited: "2001:db8:85a3:0:0:0:2:1" or "2001:db8::2:1") + * Zeros in the IP address can be stripped or completely omitted: "2001:db8:85a3:0:0:0:2:1" or "2001:db8::2:1") * * @param[in] src IPv6 address in ascii representation (e.g. ""2001:0db8:85a3:0000:0000:0000:0002:0001") * @param[out] dst Address of the target esp_ip6_addr_t structure to receive converted address @@ -972,7 +982,7 @@ const char *esp_netif_get_desc(esp_netif_t *esp_netif); * * @param[in] esp_netif Handle to esp-netif instance * - * @return Integer representing the instance's route-prio, or -1 if invalid paramters + * @return Integer representing the instance's route-prio, or -1 if invalid parameters */ int esp_netif_get_route_prio(esp_netif_t *esp_netif); diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index bf5560f49646..cedd7807c9e1 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -113,16 +113,6 @@ do { action; \ } while(0) -// -// Internal types -// -typedef enum esp_netif_action { - ESP_NETIF_UNDEF, - ESP_NETIF_STARTED, - ESP_NETIF_STOPPED, - ESP_NETIF_SET_DEFAULT, -} esp_netif_action_t; - // // Internal variables for this module // @@ -306,6 +296,11 @@ static void esp_netif_set_default_netif_internal(esp_netif_t *esp_netif) } else { netif_set_default(esp_netif->lwip_netif); } +#ifdef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF + for (int i = 0; i < DNS_MAX_SERVERS; ++i) { + dns_setserver(i, &esp_netif->dns[i]); + } +#endif } /** @@ -316,7 +311,7 @@ static void esp_netif_set_default_netif_internal(esp_netif_t *esp_netif) static esp_err_t esp_netif_update_default_netif_lwip(esp_netif_api_msg_t *msg) { esp_netif_t *esp_netif = msg->esp_netif; - esp_netif_action_t action = (esp_netif_action_t)msg->data; + esp_netif_route_prio_action_t action = (esp_netif_route_prio_action_t)msg->data; ESP_LOGD(TAG, "%s %p", __func__, esp_netif); @@ -336,6 +331,7 @@ static esp_err_t esp_netif_update_default_netif_lwip(esp_netif_api_msg_t *msg) esp_netif_set_default_netif_internal(s_last_default_esp_netif); break; case ESP_NETIF_STARTED: + case ESP_NETIF_GOT_IP: { // check if previously default interface hasn't been destroyed in the meantime s_last_default_esp_netif = esp_netif_is_active(s_last_default_esp_netif); @@ -351,6 +347,7 @@ static esp_err_t esp_netif_update_default_netif_lwip(esp_netif_api_msg_t *msg) default: case ESP_NETIF_STOPPED: + case ESP_NETIF_LOST_IP: { s_last_default_esp_netif = NULL; esp_netif_t *netif = esp_netif_next_unsafe(NULL); @@ -382,7 +379,7 @@ static esp_err_t esp_netif_update_default_netif_lwip(esp_netif_api_msg_t *msg) * @param esp_netif current interface which just updated state * @param action updating action (on-off) */ -static esp_err_t esp_netif_update_default_netif(esp_netif_t *esp_netif, esp_netif_action_t action) +esp_err_t esp_netif_update_default_netif(esp_netif_t *esp_netif, esp_netif_route_prio_action_t action) { return esp_netif_lwip_ipc_call(esp_netif_update_default_netif_lwip, esp_netif, (void*)action); } @@ -502,6 +499,24 @@ void* esp_netif_get_netif_impl(esp_netif_t *esp_netif) return NULL; } +#if CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF +static void store_dnsserver_info(struct netif* netif, u8_t numdns, const ip_addr_t *dnsserver) +{ + if (netif == NULL) { + return; + } + esp_netif_t *esp_netif = lwip_get_esp_netif(netif); + if (esp_netif == NULL || !esp_netif_is_netif_listed(esp_netif)) { + return; + } + if (!ip_addr_isany(dnsserver)) { + ip_addr_copy(esp_netif->dns[numdns], *dnsserver); + } else { + ip_addr_copy(esp_netif->dns[numdns], *IP_ADDR_ANY); + } +} +#endif + static void tcpip_init_done(void *arg) { sys_sem_t *init_sem = arg; @@ -545,6 +560,12 @@ esp_err_t esp_netif_init(void) sys_sem_wait(&init_sem); sys_sem_free(&init_sem); ESP_LOGD(TAG, "LwIP stack has been initialized"); +#if CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF + if (dns_setserver_callback(store_dnsserver_info) != ERR_OK) { + ESP_LOGE(TAG, "Feiled to configure DNS set server callback"); + return ESP_FAIL; + } +#endif } #if !LWIP_TCPIP_CORE_LOCKING @@ -1071,11 +1092,7 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg) ESP_LOGD(TAG, "%s %p", __func__, esp_netif); if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) { #if CONFIG_PPP_SUPPORT - esp_err_t ret = esp_netif_start_ppp(esp_netif); - if (ret == ESP_OK) { - esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED); - } - return ret; + return esp_netif_start_ppp(esp_netif); #endif } @@ -1152,8 +1169,10 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg) LOG_NETIF_DISABLED_AND_DO("IPv4's DHCP Client", return ESP_ERR_NOT_SUPPORTED); #endif } - - esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED); + // For netifs with (active) DHCP client: we update the default netif after getting a valid IP + if (!((esp_netif->flags & ESP_NETIF_DHCP_CLIENT) && esp_netif->dhcpc_status != ESP_NETIF_DHCP_STOPPED)) { + esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED); + } return ESP_OK; } @@ -1302,7 +1321,7 @@ static void esp_netif_internal_dhcpc_cb(struct netif *netif) if (memcmp(ip_info, ip_info_old, sizeof(esp_netif_ip_info_t))) { evt.ip_changed = true; } - + esp_netif_update_default_netif(esp_netif, ESP_NETIF_GOT_IP); memcpy(&evt.ip_info, ip_info, sizeof(esp_netif_ip_info_t)); memcpy(ip_info_old, ip_info, sizeof(esp_netif_ip_info_t)); ESP_LOGD(TAG, "if%p ip changed=%d", esp_netif, evt.ip_changed); @@ -1343,7 +1362,7 @@ static void esp_netif_ip_lost_timer(void *arg) .esp_netif = esp_netif, }; int ret; - + esp_netif_update_default_netif(esp_netif, ESP_NETIF_LOST_IP); ESP_LOGD(TAG, "if%p ip lost tmr: raise ip lost event", esp_netif); memset(esp_netif->ip_info_old, 0, sizeof(esp_netif_ip_info_t)); if (esp_netif->lost_ip_event) { @@ -1662,7 +1681,10 @@ static esp_err_t esp_netif_up_api(esp_netif_api_msg_t *msg) netif_set_up(lwip_netif); netif_set_link_up(lwip_netif); - esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED); + // For netifs with (active) DHCP client: we update the default netif after getting a valid IP + if (!((esp_netif->flags & ESP_NETIF_DHCP_CLIENT) && esp_netif->dhcpc_status != ESP_NETIF_DHCP_STOPPED)) { + esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED); + } return ESP_OK; } @@ -1841,7 +1863,7 @@ static esp_err_t esp_netif_set_ip_info_api(esp_netif_api_msg_t *msg) if (memcmp(ip_info, esp_netif->ip_info_old, sizeof(esp_netif_ip_info_t))) { evt.ip_changed = true; } - + esp_netif_update_default_netif(esp_netif, ESP_NETIF_GOT_IP); memcpy(&evt.ip_info, ip_info, sizeof(esp_netif_ip_info_t)); memcpy(esp_netif->ip_info_old, ip_info, sizeof(esp_netif_ip_info_t)); ret = esp_event_post(IP_EVENT, evt_id, &evt, sizeof(evt), 0); @@ -1902,7 +1924,7 @@ static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg) ip_addr_t lwip_ip = {}; ESPIP_TO_IP(&dns->ip, &lwip_ip); - if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) { + if (esp_netif && esp_netif->flags & ESP_NETIF_DHCP_SERVER) { #if ESP_DHCPS // if DHCP server configured to set DNS in dhcps API if (type != ESP_NETIF_DNS_MAIN) { @@ -1915,7 +1937,17 @@ static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg) LOG_NETIF_DISABLED_AND_DO("DHCP Server", return ESP_ERR_NOT_SUPPORTED); #endif } else { +#ifdef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF + if (esp_netif) { + store_dnsserver_info(esp_netif->lwip_netif, type, &lwip_ip); + } + if (esp_netif == s_last_default_esp_netif || // if this is the default one -> need to update global DNS servers + esp_netif == NULL) { // if the netif ptr is set to NULL -> we explicitly require the update + dns_setserver(type, &lwip_ip); + } +#else dns_setserver(type, &lwip_ip); +#endif } return ESP_OK; @@ -1923,9 +1955,11 @@ static esp_err_t esp_netif_set_dns_info_api(esp_netif_api_msg_t *msg) esp_err_t esp_netif_set_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns) { +#ifndef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF if (esp_netif == NULL) { return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } +#endif if (dns == NULL) { ESP_LOGD(TAG, "set dns null dns"); @@ -1953,7 +1987,7 @@ static esp_err_t esp_netif_get_dns_info_api(esp_netif_api_msg_t *msg) ESP_LOGD(TAG, "esp_netif_get_dns_info: esp_netif=%p type=%d", esp_netif, type); - if (esp_netif->flags & ESP_NETIF_DHCP_SERVER) { + if (esp_netif && esp_netif->flags & ESP_NETIF_DHCP_SERVER) { #if ESP_DHCPS ip4_addr_t dns_ip; dhcps_dns_getserver(esp_netif->dhcps, &dns_ip); @@ -1964,7 +1998,15 @@ static esp_err_t esp_netif_get_dns_info_api(esp_netif_api_msg_t *msg) #endif } else { const ip_addr_t* dns_ip = NULL; +#ifdef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF + if (esp_netif == NULL) { // by setting esp_netif to NULL we require the global DNS server entry + dns_ip = dns_getserver(type); + } else { + dns_ip = &esp_netif->dns[type]; + } +#else dns_ip = dns_getserver(type); +#endif if(dns_ip != NULL) { IP_TO_ESPIP(dns_ip, &dns->ip); } @@ -1975,9 +2017,11 @@ static esp_err_t esp_netif_get_dns_info_api(esp_netif_api_msg_t *msg) esp_err_t esp_netif_get_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns) { +#ifndef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF if (esp_netif == NULL) { return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } +#endif if (dns == NULL) { ESP_LOGE(TAG, "%s: dns_info cannot be NULL", __func__); @@ -2073,7 +2117,7 @@ static void esp_netif_internal_nd6_cb(struct netif *netif, uint8_t ip_index) ESP_LOGW(TAG,"CONFIG_LWIP_ESP_MLDV6_REPORT not enabled, but esp-netif configured with ESP_NETIF_FLAG_MLDV6_REPORT"); #endif } - + esp_netif_update_default_netif(esp_netif, ESP_NETIF_GOT_IP); memcpy(&evt.ip6_info, &ip6_info, sizeof(esp_netif_ip6_info_t)); int ret = esp_event_post(IP_EVENT, IP_EVENT_GOT_IP6, &evt, sizeof(evt), 0); if (ESP_OK != ret) { @@ -2515,15 +2559,6 @@ esp_err_t esp_netif_ppp_set_auth(esp_netif_t *esp_netif, esp_netif_auth_type_t a { set_auth_msg_t msg = { .authtype = authtype, .user = user, .passwd = passwd }; return esp_netif_lwip_ipc_call(esp_netif_ppp_set_auth_api, esp_netif, &msg); -#if PPP_AUTH_SUPPORT - lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif->related_data; - assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); - pppapi_set_auth(ppp_ctx->ppp, authtype, user, passwd); - return ESP_OK; -#else - ESP_LOGE(TAG, "%s failed: No authorisation enabled in menuconfig", __func__); - return ESP_ERR_ESP_NETIF_IF_NOT_READY; -#endif } esp_err_t esp_netif_napt_disable(esp_netif_t *esp_netif) @@ -2612,7 +2647,7 @@ static esp_err_t esp_netif_add_ip6_address_api(esp_netif_api_msg_t *msg) err_t err = netif_add_ip6_address(msg->esp_netif->lwip_netif, &ip6addr, &index); ESP_RETURN_ON_FALSE(err == ERR_OK && index >= 0, ESP_ERR_ESP_NETIF_IP6_ADDR_FAILED, TAG, "Failed to add ip6 address"); - + esp_netif_update_default_netif(msg->esp_netif, ESP_NETIF_GOT_IP); netif_ip6_addr_set_state(msg->esp_netif->lwip_netif, index, addr->preferred ? IP6_ADDR_PREFERRED : IP6_ADDR_DEPRECATED); ip_event_got_ip6_t evt = {.esp_netif = msg->esp_netif, .ip_index = index}; diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index 842fc8173580..4d5130379ffb 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -114,4 +114,19 @@ struct esp_netif_obj { #endif // CONFIG_ESP_NETIF_BRIDGE_EN // mldv6 timer bool mldv6_report_timer_started; + +#ifdef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF + ip_addr_t dns[DNS_MAX_SERVERS]; +#endif }; + +typedef enum esp_netif_set_default_state { + ESP_NETIF_UNDEF, + ESP_NETIF_STARTED, + ESP_NETIF_GOT_IP, + ESP_NETIF_STOPPED, + ESP_NETIF_LOST_IP, + ESP_NETIF_SET_DEFAULT, +} esp_netif_route_prio_action_t; + +esp_err_t esp_netif_update_default_netif(esp_netif_t *esp_netif, esp_netif_route_prio_action_t action); diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.c b/components/esp_netif/lwip/esp_netif_lwip_ppp.c index 7e4a61a17f3f..03a11bafe3bf 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_ppp.c +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.c @@ -75,6 +75,7 @@ static void on_ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx) break; case PPPERR_CONNECT: /* Connection lost */ ESP_LOGI(TAG, "Connection lost"); + esp_netif_update_default_netif(netif, ESP_NETIF_LOST_IP); err = esp_event_post(IP_EVENT, netif->lost_ip_event, &evt, sizeof(evt), 0); if (ESP_OK != err) { diff --git a/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c index 84705bc784e3..080f565ec52b 100644 --- a/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c +++ b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c @@ -502,6 +502,81 @@ TEST(esp_netif, route_priority) } } +// to probe DNS server info directly in LWIP +const ip_addr_t * dns_getserver(u8_t numdns); + +TEST(esp_netif, set_get_dnsserver) +{ + // create a couple of netifs + test_case_uses_tcpip(); + const char *if_keys[] = {"if0", "if1", "if2", "if3", "if4", "if5", "if6", "if7", "if8", "if9"}; + const int nr_of_netifs = sizeof(if_keys) / sizeof(char *); + esp_netif_t *netifs[nr_of_netifs]; + esp_netif_driver_ifconfig_t driver_config = { .handle = (void*)1, .transmit = dummy_transmit }; + // create 10 netifs with different route prio + for (int i = 0; i < nr_of_netifs; ++i) { + esp_netif_inherent_config_t base_netif_config = { .if_key = if_keys[i], .route_prio = i }; + esp_netif_config_t cfg = { .base = &base_netif_config, + .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, + .driver = &driver_config }; + netifs[i] = esp_netif_new(&cfg); + TEST_ASSERT_NOT_NULL(netifs[i]); + // set the interface up and connected -- to enable the default netif based on route_prio + esp_netif_action_start(netifs[i], 0, 0, 0); + esp_netif_action_connected(netifs[i], 0, 0, 0); + } + + esp_netif_dns_info_t dns[2]; + esp_netif_dns_info_t get_dns; + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip4("1.2.3.4", &dns[0].ip.u_addr.ip4)); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip4("5.6.7.8", &dns[1].ip.u_addr.ip4)); + + // set DNS info to one netif + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_set_dns_info(netifs[3], ESP_NETIF_DNS_MAIN, &dns[0])); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_set_dns_info(netifs[3], ESP_NETIF_DNS_BACKUP, &dns[1])); +#ifndef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF + // check that calling setters/getters with 'esp_netif==NULL' is invalid + TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_set_dns_info(NULL, ESP_NETIF_DNS_BACKUP, &dns[1])); + TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_get_dns_info(NULL, ESP_NETIF_DNS_BACKUP, &get_dns)); + + // check that the global DNS is configured the same way + const ip_addr_t *ip = dns_getserver(0); + TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[0].ip.u_addr.ip4.addr); + ip = dns_getserver(1); + TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); + + // check that we get the same DNS information for all netifs + for (int i=0; i < nr_of_netifs; ++i) { + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(netifs[i], ESP_NETIF_DNS_MAIN, &get_dns)); + TEST_ASSERT_EQUAL(get_dns.ip.u_addr.ip4.addr, dns[0].ip.u_addr.ip4.addr); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(netifs[i], ESP_NETIF_DNS_BACKUP, &get_dns)); + TEST_ASSERT_EQUAL(get_dns.ip.u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); + } +#else + // check that calling setters/getters with 'esp_netif==NULL' is valid, they set/get global DNS servers + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_set_dns_info(NULL, ESP_NETIF_DNS_MAIN, &dns[0])); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(NULL, ESP_NETIF_DNS_BACKUP, &get_dns)); + const ip_addr_t *ip = dns_getserver(0); + TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[0].ip.u_addr.ip4.addr); + ip = dns_getserver(1); + TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, get_dns.ip.u_addr.ip4.addr); // same as what we got at the esp-netif layer + TEST_ASSERT_NOT_EQUAL(ip->u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); // but different from what we set earlier per netif + + // now we set the netif[3] as default one and check again + esp_netif_set_default_netif(netifs[3]); + ip = dns_getserver(1); + TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); // now the ESP_NETIF_DNS_BACKUP[3[ should be set globally + + // check that we get a different DNS server with another netif + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(netifs[5], ESP_NETIF_DNS_MAIN, &get_dns)); + TEST_ASSERT_NOT_EQUAL(dns[0].ip.u_addr.ip4.addr, get_dns.ip.u_addr.ip4.addr); +#endif + + for (int i=0; i < nr_of_netifs; ++i) { + esp_netif_destroy(netifs[i]); + TEST_ASSERT_FALSE(esp_netif_is_netif_listed(netifs[i])); + } +} TEST_GROUP_RUNNER(esp_netif) { @@ -531,6 +606,7 @@ TEST_GROUP_RUNNER(esp_netif) RUN_TEST_CASE(esp_netif, dhcp_server_state_transitions_mesh) #endif RUN_TEST_CASE(esp_netif, route_priority) + RUN_TEST_CASE(esp_netif, set_get_dnsserver) } void app_main(void) diff --git a/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py b/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py index 841d8253608c..43c01256372f 100644 --- a/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py +++ b/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut @@ -8,5 +7,9 @@ @pytest.mark.esp32s2 @pytest.mark.esp32c3 @pytest.mark.generic +@pytest.mark.parametrize('config', [ + 'global_dns', + 'dns_per_netif', +], indirect=True) def test_esp_netif(dut: Dut) -> None: dut.expect_unity_test_output() diff --git a/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.dns_per_netif b/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.dns_per_netif new file mode 100644 index 000000000000..3abbf3a3bcfd --- /dev/null +++ b/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.dns_per_netif @@ -0,0 +1 @@ +CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF=y diff --git a/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.global_dns b/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.global_dns new file mode 100644 index 000000000000..ba627cbf81db --- /dev/null +++ b/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.global_dns @@ -0,0 +1 @@ +CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF=n diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index d7f0ee7d3b87..4581363803d6 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -49,7 +49,7 @@ menu "Power Management" config PM_SLP_IRAM_OPT bool "Put lightsleep related codes in internal RAM" - depends on FREERTOS_USE_TICKLESS_IDLE + depends on SOC_LIGHT_SLEEP_SUPPORTED help If enabled, about 2.1KB of lightsleep related source code would be in IRAM and chip would sleep longer for 310us at 160MHz CPU frequency most each time. diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 37d76df5d106..d9b3c1b6f362 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -438,7 +438,7 @@ esp_err_t esp_pm_configure(const void* vconfig) /* Maximum SOC APB clock frequency is 40 MHz, maximum Modem (WiFi, * Bluetooth, etc..) APB clock frequency is 80 MHz */ int apb_clk_freq = esp_clk_apb_freq() / MHZ; -#if CONFIG_ESP_WIFI_ENABLED || CONFIG_BT_ENABLED || CONFIG_IEEE802154_ENABLED +#if (CONFIG_ESP_WIFI_ENABLED || CONFIG_BT_ENABLED || CONFIG_IEEE802154_ENABLED) && SOC_PHY_SUPPORTED apb_clk_freq = MAX(apb_clk_freq, MODEM_REQUIRED_MIN_APB_CLK_FREQ / MHZ); #endif int apb_max_freq = MIN(max_freq_mhz, apb_clk_freq); /* CPU frequency in APB_MAX mode */ @@ -466,6 +466,16 @@ esp_err_t esp_pm_configure(const void* vconfig) res = rtc_clk_cpu_freq_mhz_to_config(min_freq_mhz, &s_cpu_freq_by_mode[PM_MODE_APB_MIN]); assert(res); s_cpu_freq_by_mode[PM_MODE_LIGHT_SLEEP] = s_cpu_freq_by_mode[PM_MODE_APB_MIN]; + + if (config->light_sleep_enable) { + // Enable the wakeup source here because the `esp_sleep_disable_wakeup_source` in the `else` + // branch must be called if corresponding wakeup source is already enabled. + esp_sleep_enable_timer_wakeup(0); + } else if (s_light_sleep_en) { + // Since auto light-sleep will enable the timer wakeup source, to avoid affecting subsequent possible + // deepsleep requests, disable the timer wakeup source here. + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); + } s_light_sleep_en = config->light_sleep_enable; s_config_changed = true; portEXIT_CRITICAL(&s_switch_lock); diff --git a/components/esp_psram/Kconfig.spiram.common b/components/esp_psram/Kconfig.spiram.common index dd584a55b41a..cbff587ffc18 100644 --- a/components/esp_psram/Kconfig.spiram.common +++ b/components/esp_psram/Kconfig.spiram.common @@ -23,7 +23,8 @@ config SPIRAM_IGNORE_NOTFOUND ESP_WIFI_CACHE_TX_BUFFER_NUM and use static WiFi Tx buffer may cause potential memory exhaustion issues. Suggest disable SPIRAM_TRY_ALLOCATE_WIFI_LWIP. Suggest disable ESP_WIFI_AMSDU_TX_ENABLED. - Suggest disable ESP_WIFI_CACHE_TX_BUFFER_NUM, need clear CONFIG_FEATURE_CACHE_TX_BUF_BIT of config->feature_caps. + Suggest disable ESP_WIFI_CACHE_TX_BUFFER_NUM, + need clear CONFIG_FEATURE_CACHE_TX_BUF_BIT of config->feature_caps. Suggest change ESP_WIFI_TX_BUFFER from static to dynamic. Also suggest to adjust some buffer numbers to the values used without PSRAM case. Such as, ESP_WIFI_STATIC_TX_BUFFER_NUM, ESP_WIFI_DYNAMIC_TX_BUFFER_NUM. @@ -109,7 +110,7 @@ config SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY config SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY bool "Allow .noinit segment placed in external memory" default n - depends on SPIRAM && IDF_TARGET_ESP32 + depends on SPIRAM help If enabled, noinit variables can be placed in PSRAM using EXT_RAM_NOINIT_ATTR. diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld index 9150a4e32ceb..893c20604aec 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld @@ -175,6 +175,7 @@ r_btdm_task_recycle = 0x40000c1c; r_hci_register_vendor_desc_tab = 0x40000d9c; r_ke_task_schedule = 0x40000e80; r_llc_hci_command_handler = 0x40000ef0; +r_llc_loc_ch_map_proc_continue = 0x40000f5c; r_llc_loc_con_upd_proc_continue = 0x40000f60; r_llc_loc_phy_upd_proc_continue = 0x40000f78; r_llc_rem_con_upd_proc_continue = 0x40000fb4; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index b9201bc0c7ac..ba38ae960956 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -934,7 +934,6 @@ r_llc_llcp_send = 0x40000f4c; r_llc_llcp_state_set = 0x40000f50; r_llc_llcp_trans_timer_set = 0x40000f54; r_llc_llcp_tx_check = 0x40000f58; -r_llc_loc_ch_map_proc_continue = 0x40000f5c; r_llc_loc_con_upd_proc_err_cb = 0x40000f64; r_llc_loc_dl_upd_proc_continue = 0x40000f68; r_llc_loc_encrypt_proc_continue = 0x40000f6c; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index ccc4a539fe5d..af7475886356 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -1184,7 +1184,7 @@ r_llc_llcp_send = 0x40003dc8; r_llc_llcp_state_set = 0x40003dd4; r_llc_llcp_trans_timer_set = 0x40003de0; r_llc_llcp_tx_check = 0x40003dec; -r_llc_loc_ch_map_proc_continue = 0x40003df8; +/* r_llc_loc_ch_map_proc_continue = 0x40003df8; */ r_llc_loc_con_upd_proc_err_cb = 0x40003e10; r_llc_loc_dl_upd_proc_continue = 0x40003e1c; r_llc_loc_encrypt_proc_continue = 0x40003e28; diff --git a/components/esp_system/ld/esp32p4/sections.ld.in b/components/esp_system/ld/esp32p4/sections.ld.in index ef288b49a955..e9a6833cfca6 100644 --- a/components/esp_system/ld/esp32p4/sections.ld.in +++ b/components/esp_system/ld/esp32p4/sections.ld.in @@ -475,7 +475,6 @@ SECTIONS mapping[rodata_noload] } > rodata_seg_low -#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY #if CONFIG_SPIRAM_XIP_FROM_PSRAM /** * This section is required to skip flash sections, because `extern_ram_seg` @@ -488,6 +487,7 @@ SECTIONS } > ext_ram_seg #endif //CONFIG_SPIRAM_XIP_FROM_PSRAM +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY /* This section holds .ext_ram.bss data, and will be put in PSRAM */ .ext_ram.bss (NOLOAD) : { @@ -497,6 +497,21 @@ SECTIONS } > ext_ram_seg #endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY +#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + /** + * This section holds data that won't be initialised when startup. + * This section locates in External RAM region. + */ + .ext_ram_noinit (NOLOAD) : + { + _ext_ram_noinit_start = ABSOLUTE(.); + + *(.ext_ram_noinit*) + + ALIGNED_SYMBOL(4, _ext_ram_noinit_end) + } > ext_ram_seg +#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + .dram0.bss (NOLOAD) : { ALIGNED_SYMBOL(4, _bss_start_low) diff --git a/components/esp_system/ld/esp32s2/memory.ld.in b/components/esp_system/ld/esp32s2/memory.ld.in index 8a732b2b094e..bd4d7d73e69a 100644 --- a/components/esp_system/ld/esp32s2/memory.ld.in +++ b/components/esp_system/ld/esp32s2/memory.ld.in @@ -127,8 +127,7 @@ _data_seg_org = ORIGIN(rtc_data_seg); /* The lines below define location alias for .rtc.data section based on Kconfig option. When the option is not defined then use slow memory segment - else the data will be placed in fast memory segment - TODO: check whether the rtc_data_location is correct for esp32s2 - IDF-761 */ + else the data will be placed in fast memory segment */ #ifndef CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM REGION_ALIAS("rtc_data_location", rtc_slow_seg ); #else diff --git a/components/esp_system/ld/esp32s2/sections.ld.in b/components/esp_system/ld/esp32s2/sections.ld.in index 65935dcf976f..1b6e992da639 100644 --- a/components/esp_system/ld/esp32s2/sections.ld.in +++ b/components/esp_system/ld/esp32s2/sections.ld.in @@ -265,6 +265,7 @@ SECTIONS ALIGNED_SYMBOL(4, _noinit_end) } > dram0_0_seg +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY /* External Memory BSS. (Variables with EXT_RAM_BSS_ATTR attribute). */ .ext_ram.bss (NOLOAD) : { @@ -274,6 +275,22 @@ SECTIONS ALIGNED_SYMBOL(4, _ext_ram_bss_end) } > extern_ram_seg +#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + +#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + /** + * This section holds data that won't be initialised when startup. + * This section locates in External RAM region. + */ + .ext_ram_noinit (NOLOAD) : + { + _ext_ram_noinit_start = ABSOLUTE(.); + + *(.ext_ram_noinit*) + + ALIGNED_SYMBOL(4, _ext_ram_noinit_end) + } > extern_ram_seg +#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY /* Shared RAM */ .dram0.bss (NOLOAD) : diff --git a/components/esp_system/ld/esp32s3/sections.ld.in b/components/esp_system/ld/esp32s3/sections.ld.in index 48173b875724..527f8b935010 100644 --- a/components/esp_system/ld/esp32s3/sections.ld.in +++ b/components/esp_system/ld/esp32s3/sections.ld.in @@ -439,6 +439,7 @@ SECTIONS . = ALIGN (0x10000); } > extern_ram_seg +#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY /* This section holds .ext_ram.bss data, and will be put in PSRAM */ .ext_ram.bss (NOLOAD) : { @@ -448,6 +449,22 @@ SECTIONS ALIGNED_SYMBOL(4, _ext_ram_bss_end) } > extern_ram_seg +#endif //CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + +#if CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY + /** + * This section holds data that won't be initialised when startup. + * This section locates in External RAM region. + */ + .ext_ram_noinit (NOLOAD) : + { + _ext_ram_noinit_start = ABSOLUTE(.); + + *(.ext_ram_noinit*) + + ALIGNED_SYMBOL(4, _ext_ram_noinit_end) + } > extern_ram_seg +#endif //CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY /* Marks the end of IRAM code segment */ .iram0.text_end (NOLOAD) : diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 6fbe2ff95d3c..5e689e121067 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -339,6 +339,17 @@ static void start_other_core(void) } #if !SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +#if CONFIG_IDF_TARGET_ESP32 +static void restore_app_mmu_from_pro_mmu(void) +{ + const int mmu_reg_num = 2048; + volatile uint32_t* from = (uint32_t*)DR_REG_FLASH_MMU_TABLE_PRO; + volatile uint32_t* to = (uint32_t*)DR_REG_FLASH_MMU_TABLE_APP; + for (int i = 0; i < mmu_reg_num; i++) { + *(to++) = *(from++); + } +} +#endif // This function is needed to make the multicore app runnable on a unicore bootloader (built with FREERTOS UNICORE). // It does some cache settings for other CPUs. void IRAM_ATTR do_multicore_settings(void) @@ -350,9 +361,11 @@ void IRAM_ATTR do_multicore_settings(void) Cache_Read_Disable(1); Cache_Flush(1); DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR); + mmu_init(1); DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR); // We do not enable cache for CPU1 now because it will be done later in start_other_core(). } + restore_app_mmu_from_pro_mmu(); #endif cache_bus_mask_t cache_bus_mask_core0 = cache_ll_l1_get_enabled_bus(0); diff --git a/components/esp_system/test_apps/.build-test-rules.yml b/components/esp_system/test_apps/.build-test-rules.yml index e0343c14e304..76aa754ff12f 100644 --- a/components/esp_system/test_apps/.build-test-rules.yml +++ b/components/esp_system/test_apps/.build-test-rules.yml @@ -7,6 +7,7 @@ components/esp_system/test_apps/console: components/esp_system/test_apps/esp_system_unity_tests: disable: - if: IDF_TARGET == "esp32c5" or (CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1) + - if: IDF_TARGET == "esp32c5" or (CONFIG_NAME == "psram_with_pd_top" and (SOC_SPIRAM_SUPPORTED != 1 or SOC_PM_SUPPORT_TOP_PD != 1)) components/esp_system/test_apps/linux_apis: enable: diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/CMakeLists.txt b/components/esp_system/test_apps/esp_system_unity_tests/main/CMakeLists.txt index 7bccda3753b0..0f33f8666dd0 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/CMakeLists.txt +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/CMakeLists.txt @@ -12,11 +12,14 @@ set(SRC "test_app_main.c" "test_ipc.c" "test_reset_reason.c" "test_shared_stack_printf.c" - "test_sleep.c" "test_stack_check.c" "test_system_time.c" "test_task_wdt.c") +if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED OR CONFIG_SOC_DEEP_SLEEP_SUPPORTED) + list(APPEND SRC "test_sleep.c") +endif() + if(CONFIG_ESP_IPC_ISR_ENABLE) list(APPEND SRC "test_ipc_isr.c") if(CONFIG_IDF_TARGET_ARCH_XTENSA) diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c index 7da14280b511..10ac4c2f2c50 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c @@ -8,6 +8,7 @@ #include #include #include "esp_sleep.h" +#include "esp_private/esp_sleep_internal.h" #include "driver/rtc_io.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -31,7 +32,14 @@ #include "nvs_flash.h" #include "nvs.h" -#if SOC_DEEP_SLEEP_SUPPORTED +#if CONFIG_SPIRAM +#include "esp_private/esp_psram_extram.h" +#endif + +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP +#include "esp_private/sleep_cpu.h" +#endif + #if SOC_PMU_SUPPORTED #include "esp_private/esp_pmu.h" #else @@ -42,67 +50,11 @@ #define ESP_EXT0_WAKEUP_LEVEL_HIGH 1 __attribute__((unused)) static struct timeval tv_start, tv_stop; -static void check_sleep_reset(void) -{ - TEST_ASSERT_EQUAL(ESP_RST_DEEPSLEEP, esp_reset_reason()); -} - -#ifndef CONFIG_FREERTOS_UNICORE -static void deep_sleep_task(void *arg) -{ - esp_deep_sleep_start(); -} - -static void do_deep_sleep_from_app_cpu(void) -{ - esp_sleep_enable_timer_wakeup(2000000); - - xTaskCreatePinnedToCore(&deep_sleep_task, "ds", 2048, NULL, 5, NULL, 1); - -#if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) ) - //Note: Scheduler suspension behavior changed in FreeRTOS SMP - vTaskPreemptionDisable(NULL); -#else - // keep running some non-IRAM code - vTaskSuspendAll(); -#endif // #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) ) - - while (true) { - ; - } -} - -TEST_CASE_MULTIPLE_STAGES("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][reset=DEEPSLEEP_RESET]", - do_deep_sleep_from_app_cpu, - check_sleep_reset) - -#endif - -static void do_deep_sleep_timer(void) -{ - esp_sleep_enable_timer_wakeup(2000000); - esp_deep_sleep_start(); -} - -TEST_CASE_MULTIPLE_STAGES("wake up from deep sleep using timer", "[deepsleep][reset=DEEPSLEEP_RESET]", - do_deep_sleep_timer, - check_sleep_reset) - -static void do_light_sleep_deep_sleep_timer(void) -{ - esp_sleep_enable_timer_wakeup(1000000); - esp_light_sleep_start(); - esp_deep_sleep_start(); -} - -TEST_CASE_MULTIPLE_STAGES("light sleep followed by deep sleep", "[deepsleep][reset=DEEPSLEEP_RESET]", - do_light_sleep_deep_sleep_timer, - check_sleep_reset) - -TEST_CASE("wake up from light sleep using timer", "[deepsleep]") +/////////////////////////// Light Sleep Test Cases //////////////////////////////////// +#if SOC_LIGHT_SLEEP_SUPPORTED +TEST_CASE("wake up from light sleep using timer", "[lightsleep]") { esp_sleep_enable_timer_wakeup(2000000); - struct timeval tv_start, tv_stop; gettimeofday(&tv_start, NULL); esp_light_sleep_start(); gettimeofday(&tv_stop, NULL); @@ -126,7 +78,7 @@ static void test_light_sleep(void* arg) vTaskDelete(NULL); } -TEST_CASE("light sleep stress test", "[deepsleep]") +TEST_CASE("light sleep stress test", "[lightsleep]") { SemaphoreHandle_t done = xSemaphoreCreateCounting(2, 0); esp_sleep_enable_timer_wakeup(1000); @@ -146,7 +98,7 @@ static void timer_func(void* arg) esp_rom_delay_us(50); } -TEST_CASE("light sleep stress test with periodic esp_timer", "[deepsleep]") +TEST_CASE("light sleep stress test with periodic esp_timer", "[lightsleep]") { SemaphoreHandle_t done = xSemaphoreCreateCounting(2, 0); esp_sleep_enable_timer_wakeup(1000); @@ -176,7 +128,7 @@ TEST_CASE("light sleep stress test with periodic esp_timer", "[deepsleep]") #define MAX_SLEEP_TIME_ERROR_US 100 #endif -TEST_CASE("light sleep duration is correct", "[deepsleep][ignore]") +TEST_CASE("light sleep duration is correct", "[lightsleep][ignore]") { // don't power down XTAL — powering it up takes different time on // different boards @@ -215,7 +167,7 @@ TEST_CASE("light sleep duration is correct", "[deepsleep][ignore]") } } -TEST_CASE("light sleep and frequency switching", "[deepsleep]") +TEST_CASE("light sleep and frequency switching", "[lightsleep]") { #ifndef CONFIG_PM_ENABLE uart_sclk_t clk_source = UART_SCLK_DEFAULT; @@ -251,6 +203,201 @@ TEST_CASE("light sleep and frequency switching", "[deepsleep]") } } +#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED +__attribute__((unused)) static float get_time_ms(void) +{ + gettimeofday(&tv_stop, NULL); + + float dt = (tv_stop.tv_sec - tv_start.tv_sec) * 1e3f + + (tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f; + return fabs(dt); +} + +__attribute__((unused)) static uint32_t get_cause(void) +{ +#if SOC_PMU_SUPPORTED + uint32_t wakeup_cause = pmu_ll_hp_get_wakeup_cause(&PMU); +#else + uint32_t wakeup_cause = rtc_cntl_ll_get_wakeup_cause(); +#endif + return wakeup_cause; +} + +#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3) && SOC_PM_SUPPORT_EXT0_WAKEUP +// Fails on S2 IDF-2903 + +// This test case verifies deactivation of trigger for wake up sources +TEST_CASE("disable source trigger behavior", "[lightsleep]") +{ + float dt = 0; + + printf("Setup timer and ext0 to wake up immediately from GPIO_13 \n"); + + // Setup ext0 configuration to wake up almost immediately + // The wakeup time is proportional to input capacitance * pullup resistance + ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); + ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13)); + ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13)); + ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH)); + + // Setup timer to wakeup with timeout + esp_sleep_enable_timer_wakeup(2000000); + + // Save start time + gettimeofday(&tv_start, NULL); + esp_light_sleep_start(); + + dt = get_time_ms(); + printf("Ext0 sleep time = %d \n", (int) dt); + + // Check wakeup from Ext0 using time measurement because wakeup cause is + // not available in light sleep mode + TEST_ASSERT_INT32_WITHIN(100, 100, (int) dt); + + TEST_ASSERT((get_cause() & RTC_EXT0_TRIG_EN) != 0); + + // Disable Ext0 source. Timer source should be triggered + ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0)); + printf("Disable ext0 trigger and leave timer active.\n"); + + gettimeofday(&tv_start, NULL); + esp_light_sleep_start(); + + dt = get_time_ms(); + printf("Timer sleep time = %d \n", (int) dt); + + TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt); + + // Additionally check wakeup cause + TEST_ASSERT((get_cause() & RTC_TIMER_TRIG_EN) != 0); + + // Disable timer source. + ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER)); + + // Setup ext0 configuration to wake up immediately + ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); + ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13)); + ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13)); + ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH)); + + printf("Disable timer trigger to wake up from ext0 source.\n"); + + gettimeofday(&tv_start, NULL); + esp_light_sleep_start(); + + dt = get_time_ms(); + printf("Ext0 sleep time = %d \n", (int) dt); + + TEST_ASSERT_INT32_WITHIN(100, 100, (int) dt); + TEST_ASSERT((get_cause() & RTC_EXT0_TRIG_EN) != 0); + + // Check error message when source is already disabled + esp_err_t err_code = esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); + TEST_ASSERT(err_code == ESP_ERR_INVALID_STATE); + + // Disable ext0 wakeup source, as this might interfere with other tests + ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0)); +} +#endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3) +#endif //SOC_RTCIO_INPUT_OUTPUT_SUPPORTED + +#if CONFIG_SPIRAM +static void test_psram_accessible_after_lightsleep(void) +{ + esp_sleep_context_t sleep_ctx; + esp_sleep_set_sleep_context(&sleep_ctx); + +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + TEST_ESP_OK(sleep_cpu_configure(true)); +#endif + + esp_sleep_enable_timer_wakeup(100 * 1000); + esp_light_sleep_start(); + TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); + +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); + TEST_ESP_OK(sleep_cpu_configure(false)); +#endif + + TEST_ASSERT_EQUAL(true, esp_psram_extram_test()); + + esp_sleep_set_sleep_context(NULL); + esp_restart(); +} + +static void restart_for_reinit_psram(void) +{ + TEST_ASSERT_EQUAL(ESP_RST_SW, esp_reset_reason()); + printf("PSRAM survives after lightsleep test - OK\n"); +} + +TEST_CASE_MULTIPLE_STAGES("Test PSRAM survives after lightsleep", "[lightsleep]", + test_psram_accessible_after_lightsleep, + restart_for_reinit_psram); +#endif + +#endif // SOC_LIGHT_SLEEP_SUPPORTED + +/////////////////////////// Deep Sleep Test Cases //////////////////////////////////// +#if SOC_DEEP_SLEEP_SUPPORTED +static void check_sleep_reset(void) +{ + TEST_ASSERT_EQUAL(ESP_RST_DEEPSLEEP, esp_reset_reason()); +} + +#ifndef CONFIG_FREERTOS_UNICORE +static void deep_sleep_task(void *arg) +{ + esp_deep_sleep_start(); +} + +static void do_deep_sleep_from_app_cpu(void) +{ + esp_sleep_enable_timer_wakeup(2000000); + + xTaskCreatePinnedToCore(&deep_sleep_task, "ds", 2048, NULL, 5, NULL, 1); + +#if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) ) + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionDisable(NULL); +#else + // keep running some non-IRAM code + vTaskSuspendAll(); +#endif // #if ( ( CONFIG_FREERTOS_SMP ) && ( !CONFIG_FREERTOS_UNICORE ) ) + + while (true) { + ; + } +} + +TEST_CASE_MULTIPLE_STAGES("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][reset=DEEPSLEEP_RESET]", + do_deep_sleep_from_app_cpu, + check_sleep_reset) + +#endif + +static void do_deep_sleep_timer(void) +{ + esp_sleep_enable_timer_wakeup(2000000); + esp_deep_sleep_start(); +} + +TEST_CASE_MULTIPLE_STAGES("wake up from deep sleep using timer", "[deepsleep][reset=DEEPSLEEP_RESET]", + do_deep_sleep_timer, + check_sleep_reset) + +static void do_light_sleep_deep_sleep_timer(void) +{ + esp_sleep_enable_timer_wakeup(1000000); + esp_light_sleep_start(); + esp_deep_sleep_start(); +} + +TEST_CASE_MULTIPLE_STAGES("light sleep followed by deep sleep", "[deepsleep][reset=DEEPSLEEP_RESET]", + do_light_sleep_deep_sleep_timer, + check_sleep_reset) + static void do_deep_sleep(void) { esp_sleep_enable_timer_wakeup(100000); @@ -382,106 +529,6 @@ TEST_CASE_MULTIPLE_STAGES("can set sleep wake stub from stack in RTC RAM", "[dee #endif // CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP #endif // ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB -#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED - -__attribute__((unused)) static float get_time_ms(void) -{ - gettimeofday(&tv_stop, NULL); - - float dt = (tv_stop.tv_sec - tv_start.tv_sec) * 1e3f + - (tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f; - return fabs(dt); -} - -__attribute__((unused)) static uint32_t get_cause(void) -{ -#if SOC_PMU_SUPPORTED - uint32_t wakeup_cause = pmu_ll_hp_get_wakeup_cause(&PMU); -#else - uint32_t wakeup_cause = rtc_cntl_ll_get_wakeup_cause(); -#endif - return wakeup_cause; -} - -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3) && SOC_PM_SUPPORT_EXT0_WAKEUP -// Fails on S2 IDF-2903 - -// This test case verifies deactivation of trigger for wake up sources -TEST_CASE("disable source trigger behavior", "[deepsleep]") -{ - float dt = 0; - - printf("Setup timer and ext0 to wake up immediately from GPIO_13 \n"); - - // Setup ext0 configuration to wake up almost immediately - // The wakeup time is proportional to input capacitance * pullup resistance - ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); - ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13)); - ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13)); - ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH)); - - // Setup timer to wakeup with timeout - esp_sleep_enable_timer_wakeup(2000000); - - // Save start time - gettimeofday(&tv_start, NULL); - esp_light_sleep_start(); - - dt = get_time_ms(); - printf("Ext0 sleep time = %d \n", (int) dt); - - // Check wakeup from Ext0 using time measurement because wakeup cause is - // not available in light sleep mode - TEST_ASSERT_INT32_WITHIN(100, 100, (int) dt); - - TEST_ASSERT((get_cause() & RTC_EXT0_TRIG_EN) != 0); - - // Disable Ext0 source. Timer source should be triggered - ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0)); - printf("Disable ext0 trigger and leave timer active.\n"); - - gettimeofday(&tv_start, NULL); - esp_light_sleep_start(); - - dt = get_time_ms(); - printf("Timer sleep time = %d \n", (int) dt); - - TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt); - - // Additionally check wakeup cause - TEST_ASSERT((get_cause() & RTC_TIMER_TRIG_EN) != 0); - - // Disable timer source. - ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER)); - - // Setup ext0 configuration to wake up immediately - ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); - ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13)); - ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13)); - ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH)); - - printf("Disable timer trigger to wake up from ext0 source.\n"); - - gettimeofday(&tv_start, NULL); - esp_light_sleep_start(); - - dt = get_time_ms(); - printf("Ext0 sleep time = %d \n", (int) dt); - - TEST_ASSERT_INT32_WITHIN(100, 100, (int) dt); - TEST_ASSERT((get_cause() & RTC_EXT0_TRIG_EN) != 0); - - // Check error message when source is already disabled - esp_err_t err_code = esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); - TEST_ASSERT(err_code == ESP_ERR_INVALID_STATE); - - // Disable ext0 wakeup source, as this might interfere with other tests - ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0)); -} -#endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3) - -#endif //SOC_RTCIO_INPUT_OUTPUT_SUPPORTED - static void trigger_deepsleep(void) { struct timeval start; diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c index c924b5c5bbe7..caec9f1e768f 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c @@ -68,6 +68,7 @@ TEST_CASE("Task WDT task timeout after peripheral powerdown lightsleep", "[task_ TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP); TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result); + esp_sleep_set_sleep_context(NULL); // Short delay to allow timeout to occur esp_rom_delay_us(TASK_WDT_TIMEOUT_MS * 1000); diff --git a/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py b/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py index 93d73937ce8b..03c3ba980b50 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py +++ b/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py @@ -11,6 +11,7 @@ pytest.param('default', marks=[pytest.mark.supported_targets]), pytest.param('pd_vddsdio', marks=[pytest.mark.supported_targets]), pytest.param('psram', marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.esp32s3, pytest.mark.esp32p4]), + pytest.param('psram_with_pd_top', marks=[pytest.mark.esp32p4]), pytest.param('single_core_esp32', marks=[pytest.mark.esp32]), ] ) diff --git a/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.default b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.default index fcbda27d4066..e8104032cf2a 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.default +++ b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.default @@ -1,5 +1,4 @@ # Default configuration # Used for testing stack smashing protection CONFIG_COMPILER_STACK_CHECK=y -CONFIG_ESP_SLEEP_DEBUG=y CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y diff --git a/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.psram_with_pd_top b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.psram_with_pd_top new file mode 100644 index 000000000000..440009beb18b --- /dev/null +++ b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.psram_with_pd_top @@ -0,0 +1,4 @@ +CONFIG_SPIRAM=y +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y +CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y +CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y diff --git a/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.defaults b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.defaults index 55604ff94b1b..c381fad085db 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.defaults +++ b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.defaults @@ -4,3 +4,4 @@ CONFIG_ESP_TASK_WDT_INIT=n # esp_sleep_enable_gpio_switch() has the change to break UART RX during light sleep stress tests # Remove this when IDF-4897 is fixed CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=n +CONFIG_ESP_SLEEP_DEBUG=y diff --git a/components/esp_wifi/esp32/esp_adapter.c b/components/esp_wifi/esp32/esp_adapter.c index ce79917000c6..f58f93769d92 100644 --- a/components/esp_wifi/esp32/esp_adapter.c +++ b/components/esp_wifi/esp32/esp_adapter.c @@ -49,6 +49,9 @@ #include "esp_rom_sys.h" #include "esp32/rom/ets_sys.h" #include "private/esp_modem_wrapper.h" +#if __has_include("esp_psram.h") +#include "esp_psram.h" +#endif #define TAG "esp_adapter" @@ -260,36 +263,31 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) - /* - * Since release/v5.1, FreeRTOS has been updated to always use internal memory (i.e., DRAM) - * for dynamic memory allocation. Calling FreeRTOS creation functions (e.g., xTaskCreate(), xQueueCreate()) - * will guarantee that the memory allocated for those tasks/objects is from internal memory. - * For more details, please refer to the Migration Guide in release/v5.1. - */ -#if CONFIG_SPIRAM_USE_MALLOC - /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ - return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; } static void queue_delete_wrapper(void *queue) { if (queue) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) -#if CONFIG_SPIRAM_USE_MALLOC - vQueueDeleteWithCaps(queue); -#else + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); vQueueDelete(queue); -#endif -#else - vQueueDelete(queue); -#endif + if (queue_buffer) { + free(queue_buffer); + } } } diff --git a/components/esp_wifi/esp32c5/esp_adapter.c b/components/esp_wifi/esp32c5/esp_adapter.c index c0c735e01a79..12a56d2e03ce 100644 --- a/components/esp_wifi/esp32c5/esp_adapter.c +++ b/components/esp_wifi/esp32c5/esp_adapter.c @@ -207,7 +207,32 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { - return (void *)xQueueCreate(queue_len, item_size); + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; +} + +static void queue_delete_wrapper(void *queue) +{ + if (queue) { + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); + vQueueDelete(queue); + if (queue_buffer) { + free(queue_buffer); + } + } } static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) @@ -587,7 +612,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._mutex_lock = mutex_lock_wrapper, ._mutex_unlock = mutex_unlock_wrapper, ._queue_create = queue_create_wrapper, - ._queue_delete = (void(*)(void *))vQueueDelete, + ._queue_delete = queue_delete_wrapper, ._queue_send = queue_send_wrapper, ._queue_send_from_isr = queue_send_from_isr_wrapper, ._queue_send_to_back = queue_send_to_back_wrapper, diff --git a/components/esp_wifi/esp32p4/esp_adapter.c b/components/esp_wifi/esp32p4/esp_adapter.c index f78dc1972d6e..4def952a2c96 100644 --- a/components/esp_wifi/esp32p4/esp_adapter.c +++ b/components/esp_wifi/esp32p4/esp_adapter.c @@ -53,6 +53,10 @@ extern void wifi_apb80m_request(void); extern void wifi_apb80m_release(void); #endif +#if CONFIG_ESP_EXT_CONN_ENABLE +extern uint8_t *esp_extconn_get_mac(void); +#endif + IRAM_ATTR void *wifi_malloc(size_t size) { #if CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP @@ -253,7 +257,32 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { - return (void *)xQueueCreate(queue_len, item_size); + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; +} + +static void queue_delete_wrapper(void *queue) +{ + if (queue) { + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); + vQueueDelete(queue); + if (queue_buffer) { + free(queue_buffer); + } + } } static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) @@ -402,7 +431,26 @@ static void esp_log_write_wrapper(unsigned int level, const char *tag, const cha static esp_err_t esp_read_mac_wrapper(uint8_t *mac, unsigned int type) { + if (mac == NULL) { + ESP_LOGE(TAG, "mac address param is NULL"); + return ESP_ERR_INVALID_ARG; + } + + // get mac address from target +#if CONFIG_ESP_EXT_CONN_ENABLE + memcpy(mac, esp_extconn_get_mac(), 6); +#else + ESP_LOGE(TAG, "Not support read mac"); return ESP_FAIL; +#endif + + if (type == ESP_MAC_WIFI_SOFTAP) { + mac[5] += 1; + } + + ESP_LOGD(TAG, "%s MAC addr: " MACSTR, (type == ESP_MAC_WIFI_STA ? "STA" : "AP"), MAC2STR(mac)); + + return ESP_OK; } static int coex_init_wrapper(void) @@ -668,7 +716,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._mutex_lock = mutex_lock_wrapper, ._mutex_unlock = mutex_unlock_wrapper, ._queue_create = queue_create_wrapper, - ._queue_delete = (void(*)(void *))vQueueDelete, + ._queue_delete = queue_delete_wrapper, ._queue_send = queue_send_wrapper, ._queue_send_from_isr = queue_send_from_isr_wrapper, ._queue_send_to_back = queue_send_to_back_wrapper, diff --git a/components/esp_wifi/esp32s2/esp_adapter.c b/components/esp_wifi/esp32s2/esp_adapter.c index 95f9f2dbb102..3e131130f845 100644 --- a/components/esp_wifi/esp32s2/esp_adapter.c +++ b/components/esp_wifi/esp32s2/esp_adapter.c @@ -50,6 +50,9 @@ #include "esp_rom_sys.h" #include "esp32s2/rom/ets_sys.h" #include "private/esp_modem_wrapper.h" +#if __has_include("esp_psram.h") +#include "esp_psram.h" +#endif #define TAG "esp_adapter" @@ -251,36 +254,31 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) - /* - * Since release/v5.1, FreeRTOS has been updated to always use internal memory (i.e., DRAM) - * for dynamic memory allocation. Calling FreeRTOS creation functions (e.g., xTaskCreate(), xQueueCreate()) - * will guarantee that the memory allocated for those tasks/objects is from internal memory. - * For more details, please refer to the Migration Guide in release/v5.1. - */ -#if CONFIG_SPIRAM_USE_MALLOC - /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ - return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; } static void queue_delete_wrapper(void *queue) { if (queue) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) -#if CONFIG_SPIRAM_USE_MALLOC - vQueueDeleteWithCaps(queue); -#else + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); vQueueDelete(queue); -#endif -#else - vQueueDelete(queue); -#endif + if (queue_buffer) { + free(queue_buffer); + } } } diff --git a/components/esp_wifi/esp32s3/esp_adapter.c b/components/esp_wifi/esp32s3/esp_adapter.c index ba3311a24001..3fef6ab866c5 100644 --- a/components/esp_wifi/esp32s3/esp_adapter.c +++ b/components/esp_wifi/esp32s3/esp_adapter.c @@ -51,6 +51,9 @@ #include "esp_rom_sys.h" #include "esp32s3/rom/ets_sys.h" #include "private/esp_modem_wrapper.h" +#if __has_include("esp_psram.h") +#include "esp_psram.h" +#endif #define TAG "esp_adapter" @@ -254,36 +257,31 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) - /* - * Since release/v5.1, FreeRTOS has been updated to always use internal memory (i.e., DRAM) - * for dynamic memory allocation. Calling FreeRTOS creation functions (e.g., xTaskCreate(), xQueueCreate()) - * will guarantee that the memory allocated for those tasks/objects is from internal memory. - * For more details, please refer to the Migration Guide in release/v5.1. - */ -#if CONFIG_SPIRAM_USE_MALLOC - /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ - return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif -#else - return (void *)xQueueCreate(queue_len, item_size); -#endif + StaticQueue_t *queue_buffer = heap_caps_malloc_prefer(sizeof(StaticQueue_t) + (queue_len * item_size), 2, + MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM, + MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + if (!queue_buffer) { + return NULL; + } + QueueHandle_t queue_handle = xQueueCreateStatic(queue_len, item_size, (uint8_t *)queue_buffer + sizeof(StaticQueue_t), + queue_buffer); + if (!queue_handle) { + free(queue_buffer); + return NULL; + } + + return (void *)queue_handle; } static void queue_delete_wrapper(void *queue) { if (queue) { -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) -#if CONFIG_SPIRAM_USE_MALLOC - vQueueDeleteWithCaps(queue); -#else + StaticQueue_t *queue_buffer = NULL; + xQueueGetStaticBuffers(queue, NULL, &queue_buffer); vQueueDelete(queue); -#endif -#else - vQueueDelete(queue); -#endif + if (queue_buffer) { + free(queue_buffer); + } } } diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index d1df171e4c97..7f021d55ddb3 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit d1df171e4c9756dac17aa586201c7f94b99dc8aa +Subproject commit 7f021d55ddb302b090846746123a3a727c017a08 diff --git a/components/espcoredump/src/core_dump_elf.c b/components/espcoredump/src/core_dump_elf.c index 2e3da6ee0289..db05493ca157 100644 --- a/components/espcoredump/src/core_dump_elf.c +++ b/components/espcoredump/src/core_dump_elf.c @@ -933,7 +933,7 @@ static void elf_parse_version_info(esp_core_dump_summary_t *summary, void *data) { core_dump_elf_version_info_t *version = (core_dump_elf_version_info_t *)data; summary->core_dump_version = version->version; - memcpy(summary->app_elf_sha256, version->app_elf_sha256, ELF_APP_SHA256_SIZE); + memcpy(summary->app_elf_sha256, version->app_elf_sha256, sizeof(summary->app_elf_sha256)); ESP_COREDUMP_LOGD("Core dump version 0x%x", summary->core_dump_version); ESP_COREDUMP_LOGD("App ELF SHA2 %s", (char *)summary->app_elf_sha256); } diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c index 955587ba427f..0baffbcd82e9 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c @@ -90,8 +90,13 @@ void vPortEnterCritical(void) void vPortExitCritical(void) { + + /* Critical section nesting coung must never be negative */ + configASSERT( port_uxCriticalNestingIDF > 0 ); + if (port_uxCriticalNestingIDF > 0) { port_uxCriticalNestingIDF--; + if (port_uxCriticalNestingIDF == 0) { // Restore the saved interrupt threshold vPortClearInterruptMask((int)port_uxCriticalOldInterruptStateIDF); diff --git a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c index 4cd6918472f1..d39faf60f025 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/portable/xtensa/port.c @@ -145,9 +145,14 @@ void vPortExitCriticalIDF(portMUX_TYPE *lock) spinlock_release(lock); BaseType_t coreID = xPortGetCoreID(); BaseType_t nesting = port_uxCriticalNestingIDF[coreID]; + + /* Critical section nesting count must never be negative */ + configASSERT( nesting > 0 ); + if (nesting > 0) { nesting--; port_uxCriticalNestingIDF[coreID] = nesting; + //This is the last exit call, restore the saved interrupt level if ( nesting == 0 ) { XTOS_RESTORE_JUST_INTLEVEL((int) port_uxCriticalOldInterruptStateIDF[coreID]); diff --git a/components/freertos/FreeRTOS-Kernel/portable/linux/port.c b/components/freertos/FreeRTOS-Kernel/portable/linux/port.c index 33253f2240ed..4e851768c7f5 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/linux/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/linux/port.c @@ -261,7 +261,13 @@ void vPortEnterCritical( void ) void vPortExitCritical( void ) { - uxCriticalNesting--; + if ( uxCriticalNesting > 0 ) + { + uxCriticalNesting--; + } + + /* Critical section nesting count must always be >= 0. */ + configASSERT( uxCriticalNesting >= 0 ); /* If we have reached 0 then re-enable the interrupts. */ if( uxCriticalNesting == 0 ) diff --git a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c index 29cc3fe09636..646fa7686ec5 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/riscv/port.c @@ -568,9 +568,13 @@ void __attribute__((optimize("-O3"))) vPortExitCriticalMultiCore(portMUX_TYPE *m BaseType_t coreID = xPortGetCoreID(); BaseType_t nesting = port_uxCriticalNesting[coreID]; + /* Critical section nesting count must never be negative */ + configASSERT( nesting > 0 ); + if (nesting > 0) { nesting--; port_uxCriticalNesting[coreID] = nesting; + //This is the last exit call, restore the saved interrupt level if ( nesting == 0 ) { portCLEAR_INTERRUPT_MASK_FROM_ISR(port_uxOldInterruptState[coreID]); @@ -623,8 +627,13 @@ void vPortExitCritical(void) esp_rom_printf("vPortExitCritical(void) is not supported on single-core targets. Please use vPortExitCriticalMultiCore(portMUX_TYPE *mux) instead.\n"); abort(); #endif /* (configNUM_CORES > 1) */ + + /* Critical section nesting count must never be negative */ + configASSERT( port_uxCriticalNesting[0] > 0 ); + if (port_uxCriticalNesting[0] > 0) { port_uxCriticalNesting[0]--; + if (port_uxCriticalNesting[0] == 0) { portCLEAR_INTERRUPT_MASK_FROM_ISR(port_uxOldInterruptState[0]); } diff --git a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c index 9722a2c30870..b35b71ac12c6 100644 --- a/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c +++ b/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c @@ -497,9 +497,13 @@ void __attribute__((optimize("-O3"))) vPortExitCritical(portMUX_TYPE *mux) BaseType_t coreID = xPortGetCoreID(); BaseType_t nesting = port_uxCriticalNesting[coreID]; + /* Critical section nesting count must never be negative */ + configASSERT( nesting > 0 ); + if (nesting > 0) { nesting--; port_uxCriticalNesting[coreID] = nesting; + //This is the last exit call, restore the saved interrupt level if ( nesting == 0 ) { portCLEAR_INTERRUPT_MASK_FROM_ISR(port_uxOldInterruptState[coreID]); diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index 2482826674e8..8d06ea30b0d0 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -3856,7 +3856,7 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, prvAddCurrentTaskToDelayedList( xTicksToWait, xWaitIndefinitely ); } /* Release the previously taken kernel lock. */ - taskEXIT_CRITICAL( &xKernelLock ); + prvEXIT_CRITICAL_SMP_ONLY( &xKernelLock ); } #endif /* configUSE_TIMERS */ diff --git a/components/freertos/test_apps/freertos/performance/test_freertos_scheduling_time.c b/components/freertos/test_apps/freertos/performance/test_freertos_scheduling_time.c index 1d7e5efe937b..dc79986fe0e4 100644 --- a/components/freertos/test_apps/freertos/performance/test_freertos_scheduling_time.c +++ b/components/freertos/test_apps/freertos/performance/test_freertos_scheduling_time.c @@ -16,12 +16,26 @@ #include "unity.h" #include "test_utils.h" -#define NUMBER_OF_ITERATIONS 10 +#define NUMBER_OF_ITERATIONS 1023 + +static int compare_uint32(const void *a, const void *b) +{ + return (*(uint32_t *)a - * (uint32_t *)b); +} + +static uint32_t calculate_median(uint32_t *values, int size) +{ + /* Sort the array of values containing the scheduling time of each iteration */ + qsort(values, size, sizeof(uint32_t), compare_uint32); + + /* Return the median value. (size is an odd number) */ + return values[size / 2]; +} typedef struct { SemaphoreHandle_t end_sema; uint32_t before_sched; - uint32_t cycles_to_sched; + uint32_t cycles_to_sched[NUMBER_OF_ITERATIONS]; TaskHandle_t t1_handle; } test_context_t; @@ -40,20 +54,18 @@ static void test_task_1(void *arg) static void test_task_2(void *arg) { test_context_t *context = (test_context_t *)arg; - uint64_t accumulator = 0; vTaskPrioritySet(NULL, CONFIG_UNITY_FREERTOS_PRIORITY + 1); vTaskPrioritySet(context->t1_handle, CONFIG_UNITY_FREERTOS_PRIORITY + 1); taskYIELD(); for (int i = 0; i < NUMBER_OF_ITERATIONS; i++) { - accumulator += (esp_cpu_get_cycle_count() - context->before_sched); + context->cycles_to_sched[i] = esp_cpu_get_cycle_count() - context->before_sched; taskYIELD(); } - context->cycles_to_sched = accumulator / NUMBER_OF_ITERATIONS; - vTaskDelete(context->t1_handle); xSemaphoreGive(context->end_sema); + vTaskDelete(context->t1_handle); vTaskDelete(NULL); } @@ -74,7 +86,10 @@ TEST_CASE("scheduling time test", "[freertos]") BaseType_t result = xSemaphoreTake(context.end_sema, portMAX_DELAY); TEST_ASSERT_EQUAL_HEX32(pdTRUE, result); - TEST_PERFORMANCE_LESS_THAN(SCHEDULING_TIME, "%"PRIu32" cycles", context.cycles_to_sched); + + /* We calculate the median instead of the average to avoid outliers which may occur due to cache speed variabilities */ + uint32_t median_cycles = calculate_median(context.cycles_to_sched, NUMBER_OF_ITERATIONS); + TEST_PERFORMANCE_LESS_THAN(SCHEDULING_TIME, "%"PRIu32" cycles", median_cycles); /* Cleanup */ vSemaphoreDelete(context.end_sema); diff --git a/components/hal/esp32/include/hal/mwdt_ll.h b/components/hal/esp32/include/hal/mwdt_ll.h index 48a468f5acc5..28167fa17a40 100644 --- a/components/hal/esp32/include/hal/mwdt_ll.h +++ b/components/hal/esp32/include/hal/mwdt_ll.h @@ -17,7 +17,7 @@ extern "C" { #include #include "hal/misc.h" #include "hal/assert.h" -#include "soc/timer_periph.h" +#include "soc/wdt_periph.h" #include "soc/timer_group_struct.h" #include "hal/wdt_types.h" #include "esp_attr.h" diff --git a/components/hal/esp32c2/include/hal/mwdt_ll.h b/components/hal/esp32c2/include/hal/mwdt_ll.h index cb3649497b90..11eeaa64626d 100644 --- a/components/hal/esp32c2/include/hal/mwdt_ll.h +++ b/components/hal/esp32c2/include/hal/mwdt_ll.h @@ -15,7 +15,7 @@ extern "C" { #include #include -#include "soc/timer_periph.h" +#include "soc/wdt_periph.h" #include "soc/timer_group_struct.h" #include "hal/wdt_types.h" #include "esp_attr.h" diff --git a/components/hal/esp32c3/include/hal/mwdt_ll.h b/components/hal/esp32c3/include/hal/mwdt_ll.h index 24fd44803e95..711b437590d3 100644 --- a/components/hal/esp32c3/include/hal/mwdt_ll.h +++ b/components/hal/esp32c3/include/hal/mwdt_ll.h @@ -15,7 +15,7 @@ extern "C" { #include #include -#include "soc/timer_periph.h" +#include "soc/wdt_periph.h" #include "soc/timer_group_struct.h" #include "hal/wdt_types.h" #include "hal/assert.h" diff --git a/components/hal/esp32c5/include/hal/mwdt_ll.h b/components/hal/esp32c5/include/hal/mwdt_ll.h index 2a335affcb6d..c4e386a6646f 100644 --- a/components/hal/esp32c5/include/hal/mwdt_ll.h +++ b/components/hal/esp32c5/include/hal/mwdt_ll.h @@ -15,7 +15,7 @@ extern "C" { #include #include -#include "soc/timer_periph.h" +#include "soc/wdt_periph.h" #include "soc/timer_group_struct.h" #include "soc/pcr_struct.h" #include "hal/wdt_types.h" diff --git a/components/hal/esp32c6/include/hal/mwdt_ll.h b/components/hal/esp32c6/include/hal/mwdt_ll.h index 28a34eb88a26..21e15e209fc0 100644 --- a/components/hal/esp32c6/include/hal/mwdt_ll.h +++ b/components/hal/esp32c6/include/hal/mwdt_ll.h @@ -15,7 +15,7 @@ extern "C" { #include #include -#include "soc/timer_periph.h" +#include "soc/wdt_periph.h" #include "soc/timer_group_struct.h" #include "soc/pcr_struct.h" #include "hal/wdt_types.h" diff --git a/components/hal/esp32c6/include/hal/timer_ll.h b/components/hal/esp32c6/include/hal/timer_ll.h index bc507a38771a..a12488a2857a 100644 --- a/components/hal/esp32c6/include/hal/timer_ll.h +++ b/components/hal/esp32c6/include/hal/timer_ll.h @@ -24,6 +24,7 @@ extern "C" { // Get timer group register base address with giving group number #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1)) #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id)) +#define TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id) ((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER: SLEEP_RETENTION_MODULE_TG1_TIMER) #define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \ (uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \ diff --git a/components/hal/esp32c61/include/hal/mwdt_ll.h b/components/hal/esp32c61/include/hal/mwdt_ll.h index 8f3829ed4d81..39431442eea6 100644 --- a/components/hal/esp32c61/include/hal/mwdt_ll.h +++ b/components/hal/esp32c61/include/hal/mwdt_ll.h @@ -15,7 +15,7 @@ extern "C" { #include #include -#include "soc/timer_periph.h" +#include "soc/wdt_periph.h" #include "soc/timer_group_struct.h" #include "soc/pcr_struct.h" #include "hal/wdt_types.h" diff --git a/components/hal/esp32h2/include/hal/mwdt_ll.h b/components/hal/esp32h2/include/hal/mwdt_ll.h index 8b2f01e2d50f..b3b4cf1ef9ec 100644 --- a/components/hal/esp32h2/include/hal/mwdt_ll.h +++ b/components/hal/esp32h2/include/hal/mwdt_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ extern "C" { #include #include -#include "soc/timer_periph.h" +#include "soc/wdt_periph.h" #include "soc/timer_group_struct.h" #include "soc/pcr_struct.h" #include "hal/wdt_types.h" diff --git a/components/hal/esp32h2/include/hal/timer_ll.h b/components/hal/esp32h2/include/hal/timer_ll.h index b62bdb4db803..982d42e500f8 100644 --- a/components/hal/esp32h2/include/hal/timer_ll.h +++ b/components/hal/esp32h2/include/hal/timer_ll.h @@ -24,6 +24,7 @@ extern "C" { // Get timer group register base address with giving group number #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1)) #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id)) +#define TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id) ((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER: SLEEP_RETENTION_MODULE_TG1_TIMER) #define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \ (uint32_t [2][1][GPTIMER_ETM_TASK_MAX]){{{ \ diff --git a/components/hal/esp32p4/include/hal/lcd_ll.h b/components/hal/esp32p4/include/hal/lcd_ll.h index bdd3ef12a9fa..99e41cfc6894 100644 --- a/components/hal/esp32p4/include/hal/lcd_ll.h +++ b/components/hal/esp32p4/include/hal/lcd_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -507,7 +507,8 @@ static inline void lcd_ll_reverse_wire_bit_order(lcd_cam_dev_t *dev, bool en) * @brief Whether to swap adjacent two bytes * * @note This acts before the YUV-RGB converter, mainly to change the data endian. - * {B1,B0},{B3,B2} => {B0,B1}{B2,B3} + * e.g. {B1,B0},{B3,B2} => {B0,B1}{B2,B3}. + * Only valid when `lcd_ll_set_dma_read_stride` set the DMA read stride >= 16 bits * * @param dev LCD register base address * @param en True to swap the byte order, False to not swap @@ -606,7 +607,7 @@ static inline void lcd_ll_set_command(lcd_cam_dev_t *dev, uint32_t data_width, u } /** - * @brief Wether to enable RGB interface + * @brief Whether to enable RGB interface * * @param dev LCD register base address * @param en True to enable RGB interface, False to disable RGB interface @@ -629,7 +630,7 @@ static inline void lcd_ll_enable_auto_next_frame(lcd_cam_dev_t *dev, bool en) } /** - * @brief Wether to output HSYNC signal in porch resion + * @brief Whether to output HSYNC signal in porch resion * * @param dev LCD register base address * @param en True to enable, False to disable @@ -746,7 +747,7 @@ static inline uint32_t lcd_ll_get_interrupt_status(lcd_cam_dev_t *dev) * @brief Clear interrupt status by mask * * @param dev LCD register base address - * @param mask Interupt status mask + * @param mask Interrupt status mask */ __attribute__((always_inline)) static inline void lcd_ll_clear_interrupt_status(lcd_cam_dev_t *dev, uint32_t mask) diff --git a/components/hal/esp32p4/include/hal/ldo_ll.h b/components/hal/esp32p4/include/hal/ldo_ll.h index 96ae2250f0b5..6e707890adb4 100644 --- a/components/hal/esp32p4/include/hal/ldo_ll.h +++ b/components/hal/esp32p4/include/hal/ldo_ll.h @@ -4,29 +4,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The ll is not public api, don't use in application code. - * See readme.md in hal/include/hal/readme.md - ******************************************************************************/ - #pragma once #include #include #include "esp_bit_defs.h" -#include "hal/assert.h" +#include "hal/misc.h" #include "soc/pmu_struct.h" #ifdef __cplusplus extern "C" { #endif -/** - * LDO capabilities - */ -#define LDO_LL_UNIT_NUM 4 - +#define LDO_LL_NUM_UNITS 4 // NUmber of LDO units #define LDO_LL_ADJUSTABLE_CHAN_MASK 0x0F // all the 4 channels can be adjustable #define LDO_LL_MAX_VOLTAGE_MV 3300 @@ -48,103 +38,186 @@ extern "C" { #define LDO_ID2UNIT(ldo_id) ((ldo_id) - 1) /** - * @brief Check if a LDO ID is valid - * - * @return True for valid + * @brief LDO unit owner */ -__attribute__((always_inline)) -static inline bool ldo_ll_is_valid_ldo_id(int ldo_id) -{ - return ((ldo_id > 0) && (ldo_id <= LDO_LL_UNIT_NUM)); -} +typedef enum { + LDO_LL_UNIT_OWNER_HW, // LDO unit is controlled by hardware + LDO_LL_UNIT_OWNER_SW, // LDO unit is controlled by software +} ldo_ll_unit_owner_t; /** - * @brief Enable a LDO + * @brief Check if a LDO channel is valid * - * @param ldo_id LDO ID - * @param enable True: enable; False: disable + * @return True for valid, false for invalid */ __attribute__((always_inline)) -static inline void ldo_ll_enable(int ldo_id, bool enable) +static inline bool ldo_ll_is_valid_ldo_channel(int ldo_chan) { - HAL_ASSERT(ldo_id < LDO_LL_UNIT_NUM); - uint8_t index_array[LDO_LL_UNIT_NUM] = {0,3,1,4}; - PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo.xpd = enable; + return (ldo_chan > 0) && (ldo_chan <= LDO_LL_NUM_UNITS); } /** - * @brief Enable a LDO + * @brief Convert voltage to dref and mul value * - * @param ldo_id LDO ID + * @note Vref = (dref < 9)?(0.5+dref*0.05):(1+(dref-9)*0.1) + * @note Vout = (Vref*K+Vos)*(1+0.25*mul*C), K, Vos, C are constants saved in the eFuse, for calibration + * + * @param ldo_unit LDO unit * @param voltage_mv Voltage in mV + * @param dref Returned dref value + * @param mul Returned mul value */ __attribute__((always_inline)) -static inline void ldo_ll_set_output_voltage_mv(int ldo_id, int voltage_mv) +static inline void ldo_ll_voltage_to_dref_mul(int ldo_unit, int voltage_mv, uint8_t *dref, uint8_t *mul) { - int dref = 0, mul = 0; - - /** - * Vout = dref * mul - * - * mul reg[2:0]: - * mul = 1~2.75, step = 0.25 - - * dref reg[3:0]: - * 0~8 : dref = 0.5V ~ 0.9V, step 50mV - * 9~15 : dref = 1.0V ~ 1.6V, step 100mV - */ + // TODO [IDF-10754]: also take the calibration parameters into account if (voltage_mv <= 500) { - dref = 0; - mul = 0; + *dref = 0; + *mul = 0; } else if (voltage_mv <= 900) { - mul = 0; - dref = (voltage_mv - LDO_LL_EXT_LDO_DREF_VOL_L_BASE) / LDO_LL_EXT_LDO_DREF_VOL_L_STEP; + *mul = 0; + *dref = (voltage_mv - LDO_LL_EXT_LDO_DREF_VOL_L_BASE) / LDO_LL_EXT_LDO_DREF_VOL_L_STEP; } else if (voltage_mv <= 1600) { - mul = 1; - dref = 6 + (voltage_mv - LDO_LL_EXT_LDO_DREF_VOL_H_BASE) / LDO_LL_EXT_LDO_DREF_VOL_H_STEP; + *mul = 1; + *dref = 6 + (voltage_mv - LDO_LL_EXT_LDO_DREF_VOL_H_BASE) / LDO_LL_EXT_LDO_DREF_VOL_H_STEP; } else if (voltage_mv <= 2000) { - mul = 4; - dref = (voltage_mv / 2 - LDO_LL_EXT_LDO_DREF_VOL_L_BASE) / LDO_LL_EXT_LDO_DREF_VOL_L_STEP; + *mul = 4; + *dref = (voltage_mv / 2 - LDO_LL_EXT_LDO_DREF_VOL_L_BASE) / LDO_LL_EXT_LDO_DREF_VOL_L_STEP; } else if (voltage_mv <= 3200) { - mul = 4; - dref = 9 + (voltage_mv / 2 - LDO_LL_EXT_LDO_DREF_VOL_H_BASE) / LDO_LL_EXT_LDO_DREF_VOL_H_STEP; + *mul = 4; + *dref = 9 + (voltage_mv / 2 - LDO_LL_EXT_LDO_DREF_VOL_H_BASE) / LDO_LL_EXT_LDO_DREF_VOL_H_STEP; } else { - mul = 7; - dref = 15; - } - if (mul > 7) { - mul = 7; - } - if (mul < 0) { - mul = 0; - } - if (dref > 15) { - dref = 15; - } - if (dref < 0) { - dref = 0; + *mul = 7; + *dref = 15; } +} + +/** + * @brief Set owner of a LDO unit + * + * @note Even if the LDO unit is controlled by hardware, its voltage can still be changed by software by `ldo_ll_adjust_voltage` + * + * @param ldo_unit LDO unit + * @param owner Owner of the LDO unit + */ +__attribute__((always_inline)) +static inline void ldo_ll_set_owner(int ldo_unit, ldo_ll_unit_owner_t owner) +{ + uint8_t index_array[LDO_LL_NUM_UNITS] = {0, 3, 1, 4}; + /* + * force_tieh_sel: + * - 0: efuse, i.e. by hardware + * - 1: tieh_sel, i.e. by software + */ + PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo.force_tieh_sel = owner; +} + +/** + * @brief Enable a LDO unit + * + * @param ldo_unit LDO unit + * @param enable True: enable; False: disable + */ +__attribute__((always_inline)) +static inline void ldo_ll_enable(int ldo_unit, bool enable) +{ + uint8_t index_array[LDO_LL_NUM_UNITS] = {0, 3, 1, 4}; + PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo.xpd = enable; +} + +/** + * @brief Adjust voltage of a LDO unit + * + * @param ldo_unit LDO unit + * @param dref A parameter which controls the internal reference voltage + * @param mul Multiply factor + */ +__attribute__((always_inline)) +static inline void ldo_ll_adjust_voltage(int ldo_unit, uint8_t dref, uint8_t mul) +{ + uint8_t index_array[LDO_LL_NUM_UNITS] = {0, 3, 1, 4}; + PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo_ana.dref = dref; + PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo_ana.mul = mul; /** + * tieh: + * - 0: Vref * Mul + * - 1: 3.3V + * * tieh_sel: * - 0: tieh; * - 1: sdmmc0_tieh; * - 2: 3.3V; * - 3: sdmmc1_tieh; - * - * tieh: - * - 0: dref * mul - * - 1: 3.3V - * - * force_tieh_sel: - * - 0: efuse - * - 1: tieh_sel */ - uint8_t index_array[LDO_LL_UNIT_NUM] = {0,3,1,4}; - PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo.tieh_sel = 0; - PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo.tieh = 0; - PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo.force_tieh_sel = 1; - PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo_ana.dref = dref; - PMU.ext_ldo[index_array[ldo_id]].pmu_ext_ldo_ana.mul = mul; + PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo.tieh_sel = 0; + PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo.tieh = 0; +} + +/** + * @brief Enable power on delay of a LDO unit + * + * @param ldo_unit LDO unit + * @param enable True: enable; False: disable + */ +__attribute__((always_inline)) +static inline void ldo_ll_enable_power_on_delay(int ldo_unit, bool enable) +{ + uint8_t index_array[LDO_LL_NUM_UNITS] = {0, 3, 1, 4}; + PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo.tieh_pos_en = enable; +} + +/** + * @brief Enable power off delay of a LDO unit + * + * @param ldo_unit LDO unit + * @param enable True: enable; False: disable + */ +__attribute__((always_inline)) +static inline void ldo_ll_enable_power_off_delay(int ldo_unit, bool enable) +{ + uint8_t index_array[LDO_LL_NUM_UNITS] = {0, 3, 1, 4}; + PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo.tieh_neg_en = enable; +} + +/** + * @brief Set power on delay target of a LDO unit + * + * @param ldo_unit LDO unit + * @param target0 Target 0 + * @param target1 Target 1 + */ +__attribute__((always_inline)) +static inline void ldo_ll_set_delay_target(int ldo_unit, uint8_t target0, uint8_t target1) +{ + uint8_t index_array[LDO_LL_NUM_UNITS] = {0, 3, 1, 4}; + HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo, target0, target0); + HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo, target1, target1); +} + +/** + * @brief Enable current limit of a LDO unit to avoid inrush current + * + * @param ldo_unit LDO unit + * @param enable True: enable; False: disable + */ +__attribute__((always_inline)) +static inline void ldo_ll_enable_current_limit(int ldo_unit, bool enable) +{ + uint8_t index_array[LDO_LL_NUM_UNITS] = {0, 3, 1, 4}; + PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo_ana.en_cur_lim = enable; +} + +/** + * @brief Enable ripple suppression of a LDO unit + * + * @param ldo_unit LDO unit + * @param enable True: enable; False: disable + */ +__attribute__((always_inline)) +static inline void ldo_ll_enable_ripple_suppression(int ldo_unit, bool enable) +{ + uint8_t index_array[LDO_LL_NUM_UNITS] = {0, 3, 1, 4}; + PMU.ext_ldo[index_array[ldo_unit]].pmu_ext_ldo_ana.en_vdet = enable; } #ifdef __cplusplus diff --git a/components/hal/esp32p4/include/hal/mwdt_ll.h b/components/hal/esp32p4/include/hal/mwdt_ll.h index fb0091c50f7f..2879b9916ac4 100644 --- a/components/hal/esp32p4/include/hal/mwdt_ll.h +++ b/components/hal/esp32p4/include/hal/mwdt_ll.h @@ -15,7 +15,7 @@ extern "C" { #include #include -#include "soc/timer_periph.h" +#include "soc/wdt_periph.h" #include "soc/timer_group_struct.h" #include "soc/hp_sys_clkrst_struct.h" #include "hal/wdt_types.h" diff --git a/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h b/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h index 822a4759be4f..7579bd674e86 100644 --- a/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h +++ b/components/hal/esp32p4/include/hal/psram_ctrlr_ll.h @@ -289,15 +289,16 @@ static inline void psram_ctrlr_ll_enable_rd_splice(uint32_t mspi_id, bool en) * @param en enable / disable */ __attribute__((always_inline)) -static inline void psram_ctrlr_ll_enable_module_clock(uint32_t mspi_id, bool en) +static inline void _psram_ctrlr_ll_enable_module_clock(uint32_t mspi_id, bool en) { (void)mspi_id; HP_SYS_CLKRST.soc_clk_ctrl0.reg_psram_sys_clk_en = en; + HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_pll_clk_en = en; } /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define psram_ctrlr_ll_enable_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; psram_ctrlr_ll_enable_module_clock(__VA_ARGS__) +#define psram_ctrlr_ll_enable_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _psram_ctrlr_ll_enable_module_clock(__VA_ARGS__) /** * @brief Reset PSRAM module clock @@ -325,7 +326,7 @@ static inline void psram_ctrlr_ll_reset_module_clock(uint32_t mspi_id) * @param clk_src clock source, see valid sources in type `soc_periph_psram_clk_src_t` */ __attribute__((always_inline)) -static inline void psram_ctrlr_ll_select_clk_source(uint32_t mspi_id, soc_periph_psram_clk_src_t clk_src) +static inline void _psram_ctrlr_ll_select_clk_source(uint32_t mspi_id, soc_periph_psram_clk_src_t clk_src) { (void)mspi_id; uint32_t clk_val = 0; @@ -347,13 +348,12 @@ static inline void psram_ctrlr_ll_select_clk_source(uint32_t mspi_id, soc_periph break; } - HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_pll_clk_en = 1; HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_clk_src_sel = clk_val; } /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define psram_ctrlr_ll_select_clk_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; psram_ctrlr_ll_select_clk_source(__VA_ARGS__) +#define psram_ctrlr_ll_select_clk_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; _psram_ctrlr_ll_select_clk_source(__VA_ARGS__) /** * @brief Set PSRAM core clock @@ -362,15 +362,29 @@ static inline void psram_ctrlr_ll_select_clk_source(uint32_t mspi_id, soc_periph * @param freqdiv Divider value */ __attribute__((always_inline)) -static inline void psram_ctrlr_ll_set_core_clock(uint8_t spi_num, uint32_t freqdiv) +static inline void _psram_ctrlr_ll_set_core_clock_div(uint8_t spi_num, uint32_t freqdiv) { - HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_core_clk_en = 1; HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl00, reg_psram_core_clk_div_num, freqdiv - 1); } /// use a macro to wrap the function, force the caller to use it in a critical section /// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance -#define psram_ctrlr_ll_set_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; psram_ctrlr_ll_set_core_clock(__VA_ARGS__) +#define psram_ctrlr_ll_set_core_clock_div(...) (void)__DECLARE_RCC_ATOMIC_ENV; _psram_ctrlr_ll_set_core_clock_div(__VA_ARGS__) + +/** + * @brief Enable or disable the PSRAM core clock + * + * @param en enable / disable + */ +__attribute__((always_inline)) +static inline void _psram_ctrlr_ll_enable_core_clock(uint8_t spi_num, bool en) +{ + HP_SYS_CLKRST.peri_clk_ctrl00.reg_psram_core_clk_en = en; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define psram_ctrlr_ll_enable_core_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _psram_ctrlr_ll_enable_core_clock(__VA_ARGS__) /** * @brief Set PSRAM bus clock @@ -735,6 +749,24 @@ static inline void psram_ctrlr_ll_common_transaction(uint32_t mspi_id, is_write_erase_operation); } +/** + * @brief Wait MSPI PSRAM controller transaction done + * + */ +__attribute__((always_inline)) +static inline void psram_ctrlr_ll_wait_all_transaction_done(void) +{ +#define ALL_TRANSACTION_DONE ( SPI_MEM_S_ALL_FIFO_EMPTY | \ + SPI_MEM_S_RDATA_AFIFO_REMPTY | \ + SPI_MEM_S_RADDR_AFIFO_REMPTY | \ + SPI_MEM_S_WDATA_AFIFO_REMPTY | \ + SPI_MEM_S_WBLEN_AFIFO_REMPTY | \ + SPI_MEM_S_ALL_AXI_TRANS_AFIFO_EMPTY) + while (SPIMEM2.smem_axi_addr_ctrl.val != ALL_TRANSACTION_DONE) { + ; + } +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/timer_ll.h b/components/hal/esp32p4/include/hal/timer_ll.h index 9dc5f1cef06d..e8c678e88e6e 100644 --- a/components/hal/esp32p4/include/hal/timer_ll.h +++ b/components/hal/esp32p4/include/hal/timer_ll.h @@ -24,6 +24,7 @@ extern "C" { // Get timer group register base address with giving group number #define TIMER_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1)) #define TIMER_LL_EVENT_ALARM(timer_id) (1 << (timer_id)) +#define TIMER_LL_SLEEP_RETENTION_MODULE_ID(group_id) ((group_id == 0) ? SLEEP_RETENTION_MODULE_TG0_TIMER: SLEEP_RETENTION_MODULE_TG1_TIMER) #define TIMER_LL_ETM_TASK_TABLE(group, timer, task) \ (uint32_t[2][2][GPTIMER_ETM_TASK_MAX]){ \ diff --git a/components/hal/esp32p4/include/hal/usb_utmi_ll.h b/components/hal/esp32p4/include/hal/usb_utmi_ll.h index f58d72f9f523..027bb2e61343 100644 --- a/components/hal/esp32p4/include/hal/usb_utmi_ll.h +++ b/components/hal/esp32p4/include/hal/usb_utmi_ll.h @@ -10,18 +10,34 @@ #include "esp_attr.h" #include "soc/lp_clkrst_struct.h" #include "soc/hp_sys_clkrst_struct.h" +#include "soc/hp_system_struct.h" #include "soc/usb_utmi_struct.h" #ifdef __cplusplus extern "C" { #endif +/* ---------------------------- USB PHY Control ---------------------------- */ + +/** + * @brief Configure Low-Speed mode + * + * @param[in] hw Beginning address of the peripheral registers + * @param[in] parallel Parallel or serial LS mode + * @return FORCE_INLINE_ATTR + */ +FORCE_INLINE_ATTR void usb_utmi_ll_configure_ls(usb_utmi_dev_t *hw, bool parallel) +{ + hw->fc_06.ls_par_en = parallel; + hw->fc_06.ls_kpalv_en = 1; +} + /* ----------------------------- RCC Functions ----------------------------- */ /** * @brief Enable the bus clock for the USB UTMI PHY and USB_DWC_HS controller * - * @param clk_en True to enable, false to disable + * @param[in] clk_en True to enable, false to disable */ FORCE_INLINE_ATTR void usb_utmi_ll_enable_bus_clock(bool clk_en) { @@ -41,12 +57,25 @@ FORCE_INLINE_ATTR void usb_utmi_ll_reset_register(void) { // Reset the USB_UTMI and USB_DWC_HS LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_otg20 = 1; + LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_otg20_phy = 1; + LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_otg20_phy = 0; LP_AON_CLKRST.hp_usb_clkrst_ctrl1.rst_en_usb_otg20 = 0; } -// P_AON_CLKRST.hp_usb_clkrst_ctrlx are shared registers, so this function must be used in an atomic way +// P_AON_CLKRST.hp_usb_clkrst_ctrlx is shared register, so this function must be used in an atomic way #define usb_utmi_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_utmi_ll_reset_register(__VA_ARGS__) +/** + * @brief Enable precise detection of VBUS + * + * @param[in] enable Enable/Disable precise detection + */ +FORCE_INLINE_ATTR void usb_utmi_ll_enable_precise_detection(bool enable) +{ + // Enable VBUS precise detection + HP_SYSTEM.sys_usbotg20_ctrl.sys_otg_suspendm = enable; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/usb_wrap_ll.h b/components/hal/esp32p4/include/hal/usb_wrap_ll.h index 113a56fe771f..5e6b94236680 100644 --- a/components/hal/esp32p4/include/hal/usb_wrap_ll.h +++ b/components/hal/esp32p4/include/hal/usb_wrap_ll.h @@ -12,7 +12,6 @@ #include "soc/lp_system_struct.h" #include "soc/lp_clkrst_struct.h" #include "soc/hp_sys_clkrst_struct.h" -#include "soc/hp_system_struct.h" // For HP_SYSTEM domain #include "soc/usb_wrap_struct.h" #include "hal/usb_wrap_types.h" @@ -263,14 +262,6 @@ FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void) // P_AON_CLKRST.hp_usb_clkrst_ctrlx are shared registers, so this function must be used in an atomic way #define usb_wrap_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; usb_wrap_ll_reset_register(__VA_ARGS__) -/* ------------------------------- HP System ------------------------------- */ - -FORCE_INLINE_ATTR void usb_wrap_ll_enable_precise_detection(void) -{ - // Enable VBUS precise detection - HP_SYSTEM.sys_usbotg20_ctrl.sys_otg_suspendm = 1; -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s2/include/hal/mwdt_ll.h b/components/hal/esp32s2/include/hal/mwdt_ll.h index 5f425bada27a..45952c4384cb 100644 --- a/components/hal/esp32s2/include/hal/mwdt_ll.h +++ b/components/hal/esp32s2/include/hal/mwdt_ll.h @@ -16,7 +16,7 @@ extern "C" { #include #include #include "esp_assert.h" -#include "soc/timer_periph.h" +#include "soc/wdt_periph.h" #include "soc/timer_group_struct.h" #include "hal/wdt_types.h" #include "hal/assert.h" diff --git a/components/hal/esp32s3/include/hal/mwdt_ll.h b/components/hal/esp32s3/include/hal/mwdt_ll.h index c3cc7b062bce..f91a4ec68254 100644 --- a/components/hal/esp32s3/include/hal/mwdt_ll.h +++ b/components/hal/esp32s3/include/hal/mwdt_ll.h @@ -16,7 +16,7 @@ extern "C" { #include #include #include "hal/misc.h" -#include "soc/timer_periph.h" +#include "soc/wdt_periph.h" #include "soc/timer_group_struct.h" #include "hal/wdt_types.h" #include "hal/assert.h" diff --git a/components/hal/include/hal/lcd_types.h b/components/hal/include/hal/lcd_types.h index e25ff40ac5dc..1bff0f6472d8 100644 --- a/components/hal/include/hal/lcd_types.h +++ b/components/hal/include/hal/lcd_types.h @@ -14,14 +14,14 @@ extern "C" { #endif -#if SOC_LCD_I80_SUPPORTED || SOC_LCD_RGB_SUPPORTED +#if SOC_I2S_SUPPORTS_LCD_CAMERA || SOC_LCDCAM_SUPPORTED /** * @brief LCD clock source */ typedef soc_periph_lcd_clk_src_t lcd_clock_source_t; #else typedef int lcd_clock_source_t; -#endif // SOC_LCD_I80_SUPPORTED || SOC_LCD_RGB_SUPPORTED +#endif // SOC_I2S_SUPPORTS_LCD_CAMERA || SOC_LCDCAM_SUPPORTED /** * @brief RGB data endian diff --git a/components/hal/include/hal/spi_hal.h b/components/hal/include/hal/spi_hal.h index 41f32a5f520c..8e5a53778dbc 100644 --- a/components/hal/include/hal/spi_hal.h +++ b/components/hal/include/hal/spi_hal.h @@ -72,7 +72,7 @@ typedef struct { typedef struct { spi_ll_clock_val_t clock_reg; ///< Register value used by the LL layer spi_clock_source_t clock_source; ///< Clock source of each device used by LL layer - uint32_t source_pre_div; ///< Pre divider befor enter SPI peripheral + uint32_t source_pre_div; ///< Pre divider before enter SPI peripheral int real_freq; ///< Output of the actual frequency int timing_dummy; ///< Extra dummy needed to compensate the timing int timing_miso_delay; ///< Extra miso delay clocks to compensate the timing @@ -129,7 +129,7 @@ typedef struct { #if SOC_SPI_AS_CS_SUPPORTED uint32_t as_cs : 1; ///< Whether to toggle the CS while the clock toggles, device specific #endif - uint32_t positive_cs : 1; ///< Whether the postive CS feature is abled, device specific + uint32_t positive_cs : 1; ///< Whether the positive CS feature is abled, device specific };//boolean configurations } spi_hal_dev_config_t; diff --git a/components/linux/linux_include/sys/cdefs.h b/components/linux/include/sys/cdefs.h similarity index 59% rename from components/linux/linux_include/sys/cdefs.h rename to components/linux/include/sys/cdefs.h index 2b34193912bf..1e10b63a1f58 100644 --- a/components/linux/linux_include/sys/cdefs.h +++ b/components/linux/include/sys/cdefs.h @@ -12,6 +12,20 @@ #pragma once +#if (defined(__APPLE__) && defined(__MACH__)) +// MacOS + +#if !defined(__containerof) +#define __containerof(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +#endif + +#include_next // include the actual cdefs.h (which does not contain containerof) + +#else +// Linux + #include // We need a define. We can't typedef here since, depending on the include order, @@ -20,3 +34,5 @@ #include_next #include + +#endif diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index 448588615353..3f7d520de8b8 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -132,12 +132,7 @@ if(CONFIG_LWIP_ENABLE) "lwip/src/netif/ppp/pppos.c" "lwip/src/netif/ppp/upap.c" "lwip/src/netif/ppp/utils.c" - "lwip/src/netif/ppp/vj.c" - "lwip/src/netif/ppp/polarssl/arc4.c" - "lwip/src/netif/ppp/polarssl/des.c" - "lwip/src/netif/ppp/polarssl/md4.c" - "lwip/src/netif/ppp/polarssl/md5.c" - "lwip/src/netif/ppp/polarssl/sha1.c") + "lwip/src/netif/ppp/vj.c") endif() if(NOT ${target} STREQUAL "linux") @@ -160,6 +155,15 @@ if(CONFIG_LWIP_ENABLE) "apps/ping/ping_sock.c") endif() + if(NOT CONFIG_LWIP_USE_EXTERNAL_MBEDTLS) + list(APPEND srcs + "lwip/src/netif/ppp/polarssl/arc4.c" + "lwip/src/netif/ppp/polarssl/des.c" + "lwip/src/netif/ppp/polarssl/md4.c" + "lwip/src/netif/ppp/polarssl/md5.c" + "lwip/src/netif/ppp/polarssl/sha1.c") + endif() + if(CONFIG_LWIP_DHCPS) list(APPEND srcs "apps/dhcpserver/dhcpserver.c") endif() @@ -215,6 +219,10 @@ if(CONFIG_LWIP_ENABLE) idf_component_optional_requires(PRIVATE nvs_flash) endif() + if(CONFIG_LWIP_USE_EXTERNAL_MBEDTLS) + idf_component_optional_requires(PRIVATE mbedtls) + endif() + if(${target} STREQUAL "linux") set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index 1904ba5b7032..5f2bb733e830 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -669,7 +669,7 @@ menu "LWIP" LWIP_TCP_RECCVMBOX_SIZE packets for each TCP socket, so the maximum possible cached TCP packets for all TCP sockets is LWIP_TCP_RECCVMBOX_SIZE multiples the maximum TCP socket number. In other words, the bigger LWIP_TCP_RECVMBOX_SIZE means more memory. - On the other hand, if the receiv mail box is too small, the mail box may be full. If the + On the other hand, if the receive mail box is too small, the mail box may be full. If the mail box is full, the LWIP drops the packets. So generally we need to make sure the TCP receive mail box is big enough to avoid packet drop between LWIP core and application. @@ -813,7 +813,7 @@ menu "LWIP" UDP_RECCVMBOX_SIZE packets for each UDP socket, so the maximum possible cached UDP packets for all UDP sockets is UDP_RECCVMBOX_SIZE multiples the maximum UDP socket number. In other words, the bigger UDP_RECVMBOX_SIZE means more memory. - On the other hand, if the receiv mail box is too small, the mail box may be full. If the + On the other hand, if the receive mail box is too small, the mail box may be full. If the mail box is full, the LWIP drops the packets. So generally we need to make sure the UDP receive mail box is big enough to avoid packet drop between LWIP core and application. @@ -992,6 +992,17 @@ menu "LWIP" help Enable PPP debug log output + config LWIP_USE_EXTERNAL_MBEDTLS + bool "Use mbedTLS instead of internal polarSSL" + depends on LWIP_PPP_SUPPORT + depends on !LWIP_PPP_MPPE_SUPPORT && !LWIP_PPP_MSCHAP_SUPPORT + default n + help + This option uses mbedTLS crypto functions (instead of internal PolarSSL + implementation) for PPP authentication modes (PAP, CHAP, etc.). + You can use this option to address symbol duplication issues, since + the internal functions are not namespaced (e.g. md5_init()). + menuconfig LWIP_SLIP_SUPPORT bool "Enable SLIP support (new/experimental)" default n @@ -1060,12 +1071,12 @@ menu "LWIP" SNTP callback for such replies should be set accordingly (see sntp_servermode_dhcp() func.) config LWIP_DHCP_MAX_NTP_SERVERS - int "Maximum number of NTP servers aquired via DHCP" + int "Maximum number of NTP servers acquired via DHCP" default 1 range 1 16 depends on LWIP_DHCP_GET_NTP_SRV help - Set maximum number of NTP servers aquired via DHCP-offer. + Set maximum number of NTP servers acquired via DHCP-offer. Should be less or equal to "Maximum number of NTP servers", any extra servers would be just ignored. config LWIP_SNTP_UPDATE_DELAY @@ -1101,6 +1112,12 @@ menu "LWIP" menu "DNS" + config LWIP_DNS_MAX_HOST_IP + int "Maximum number of IP addresses per host" + default 1 + help + Maximum number of IP addresses that can be returned by DNS queries for a single host. + config LWIP_DNS_MAX_SERVERS int "Maximum number of DNS servers" default 3 @@ -1124,6 +1141,15 @@ menu "LWIP" help This option allows you to config dns fallback server address. + config LWIP_DNS_SETSERVER_WITH_NETIF + bool "Enable DNS server settings with netif" + default n + help + This option allows collecting DNS server settings per netif using + configurable callback function. + It's typically used with CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF + which configures a callback to collect the DNS info on esp_netif layer. + endmenu # DNS config LWIP_BRIDGEIF_MAX_PORTS diff --git a/components/lwip/lwip b/components/lwip/lwip index f79221431fa9..bced058f737e 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit f79221431fa9042b3572d271d687de66da7560c4 +Subproject commit bced058f737eaabea1aa193f3c365ee78ff555f3 diff --git a/components/lwip/port/include/lwipopts.h b/components/lwip/port/include/lwipopts.h index 51e3c3c3d0da..db4ef60bcfaa 100644 --- a/components/lwip/port/include/lwipopts.h +++ b/components/lwip/port/include/lwipopts.h @@ -470,6 +470,10 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) */ #define LWIP_DNS 1 +/** The maximum number of IP addresses per host + */ +#define DNS_MAX_HOST_IP CONFIG_LWIP_DNS_MAX_HOST_IP + /** The maximum of DNS servers */ #define DNS_MAX_SERVERS CONFIG_LWIP_DNS_MAX_SERVERS @@ -499,6 +503,17 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #define LWIP_DNS_SUPPORT_MDNS_QUERIES 0 #endif +/** + * LWIP_DNS_SETSERVER_WITH_NETIF: If this is turned on, the dns_setserver_with_netif() is enabled and called + * from all internal modules (instead of dns_setserver()) allowing to setup a user callback to collect DNS server + * information acquired by the related network interface. + */ +#ifdef CONFIG_LWIP_DNS_SETSERVER_WITH_NETIF +#define LWIP_DNS_SETSERVER_WITH_NETIF 1 +#else +#define LWIP_DNS_SETSERVER_WITH_NETIF 0 +#endif + /* --------------------------------- ---------- UDP options ---------- @@ -1103,7 +1118,7 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) /** * PPP_MAXIDLEFLAG: Max Xmit idle time (in ms) before resend flag char. * TODO: If PPP_MAXIDLEFLAG > 0 and next package is send during PPP_MAXIDLEFLAG time, - * then 0x7E is not added at the begining of PPP package but 0x7E termination + * then 0x7E is not added at the beginning of PPP package but 0x7E termination * is always at the end. This behaviour brokes PPP dial with GSM (PPPoS). * The PPP package should always start and end with 0x7E. */ @@ -1136,6 +1151,15 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #define PPP_SUPPORT 0 #endif /* CONFIG_LWIP_PPP_SUPPORT */ +/** + * LWIP_USE_EXTERNAL_MBEDTLS: Use external mbed TLS library for crypto implementation used in PPP AUTH + */ +#ifdef CONFIG_LWIP_USE_EXTERNAL_MBEDTLS +#define LWIP_USE_EXTERNAL_MBEDTLS 1 +#else +#define LWIP_USE_EXTERNAL_MBEDTLS 0 +#endif + /* -------------------------------------- ---------- Checksum options ---------- diff --git a/components/mbedtls/port/aes/esp_aes_gcm.c b/components/mbedtls/port/aes/esp_aes_gcm.c index 380bee837957..2491de8b8c71 100644 --- a/components/mbedtls/port/aes/esp_aes_gcm.c +++ b/components/mbedtls/port/aes/esp_aes_gcm.c @@ -41,7 +41,7 @@ *(uint64_t*)(a) = __builtin_bswap64( (uint64_t)(val) ); \ } while (0) -/* For simplicity limit the maxium amount of aad bytes to a single DMA descriptor +/* For simplicity limit the maximum amount of aad bytes to a single DMA descriptor This should cover all normal, e.g. mbedtls, use cases */ #define ESP_AES_GCM_AAD_MAX_BYTES 4080 @@ -131,7 +131,7 @@ static void xor_data(uint8_t *d, const uint8_t *s) } #endif -/* Based on MbedTLS's implemenation +/* Based on MbedTLS's implementation * * Precompute small multiples of H, that is set * HH[i] || HL[i] = H times i, @@ -198,7 +198,7 @@ static const uint64_t last4[16] = { 0xe100, 0xfd20, 0xd940, 0xc560, 0x9180, 0x8da0, 0xa9c0, 0xb5e0 }; -/* Based on MbedTLS's implemenation +/* Based on MbedTLS's implementation * * Sets output to x times H using the precomputed tables. * x and output are seen as elements of GF(2^128) as in [MGV]. @@ -670,7 +670,7 @@ int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx, int ret; size_t remainder_bit; - /* Due to hardware limition only certain cases are fully supported in HW */ + /* Due to hardware limitation only certain cases are fully supported in HW */ if (!esp_aes_gcm_input_support_hw_accel(length, aad, aad_len, input, output)) { return esp_aes_gcm_crypt_and_tag_partial_hw(ctx, mode, length, iv, iv_len, aad, aad_len, input, output, tag_len, tag); } diff --git a/components/mqtt/esp-mqtt b/components/mqtt/esp-mqtt index aa6f889fb4f6..cac1552e62b0 160000 --- a/components/mqtt/esp-mqtt +++ b/components/mqtt/esp-mqtt @@ -1 +1 @@ -Subproject commit aa6f889fb4f6f743b3a550aa587713aabbdca1fc +Subproject commit cac1552e62b0474c162547b7cce345d7cd1aecfe diff --git a/components/newlib/sbom.yml b/components/newlib/sbom.yml index f0fee8725557..b44a0d098a49 100644 --- a/components/newlib/sbom.yml +++ b/components/newlib/sbom.yml @@ -4,3 +4,6 @@ cpe: cpe:2.3:a:newlib_project:newlib:{}:*:*:*:*:*:*:* supplier: 'Organization: Espressif Systems (Shanghai) CO LTD' originator: 'Organization: Red Hat Incorporated' description: An open-source C standard library implementation with additional features and patches from Espressif. +cve-exclude-list: + - cve: CVE-2024-30949 + reason: May affect RISCV binaries that are linked with libgloss. IDF does not link against this library. diff --git a/components/newlib/time.c b/components/newlib/time.c index 4b9fc6ca8ec3..ce993e8f71c9 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -200,7 +200,10 @@ WEAK_UNLESS_TIMEFUNC_IMPL int settimeofday(const struct timeval *tv, const struc int usleep(useconds_t us) { - const int us_per_tick = portTICK_PERIOD_MS * 1000; + /* Even at max tick rate, vTaskDelay can still delay for the max of the us argument, + we just need to make sure the tick calculation does not overflow + */ + const int64_t us_per_tick = portTICK_PERIOD_MS * 1000; if (us < us_per_tick) { esp_rom_delay_us((uint32_t) us); } else { diff --git a/components/protocomm/include/transports/protocomm_ble.h b/components/protocomm/include/transports/protocomm_ble.h index cbc7c81bd52a..a6758a4cf314 100644 --- a/components/protocomm/include/transports/protocomm_ble.h +++ b/components/protocomm/include/transports/protocomm_ble.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -142,6 +142,11 @@ typedef struct protocomm_ble_config { * BLE address */ uint8_t *ble_addr; + + /** + * BLE characteristic notify flag + */ + unsigned ble_notify:1; } protocomm_ble_config_t; /** diff --git a/components/protocomm/src/simple_ble/simple_ble.c b/components/protocomm/src/simple_ble/simple_ble.c index ac33cf2409fa..86a6acd4dc3b 100644 --- a/components/protocomm/src/simple_ble/simple_ble.c +++ b/components/protocomm/src/simple_ble/simple_ble.c @@ -236,14 +236,15 @@ esp_err_t simple_ble_start(simple_ble_cfg_t *cfg) return ret; } -#ifdef CONFIG_BTDM_CTRL_MODE_BTDM - ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); -#elif defined CONFIG_BTDM_CTRL_MODE_BLE_ONLY || CONFIG_BT_CTRL_MODE_EFF - ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); -#else +#ifdef CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY ESP_LOGE(TAG, "Configuration mismatch. Select BLE Only or BTDM mode from menuconfig"); return ESP_FAIL; +#elif CONFIG_BTDM_CTRL_MODE_BTDM + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); +#else //For all other chips supporting BLE Only + ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); #endif + if (ret) { ESP_LOGE(TAG, "%s enable controller failed %d", __func__, ret); return ret; diff --git a/components/protocomm/src/transports/protocomm_ble.c b/components/protocomm/src/transports/protocomm_ble.c index 6fedd85abb92..742f453d9c08 100644 --- a/components/protocomm/src/transports/protocomm_ble.c +++ b/components/protocomm/src/transports/protocomm_ble.c @@ -37,6 +37,8 @@ static const uint16_t primary_service_uuid = ESP_GATT_UUID_PRI_SERVICE; static const uint16_t character_declaration_uuid = ESP_GATT_UUID_CHAR_DECLARE; static const uint16_t character_user_description = ESP_GATT_UUID_CHAR_DESCRIPTION; static const uint8_t character_prop_read_write = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE; +static const uint8_t character_prop_read_write_notify = ESP_GATT_CHAR_PROP_BIT_READ | ESP_GATT_CHAR_PROP_BIT_WRITE | \ + ESP_GATT_CHAR_PROP_BIT_NOTIFY; typedef struct { uint8_t type; @@ -64,6 +66,7 @@ typedef struct _protocomm_ble { uint16_t gatt_mtu; uint8_t *service_uuid; unsigned ble_link_encryption:1; + unsigned ble_notify:1; } _protocomm_ble_internal_t; static _protocomm_ble_internal_t *protoble_internal; @@ -450,7 +453,12 @@ static ssize_t populate_gatt_db(esp_gatts_attr_db_t **gatt_db_generated) (*gatt_db_generated)[i].att_desc.uuid_p = (uint8_t *) &character_declaration_uuid; (*gatt_db_generated)[i].att_desc.max_length = sizeof(uint8_t); (*gatt_db_generated)[i].att_desc.length = sizeof(uint8_t); - (*gatt_db_generated)[i].att_desc.value = (uint8_t *) &character_prop_read_write; + + if (protoble_internal->ble_notify) { + (*gatt_db_generated)[i].att_desc.value = (uint8_t *) &character_prop_read_write_notify; + } else { + (*gatt_db_generated)[i].att_desc.value = (uint8_t *) &character_prop_read_write; + } } else if (i % 3 == 2) { /* Characteristic Value */ (*gatt_db_generated)[i].att_desc.perm = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE ; @@ -562,6 +570,7 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con protoble_internal->pc_ble = pc; protoble_internal->gatt_mtu = ESP_GATT_DEF_BLE_MTU_SIZE; protoble_internal->ble_link_encryption = config->ble_link_encryption; + protoble_internal->ble_notify = config->ble_notify; // Config adv data adv_config.service_uuid_len = ESP_UUID_LEN_128; diff --git a/components/protocomm/src/transports/protocomm_nimble.c b/components/protocomm/src/transports/protocomm_nimble.c index 8aa2e4ec6def..5d83f5635958 100644 --- a/components/protocomm/src/transports/protocomm_nimble.c +++ b/components/protocomm/src/transports/protocomm_nimble.c @@ -69,6 +69,7 @@ typedef struct _protocomm_ble { ssize_t g_nu_lookup_count; uint16_t gatt_mtu; unsigned ble_link_encryption:1; + unsigned ble_notify:1; } _protocomm_ble_internal_t; static _protocomm_ble_internal_t *protoble_internal; @@ -133,6 +134,8 @@ typedef struct { unsigned ble_link_encryption:1; /** BLE address */ uint8_t *ble_addr; + /** BLE Characteristic notify flag */ + unsigned ble_notify:1; } simple_ble_cfg_t; static simple_ble_cfg_t *ble_cfg_p; @@ -265,6 +268,14 @@ simple_ble_gap_event(struct ble_gap_event *event, void *arg) event->mtu.value); transport_simple_ble_set_mtu(event, arg); return 0; + case BLE_GAP_EVENT_NOTIFY_TX: + ESP_LOGI(TAG, "notify_tx event; conn_handle=%d attr_handle=%d " + "status=%d is_indication=%d", + event->notify_tx.conn_handle, + event->notify_tx.attr_handle, + event->notify_tx.status, + event->notify_tx.indication); + return 0; } return 0; } @@ -715,6 +726,10 @@ ble_gatt_add_characteristics(struct ble_gatt_chr_def *characteristics, int idx) BLE_GATT_CHR_F_WRITE_ENC; } + if (protoble_internal->ble_notify) { + (characteristics + idx)->flags |= BLE_GATT_CHR_F_NOTIFY; + } + (characteristics + idx)->access_cb = gatt_svr_chr_access; /* Out of 128 bit UUID, 16 bits from g_nu_lookup table. Currently @@ -972,6 +987,7 @@ esp_err_t protocomm_ble_start(protocomm_t *pc, const protocomm_ble_config_t *con protoble_internal->pc_ble = pc; protoble_internal->gatt_mtu = BLE_ATT_MTU_DFLT; protoble_internal->ble_link_encryption = config->ble_link_encryption; + protoble_internal->ble_notify = config->ble_notify; simple_ble_cfg_t *ble_config = (simple_ble_cfg_t *) calloc(1, sizeof(simple_ble_cfg_t)); if (ble_config == NULL) { diff --git a/components/riscv/include/riscv/rv_utils.h b/components/riscv/include/riscv/rv_utils.h index c0d3a64b2f03..cc8c608e4aeb 100644 --- a/components/riscv/include/riscv/rv_utils.h +++ b/components/riscv/include/riscv/rv_utils.h @@ -27,6 +27,13 @@ extern "C" { #define CSR_PCCR_MACHINE 0x7e2 #endif /* SOC_CPU_HAS_CSR_PC */ +#if SOC_BRANCH_PREDICTOR_SUPPORTED +#define MHCR 0x7c1 +#define MHCR_RS (1<<4) /* R/W, address return stack set bit */ +#define MHCR_BFE (1<<5) /* R/W, allow predictive jump set bit */ +#define MHCR_BTB (1<<12) /* R/W, branch target prediction enable bit */ +#endif //SOC_BRANCH_PREDICTOR_SUPPORTED + #if SOC_CPU_HAS_FPU /* FPU bits in mstatus start at bit 13 */ @@ -363,12 +370,13 @@ FORCE_INLINE_ATTR bool rv_utils_compare_and_set(volatile uint32_t *addr, uint32_ #if SOC_BRANCH_PREDICTOR_SUPPORTED FORCE_INLINE_ATTR void rv_utils_en_branch_predictor(void) { -#define MHCR 0x7c1 -#define MHCR_RS (1<<4) /* R/W, address return stack set bit */ -#define MHCR_BFE (1<<5) /* R/W, allow predictive jump set bit */ -#define MHCR_BTB (1<<12) /* R/W, branch target prediction enable bit */ RV_SET_CSR(MHCR, MHCR_RS|MHCR_BFE|MHCR_BTB); } + +FORCE_INLINE_ATTR void rv_utils_dis_branch_predictor(void) +{ + RV_CLEAR_CSR(MHCR, MHCR_RS|MHCR_BFE|MHCR_BTB); +} #endif #ifdef __cplusplus diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index b3a53fb77984..2b21132528a4 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -91,7 +91,7 @@ if(CONFIG_SOC_GPTIMER_SUPPORTED) list(APPEND srcs "${target_folder}/timer_periph.c") endif() -if(CONFIG_SOC_LCDCAM_SUPPORTED OR CONFIG_SOC_LCD_I80_SUPPORTED) +if(CONFIG_SOC_LCDCAM_SUPPORTED OR CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA) list(APPEND srcs "${target_folder}/lcd_periph.c") endif() @@ -127,6 +127,10 @@ if(CONFIG_SOC_TWAI_SUPPORTED) list(APPEND srcs "${target_folder}/twai_periph.c") endif() +if(CONFIG_SOC_WDT_SUPPORTED) + list(APPEND srcs "${target_folder}/wdt_periph.c") +endif() + if(CONFIG_SOC_IEEE802154_SUPPORTED) if(NOT target STREQUAL "esp32h4") list(APPEND srcs "${target_folder}/ieee802154_periph.c") diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index ebe9974fb033..7837f082aacd 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -439,6 +439,10 @@ config SOC_I2S_SUPPORTS_LCD_CAMERA bool default y +config SOC_I2S_MAX_DATA_WIDTH + int + default 24 + config SOC_I2S_TRANS_SIZE_ALIGN_WORD bool default y diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index 0519bc04c88e..0b988de2f192 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -222,6 +222,7 @@ #define SOC_I2S_SUPPORTS_ADC (1) #define SOC_I2S_SUPPORTS_DAC (1) #define SOC_I2S_SUPPORTS_LCD_CAMERA (1) +#define SOC_I2S_MAX_DATA_WIDTH (24) #define SOC_I2S_TRANS_SIZE_ALIGN_WORD (1) // I2S DMA transfer size must be aligned to word #define SOC_I2S_LCD_I80_VARIANT (1) // I2S has a special LCD mode that can generate Intel 8080 TX timing diff --git a/components/soc/esp32/lcd_periph.c b/components/soc/esp32/lcd_periph.c index 148a1527aa86..20bfe02713ca 100644 --- a/components/soc/esp32/lcd_periph.c +++ b/components/soc/esp32/lcd_periph.c @@ -8,7 +8,7 @@ #include "soc/lcd_periph.h" #include "soc/gpio_sig_map.h" -const lcd_signal_conn_t lcd_periph_signals = { +const lcd_i2s_signal_conn_t lcd_periph_i2s_signals = { .buses = { [0] = { .module = PERIPH_I2S0_MODULE, diff --git a/components/soc/esp32/wdt_periph.c b/components/soc/esp32/wdt_periph.c new file mode 100644 index 000000000000..58f1349d3d24 --- /dev/null +++ b/components/soc/esp32/wdt_periph.c @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/wdt_periph.h" diff --git a/components/soc/esp32c2/wdt_periph.c b/components/soc/esp32c2/wdt_periph.c new file mode 100644 index 000000000000..58f1349d3d24 --- /dev/null +++ b/components/soc/esp32c2/wdt_periph.c @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/wdt_periph.h" diff --git a/components/soc/esp32c3/wdt_periph.c b/components/soc/esp32c3/wdt_periph.c new file mode 100644 index 000000000000..58f1349d3d24 --- /dev/null +++ b/components/soc/esp32c3/wdt_periph.c @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/wdt_periph.h" diff --git a/components/soc/esp32c5/beta3/include/soc/system_periph_retention.h b/components/soc/esp32c5/beta3/include/soc/system_periph_retention.h index 23c82b295388..a63ae5fdeca4 100644 --- a/components/soc/esp32c5/beta3/include/soc/system_periph_retention.h +++ b/components/soc/esp32c5/beta3/include/soc/system_periph_retention.h @@ -76,7 +76,7 @@ extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_L * useful for external use. */ #define SPIMEM_RETENTION_LINK_LEN 8 -extern const regdma_entries_config_t spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; +extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; /** * @brief Provide access to systimer configuration registers retention diff --git a/components/soc/esp32c5/beta3/system_retention_periph.c b/components/soc/esp32c5/beta3/system_retention_periph.c index 52822f92720e..74d1b2a367e4 100644 --- a/components/soc/esp32c5/beta3/system_retention_periph.c +++ b/components/soc/esp32c5/beta3/system_retention_periph.c @@ -66,7 +66,7 @@ _Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "In #define N_REGS_SPI0_MEM_1() (((SPI_SMEM_AC_REG(0) - SPI_FMEM_PMS0_ATTR_REG(0)) / 4) + 1) #define N_REGS_SPI0_MEM_2() (1) #define N_REGS_SPI0_MEM_3() (((SPI_MEM_DATE_REG(0) - SPI_MEM_MMU_POWER_CTRL_REG(0)) / 4) + 1) -const regdma_entries_config_t spimem_regs_retention[] = { +const regdma_entries_config_t flash_spimem_regs_retention[] = { /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), REG_SPI_MEM_BASE(1), REG_SPI_MEM_BASE(1), N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */ [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_FMEM_PMS0_ATTR_REG(1), SPI_FMEM_PMS0_ATTR_REG(1), N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, @@ -79,7 +79,7 @@ const regdma_entries_config_t spimem_regs_retention[] = { [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } }; -_Static_assert(ARRAY_SIZE(spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); +_Static_assert(ARRAY_SIZE(flash_spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); /* Systimer Registers Context */ #define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) diff --git a/components/soc/esp32c5/wdt_periph.c b/components/soc/esp32c5/wdt_periph.c new file mode 100644 index 000000000000..58f1349d3d24 --- /dev/null +++ b/components/soc/esp32c5/wdt_periph.c @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/wdt_periph.h" diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index ad96f280199c..73b9b913df14 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1131,6 +1131,10 @@ config SOC_MWDT_SUPPORT_XTAL bool default y +config SOC_MWDT_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_TWAI_CONTROLLER_NUM int default 2 diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 0fe0febf20e1..f4d5a4c3fd55 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -447,6 +447,7 @@ /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ #define SOC_MWDT_SUPPORT_XTAL (1) +#define SOC_MWDT_SUPPORT_SLEEP_RETENTION (1) /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 2 diff --git a/components/soc/esp32c6/include/soc/system_periph_retention.h b/components/soc/esp32c6/include/soc/system_periph_retention.h index 539b3500d35c..54f7c3e205f7 100644 --- a/components/soc/esp32c6/include/soc/system_periph_retention.h +++ b/components/soc/esp32c6/include/soc/system_periph_retention.h @@ -75,7 +75,7 @@ extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_L * useful for external use. */ #define SPIMEM_RETENTION_LINK_LEN 8 -extern const regdma_entries_config_t spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; +extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; /** * @brief Provide access to systimer configuration registers retention diff --git a/components/soc/esp32c6/system_retention_periph.c b/components/soc/esp32c6/system_retention_periph.c index 4ff06bdbcbfb..2d9227575a38 100644 --- a/components/soc/esp32c6/system_retention_periph.c +++ b/components/soc/esp32c6/system_retention_periph.c @@ -67,7 +67,7 @@ _Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "In #define N_REGS_SPI0_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(0) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0)) / 4) + 1) #define N_REGS_SPI0_MEM_2() (1) #define N_REGS_SPI0_MEM_3() (((SPI_MEM_DATE_REG(0) - SPI_MEM_MMU_POWER_CTRL_REG(0)) / 4) + 1) -const regdma_entries_config_t spimem_regs_retention[] = { +const regdma_entries_config_t flash_spimem_regs_retention[] = { /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), REG_SPI_MEM_BASE(1), REG_SPI_MEM_BASE(1), N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */ [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, @@ -80,7 +80,7 @@ const regdma_entries_config_t spimem_regs_retention[] = { [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } }; -_Static_assert(ARRAY_SIZE(spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); +_Static_assert(ARRAY_SIZE(flash_spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); /* Systimer Registers Context */ #define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) diff --git a/components/soc/esp32c6/timer_periph.c b/components/soc/esp32c6/timer_periph.c index 422b536f37a4..58750906fd8f 100644 --- a/components/soc/esp32c6/timer_periph.c +++ b/components/soc/esp32c6/timer_periph.c @@ -23,68 +23,111 @@ const timer_group_signal_conn_t timer_group_periph_signals = { } }; -#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG - -static const regdma_entries_config_t tg0_wdt_regs_retention[] = { - /*Timer group backup. should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, -}; - -static const regdma_entries_config_t tg1_wdt_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, -}; - /* Registers in retention context: * TIMG_T0CONFIG_REG * TIMG_T0ALARMLO_REG * TIMG_T0ALARMHI_REG + * TIMG_T0LOADLO_REG + * TIMG_T0LOADHI_REG * TIMG_INT_ENA_TIMERS_REG * TIMG_REGCLK_REG */ -#define N_REGS_TG_TIMER_CFG 5 -static const uint32_t tg_timer_regs_map[4] = {0x10000031, 0x80000000, 0, 0}; +#define TG_TIMER_RETENTION_REGS_CNT 7 +static const uint32_t tg_timer_regs_map[4] = {0x100000f1, 0x80000000, 0x0, 0x0}; -const regdma_entries_config_t tg0_timer_regs_retention[] = { +const regdma_entries_config_t tg0_timer_regdma_entries[] = { + // backup stage: trigger a soft capture [0] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), N_REGS_TG_TIMER_CFG, 0, 0, \ - tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2) + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x00), + TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: wait for the capture done + [1] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x01), + TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save the captured counter value + // restore stage: store the captured counter value to the loader register + [2] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x02), + TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + [3] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), + TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // restore stage: trigger a soft reload, so the timer can continue from where it was backed up + [4] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x04), + TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save other configuration and status registers + // restore stage: restore the configuration and status registers + [5] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x05), + TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), + TG_TIMER_RETENTION_REGS_CNT, 0, 0, + tg_timer_regs_map[0], tg_timer_regs_map[1], + tg_timer_regs_map[2], tg_timer_regs_map[3]), + .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x05), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, }; -const regdma_entries_config_t tg1_timer_regs_retention[] = { +const regdma_entries_config_t tg1_timer_regdma_entries[] = { + // backup stage: trigger a soft capture [0] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), N_REGS_TG_TIMER_CFG, 0, 0, \ - tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2) + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x00), + TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: wait for the capture done + [1] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x01), + TIMG_T0UPDATE_REG(1), 0x0, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save the captured counter value + // restore stage: store the captured counter value to the loader register + [2] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x02), + TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + [3] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), + TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // restore stage: trigger a soft reload, so the timer can continue from where it was backed up + [4] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x04), + TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save other configuration and status registers + // restore stage: restore the configuration and status registers + [5] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x05), + TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), + TG_TIMER_RETENTION_REGS_CNT, 0, 0, + tg_timer_regs_map[0], tg_timer_regs_map[1], + tg_timer_regs_map[2], tg_timer_regs_map[3]), + .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, -}; - -const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = { - [0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, - [1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, }; -const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = { - [0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)}, - [1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)}, +const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS] = { + [0] = { + .regdma_entry_array = tg0_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg0_timer_regdma_entries) + }, + [1] = { + .regdma_entry_array = tg1_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg1_timer_regdma_entries) + }, }; diff --git a/components/soc/esp32c6/wdt_periph.c b/components/soc/esp32c6/wdt_periph.c new file mode 100644 index 000000000000..f615401cfa8f --- /dev/null +++ b/components/soc/esp32c6/wdt_periph.c @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/wdt_periph.h" + +#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG + +static const regdma_entries_config_t tg0_wdt_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x02), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x04), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x05), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +static const regdma_entries_config_t tg1_wdt_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x05), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = { + [0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, + [1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, +}; diff --git a/components/soc/esp32c61/wdt_periph.c b/components/soc/esp32c61/wdt_periph.c new file mode 100644 index 000000000000..58f1349d3d24 --- /dev/null +++ b/components/soc/esp32c61/wdt_periph.c @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/wdt_periph.h" diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index f4097d1e6fa1..344914ca47fe 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1131,6 +1131,10 @@ config SOC_MWDT_SUPPORT_XTAL bool default y +config SOC_MWDT_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_TWAI_CONTROLLER_NUM int default 1 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 715821f8afc0..ec15e3e7932d 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -444,6 +444,7 @@ /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ #define SOC_MWDT_SUPPORT_XTAL (1) +#define SOC_MWDT_SUPPORT_SLEEP_RETENTION (1) /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 1UL diff --git a/components/soc/esp32h2/include/soc/system_periph_retention.h b/components/soc/esp32h2/include/soc/system_periph_retention.h index 539b3500d35c..54f7c3e205f7 100644 --- a/components/soc/esp32h2/include/soc/system_periph_retention.h +++ b/components/soc/esp32h2/include/soc/system_periph_retention.h @@ -75,7 +75,7 @@ extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_L * useful for external use. */ #define SPIMEM_RETENTION_LINK_LEN 8 -extern const regdma_entries_config_t spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; +extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; /** * @brief Provide access to systimer configuration registers retention diff --git a/components/soc/esp32h2/system_retention_periph.c b/components/soc/esp32h2/system_retention_periph.c index d9f3c5b469f8..436840e68231 100644 --- a/components/soc/esp32h2/system_retention_periph.c +++ b/components/soc/esp32h2/system_retention_periph.c @@ -66,7 +66,7 @@ _Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "In #define N_REGS_SPI0_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(0) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(0)) / 4) + 1) #define N_REGS_SPI0_MEM_2() (1) #define N_REGS_SPI0_MEM_3() (((SPI_MEM_DATE_REG(0) - SPI_MEM_MMU_POWER_CTRL_REG(0)) / 4) + 1) -const regdma_entries_config_t spimem_regs_retention[] = { +const regdma_entries_config_t flash_spimem_regs_retention[] = { /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), REG_SPI_MEM_BASE(1), REG_SPI_MEM_BASE(1), N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */ [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1), N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, @@ -79,7 +79,7 @@ const regdma_entries_config_t spimem_regs_retention[] = { [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } }; -_Static_assert(ARRAY_SIZE(spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); +_Static_assert(ARRAY_SIZE(flash_spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); /* Systimer Registers Context */ #define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) diff --git a/components/soc/esp32h2/timer_periph.c b/components/soc/esp32h2/timer_periph.c index 422b536f37a4..58750906fd8f 100644 --- a/components/soc/esp32h2/timer_periph.c +++ b/components/soc/esp32h2/timer_periph.c @@ -23,68 +23,111 @@ const timer_group_signal_conn_t timer_group_periph_signals = { } }; -#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG - -static const regdma_entries_config_t tg0_wdt_regs_retention[] = { - /*Timer group backup. should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, -}; - -static const regdma_entries_config_t tg1_wdt_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, -}; - /* Registers in retention context: * TIMG_T0CONFIG_REG * TIMG_T0ALARMLO_REG * TIMG_T0ALARMHI_REG + * TIMG_T0LOADLO_REG + * TIMG_T0LOADHI_REG * TIMG_INT_ENA_TIMERS_REG * TIMG_REGCLK_REG */ -#define N_REGS_TG_TIMER_CFG 5 -static const uint32_t tg_timer_regs_map[4] = {0x10000031, 0x80000000, 0, 0}; +#define TG_TIMER_RETENTION_REGS_CNT 7 +static const uint32_t tg_timer_regs_map[4] = {0x100000f1, 0x80000000, 0x0, 0x0}; -const regdma_entries_config_t tg0_timer_regs_retention[] = { +const regdma_entries_config_t tg0_timer_regdma_entries[] = { + // backup stage: trigger a soft capture [0] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), N_REGS_TG_TIMER_CFG, 0, 0, \ - tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2) + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x00), + TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: wait for the capture done + [1] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x01), + TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save the captured counter value + // restore stage: store the captured counter value to the loader register + [2] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x02), + TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + [3] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), + TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // restore stage: trigger a soft reload, so the timer can continue from where it was backed up + [4] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x04), + TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save other configuration and status registers + // restore stage: restore the configuration and status registers + [5] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x05), + TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), + TG_TIMER_RETENTION_REGS_CNT, 0, 0, + tg_timer_regs_map[0], tg_timer_regs_map[1], + tg_timer_regs_map[2], tg_timer_regs_map[3]), + .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x03), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x05), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, }; -const regdma_entries_config_t tg1_timer_regs_retention[] = { +const regdma_entries_config_t tg1_timer_regdma_entries[] = { + // backup stage: trigger a soft capture [0] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), N_REGS_TG_TIMER_CFG, 0, 0, \ - tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2) + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x00), + TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: wait for the capture done + [1] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x01), + TIMG_T0UPDATE_REG(1), 0x0, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save the captured counter value + // restore stage: store the captured counter value to the loader register + [2] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x02), + TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + [3] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), + TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // restore stage: trigger a soft reload, so the timer can continue from where it was backed up + [4] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x04), + TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), + .owner = ENTRY(0) | ENTRY(2) + }, + // backup stage: save other configuration and status registers + // restore stage: restore the configuration and status registers + [5] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x05), + TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), + TG_TIMER_RETENTION_REGS_CNT, 0, 0, + tg_timer_regs_map[0], tg_timer_regs_map[1], + tg_timer_regs_map[2], tg_timer_regs_map[3]), + .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x03), TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, -}; - -const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = { - [0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, - [1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, }; -const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = { - [0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)}, - [1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)}, +const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS] = { + [0] = { + .regdma_entry_array = tg0_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg0_timer_regdma_entries) + }, + [1] = { + .regdma_entry_array = tg1_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg1_timer_regdma_entries) + }, }; diff --git a/components/soc/esp32h2/wdt_periph.c b/components/soc/esp32h2/wdt_periph.c new file mode 100644 index 000000000000..f615401cfa8f --- /dev/null +++ b/components/soc/esp32h2/wdt_periph.c @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/wdt_periph.h" + +#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG + +static const regdma_entries_config_t tg0_wdt_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x02), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x04), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x05), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +static const regdma_entries_config_t tg1_wdt_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x05), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = { + [0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, + [1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, +}; diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index e55ced27f023..9fbb14e8326a 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -47,10 +47,18 @@ config SOC_PCNT_SUPPORTED bool default y +config SOC_LCDCAM_SUPPORTED + bool + default y + config SOC_LCDCAM_CAM_SUPPORTED bool default y +config SOC_LCDCAM_I80_LCD_SUPPORTED + bool + default y + config SOC_MIPI_CSI_SUPPORTED bool default y @@ -999,25 +1007,21 @@ config SOC_RMT_SUPPORT_DMA bool default y -config SOC_LCD_I80_BUSES - int - default 1 +config SOC_LCD_I80_SUPPORTED + bool + default y -config SOC_LCD_RGB_PANELS +config SOC_LCDCAM_I80_NUM_BUSES int default 1 -config SOC_LCD_I80_BUS_WIDTH +config SOC_LCDCAM_I80_BUS_WIDTH int default 24 -config SOC_LCD_RGB_DATA_WIDTH +config SOC_LCDCAM_RGB_NUM_PANELS int - default 24 - -config SOC_LCD_SUPPORT_RGB_YUV_CONV - bool - default y + default 1 config SOC_MCPWM_GROUPS int @@ -1403,6 +1407,10 @@ config SOC_MWDT_SUPPORT_XTAL bool default y +config SOC_MWDT_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_TOUCH_SENSOR_VERSION int default 3 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 71d88b890a22..e92337780891 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -28,8 +28,10 @@ #define SOC_DMA2D_SUPPORTED 1 #define SOC_GPTIMER_SUPPORTED 1 #define SOC_PCNT_SUPPORTED 1 -// #define SOC_LCDCAM_SUPPORTED 1 // TODO: IDF-7465 +#define SOC_LCDCAM_SUPPORTED 1 #define SOC_LCDCAM_CAM_SUPPORTED 1 +#define SOC_LCDCAM_I80_LCD_SUPPORTED 1 // support the Intel 8080 bus driver based on the LCD_CAM peripheral +// #define SOC_LCDCAM_RGB_LCD_SUPPORTED 1 // TODO: IDF-7465 #define SOC_MIPI_CSI_SUPPORTED 1 #define SOC_MIPI_DSI_SUPPORTED 1 #define SOC_MCPWM_SUPPORTED 1 @@ -117,7 +119,7 @@ #define SOC_ADC_DIG_SUPPORTED_UNIT(UNIT) 1 //Digital controller supported ADC unit #define SOC_ADC_DMA_SUPPORTED 1 #define SOC_ADC_PERIPH_NUM (2) -#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 6: 8) +#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 8: 6) #define SOC_ADC_MAX_CHANNEL_NUM (8) #define SOC_ADC_ATTEN_NUM (4) @@ -384,14 +386,13 @@ #define SOC_RMT_SUPPORT_DMA 1 /*!< RMT peripheral can connect to DMA channel */ /*-------------------------- LCD CAPS ----------------------------------------*/ -/* I80 bus and RGB timing generator can't work at the same time */ -// #define SOC_LCD_I80_SUPPORTED (1) /*!< Intel 8080 LCD is supported */ // TODO: IDF-7465 -// #define SOC_LCD_RGB_SUPPORTED (1) /*!< RGB LCD is supported */ // TODO: IDF-7465 -#define SOC_LCD_I80_BUSES (1U) /*!< Has one LCD Intel 8080 bus */ -#define SOC_LCD_RGB_PANELS (1U) /*!< Support one RGB LCD panel */ -#define SOC_LCD_I80_BUS_WIDTH (24) /*!< Intel 8080 bus width */ -#define SOC_LCD_RGB_DATA_WIDTH (24) /*!< Number of LCD data lines */ -#define SOC_LCD_SUPPORT_RGB_YUV_CONV (1) /*!< Support color format conversion between RGB and YUV */ +/* I80 bus and RGB timing generator can't work at the same time in the LCD_CAM peripheral */ +#define SOC_LCD_I80_SUPPORTED 1 /*!< support intel 8080 driver */ +#define SOC_LCDCAM_I80_NUM_BUSES 1U /*!< LCD_CAM peripheral provides one LCD Intel 8080 bus */ +#define SOC_LCDCAM_I80_BUS_WIDTH 24 /*!< Intel 8080 bus max data width */ +#define SOC_LCDCAM_RGB_NUM_PANELS 1U /*!< Support one RGB LCD panel */ +// #define SOC_LCD_RGB_DATA_WIDTH 24 /*!< Number of LCD data lines */ +// #define SOC_LCD_SUPPORT_RGB_YUV_CONV 1 /*!< Support color format conversion between RGB and YUV */ /*-------------------------- MCPWM CAPS --------------------------------------*/ #define SOC_MCPWM_GROUPS (2U) ///< 2 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals) @@ -552,6 +553,7 @@ /*--------------------------- WATCHDOG CAPS ---------------------------------------*/ #define SOC_MWDT_SUPPORT_XTAL (1) +#define SOC_MWDT_SUPPORT_SLEEP_RETENTION (1) /*-------------------------- TOUCH SENSOR CAPS -------------------------------*/ #define SOC_TOUCH_SENSOR_VERSION (3) /*!< Hardware version of touch sensor */ diff --git a/components/soc/esp32p4/include/soc/system_periph_retention.h b/components/soc/esp32p4/include/soc/system_periph_retention.h index d7fd022775fa..45041ad49b14 100644 --- a/components/soc/esp32p4/include/soc/system_periph_retention.h +++ b/components/soc/esp32p4/include/soc/system_periph_retention.h @@ -62,18 +62,28 @@ extern const regdma_entries_config_t tg_regs_retention[TIMG_RETENTION_LINK_LEN]; * This is an internal function of the sleep retention driver, and is not * useful for external use. */ -#define IOMUX_RETENTION_LINK_LEN 2 +#define IOMUX_RETENTION_LINK_LEN 3 extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_LEN]; /** - * @brief Provide access to spimem configuration registers retention + * @brief Provide access to FLASH spimem configuration registers retention * context definition. * * This is an internal function of the sleep retention driver, and is not * useful for external use. */ -#define SPIMEM_RETENTION_LINK_LEN 8 -extern const regdma_entries_config_t spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN]; +#define SPIMEM_FLASH_RETENTION_LINK_LEN 8 +extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_FLASH_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to PSRAM spimem configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define SPIMEM_PSRAM_RETENTION_LINK_LEN 14 +extern const regdma_entries_config_t psram_spimem_regs_retention[SPIMEM_PSRAM_RETENTION_LINK_LEN]; /** * @brief Provide access to systimer configuration registers retention diff --git a/components/soc/esp32p4/include/soc/usb_dwc_cfg.h b/components/soc/esp32p4/include/soc/usb_dwc_cfg.h index 7d874e71c82e..3b5b887568fb 100644 --- a/components/soc/esp32p4/include/soc/usb_dwc_cfg.h +++ b/components/soc/esp32p4/include/soc/usb_dwc_cfg.h @@ -17,7 +17,7 @@ Configuration Set ID: 11 /* 3.1 Basic Config Parameters */ #define OTG_MODE 0 #define OTG_ARCHITECTURE 2 -#define OTG_SINGLE_POINT 0 +#define OTG_SINGLE_POINT 1 #define OTG_ENABLE_LPM 0 #define OTG_EN_DED_TX_FIFO 1 #define OTG_EN_DESC_DMA 1 diff --git a/components/soc/esp32p4/include/soc/usb_utmi_struct.h b/components/soc/esp32p4/include/soc/usb_utmi_struct.h index fa2c9f9c92aa..29c8ff745d24 100644 --- a/components/soc/esp32p4/include/soc/usb_utmi_struct.h +++ b/components/soc/esp32p4/include/soc/usb_utmi_struct.h @@ -12,6 +12,11 @@ extern "C" { #endif +/** + * Following register description is taken from + * U2OPHYT40LL USB 2.0 OTG PHY specification v2.0 + */ + typedef union { struct { /** clk_gate_rx : R/W; bitpos: [0]; default 2'b0; @@ -93,38 +98,130 @@ typedef union { * PLL adjustment signal */ uint32_t adj_pll:4; - /** adj_osc : R/W; bitpos: [4]; default: 2'b00 - * PLL adjustment signal + /** adj_osc : R/W; bitpos: [4]; default: 3'b000 + * TX Clock phase adjust signal */ - uint32_t adj_osc:2; - uint32_t reserved_6:26; + uint32_t adj_txclk_phase:3; + uint32_t reserved_7:25; }; uint32_t val; } usb_utmi_fc_03_reg_t; typedef union { struct { - /** reserved_out5 : R/W; bitpos: [0]; default: 8'b0 - * RESERVED_OUT5 + /** test_sel : R/W; bitpos: [0]; default: 8'b0 + * The PHY has test_sel register here, which normally drives DTO (Digital Test Output) signal. + * In our implementation output of this register is left floating and DTO is driven from Probe module. + * Thus writing to this register has no effect and is renamed to 'reserved' */ - uint32_t reserved_out5:8; + uint32_t reserved:8; uint32_t reserved_8:24; }; uint32_t val; } usb_utmi_fc_04_reg_t; +typedef union { + struct { + /** rxgap_fix_en : R/W; bitpos: [0]; default: 1'b1 + * RXGAP fix enable + */ + uint32_t rxgap_fix_en:1; + /** counter_sel : R/W; bitpos: [1]; default: 1'b0 + * SIE_input sample enable + */ + uint32_t counter_sel:1; + /** clk_sel : R/W; bitpos: [2]; default: 1'b0 + * CLK60_30 source select + */ + uint32_t clk_sel:1; + /** phy_mode_sel : R/W; bitpos: [3]; default: 1'b0 + * PHY MODE select + */ + uint32_t phy_mode_sel:1; + /** uni_bidi_i : R/W; bitpos: [4]; default: 1'b0 + * UNI_BIDI signal + */ + uint32_t uni_bidi_i:1; + /** short_5v : R/W; bitpos: [5]; default: 1'b0 + * SHORT_5V signal + */ + uint32_t short_5v:1; + /** short_5v_enable : R/W; bitpos: [6]; default: 1'b1 + * SHORT_5V_ENABLE signal + */ + uint32_t short_5v_enable:1; + /** usable_en : R/W; bitpos: [7]; default: 1'b1 + * compare_begin delay time select + */ + uint32_t usable_en:1; + uint32_t reserved_8:24; + }; + uint32_t val; +} usb_utmi_fc_05_reg_t; + +typedef union { + struct { + /** ls_par_en : R/W; bitpos: [0]; default: 1'b0 + * LS mode with parallel enable + */ + uint32_t ls_par_en:1; + /** det_fseop_en : R/W; bitpos: [1]; default: 1'b0 + * FS EOP detect enable + */ + uint32_t det_fseop_en:1; + /** pre_hphy_lsie : R/W; bitpos: [2]; default: 1'b0 + * Dis_preamble enable + */ + uint32_t pre_hphy_lsie:1; + /** ls_kpalv_en : R/W; bitpos: [3]; default: 1'b0 + * LS mode keep alive enable + */ + uint32_t ls_kpalv_en:1; + /** hs_tx2rx_dly_cnt_sel : R/W; bitpos: [4]; default: 3'b100 + * PHY High-SPeed bus turn-around time select + */ + uint32_t hs_tx2rx_dly_cnt_sel:3; + uint32_t reserved_7:25; + }; + uint32_t val; +} usb_utmi_fc_06_reg_t; + +typedef union { + struct { + /** cnt_num : R/W; bitpos: [1:0]; default: 2'b00 + * 3 ms counter select + * 00: 392us (Default) + * 01: 682us + * 10: 1.36ms + * 11: 2.72ms + */ + uint32_t cnt_num:2; + /** clk480_sel : R/W; bitpos: [2]; default: 1'b0 + * CLK_480 output time select + * 0: CLK_480 is valid after a delay time when PLL is locked + * 1: CLK_480 is valid immediately after PLL is locked + */ + uint32_t clk480_sel:1; + uint32_t reserved_3:29; + }; + uint32_t val; +} usb_utmi_fc_07_reg_t; + typedef struct usb_utmi_dev_t { volatile usb_utmi_fc_00_reg_t fc_00; volatile usb_utmi_fc_01_reg_t fc_01; volatile usb_utmi_fc_02_reg_t fc_02; volatile usb_utmi_fc_03_reg_t fc_03; - usb_utmi_fc_04_reg_t fc_04; + volatile usb_utmi_fc_04_reg_t fc_04; + volatile usb_utmi_fc_05_reg_t fc_05; + volatile usb_utmi_fc_06_reg_t fc_06; + volatile usb_utmi_fc_07_reg_t fc_07; } usb_utmi_dev_t; extern usb_utmi_dev_t USB_UTMI; #ifndef __cplusplus -_Static_assert(sizeof(usb_utmi_dev_t) == 0x14, "Invalid size of usb_utmi_dev_t structure"); +_Static_assert(sizeof(usb_utmi_dev_t) == 0x20, "Invalid size of usb_utmi_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/lcd_periph.c b/components/soc/esp32p4/lcd_periph.c index a45836dc7cdb..feed13869194 100644 --- a/components/soc/esp32p4/lcd_periph.c +++ b/components/soc/esp32p4/lcd_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,8 @@ #include "soc/lcd_periph.h" #include "soc/gpio_sig_map.h" -const lcd_signal_conn_t lcd_periph_signals = { +#if SOC_LCDCAM_I80_LCD_SUPPORTED +const lcd_i80_signal_conn_t lcd_periph_i80_signals = { .buses = { [0] = { .module = PERIPH_LCD_CAM_MODULE, @@ -42,7 +43,12 @@ const lcd_signal_conn_t lcd_periph_signals = { .dc_sig = LCD_DC_PAD_OUT_IDX, .wr_sig = LCD_PCLK_PAD_OUT_IDX } - }, + } +}; +#endif // SOC_LCDCAM_I80_LCD_SUPPORTED + +#if SOC_LCDCAM_RGB_LCD_SUPPORTED +const lcd_rgb_signal_conn_t lcd_periph_rgb_signals = { .panels = { [0] = { .module = PERIPH_LCD_CAM_MODULE, @@ -80,3 +86,4 @@ const lcd_signal_conn_t lcd_periph_signals = { } } }; +#endif // SOC_LCDCAM_RGB_LCD_SUPPORTED diff --git a/components/soc/esp32p4/system_retention_periph.c b/components/soc/esp32p4/system_retention_periph.c index 1cc4a49da4a5..18a2ea302f72 100644 --- a/components/soc/esp32p4/system_retention_periph.c +++ b/components/soc/esp32p4/system_retention_periph.c @@ -7,13 +7,17 @@ #include "soc/cache_reg.h" #include "soc/gpio_reg.h" #include "soc/hp_system_reg.h" +#include "soc/hp_sys_clkrst_reg.h" #include "soc/io_mux_reg.h" +#include "soc/iomux_mspi_pin_reg.h" #include "soc/interrupt_core0_reg.h" #include "soc/interrupt_core1_reg.h" #include "soc/pau_reg.h" #include "soc/regdma.h" #include "soc/system_periph_retention.h" #include "soc/spi_mem_reg.h" +#include "soc/spi_mem_s_reg.h" +#include "soc/spi1_mem_s_reg.h" #include "soc/systimer_reg.h" #include "soc/timer_group_reg.h" #include "soc/timer_periph.h" @@ -44,36 +48,71 @@ _Static_assert(ARRAY_SIZE(hp_system_regs_retention) == HP_SYSTEM_RETENTION_LINK_ /* IO MUX Registers Context */ #define N_REGS_IOMUX_0() (((IO_MUX_GPIO54_REG - REG_IO_MUX_BASE) / 4) + 1) -#define N_REGS_IOMUX_1() (((GPIO_ZERO_DET1_FILTER_CNT_REG - DR_REG_GPIO_BASE) / 4) + 1) +#define N_REGS_GPIO_MTX() (((GPIO_ZERO_DET1_FILTER_CNT_REG - DR_REG_GPIO_BASE) / 4) + 1) +#define N_REGS_MSPI_IOMUX() (((IOMUX_MSPI_PIN_PSRAM_DQS_1_PIN0_REG - IOMUX_MSPI_PIN_CLK_EN0_REG) / 4) + 1) const regdma_entries_config_t iomux_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x00), REG_IO_MUX_BASE, REG_IO_MUX_BASE, N_REGS_IOMUX_0(), 0, 0), .owner = ENTRY(0) }, /* io_mux */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_IOMUX_1(), 0, 0), .owner = ENTRY(0) }, + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x00), REG_IO_MUX_BASE, REG_IO_MUX_BASE, N_REGS_IOMUX_0(), 0, 0), .owner = ENTRY(0) }, /* io_mux */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_GPIO_MTX(), 0, 0), .owner = ENTRY(0) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), IOMUX_MSPI_PIN_CLK_EN0_REG, IOMUX_MSPI_PIN_CLK_EN0_REG, N_REGS_GPIO_MTX(), 0, 0), .owner = ENTRY(0) }, }; _Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "Inconsistent IOMUX retention link length definitions"); /* Memory SPI Registers Context */ -#define N_REGS_SPI1_MEM_0() (((SPI1_MEM_C_SUS_STATUS_REG - DR_REG_FLASH_SPI1_BASE) / 4) + 1) -#define N_REGS_SPI1_MEM_1() (((SPI1_MEM_C_DDR_REG - SPI1_MEM_C_INT_ENA_REG) / 4) + 1) -#define N_REGS_SPI1_MEM_2() (1) -#define N_REGS_SPI1_MEM_3() (1) -#define N_REGS_SPI0_MEM_0() ((SPI_MEM_C_SMEM_DDR_REG - DR_REG_FLASH_SPI0_BASE) / 4 + 1) -#define N_REGS_SPI0_MEM_1() (((SPI_MEM_C_SMEM_AC_REG - SPI_MEM_C_FMEM__PMS0_ATTR_REG) / 4) + 1) -#define N_REGS_SPI0_MEM_2() (1) -#define N_REGS_SPI0_MEM_3() (((SPI_MEM_C_DATE_REG - SPI_MEM_C_MMU_POWER_CTRL_REG) / 4) + 1) -const regdma_entries_config_t spimem_regs_retention[] = { +#define N_REGS_SPI1_C_MEM_0() (((SPI1_MEM_C_SUS_STATUS_REG - DR_REG_FLASH_SPI1_BASE) / 4) + 1) +#define N_REGS_SPI1_C_MEM_1() (((SPI1_MEM_C_DDR_REG - SPI1_MEM_C_INT_ENA_REG) / 4) + 1) +#define N_REGS_SPI1_C_MEM_2() (1) +#define N_REGS_SPI1_C_MEM_3() (1) +#define N_REGS_SPI0_C_MEM_0() ((SPI_MEM_C_SMEM_DDR_REG - DR_REG_FLASH_SPI0_BASE) / 4 + 1) +#define N_REGS_SPI0_C_MEM_1() (((SPI_MEM_C_SMEM_AC_REG - SPI_MEM_C_FMEM__PMS0_ATTR_REG) / 4) + 1) +#define N_REGS_SPI0_C_MEM_2() (1) +#define N_REGS_SPI0_C_MEM_3() (((SPI_MEM_C_DPA_CTRL_REG - SPI_MEM_C_MMU_POWER_CTRL_REG) / 4) + 1) + +const regdma_entries_config_t flash_spimem_regs_retention[] = { /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), DR_REG_FLASH_SPI1_BASE, DR_REG_FLASH_SPI1_BASE, N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi1_mem */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI1_MEM_C_INT_ENA_REG, SPI1_MEM_C_INT_ENA_REG, N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) }, - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI1_MEM_C_TIMING_CALI_REG, SPI1_MEM_C_TIMING_CALI_REG, N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), SPI1_MEM_C_CLOCK_GATE_REG, SPI1_MEM_C_CLOCK_GATE_REG, N_REGS_SPI1_MEM_3(), 0, 0), .owner = ENTRY(0) }, + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), DR_REG_FLASH_SPI1_BASE, DR_REG_FLASH_SPI1_BASE, N_REGS_SPI1_C_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi1_mem */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI1_MEM_C_INT_ENA_REG, SPI1_MEM_C_INT_ENA_REG, N_REGS_SPI1_C_MEM_1(), 0, 0), .owner = ENTRY(0) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI1_MEM_C_TIMING_CALI_REG, SPI1_MEM_C_TIMING_CALI_REG, N_REGS_SPI1_C_MEM_2(), 0, 0), .owner = ENTRY(0) }, /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), DR_REG_FLASH_SPI0_BASE, DR_REG_FLASH_SPI0_BASE, N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi0_mem */ - [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_C_FMEM__PMS0_ATTR_REG, SPI_MEM_C_FMEM__PMS0_ATTR_REG, N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_C_CLOCK_GATE_REG, SPI_MEM_C_CLOCK_GATE_REG, N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) }, - [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_C_MMU_POWER_CTRL_REG, SPI_MEM_C_MMU_POWER_CTRL_REG, N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) } + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), DR_REG_FLASH_SPI0_BASE, DR_REG_FLASH_SPI0_BASE, N_REGS_SPI0_C_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi0_mem */ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_C_FMEM__PMS0_ATTR_REG, SPI_MEM_C_FMEM__PMS0_ATTR_REG, N_REGS_SPI0_C_MEM_1(), 0, 0), .owner = ENTRY(0) }, + [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_C_CLOCK_GATE_REG, SPI_MEM_C_CLOCK_GATE_REG, N_REGS_SPI0_C_MEM_2(), 0, 0), .owner = ENTRY(0) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_C_MMU_POWER_CTRL_REG, SPI_MEM_C_MMU_POWER_CTRL_REG, N_REGS_SPI0_C_MEM_3(), 0, 0), .owner = ENTRY(0) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_SPIMEM_LINK(0x08), SPI_MEM_C_TIMING_CALI_REG, SPI_MEM_C_TIMING_CALI_UPDATE, SPI_MEM_C_TIMING_CALI_UPDATE_M, 1, 0), .owner = ENTRY(0) }, }; -_Static_assert(ARRAY_SIZE(spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions"); +_Static_assert(ARRAY_SIZE(flash_spimem_regs_retention) == SPIMEM_FLASH_RETENTION_LINK_LEN, "Inconsistent Flash SPI Mem retention link length definitions"); + +#if CONFIG_SPIRAM +#define N_REGS_SPI0_S_MEM_0() (((SPI_MEM_S_USER2_REG - SPI_MEM_S_CTRL_REG) / 4) + 1) +#define N_REGS_SPI0_S_MEM_1() (((SPI_MEM_S_FSM_REG - SPI_MEM_S_MISC_REG) / 4) + 1) +#define N_REGS_SPI0_S_MEM_2() (((SPI_MEM_S_SMEM_DDR_REG - SPI_MEM_S_INT_ENA_REG) / 4) + 1) +#define N_REGS_SPI0_S_MEM_3() (((SPI_MEM_S_SMEM_DOUT_HEX_MODE_REG - SPI_MEM_S_ECC_CTRL_REG) / 4) + 1) +#define N_REGS_SPI0_S_MEM_4() (((SPI_MEM_S_DPA_CTRL_REG - SPI_MEM_S_MMU_POWER_CTRL_REG) / 4) + 1) +#define N_REGS_SPI1_S_MEM_0() ((SPI1_MEM_S_CACHE_FCTRL_REG - SPI1_MEM_S_CMD_REG) / 4 + 1) +#define N_REGS_SPI1_S_MEM_1() (((SPI1_MEM_S_SUS_STATUS_REG - SPI1_MEM_S_FLASH_WAITI_CTRL_REG) / 4) + 1) +#define N_REGS_SPI1_S_MEM_2() (((SPI1_MEM_S_DDR_REG - SPI1_MEM_S_INT_ENA_REG) / 4) + 1) +#define N_REGS_SPI1_S_MEM_3() (1) +#define N_REGS_SPI1_S_MEM_4() (1) + +const regdma_entries_config_t psram_spimem_regs_retention[SPIMEM_PSRAM_RETENTION_LINK_LEN] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SPIMEM_LINK(0x08), HP_SYS_CLKRST_PERI_CLK_CTRL00_REG, HP_SYS_CLKRST_REG_PSRAM_CORE_CLK_EN, HP_SYS_CLKRST_REG_PSRAM_CORE_CLK_EN_M, 1, 0), .owner = ENTRY(0) }, // Enable PSRAM mspi core clock on restore + [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SPIMEM_LINK(0x09), HP_SYS_CLKRST_SOC_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_PSRAM_SYS_CLK_EN, HP_SYS_CLKRST_REG_PSRAM_SYS_CLK_EN_M, 1, 0), .owner = ENTRY(0) }, // Enable PSRAM mspi core clock on restore + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0a), SPI_MEM_S_CTRL_REG, SPI_MEM_S_CTRL_REG, N_REGS_SPI0_S_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi0_mem */ + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0b), SPI_MEM_S_MISC_REG, SPI_MEM_S_MISC_REG, N_REGS_SPI0_S_MEM_1(), 0, 0), .owner = ENTRY(0) }, + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0c), SPI_MEM_S_INT_ENA_REG, SPI_MEM_S_INT_ENA_REG, N_REGS_SPI0_S_MEM_2(), 0, 0), .owner = ENTRY(0) }, + [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0d), SPI_MEM_S_ECC_CTRL_REG, SPI_MEM_S_ECC_CTRL_REG, N_REGS_SPI0_S_MEM_3(), 0, 0), .owner = ENTRY(0) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0e), SPI_MEM_S_MMU_POWER_CTRL_REG, SPI_MEM_S_MMU_POWER_CTRL_REG, N_REGS_SPI0_S_MEM_4(), 0, 0), .owner = ENTRY(0) }, + [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x0f), SPI1_MEM_S_CMD_REG, SPI1_MEM_S_CMD_REG, N_REGS_SPI1_S_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi1_mem */ + [8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x10), SPI1_MEM_S_FLASH_WAITI_CTRL_REG, SPI1_MEM_S_FLASH_WAITI_CTRL_REG, N_REGS_SPI1_S_MEM_1(), 0, 0), .owner = ENTRY(0) }, + [9] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x11), SPI1_MEM_S_INT_ENA_REG, SPI1_MEM_S_INT_ENA_REG, N_REGS_SPI1_S_MEM_2(), 0, 0), .owner = ENTRY(0) }, + [10] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x12), SPI1_MEM_S_TIMING_CALI_REG, SPI1_MEM_S_TIMING_CALI_REG, N_REGS_SPI1_S_MEM_3(), 0, 0), .owner = ENTRY(0) }, + [11] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x13), SPI1_MEM_S_CLOCK_GATE_REG, SPI1_MEM_S_CLOCK_GATE_REG, N_REGS_SPI1_S_MEM_4(), 0, 0), .owner = ENTRY(0) }, + [12] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SPIMEM_LINK(0x14), HP_SYS_CLKRST_PERI_CLK_CTRL00_REG, 0, HP_SYS_CLKRST_REG_PSRAM_CORE_CLK_EN_M, 0, 1), .owner = ENTRY(0) }, // Enable PSRAM mspi core clock on backup + [13] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SPIMEM_LINK(0x15), HP_SYS_CLKRST_SOC_CLK_CTRL0_REG, 0, HP_SYS_CLKRST_REG_PSRAM_SYS_CLK_EN_M, 0, 1), .owner = ENTRY(0) }, // Enable PSRAM mspi core clock on backup +}; + +_Static_assert(ARRAY_SIZE(psram_spimem_regs_retention) == SPIMEM_PSRAM_RETENTION_LINK_LEN, "Inconsistent PSRAM SPI Mem retention link length definitions"); +#endif /* Systimer Registers Context */ #define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) diff --git a/components/soc/esp32p4/timer_periph.c b/components/soc/esp32p4/timer_periph.c index b94dacaefb26..88d1f44e1c81 100644 --- a/components/soc/esp32p4/timer_periph.c +++ b/components/soc/esp32p4/timer_periph.c @@ -25,78 +25,160 @@ const timer_group_signal_conn_t timer_group_periph_signals = { } }; -#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG - -static const regdma_entries_config_t tg0_wdt_regs_retention[] = { - /*Timer group backup. should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, -}; - -static const regdma_entries_config_t tg1_wdt_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x04), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, -}; - /* Registers in retention context: * TIMG_T0CONFIG_REG / TIMG_T1CONFIG_REG * TIMG_T0ALARMLO_REG / TIMG_T1ALARMLO_REG * TIMG_T0ALARMHI_REG / TIMG_T1ALARMHI_REG + * TIMG_T0LOADLO_REG / TIMG_T1LOADLO_REG + * TIMG_T0LOADHI_REG / TIMG_T1LOADHI_REG * TIMG_INT_ENA_TIMERS_REG * TIMG_REGCLK_REG */ -#define N_REGS_TG_TIMER_CFG 8 -static const uint32_t tg_timer_regs_map[4] = {0x10006231, 0x80000000, 0x0, 0x0}; +#define TG_TIMER_RETENTION_REGS_CNT 12 +static const uint32_t tg_timer_regs_map[4] = {0x1001e2f1, 0x80000000, 0x0, 0x0}; -const regdma_entries_config_t tg0_timer_regs_retention[] = { +const regdma_entries_config_t tg0_timer_regdma_entries[] = { + // backup stage: trigger a soft capture [0] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), N_REGS_TG_TIMER_CFG, 0, 0, \ - tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2) - }, - [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x02), TIMG_T1UPDATE_REG(0), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x03), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x04), TIMG_T1UPDATE_REG(0), 0x0, TIMG_T1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x05), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x06), TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x07), TIMG_T1LO_REG(0), TIMG_T1LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x08), TIMG_T1HI_REG(0), TIMG_T1LOADHI_REG(0), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x09), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x0a), TIMG_T1LOAD_REG(0), 0x1, TIMG_T1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x00), + TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + [1] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x01), + TIMG_T1UPDATE_REG(0), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + // backup stage: wait for the capture done + [2] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x02), + TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + [3] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG0_TIMER_LINK(0x03), + TIMG_T1UPDATE_REG(0), 0x0, TIMG_T1_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + // backup stage: save the captured counter value + // restore stage: store the captured counter value to the loader register + [4] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x04), + TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), + .owner = ENTRY(0) + }, + [5] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x05), + TIMG_T0HI_REG(0), TIMG_T0LOADHI_REG(0), 2, 0, 0), + .owner = ENTRY(0) + }, + [6] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x06), + TIMG_T1LO_REG(0), TIMG_T1LOADLO_REG(0), 2, 0, 0), + .owner = ENTRY(0) + }, + [7] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_TIMER_LINK(0x07), + TIMG_T1HI_REG(0), TIMG_T1LOADHI_REG(0), 2, 0, 0), + .owner = ENTRY(0) + }, + // restore stage: trigger a soft reload, so the timer can continue from where it was backed up + [8] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x08), + TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), + .owner = ENTRY(0) + }, + [9] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG0_TIMER_LINK(0x09), + TIMG_T1LOAD_REG(0), 0x1, TIMG_T1_LOAD_M, 1, 0), + .owner = ENTRY(0) + }, + // backup stage: save other configuration and status registers + // restore stage: restore the configuration and status registers + [10] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG0_TIMER_LINK(0x0a), + TIMG_T0CONFIG_REG(0), TIMG_T0CONFIG_REG(0), + TG_TIMER_RETENTION_REGS_CNT, 0, 0, + tg_timer_regs_map[0], tg_timer_regs_map[1], + tg_timer_regs_map[2], tg_timer_regs_map[3]), + .owner = ENTRY(0) + }, }; -const regdma_entries_config_t tg1_timer_regs_retention[] = { +const regdma_entries_config_t tg1_timer_regdma_entries[] = { + // backup stage: trigger a soft capture [0] = { - .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x00), TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), N_REGS_TG_TIMER_CFG, 0, 0, \ - tg_timer_regs_map[0], tg_timer_regs_map[1], tg_timer_regs_map[2], tg_timer_regs_map[3]), .owner = ENTRY(0) | ENTRY(2) - }, - [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x02), TIMG_T1UPDATE_REG(1), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [3] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x03), TIMG_T0UPDATE_REG(1), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [4] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x04), TIMG_T1UPDATE_REG(1), 0x0, TIMG_T1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, - [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x05), TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x06), TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x07), TIMG_T1LO_REG(1), TIMG_T1LOADLO_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x08), TIMG_T1HI_REG(1), TIMG_T1LOADHI_REG(1), 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, - [9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x09), TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, - [10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x0a), TIMG_T1LOAD_REG(1), 0x1, TIMG_T1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, -}; - -const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = { - [0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, - [1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x00), + TIMG_T0UPDATE_REG(1), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + [1] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x01), + TIMG_T1UPDATE_REG(1), TIMG_T1_UPDATE, TIMG_T1_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + // backup stage: wait for the capture done + [2] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x02), + TIMG_T0UPDATE_REG(1), 0x0, TIMG_T0_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + [3] = { + .config = REGDMA_LINK_WAIT_INIT(REGDMA_TG1_TIMER_LINK(0x03), + TIMG_T1UPDATE_REG(1), 0x0, TIMG_T1_UPDATE_M, 0, 1), + .owner = ENTRY(0) + }, + // backup stage: save the captured counter value + // restore stage: store the captured counter value to the loader register + [4] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x04), + TIMG_T0LO_REG(1), TIMG_T0LOADLO_REG(1), 2, 0, 0), + .owner = ENTRY(0) + }, + [5] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x05), + TIMG_T0HI_REG(1), TIMG_T0LOADHI_REG(1), 2, 0, 0), + .owner = ENTRY(0) + }, + [6] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x06), + TIMG_T1LO_REG(1), TIMG_T1LOADLO_REG(1), 2, 0, 0), + .owner = ENTRY(0) + }, + [7] = { + .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_TIMER_LINK(0x07), + TIMG_T1HI_REG(1), TIMG_T1LOADHI_REG(1), 2, 0, 0), + .owner = ENTRY(0) + }, + // restore stage: trigger a soft reload, so the timer can continue from where it was backed up + [8] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x08), + TIMG_T0LOAD_REG(1), 0x1, TIMG_T0_LOAD_M, 1, 0), + .owner = ENTRY(0) + }, + [9] = { + .config = REGDMA_LINK_WRITE_INIT(REGDMA_TG1_TIMER_LINK(0x09), + TIMG_T1LOAD_REG(1), 0x1, TIMG_T1_LOAD_M, 1, 0), + .owner = ENTRY(0) + }, + // backup stage: save other configuration and status registers + // restore stage: restore the configuration and status registers + [10] = { + .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_TG1_TIMER_LINK(0x0a), + TIMG_T0CONFIG_REG(1), TIMG_T0CONFIG_REG(1), TG_TIMER_RETENTION_REGS_CNT, 0, 0, + tg_timer_regs_map[0], tg_timer_regs_map[1], + tg_timer_regs_map[2], tg_timer_regs_map[3]), + .owner = ENTRY(0) + }, }; -const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS] = { - [0] = {tg0_timer_regs_retention, ARRAY_SIZE(tg0_timer_regs_retention)}, - [1] = {tg1_timer_regs_retention, ARRAY_SIZE(tg1_timer_regs_retention)}, +const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS] = { + [0] = { + .regdma_entry_array = tg0_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg0_timer_regdma_entries) + }, + [1] = { + .regdma_entry_array = tg1_timer_regdma_entries, + .array_size = ARRAY_SIZE(tg1_timer_regdma_entries) + }, }; diff --git a/components/soc/esp32p4/wdt_periph.c b/components/soc/esp32p4/wdt_periph.c new file mode 100644 index 000000000000..1660f25c4a6e --- /dev/null +++ b/components/soc/esp32p4/wdt_periph.c @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/wdt_periph.h" + + +#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG + +static const regdma_entries_config_t tg0_wdt_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x01), TIMG_WDTCONFIG0_REG(0), TIMG_WDTCONFIG0_REG(0), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x02), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x03), TIMG_WDTFEED_REG(0), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG0_WDT_LINK(0x04), TIMG_INT_ENA_TIMERS_REG(0),TIMG_INT_ENA_TIMERS_REG(0), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x05), TIMG_WDTWPROTECT_REG(0), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +static const regdma_entries_config_t tg1_wdt_regs_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x00), TIMG_WDTWPROTECT_REG(1), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x01), TIMG_INT_ENA_TIMERS_REG(1),TIMG_INT_ENA_TIMERS_REG(1), 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TG1_WDT_LINK(0x02), TIMG_WDTCONFIG0_REG(1), TIMG_WDTCONFIG0_REG(1), N_REGS_TGWDT, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x03), TIMG_WDTCONFIG0_REG(1), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG0_WDT_LINK(0x04), TIMG_WDTFEED_REG(1), TIMG_WDT_FEED, TIMG_WDT_FEED_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, + [5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TG1_WDT_LINK(0x05), TIMG_WDTWPROTECT_REG(1), 0, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, +}; + +const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS] = { + [0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)}, + [1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)}, +}; diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 7a448c29ae09..fd0d99840eef 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -483,6 +483,10 @@ config SOC_I2S_SUPPORTS_LCD_CAMERA bool default y +config SOC_I2S_MAX_DATA_WIDTH + int + default 24 + config SOC_I2S_APLL_MIN_FREQ int default 250000000 diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index e611f9ad5dbe..e18f5ee24587 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -214,6 +214,7 @@ #define SOC_I2S_SUPPORTS_PLL_F160M (1) #define SOC_I2S_SUPPORTS_DMA_EQUAL (1) #define SOC_I2S_SUPPORTS_LCD_CAMERA (1) +#define SOC_I2S_MAX_DATA_WIDTH (24) #define SOC_I2S_APLL_MIN_FREQ (250000000) #define SOC_I2S_APLL_MAX_FREQ (500000000) #define SOC_I2S_APLL_MIN_RATE (10675) //in Hz, I2S Clock rate limited by hardware diff --git a/components/soc/esp32s2/lcd_periph.c b/components/soc/esp32s2/lcd_periph.c index af1d3b8bba93..b42bf9d426b9 100644 --- a/components/soc/esp32s2/lcd_periph.c +++ b/components/soc/esp32s2/lcd_periph.c @@ -7,7 +7,7 @@ #include "soc/lcd_periph.h" #include "soc/gpio_sig_map.h" -const lcd_signal_conn_t lcd_periph_signals = { +const lcd_i2s_signal_conn_t lcd_periph_i2s_signals = { .buses = { [0] = { .module = PERIPH_I2S0_MODULE, diff --git a/components/soc/esp32s2/wdt_periph.c b/components/soc/esp32s2/wdt_periph.c new file mode 100644 index 000000000000..58f1349d3d24 --- /dev/null +++ b/components/soc/esp32s2/wdt_periph.c @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/wdt_periph.h" diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index 843e27b80337..8a0becf86e98 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -63,6 +63,14 @@ config SOC_LCDCAM_SUPPORTED bool default y +config SOC_LCDCAM_I80_LCD_SUPPORTED + bool + default y + +config SOC_LCDCAM_RGB_LCD_SUPPORTED + bool + default y + config SOC_MCPWM_SUPPORTED bool default y @@ -763,6 +771,22 @@ config SOC_LCD_SUPPORT_RGB_YUV_CONV bool default y +config SOC_LCDCAM_I80_NUM_BUSES + int + default 1 + +config SOC_LCDCAM_I80_BUS_WIDTH + int + default 16 + +config SOC_LCDCAM_RGB_NUM_PANELS + int + default 1 + +config SOC_LCDCAM_RGB_DATA_WIDTH + int + default 16 + config SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH int default 128 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 90545f5d852f..68e346281e33 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -32,6 +32,8 @@ #define SOC_AHB_GDMA_SUPPORTED 1 #define SOC_GPTIMER_SUPPORTED 1 #define SOC_LCDCAM_SUPPORTED 1 +#define SOC_LCDCAM_I80_LCD_SUPPORTED 1 +#define SOC_LCDCAM_RGB_LCD_SUPPORTED 1 #define SOC_MCPWM_SUPPORTED 1 #define SOC_DEDICATED_GPIO_SUPPORTED 1 #define SOC_CACHE_SUPPORT_WRAP 1 @@ -288,6 +290,10 @@ #define SOC_LCD_I80_BUS_WIDTH (16) /*!< Intel 8080 bus width */ #define SOC_LCD_RGB_DATA_WIDTH (16) /*!< Number of LCD data lines */ #define SOC_LCD_SUPPORT_RGB_YUV_CONV (1) /*!< Support color format conversion between RGB and YUV */ +#define SOC_LCDCAM_I80_NUM_BUSES (1U) /*!< LCD_CAM peripheral provides one LCD Intel 8080 bus */ +#define SOC_LCDCAM_I80_BUS_WIDTH (16) /*!< Intel 8080 bus max data width */ +#define SOC_LCDCAM_RGB_NUM_PANELS (1U) /*!< LCD_CAM peripheral provides one RGB panel */ +#define SOC_LCDCAM_RGB_DATA_WIDTH (16) /*!< RGB panel max data width */ /*-------------------------- RTC CAPS --------------------------------------*/ #define SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH (128) diff --git a/components/soc/esp32s3/lcd_periph.c b/components/soc/esp32s3/lcd_periph.c index 3d60c5da9ee6..eac2deedd239 100644 --- a/components/soc/esp32s3/lcd_periph.c +++ b/components/soc/esp32s3/lcd_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,7 @@ #include "soc/lcd_periph.h" #include "soc/gpio_sig_map.h" -const lcd_signal_conn_t lcd_periph_signals = { +const lcd_i80_signal_conn_t lcd_periph_i80_signals = { .buses = { [0] = { .module = PERIPH_LCD_CAM_MODULE, @@ -34,7 +34,10 @@ const lcd_signal_conn_t lcd_periph_signals = { .dc_sig = LCD_DC_IDX, .wr_sig = LCD_PCLK_IDX } - }, + } +}; + +const lcd_rgb_signal_conn_t lcd_periph_rgb_signals = { .panels = { [0] = { .module = PERIPH_LCD_CAM_MODULE, diff --git a/components/soc/esp32s3/wdt_periph.c b/components/soc/esp32s3/wdt_periph.c new file mode 100644 index 000000000000..58f1349d3d24 --- /dev/null +++ b/components/soc/esp32s3/wdt_periph.c @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/wdt_periph.h" diff --git a/components/soc/include/soc/lcd_periph.h b/components/soc/include/soc/lcd_periph.h index 801e5ffb7460..4f0caaf0eb37 100644 --- a/components/soc/include/soc/lcd_periph.h +++ b/components/soc/include/soc/lcd_periph.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,42 +13,49 @@ extern "C" { #endif -#if SOC_LCDCAM_SUPPORTED +#if SOC_LCDCAM_I80_LCD_SUPPORTED typedef struct { struct { const periph_module_t module; const int irq_id; - const int data_sigs[SOC_LCD_I80_BUS_WIDTH]; + const int data_sigs[SOC_LCDCAM_I80_BUS_WIDTH]; const int cs_sig; const int dc_sig; const int wr_sig; - } buses[SOC_LCD_I80_BUSES]; + } buses[SOC_LCDCAM_I80_NUM_BUSES]; +} lcd_i80_signal_conn_t; + +extern const lcd_i80_signal_conn_t lcd_periph_i80_signals; +#endif // SOC_LCDCAM_I80_LCD_SUPPORTED + +#if SOC_LCDCAM_RGB_LCD_SUPPORTED +typedef struct { struct { const periph_module_t module; const int irq_id; - const int data_sigs[SOC_LCD_RGB_DATA_WIDTH]; + const int data_sigs[SOC_LCDCAM_RGB_DATA_WIDTH]; const int hsync_sig; const int vsync_sig; const int pclk_sig; const int de_sig; - } panels[SOC_LCD_RGB_PANELS]; -} lcd_signal_conn_t; + } panels[SOC_LCDCAM_RGB_NUM_PANELS]; +} lcd_rgb_signal_conn_t; -extern const lcd_signal_conn_t lcd_periph_signals; -#endif // SOC_LCDCAM_SUPPORTED +extern const lcd_rgb_signal_conn_t lcd_periph_rgb_signals; +#endif // SOC_LCDCAM_RGB_LCD_SUPPORTED -#if SOC_I2S_LCD_I80_VARIANT +#if SOC_I2S_SUPPORTS_LCD_CAMERA typedef struct { struct { const periph_module_t module; const int irq_id; - const int data_sigs[SOC_LCD_I80_BUS_WIDTH]; + const int data_sigs[SOC_I2S_MAX_DATA_WIDTH]; const int wr_sig; } buses[SOC_LCD_I80_BUSES]; -} lcd_signal_conn_t; +} lcd_i2s_signal_conn_t; -extern const lcd_signal_conn_t lcd_periph_signals; -#endif // SOC_I2S_LCD_I80_VARIANT +extern const lcd_i2s_signal_conn_t lcd_periph_i2s_signals; +#endif // SOC_I2S_SUPPORTS_LCD_CAMERA #ifdef __cplusplus } diff --git a/components/soc/include/soc/timer_periph.h b/components/soc/include/soc/timer_periph.h index 1d7cd219b3c3..b1ab0f757122 100644 --- a/components/soc/include/soc/timer_periph.h +++ b/components/soc/include/soc/timer_periph.h @@ -17,9 +17,6 @@ extern "C" { #endif -/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ -#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 - typedef struct { struct { const periph_module_t module; // Peripheral module @@ -31,13 +28,12 @@ extern const timer_group_signal_conn_t timer_group_periph_signals; #if SOC_TIMER_SUPPORT_SLEEP_RETENTION && SOC_PAU_SUPPORTED typedef struct { - const regdma_entries_config_t *link_list; - uint32_t link_num; -} tg_reg_ctx_link_t; + const regdma_entries_config_t *regdma_entry_array; + uint32_t array_size; +} tg_timer_reg_retention_info_t; -extern const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS]; -extern const tg_reg_ctx_link_t tg_timer_regs_retention[SOC_TIMER_GROUPS]; -#endif +extern const tg_timer_reg_retention_info_t tg_timer_reg_retention_info[SOC_TIMER_GROUPS]; +#endif // SOC_TIMER_SUPPORT_SLEEP_RETENTION #ifdef __cplusplus } diff --git a/components/soc/include/soc/wdt_periph.h b/components/soc/include/soc/wdt_periph.h new file mode 100644 index 000000000000..b2f1133f2b1d --- /dev/null +++ b/components/soc/include/soc/wdt_periph.h @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/timer_group_reg.h" +#include "soc/timer_group_struct.h" +#include "soc/soc_caps.h" +#include "soc/periph_defs.h" +#include "soc/regdma.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */ +#define TIMG_WDT_WKEY_VALUE 0x50D83AA1 + +#if SOC_MWDT_SUPPORT_SLEEP_RETENTION +typedef struct { + const regdma_entries_config_t *link_list; + uint32_t link_num; +} tg_reg_ctx_link_t; + +extern const tg_reg_ctx_link_t tg_wdt_regs_retention[SOC_TIMER_GROUPS]; +#endif // SOC_MWDT_SUPPORT_SLEEP_RETENTION + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index f4cb5c18fda6..153a2c3670df 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -371,12 +371,19 @@ void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid) void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state) { +#if SOC_BRANCH_PREDICTOR_SUPPORTED + //branch predictor will start cache request as well + esp_cpu_branch_prediction_disable(); +#endif cache_hal_suspend(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state) { cache_hal_resume(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); +#if SOC_BRANCH_PREDICTOR_SUPPORTED + esp_cpu_branch_prediction_enable(); +#endif } bool IRAM_ATTR spi_flash_cache_enabled(void) diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index fdff3c944cea..81a7bb573dda 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -432,15 +432,18 @@ esp_err_t esp_flash_app_init(void) // Acquire the LDO channel used by the SPI NOR flash // in case the LDO voltage is changed by other users -#if defined(CONFIG_ESP_LDO_CHAN_SPI_NOR_FLASH_DOMAIN) && CONFIG_ESP_LDO_CHAN_SPI_NOR_FLASH_DOMAIN != -1 +#if CONFIG_ESP_LDO_RESERVE_SPI_NOR_FLASH static esp_ldo_channel_handle_t s_ldo_chan = NULL; esp_ldo_channel_config_t ldo_config = { .chan_id = CONFIG_ESP_LDO_CHAN_SPI_NOR_FLASH_DOMAIN, .voltage_mv = CONFIG_ESP_LDO_VOLTAGE_SPI_NOR_FLASH_DOMAIN, + .flags = { + .owned_by_hw = true, // LDO output is totally controlled by hardware + }, }; err = esp_ldo_acquire_channel(&ldo_config, &s_ldo_chan); if (err != ESP_OK) return err; -#endif +#endif // CONFIG_ESP_LDO_RESERVE_SPI_NOR_FLASH spi_flash_init_lock(); spi_flash_guard_set(&g_flash_guard_default_ops); diff --git a/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h b/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h index 27a080581df4..3095adafde1d 100644 --- a/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h +++ b/components/ulp/lp_core/lp_core/include/ulp_lp_core_print.h @@ -5,6 +5,10 @@ */ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + #include "sdkconfig.h" /** @@ -44,3 +48,7 @@ extern void ets_install_uart_printf(void); * @param c character to be printed */ void lp_core_print_char(char c); + +#ifdef __cplusplus +} +#endif diff --git a/components/usb/hcd_dwc.c b/components/usb/hcd_dwc.c index f8ab81965dbb..0b4583dd3015 100644 --- a/components/usb/hcd_dwc.c +++ b/components/usb/hcd_dwc.c @@ -11,7 +11,6 @@ #include "freertos/task.h" #include "freertos/semphr.h" #include "esp_heap_caps.h" -#include "esp_dma_utils.h" #include "esp_intr_alloc.h" #include "soc/interrupts.h" // For interrupt index #include "esp_err.h" @@ -25,7 +24,6 @@ #include "soc/soc_caps.h" #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE #include "esp_cache.h" -#include "esp_private/esp_cache_private.h" #endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE // ----------------------------------------------------- Macros -------------------------------------------------------- @@ -325,35 +323,6 @@ static inline void cache_sync_data_buffer(pipe_t *pipe, urb_t *urb, bool done) } #endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE -// --------------------- Allocation ------------------------ - -/** - * @brief Allocate Frame List - * - * - Frame list is allocated in DMA capable memory - * - Frame list is aligned to 512 and cache line size - * - * @note Free the memory with heap_caps_free() call - * - * @param[in] frame_list_len Length of the Frame List - * @return Pointer to allocated frame list - */ -static void *frame_list_alloc(size_t frame_list_len); - -/** - * @brief Allocate Transfer Descriptor List - * - * - Frame list is allocated in DMA capable memory - * - Frame list is aligned to 512 and cache line size - * - * @note Free the memory with heap_caps_free() call - * - * @param[in] list_len Required length - * @param[out] list_len_bytes_out Allocated length in bytes (can be greater than required) - * @return Pointer to allocated transfer descriptor list - */ -static void *transfer_descriptor_list_alloc(size_t list_len, size_t *list_len_bytes_out); - // ------------------- Buffer Control ---------------------- /** @@ -987,7 +956,7 @@ static port_t *port_obj_alloc(void) { port_t *port = calloc(1, sizeof(port_t)); usb_dwc_hal_context_t *hal = malloc(sizeof(usb_dwc_hal_context_t)); - void *frame_list = frame_list_alloc(FRAME_LIST_LEN); + void *frame_list = heap_caps_aligned_calloc(USB_DWC_FRAME_LIST_MEM_ALIGN, FRAME_LIST_LEN, sizeof(uint32_t), MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED | MALLOC_CAP_INTERNAL); SemaphoreHandle_t port_mux = xSemaphoreCreateMutex(); if (port == NULL || hal == NULL || frame_list == NULL || port_mux == NULL) { free(port); @@ -1015,59 +984,6 @@ static void port_obj_free(port_t *port) free(port); } -void *frame_list_alloc(size_t frame_list_len) -{ - esp_err_t ret; - void *frame_list = NULL; - size_t actual_size = 0; - esp_dma_mem_info_t dma_mem_info = { - .dma_alignment_bytes = USB_DWC_FRAME_LIST_MEM_ALIGN, - }; - ret = esp_dma_capable_calloc(frame_list_len, sizeof(uint32_t), &dma_mem_info, &frame_list, &actual_size); - assert(ret == ESP_OK); - - // Both Frame List start address and size should be already cache aligned so this is only a sanity check - if (frame_list) { - if (!esp_dma_is_buffer_alignment_satisfied(frame_list, actual_size, dma_mem_info)) { - // This should never happen - heap_caps_free(frame_list); - frame_list = NULL; - } - } - return frame_list; -} - -void *transfer_descriptor_list_alloc(size_t list_len, size_t *list_len_bytes_out) -{ -#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - // Required Transfer Descriptor List size (in bytes) might not be aligned to cache line size, align the size up - size_t data_cache_line_size = 0; - esp_cache_get_alignment(MALLOC_CAP_DMA, &data_cache_line_size); - const size_t required_list_len_bytes = list_len * sizeof(usb_dwc_ll_dma_qtd_t); - *list_len_bytes_out = ALIGN_UP_BY(required_list_len_bytes, data_cache_line_size); -#else - *list_len_bytes_out = list_len * sizeof(usb_dwc_ll_dma_qtd_t); -#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - - esp_err_t ret; - void *qtd_list = NULL; - size_t actual_size = 0; - esp_dma_mem_info_t dma_mem_info = { - .dma_alignment_bytes = USB_DWC_QTD_LIST_MEM_ALIGN, - }; - ret = esp_dma_capable_calloc(*list_len_bytes_out, 1, &dma_mem_info, &qtd_list, &actual_size); - assert(ret == ESP_OK); - - if (qtd_list) { - if (!esp_dma_is_buffer_alignment_satisfied(qtd_list, actual_size, dma_mem_info)) { - // This should never happen - heap_caps_free(qtd_list); - qtd_list = NULL; - } - } - return qtd_list; -} - // ----------------------- Public -------------------------- esp_err_t hcd_install(const hcd_config_t *config) @@ -1593,16 +1509,24 @@ static dma_buffer_block_t *buffer_block_alloc(usb_transfer_type_t type) desc_list_len = XFER_LIST_LEN_INTR; break; } + + // DMA buffer lock: Software structure for managing the transfer buffer dma_buffer_block_t *buffer = calloc(1, sizeof(dma_buffer_block_t)); - size_t real_len = 0; - void *xfer_desc_list = transfer_descriptor_list_alloc(desc_list_len, &real_len); - if (buffer == NULL || xfer_desc_list == NULL) { + if (buffer == NULL) { + return NULL; + } + + // Transfer descriptor list: Must be 512 aligned and DMA capable (USB-DWC requirement) and its size must be cache aligned + void *xfer_desc_list = heap_caps_aligned_calloc(USB_DWC_QTD_LIST_MEM_ALIGN, desc_list_len * sizeof(usb_dwc_ll_dma_qtd_t), 1, MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED | MALLOC_CAP_INTERNAL); + if (xfer_desc_list == NULL) { free(buffer); heap_caps_free(xfer_desc_list); return NULL; } buffer->xfer_desc_list = xfer_desc_list; - buffer->xfer_desc_list_len_bytes = real_len; + // For targets with L1CACHE, the allocated size might be bigger than requested, this value is than used during memory sync + // We save this value here, so we don't have to call 'heap_caps_get_allocated_size()' during every memory sync + buffer->xfer_desc_list_len_bytes = heap_caps_get_allocated_size(xfer_desc_list); return buffer; } diff --git a/components/usb/test_apps/hcd/main/test_hcd_common.c b/components/usb/test_apps/hcd/main/test_hcd_common.c index 293f6ca21fbf..0b4c3cd35220 100644 --- a/components/usb/test_apps/hcd/main/test_hcd_common.c +++ b/components/usb/test_apps/hcd/main/test_hcd_common.c @@ -21,7 +21,6 @@ #include "test_usb_common.h" #include "mock_msc.h" #include "unity.h" -#include "esp_dma_utils.h" #define PORT_NUM 1 #define EVENT_QUEUE_LEN 5 @@ -264,19 +263,14 @@ urb_t *test_hcd_alloc_urb(int num_isoc_packets, size_t data_buffer_size) { // Allocate a URB and data buffer urb_t *urb = heap_caps_calloc(1, sizeof(urb_t) + (sizeof(usb_isoc_packet_desc_t) * num_isoc_packets), MALLOC_CAP_DEFAULT); - void *data_buffer; - size_t real_size; - esp_dma_mem_info_t dma_mem_info = { - .dma_alignment_bytes = 4, - }; - esp_dma_capable_malloc(data_buffer_size, &dma_mem_info, &data_buffer, &real_size); + void *data_buffer = heap_caps_malloc(data_buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED); TEST_ASSERT_NOT_NULL_MESSAGE(urb, "Failed to allocate URB"); TEST_ASSERT_NOT_NULL_MESSAGE(data_buffer, "Failed to allocate transfer buffer"); // Initialize URB and underlying transfer structure. Need to cast to dummy due to const fields usb_transfer_dummy_t *transfer_dummy = (usb_transfer_dummy_t *)&urb->transfer; transfer_dummy->data_buffer = data_buffer; - transfer_dummy->data_buffer_size = real_size; + transfer_dummy->data_buffer_size = heap_caps_get_allocated_size(data_buffer); transfer_dummy->num_isoc_packets = num_isoc_packets; return urb; } diff --git a/components/usb/usb_phy_p4.c b/components/usb/usb_phy_p4.c index a541fafe4c45..8365cded17d1 100644 --- a/components/usb/usb_phy_p4.c +++ b/components/usb/usb_phy_p4.c @@ -4,13 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -// This is only a dummy USB PHY file for successful linking of ESP32-P4 target -// The internal HS PHY is enabled by default, therefore it needs no configuration - // TODO: Refactor during the IDF-9198 #include "sdkconfig.h" #include "soc/usb_dwc_cfg.h" -#include "hal/usb_wrap_hal.h" +#include "hal/usb_utmi_ll.h" // We don't have usb_utmi_hal yet +#include "esp_private/periph_ctrl.h" // TODO: Remove this file when proper support of P4 PHYs is implemented IDF-7323 #include "esp_private/usb_phy.h" @@ -18,13 +16,18 @@ esp_err_t usb_new_phy(const usb_phy_config_t *config, usb_phy_handle_t *handle_r { #if (OTG_HSPHY_INTERFACE != 0) #if CONFIG_IDF_TARGET_ESP32P4 + PERIPH_RCC_ATOMIC() { + usb_utmi_ll_enable_bus_clock(true); + usb_utmi_ll_reset_register(); + } /* Additional setting to solve missing DCONN event on ESP32P4 (IDF-9953). Note: On ESP32P4, the HP_SYSTEM_OTG_SUSPENDM is not connected to 1 by hardware. For correct detection of the device detaching, internal signal should be set to 1 by the software. */ - usb_wrap_ll_enable_precise_detection(); + usb_utmi_ll_enable_precise_detection(true); + usb_utmi_ll_configure_ls(&USB_UTMI, true); #endif // CONFIG_IDF_TARGET_ESP32P4 #endif // (OTG_HSPHY_INTERFACE != 0) return ESP_OK; diff --git a/components/usb/usb_private.c b/components/usb/usb_private.c index e5ab2d3da806..56d6b3d719dc 100644 --- a/components/usb/usb_private.c +++ b/components/usb/usb_private.c @@ -5,27 +5,20 @@ */ #include "esp_heap_caps.h" -#include "esp_dma_utils.h" #include "usb_private.h" #include "usb/usb_types_ch9.h" urb_t *urb_alloc(size_t data_buffer_size, int num_isoc_packets) { urb_t *urb = heap_caps_calloc(1, sizeof(urb_t) + (sizeof(usb_isoc_packet_desc_t) * num_isoc_packets), MALLOC_CAP_DEFAULT); - void *data_buffer; - size_t real_size; - esp_dma_mem_info_t dma_mem_info = { - .dma_alignment_bytes = 4, - }; - //TODO: IDF-9639 - esp_dma_capable_malloc(data_buffer_size, &dma_mem_info, &data_buffer, &real_size); + void *data_buffer = heap_caps_malloc(data_buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_CACHE_ALIGNED); if (urb == NULL || data_buffer == NULL) { goto err; } // Cast as dummy transfer so that we can assign to const fields usb_transfer_dummy_t *dummy_transfer = (usb_transfer_dummy_t *)&urb->transfer; dummy_transfer->data_buffer = data_buffer; - dummy_transfer->data_buffer_size = real_size; + dummy_transfer->data_buffer_size = heap_caps_get_allocated_size(data_buffer); dummy_transfer->num_isoc_packets = num_isoc_packets; return urb; err: diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c index 7972a6c93f5d..58d562cdb17a 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -180,14 +180,14 @@ bool wpa_ap_rx_eapol(void *hapd_data, void *sm_data, u8 *data, size_t data_len) void wpa_ap_get_peer_spp_msg(void *sm_data, bool *spp_cap, bool *spp_req) { - struct wpa_state_machine *sm = (struct wpa_state_machine *)sm_data; + struct sta_info *sta = sm_data; - if (!sm) { + if (!sta || !sta->wpa_sm) { return; } - *spp_cap = sm->spp_sup.capable; - *spp_req = sm->spp_sup.require; + *spp_cap = sta->wpa_sm->spp_sup.capable; + *spp_req = sta->wpa_sm->spp_sup.require; } bool wpa_deattach(void) diff --git a/docs/_static/ble/feature_status/NA.svg b/docs/_static/ble/feature_status/NA.svg new file mode 100644 index 000000000000..6e4cebfee6ed --- /dev/null +++ b/docs/_static/ble/feature_status/NA.svg @@ -0,0 +1 @@ +N/AN/A diff --git a/docs/_static/ble/feature_status/developing202412.svg b/docs/_static/ble/feature_status/developing202412.svg new file mode 100644 index 000000000000..f980684dca53 --- /dev/null +++ b/docs/_static/ble/feature_status/developing202412.svg @@ -0,0 +1 @@ +In Progress: 2024/12In Progress2024/12 diff --git a/docs/_static/ble/feature_status/developingYYYYMM.svg b/docs/_static/ble/feature_status/developingYYYYMM.svg new file mode 100644 index 000000000000..e798218d713f --- /dev/null +++ b/docs/_static/ble/feature_status/developingYYYYMM.svg @@ -0,0 +1 @@ +In Progress: YYYY/MMIn ProgressYYYY/MM diff --git a/docs/_static/ble/feature_status/experimental.svg b/docs/_static/ble/feature_status/experimental.svg new file mode 100644 index 000000000000..19c27d03c7cb --- /dev/null +++ b/docs/_static/ble/feature_status/experimental.svg @@ -0,0 +1 @@ +experimentalexperimental diff --git a/docs/_static/ble/feature_status/supported.svg b/docs/_static/ble/feature_status/supported.svg new file mode 100644 index 000000000000..775eb979e925 --- /dev/null +++ b/docs/_static/ble/feature_status/supported.svg @@ -0,0 +1 @@ +supportedsupported diff --git a/docs/_static/ble/feature_status/unsupported.svg b/docs/_static/ble/feature_status/unsupported.svg new file mode 100644 index 000000000000..298cdc53e495 --- /dev/null +++ b/docs/_static/ble/feature_status/unsupported.svg @@ -0,0 +1 @@ +unsupportedunsupported diff --git a/docs/_static/classic-bluetooth-architecture.png b/docs/_static/classic-bluetooth-architecture.png new file mode 100644 index 000000000000..671f04729a1b Binary files /dev/null and b/docs/_static/classic-bluetooth-architecture.png differ diff --git a/docs/_static/esp-wrover-kit-block-diagram.png b/docs/_static/esp-wrover-kit-block-diagram.png deleted file mode 100644 index 65adba51b7be..000000000000 Binary files a/docs/_static/esp-wrover-kit-block-diagram.png and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v2-layout-back.png b/docs/_static/esp-wrover-kit-v2-layout-back.png deleted file mode 100644 index 84dab7a462dc..000000000000 Binary files a/docs/_static/esp-wrover-kit-v2-layout-back.png and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v2-layout-front.png b/docs/_static/esp-wrover-kit-v2-layout-front.png deleted file mode 100644 index d7806ad14517..000000000000 Binary files a/docs/_static/esp-wrover-kit-v2-layout-front.png and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v3-jp11-tx-rx.png b/docs/_static/esp-wrover-kit-v3-jp11-tx-rx.png deleted file mode 100644 index 4411642e4bf4..000000000000 Binary files a/docs/_static/esp-wrover-kit-v3-jp11-tx-rx.png and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v3-jp14.png b/docs/_static/esp-wrover-kit-v3-jp14.png deleted file mode 100644 index 921e298b5d23..000000000000 Binary files a/docs/_static/esp-wrover-kit-v3-jp14.png and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v3-jp7-ext_5v.png b/docs/_static/esp-wrover-kit-v3-jp7-ext_5v.png deleted file mode 100644 index c21f12b6c843..000000000000 Binary files a/docs/_static/esp-wrover-kit-v3-jp7-ext_5v.png and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v3-jp7-usb_5v.png b/docs/_static/esp-wrover-kit-v3-jp7-usb_5v.png deleted file mode 100644 index 579870c73d32..000000000000 Binary files a/docs/_static/esp-wrover-kit-v3-jp7-usb_5v.png and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v3-jp8.png b/docs/_static/esp-wrover-kit-v3-jp8.png deleted file mode 100644 index 3465f79ac37a..000000000000 Binary files a/docs/_static/esp-wrover-kit-v3-jp8.png and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v3-layout-back.jpg b/docs/_static/esp-wrover-kit-v3-layout-back.jpg deleted file mode 100644 index 12eda4b01dea..000000000000 Binary files a/docs/_static/esp-wrover-kit-v3-layout-back.jpg and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v3-layout-front.jpg b/docs/_static/esp-wrover-kit-v3-layout-front.jpg deleted file mode 100644 index b67a8ad3deec..000000000000 Binary files a/docs/_static/esp-wrover-kit-v3-layout-front.jpg and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v4.1-jp14.jpg b/docs/_static/esp-wrover-kit-v4.1-jp14.jpg deleted file mode 100644 index 3c68369b27e5..000000000000 Binary files a/docs/_static/esp-wrover-kit-v4.1-jp14.jpg and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v4.1-jp2-jtag.jpg b/docs/_static/esp-wrover-kit-v4.1-jp2-jtag.jpg deleted file mode 100644 index cfc6cc0eb3bb..000000000000 Binary files a/docs/_static/esp-wrover-kit-v4.1-jp2-jtag.jpg and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v4.1-jp2-tx-rx.jpg b/docs/_static/esp-wrover-kit-v4.1-jp2-tx-rx.jpg deleted file mode 100644 index 2910ba6f0d83..000000000000 Binary files a/docs/_static/esp-wrover-kit-v4.1-jp2-tx-rx.jpg and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v4.1-jp7-ext_5v.jpg b/docs/_static/esp-wrover-kit-v4.1-jp7-ext_5v.jpg deleted file mode 100644 index 410912048532..000000000000 Binary files a/docs/_static/esp-wrover-kit-v4.1-jp7-ext_5v.jpg and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v4.1-jp7-usb_5v.jpg b/docs/_static/esp-wrover-kit-v4.1-jp7-usb_5v.jpg deleted file mode 100644 index 050f5a96f5ef..000000000000 Binary files a/docs/_static/esp-wrover-kit-v4.1-jp7-usb_5v.jpg and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v4.1-layout-back.png b/docs/_static/esp-wrover-kit-v4.1-layout-back.png deleted file mode 100644 index 6d05551a0ab6..000000000000 Binary files a/docs/_static/esp-wrover-kit-v4.1-layout-back.png and /dev/null differ diff --git a/docs/_static/esp-wrover-kit-v4.1-layout-front.png b/docs/_static/esp-wrover-kit-v4.1-layout-front.png deleted file mode 100644 index 608809bf71fc..000000000000 Binary files a/docs/_static/esp-wrover-kit-v4.1-layout-front.png and /dev/null differ diff --git a/docs/_static/esp32-devkitc-c15-location.png b/docs/_static/esp32-devkitc-c15-location.png deleted file mode 100644 index 1b3b84441581..000000000000 Binary files a/docs/_static/esp32-devkitc-c15-location.png and /dev/null differ diff --git a/docs/_static/esp32-devkitc-dimensions-back.jpg b/docs/_static/esp32-devkitc-dimensions-back.jpg deleted file mode 100644 index 47cdfce82ebd..000000000000 Binary files a/docs/_static/esp32-devkitc-dimensions-back.jpg and /dev/null differ diff --git a/docs/_static/esp32-devkitc-functional-overview-f.jpeg b/docs/_static/esp32-devkitc-functional-overview-f.jpeg deleted file mode 100644 index 0a2220bfe9df..000000000000 Binary files a/docs/_static/esp32-devkitc-functional-overview-f.jpeg and /dev/null differ diff --git a/docs/_static/esp32-devkitc-functional-overview.jpg b/docs/_static/esp32-devkitc-functional-overview.jpg deleted file mode 100644 index bdd89bc4006a..000000000000 Binary files a/docs/_static/esp32-devkitc-functional-overview.jpg and /dev/null differ diff --git a/docs/_static/esp32-devkitc-v2-functional-overview.png b/docs/_static/esp32-devkitc-v2-functional-overview.png deleted file mode 100644 index 73ce5820cbf1..000000000000 Binary files a/docs/_static/esp32-devkitc-v2-functional-overview.png and /dev/null differ diff --git a/docs/_static/esp32-devkitc-v4-dimensions-back.jpeg b/docs/_static/esp32-devkitc-v4-dimensions-back.jpeg deleted file mode 100644 index 1ab2f9c4bbdb..000000000000 Binary files a/docs/_static/esp32-devkitc-v4-dimensions-back.jpeg and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-a-v1.0-layout.png b/docs/_static/esp32-ethernet-kit-a-v1.0-layout.png deleted file mode 100644 index ad7ee3645ead..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-a-v1.0-layout.png and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-a-v1.1-layout.png b/docs/_static/esp32-ethernet-kit-a-v1.1-layout.png deleted file mode 100644 index 7b6fba2fd7bd..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-a-v1.1-layout.png and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-a-v1.2-layout.jpg b/docs/_static/esp32-ethernet-kit-a-v1.2-layout.jpg deleted file mode 100644 index 15f5f8cfbf96..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-a-v1.2-layout.jpg and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-b-v1.0-layout.png b/docs/_static/esp32-ethernet-kit-b-v1.0-layout.png deleted file mode 100644 index 9a2cb20a918f..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-b-v1.0-layout.png and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-block-diagram.png b/docs/_static/esp32-ethernet-kit-block-diagram.png deleted file mode 100644 index 6e49b1d5ff7b..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-block-diagram.png and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-rmii-clk-from-phy.png b/docs/_static/esp32-ethernet-kit-rmii-clk-from-phy.png deleted file mode 100644 index 5c5e4d4e516b..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-rmii-clk-from-phy.png and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-rmii-clk-to-phy.png b/docs/_static/esp32-ethernet-kit-rmii-clk-to-phy.png deleted file mode 100644 index dc893f99f46f..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-rmii-clk-to-phy.png and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-v1.0.png b/docs/_static/esp32-ethernet-kit-v1.0.png deleted file mode 100644 index 5150bf03f56e..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-v1.0.png and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-v1.1-block-diagram.png b/docs/_static/esp32-ethernet-kit-v1.1-block-diagram.png deleted file mode 100644 index 8c94faf9b43a..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-v1.1-block-diagram.png and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-v1.1.png b/docs/_static/esp32-ethernet-kit-v1.1.png deleted file mode 100644 index 1a2591dc9bfa..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-v1.1.png and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-v1.2-overview.png b/docs/_static/esp32-ethernet-kit-v1.2-overview.png deleted file mode 100644 index 6297d1d57219..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-v1.2-overview.png and /dev/null differ diff --git a/docs/_static/esp32-ethernet-kit-v1.2.jpg b/docs/_static/esp32-ethernet-kit-v1.2.jpg deleted file mode 100644 index 928cedd11dd5..000000000000 Binary files a/docs/_static/esp32-ethernet-kit-v1.2.jpg and /dev/null differ diff --git a/docs/_static/esp32-pico-devkitm-2-block.png b/docs/_static/esp32-pico-devkitm-2-block.png deleted file mode 100644 index 7326e0695ac0..000000000000 Binary files a/docs/_static/esp32-pico-devkitm-2-block.png and /dev/null differ diff --git a/docs/_static/esp32-pico-devkitm-2-layout-front.png b/docs/_static/esp32-pico-devkitm-2-layout-front.png deleted file mode 100644 index f145c2560476..000000000000 Binary files a/docs/_static/esp32-pico-devkitm-2-layout-front.png and /dev/null differ diff --git a/docs/_static/esp32-pico-devkitm-2-overview.png b/docs/_static/esp32-pico-devkitm-2-overview.png deleted file mode 100644 index bed3aa35342d..000000000000 Binary files a/docs/_static/esp32-pico-devkitm-2-overview.png and /dev/null differ diff --git a/docs/_static/esp32-pico-devkitm-2-pinout.png b/docs/_static/esp32-pico-devkitm-2-pinout.png deleted file mode 100644 index 9a41045f3dc4..000000000000 Binary files a/docs/_static/esp32-pico-devkitm-2-pinout.png and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-1-block.png b/docs/_static/esp32-pico-kit-1-block.png deleted file mode 100644 index b566b54e556a..000000000000 Binary files a/docs/_static/esp32-pico-kit-1-block.png and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-1-layout-front.png b/docs/_static/esp32-pico-kit-1-layout-front.png deleted file mode 100644 index e4b35bf39618..000000000000 Binary files a/docs/_static/esp32-pico-kit-1-layout-front.png and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-1-overview.png b/docs/_static/esp32-pico-kit-1-overview.png deleted file mode 100644 index 031f83e8b9ba..000000000000 Binary files a/docs/_static/esp32-pico-kit-1-overview.png and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-1-pinout.png b/docs/_static/esp32-pico-kit-1-pinout.png deleted file mode 100644 index 7daf96bd9943..000000000000 Binary files a/docs/_static/esp32-pico-kit-1-pinout.png and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-v3-layout.jpg b/docs/_static/esp32-pico-kit-v3-layout.jpg deleted file mode 100644 index f912a8995a39..000000000000 Binary files a/docs/_static/esp32-pico-kit-v3-layout.jpg and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-v4-dimensions-back.jpg b/docs/_static/esp32-pico-kit-v4-dimensions-back.jpg deleted file mode 100644 index 0f782daf8aa7..000000000000 Binary files a/docs/_static/esp32-pico-kit-v4-dimensions-back.jpg and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-v4-dimensions-side.jpg b/docs/_static/esp32-pico-kit-v4-dimensions-side.jpg deleted file mode 100644 index 282c3d457fed..000000000000 Binary files a/docs/_static/esp32-pico-kit-v4-dimensions-side.jpg and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-v4-functional-block-diagram.png b/docs/_static/esp32-pico-kit-v4-functional-block-diagram.png deleted file mode 100644 index 0369b176066f..000000000000 Binary files a/docs/_static/esp32-pico-kit-v4-functional-block-diagram.png and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-v4-layout.jpg b/docs/_static/esp32-pico-kit-v4-layout.jpg deleted file mode 100644 index c8dd4478877a..000000000000 Binary files a/docs/_static/esp32-pico-kit-v4-layout.jpg and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-v4-pinout.png b/docs/_static/esp32-pico-kit-v4-pinout.png deleted file mode 100644 index 810c08ea9e2c..000000000000 Binary files a/docs/_static/esp32-pico-kit-v4-pinout.png and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-v4.1-dimensions-back.jpeg b/docs/_static/esp32-pico-kit-v4.1-dimensions-back.jpeg deleted file mode 100644 index a22c2fda129b..000000000000 Binary files a/docs/_static/esp32-pico-kit-v4.1-dimensions-back.jpeg and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-v4.1-dimensions-back.jpg b/docs/_static/esp32-pico-kit-v4.1-dimensions-back.jpg deleted file mode 100644 index 805ff59f7ba6..000000000000 Binary files a/docs/_static/esp32-pico-kit-v4.1-dimensions-back.jpg and /dev/null differ diff --git a/docs/_static/esp32-pico-kit-v4.1-f-layout.jpeg b/docs/_static/esp32-pico-kit-v4.1-f-layout.jpeg deleted file mode 100644 index 89098c82c69e..000000000000 Binary files a/docs/_static/esp32-pico-kit-v4.1-f-layout.jpeg and /dev/null differ diff --git a/docs/_static/wrover-jp1-both.png b/docs/_static/wrover-jp1-both.png deleted file mode 100644 index 29a44c9f3761..000000000000 Binary files a/docs/_static/wrover-jp1-both.png and /dev/null differ diff --git a/docs/_static/wrover-jp1-sd_io2.png b/docs/_static/wrover-jp1-sd_io2.png deleted file mode 100644 index be341f7c8534..000000000000 Binary files a/docs/_static/wrover-jp1-sd_io2.png and /dev/null differ diff --git a/docs/_static/wrover-jp11-tx-rx.png b/docs/_static/wrover-jp11-tx-rx.png deleted file mode 100644 index 340278f6cf95..000000000000 Binary files a/docs/_static/wrover-jp11-tx-rx.png and /dev/null differ diff --git a/docs/_static/wrover-jp14.png b/docs/_static/wrover-jp14.png deleted file mode 100644 index eaf266f46f00..000000000000 Binary files a/docs/_static/wrover-jp14.png and /dev/null differ diff --git a/docs/_static/wrover-jp7-ext_5v.png b/docs/_static/wrover-jp7-ext_5v.png deleted file mode 100644 index 86fc2f65d4e5..000000000000 Binary files a/docs/_static/wrover-jp7-ext_5v.png and /dev/null differ diff --git a/docs/_static/wrover-jp7-usb_5v.png b/docs/_static/wrover-jp7-usb_5v.png deleted file mode 100644 index bd71636af3cc..000000000000 Binary files a/docs/_static/wrover-jp7-usb_5v.png and /dev/null differ diff --git a/docs/_static/wrover-jp8.png b/docs/_static/wrover-jp8.png deleted file mode 100644 index ac21939203f6..000000000000 Binary files a/docs/_static/wrover-jp8.png and /dev/null differ diff --git a/docs/conf_common.py b/docs/conf_common.py index 7c8d64663b01..599c5846fc56 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -16,21 +16,24 @@ if os.environ.get('IDF_PATH') is None: raise RuntimeError('IDF_PATH should be set, run export.sh before building docs') -BT_DOCS = ['api-guides/bluetooth.rst', - 'api-reference/bluetooth/bt_le.rst', - 'api-reference/bluetooth/esp_bt_defs.rst', +BT_DOCS = ['api-reference/bluetooth/esp_bt_defs.rst', 'api-reference/bluetooth/esp_bt_device.rst', 'api-reference/bluetooth/esp_bt_main.rst', 'api-reference/bluetooth/bt_common.rst', 'api-reference/bluetooth/controller_vhci.rst', - 'api-reference/bluetooth/esp_gap_ble.rst', - 'api-reference/bluetooth/esp_gatt_defs.rst', - 'api-reference/bluetooth/esp_gatts.rst', - 'api-reference/bluetooth/esp_gattc.rst', - 'api-reference/bluetooth/index.rst', - 'api-reference/bluetooth/nimble/index.rst'] - -BLE_DOCS = ['migration-guides/release-5.x/5.0/bluetooth-low-energy.rst'] + 'api-reference/bluetooth/index.rst'] + +BLE_DOCS = ['api-guides/ble/index.rst', + 'api-guides/ble/overview.rst', + 'api-guides/ble/ble-feature-support-status.rst', + 'api-guides/ble/host-feature-support-status.rst', + 'api-reference/bluetooth/bt_le.rst', + 'api-reference/bluetooth/esp_gap_ble.rst', + 'api-reference/bluetooth/esp_gatt_defs.rst', + 'api-reference/bluetooth/esp_gatts.rst', + 'api-reference/bluetooth/esp_gattc.rst', + 'api-reference/bluetooth/nimble/index.rst', + 'migration-guides/release-5.x/5.0/bluetooth-low-energy.rst'] BLE_MESH_DOCS = ['api-guides/esp-ble-mesh/ble-mesh-index.rst', 'api-guides/esp-ble-mesh/ble-mesh-feature-list.rst', @@ -39,7 +42,9 @@ 'api-guides/esp-ble-mesh/ble-mesh-faq.rst', 'api-reference/bluetooth/esp-ble-mesh.rst'] -CLASSIC_BT_DOCS = ['api-reference/bluetooth/classic_bt.rst', +CLASSIC_BT_DOCS = ['api-guides/classic-bt/index.rst', + 'api-guides/classic-bt/overview.rst', + 'api-reference/bluetooth/classic_bt.rst', 'api-reference/bluetooth/esp_a2dp.rst', 'api-reference/bluetooth/esp_avrc.rst', 'api-reference/bluetooth/esp_hidd.rst', @@ -53,7 +58,7 @@ 'api-reference/bluetooth/esp_gap_bt.rst', 'migration-guides/release-5.x/5.0/bluetooth-classic.rst'] -BLUFI_DOCS = ['api-guides/blufi.rst', +BLUFI_DOCS = ['api-guides/ble/blufi.rst', 'api-reference/bluetooth/esp_blufi.rst'] WIFI_DOCS = ['api-guides/wifi.rst', @@ -162,7 +167,7 @@ ISP_DOCS = ['api-reference/peripherals/isp.rst'] -RTC_MEM_DOCS = ['api-guides/deep-sleep-stub.rst'] +DSLP_STUB_DOCS = ['api-guides/deep-sleep-stub.rst'] ADC_DOCS = ['api-reference/peripherals/adc_oneshot.rst', 'api-reference/peripherals/adc_calibration.rst'] @@ -271,7 +276,7 @@ 'SOC_GPSPI_SUPPORTED':SPI_DOCS, 'SOC_I2S_SUPPORTED':I2S_DOCS, 'SOC_ISP_SUPPORTED':ISP_DOCS, - 'SOC_RTC_MEM_SUPPORTED': RTC_MEM_DOCS, + 'ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB': DSLP_STUB_DOCS, 'SOC_ADC_SUPPORTED':ADC_DOCS, 'SOC_ADC_DMA_SUPPORTED':ADC_DMA_DOCS, 'SOC_ANA_CMPR_SUPPORTED': ANA_CMPR_DOCS, diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index eeb73f960289..e11054ce4e55 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -1,22 +1,13 @@ api-guides/partition-tables.rst api-guides/RF_calibration.rst -api-guides/deep-sleep-stub.rst api-guides/coexist.rst api-guides/wifi.rst api-guides/usb-otg-console.rst api-guides/esp-wifi-mesh.rst api-guides/dfu.rst -api-guides/current-consumption-measurement-modules.rst api-guides/wifi-security.rst api-reference/peripherals/adc_continuous.rst api-reference/peripherals/adc_oneshot.rst -api-reference/peripherals/usb_host.rst -api-reference/peripherals/usb_host/usb_host_notes_arch.rst -api-reference/peripherals/usb_host/usb_host_notes_index.rst -api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst -api-reference/peripherals/usb_host/usb_host_notes_design.rst -api-reference/peripherals/usb_host/usb_host_notes_usbh.rst -api-reference/peripherals/usb_device.rst api-reference/peripherals/touch_element.rst api-reference/peripherals/touch_pad.rst api-reference/peripherals/adc_calibration.rst @@ -29,6 +20,3 @@ api-reference/network/esp_smartconfig.rst api-reference/network/esp_nan.rst api-reference/network/esp_wifi.rst api-reference/network/index.rst -api-reference/system/sleep_modes.rst -api-reference/system/power_management.rst -api-reference/system/inc/power_management_esp32p4.rst diff --git a/docs/en/api-guides/ble/ble-feature-support-status.rst b/docs/en/api-guides/ble/ble-feature-support-status.rst new file mode 100644 index 000000000000..01a7aa5b3cc4 --- /dev/null +++ b/docs/en/api-guides/ble/ble-feature-support-status.rst @@ -0,0 +1,338 @@ +Major Feature Support Status +================================ + +:link_to_translation:`zh_CN:[中文]` + +The table below shows the support status of Bluetooth Low Energy major features on {IDF_TARGET_NAME}. + +|supported_def| **This feature has completed development and internal testing.** [1]_ + +|experimental_def| **This feature has been developed and is currently undergoing internal testing.** +You can explore these features for evaluation and feedback purposes but should be cautious of potential issues. + +|developing_def| **The feature is currently being actively developed, and expected to be supported by the end of YYYY/MM.** +You should anticipate future updates regarding the progress and availability of these features. +If you do have an urgent need, please contact our `customer support team `__ for a possible feature trial. + +|unsupported_def| **This feature is not supported on this chip series.** If you have related requirements, please prioritize selecting other Espressif chip series that support this feature. +If none of our chip series meet your needs, please contact `customer support team `__, and our R&D team will conduct an internal feasibility assessment for you. + +|NA_def| The feature with this label could be the following two types: + - **Host-only Feature**: The feature exists only above HCI, such as GATT Caching. It does not require the support from the Controller. + - **Controller-only Feature**: The feature exists only below HCI, and cannot be configured/enabled via Host API, such as Advertising Channel Index. It does not require the support from the Host. + +.. list-table:: + :width: 100% + :widths: auto + :header-rows: 1 + + * - .. centered:: Core Spec + - .. centered:: Major Features + - .. centered:: ESP Controller + - .. centered:: ESP-Bluedroid Host + - .. centered:: ESP-NimBLE Host + * - .. centered:: |4.2| + - LE Data Packet Length Extension + - |supported| + - |supported| + - |supported| + * - + - LE Secure Connections + - |supported| + - |supported| + - |supported| + * - + - Link Layer Privacy + - |supported| + - |supported| + - |supported| + * - + - Link Layer Extended Filter Policies + - |supported| + - |supported| + - |supported| + * - .. centered:: |5.0| + - 2 Msym/s PHY for LE + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + * - + - LE Long Range (Coded PHY S=2/S=8) + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + * - + - High Duty Cycle Non-Connectable Advertising + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + * - + - LE Advertising Extensions + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + * - + - LE Channel Selection Algorithm #2 + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + * - .. centered:: |5.1| + - Angle of Arrival (AoA)/Angle of Departure (AoD) + - |unsupported| + - |unsupported| + - |unsupported| + * - + - GATT Caching + - |NA| + - |experimental| + - |experimental| + * - + - Advertising Channel Index + - |unsupported| + - |NA| + - |NA| + * - + - Periodic Advertising Sync Transfer + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c2 or esp32c5 + + |experimental| + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c2 or esp32c5 + + |experimental| + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c2 or esp32c5 + + |experimental| + * - .. centered:: |5.2| + - LE Isochronous Channels (BIS/CIS) + - |unsupported| + - |unsupported| + - |unsupported| + * - + - Enhanced Attribute Protocol + - |NA| + - |unsupported| + - |developing202412| + * - + - LE Power Control + - .. only:: esp32 or esp32c2 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c3 or esp32s3 or esp32c5 + + |experimental| + - |unsupported| + - .. only:: esp32 or esp32c2 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c3 or esp32s3 or esp32c5 + + |experimental| + * - .. centered:: |5.3| + - AdvDataInfo in Periodic Advertising + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |supported| + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |supported| + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |supported| + * - + - LE Enhanced Connection Update (Connection Subrating) + - .. only:: esp32 or esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |unsupported| + .. only:: esp32c3 or esp32s3 + + |experimental| + - |unsupported| + - .. only:: esp32 or esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |unsupported| + .. only:: esp32c3 or esp32s3 + + |experimental| + * - + - LE Channel Classification + - .. only:: esp32 or esp32c3 or esp32s3 or esp32c2 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c5 + + |experimental| + - .. only:: esp32 or esp32c3 or esp32s3 or esp32c2 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c5 + + |experimental| + - .. only:: esp32 or esp32c3 or esp32s3 or esp32c2 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c5 + + |experimental| + * - .. centered:: |5.4| + - Advertising Coding Selection + - .. only:: esp32 or esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |unsupported| + .. only:: esp32c3 or esp32s3 + + |experimental| + - |unsupported| + - .. only:: esp32 or esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |unsupported| + .. only:: esp32c3 or esp32s3 + + |experimental| + * - + - Encrypted Advertising Data + - |NA| + - |unsupported| + - |experimental| + * - + - LE GATT Security Levels Characteristic + - |NA| + - |unsupported| + - |developing202412| + * - + - Periodic Advertising with Responses + - |unsupported| + - |unsupported| + - |unsupported| + +.. [1] + If you would like to know the Bluetooth SIG certification information for supported features, + please consult `SIG Bluetooth Product Database `__. + +For certain features, if the majority of the development is completed on the Controller, the Host's support status will be limited by the Controller's support status. +If you want BLE Controller and Host to run on different Espressif chips, the functionality of the Host will not be limited by the Controller's support status on the chip running the Host, +please check the :doc:`ESP Host Feature Support Status Table ` . + +It is important to clarify that this document is not a binding commitment to our customers. +The above feature support status information is for general informational purposes only and is subject to change without notice. +You are encouraged to consult with our `customer support team `__ for the most up-to-date information and to verify the suitability of features for your specific needs. + + +.. |supported| image:: ../../../_static/ble/feature_status/supported.svg + :class: align-center + :width: 65px +.. |developing202412| image:: ../../../_static/ble/feature_status/developing202412.svg + :class: align-center + :width: 120px +.. |unsupported| image:: ../../../_static/ble/feature_status/unsupported.svg + :class: align-center + :width: 75px +.. |experimental| image:: ../../../_static/ble/feature_status/experimental.svg + :class: align-center + :width: 75px +.. |NA| image:: ../../../_static/ble/feature_status/NA.svg + :class: align-center + :width: 25px +.. |supported_def| image:: ../../../_static/ble/feature_status/supported.svg +.. |developing_def| image:: ../../../_static/ble/feature_status/developingYYYYMM.svg +.. |unsupported_def| image:: ../../../_static/ble/feature_status/unsupported.svg +.. |experimental_def| image:: ../../../_static/ble/feature_status/experimental.svg +.. |NA_def| image:: ../../../_static/ble/feature_status/NA.svg +.. |4.2| replace:: `4.2 `__ +.. |5.0| replace:: `5.0 `__ +.. |5.1| replace:: `5.1 `__ +.. |5.2| replace:: `5.2 `__ +.. |5.3| replace:: `5.3 `__ +.. |5.4| replace:: `5.4 `__ diff --git a/docs/en/api-guides/blufi.rst b/docs/en/api-guides/ble/blufi.rst similarity index 99% rename from docs/en/api-guides/blufi.rst rename to docs/en/api-guides/ble/blufi.rst index 5e69ccf2a92b..ce60c53f4600 100644 --- a/docs/en/api-guides/blufi.rst +++ b/docs/en/api-guides/ble/blufi.rst @@ -1,10 +1,10 @@ BluFi -^^^^^ +^^^^^^ -:link_to_translation:`zh_CN:[中文]` +:link_to_translation:`en:[English]` Overview --------- +---------- The BluFi for {IDF_TARGET_NAME} is a Wi-Fi network configuration function via Bluetooth channel. It provides a secure protocol to pass Wi-Fi configuration and credentials to {IDF_TARGET_NAME}. Using this information, {IDF_TARGET_NAME} can then connect to an AP or establish a SoftAP. @@ -13,7 +13,7 @@ Fragmenting, data encryption, and checksum verification in the BluFi layer are t You can customize symmetric encryption, asymmetric encryption, and checksum support customization. Here we use the DH algorithm for key negotiation, 128-AES algorithm for data encryption, and CRC16 algorithm for checksum verification. The BluFi Flow ---------------- +---------------- The BluFi networking flow includes the configuration of the SoftAP and Station. @@ -46,7 +46,7 @@ The following uses Station as an example to illustrate the core parts of the pro 2. The data lengths before and after symmetric encryption/decryption must stay the same. It also supports in-place encryption and decryption. The Flow Chart of BluFi --------------------------- +------------------------- .. seqdiag:: :caption: BluFi Flow Chart @@ -75,7 +75,7 @@ The Flow Chart of BluFi .. _frame_formats: The Frame Formats Defined in BluFi ------------------------------------ +------------------------------------ The frame formats for the communication between the mobile phone App and {IDF_TARGET_NAME} are defined as follows: @@ -431,7 +431,7 @@ The format of ACK Frame: The **CheckSum** field takes two bytes, which is used to check "sequence + data length + clear text data". The Security Implementation of {IDF_TARGET_NAME} ------------------------------------------------- +-------------------------------------------------- 1. Securing Data @@ -482,7 +482,7 @@ The data to be encrypted and decrypted must be in the same length. The IV8 is an This function is used to compute CheckSum and return a value of CheckSum. BluFi uses the returned value to compare the CheckSum of the frame. GATT Related Instructions -------------------------- +---------------------------- UUID >>>>> diff --git a/docs/en/api-guides/ble/host-feature-support-status.rst b/docs/en/api-guides/ble/host-feature-support-status.rst new file mode 100644 index 000000000000..c3897ed71500 --- /dev/null +++ b/docs/en/api-guides/ble/host-feature-support-status.rst @@ -0,0 +1,159 @@ +:orphan: + +ESP Host Major Feature Support Status +======================================= + +:link_to_translation:`zh_CN:[中文]` + +The table below shows the support status of major features on ESP-Bluedroid and ESP-NimBLE Host. +If you plan to run the BLE Controller and Host on {IDF_TARGET_NAME} together, the functionality of the Host may be limited by the support status of the Controller, +please check the :doc:`{IDF_TARGET_NAME} Major Feature Support Status Table ` . + +|supported_def| **This feature has completed development and internal testing.** [1]_ + +|experimental_def| **This feature has been developed and is currently undergoing internal testing.** +You can explore these features for evaluation and feedback purposes but should be cautious of potential issues. + +|developing_def| **The feature is currently being actively developed, and expected to be supported by the end of YYYY/MM.** +You should anticipate future updates regarding the progress and availability of these features. +If you do have an urgent need, please contact our `customer support team `__ for a possible feature trial. + +|unsupported_def| **This feature is not supported on this Host.** If you have related requirements, please prioritize selecting other Espressif Bluetooth Host that support this feature. +If none of our chip series meet your needs, please contact `customer support team `__, and our R&D team will conduct an internal feasibility assessment for you. + +|NA_def| The feature with this label could be the following type: + - **Controller-only Feature**: The feature exists only below HCI, and cannot be configured/enabled via Host API, such as Advertising Channel Index. + It does not require the support from the Host. + +.. list-table:: + :width: 100% + :widths: auto + :header-rows: 1 + + * - .. centered:: Core Spec + - .. centered:: Major Features + - .. centered:: ESP-Bluedroid Host + - .. centered:: ESP-NimBLE Host + * - .. centered:: |4.2| + - LE Data Packet Length Extension + - |supported| + - |supported| + * - + - LE Secure Connections + - |supported| + - |supported| + * - + - Link Layer Privacy + - |supported| + - |supported| + * - + - Link Layer Extended Filter Policies + - |supported| + - |supported| + * - .. centered:: |5.0| + - 2 Msym/s PHY for LE + - |supported| + - |supported| + * - + - LE Long Range (Coded PHY S=2/S=8) + - |supported| + - |supported| + * - + - High Duty Cycle Non-Connectable Advertising + - |supported| + - |supported| + * - + - LE Advertising Extensions + - |supported| + - |supported| + * - + - LE Channel Selection Algorithm #2 + - |supported| + - |supported| + * - .. centered:: |5.1| + - Angle of Arrival (AoA)/Angle of Departure (AoD) + - |unsupported| + - |developing202412| + * - + - GATT Caching + - |experimental| + - |experimental| + * - + - Advertising Channel Index + - |NA| + - |NA| + * - + - Periodic Advertising Sync Transfer + - |supported| + - |supported| + * - .. centered:: |5.2| + - LE Isochronous Channels (BIS/CIS) + - |unsupported| + - |unsupported| + * - + - Enhanced Attribute Protocol + - |unsupported| + - |developing202412| + * - + - LE Power Control + - |unsupported| + - |supported| + * - .. centered:: |5.3| + - AdvDataInfo in Periodic Advertising + - |supported| + - |supported| + * - + - LE Enhanced Connection Update (Connection Subrating) + - |unsupported| + - |supported| + * - + - LE Channel Classification + - |supported| + - |supported| + * - .. centered:: |5.4| + - Advertising Coding Selection + - |unsupported| + - |supported| + * - + - Encrypted Advertising Data + - |unsupported| + - |experimental| + * - + - LE GATT Security Levels Characteristic + - |unsupported| + - |developing202412| + * - + - Periodic Advertising with Responses + - |unsupported| + - |developing202412| + +.. [1] + If you would like to know the Bluetooth SIG certification information for supported features, + please consult `SIG Bluetooth Product Database `__. + +It is important to clarify that this document is not a binding commitment to our customers. +The above feature support status information is for general informational purposes only and is subject to change without notice. +You are encouraged to consult with our `customer support team `__ for the most up-to-date information and to verify the suitability of features for your specific needs. + + +.. |supported| image:: ../../../_static/ble/feature_status/supported.svg + :class: align-center +.. |developing202412| image:: ../../../_static/ble/feature_status/developing202412.svg + :class: align-center +.. |unsupported| image:: ../../../_static/ble/feature_status/unsupported.svg + :class: align-center +.. |experimental| image:: ../../../_static/ble/feature_status/experimental.svg + :class: align-center +.. |NA| image:: ../../../_static/ble/feature_status/NA.svg + :class: align-center +.. |supported_def| image:: ../../../_static/ble/feature_status/supported.svg +.. |developing_def| image:: ../../../_static/ble/feature_status/developingYYYYMM.svg +.. |unsupported_def| image:: ../../../_static/ble/feature_status/unsupported.svg +.. |experimental_def| image:: ../../../_static/ble/feature_status/experimental.svg +.. |NA_def| image:: ../../../_static/ble/feature_status/NA.svg +.. |4.2| replace:: `4.2 `__ +.. |5.0| replace:: `5.0 `__ +.. |5.1| replace:: `5.1 `__ +.. |5.2| replace:: `5.2 `__ +.. |5.3| replace:: `5.3 `__ +.. |5.4| replace:: `5.4 `__ diff --git a/docs/en/api-guides/ble/index.rst b/docs/en/api-guides/ble/index.rst new file mode 100644 index 000000000000..226b6f73db6c --- /dev/null +++ b/docs/en/api-guides/ble/index.rst @@ -0,0 +1,24 @@ +####################### +Bluetooth® Low Energy +####################### + +:link_to_translation:`zh_CN:[中文]` + +********* +Overview +********* +.. toctree:: + :maxdepth: 1 + + overview + ble-feature-support-status + +********** +Profile +********** + +.. toctree:: + :maxdepth: 2 + + :SOC_BLE_MESH_SUPPORTED: ../esp-ble-mesh/ble-mesh-index + :SOC_BLUFI_SUPPORTED: blufi diff --git a/docs/en/api-guides/bluetooth.rst b/docs/en/api-guides/ble/overview.rst similarity index 71% rename from docs/en/api-guides/bluetooth.rst rename to docs/en/api-guides/ble/overview.rst index e02c944ba077..e360d210cd4c 100644 --- a/docs/en/api-guides/bluetooth.rst +++ b/docs/en/api-guides/ble/overview.rst @@ -1,52 +1,52 @@ -Bluetooth® Overview -=================== +Introduction +============= :link_to_translation:`zh_CN:[中文]` -This document provides an architecture overview of the Bluetooth stack in ESP-IDF and some quick links to related documents and application examples. +This document provides an architecture overview of the Bluetooth Low Energy (Bluetooth LE) stack in ESP-IDF and some quick links to related documents and application examples. .. only:: esp32 - {IDF_TARGET_NAME} supports Dual-Mode Bluetooth 4.2 and is certified for Bluetooth 4.2. + {IDF_TARGET_NAME} supports Dual-Mode Bluetooth 4.2 and is certified for Dual-Mode Bluetooth 4.2 and Bluetooth LE 5.0. .. only:: esp32c3 or esp32s3 - {IDF_TARGET_NAME} supports Bluetooth 5.0 (LE) and is certified for Bluetooth LE 5.0. + {IDF_TARGET_NAME} supports Bluetooth 5.0 (LE) and is certified for Bluetooth LE 5.4. .. only:: esp32c2 or esp32c6 or esp32h2 {IDF_TARGET_NAME} supports Bluetooth 5.0 (LE) and is certified for Bluetooth LE 5.3. -The Bluetooth stack in ESP-IDF is a layered architecture that enables Bluetooth functionality on {IDF_TARGET_NAME} chip series. The table below shows its architecture. +The Bluetooth LE stack in ESP-IDF is a layered architecture that enables Bluetooth functionality on {IDF_TARGET_NAME} chip series. The table below shows its architecture. .. only:: esp32 or esp32s3 or esp32c3 or esp32c6 - .. figure:: ../../_static/bluetooth-architecture.png + .. figure:: ../../../_static/bluetooth-architecture.png :align: center :scale: 90% - :alt: {IDF_TARGET_NAME} Bluetooth Stack Architecture + :alt: {IDF_TARGET_NAME} Bluetooth LE Stack Architecture - {IDF_TARGET_NAME} Bluetooth Stack Architecture + {IDF_TARGET_NAME} Bluetooth LE Stack Architecture .. only:: esp32c2 - .. figure:: ../../_static/bluetooth-architecture-no-ble-mesh.png + .. figure:: ../../../_static/bluetooth-architecture-no-ble-mesh.png :align: center :scale: 90% - :alt: {IDF_TARGET_NAME} Bluetooth Stack Architecture + :alt: {IDF_TARGET_NAME} Bluetooth LE Stack Architecture - {IDF_TARGET_NAME} Bluetooth Stack Architecture + {IDF_TARGET_NAME} Bluetooth LE Stack Architecture .. only:: esp32h2 - .. figure:: ../../_static/bluetooth-architecture-no-blufi.png + .. figure:: ../../../_static/bluetooth-architecture-no-blufi.png :align: center :scale: 90% - :alt: {IDF_TARGET_NAME} Bluetooth Stack Architecture + :alt: {IDF_TARGET_NAME} Bluetooth LE Stack Architecture - {IDF_TARGET_NAME} Bluetooth Stack Architecture + {IDF_TARGET_NAME} Bluetooth LE Stack Architecture -The table below shows whether the Bluetooth modules are supported in a specific chip series. +The table below shows whether the Bluetooth LE modules are supported in a specific chip series. .. list-table:: :width: 100% @@ -110,7 +110,7 @@ ESP Bluetooth Controller At the bottom layer is ESP Bluetooth Controller, which encompasses various modules such as PHY, Baseband, Link Controller, Link Manager, Device Manager, and HCI. It handles hardware interface management and link management. It provides functions in the form of libraries and is accessible through APIs. This layer directly interacts with the hardware and low-level Bluetooth protocols. -- :doc:`API reference <../api-reference/bluetooth/controller_vhci>` +- :doc:`API reference <../../api-reference/bluetooth/controller_vhci>` - :example:`Application examples ` @@ -129,7 +129,7 @@ There are two hosts, ESP-Bluedroid and ESP-NimBLE. The major difference between ESP-Bluedroid ^^^^^^^^^^^^^ -ESP-Bluedroid is a modified version of the native Android Bluetooth stack, Bluedroid. It consists of two layers: the Bluetooth Upper Layer (BTU) and the Bluetooth Transport Controller layer (BTC). The BTU layer is responsible for processing bottom layer Bluetooth protocols such as L2CAP, GATT/ATT, SMP, GAP, and other profiles. The BTU layer provides an interface prefixed with "bta". The BTC layer is mainly responsible for providing a supported interface, prefixed with "esp", to the application layer, processing GATT-based profiles and handling miscellaneous tasks. All the APIs are located in the ESP_API layer. Developers should use the Bluetooth APIs prefixed with "esp". +ESP-Bluedroid is a modified version of the native Android Bluetooth stack, Bluedroid. It consists of two layers: the Bluetooth Upper Layer (BTU) and the Bluetooth Transport Controller layer (BTC). The BTU layer is responsible for processing bottom layer Bluetooth protocols such as L2CAP, GATT/ATT, SMP, GAP, and other profiles. The BTU layer provides an interface prefixed with "bta". The BTC layer is mainly responsible for providing a supported interface, prefixed with "esp", to the application layer, processing GATT-based profiles and handling miscellaneous tasks. All the APIs are located in the ESP_API layer. Developers should use the Bluetooth Low Energy APIs prefixed with "esp". .. only:: esp32 @@ -141,15 +141,17 @@ ESP-Bluedroid is a modified version of the native Android Bluetooth stack, Blued - API references - - :doc:`../api-reference/bluetooth/bt_common` - - :doc:`Bluetooth LE <../api-reference/bluetooth/bt_le>` + - :doc:`../../api-reference/bluetooth/bt_common` + - :doc:`Bluetooth LE <../../api-reference/bluetooth/bt_le>` - .. only:: esp32 +.. only:: esp32 - - :doc:`../api-reference/bluetooth/classic_bt` + - :example:`Bluetooth LE 4.2 Application Examples ` -- :example:`Application examples ` +.. only:: not esp32 + - :example:`Bluetooth LE 4.2 Application Examples ` + - :example:`Bluetooth LE 5.0 Application Examples ` ESP-NimBLE ^^^^^^^^^^ @@ -162,7 +164,7 @@ ESP-NimBLE supports Bluetooth LE only. Classic Bluetooth is not supported. - API references - `NimBLE API references `__ - - :doc:`ESP-NimBLE API references for initialization <../api-reference/bluetooth/nimble/index>` + - :doc:`ESP-NimBLE API references for initialization <../../api-reference/bluetooth/nimble/index>` - :example:`Application examples ` @@ -180,7 +182,7 @@ Above the host stacks are the profile implementations by Espressif and some comm Built on top of Zephyr Bluetooth Mesh stack, the ESP-BLE-MESH implementation supports device provisioning and node control. It also supports such node features as Proxy, Relay, Low power and Friend. - - :doc:`ESP-BLE-MESH documentation `: feature list, get started, architecture, description of application examples, frequently asked questions, etc. + - :doc:`ESP-BLE-MESH documentation <../esp-ble-mesh/ble-mesh-index>`: feature list, get started, architecture, description of application examples, frequently asked questions, etc. - :example:`Application examples ` @@ -198,4 +200,4 @@ Above the host stacks are the profile implementations by Espressif and some comm Applications ------------ -At the uppermost layer are applications. You can build your own applications on top of the ESP-Bluedroid and ESP-NimBLE stacks, leveraging the provided APIs and profiles to create Bluetooth-enabled applications tailored to specific use cases. +At the uppermost layer are applications. You can build your own applications on top of the ESP-Bluedroid and ESP-NimBLE stacks, leveraging the provided APIs and profiles to create Bluetooth LE-enabled applications tailored to specific use cases. diff --git a/docs/en/api-guides/classic-bt/index.rst b/docs/en/api-guides/classic-bt/index.rst new file mode 100644 index 000000000000..e6e9141c70c6 --- /dev/null +++ b/docs/en/api-guides/classic-bt/index.rst @@ -0,0 +1,13 @@ +####################### +Bluetooth® Classic +####################### + +:link_to_translation:`zh_CN:[中文]` + +********* +Overview +********* +.. toctree:: + :maxdepth: 2 + + overview diff --git a/docs/en/api-guides/classic-bt/overview.rst b/docs/en/api-guides/classic-bt/overview.rst new file mode 100644 index 000000000000..4c28f800e899 --- /dev/null +++ b/docs/en/api-guides/classic-bt/overview.rst @@ -0,0 +1,80 @@ +Introduction +============= + +:link_to_translation:`zh_CN:[中文]` + +This document provides an architecture overview of the Bluetooth Classic stack in ESP-IDF and some quick links to related documents and application examples. + +.. only:: esp32 + + {IDF_TARGET_NAME} supports Dual-Mode Bluetooth 4.2. + +The Bluetooth Classic stack in ESP-IDF is a layered architecture that enables Bluetooth functionality on {IDF_TARGET_NAME} chip series. The table below shows its architecture. + +.. only:: esp32 + + .. figure:: ../../../_static/classic-bluetooth-architecture.png + :align: center + :scale: 90% + :alt: {IDF_TARGET_NAME} Bluetooth Classic Stack Architecture + + {IDF_TARGET_NAME} Bluetooth Classic Stack Architecture + +The table below shows whether the Bluetooth Classic Controller are supported in a specific chip series. + +.. list-table:: + :width: 100% + :widths: auto + :header-rows: 1 + + * - Chip Series + - Controller + * - ESP32 + - Y + * - ESP32-S2 + - \– + * - ESP32-S3 + - \– + * - ESP32-C2 + - \– + * - ESP32-C3 + - \- + * - ESP32-C6 + - \- + * - ESP32-H2 + - \- + +The following sections briefly describe each layer and provide quick links to the related documents and application examples. + + +ESP Bluetooth Controller +------------------------ + +At the bottom layer is ESP Bluetooth Controller, which encompasses various modules such as PHY, Baseband, Link Controller, Link Manager, Device Manager, and HCI. It handles hardware interface management and link management. It provides functions in the form of libraries and is accessible through APIs. This layer directly interacts with the hardware and low-level Bluetooth protocols. + +- :doc:`API reference <../../api-reference/bluetooth/controller_vhci>` +- :example:`Application examples ` + + +Hosts +----- + +There is one host, ESP-Bluedroid, supporting Classic Bluetooth in IDF. + + +ESP-Bluedroid +^^^^^^^^^^^^^ + +ESP-Bluedroid is a modified version of the native Android Bluetooth stack, Bluedroid. It consists of two layers: the Bluetooth Upper Layer (BTU) and the Bluetooth Transport Controller layer (BTC). The BTU layer is responsible for processing bottom layer Bluetooth protocols such as L2CAP and other profiles. The BTU layer provides an interface prefixed with "bta". The BTC layer is mainly responsible for providing a supported interface, prefixed with "esp", to the application layer and handling miscellaneous tasks. All the APIs are located in the ESP_API layer. Developers should use the Classic Bluetooth APIs prefixed with "esp". + +- API references + + - :doc:`../../api-reference/bluetooth/bt_common` + - :doc:`../../api-reference/bluetooth/classic_bt` +- :example:`Application examples ` + + +Applications +------------ + +At the uppermost layer are applications. You can build your own applications on top of the ESP-Bluedroid stacks, leveraging the provided APIs and profiles to create Bluetooth Classic applications tailored to specific use cases. diff --git a/docs/en/api-guides/current-consumption-measurement-modules.rst b/docs/en/api-guides/current-consumption-measurement-modules.rst index 3bac49f5bd03..2db15c1d9cd7 100644 --- a/docs/en/api-guides/current-consumption-measurement-modules.rst +++ b/docs/en/api-guides/current-consumption-measurement-modules.rst @@ -1,7 +1,7 @@ Current Consumption Measurement of Modules ========================================== -{IDF_TARGET_SOC_BOOT_PIN:default="Not updated", esp32="IO0", esp32s2="IO0", esp32s3="IO0", esp32c3="IO9", esp32c2="IO9", "esp32c6"="IO9", "esp32h2"="IO9"} +{IDF_TARGET_SOC_BOOT_PIN:default="Not updated", esp32="IO0", esp32s2="IO0", esp32s3="IO0", esp32c3="IO9", esp32c2="IO9", "esp32c6"="IO9", "esp32h2"="IO9", "esp32p4"="IO35"} You may want to know the current consumption of a `module `__ in deep-sleep mode, :doc:`other power-saving modes `, and active mode to develop some applications sensitive to power consumption. This section introduces how to measure the current consumption of a module running such an application. @@ -24,7 +24,7 @@ Can We Use a Development Board? With such development boards, you can measure current consumption of modules in deep-sleep mode by flashing chips with the :example:`deep_sleep ` example. However, you can also measure current of bare modules equipped with {IDF_TARGET_NAME} chip using the following method. -.. only:: esp32 or esp32s2 or esp32s3 or esp32c2 or esp32c3 +.. only:: esp32 or esp32s2 or esp32s3 or esp32c2 or esp32c3 or esp32p4 For {IDF_TARGET_NAME}, using a development board directly to measure current consumption of the corresponding module is not recommended, as some circuits still consume power on the board even when you flash the chip with the :example:`deep_sleep ` example. Therefore, you need to cut off the power supply circuit to the module to measure the module's current. This method is inconvenient and increases measurement costs. diff --git a/docs/en/api-guides/esp-ble-mesh/ble-mesh-architecture.rst b/docs/en/api-guides/esp-ble-mesh/ble-mesh-architecture.rst index f096c8a79750..64f1e09636fc 100644 --- a/docs/en/api-guides/esp-ble-mesh/ble-mesh-architecture.rst +++ b/docs/en/api-guides/esp-ble-mesh/ble-mesh-architecture.rst @@ -1,5 +1,5 @@ -ESP-BLE-MESH Architecture -========================= +Architecture +============= :link_to_translation:`zh_CN:[中文]` diff --git a/docs/en/api-guides/esp-ble-mesh/ble-mesh-faq.rst b/docs/en/api-guides/esp-ble-mesh/ble-mesh-faq.rst index e6ed54892363..4256297eda73 100644 --- a/docs/en/api-guides/esp-ble-mesh/ble-mesh-faq.rst +++ b/docs/en/api-guides/esp-ble-mesh/ble-mesh-faq.rst @@ -1,5 +1,5 @@ -ESP-BLE-MESH FAQ -================ +FAQ +===== :link_to_translation:`zh_CN:[中文]` @@ -532,7 +532,7 @@ Generally, a Provisioner is used to provision unprovisioned devices and form a m .. only:: esp32 - The :doc:`ESP32-DevKitC <../../hw-reference/esp32/get-started-devkitc>` board without PSRAM can run properly but the throughput of it is low since it has no PSRAM. When Bluetooth and Wi-Fi coexist, the throughput of ESP32-DevKitC with PSRAM can be stabilized to more than 1 Mbps. + The `ESP32-DevKitC `__ board without PSRAM can run properly but the throughput of it is low since it has no PSRAM. When Bluetooth and Wi-Fi coexist, the throughput of ESP32-DevKitC with PSRAM can be stabilized to more than 1 Mbps. Some configurations in menuconfig shall be enabled to support PSRAM. diff --git a/docs/en/api-guides/esp-ble-mesh/ble-mesh-feature-list.rst b/docs/en/api-guides/esp-ble-mesh/ble-mesh-feature-list.rst index 28eb45c104e9..595564629605 100644 --- a/docs/en/api-guides/esp-ble-mesh/ble-mesh-feature-list.rst +++ b/docs/en/api-guides/esp-ble-mesh/ble-mesh-feature-list.rst @@ -1,5 +1,7 @@ -ESP-BLE-MESH Feature List -========================= +Feature List +============= + +:link_to_translation:`zh_CN:[中文]` Supported Features ------------------ @@ -7,7 +9,7 @@ Supported Features Mesh Core """"""""" -* Provisioning: +* Provisioning * PB-ADV, PB-GATT and PB-Remote * OOB Authentication * Certificate-based Provisioning @@ -130,8 +132,8 @@ Mesh Models * Light LC Server * Light LC Setup Server -Mesh Applications -""""""""""""""""" +Mesh Examples +""""""""""""" * ESP-BLE-MESH Node * :example_file:`Tutorial ` @@ -149,18 +151,3 @@ Mesh Applications * :example_file:`Tutorial ` * :example:`Example ` * `Demo Video `__ - - -Future Release Features ------------------------ - -Mesh Core -""""""""" - -* Provisioner NVS Storage - -Mesh Applications -""""""""""""""""" - -* Fast OTA -* Friendship diff --git a/docs/en/api-guides/esp-ble-mesh/ble-mesh-index.rst b/docs/en/api-guides/esp-ble-mesh/ble-mesh-index.rst index b6874b932f09..402dfb008ca3 100644 --- a/docs/en/api-guides/esp-ble-mesh/ble-mesh-index.rst +++ b/docs/en/api-guides/esp-ble-mesh/ble-mesh-index.rst @@ -25,8 +25,8 @@ ESP-BLE-MESH is implemented and certified based on the latest Mesh Profile v1.0. .. _getting-started-with-ble-mesh: -Getting Started with ESP-BLE-MESH -================================= +Getting Started +================= This section is intended to help you get started with ESP-BLE-MESH for the hardware based on the {IDF_TARGET_NAME} chip by Espressif. @@ -210,8 +210,8 @@ The following screenshot shows different board with different color on. .. _esp-ble-mesh-examples: -ESP-BLE-MESH Examples -===================== +Examples +========= * :example_file:`OnOff Server ` - shows the use of ESP-BLE-MESH as a node having a Configuration Server model and a Generic OnOff Server model. A ESP-BLE-MESH Provisioner can then provision the unprovisioned device and control a RGB LED representing on/off state, see :example:`example code `. @@ -230,15 +230,15 @@ ESP-BLE-MESH Examples .. _esp-ble-mesh-demo-videos: -ESP-BLE-MESH Demo Videos -======================== +Demo Videos +============ * `Espressif Fast Provisioning using ESP-BLE-MESH App `_ * `Espressif ESP-BLE-MESH and Wi-Fi Coexistence `_ -ESP-BLE-MESH FAQ -================ +FAQ +==== * :ref:`ble-mesh-faq-provisioner-development` * :ref:`ble-mesh-faq-node-development` diff --git a/docs/en/api-guides/esp-ble-mesh/ble-mesh-terminology.rst b/docs/en/api-guides/esp-ble-mesh/ble-mesh-terminology.rst index d6ab0031e39a..fdf4dbdf5aec 100644 --- a/docs/en/api-guides/esp-ble-mesh/ble-mesh-terminology.rst +++ b/docs/en/api-guides/esp-ble-mesh/ble-mesh-terminology.rst @@ -1,5 +1,5 @@ -ESP-BLE-MESH Terminology -======================== +Terminology +============ :link_to_translation:`zh_CN:[中文]` diff --git a/docs/en/api-guides/external-ram.rst b/docs/en/api-guides/external-ram.rst index 39f2b402b9bc..521c1f959c50 100644 --- a/docs/en/api-guides/external-ram.rst +++ b/docs/en/api-guides/external-ram.rst @@ -123,16 +123,14 @@ This option reduces the internal static memory used by the BSS segment. Remaining external RAM can also be added to the capability heap allocator using the method shown above. -.. only:: esp32 - - .. _external_ram_config_noinit: +.. _external_ram_config_noinit: - Allow .noinit Segment to Be Placed in External Memory - -------------------------------------------------------------- +Allow .noinit Segment to Be Placed in External Memory +-------------------------------------------------------------- - Enable this option by checking :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY`. If enabled, the region of the data virtual address space where the PSRAM is mapped to will be used to store non-initialized data. The values placed in this segment will not be initialized or modified even during startup or restart. +Enable this option by checking :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY`. If enabled, the region of the data virtual address space where the PSRAM is mapped to will be used to store non-initialized data. The values placed in this segment will not be initialized or modified even during startup or restart. - By applying the macro ``EXT_RAM_NOINIT_ATTR``, data could be moved from the internal NOINIT segment to external RAM. Remaining external RAM can still be added to the capability heap allocator using the method shown above, :ref:`external_ram_config_capability_allocator`. +By applying the macro ``EXT_RAM_NOINIT_ATTR``, data could be moved from the internal NOINIT segment to external RAM. Remaining external RAM can still be added to the capability heap allocator using the method shown above, :ref:`external_ram_config_capability_allocator`. .. only:: SOC_SPIRAM_XIP_SUPPORTED diff --git a/docs/en/api-guides/index.rst b/docs/en/api-guides/index.rst index 5e5fe37d12c4..aec38f2e5f67 100644 --- a/docs/en/api-guides/index.rst +++ b/docs/en/api-guides/index.rst @@ -7,8 +7,9 @@ API Guides app_trace startup - :SOC_BLUFI_SUPPORTED: blufi - :SOC_BT_SUPPORTED: bluetooth + :SOC_BT_CLASSIC_SUPPORTED: classic-bt/index + :SOC_BLE_SUPPORTED: ble/index + :SOC_BLE_MESH_SUPPORTED: esp-ble-mesh/ble-mesh-index bootloader build-system :SOC_SUPPORT_COEXISTENCE: coexist @@ -16,10 +17,9 @@ API Guides cplusplus core_dump current-consumption-measurement-modules - :SOC_RTC_MEM_SUPPORTED: deep-sleep-stub + :ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB: deep-sleep-stub :SOC_USB_OTG_SUPPORTED and not esp32p4: dfu error-handling - :SOC_BLE_MESH_SUPPORTED: esp-ble-mesh/ble-mesh-index :SOC_WIFI_MESH_SUPPORT: esp-wifi-mesh :SOC_SPIRAM_SUPPORTED: external-ram fatal-errors diff --git a/docs/en/api-guides/jtag-debugging/esp32.inc b/docs/en/api-guides/jtag-debugging/esp32.inc index ee6c9f47bbdf..6358a022f6db 100644 --- a/docs/en/api-guides/jtag-debugging/esp32.inc +++ b/docs/en/api-guides/jtag-debugging/esp32.inc @@ -163,12 +163,12 @@ .. devkit-defs .. |devkit-name| replace:: ESP-WROVER-KIT -.. |devkit-name-with-link| replace:: :doc:`ESP-WROVER-KIT <../../hw-reference/index>` +.. |devkit-name-with-link| replace:: `ESP-WROVER-KIT `__ --- .. devkit-hw-config -* Enable on-board JTAG functionality by setting JP8 according to :doc:`../../hw-reference/esp32/get-started-wrover-kit`, Section :ref:`get-started-esp-wrover-kit-v4.1-setup-options`. +* Enable on-board JTAG functionality by setting JP2 according to `ESP-WROVER-KIT `__. --- diff --git a/docs/en/api-guides/linker-script-generation.rst b/docs/en/api-guides/linker-script-generation.rst index 3f77e35b2c80..65a8dbeced90 100644 --- a/docs/en/api-guides/linker-script-generation.rst +++ b/docs/en/api-guides/linker-script-generation.rst @@ -14,7 +14,7 @@ For example, it may be necessary to place: * critical code in RAM for performance reasons. * executable code in IRAM so that it can be ran while cache is disabled. - :SOC_RTC_MEM_SUPPORTED: * code in RTC memory for use in a wake stub. + :ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB: * code in RTC memory for use in a wake stub. :SOC_ULP_SUPPORTED: * code in RTC memory for use by the ULP coprocessor. With the linker script generation mechanism, it is possible to specify these placements at the component level within ESP-IDF. The component presents information on how it would like to place its symbols, objects or the entire archive. During build, the information presented by the components are collected, parsed and processed; and the placement rules generated is used to link the app. diff --git a/docs/en/api-guides/lwip.rst b/docs/en/api-guides/lwip.rst index 56e9c54f6739..462ded4e9eb0 100644 --- a/docs/en/api-guides/lwip.rst +++ b/docs/en/api-guides/lwip.rst @@ -459,6 +459,10 @@ Limitations ESP-IDF additions to lwIP still suffer from the global DNS limitation, described in :ref:`lwip-dns-limitation`. To address this limitation from application code, the ``FALLBACK_DNS_SERVER_ADDRESS()`` macro can be utilized to define a global DNS fallback server accessible from all interfaces. Alternatively, you have the option to maintain per-interface DNS servers and reconfigure them whenever the default interface changes. +The number of IP addresses returned by network database APIs such as ``getaddrinfo()`` and ``gethostbyname()`` is restricted by the macro ``DNS_MAX_HOST_IP``. By default, the value of this macro is set to 1. + +In the implementation of ``getaddrinfo()``, the canonical name is not available. Therefore, the ``ai_canonname`` field of the first returned ``addrinfo`` structure will always refer to the ``nodename`` argument or a string with the same contents. + Calling ``send()`` or ``sendto()`` repeatedly on a UDP socket may eventually fail with ``errno`` equal to ``ENOMEM``. This failure occurs due to the limitations of buffer sizes in the lower-layer network interface drivers. If all driver transmit buffers are full, the UDP transmission will fail. For applications that transmit a high volume of UDP datagrams and aim to avoid any dropped datagrams by the sender, it is advisable to implement error code checking and employ a retransmission mechanism with a short delay. .. only:: esp32 diff --git a/docs/en/api-guides/memory-types.rst b/docs/en/api-guides/memory-types.rst index 3bdcfcb825db..0f756076efcb 100644 --- a/docs/en/api-guides/memory-types.rst +++ b/docs/en/api-guides/memory-types.rst @@ -150,7 +150,9 @@ The ``DRAM_ATTR`` attribute can be used to force constants from DROM into the :r RTC Slow Memory ^^^^^^^^^^^^^^^ - Global and static variables used by code which runs from RTC memory must be placed into RTC Slow memory. For example :doc:`deep sleep ` variables can be placed here instead of RTC FAST memory, or code and variables accessed by the :doc:`/api-reference/system/ulp`. + .. only:: ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB + + Global and static variables used by code which runs from RTC memory must be placed into RTC Slow memory. For example :doc:`deep sleep ` variables can be placed here instead of RTC FAST memory, or code and variables accessed by the :doc:`/api-reference/system/ulp`. The attribute macro named ``RTC_NOINIT_ATTR`` can be used to place data into this type of memory. The values placed into this section keep their value after waking from deep sleep. @@ -170,8 +172,9 @@ The ``DRAM_ATTR`` attribute can be used to force constants from DROM into the :r On {IDF_TARGET_NAME} what was previously referred to as RTC memory has been renamed LP (low power) memory. You might see both terms being used interchangeably in IDF code, docs and the technical reference manual. + .. only:: ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB - The same region of RTC FAST memory can be accessed as both instruction and data memory. Code which has to run after wake-up from deep sleep mode has to be placed into RTC memory. Please check detailed description in :doc:`deep sleep ` documentation. + The same region of RTC FAST memory can be accessed as both instruction and data memory. Code which has to run after wake-up from deep sleep mode has to be placed into RTC memory. Please check detailed description in :doc:`deep sleep ` documentation. .. only:: esp32 diff --git a/docs/en/api-guides/performance/size.rst b/docs/en/api-guides/performance/size.rst index c48eb3309f6c..0e132de01295 100644 --- a/docs/en/api-guides/performance/size.rst +++ b/docs/en/api-guides/performance/size.rst @@ -18,10 +18,6 @@ To optimize both the firmware binary size and the memory usage, it is necessary Using the :ref:`idf.py` sub-commands ``size``, ``size-components``, and ``size-files`` provides a summary of memory used by the project: -.. note:: - - It is possible to add ``-DOUTPUT_FORMAT=csv`` or ``-DOUTPUT_FORMAT=json`` to get the output in CSV or JSON format. - Size Summary ``idf.py size`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/en/api-guides/startup.rst b/docs/en/api-guides/startup.rst index a9196363aefc..35ebc5b14e8b 100644 --- a/docs/en/api-guides/startup.rst +++ b/docs/en/api-guides/startup.rst @@ -32,7 +32,7 @@ Startup code called from the reset vector determines the boot mode by checking ` .. list:: - :SOC_RTC_MEM_SUPPORTED: #. Reset from deep sleep: if the value in ``RTC_CNTL_STORE6_REG`` is non-zero, and CRC value of RTC memory in ``RTC_CNTL_STORE7_REG`` is valid, use ``RTC_CNTL_STORE6_REG`` as an entry point address and jump immediately to it. If ``RTC_CNTL_STORE6_REG`` is zero, or ``RTC_CNTL_STORE7_REG`` contains invalid CRC, or once the code called via ``RTC_CNTL_STORE6_REG`` returns, proceed with boot as if it was a power-on reset. **Note**: to run customized code at this point, a deep sleep stub mechanism is provided. Please see :doc:`deep sleep ` documentation for this. + :ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB: #. Reset from deep sleep: if the value in ``RTC_CNTL_STORE6_REG`` is non-zero, and CRC value of RTC memory in ``RTC_CNTL_STORE7_REG`` is valid, use ``RTC_CNTL_STORE6_REG`` as an entry point address and jump immediately to it. If ``RTC_CNTL_STORE6_REG`` is zero, or ``RTC_CNTL_STORE7_REG`` contains invalid CRC, or once the code called via ``RTC_CNTL_STORE6_REG`` returns, proceed with boot as if it was a power-on reset. **Note**: to run customized code at this point, a deep sleep stub mechanism is provided. Please see :doc:`deep sleep ` documentation for this. #. For power-on reset, software SoC reset, and watchdog SoC reset: check the ``GPIO_STRAP_REG`` register if a custom boot mode (such as UART Download Mode) is requested. If this is the case, this custom loader mode is executed from ROM. Otherwise, proceed with boot as if it was due to software CPU reset. Consult {IDF_TARGET_NAME} datasheet for a description of SoC boot modes and how to execute them. diff --git a/docs/en/api-reference/bluetooth/classic_bt.rst b/docs/en/api-reference/bluetooth/classic_bt.rst index a1f861bb5070..0fc595fb7954 100644 --- a/docs/en/api-reference/bluetooth/classic_bt.rst +++ b/docs/en/api-reference/bluetooth/classic_bt.rst @@ -1,8 +1,8 @@ -Classic Bluetooth® -================== +Bluetooth® Classic +=================== .. toctree:: - :caption: Classic Bluetooth + :caption: Bluetooth Classic Bluetooth GAP Bluetooth A2DP diff --git a/docs/en/api-reference/network/esp_eth.rst b/docs/en/api-reference/network/esp_eth.rst index 39bf96cdb0d8..124a20f63d96 100644 --- a/docs/en/api-reference/network/esp_eth.rst +++ b/docs/en/api-reference/network/esp_eth.rst @@ -191,7 +191,7 @@ The Ethernet driver is composed of two parts: MAC and PHY. .. only:: not SOC_EMAC_USE_MULTI_IO_MUX .. note:: - Signals used in the data plane are fixed to specific GPIOs via IO_MUX, they can not be modified to other GPIOs. Signals used in the control plane can be routed to any free GPIOs via Matrix. Please refer to :doc:`ESP32-Ethernet-Kit <../../hw-reference/esp32/get-started-ethernet-kit>` for hardware design example. + Signals used in the data plane are fixed to specific GPIOs via IO_MUX, they can not be modified to other GPIOs. Signals used in the control plane can be routed to any free GPIOs via Matrix. Please refer to `ESP32-Ethernet-Kit `_ for hardware design example. .. only:: SOC_EMAC_USE_MULTI_IO_MUX diff --git a/docs/en/api-reference/peripherals/adc_calibration.rst b/docs/en/api-reference/peripherals/adc_calibration.rst index cc639012d40c..831805e6643b 100644 --- a/docs/en/api-reference/peripherals/adc_calibration.rst +++ b/docs/en/api-reference/peripherals/adc_calibration.rst @@ -6,7 +6,7 @@ Analog to Digital Converter (ADC) Calibration Driver Introduction ------------ -In {IDF_TARGET_NAME}, the digital-to-analog converter (ADC) compares the input analog voltage to the reference, and determines each bit of the output digital result. By design, the ADC reference voltage for {IDF_TARGET_NAME} is 1100 mV. However, the true reference voltage can range from 1000 mV to 1200 mV among different chips. This guide introduces the ADC calibration driver to minimize the effect of different reference voltages, and get more accurate output results. +In {IDF_TARGET_NAME}, the analog-to-digital converter (ADC) compares the input analog voltage to the reference, and determines each bit of the output digital result. By design, the ADC reference voltage for {IDF_TARGET_NAME} is 1100 mV. However, the true reference voltage can range from 1000 mV to 1200 mV among different chips. This guide introduces the ADC calibration driver to minimize the effect of different reference voltages, and get more accurate output results. Functional Overview diff --git a/docs/en/api-reference/peripherals/adc_oneshot.rst b/docs/en/api-reference/peripherals/adc_oneshot.rst index bec0bee1862f..cd197000dad6 100644 --- a/docs/en/api-reference/peripherals/adc_oneshot.rst +++ b/docs/en/api-reference/peripherals/adc_oneshot.rst @@ -142,7 +142,7 @@ where: * - Vmax - Maximum measurable input analog voltage, this is related to the ADC attenuation, please refer to `TRM <{IDF_TARGET_TRM_EN_URL}>`__ > ``On-Chip Sensor and Analog Signal Processing``. * - Dmax - - Maximum of the output ADC raw digital reading result, which is 2^bitwidth, where bitwidth is the :cpp:member::`adc_oneshot_chan_cfg_t:bitwidth` configured before. + - Maximum of the output ADC raw digital reading result, which is 2^bitwidth, where bitwidth is the :cpp:member:`adc_oneshot_chan_cfg_t::bitwidth` configured before. To do further calibration to convert the ADC raw result to voltage in mV, please refer to calibration doc :doc:`adc_calibration`. diff --git a/docs/en/api-reference/peripherals/gptimer.rst b/docs/en/api-reference/peripherals/gptimer.rst index b836a05551cc..844b3b032158 100644 --- a/docs/en/api-reference/peripherals/gptimer.rst +++ b/docs/en/api-reference/peripherals/gptimer.rst @@ -43,14 +43,11 @@ A GPTimer instance is represented by :cpp:type:`gptimer_handle_t`. The driver be To install a timer instance, there is a configuration structure that needs to be given in advance: :cpp:type:`gptimer_config_t`: - :cpp:member:`gptimer_config_t::clk_src` selects the source clock for the timer. The available clocks are listed in :cpp:type:`gptimer_clock_source_t`, you can only pick one of them. For the effect on power consumption of different clock source, please refer to Section :ref:`gptimer-power-management`. - - :cpp:member:`gptimer_config_t::direction` sets the counting direction of the timer, supported directions are listed in :cpp:type:`gptimer_count_direction_t`, you can only pick one of them. - - :cpp:member:`gptimer_config_t::resolution_hz` sets the resolution of the internal counter. Each count step is equivalent to **1 / resolution_hz** seconds. - -- :cpp:member:`gptimer_config::intr_priority` sets the priority of the timer interrupt. If it is set to ``0``, the driver will allocate an interrupt with a default priority. Otherwise, the driver will use the given priority. - -- Optional :cpp:member:`gptimer_config_t::intr_shared` sets whether or not mark the timer interrupt source as a shared one. For the pros/cons of a shared interrupt, you can refer to :doc:`Interrupt Handling <../../api-reference/system/intr_alloc>`. +- :cpp:member:`gptimer_config::intr_priority` sets the priority of the timer interrupt. If it is set to ``0``, the driver will allocate an interrupt with a default priority. Otherwise, the driver will use the given priority. +- :cpp:member:`gptimer_config_t::backup_before_sleep` enables the backup of the GPTimer registers before entering sleep mode. This option implies an balance between power consumption and memory usage. If the power consumption is not a concern, you can disable this option to save memory. But if you want to save more power, you should enable this option to backup the GPTimer registers before entering sleep mode, and restore them after waking up. This feature depends on specific hardware module, if you enable this flag on an unsupported chip, you will get an error message like ``register back up is not supported``. +- Optional :cpp:member:`gptimer_config_t::intr_shared` sets whether or not mark the timer interrupt source as a shared one. For the pros/cons of a shared interrupt, you can refer to :doc:`Interrupt Handling <../../api-reference/system/intr_alloc>`. With all the above configurations set in the structure, the structure can be passed to :cpp:func:`gptimer_new_timer` which will instantiate the timer instance and return a handle of the timer. @@ -261,7 +258,7 @@ Alarm value can be updated dynamically inside the ISR handler callback, by chang }; ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue)); ESP_ERROR_CHECK(gptimer_enable(gptimer)); - ESP_ERROR_CHECK(gptimer_start(gptimer, &alarm_config)); + ESP_ERROR_CHECK(gptimer_start(gptimer)); .. only:: SOC_ETM_SUPPORTED and SOC_TIMER_SUPPORT_ETM @@ -284,9 +281,13 @@ Alarm value can be updated dynamically inside the ISR handler callback, by chang Power Management ^^^^^^^^^^^^^^^^ -There are some power management strategies, which might turn off or change the frequency of GPTimer's source clock to save power consumption. For example, during DFS, APB clock will be scaled down. If light-sleep is also enabled, PLL and XTAL clocks will be powered off. Both of them can result in an inaccurate time keeping. +When power management is enabled, i.e., :ref:`CONFIG_PM_ENABLE` is on, the system may adjust or disable the clock source before going to sleep. As a result, the time keeping will be inaccurate. + +The driver can prevent the above issue by creating a power management lock. The lock type is set based on different clock sources. The driver will acquire the lock in :cpp:func:`gptimer_enable`, and release it in :cpp:func:`gptimer_disable`. So that the timer can work correctly in between these two functions, because the clock source won't be disabled or adjusted its frequency during this time. + +.. only:: SOC_TIMER_SUPPORT_SLEEP_RETENTION -The driver can prevent the above situation from happening by creating different power management lock according to different clock source. The driver increases the reference count of that power management lock in the :cpp:func:`gptimer_enable` and decrease it in the :cpp:func:`gptimer_disable`. So we can ensure the clock source is stable between :cpp:func:`gptimer_enable` and :cpp:func:`gptimer_disable`. + Besides the potential changes to the clock source, when the power management is enabled, the system can also power down a domain where GPTimer register located. To ensure the GPTimer driver can continue work after sleep, we can either backup the GPTimer registers to the RAM, or just refuse to power down. You can choose what to do in :cpp:member:`gptimer_config_t::backup_before_sleep`. It's a balance between power saving and memory consumption. Set it based on your application requirements. .. _gptimer-iram-safe: diff --git a/docs/en/api-reference/peripherals/lcd/dsi_lcd.rst b/docs/en/api-reference/peripherals/lcd/dsi_lcd.rst index 4cb6d7d58f6a..a5fb8e866804 100644 --- a/docs/en/api-reference/peripherals/lcd/dsi_lcd.rst +++ b/docs/en/api-reference/peripherals/lcd/dsi_lcd.rst @@ -61,7 +61,7 @@ MIPI DSI Interfaced LCD - :cpp:member:`esp_lcd_dpi_panel_config_t::dpi_clock_freq_mhz` sets the DPI clock frequency in MHz. Higher pixel clock frequency results in higher refresh rate, but may cause flickering if the DMA bandwidth is not sufficient or the LCD controller chip does not support high pixel clock frequency. - :cpp:member:`esp_lcd_dpi_panel_config_t::pixel_format` sets the pixel format of the pixel data. The available pixel formats are listed in :cpp:type:`lcd_color_rgb_pixel_format_t`. We usually use **RGB888** for MIPI LCD to get the best color depth. - :cpp:member:`esp_lcd_dpi_panel_config_t::video_timing` sets the LCD panel specific timing parameters. All required parameters are listed in the :cpp:type:`esp_lcd_video_timing_t`, including the LCD resolution and blanking porches. Please fill them according to the datasheet of your LCD. - - :cpp:member:`esp_lcd_dpi_panel_config_t::extra_flags::use_dma2d` sets whether to use the DMA2D peripheral to copy the user data to the frame buffer, asynchronously. + - :cpp:member:`esp_lcd_dpi_panel_config_t::extra_dpi_panel_flags::use_dma2d` sets whether to use the 2D DMA peripheral to copy the user data to the frame buffer, asynchronously. .. code-block:: c diff --git a/docs/en/api-reference/peripherals/mcpwm.rst b/docs/en/api-reference/peripherals/mcpwm.rst index 90c9305c1dac..e648eb83e6c5 100644 --- a/docs/en/api-reference/peripherals/mcpwm.rst +++ b/docs/en/api-reference/peripherals/mcpwm.rst @@ -204,11 +204,11 @@ Next, to allocate a capture channel, you can call the :cpp:func:`mcpwm_new_captu - :cpp:member:`mcpwm_capture_channel_config_t::intr_priority` sets the priority of the interrupt. If it is set to ``0``, the driver will allocate an interrupt with a default priority. Otherwise, the driver will use the given priority. - :cpp:member:`mcpwm_capture_channel_config_t::gpio_num` sets the GPIO number used by the capture channel. - :cpp:member:`mcpwm_capture_channel_config_t::prescale` sets the prescaler of the input signal. -- :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::pos_edge` and :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::neg_edge` set whether to capture on the positive and/or falling edge of the input signal. -- :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::pull_up` and :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::pull_down` set whether to pull up and/or pull down the GPIO internally. -- :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::invert_cap_signal` sets whether to invert the capture signal. -- :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::io_loop_back` sets whether to enable the Loop-back mode. It is for debugging purposes only. It enables both the GPIO's input and output ability through the GPIO matrix peripheral. -- :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::keep_io_conf_at_exit` sets whether to keep the GPIO configuration when the capture channel is deleted. +- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pos_edge` and :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::neg_edge` set whether to capture on the positive and/or falling edge of the input signal. +- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_up` and :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_down` set whether to pull up and/or pull down the GPIO internally. +- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::invert_cap_signal` sets whether to invert the capture signal. +- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::io_loop_back` sets whether to enable the Loop-back mode. It is for debugging purposes only. It enables both the GPIO's input and output ability through the GPIO matrix peripheral. +- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::keep_io_conf_at_exit` sets whether to keep the GPIO configuration when the capture channel is deleted. The :cpp:func:`mcpwm_new_capture_channel` will return a pointer to the allocated capture channel object if the allocation succeeds. Otherwise, it will return an error code. Specifically, when there is no free capture channel left in the capture timer, this function will return the :c:macro:`ESP_ERR_NOT_FOUND` error. diff --git a/docs/en/api-reference/peripherals/rmt.rst b/docs/en/api-reference/peripherals/rmt.rst index fe32e4242d10..1a418f9db3a1 100644 --- a/docs/en/api-reference/peripherals/rmt.rst +++ b/docs/en/api-reference/peripherals/rmt.rst @@ -219,7 +219,7 @@ The RX-complete event data is defined in :cpp:type:`rmt_rx_done_event_data_t`: - :cpp:member:`rmt_rx_done_event_data_t::received_symbols` points to the received RMT symbols. These symbols are saved in the ``buffer`` parameter of the :cpp:func:`rmt_receive` function. Users should not free this receive buffer before the callback returns. If you also enabled the partial receive feature, then the user buffer will be used as a "second level buffer", where its content can be overwritten by data comes in afterwards. In this case, you should copy the received data to another place if you want to keep it or process it later. - :cpp:member:`rmt_rx_done_event_data_t::num_symbols` indicates the number of received RMT symbols. This value is not larger than the ``buffer_size`` parameter of :cpp:func:`rmt_receive` function. If the ``buffer_size`` is not sufficient to accommodate all the received RMT symbols, the driver only keeps the maximum number of symbols that the buffer can hold, and excess symbols are discarded or ignored. -- :cpp:member:`rmt_rx_done_event_data_t::is_last` indicates whether the current received buffer is the last one in the transaction. This is useful when you enable the partial reception feature by :cpp:member:`rmt_receive_config_t::extra_flags::en_partial_rx`. +- :cpp:member:`rmt_rx_done_event_data_t::is_last` indicates whether the current received buffer is the last one in the transaction. This is useful when you enable the partial reception feature by :cpp:member:`rmt_receive_config_t::extra_rmt_receive_flags::en_partial_rx`. .. _rmt-enable-and-disable-channel: @@ -331,7 +331,7 @@ As also discussed in the :ref:`rmt-enable-and-disable-channel`, calling :cpp:fun - :cpp:member:`rmt_receive_config_t::signal_range_min_ns` specifies the minimal valid pulse duration in either high or low logic levels. A pulse width that is smaller than this value is treated as a glitch, and ignored by the hardware. - :cpp:member:`rmt_receive_config_t::signal_range_max_ns` specifies the maximum valid pulse duration in either high or low logic levels. A pulse width that is bigger than this value is treated as **Stop Signal**, and the receiver generates receive-complete event immediately. -- If the incoming packet is long, that they cannot be stored in the user buffer at once, you can enable the partial reception feature by setting :cpp:member:`rmt_receive_config_t::extra_flags::en_partial_rx` to ``true``. In this case, the driver invokes :cpp:member:`rmt_rx_event_callbacks_t::on_recv_done` callback multiple times during one transaction, when the user buffer is **almost full**. You can check the value of :cpp:member::`rmt_rx_done_event_data_t::is_last` to know if the transaction is about to finish. Please note this features is not supported on all ESP series chips because it relies on hardware abilities like "ping-pong receive" or "DMA receive". +- If the incoming packet is long, that they cannot be stored in the user buffer at once, you can enable the partial reception feature by setting :cpp:member:`rmt_receive_config_t::extra_rmt_receive_flags::en_partial_rx` to ``true``. In this case, the driver invokes :cpp:member:`rmt_rx_event_callbacks_t::on_recv_done` callback multiple times during one transaction, when the user buffer is **almost full**. You can check the value of :cpp:member::`rmt_rx_done_event_data_t::is_last` to know if the transaction is about to finish. Please note this features is not supported on all ESP series chips because it relies on hardware abilities like "ping-pong receive" or "DMA receive". The RMT receiver starts the RX machine after the user calls :cpp:func:`rmt_receive` with the provided configuration above. Note that, this configuration is transaction specific, which means, to start a new round of reception, the user needs to set the :cpp:type:`rmt_receive_config_t` again. The receiver saves the incoming signals into its internal memory block or DMA buffer, in the format of :cpp:type:`rmt_symbol_word_t`. diff --git a/docs/en/api-reference/peripherals/usb_device.rst b/docs/en/api-reference/peripherals/usb_device.rst index a41e85ffa8b0..696ae8350942 100644 --- a/docs/en/api-reference/peripherals/usb_device.rst +++ b/docs/en/api-reference/peripherals/usb_device.rst @@ -5,9 +5,9 @@ USB Device Stack {IDF_TARGET_USB_DP_GPIO_NUM:default="20"} {IDF_TARGET_USB_DM_GPIO_NUM:default="19"} -{IDF_TARGET_USB_EP_NUM:default="6"} -{IDF_TARGET_USB_EP_NUM_INOUT:default="5"} -{IDF_TARGET_USB_EP_NUM_IN:default="1"} +{IDF_TARGET_USB_EP_NUM: default="6", esp32p4="15"} +{IDF_TARGET_USB_EP_NUM_INOUT:default="5", esp32p4="8"} +{IDF_TARGET_USB_EP_NUM_IN:default="1", esp32p4="7"} Overview -------- @@ -34,16 +34,24 @@ Features Hardware Connection ------------------- -The {IDF_TARGET_NAME} routes the USB D+ and D- signals to GPIOs {IDF_TARGET_USB_DP_GPIO_NUM} and {IDF_TARGET_USB_DM_GPIO_NUM} respectively. For USB device functionality, these GPIOs should be connected to the bus in some way (e.g., via a Micro-B port, USB-C port, or directly to standard-A plug). +.. only:: esp32s2 or esp32s3 + + The {IDF_TARGET_NAME} routes the USB D+ and D- signals to GPIOs {IDF_TARGET_USB_DP_GPIO_NUM} and {IDF_TARGET_USB_DM_GPIO_NUM} respectively. For USB device functionality, these GPIOs should be connected to the bus in some way (e.g., via a Micro-B port, USB-C port, or directly to standard-A plug). + +.. only:: esp32p4 + + The {IDF_TARGET_NAME} routes the USB D+ and D- signals to their dedicated pins. For USB device functionality, these pins should be connected to the bus in some way (e.g., via a Micro-B port, USB-C port, or directly to standard-A plug). .. figure:: ../../../_static/usb-board-connection.png :align: center :alt: Connection of an USB GPIOs directly to a USB standard-A plug :figclass: align-center -.. note:: +.. only:: esp32s2 or esp32s3 - If you are using an {IDF_TARGET_NAME} development board with two USB ports, the port labeled "USB" will already be connected to the D+ and D- GPIOs. + .. note:: + + If you are using an {IDF_TARGET_NAME} development board with two USB ports, the port labeled "USB" will already be connected to the D+ and D- GPIOs. .. note:: @@ -95,15 +103,17 @@ Full-speed devices should initialize the following field to provide their config - :cpp:member:`configuration_descriptor` -High-speed devices should initialize the following fields to provide configuration descriptors at each speed: +.. only:: esp32p4 -- :cpp:member:`fs_configuration_descriptor` -- :cpp:member:`hs_configuration_descriptor` -- :cpp:member:`qualifier_descriptor` + High-speed devices should initialize the following fields to provide configuration descriptors at each speed: -.. note:: + - :cpp:member:`fs_configuration_descriptor` + - :cpp:member:`hs_configuration_descriptor` + - :cpp:member:`qualifier_descriptor` + + .. note:: - When Device Stack supports high-speed, both :cpp:member:`fs_configuration_descriptor` and :cpp:member:`hs_configuration_descriptor` should be present to comply with usb2.0 specification. + Both :cpp:member:`fs_configuration_descriptor` and :cpp:member:`hs_configuration_descriptor` must be present to comply with USB 2.0 specification. The Device Stack will instantiate a USB device based on the descriptors provided in the fields described above when :cpp:func:`tinyusb_driver_install` is called. diff --git a/docs/en/api-reference/peripherals/usb_host.rst b/docs/en/api-reference/peripherals/usb_host.rst index ea30d2f507da..63b98e3790a6 100644 --- a/docs/en/api-reference/peripherals/usb_host.rst +++ b/docs/en/api-reference/peripherals/usb_host.rst @@ -25,18 +25,26 @@ Features & Limitations The Host Library has the following features: -- Supports Full Speed (FS) and Low Speed (LS) Devices. -- Supports all four transfer types, i.e., Control, Bulk, Interrupt, and Isochronous. -- Allows multiple class drivers to run simultaneously, i.e., multiple clients of the Host Library. -- A single device can be used by multiple clients simultaneously, e.g., composite devices. -- The Host Library itself and the underlying Host Stack does not internally instantiate any OS tasks. The number of tasks is entirely controlled by how the Host Library interface is used. However, a general rule of thumb regarding the number of tasks is ``(the number of host class drivers running + 1)``. +.. list:: + + :esp32s2 or esp32s3: - Supports Full Speed (FS) and Low Speed (LS) Devices. + :esp32p4: - Supports High Speed (HS), Full Speed (FS) and Low Speed (LS) Devices. + - Supports all four transfer types: Control, Bulk, Interrupt, and Isochronous. + :esp32p4: - Supports High-Bandwidth Isochronous endpoints. + - Allows multiple class drivers to run simultaneously, i.e., multiple clients of the Host Library. + - A single device can be used by multiple clients simultaneously, e.g., composite devices. + - The Host Library itself and the underlying Host Stack does not internally instantiate any OS tasks. The number of tasks is entirely controlled by how the Host Library interface is used. However, a general rule of thumb regarding the number of tasks is ``(the number of host class drivers running + 1)``. Currently, the Host Library and the underlying Host Stack has the following limitations: -- Only supports a single device, but the Host Library's API is designed for multiple device support. -- Only supports Asynchronous transfers. -- Only supports using the first configuration found. Changing to other configurations is not supported yet. -- Transfer timeouts are not supported yet. +.. list:: + + - Only supports a single device, but the Host Library's API is designed for multiple device support. + - Only supports Asynchronous transfers. + - Only supports using one configuration. Changing to other configurations after enumeration is not supported yet. + - Transfer timeouts are not supported yet. + :esp32p4: - {IDF_TARGET_NAME} contains two USB-OTG peripherals USB 2.0 OTG High-Speed and USB 2.0 OTG Full-Speed. Only the High-Speed instance is supported now. + :esp32p4: - {IDF_TARGET_NAME} cannot enumerate Low-Speed devices yet. .. -------------------------------------------------- Architecture ----------------------------------------------------- @@ -89,7 +97,7 @@ Therefore, in addition to the client tasks, the Host Library also requires a tas Devices ^^^^^^^ -The Host Library shields clients from the details of device handling, encompassing details such as connection, memory allocation, and enumeration. The clients are provided only with a list of already connected and enumerated devices to choose from. During enumeration, each device is automatically configured to use the first configuration found, namely, the first configuration descriptor returned on a Get Configuration Descriptor request. For most standard devices, the first configuration will have a ``bConfigurationValue`` of ``1``. +The Host Library shields clients from the details of device handling, encompassing details such as connection, memory allocation, and enumeration. The clients are provided only with a list of already connected and enumerated devices to choose from. By default during enumeration, each device is automatically configured to use the first configuration found, namely, the first configuration descriptor returned on a Get Configuration Descriptor request. For most standard devices, the first configuration will have a ``bConfigurationValue`` of ``1``. If option :ref:`CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK` is enabled, a different ``bConfigurationValue`` can be selected, see `Multiple configuration Support`_ for more details. It is possible for two or more clients to simultaneously communicate with the same device as long as they are not communicating to the same interface. However, multiple clients can simultaneously communicate with the same device's default endpoint (i.e., EP0), which will result in their control transfers being serialized. diff --git a/docs/en/api-reference/peripherals/usb_host/usb_host_notes_arch.rst b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_arch.rst index 1770120b0001..ac6e7ff0087d 100644 --- a/docs/en/api-reference/peripherals/usb_host/usb_host_notes_arch.rst +++ b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_arch.rst @@ -37,7 +37,7 @@ The layers of the Host Stack are described in the following table. The layers ar - ``usb_host.h``, ``usb_host.c`` - The USB Host Library layer is the lowest public API layer of the Host Stack and presents the concept of USB Host Clients. The abstraction of clients allows for multiple class drivers to coexist simultaneously (where each class roughly maps to a single client) and also acts as a mechanism for division of labor (where each client is responsible for its own processing and event handling). * - Host Class Drivers - - See the `ESP-IDF Extra Components repository `_ or the USB Host examples in ESP-IDF (via :example:`peripherals/usb/host`). + - See the `ESP-USB repository `_ or the USB Host examples in ESP-IDF (via :example:`peripherals/usb/host`). - The Host Class Drivers implement the host side of a particular device class (e.g., CDC, MSC, HID). The exposed API is specific to each class driver. Layer Dependencies diff --git a/docs/en/api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst index 3415e02007f0..e54dbd8c61f7 100644 --- a/docs/en/api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst +++ b/docs/en/api-reference/peripherals/usb_host/usb_host_notes_dwc_otg.rst @@ -89,26 +89,51 @@ Hardware Configuration The DWC_OTG IP is configurable. The notable Host related configurations of the {IDF_TARGET_NAME}'s DWC_OTG are listed below: -.. list-table:: {IDF_TARGET_NAME}'s DWC_OTG Configuration - :widths: 70 30 - :header-rows: 1 - - * - Description - - Configuration - * - Host and Device Mode support with OTG - - ``OTG_MODE = 0`` - * - Full Speed (FS) and Low Speed (LS) support - - ``OTG_FSPHY_INTERFACE = 1``, ``OTG_HSPHY_INTERFACE = 0`` - * - Internal DMA controller with Scatter/Gather DMA - - ``OTG_ARCHITECTURE = 2``, ``OTG_EN_DESC_DMA = 1`` - * - FS Hubs are supported but HS Hub are not (i.e., split transfers not supported) - - ``OTG_SINGLE_POINT = 0`` - * - 8 Host Mode channels - - ``OTG_NUM_HOST_CHAN = 8`` - * - All transfer types supported, including ISOC and INTR OUT transfers - - ``OTG_EN_PERIO_HOST = 1`` - * - Dynamically sized Data FIFO of 1024 bytes (256 lines) - - ``OTG_DFIFO_DYNAMIC = 1``, ``OTG_DFIFO_DEPTH = 256`` +.. only:: esp32p4 + + .. list-table:: {IDF_TARGET_NAME}'s DWC_OTG Configuration + :widths: 70 30 + :header-rows: 1 + + * - Description + - Configuration + * - Host and Device Mode support with OTG + - ``OTG_MODE = 0`` + * - High Speed (HS), Full Speed (FS) and Low Speed (LS) support + - ``OTG_FSPHY_INTERFACE = 2``, ``OTG_HSPHY_INTERFACE = 3`` + * - Internal DMA controller with Scatter/Gather DMA + - ``OTG_ARCHITECTURE = 2``, ``OTG_EN_DESC_DMA = 1`` + * - Split transfers not supported + - ``OTG_SINGLE_POINT = 1`` + * - 16 Host Mode channels + - ``OTG_NUM_HOST_CHAN = 16`` + * - All transfer types supported, including ISOC and INTR OUT transfers + - ``OTG_EN_PERIO_HOST = 1`` + * - Dynamically sized Data FIFO of 4096 bytes (1024 lines) + - ``OTG_DFIFO_DYNAMIC = 1``, ``OTG_DFIFO_DEPTH = 1024`` + * - Only 4 periodic and 4 non-periodic transactions per microframe + - ``OTG_NPERIO_TX_QUEUE_DEPTH = 4``, ``OTG_PERIO_TX_QUEUE_DEPTH = 4`` + +.. only:: esp32s2 or esp32s3 + + .. list-table:: {IDF_TARGET_NAME}'s DWC_OTG Configuration + :widths: 70 30 + :header-rows: 1 + + * - Description + - Configuration + * - Host and Device Mode support with OTG + - ``OTG_MODE = 0`` + * - Full Speed (FS) and Low Speed (LS) support + - ``OTG_FSPHY_INTERFACE = 1``, ``OTG_HSPHY_INTERFACE = 0`` + * - Internal DMA controller with Scatter/Gather DMA + - ``OTG_ARCHITECTURE = 2``, ``OTG_EN_DESC_DMA = 1`` + * - 8 Host Mode channels + - ``OTG_NUM_HOST_CHAN = 8`` + * - All transfer types supported, including ISOC and INTR OUT transfers + - ``OTG_EN_PERIO_HOST = 1`` + * - Dynamically sized Data FIFO of 1024 bytes (256 lines) + - ``OTG_DFIFO_DYNAMIC = 1``, ``OTG_DFIFO_DEPTH = 256`` Scatter/Gather DMA Transfer --------------------------- diff --git a/docs/en/api-reference/storage/nvs_encryption.rst b/docs/en/api-reference/storage/nvs_encryption.rst index ad6f9cc474ba..d4938e3dec7d 100644 --- a/docs/en/api-reference/storage/nvs_encryption.rst +++ b/docs/en/api-reference/storage/nvs_encryption.rst @@ -35,7 +35,7 @@ For using NVS encryption using this scheme, the partition table must contain the NVS Key Partition ^^^^^^^^^^^^^^^^^ -An application requiring NVS encryption support (using the Flash Encryption-based scheme) needs to be compiled with a key-partition of the type ``data`` and subtype ``key``. This partition should be marked as ``encrypted`` and its size should be the minimum partition size (4 KB). Refer to :doc:`../../api-guides/partition-tables` for more details. Two additional partition tables which contain the :ref:`nvs_encr_key_partition` are provided under the partition table option (``menuconfig`` > ``Partition Table``). They can be directly used for NVS encryption. The structure of these partitions is depicted below: +An application requiring NVS encryption support (using the Flash Encryption-based scheme) needs to be compiled with a key-partition of the type ``data`` and subtype ``nvs_keys``. This partition should be marked as ``encrypted`` and its size should be the minimum partition size (4 KB). Refer to :doc:`../../api-guides/partition-tables` for more details. Two additional partition tables which contain the :ref:`nvs_encr_key_partition` are provided under the partition table option (``menuconfig`` > ``Partition Table``). They can be directly used for NVS encryption. The structure of these partitions is depicted below: .. highlight:: none diff --git a/docs/en/api-reference/system/inc/power_management_esp32p4.rst b/docs/en/api-reference/system/inc/power_management_esp32p4.rst index 949099543fea..fb9a759f0c1e 100644 --- a/docs/en/api-reference/system/inc/power_management_esp32p4.rst +++ b/docs/en/api-reference/system/inc/power_management_esp32p4.rst @@ -1 +1,13 @@ -TO BE UPDATED IDF-7672 ++---------------+---------------------------------------+-------------------------------------+ +| Max CPU | Lock Acquisition | CPU and APB Frequencies | +| Frequency Set | | | ++---------------+---------------------------------------+-------------------------------------+ +| 360 | ``ESP_PM_CPU_FREQ_MAX`` acquired | | CPU: 360 MHz | +| | | | APB: 90 MHz | ++ +---------------------------------------+-------------------------------------+ +| | ``ESP_PM_APB_FREQ_MAX`` acquired, | | CPU: 90 MHz | +| | ``ESP_PM_CPU_FREQ_MAX`` not acquired | | APB: 90 MHz | ++ +---------------------------------------+-------------------------------------+ +| | None | Min values for both frequencies set | +| | | with :cpp:func:`esp_pm_configure` | ++---------------+---------------------------------------+-------------------------------------+ diff --git a/docs/en/api-reference/system/power_management.rst b/docs/en/api-reference/system/power_management.rst index 0d016aae2eeb..4d3d3766ce0a 100644 --- a/docs/en/api-reference/system/power_management.rst +++ b/docs/en/api-reference/system/power_management.rst @@ -55,7 +55,7 @@ Dynamic frequency scaling (DFS) and automatic Light-sleep can be enabled in an a Power Management Locks ---------------------- -{IDF_TARGET_MAX_CPU_FREQ: default="Not updated yet", esp32="80 MHz, 160 MHz, or 240 MHz", esp32s2="80 MHz, 160 MHz, or 240 MHz", esp32s3="80 MHz, 160 MHz, or 240 MHz", esp32c2="80 MHz or 120 MHz", esp32c3="80 MHz or 160 MHz", esp32c6="80 MHz or 160 MHz"} +{IDF_TARGET_MAX_CPU_FREQ: default="Not updated yet", esp32="80 MHz, 160 MHz, or 240 MHz", esp32s2="80 MHz, 160 MHz, or 240 MHz", esp32s3="80 MHz, 160 MHz, or 240 MHz", esp32c2="80 MHz or 120 MHz", esp32c3="80 MHz or 160 MHz", esp32c6="80 MHz or 160 MHz", esp32p4="360 MHz"} Applications have the ability to acquire/release locks in order to control the power management algorithm. When an application acquires a lock, the power management algorithm operation is restricted in a way described below. When the lock is released, such restrictions are removed. @@ -114,7 +114,7 @@ The following drivers hold the ``ESP_PM_APB_FREQ_MAX`` lock while the driver is - **SPI slave**: between calls to :cpp:func:`spi_slave_initialize` and :cpp:func:`spi_slave_free`. - **GPTimer**: between calls to :cpp:func:`gptimer_enable` and :cpp:func:`gptimer_disable`. - **Ethernet**: between calls to :cpp:func:`esp_eth_driver_install` and :cpp:func:`esp_eth_driver_uninstall`. - - **WiFi**: between calls to :cpp:func:`esp_wifi_start` and :cpp:func:`esp_wifi_stop`. If modem sleep is enabled, the lock will be released for the periods of time when radio is disabled. + :SOC_WIFI_SUPPORTED: - **WiFi**: between calls to :cpp:func:`esp_wifi_start` and :cpp:func:`esp_wifi_stop`. If modem sleep is enabled, the lock will be released for the periods of time when radio is disabled. :SOC_TWAI_SUPPORTED: - **TWAI**: between calls to :cpp:func:`twai_driver_install` and :cpp:func:`twai_driver_uninstall` (only when the clock source is set to :cpp:enumerator:`TWAI_CLK_SRC_APB`). :SOC_BT_SUPPORTED and esp32: - **Bluetooth**: between calls to :cpp:func:`esp_bt_controller_enable` and :cpp:func:`esp_bt_controller_disable`. If Bluetooth Modem-sleep is enabled, the ``ESP_PM_APB_FREQ_MAX`` lock will be released for the periods of time when radio is disabled. However the ``ESP_PM_NO_LIGHT_SLEEP`` lock will still be held, unless :ref:`CONFIG_BTDM_CTRL_LOW_POWER_CLOCK` option is set to "External 32kHz crystal". :SOC_BT_SUPPORTED and not esp32: - **Bluetooth**: between calls to :cpp:func:`esp_bt_controller_enable` and :cpp:func:`esp_bt_controller_disable`. If Bluetooth Modem-sleep is enabled, the ``ESP_PM_APB_FREQ_MAX`` lock will be released for the periods of time when radio is disabled. However the ``ESP_PM_NO_LIGHT_SLEEP`` lock will still be held. @@ -129,48 +129,53 @@ The following peripheral drivers are not aware of DFS yet. Applications need to :SOC_MCPWM_SUPPORTED: - MCPWM -Light-sleep Peripheral Power Down ---------------------------------- +.. only:: SOC_PM_SUPPORT_TOP_PD and not esp32c5 -.. only:: esp32c6 or esp32h2 + Light-sleep Peripheral Power Down + --------------------------------- - {IDF_TARGET_NAME} supports power-down peripherals during Light-sleep. + {IDF_TARGET_NAME} supports power-down peripherals during Light-sleep. - If :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` is enabled, when the driver initializes the peripheral, the driver will register the working register context of the peripheral to the sleep retention link. Before entering sleep, the ``REG_DMA`` peripheral reads the configuration in the sleep retention link, and back up the register context to memory according to the configuration. ``REG_DMA`` also restores context from memory to peripheral registers on wakeup. + If :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` is enabled, when the driver initializes the peripheral, the driver will register the working register context of the peripheral to the sleep retention link. Before entering sleep, the ``REG_DMA`` peripheral reads the configuration in the sleep retention link, and back up the register context to memory according to the configuration. ``REG_DMA`` also restores context from memory to peripheral registers on wakeup. - Currently ESP-IDF supports Light-sleep context retention for the following peripherals: - - INT_MTX - - TEE/APM - - IO_MUX / GPIO - - UART0 - - TIMG0 - - SPI0/1 - - SYSTIMER + Currently ESP-IDF supports Light-sleep context retention for the following peripherals: - The following peripherals are not yet supported: - - ETM - - TIMG1 - - ASSIST_DEBUG - - Trace - - Crypto: AES/ECC/HMAC/RSA/SHA/DS/XTA_AES/ECDSA - - SPI2 - - I2S - - PCNT - - USB-Serial-JTAG - - TWAI - - LEDC - - MCPWM - - RMT - - SARADC - - SDIO - - PARL_IO - - UART1 + .. list:: + + - INT_MTX + - TEE/APM + - IO_MUX / GPIO + - Timer Group 0 & Timer Group 1 + - SPI0/1 + - SYSTIMER + :SOC_RMT_SUPPORT_SLEEP_RETENTION: - RMT + :SOC_I2C_SUPPORT_SLEEP_RETENTION: - I2C + :SOC_UART_SUPPORT_SLEEP_RETENTION: - All UARTs + + The following peripherals are not yet supported: + + .. list:: + + - ETM + - ASSIST_DEBUG + - Trace + - Crypto: AES/ECC/HMAC/RSA/SHA/DS/XTA_AES/ECDSA + - SPI2 + - I2S + - PCNT + - USB-Serial-JTAG + - TWAI + - LEDC + - MCPWM + - SARADC + - SDIO + - PARL_IO - For peripherals that do not support Light-sleep context retention, if the Power management is enabled, the ``ESP_PM_NO_LIGHT_SLEEP`` lock should be held when the peripheral is working to avoid losing the working context of the peripheral when entering sleep. + For peripherals that do not support Light-sleep context retention, if the Power management is enabled, the ``ESP_PM_NO_LIGHT_SLEEP`` lock should be held when the peripheral is working to avoid losing the working context of the peripheral when entering sleep. - .. note:: + .. note:: - When the peripheral power domain is powered down during sleep, both the IO_MUX and GPIO modules are inactive, meaning the chip pins' state is not maintained by these modules. To preserve the state of an IO during sleep, it's essential to call :cpp:func:`gpio_hold_dis` and :cpp:func:`gpio_hold_en` before and after configuring the GPIO state. This action ensures that the IO configuration is latched and prevents the IO from becoming floating while in sleep mode. + When the peripheral power domain is powered down during sleep, both the IO_MUX and GPIO modules are inactive, meaning the chip pins' state is not maintained by these modules. To preserve the state of an IO during sleep, it's essential to call :cpp:func:`gpio_hold_dis` and :cpp:func:`gpio_hold_en` before and after configuring the GPIO state. This action ensures that the IO configuration is latched and prevents the IO from becoming floating while in sleep mode. API Reference diff --git a/docs/en/api-reference/system/sleep_modes.rst b/docs/en/api-reference/system/sleep_modes.rst index faf68f80d74e..abde7acc64ef 100644 --- a/docs/en/api-reference/system/sleep_modes.rst +++ b/docs/en/api-reference/system/sleep_modes.rst @@ -32,7 +32,7 @@ In Deep-sleep mode, the CPUs, most of the RAM, and all digital peripherals that :SOC_RTC_FAST_MEM_SUPPORTED: - RTC FAST memory :SOC_RTC_SLOW_MEM_SUPPORTED: - RTC SLOW memory -.. only:: SOC_BT_SUPPORTED +.. only:: SOC_WIFI_SUPPORTED and SOC_BT_SUPPORTED Wi-Fi/Bluetooth and Sleep Modes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ In Deep-sleep mode, the CPUs, most of the RAM, and all digital peripherals that If Wi-Fi/Bluetooth connections need to be maintained, enable Wi-Fi/Bluetooth Modem-sleep mode and automatic Light-sleep feature (see :doc:`Power Management APIs `). This allows the system to wake up from sleep automatically when required by the Wi-Fi/Bluetooth driver, thereby maintaining the connection. -.. only:: not SOC_BT_SUPPORTED +.. only:: SOC_WIFI_SUPPORTED and not SOC_BT_SUPPORTED Wi-Fi and Sleep Modes ^^^^^^^^^^^^^^^^^^^^^^^ @@ -227,7 +227,7 @@ RTC peripherals or RTC memories do not need to be powered on during sleep in thi - wake up if any of the selected pins is high (``ESP_EXT1_WAKEUP_ANY_HIGH``) - wake up if all the selected pins are low (``ESP_EXT1_WAKEUP_ALL_LOW``) - .. only:: esp32s2 or esp32s3 or esp32c6 or esp32h2 + .. only:: not esp32 - wake up if any of the selected pins is high (``ESP_EXT1_WAKEUP_ANY_HIGH``) - wake up if any of the selected pins is low (``ESP_EXT1_WAKEUP_ANY_LOW``) @@ -344,7 +344,7 @@ When {IDF_TARGET_NAME} receives UART input from external devices, it is often ne After waking-up from UART, you should send some extra data through the UART port in Active mode, so that the internal wakeup indication signal can be cleared. Otherwises, the next UART wake-up would trigger with two less rising edges than the configured threshold value. - .. only:: esp32c6 or esp32h2 + .. only:: SOC_PM_SUPPORT_TOP_PD and not esp32c5 .. note:: @@ -471,13 +471,12 @@ Application Example .. list:: - - :example:`protocols/sntp`: the implementation of basic functionality of Deep-sleep, where ESP module is periodically waken up to retrieve time from NTP server. - - :example:`wifi/power_save`: the usage of Wi-Fi Modem-sleep mode and automatic Light-sleep feature to maintain Wi-Fi connections. - :SOC_BT_SUPPORTED: - :example:`bluetooth/nimble/power_save`: the usage of Bluetooth Modem-sleep mode and automatic Light-sleep feature to maintain Bluetooth connections. - :SOC_ULP_SUPPORTED: - :example:`system/deep_sleep`: the usage of various Deep-sleep wakeup triggers and ULP coprocessor programming. - :not SOC_ULP_SUPPORTED: - :example:`system/deep_sleep`: the usage of Deep-sleep wakeup triggered by various sources supported by the chip (RTC Timer, GPIO, EXT0, EXT1, Touch Sensor, etc.). - - :example:`system/light_sleep`: the usage of Light-sleep wakeup triggered by various sources supported by the chip (Timer, GPIO, Touch Sensor, etc.). - + - :example:`protocols/sntp` demonstrates the implementation of basic functionality of Deep-sleep, where ESP module is periodically waken up to retrieve time from NTP server. + :SOC_WIFI_SUPPORTED: - :example:`wifi/power_save` demonstrates the usage of Wi-Fi Modem-sleep mode and automatic Light-sleep feature to maintain Wi-Fi connections. + :SOC_BT_SUPPORTED: - :example:`bluetooth/nimble/power_save` demonstrates the usage of Bluetooth Modem-sleep mode and automatic Light-sleep feature to maintain Bluetooth connections. + :SOC_ULP_SUPPORTED: - :example:`system/deep_sleep` demonstrates the usage of various Deep-sleep wakeup triggers and ULP coprocessor programming. + :not SOC_ULP_SUPPORTED: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer, GPIOs, EXT0, EXT1, the touch sensor, supported by {IDF_TARGET_NAME}. + - :example:`system/light_sleep` demonstrates the usage of Light-sleep wakeup triggered by various sources, such as the timer, GPIOs, the touch sensor, supported by {IDF_TARGET_NAME}. API Reference ------------- diff --git a/docs/en/get-started/index.rst b/docs/en/get-started/index.rst index 8b3071c787a7..bdd74ddf899f 100644 --- a/docs/en/get-started/index.rst +++ b/docs/en/get-started/index.rst @@ -107,13 +107,13 @@ If you have one of {IDF_TARGET_NAME} official development boards listed below, y .. toctree:: :maxdepth: 1 - ESP32-DevKitC <../hw-reference/esp32/get-started-devkitc> - ESP-WROVER-KIT <../hw-reference/esp32/get-started-wrover-kit> - ESP32-PICO-KIT <../hw-reference/esp32/get-started-pico-kit> - ESP32-Ethernet-Kit <../hw-reference/esp32/get-started-ethernet-kit> + ESP32-DevKitC + ESP-WROVER-KIT + ESP32-PICO-KIT + ESP32-Ethernet-Kit ESP32-DevKit-S(-R) <../hw-reference/esp32/user-guide-devkits-r-v1.1> - ESP32-PICO-KIT-1 <../hw-reference/esp32/get-started-pico-kit-1> - ESP32-PICO-DevKitM-2 <../hw-reference/esp32/get-started-pico-devkitm-2> + ESP32-PICO-KIT-1 + ESP32-PICO-DevKitM-2 ESP32-DevKitM-1 <../hw-reference/esp32/user-guide-devkitm-1> .. only:: esp32s2 @@ -124,7 +124,7 @@ If you have one of {IDF_TARGET_NAME} official development boards listed below, y ESP32-S2-Saola-1 <../hw-reference/esp32s2/user-guide-saola-1-v1.2> ESP32-S2-DevKitM-1 ESP32-S2-DevKitC-1 - ESP32-S2-Kaluga-Kit <../hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit> + ESP32-S2-Kaluga-Kit .. only:: esp32c3 diff --git a/docs/en/hw-reference/esp32/get-started-devkitc-v2.rst b/docs/en/hw-reference/esp32/get-started-devkitc-v2.rst deleted file mode 100644 index 1af22b25d536..000000000000 --- a/docs/en/hw-reference/esp32/get-started-devkitc-v2.rst +++ /dev/null @@ -1,85 +0,0 @@ -ESP32-DevKitC V2 Getting Started Guide -====================================== - -:link_to_translation:`zh_CN:[中文]` - -This guide shows how to start using the ESP32-DevKitC V2 development board. - - -What You Need -------------- - -* :ref:`ESP32-DevKitC V2 board ` -* USB A/micro USB B cable -* Computer running Windows, Linux, or macOS - -You can skip the introduction sections and go directly to Section `Start Application Development`_. - - -Overview --------- - -ESP32-DevKitC V2 is a small-sized ESP32-based development board produced by `Espressif `_. Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can either connect peripherals with jumper wires or mount ESP32-DevKitC V4 on a breadboard. - - -Functional Description ----------------------- - -The following figure and the table below describe the key components, interfaces and controls of the ESP32-DevKitC V2 board. - -.. _get-started-esp32-devkitc-v2-board-front-make: - -.. figure:: ../../../_static/esp32-devkitc-v2-functional-overview.png - :align: center - :alt: ESP32-DevKitC V2 board layout - :figclass: align-center - - ESP32-DevKitC V2 board layout - - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-WROOM-32 - - Standard module with ESP32 at its core. For more information, see `ESP32-WROOM-32 Datasheet `_ - * - EN - - Reset button. - * - Boot - - Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - Micro USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and ESP32-WROOM-32. - * - I/O - - Most of the pins on the ESP module are broken out to the pin headers on the board. You can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. - - -Power Supply Options --------------------- - -There are three mutually exclusive ways to provide power to the board: - -* Micro USB port, default power supply -* 5V and GND header pins -* 3V3 and GND header pins - -.. warning:: - - The power supply must be provided using **one and only one of the options above**, otherwise the board and/or the power supply source can be damaged. - - -Start Application Development ------------------------------- - -Before powering up your ESP32-DevKitC V2, please make sure that the board is in good condition with no obvious signs of damage. - -After that, proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. - - -Related Documents ------------------ - -* `ESP32-DevKitC schematics `_ (PDF) -* `ESP32 Datasheet `_ (PDF) -* `ESP32-WROOM-32 Datasheet `_ (PDF) diff --git a/docs/en/hw-reference/esp32/get-started-devkitc.rst b/docs/en/hw-reference/esp32/get-started-devkitc.rst deleted file mode 100644 index ec2e64baeb0d..000000000000 --- a/docs/en/hw-reference/esp32/get-started-devkitc.rst +++ /dev/null @@ -1,225 +0,0 @@ -ESP32-DevKitC V4 Getting Started Guide -====================================== - -:link_to_translation:`zh_CN:[中文]` - -This guide shows how to start using the ESP32-DevKitC V4 development board. - - -What You Need -------------- - -* :ref:`ESP32-DevKitC V4 board ` -* USB A/micro USB B cable -* Computer running Windows, Linux, or macOS - -You can skip the introduction sections and go directly to Section `Start Application Development`_. - - -.. _DevKitC-Overview: - -Overview --------- - -ESP32-DevKitC V4 is a small-sized ESP32-based development board produced by `Espressif `_. Most of the I/O pins are broken out to the pin headers on both sides for easy interfacing. Developers can either connect peripherals with jumper wires or mount ESP32-DevKitC V4 on a breadboard. - -To cover a wide range of user requirements, the following versions of ESP32-DevKitC V4 are available: - -- different ESP32 modules - - - `ESP32-WROOM-DA `_ - - `ESP32-WROOM-32E `_ - - `ESP32-WROOM-32UE `_ - - `ESP32-WROOM-32D `_ - - `ESP32-WROOM-32U `_ - - `ESP32-SOLO-1 `_ - - `ESP32-WROVER-E `_ - - `ESP32-WROVER-IE `_ - -- male or female pin headers. - -For details please refer to `ESP Product Selector `_. - - -Functional Description ----------------------- - -The following figure and the table below describe the key components, interfaces and controls of the ESP32-DevKitC V4 board. - -.. _get-started-esp32-devkitc-board-front: - -.. figure:: ../../../_static/esp32-devkitc-functional-overview.jpg - :align: center - :alt: ESP32-DevKitC V4 with ESP-WROOM-32 module soldered - - ESP32-DevKitC V4 with ESP32-WROOM-32 module soldered - - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-WROOM-32 - - A module with ESP32 at its core. For more information, see `ESP32-WROOM-32 Datasheet`_. - * - EN - - Reset button. - * - Boot - - Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - USB-to-UART Bridge - - Single USB-UART bridge chip provides transfer rates of up to 3 Mbps. - * - Micro USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the ESP32-WROOM-32 module. - * - 5V Power On LED - - Turns on when the USB or an external 5V power supply is connected to the board. For details see the schematics in `Related Documents`_. - * - I/O - - Most of the pins on the ESP module are broken out to the pin headers on the board. You can program ESP32 to enable multiple functions such as PWM, ADC, DAC, I2C, I2S, SPI, etc. - - -Power Supply Options --------------------- - -There are three mutually exclusive ways to provide power to the board: - -* Micro USB port, default power supply -* 5V and GND header pins -* 3V3 and GND header pins - -.. warning:: - - The power supply must be provided using **one and only one of the options above**, otherwise the board and/or the power supply source can be damaged. - - -Header Block ------------- - -The two tables below provide the **Name** and **Function** of I/O header pins on both sides of the board, as shown in :ref:`get-started-esp32-devkitc-board-front`. - - -J2 -^^^ -=== ==== ========== =============================================== -No. Name Type [1]_ Function -=== ==== ========== =============================================== -1 3V3 P 3.3 V power supply -2 EN I CHIP_PU, Reset -3 VP I GPIO36, ADC1_CH0, S_VP -4 VN I GPIO39, ADC1_CH3, S_VN -5 IO34 I GPIO34, ADC1_CH6, VDET_1 -6 IO35 I GPIO35, ADC1_CH7, VDET_2 -7 IO32 I/O GPIO32, ADC1_CH4, TOUCH_CH9, XTAL_32K_P -8 IO33 I/O GPIO33, ADC1_CH5, TOUCH_CH8, XTAL_32K_N -9 IO25 I/O GPIO25, ADC1_CH8, DAC_1 -10 IO26 I/O GPIO26, ADC2_CH9, DAC_2 -11 IO27 I/O GPIO27, ADC2_CH7, TOUCH_CH7 -12 IO14 I/O GPIO14, ADC2_CH6, TOUCH_CH6, MTMS -13 IO12 I/O GPIO12, ADC2_CH5, TOUCH_CH5, MTDI -14 GND G Ground -15 IO13 I/O GPIO13, ADC2_CH4, TOUCH_CH4, MTCK -16 D2 I/O GPIO9, D2 [2]_ -17 D3 I/O GPIO10, D3 [2]_ -18 CMD I/O GPIO11, CMD [2]_ -19 5V P 5 V power supply -=== ==== ========== =============================================== - - -J3 -^^^ -=== ==== ========== =============================================== -No. Name Type [1]_ Function -=== ==== ========== =============================================== -1 GND G Ground -2 IO23 I/O GPIO23 -3 IO22 I/O GPIO22 -4 TX I/O GPIO1, U0TXD -5 RX I/O GPIO3, U0RXD -6 IO21 I/O GPIO21 -7 GND G Ground -8 IO19 I/O GPIO19 -9 IO18 I/O GPIO18 -10 IO5 I/O GPIO5 -11 IO17 I/O GPIO17 [3]_ -12 IO16 I/O GPIO16 [3]_ -13 IO4 I/O GPIO4, ADC2_CH0, TOUCH_CH0 -14 IO0 I/O GPIO0, ADC2_CH1, TOUCH_CH1, Boot -15 IO2 I/O GPIO2, ADC2_CH2, TOUCH_CH2 -16 IO15 I/O GPIO15, ADC2_CH3, TOUCH_CH3, MTDO -17 D1 I/O GPIO8, D1 [2]_ -18 D0 I/O GPIO7, D0 [2]_ -19 CLK I/O GPIO6, CLK [2]_ -=== ==== ========== =============================================== - -.. [1] P: Power supply; I: Input; O: Output. -.. [2] The pins D0, D1, D2, D3, CMD and CLK are used internally for communication between ESP32 and SPI flash memory. They are grouped on both sides near the USB connector. Avoid using these pins, as it may disrupt access to the SPI flash memory/SPI RAM. -.. [3] The pins GPIO16 and GPIO17 are available for use only on the boards with the modules ESP32-WROOM and ESP32-SOLO-1. The boards with ESP32-WROVER modules have the pins reserved for internal use. - - -Pin Layout -^^^^^^^^^^^ -.. figure:: ../../../_static/esp32-devkitC-v4-pinout.png - :align: center - :scale: 45% - :alt: ESP32-DevKitC (click to enlarge) - - ESP32-DevKitC Pin Layout (click to enlarge) - - -Note on C15 ------------ - -The component C15 may cause the following issues on earlier ESP32-DevKitC V4 boards: - -* The board may boot into Download mode -* If you output clock on GPIO0, C15 may impact the signal - -In case these issues occur, please remove the component. The figure below shows the location of C15 highlighted in yellow. - - -.. figure:: ../../../_static/esp32-devkitc-c15-location.png - :align: center - :alt: Location of C15 (colored yellow) on ESP32-DevKitC V4 board - :width: 30% - - Location of C15 (yellow) on ESP32-DevKitC V4 board - - -Start Application Development ------------------------------ - -Before powering up your ESP32-DevKitC V4, please make sure that the board is in good condition with no obvious signs of damage. - -After that, proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. - - -Board Dimensions ----------------- - -.. figure:: ../../../_static/esp32-devkitc-dimensions-back.jpg - :align: center - :scale: 80% - :alt: Dimensions of ESP32-DevKitC board with ESP32-WROOM-32 module soldered - back (click to enlarge) - - Dimensions of ESP32-DevKitC board with ESP32-WROOM-32 module soldered - back (click to enlarge) - - -Related Documents ------------------ - -* `ESP32-DevKitC V4 schematics `_ (PDF) -* `ESP32 Datasheet `_ (PDF) -* `ESP32-WROOM-32 Datasheet `_ (PDF) -* `ESP32-WROOM-32D and ESP32-WROOM-32U Datasheet `_ (PDF) -* `ESP32-WROOM-32E and ESP32-WROOM-32UE Datasheet `_ (PDF) -* `ESP32-WROOM-DA Datasheet `_ (PDF) -* `ESP32-WROVER Datasheet `_ (PDF) -* `ESP32-WROVER-B Datasheet `_ (PDF) -* `ESP Product Selector `_ - -For further design documentation for the board, please contact us at `sales@espressif.com `_. - - -.. toctree:: - :hidden: - - get-started-devkitc-v2 diff --git a/docs/en/hw-reference/esp32/get-started-ethernet-kit-v1.0.rst b/docs/en/hw-reference/esp32/get-started-ethernet-kit-v1.0.rst deleted file mode 100644 index 6861c99c0757..000000000000 --- a/docs/en/hw-reference/esp32/get-started-ethernet-kit-v1.0.rst +++ /dev/null @@ -1,380 +0,0 @@ -ESP32-Ethernet-Kit V1.0 Getting Started Guide -============================================= - -:link_to_translation:`zh_CN:[中文]` - -This guide shows how to get started with the ESP32-Ethernet-Kit development board and also provides information about its functionality and configuration options. - -The :ref:`ESP32-Ethernet-Kit ` is an Ethernet-to-Wi-Fi development board that enables Ethernet devices to be interconnected over Wi-Fi. At the same time, to provide more flexible power supply options, the ESP32-Ethernet-Kit also supports power over Ethernet (PoE). - - -What You Need -------------- - -* :ref:`ESP32-Ethernet-Kit V1.0 board ` -* USB 2.0 A to Micro B Cable -* Computer running Windows, Linux, or macOS - -You can skip the introduction sections and go directly to Section `Start Application Development`_. - - -Overview --------- - -ESP32-Ethernet-Kit is an ESP32-based development board produced by `Espressif `_. - -It consists of two development boards, the Ethernet board A and the PoE board B. The :ref:`Ethernet board (A) ` contains Bluetooth®/Wi-Fi dual-mode ESP32-WROVER-B module and IP101GRI, a Single Port 10/100 Fast Ethernet Transceiver (PHY). The :ref:`PoE board (B) ` provides power over Ethernet functionality. The A board can work independently, without the board B installed. - -.. _get-started-esp32-ethernet-kit-b-v1.0: - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.0.png - :align: center - :alt: ESP32-Ethernet-Kit V1.0 - :figclass: align-center - - ESP32-Ethernet-Kit V1.0 - -For the application loading and monitoring the Ethernet board (A) also features FTDI FT2232H chip - an advanced multi-interface USB bridge. This chip enables to use JTAG for direct debugging of ESP32 through the USB interface without a separate JTAG debugger. - - -Functionality Overview ----------------------- - -The block diagram below shows the main components of ESP32-Ethernet-Kit and their interconnections. - -.. figure:: ../../../_static/esp32-ethernet-kit-block-diagram.png - :align: center - :scale: 50% - :alt: ESP32-Ethernet-Kit block diagram (click to enlarge) - :figclass: align-center - - ESP32-Ethernet-Kit block diagram (click to enlarge) - - -Functional Description ----------------------- - -The following two figures and tables describe the key components, interfaces, and controls of the ESP32-Ethernet-Kit. - - -.. _get-started-esp32-ethernet-kit-a-v1.0-layout: - -Ethernet Board (A) -^^^^^^^^^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-ethernet-kit-a-v1.0-layout.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit - Ethernet board (A) layout - :figclass: align-center - - ESP32-Ethernet-Kit - Ethernet board (A) layout (click to enlarge) - -The table below provides description starting from the picture's top right corner and going clockwise. - -================== ================================================================================================================================= -Key Component Description -================== ================================================================================================================================= -ESP32-WROVER-B This ESP32 module features 64-Mbit PSRAM for flexible extended storage and data processing capabilities. - -GPIO Header 2 Five unpopulated through-hole solder pads to provide access to selected GPIOs of ESP32. For details, see `GPIO Header 2`_. - -Flow Control A jumper header with access to the board signals. For details, see `Flow Control`_. - -Function Switch A DIP switch used to configure the functionality of selected GPIOs of ESP32. For details, see `Function Switch`_. - -Tx/Rx LEDs Two LEDs to show the status of UART transmission. - -GPIO Header 3 Provides access to some GPIOs of ESP32 that can be used depending on the position of the `Function Switch`_. - -FT2232H The FT2232H chip serves as a multi-protocol USB-to-serial bridge which can be programmed and controlled via USB to provide communication with ESP32. FT2232H also features USB-to-JTAG interface which is available on channel A of the chip, while USB-to-serial is on channel B. The FT2232H chip enhances user-friendliness in terms of application development and debugging. See `ESP32-Ethernet-Kit V1.0 Ethernet board (A) schematic`_. - -USB Port USB interface. Power supply for the board as well as the communication interface between a computer and the board. - -Power Switch Power On/Off Switch. Toggling toward the **Boot** button powers the board on, toggling away from **Boot** powers the board off. - -5V Input The 5V power supply interface can be more convenient when the board is operating autonomously (not connected to a computer). - -5V Power On LED This red LED turns on when power is supplied to the board, either from USB or 5 V Input. - -DC/DC Converter Provided DC 5 V to 3.3 V conversion, output current up to 2 A. - -Board B Connectors A pair male header pins for mounting the :ref:`PoE board (B) `. - -IP101GRI (PHY) The physical layer (PHY) connection to the Ethernet cable is implemented using the `IP101GRI `_ chip. The connection between PHY and ESP32 is done through the reduced media-independent interface (RMII), a variant of the media-independent interface `(MII) `_ standard. The PHY supports the IEEE 802.3/802.3u standard of 10/100 Mbps. - -RJ45 Port Ethernet network data transmission port. - -Magnetics Module The Magnetics are part of the Ethernet specification to protect against faults and transients, including rejection of common mode signals between the transceiver IC and the cable. The magnetics also provide galvanic isolation between the transceiver and the Ethernet device. - -Link/Activity LEDs Two LEDs (green and red) that respectively indicate the "Link" and "Activity" statuses of the PHY. - -BOOT Button Download button. Holding down **BOOT** and then pressing **CH_PU** initiates Firmware Download mode for downloading firmware through the serial port. - -CH_PU Button Reset button. - -GPIO Header 1 This header provides six unpopulated through-hole solder pads connected to spare GPIOs of ESP32. For details, see `GPIO Header 1`_. - -================== ================================================================================================================================= - - -.. _get-started-esp32-ethernet-kit-b-v1.0-layout: - -PoE Board (B) -^^^^^^^^^^^^^ - -This board coverts power delivered over the Ethernet cable (PoE) to provide a power supply for the Ethernet board (A). The main components of the PoE board (B) are shown on the block diagram under `Functionality Overview`_. - -The PoE board (B) has the following features: - -* Support for IEEE 802.3at -* Power output: 5 V, 1.4 A - -To take advantage of the PoE functionality the **RJ45 Port** of the Ethernet board (A) should be connected with an Ethernet cable to a switch that supports PoE. When the Ethernet board (A) detects 5 V power output from the PoE board (B), the USB power will be automatically cut off. - -.. figure:: ../../../_static/esp32-ethernet-kit-b-v1.0-layout.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit - PoE board (B) - :figclass: align-center - - ESP32-Ethernet-Kit - PoE board (B) layout (click to enlarge) - -========================== ================================================================================================================================= -Key Component Description -========================== ================================================================================================================================= -Board A Connector Four female header pins for mounting this board onto :ref:`Ethernet board (A) `. - -External Power Terminals Optional power supply to the PoE board (B). - -========================== ================================================================================================================================= - - -.. _get-started-esp32-ethernet-kit-b-v1.0-setup-options: - -Setup Options -------------- - -This section describes options to configure the ESP32-Ethernet-Kit hardware. - - -Function Switch -^^^^^^^^^^^^^^^ - -The functions for specific GPIO pins can be selected with the **Function Switch**. - -======= ================ ================================================================ -DIP SW GPIO Pin Pin Functionality if DIP SW is ON -======= ================ ================================================================ - 1 GPIO14 Connected to FT2232H to provide JTAG functionality - 2 GPIO12 Connected to FT2232H to provide JTAG functionality - 3 GPIO13 Connected to FT2232H to provide JTAG functionality - 4 GPIO15 Connected to FT2232H to provide JTAG functionality - 5 GPIO4 Connected to FT2232H to provide JTAG functionality - 6 GPIO2 Connected to on-board 25 MHz oscillator - 7 GPIO5 Connected to RESET_N input of IP101GRI - 8 n/a -======= ================ ================================================================ - -You can make a certain GPIO pin available for other purposes by putting its DIP SW to the Off position. - - -Flow Control -^^^^^^^^^^^^ - -This is a 2 x 2 jumper pin header intended for the UART flow control. - -==== ======= ================================================= -. Signal Comment -==== ======= ================================================= - 1 MTDO GPIO13, see also `Function Switch`_ - 2 MTCK GPIO15, see also `Function Switch`_ - 3 RTS RTS signal of FT2232H - 4 CTS CTS signal of FT2232H -==== ======= ================================================= - - -GPIO Allocation ---------------- - -This section describes allocation of ESP32 GPIOs to specific interfaces or functions of the ESP32-Ethernet-Kit. - - -IP101GRI (PHY) Interface -^^^^^^^^^^^^^^^^^^^^^^^^ - -The allocation of the ESP32 (MAC) pins to IP101GRI (PHY) is shown in the table below. Implementation of ESP32-Ethernet-Kit defaults to Reduced Media-Independent Interface (RMII). - -==== ================ =============== -. ESP32 Pin (MAC) IP101GRI (PHY) -==== ================ =============== -*RMII Interface* ---------------------------------------- - 1 GPIO21 TX_EN - 2 GPIO19 TXD[0] - 3 GPIO22 TXD[1] - 4 GPIO25 RXD[0] - 5 GPIO26 RXD[1] - 6 GPIO27 CRS_DV - 7 GPIO0 REF_CLK ----- ---------------- --------------- -*Serial Management Interface* ---------------------------------------- - 8 GPIO23 MDC - 9 GPIO18 MDIO ----- ---------------- --------------- -*PHY Reset* ---------------------------------------- -10 GPIO5 Reset_N -==== ================ =============== - -.. note:: - - Except for REF_CLK, the allocation of all pins under the *RMII Interface* is fixed and cannot be changed either through IOMUX or GPIO Matrix. - - -GPIO Header 1 -^^^^^^^^^^^^^ - -This header exposes some GPIOs that are not used elsewhere on the ESP32-Ethernet-Kit. - -==== ================ -. ESP32 Pin -==== ================ - 1 GPIO32 - 2 GPIO33 - 3 GPIO34 - 4 GPIO35 - 5 GPIO36 - 6 GPIO39 -==== ================ - - -GPIO Header 2 -^^^^^^^^^^^^^ - -This header contains the GPIOs with specific MII functionality (except GPIO2), as opposed to Reduced Media-Independent Interface (RMII) functionality implemented on ESP32-Ethernet-Kit board by default, see `IP101GRI (PHY) Interface`_. Depending on the situation, if MMI is used, specific Ethernet applications might require this functionality. - -==== ========== ================= ================== -. ESP32 Pin MII Function Comments -==== ========== ================= ================== - 1 GPIO17 EMAC_CLK_180 See note 1 - 2 GPIO16 EMAC_CLK_OUT See note 1 - 3 GPIO4 EMAC_TX_ER - 4 GPIO2 n/a See note 2 - 5 GPIO5 EMAC_RX_CLK See note 2 -==== ========== ================= ================== - -.. note:: - - 1. The ESP32 pins GPIO16 and GPIO17 are not broken out to the ESP32-WROVER-B module and therefore not available for use. If you need to use these pins, please solder a module without SPIRAM memory inside, e.g., the ESP32-WROOM-32D or ESP32-SOLO-1. - 2. Functionality depends on the settings of the `Function Switch`_. - - -GPIO Header 3 -^^^^^^^^^^^^^ - -The functionality of GPIOs connected to this header depends on the settings of the `Function Switch`_. - -==== =========== -. ESP32 Pin -==== =========== - 1 GPIO15 - 2 GPIO13 - 3 GPIO12 - 4 GPIO14 - 5 GND - 6 3V3 -==== =========== - - -GPIO Allocation Summary -^^^^^^^^^^^^^^^^^^^^^^^ - -.. csv-table:: - :header: ESP32-WROVER-B,IP101GRI,UART,JTAG,GPIO, Comments - - S_VP,,,,IO36, - S_VN,,,,IO39, - IO34,,,,IO34, - IO35,,,,IO35, - IO32,,,,IO32, - IO33,,,,IO33, - IO25,RXD[0],,,, - IO26,RXD[1],,,, - IO27,CRS_DV,,,, - IO14,,,TMS,IO14, - IO12,,,TDI,IO12, - IO13,,RTS,TCK,IO13, - IO15,,CTS,TDO,IO15, - IO2,,,,IO2,See notes 1 and 3 below - IO0,REF_CLK,,,,See notes 2 and 3 below - IO4,,,nTRST,IO4, - IO16,,,,IO16 (NC),See note 4 below - IO17,,,,IO17 (NC),See note 4 below - IO5,Reset_N,,,IO5, - IO18,MDIO,,,, - IO19,TXD[0],,,, - IO21,TX_EN,,,, - RXD0,,RXD,,, - TXD0,,TXD,,, - IO22,TXD[1],,,, - IO23,MDC,,,, - - -.. note:: - - 1. GPIO2 is used to enable external oscillator of the PHY. - 2. GPIO0 is a source of 50 MHz reference clock for the PHY. The clock signal is first inverted, to account for transmission line delay, and then supplied to the PHY. - 3. To prevent affecting the power-on state of GPIO0 by the clock output on the PHY side, the PHY external oscillator is enabled using GPIO2 after ESP32 is powered up. - 4. The ESP32 pins GPIO16 and GPIO17 are not broken out to the ESP32-WROVER-B module and therefore not available for use. If you need to use these pins, please solder a module without SPIRAM memory inside, e.g., the ESP32-WROOM-32D or ESP32-SOLO-1. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-Ethernet-Kit, please make sure that the board is in good condition with no obvious signs of damage. - - -Initial Setup -^^^^^^^^^^^^^ - -1. Set the **Function Switch** on the :ref:`Ethernet board (A) ` to its default position by turning all the switches to **ON**. -2. To simplify flashing and testing the application, do not install any jumpers and do not connect any signals to the board headers. -3. The :ref:`PoE board (B) ` can now be plugged in, but do not connect external power to it. -4. Connect the :ref:`Ethernet board (A) ` to the PC with a USB cable. -5. Turn the **Power Switch** from GND to 5V0 position, the **5V Power On LED** should light up. - - -Now to Development -^^^^^^^^^^^^^^^^^^ - -Proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. - -To use the older GNU Make compilation system, please refer to :ref:`get-started-step-by-step` section. - -Move on to the next section only if you have successfully completed all the above steps. - - -Configure and Load the Ethernet Example -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -After setting up the development environment and testing the board, you can configure and flash the :example:`ethernet/basic` example. This example has been created for testing Ethernet functionality. It supports different PHY, including **IP101GRI** installed on :ref:`ESP32-Ethernet-Kit V1.0 board `. - - -Related Documents ------------------ - -* `ESP32-Ethernet-Kit V1.0 Ethernet board (A) schematic`_ (PDF) -* `ESP32-Ethernet-Kit V1.0 PoE board (B) schematic`_ (PDF) -* `ESP32 Datasheet `_ (PDF) -* `ESP32-WROVER-B Datasheet `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - -For other design documentation for the board, please contact us at sales@espressif.com. - -.. _ESP32-Ethernet-Kit V1.0 Ethernet board (A) schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_A_V1.0_20190517.pdf -.. _ESP32-Ethernet-Kit V1.0 PoE board (B) schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_B_V1.0_20190517.pdf -.. _IP101GRI: http://www.bdtic.com/DataSheet/ICplus/IP101G_DS_R01_20121224.pdf -.. _MII: https://en.wikipedia.org/wiki/Media-independent_interface diff --git a/docs/en/hw-reference/esp32/get-started-ethernet-kit-v1.1.rst b/docs/en/hw-reference/esp32/get-started-ethernet-kit-v1.1.rst deleted file mode 100644 index 68ad0e943fe7..000000000000 --- a/docs/en/hw-reference/esp32/get-started-ethernet-kit-v1.1.rst +++ /dev/null @@ -1,410 +0,0 @@ -ESP32-Ethernet-Kit V1.1 Getting Started Guide -============================================= - -:link_to_translation:`zh_CN:[中文]` - -This guide shows how to get started with the ESP32-Ethernet-Kit development board and also provides information about its functionality and configuration options. - -The :ref:`ESP32-Ethernet-Kit ` is an Ethernet-to-Wi-Fi development board that enables Ethernet devices to be interconnected over Wi-Fi. At the same time, to provide more flexible power supply options, the ESP32-Ethernet-Kit also supports power over Ethernet (PoE). - - -What You Need -------------- - -* :ref:`ESP32-Ethernet-Kit V1.1 board ` -* USB 2.0 A to Micro B Cable -* Computer running Windows, Linux, or macOS - -You can skip the introduction sections and go directly to Section `Start Application Development`_. - - -Overview --------- - -ESP32-Ethernet-Kit is an ESP32-based development board produced by `Espressif `_. - -It consists of two development boards, the Ethernet board A and the PoE board B. The :ref:`Ethernet board (A) ` contains Bluetooth®/Wi-Fi dual-mode ESP32-WROVER-B module and IP101GRI, a Single Port 10/100 Fast Ethernet Transceiver (PHY). The `PoE board (B)`_ provides power over Ethernet functionality. The A board can work independently, without the board B installed. - -.. _get-started-esp32-ethernet-kit-v1.1: - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.1.png - :align: center - :alt: ESP32-Ethernet-Kit V1.1 - :figclass: align-center - - ESP32-Ethernet-Kit V1.1 - -For the application loading and monitoring, the Ethernet board (A) also features FTDI FT2232H chip - an advanced multi-interface USB bridge. This chip enables to use JTAG for direct debugging of ESP32 through the USB interface without a separate JTAG debugger. - - -Functionality Overview ----------------------- - -The block diagram below shows the main components of ESP32-Ethernet-Kit and their interconnections. - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.1-block-diagram.png - :align: center - :scale: 60% - :alt: ESP32-Ethernet-Kit block diagram (click to enlarge) - :figclass: align-center - - ESP32-Ethernet-Kit block diagram (click to enlarge) - - -Functional Description ----------------------- - -The following figures and tables describe the key components, interfaces, and controls of the ESP32-Ethernet-Kit. - -.. _get-started-esp32-ethernet-kit-a-v1.1-layout: - - -Ethernet Board (A) -^^^^^^^^^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-ethernet-kit-a-v1.1-layout.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit - Ethernet board (A) layout - :figclass: align-center - - ESP32-Ethernet-Kit - Ethernet board (A) layout (click to enlarge) - -The table below provides description starting from the picture's top right corner and going clockwise. - -.. list-table:: Table 1 Component Description - :widths: 40 150 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-WROVER-B - - This ESP32 module features 64-Mbit PSRAM for flexible extended storage and data processing capabilities. - * - GPIO Header 2 - - Five unpopulated through-hole solder pads to provide access to selected GPIOs of ESP32. For details, see `GPIO Header 2`_. - * - Function Switch - - A 4-bit DIP switch used to configure the functionality of selected GPIOs of ESP32. Please note that placement of GPIO pin number marking on the board's silkscreen besides the DIP switch is incorrect. For details and correct pin allocation see `Function Switch`_. - * - Tx/Rx LEDs - - Two LEDs to show the status of UART transmission. - * - FT2232H - - The FT2232H chip serves as a multi-protocol USB-to-serial bridge which can be programmed and controlled via USB to provide communication with ESP32. FT2232H also features USB-to-JTAG interface which is available on channel A of the chip, while USB-to-serial is on channel B. The FT2232H chip enhances user-friendliness in terms of application development and debugging. See `ESP32-Ethernet-Kit V1.1 Ethernet board (A) schematic`_. - * - USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the board. - * - Power Switch - - Power On/Off Switch. Toggling the switch to **5V0** position powers the board on, toggling to **GND** position powers the board off. - * - 5V Input - - The 5 V power supply interface can be more convenient when the board is operating autonomously (not connected to a computer). - * - 5V Power On LED - - This red LED turns on when power is supplied to the board, either from USB or 5 V Input. - * - DC/DC Converter - - Provided DC 5 V to 3.3 V conversion, output current up to 2 A. - * - Board B Connectors - - A pair male and female header pins for mounting the `PoE board (B)`_. - * - IP101GRI (PHY) - - The physical layer (PHY) connection to the Ethernet cable is implemented using the `IP101GRI `_ chip. The connection between PHY and ESP32 is done through the reduced media-independent interface (RMII), a variant of the media-independent interface `(MII) `_ standard. The PHY supports the IEEE 802.3/802.3u standard of 10/100 Mbps. - * - RJ45 Port - - Ethernet network data transmission port. - * - Magnetics Module - - The Magnetics are part of the Ethernet specification to protect against faults and transients, including rejection of common mode signals between the transceiver IC and the cable. The magnetics also provide galvanic isolation between the transceiver and the Ethernet device. - * - Link/Activity LEDs - - Two LEDs (green and red) that respectively indicate the "Link" and "Activity" statuses of the PHY. - * - BOOT Button - - Download button. Holding down **BOOT** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - EN Button - - Reset button. - * - GPIO Header 1 - - This header provides six unpopulated through-hole solder pads connected to spare GPIOs of ESP32. For details, see `GPIO Header 1`_. - - -PoE Board (B) -^^^^^^^^^^^^^ - -This board coverts power delivered over the Ethernet cable (PoE) to provide a power supply for the Ethernet board (A). The main components of the PoE board (B) are shown on the block diagram under `Functionality Overview`_. - -The PoE board (B) has the following features: - -* Support for IEEE 802.3at -* Power output: 5 V, 1.4 A - -To take advantage of the PoE functionality the **RJ45 Port** of the Ethernet board (A) should be connected with an Ethernet cable to a switch that supports PoE. When the Ethernet board (A) detects 5 V power output from the PoE board (B), the USB power will be automatically cut off. - -.. figure:: ../../../_static/esp32-ethernet-kit-b-v1.0-layout.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit - PoE board (B) - :figclass: align-center - - ESP32-Ethernet-Kit - PoE board (B) layout (click to enlarge) - -.. list-table:: Table PoE board (B) - :widths: 40 150 - :header-rows: 1 - - * - Key Component - - Description - * - Board A Connector - - Four female (left) and four male (right) header pins for connecting the PoE board (B) to :ref:`Ethernet board (A) `. The pins on the left accept power coming from a PoE switch. The pins on the right deliver 5 V power supply to the Ethernet board (A). - * - External Power Terminals - - Optional power supply (26.6 ~ 54 V) to the PoE board (B). - -.. _get-started-esp32-ethernet-kit-v1.1-setup-options: - - -Setup Options -------------- - -This section describes options to configure the ESP32-Ethernet-Kit hardware. - - -Function Switch -^^^^^^^^^^^^^^^ - -When in On position, this DIP switch is routing listed GPIOs to FT2232H to provide JTAG functionality. When in Off position, the GPIOs may be used for other purposes. - -======= ================ -DIP SW GPIO Pin -======= ================ - 1 GPIO13 - 2 GPIO12 - 3 GPIO15 - 4 GPIO14 -======= ================ - -.. note:: - - Placement of GPIO pin number marking on the board's silkscreen besides the DIP switch is incorrect. Please use instead the pin order as in the table above. - - -RMII Clock Selection -^^^^^^^^^^^^^^^^^^^^ - -The ethernet MAC and PHY under RMII working mode need a common 50 MHz reference clock (i.e., RMII clock) that can be provided either externally, or generated from internal ESP32 APLL. - -.. note:: - - For additional information on the RMII clock selection, please refer to `ESP32-Ethernet-Kit V1.1 Ethernet board (A) schematic`_, sheet 2, location D2. - - -RMII Clock Sourced Externally by PHY -"""""""""""""""""""""""""""""""""""" - -By default, the ESP32-Ethernet-Kit is configured to provide RMII clock for the IP101GRI PHY's 50M_CLKO output. The clock signal is generated by the frequency multiplication of 25 MHz crystal connected to the PHY. For details, please see the figure below. - -.. figure:: ../../../_static/esp32-ethernet-kit-rmii-clk-from-phy.png - :align: center - :scale: 80% - :alt: RMII Clock from IP101GRI PHY - :figclass: align-center - - RMII Clock from IP101GRI PHY - -Please note that the PHY is reset on power up by pulling the RESET_N signal down with a resistor. ESP32 should assert RESET_N high with GPIO5 to enable PHY. Only this can ensure the power-up of system. Otherwise ESP32 may enter download mode (when the clock signal of REF_CLK_50M is at a high logic level during the GPIO0 power-up sampling phase). - - -RMII Clock Sourced Internally from ESP32's APLL -""""""""""""""""""""""""""""""""""""""""""""""" - -Another option is to source the RMII Clock from internal ESP32 APLL, see figure below. The clock signal coming from GPIO0 is first inverted, to account for transmission line delay, and then supplied to the PHY. - -.. figure:: ../../../_static/esp32-ethernet-kit-rmii-clk-to-phy.png - :align: center - :scale: 80% - :alt: RMII Clock from ESP Internal APLL - :figclass: align-center - - RMII Clock from ESP Internal APLL - -To implement this option, users need to remove or add some RC components on the board. For details please refer to `ESP32-Ethernet-Kit V1.1 Ethernet board (A) schematic`_, sheet 2, location D2. Please note that if the APLL is already used for other purposes (e.g., I2S peripheral), then you have no choice but use an external RMII clock. - - -GPIO Allocation ---------------- - -This section describes allocation of ESP32 GPIOs to specific interfaces or functions of the ESP32-Ethernet-Kit. - - -IP101GRI (PHY) Interface -^^^^^^^^^^^^^^^^^^^^^^^^ - -The allocation of the ESP32 (MAC) pins to IP101GRI (PHY) is shown in the table below. Implementation of ESP32-Ethernet-Kit defaults to Reduced Media-Independent Interface (RMII). - -==== ================ =============== -. ESP32 Pin (MAC) IP101GRI (PHY) -==== ================ =============== -*RMII Interface* ---------------------------------------- - 1 GPIO21 TX_EN - 2 GPIO19 TXD[0] - 3 GPIO22 TXD[1] - 4 GPIO25 RXD[0] - 5 GPIO26 RXD[1] - 6 GPIO27 CRS_DV - 7 GPIO0 REF_CLK ----- ---------------- --------------- -*Serial Management Interface* ---------------------------------------- - 8 GPIO23 MDC - 9 GPIO18 MDIO ----- ---------------- --------------- -*PHY Reset* ---------------------------------------- -10 GPIO5 Reset_N -==== ================ =============== - -.. note:: - - Except for REF_CLK, the allocation of all pins under the ESP32's *RMII Interface* is fixed and cannot be changed either through IOMUX or GPIO Matrix. - - -GPIO Header 1 -^^^^^^^^^^^^^ - -This header exposes some GPIOs that are not used elsewhere on the ESP32-Ethernet-Kit. - -==== ================ -. ESP32 Pin -==== ================ - 1 GPIO32 - 2 GPIO33 - 3 GPIO34 - 4 GPIO35 - 5 GPIO36 - 6 GPIO39 -==== ================ - - -GPIO Header 2 -^^^^^^^^^^^^^ - -This header contains GPIOs that may be used for other purposes depending on scenarios described in column "Comments". - -==== ========== ==================== -. ESP32 Pin Comments -==== ========== ==================== - 1 GPIO17 See note 1 - 2 GPIO16 See note 1 - 3 GPIO4 - 4 GPIO2 - 5 GPIO13 See note 2 - 6 GPIO12 See note 2 - 7 GPIO15 See note 2 - 8 GPIO14 See note 2 - 9 GND Ground -10 3V3 3.3 V power supply -==== ========== ==================== - -.. note:: - - 1. The ESP32 pins GPIO16 and GPIO17 are not broken out to the ESP32-WROVER-B module and therefore not available for use. If you need to use these pins, please solder a module without PSRAM memory inside, e.g., the ESP32-WROOM-32D or ESP32-SOLO-1. - - 2. Functionality depends on the settings of the `Function Switch`_. - - -GPIO Allocation Summary -^^^^^^^^^^^^^^^^^^^^^^^ - -.. csv-table:: - :header: ESP32-WROVER-B,IP101GRI,UART,JTAG,GPIO,Comments - - S_VP,,,,IO36, - S_VN,,,,IO39, - IO34,,,,IO34, - IO35,,,,IO35, - IO32,,,,IO32, - IO33,,,,IO33, - IO25,RXD[0],,,, - IO26,RXD[1],,,, - IO27,CRS_DV,,,, - IO14,,,TMS,IO14, - IO12,,,TDI,IO12, - IO13,,RTS,TCK,IO13, - IO15,,CTS,TDO,IO15, - IO2,,,,IO2, - IO0,REF_CLK,,,,See note 1 - IO4,,,,IO4, - IO16,,,,IO16 (NC),See note 2 - IO17,,,,IO17 (NC),See note 2 - IO5,Reset_N,,,,See note 1 - IO18,MDIO,,,, - IO19,TXD[0],,,, - IO21,TX_EN,,,, - RXD0,,RXD,,, - TXD0,,TXD,,, - IO22,TXD[1],,,, - IO23,MDC,,,, - -.. note:: - - 1. To prevent the power-on state of the GPIO0 from being affected by the clock output on the PHY side, the RESET_N signal to PHY defaults to low, turning the clock output off. After power-on you can control RESET_N with GPIO5 to turn the clock output on. See also `RMII Clock Sourced Externally by PHY`_. For PHYs that cannot turn off the clock output through RESET_N, it is recommended to use a crystal module that can be disabled/enabled externally. Similarly like when using RESET_N, the oscillator module should be disabled by default and turned on by ESP32 after power-up. For a reference design please see `ESP32-Ethernet-Kit V1.1 Ethernet board (A) schematic`_. - - 2. The ESP32 pins GPIO16 and GPIO17 are not broken out to the ESP32-WROVER-B module and therefore not available for use. If you need to use these pins, please solder a module without PSRAM memory inside, e.g., the ESP32-WROOM-32D or ESP32-SOLO-1. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-Ethernet-Kit, please make sure that the board is in good condition with no obvious signs of damage. - - -Initial Setup -^^^^^^^^^^^^^ - -1. Set the **Function Switch** on the :ref:`Ethernet board (A) ` to its default position by turning all the switches to **ON**. -2. To simplify flashing and testing of the application, do not input extra signals to the board headers. -3. The `PoE board (B)`_ can now be plugged in, but do not connect external power to it. -4. Connect the :ref:`Ethernet board (A) ` to the PC with a USB cable. -5. Turn the **Power Switch** from GND to 5V0 position, the **5V Power On LED** should light up. - - -Now to Development -^^^^^^^^^^^^^^^^^^ - -Proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. - -Move on to the next section only if you have successfully completed all the above steps. - - -Configure and Load the Ethernet Example -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -After setting up the development environment and testing the board, you can configure and flash the :example:`ethernet/basic` example. This example has been created for testing Ethernet functionality. It supports different PHY, including **IP101GRI** installed on :ref:`get-started-esp32-ethernet-kit-v1.1`. - - -Summary of Changes from ESP32-Ethernet-Kit V1.0 ------------------------------------------------ - -* The original inverted clock provided to the PHY by ESP32 using GPIO0 has been replaced by a clock generated on PHY side. The PHY's clock is connected to the ESP32 with same GPIO0. The GPIO2 which was originally used to control the active crystal oscillator on the PHY side, can now be used for other purposes. -* On power up, the ESP32 boot strapping pin GPIO0 may be affected by clock generated on the PHY side. To resolve this issue the PHY's Reset-N signal is pulled low using resistor R17 and effectively turning off the PHY's clock output. The Reset-N signal can be then pulled high by ESP32 using GPIO5. -* Removed FT2232H chip's external SPI Flash U6. -* Removed flow control jumper header J4. -* Removed nTRST JTAG signal. The corresponding GPIO4 can now be used for other purposes. -* Pull-up resistor R68 on the GPIO15 line is moved to the MTDO side of JTAG. -* To make the A and B board connections more foolproof (reduce chances of plugging in the B board in reverse orientation), the original two 4-pin male rows on board A were changed to one 4-pin female row and one 4-pin male row. Corresponding male and female 4-pins rows were installed on board B. - - -Other Versions of ESP32-Ethernet-Kit ------------------------------------- - -* :doc:`get-started-ethernet-kit-v1.0` - - -Related Documents ------------------ - -* `ESP32-Ethernet-Kit V1.1 Ethernet board (A) schematic`_ (PDF) -* `ESP32-Ethernet-Kit V1.0 PoE board (B) schematic`_ (PDF) -* `ESP32 Datasheet `_ (PDF) -* `ESP32-WROVER-B Datasheet `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - -For other design documentation for the board, please contact us at sales@espressif.com. - -.. _ESP32-Ethernet-Kit V1.1 Ethernet board (A) schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_A_V1.1_20190711.pdf -.. _ESP32-Ethernet-Kit V1.0 PoE board (B) schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_B_V1.0_20190517.pdf -.. _ESP32-Ethernet-Kit V1.0 Ethernet board (A) schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_A_V1.0_20190517.pdf - -.. toctree:: - :hidden: - - get-started-ethernet-kit-v1.0.rst diff --git a/docs/en/hw-reference/esp32/get-started-ethernet-kit.rst b/docs/en/hw-reference/esp32/get-started-ethernet-kit.rst deleted file mode 100644 index 256457f59c02..000000000000 --- a/docs/en/hw-reference/esp32/get-started-ethernet-kit.rst +++ /dev/null @@ -1,423 +0,0 @@ -ESP32-Ethernet-Kit V1.2 Getting Started Guide -============================================= - -:link_to_translation:`zh_CN:[中文]` - -This guide shows how to get started with the ESP32-Ethernet-Kit development board and also provides information about its functionality and configuration options. - -The :ref:`ESP32-Ethernet-Kit ` is an Ethernet-to-Wi-Fi development board that enables Ethernet devices to be interconnected over Wi-Fi. At the same time, to provide more flexible power supply options, the ESP32-Ethernet-Kit also supports power over Ethernet (PoE). - -.. _get-started-esp32-ethernet-kit-v1.2-overview: - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.2-overview.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit V1.2 - :figclass: align-center - - ESP32-Ethernet-Kit V1.2 Overview (click to enlarge) - - -What You Need -------------- - -* :ref:`ESP32-Ethernet-Kit V1.2 board ` -* USB 2.0 A to Micro B Cable -* Computer running Windows, Linux, or macOS - -You can skip the introduction sections and go directly to Section `Start Application Development`_. - - -Overview --------- - -ESP32-Ethernet-Kit is an ESP32-based development board produced by `Espressif `_. - -It consists of two development boards, the Ethernet board A and the PoE board B. The :ref:`Ethernet board (A) ` contains Bluetooth®/Wi-Fi dual-mode ESP32-WROVER-E module and IP101GRI, a Single Port 10/100 Fast Ethernet Transceiver (PHY). The `PoE board (B)`_ provides power over Ethernet functionality. The A board can work independently, without the board B installed. - -.. _get-started-esp32-ethernet-kit-v1.2: - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.2.jpg - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit V1.2 - :figclass: align-center - - ESP32-Ethernet-Kit V1.2 (click to enlarge) - -For the application loading and monitoring, the Ethernet board (A) also features FTDI FT2232H chip - an advanced multi-interface USB bridge. This chip enables to use JTAG for direct debugging of ESP32 through the USB interface without a separate JTAG debugger. - - -Functionality Overview ----------------------- - -The block diagram below shows the main components of ESP32-Ethernet-Kit and their interconnections. - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.1-block-diagram.png - :align: center - :scale: 60% - :alt: ESP32-Ethernet-Kit block diagram (click to enlarge) - :figclass: align-center - - ESP32-Ethernet-Kit block diagram (click to enlarge) - - -Functional Description ----------------------- - -The following figures and tables describe the key components, interfaces, and controls of the ESP32-Ethernet-Kit. - -.. _get-started-esp32-ethernet-kit-a-v1.2-layout: - - -Ethernet Board (A) -^^^^^^^^^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-ethernet-kit-a-v1.2-layout.jpg - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit V1.2 (click to enlarge) - :figclass: align-center - - ESP32-Ethernet-Kit - Ethernet board (A) layout (click to enlarge) - -The table below provides description starting from the picture's top right corner and going clockwise. - -.. list-table:: Table 1 Component Description - :widths: 40 150 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-WROVER-E - - This ESP32 module features 64-Mbit PSRAM for flexible extended storage and data processing capabilities. - * - GPIO Header 2 - - Five unpopulated through-hole solder pads to provide access to selected GPIOs of ESP32. For details, see `GPIO Header 2`_. - * - Function Switch - - A 4-bit DIP switch used to configure the functionality of selected GPIOs of ESP32. For details see `Function Switch`_. - * - Tx/Rx LEDs - - Two LEDs to show the status of UART transmission. - * - FT2232H - - The FT2232H chip serves as a multi-protocol USB-to-serial bridge which can be programmed and controlled via USB to provide communication with ESP32. FT2232H also features USB-to-JTAG interface which is available on channel A of the chip, while USB-to-serial is on channel B. The FT2232H chip enhances user-friendliness in terms of application development and debugging. See `ESP32-Ethernet-Kit V1.2 Ethernet board (A) schematic`_. - * - USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the board. - * - Power Switch - - Power On/Off Switch. Toggling the switch to **5V0** position powers the board on, toggling to **GND** position powers the board off. - * - 5V Input - - The 5 V power supply interface can be more convenient when the board is operating autonomously (not connected to a computer). - * - 5V Power On LED - - This red LED turns on when power is supplied to the board, either from USB or 5 V Input. - * - DC/DC Converter - - Provided DC 5 V to 3.3 V conversion, output current up to 2 A. - * - Board B Connectors - - A pair male and female header pins for mounting the `PoE board (B)`_ - * - IP101GRI (PHY) - - The physical layer (PHY) connection to the Ethernet cable is implemented using the `IP101GRI `_ chip. The connection between PHY and ESP32 is done through the reduced media-independent interface (RMII), a variant of the media-independent interface `(MII) `_ standard. The PHY supports the IEEE 802.3/802.3u standard of 10/100 Mbps. - * - RJ45 Port - - Ethernet network data transmission port. - * - Magnetics Module - - The Magnetics are part of the Ethernet specification to protect against faults and transients, including rejection of common mode signals between the transceiver IC and the cable. The magnetics also provide galvanic isolation between the transceiver and the Ethernet device. - * - Link/Activity LEDs - - Two LEDs (green and red) that respectively indicate the "Link" and "Activity" statuses of the PHY. - * - BOOT Button - - Download button. Holding down **BOOT** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - EN Button - - Reset button. - * - GPIO Header 1 - - This header provides six unpopulated through-hole solder pads connected to spare GPIOs of ESP32. For details, see `GPIO Header 1`_. - -.. note:: - - Automatic firmware download is supported. If following steps and using software described in Section `Start Application Development`_, users do not need to do any operation with BOOT button or EN button. - - -PoE Board (B) -^^^^^^^^^^^^^ - -This board coverts power delivered over the Ethernet cable (PoE) to provide a power supply for the Ethernet board (A). The main components of the PoE board (B) are shown on the block diagram under `Functionality Overview`_. - -The PoE board (B) has the following features: - -* Support for IEEE 802.3at -* Power output: 5 V, 1.4 A - -To take advantage of the PoE functionality the **RJ45 Port** of the Ethernet board (A) should be connected with an Ethernet cable to a switch that supports PoE. When the Ethernet board (A) detects 5 V power output from the PoE board (B), the USB power will be automatically cut off. - -.. figure:: ../../../_static/esp32-ethernet-kit-b-v1.0-layout.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit - PoE board (B) - :figclass: align-center - - ESP32-Ethernet-Kit - PoE board (B) layout (click to enlarge) - -.. list-table:: Table PoE board (B) - :widths: 40 150 - :header-rows: 1 - - * - Key Component - - Description - * - Board A Connector - - Four female (left) and four male (right) header pins for connecting the PoE board (B) to :ref:`Ethernet board (A) `. The pins on the left accept power coming from a PoE switch. The pins on the right deliver 5 V power supply to the Ethernet board (A). - * - External Power Terminals - - Optional power supply (26.6 ~ 54 V) to the PoE board (B). - - -.. _get-started-esp32-ethernet-kit-v1.2-setup-options: - -Setup Options -------------- - -This section describes options to configure the ESP32-Ethernet-Kit hardware. - - -Function Switch -^^^^^^^^^^^^^^^ - -When in On position, this DIP switch is routing listed GPIOs to FT2232H to provide JTAG functionality. When in Off position, the GPIOs may be used for other purposes. - -======= ================ -DIP SW GPIO Pin -======= ================ - 1 GPIO13 - 2 GPIO12 - 3 GPIO15 - 4 GPIO14 -======= ================ - - -RMII Clock Selection -^^^^^^^^^^^^^^^^^^^^ - -The ethernet MAC and PHY under RMII working mode need a common 50 MHz reference clock (i.e., RMII clock) that can be provided either externally, or generated from internal ESP32 APLL (not recommended). - -.. note:: - - For additional information on the RMII clock selection, please refer to `ESP32-Ethernet-Kit V1.2 Ethernet board (A) schematic`_, sheet 2, location D2. - - -RMII Clock Sourced Externally by PHY -"""""""""""""""""""""""""""""""""""" - -By default, the ESP32-Ethernet-Kit is configured to provide RMII clock for the IP101GRI PHY's 50M_CLKO output. The clock signal is generated by the frequency multiplication of 25 MHz crystal connected to the PHY. For details, please see the figure below. - -.. figure:: ../../../_static/esp32-ethernet-kit-rmii-clk-from-phy.png - :align: center - :scale: 80% - :alt: RMII Clock from IP101GRI PHY - :figclass: align-center - - RMII Clock from IP101GRI PHY - -Please note that the PHY is reset on power up by pulling the RESET_N signal down with a resistor. ESP32 should assert RESET_N high with GPIO5 to enable PHY. Only this can ensure the power-up of system. Otherwise ESP32 may enter download mode (when the clock signal of REF_CLK_50M is at a high logic level during the GPIO0 power-up sampling phase). - - -RMII Clock Sourced Internally from ESP32's APLL -""""""""""""""""""""""""""""""""""""""""""""""" - -Another option is to source the RMII Clock from internal ESP32 APLL, see figure below. The clock signal coming from GPIO0 is first inverted, to account for transmission line delay, and then supplied to the PHY. - -.. figure:: ../../../_static/esp32-ethernet-kit-rmii-clk-to-phy.png - :align: center - :scale: 80% - :alt: RMII Clock from ESP Internal APLL - :figclass: align-center - - RMII Clock from ESP Internal APLL - -To implement this option, users need to remove or add some RC components on the board. For details please refer to `ESP32-Ethernet-Kit V1.2 Ethernet board (A) schematic`_, sheet 2, location D2. Please note that if the APLL is already used for other purposes (e.g., I2S peripheral), then you have no choice but use an external RMII clock. - - -GPIO Allocation ---------------- - -This section describes allocation of ESP32 GPIOs to specific interfaces or functions of the ESP32-Ethernet-Kit. - - -IP101GRI (PHY) Interface -^^^^^^^^^^^^^^^^^^^^^^^^ - -The allocation of the ESP32 (MAC) pins to IP101GRI (PHY) is shown in the table below. Implementation of ESP32-Ethernet-Kit defaults to Reduced Media-Independent Interface (RMII). - -==== ================ =============== -No. ESP32 Pin (MAC) IP101GRI (PHY) -==== ================ =============== -*RMII Interface* ---------------------------------------- - 1 GPIO21 TX_EN - 2 GPIO19 TXD[0] - 3 GPIO22 TXD[1] - 4 GPIO25 RXD[0] - 5 GPIO26 RXD[1] - 6 GPIO27 CRS_DV - 7 GPIO0 REF_CLK ----- ---------------- --------------- -*Serial Management Interface* ---------------------------------------- - 8 GPIO23 MDC - 9 GPIO18 MDIO ----- ---------------- --------------- -*PHY Reset* ---------------------------------------- -10 GPIO5 Reset_N -==== ================ =============== - -.. note:: - - The allocation of all pins under the ESP32's *RMII Interface* is fixed and cannot be changed either through IO MUX or GPIO Matrix. REF_CLK can only be selected from GPIO0, GPIO16 or GPIO17 and it can not be changed through GPIO Matrix. - - -GPIO Header 1 -^^^^^^^^^^^^^ - -This header exposes some GPIOs that are not used elsewhere on the ESP32-Ethernet-Kit. - -==== ================ -No. ESP32 Pin -==== ================ - 1 GPIO32 - 2 GPIO33 - 3 GPIO34 - 4 GPIO35 - 5 GPIO36 - 6 GPIO39 -==== ================ - - -GPIO Header 2 -^^^^^^^^^^^^^ - -This header contains GPIOs that may be used for other purposes depending on scenarios described in column "Comments". - -==== ========== ==================== -No. ESP32 Pin Comments -==== ========== ==================== - 1 GPIO17 See note 1 - 2 GPIO16 See note 1 - 3 GPIO4 - 4 GPIO2 - 5 GPIO13 See note 2 - 6 GPIO12 See note 2 - 7 GPIO15 See note 2 - 8 GPIO14 See note 2 - 9 GND Ground -10 3V3 3.3 V power supply -==== ========== ==================== - -.. note:: - - 1. The ESP32 pins GPIO16 and GPIO17 are not broken out to the ESP32-WROVER-E module and therefore not available for use. If you need to use these pins, please solder a module without PSRAM memory inside, e.g., the ESP32-WROOM-32D or ESP32-SOLO-1. - - 2. Functionality depends on the settings of the `Function Switch`_. - - -GPIO Allocation Summary -^^^^^^^^^^^^^^^^^^^^^^^ - -.. csv-table:: - :header: ESP32-WROVER-E,IP101GRI,UART,JTAG,GPIO,Comments - - S_VP,,,,IO36, - S_VN,,,,IO39, - IO34,,,,IO34, - IO35,,,,IO35, - IO32,,,,IO32, - IO33,,,,IO33, - IO25,RXD[0],,,, - IO26,RXD[1],,,, - IO27,CRS_DV,,,, - IO14,,,TMS,IO14, - IO12,,,TDI,IO12, - IO13,,,TCK,IO13, - IO15,,,TDO,IO15, - IO2,,,,IO2, - IO0,REF_CLK,,,,See note 1 - IO4,,,,IO4, - IO16,,,,IO16 (NC),See note 2 - IO17,,,,IO17 (NC),See note 2 - IO5,Reset_N,,,,See note 1 - IO18,MDIO,,,, - IO19,TXD[0],,,, - IO21,TX_EN,,,, - RXD0,,RXD,,, - TXD0,,TXD,,, - IO22,TXD[1],,,, - IO23,MDC,,,, - -.. note:: - - 1. To prevent the power-on state of the GPIO0 from being affected by the clock output on the PHY side, the RESET_N signal to PHY defaults to low, turning the clock output off. After power-on you can control RESET_N with GPIO5 to turn the clock output on. See also `RMII Clock Sourced Externally by PHY`_. For PHYs that cannot turn off the clock output through RESET_N, it is recommended to use a crystal module that can be disabled/enabled externally. Similarly like when using RESET_N, the oscillator module should be disabled by default and turned on by ESP32 after power-up. For a reference design please see `ESP32-Ethernet-Kit V1.2 Ethernet board (A) schematic`_. - - 2. The ESP32 pins GPIO16 and GPIO17 are not broken out to the ESP32-WROVER-E module and therefore not available for use. If you need to use these pins, please solder a module without PSRAM memory inside, e.g., the ESP32-WROOM-32D or ESP32-SOLO-1. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-Ethernet-Kit, please make sure that the board is in good condition with no obvious signs of damage. - - -Initial Setup -^^^^^^^^^^^^^ - -1. Set the **Function Switch** on the :ref:`Ethernet board (A) ` to its default position by turning all the switches to **ON**. -2. To simplify flashing and testing of the application, do not input extra signals to the board headers. -3. The `PoE board (B)`_ can now be plugged in, but do not connect external power to it. -4. Connect the :ref:`Ethernet board (A) ` to the PC with a USB cable. -5. Turn the **Power Switch** from GND to 5V0 position, the **5V Power On LED** should light up. - - -Now to Development -^^^^^^^^^^^^^^^^^^ - -Proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. - -Move on to the next section only if you have successfully completed all the above steps. - - -Configure and Load the Ethernet Example -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -After setting up the development environment and testing the board, you can configure and flash the :example:`ethernet/basic` example. This example has been created for testing Ethernet functionality. It supports different PHY, including **IP101GRI** installed on :ref:`get-started-esp32-ethernet-kit-v1.2`. - - -Summary of Changes from ESP32-Ethernet-Kit V1.1 ------------------------------------------------ - -* Correct the placement of GPIO pin number marking on the board's silkscreen besides the DIP switch. -* Values of C1, C2, C42, and C43 are updated to 20 pF. For more information, please check `ESP32-Ethernet-Kit V1.2 Ethernet board (A) schematic`_. -* Replace ESP32-WROVER-B with ESP32-WROVER-E. - - -Other Versions of ESP32-Ethernet-Kit ------------------------------------- - -* :doc:`get-started-ethernet-kit-v1.0` -* :doc:`get-started-ethernet-kit-v1.1` - - -Related Documents ------------------ - -* `ESP32-Ethernet-Kit V1.2 Ethernet Board (A) Schematic`_ (PDF) -* `ESP32-Ethernet-Kit PoE Board (B) Schematic`_ (PDF) -* `ESP32-Ethernet-Kit V1.2 Ethernet Board (A) PCB Layout `_ (PDF) -* `ESP32-Ethernet-Kit PoE Board (B) PCB Layout `_ (PDF) -* `ESP32 Datasheet `_ (PDF) -* `ESP32-WROVER-E Datasheet `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - -For other design documentation for the board, please contact us at sales@espressif.com. - -.. _ESP32-Ethernet-Kit V1.1 Ethernet board (A) schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_A_V1.1_20190711.pdf -.. _ESP32-Ethernet-Kit PoE board (B) schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_B_V1.0_20190517.pdf -.. _ESP32-Ethernet-Kit V1.0 Ethernet board (A) schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_A_V1.0_20190517.pdf -.. _ESP32-Ethernet-Kit V1.2 Ethernet board (A) schematic: https://dl.espressif.com/dl/schematics/SCH_ESP32-Ethernet-Kit_A_V1.2_20200528.pdf - -.. toctree:: - :hidden: - - get-started-ethernet-kit-v1.0.rst - get-started-ethernet-kit-v1.1.rst - diff --git a/docs/en/hw-reference/esp32/get-started-pico-devkitm-2.rst b/docs/en/hw-reference/esp32/get-started-pico-devkitm-2.rst deleted file mode 100644 index 7c0b2ea11bd9..000000000000 --- a/docs/en/hw-reference/esp32/get-started-pico-devkitm-2.rst +++ /dev/null @@ -1,369 +0,0 @@ -ESP32-PICO-DevKitM-2 -******************** - -:link_to_translation:`zh_CN:[中文]` - -Overview -======== - -ESP32-PICO-DevKitM-2 is an ESP32-based development board produced by `Espressif `_. - -The core of this board is `ESP32-PICO-MINI-02/02U `_ module with complete Wi-Fi and Bluetooth® functionalities. The development board features a USB-to-UART Bridge circuit which allows developers to connect the board to a computer's USB port for flashing and debugging. - -All the IO signals and system power on ESP32-PICO-MINI-02/02U are led out to two rows of 18 x 0.1" header pads on both sides of the development board for easy access. For compatibility with Dupont wires, all header pads are populated with two rows of male pin headers. - -.. note:: - - ESP32-PICO-DevKitM-2 comes with male headers by default. - -ESP32-PICO-DevKitM-2 provides the users with hardware for development of applications based on the ESP32, making it easier for users to explore ESP32 functionalities. - -.. figure:: ../../../_static/esp32-pico-devkitm-2-overview.png - :align: center - :scale: 70% - :alt: ESP32-PICO-DevKitM-2 (click to enlarge) - :figclass: align-center - - ESP32-PICO-DevKitM-2 Overview (click to enlarge) - -This guide covers: - -- `Getting Started`_: Provides an overview of the ESP32-PICO-DevKitM-2 and software setup instructions to get started. -- `Contents and Packaging`_: Provides information about packaging and contents for retail and wholesale orders. -- `Hardware Reference`_: Provides more detailed information about the ESP32-PICO-DevKitM-2's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions (if any) of the ESP32-PICO-DevKitM-2. -- `Related Documents`_: Gives links to related documentation. - - -Getting Started -=============== - -This section describes how to get started with the ESP32-PICO-DevKitM-2. It begins with a few introductory sections about the ESP32-PICO-DevKitM-2, then Section `Start Application Development`_ provides instructions on how to flash firmware onto the ESP32-PICO-DevKitM-2. - - -.. _get-started-pico-devkitm-2-board-front: - -Description of Components -------------------------- - -The following figure and the table below describe the key components, interfaces, and controls of the ESP32-PICO-DevKitM-2 board. We take the board with a ESP32-PICO-MINI-02 module as an example in the following sections. - -.. figure:: ../../../_static/esp32-pico-devkitm-2-layout-front.png - :align: center - :scale: 90% - :alt: ESP32-PICO-DevKitM-2 (click to enlarge) - :figclass: align-center - - ESP32-PICO-DevKitM-2 board layout - front (click to enlarge) - -Below is the description of the items identified in the figure starting from the top left corner and going clockwise. - -.. list-table:: - :widths: 10 25 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-PICO-MINI-02 - - Standard ESP32-PICO-MINI-02 module soldered to the ESP32-PICO-DevKitM-2 board. The complete ESP32 system on a chip (ESP32 SoC) has been integrated into the module. Users can also select the board with ESP32-PICO-MINI-02U soldered. - * - LDO - - V-to-3.3V Low dropout voltage regulator (LDO). - * - USB-to-UART bridge - - CP2102N, single-chip USB-UART bridge that offers up to 3 Mbps transfers rates. - * - Micro-B USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the board. - * - 5V Power On LED - - This red LED turns on when power is supplied to the board. For details, see the schematic in `Related Documents`_. - * - I/O Connector - - All the pins on ESP32-PICO-MINI-02 are broken out to pin headers. You can program ESP32 to enable multiple functions, such as PWM, ADC, DAC, I2C, I2S, SPI, etc. For details, please see Section `Pin Descriptions`_. - * - BOOT Button - - Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - EN Button - - Reset button. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-PICO-DevKitM-2, please make sure that the board is in good condition with no obvious signs of damage. - - -Required Hardware -""""""""""""""""" - -- 1 x ESP32-PICO-DevKitM-2 -- 1 x USB 2.0 A to Micro B cable -- 1 x Computer running Windows, Linux, or macOS - - -.. _user-guide-pico-devkitm-2-software-setup: - -Software Setup -"""""""""""""" - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment. - - -Contents and Packaging -====================== - -Retail Orders -------------- - -If you order one or several samples of the board, each ESP32-PICO-DevKitM-2 development board comes in an individual package. - -For retail orders, please go to https://www.espressif.com/en/contact-us/get-samples. - - -Wholesale Orders ----------------- - -If you order in bulk, the boards come in large cardboard boxes. - -For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales-questions. - - -Hardware Reference -================== - -Block Diagram -------------- - -The block diagram below shows the main components of ESP32-PICO-DevKitM-2 and their interconnections. - -.. figure:: ../../../_static/esp32-pico-devkitm-2-block.png - :align: center - :scale: 70% - :alt: ESP32-PICO-DevKitM-2 (click to enlarge) - :figclass: align-center - - ESP32-PICO-DevKitM-2 Block Diagram (click to enlarge) - - -Power Supply Options --------------------- - -There are three mutually exclusive ways to provide power to the board: - -* Micro USB port, default power supply -* 5V/GND header pins -* 3V3/GND header pins - -.. warning:: - - The power supply must be provided using **one and only one of the options above**, otherwise the board and/or the power supply source can be damaged. - - -Pin Descriptions ----------------- - -The two tables below provide the **Name** and **Function** of I/O header pins on both sides of the board, see :ref:`get-started-pico-devkitm-2-board-front`. The pin numbering and header names are the same as in the schematic given in `Related Documents`_. - - -Header J2 -""""""""" - -.. list-table:: - :widths: 5 5 5 35 - :header-rows: 1 - - * - No. - - Name - - Type - - Function - * - 1 - - IO20 - - I/O - - GPIO20 - * - 2 - - IO21 - - I/O - - GPIO21, VSPIHD, EMAC_TX_EN - * - 3 - - IO22 - - I/O - - GPIO22, VSPIWP, U0RTS, EMAC_TXD1 - * - 4 - - IO19 - - I/O - - GPIO19, VSPIQ, U0CTS, EMAC_TXD0 - * - 5 - - IO8 - - I/O - - GPIO8, SD_DATA1, HS1_DATA1, U2CTS - * - 6 - - IO7 - - I/O - - GPIO7, SD_DATA0, HS1_DATA0, U2RTS - * - 7 - - IO5 - - I/O - - GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK - * - 8 - - NC - - \- - - NC - * - 9 - - NC - - \- - - NC - * - 10 - - RXD0 - - I/O - - GPIO3, U0RXD :ref:`(See 1) `, CLK_OUT2 - * - 11 - - TXD0 - - I/O - - GPIO1, U0TXD :ref:`(See 1) `, CLK_OUT3, EMAC_RXD2 - * - 12 - - IO35 - - I - - ADC1_CH7, RTC_GPIO5 - * - 13 - - IO34 - - I - - ADC1_CH6, RTC_GPIO4 - * - 14 - - IO38 - - I - - GPIO38, ADC1_CH2, RTC_GPIO2 - * - 15 - - IO37 - - I - - GPIO37, ADC1_CH1, RTC_GPIO1 - * - 16 - - EN - - I - - CHIP_PU - * - 17 - - GND - - P - - Ground - * - 18 - - VDD33 (3V3) - - P - - 3.3 V power supply - - -Header J3 -""""""""" - -.. list-table:: - :widths: 5 5 5 35 - :header-rows: 1 - - * - No. - - Name - - Type - - Function - * - 1 - - GND - - P - - Ground - * - 2 - - SENSOR_VP (FSVP) - - I - - GPIO36, ADC1_CH0, RTC_GPIO0 - * - 3 - - SENSOR_VN (FSVN) - - I - - GPIO39, ADC1_CH3, RTC_GPIO3 - * - 4 - - IO25 - - I/O - - GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 - * - 5 - - IO26 - - I/O - - GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 - * - 6 - - IO32 - - I/O - - 32K_XP :ref:`(See 2a) `, ADC1_CH4, TOUCH9, RTC_GPIO9 - * - 7 - - IO33 - - I/O - - 32K_XN :ref:`(See 2b) `, ADC1_CH5, TOUCH8, RTC_GPIO8 - * - 8 - - IO27 - - I/O - - GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV - * - 9 - - IO14 - - I/O - - ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 - * - 10 - - IO12 - - I/O - - ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI :ref:`(See 3) `, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 - * - 11 - - IO13 - - I/O - - ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER - * - 12 - - IO15 - - I/O - - ADC2_CH3, TOUCH3, RTC_GPIO13, MTDO, HSPICS0, HS2_CMD, SD_CMD, EMAC_RXD3 - * - 13 - - IO2 - - I/O - - ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 - * - 14 - - IO4 - - I/O - - ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - * - 15 - - IO0 - - I/O - - ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK - * - 16 - - VDD33 (3V3) - - P - - 3.3V power supply - * - 17 - - GND - - P - - Ground - * - 18 - - EXT_5V (5V) - - P - - 5V power supply - - -.. _get-started-pico-devkitm-2-pin-notes: - -.. note:: - - 1. This pin is connected to the pin of the USB bridge chip on the board. - 2. 32.768 kHz crystal oscillator: - a) input - b) output - 3. The operating voltage of ESP32-PICO-DevKitM-2's embedded SPI flash is 3.3 V. Therefore, the strapping pin MTDI should be pulled down during the module power-on reset. If connected, please make sure that this pin is not held up on reset. - - -Pin Layout -"""""""""" -.. figure:: ../../../_static/esp32-pico-devkitm-2-pinout.png - :align: center - :scale: 50% - :alt: ESP32-PICO-DevKitM-2 (click to enlarge) - :figclass: align-center - - ESP32-PICO-DevKitM-2 Pin Layout (click to enlarge) - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -* `ESP32-PICO-MINI-02 & ESP32-PICO-MINI-1U Datasheet `_ (PDF) -* `ESP Product Selector `_ -* `ESP32-PICO-DevKitM-2 Schematic `_ (PDF) -* `ESP32-PICO-DevKitM-2 PCB Layout `_ (PDF) - -For other design documentation for the board, please contact us at sales@espressif.com. diff --git a/docs/en/hw-reference/esp32/get-started-pico-kit-1.rst b/docs/en/hw-reference/esp32/get-started-pico-kit-1.rst deleted file mode 100644 index c0fa06dc31be..000000000000 --- a/docs/en/hw-reference/esp32/get-started-pico-kit-1.rst +++ /dev/null @@ -1,379 +0,0 @@ -ESP32-PICO-KIT-1 -**************** - -:link_to_translation:`zh_CN:[中文]` - -Overview -======== - -ESP32-PICO-KIT-1 is an ESP32-based development board produced by `Espressif `_. - -The core of this board is `ESP32-PICO-V3 `_ - a System-in-Package (SiP) module with complete Wi-Fi and Bluetooth® functionalities. Compared to other ESP32 modules, ESP32-PICO-V3 integrates the following peripheral components in one single package, which otherwise would need to be installed separately: - -- 40 MHz crystal oscillator -- 4 MB flash -- Filter capacitors -- RF matching network - -This setup reduces the costs of additional external components as well as the cost of assembly and testing and also increases the overall usability of the product. - -The development board features a USB-to-UART Bridge circuit which allows developers to connect the board to a computer's USB port for flashing and debugging. - -All the IO signals and system power on ESP32-PICO-V3 are led out to two rows of 18 x 0.1" header pads on both sides of the development board for easy access. For compatibility with Dupont wires, all header pads are populated with two rows of male pin headers. - -.. note:: - - ESP32-PICO-KIT-1 comes with male headers by default. - -ESP32-PICO-KIT-1 provides the users with hardware for development of applications based on the ESP32, making it easier for users to explore ESP32 functionalities. - -.. figure:: ../../../_static/esp32-pico-kit-1-overview.png - :align: center - :scale: 70% - :alt: ESP32-PICO-KIT-1 (click to enlarge) - :figclass: align-center - - ESP32-PICO-KIT-1 Overview (click to enlarge) - -This guide covers: - -- `Getting Started`_: Provides an overview of the ESP32-PICO-KIT-1 and software setup instructions to get started. -- `Contents and Packaging`_: Provides information about packaging and contents for retail and wholesale orders. -- `Hardware Reference`_: Provides more detailed information about the ESP32-PICO-KIT-1's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions of the ESP32-PICO-KIT-1. -- `Related Documents`_: Gives links to related documentation. - - -Getting Started -=============== - -This section describes how to get started with the ESP32-PICO-KIT-1. It begins with a few introductory sections about the ESP32-PICO-KIT-1, then Section `Start Application Development`_ provides instructions on how to flash firmware onto the ESP32-PICO-KIT-1. - - -.. _get-started-pico-kit-1-board-front: - -Description of Components -------------------------- - -The following figure and the table below describe the key components, interfaces, and controls of the ESP32-PICO-KIT-1 board. - -.. figure:: ../../../_static/esp32-pico-kit-1-layout-front.png - :align: center - :scale: 90% - :alt: ESP32-PICO-KIT-1 (click to enlarge) - :figclass: align-center - - ESP32-PICO-KIT-1 board layout - front (click to enlarge) - - -Below is the description of the items identified in the figure starting from the top left corner and going clockwise. - -.. list-table:: - :widths: 10 25 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-PICO-V3 - - Standard ESP32-PICO-V3 module soldered to the ESP32-PICO-KIT-1 board. The complete ESP32 system on a chip (ESP32 SoC) has been integrated into the SiP module, requiring only an external antenna with LC matching network, decoupling capacitors, and a pull-up resistor for EN signals to function properly. - * - LDO - - 5V-to-3.3V Low dropout voltage regulator (LDO). - * - USB-to-UART bridge - - CP2102N, single-chip USB-to-UART bridge that offers up to 3 Mbps transfers rates. - * - Micro USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the board. - * - 5V Power On LED - - This red LED turns on when power is supplied to the board. For details, see the schematic in `Related Documents`_. - * - I/O Connector - - All the pins on ESP32-PICO-V3 are broken out to pin headers. You can program ESP32 to enable multiple functions, such as PWM, ADC, DAC, I2C, I2S, SPI, etc. For details, please see Section `Pin Descriptions`_. - * - BOOT Button - - Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - EN Button - - Reset button. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-PICO-KIT-1, please make sure that the board is in good condition with no obvious signs of damage. - - -Required Hardware -""""""""""""""""" - -- 1 x ESP32-PICO-KIT-1 -- 1 x USB 2.0 A to Micro B cable -- 1 x Computer running Windows, Linux, or macOS - - -.. _user-guide-pico-kit-1-software-setup: - -Software Setup -"""""""""""""" - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment. - - -Contents and Packaging -====================== - -Retail Orders -------------- - -If you order one or several samples of the board, each ESP32-PICO-KIT-1 development board comes in an individual package. - -For retail orders, please go to https://www.espressif.com/en/contact-us/get-samples. - - -Wholesale Orders ----------------- - -If you order in bulk, the boards come in large cardboard boxes. - -For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales-questions. - - -Hardware Reference -================== - -Block Diagram -------------- - -The block diagram below shows the main components of ESP32-PICO-KIT-1 and their interconnections. - -.. figure:: ../../../_static/esp32-pico-kit-1-block.png - :align: center - :scale: 70% - :alt: ESP32-PICO-KIT-1 (click to enlarge) - :figclass: align-center - - ESP32-PICO-KIT-1 Block Diagram (click to enlarge) - - -Power Supply Options --------------------- - -There are three mutually exclusive ways to provide power to the board: - -* Micro USB port, default power supply -* 5V/GND header pins -* 3V3/GND header pins - -.. warning:: - - The power supply must be provided using **one and only one of the options above**, otherwise the board and/or the power supply source can be damaged. - - -Pin Descriptions ----------------- - -The two tables below provide the **Name** and **Function** of I/O header pins on both sides of the board, see :ref:`get-started-pico-kit-1-board-front`. The pin numbering and header names are the same as in the schematic given in `Related Documents`_. - - -Header J2 -""""""""" - -.. list-table:: - :widths: 5 5 5 35 - :header-rows: 1 - - * - No. - - Name - - Type - - Function - * - 1 - - IO20 - - I/O - - GPIO20 - * - 2 - - IO21 - - I/O - - GPIO21, VSPIHD, EMAC_TX_EN - * - 3 - - IO22 - - I/O - - GPIO22, VSPIWP, U0RTS, EMAC_TXD1 - * - 4 - - IO19 - - I/O - - GPIO19, VSPIQ, U0CTS, EMAC_TXD0 - * - 5 - - IO8 - - I/O - - GPIO8, SD_DATA1, HS1_DATA1, U2CTS - * - 6 - - IO7 - - I/O - - GPIO7, SD_DATA0, HS1_DATA0, U2RTS - * - 7 - - IO5 - - I/O - - GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK - * - 8 - - IO10 - - I/O - - GPIO10, SD_DATA3, SPIWP, HS1_DATA3, U1TXD - * - 9 - - IO9 - - I/O - - GPIO9, SD_DATA2, SPIHD, HS1_DATA2, U1RXD - * - 10 - - RXD0 - - I/O - - GPIO3, U0RXD :ref:`(See 1) `, CLK_OUT2 - * - 11 - - TXD0 - - I/O - - GPIO1, U0TXD :ref:`(See 1) `, CLK_OUT3, EMAC_RXD2 - * - 12 - - IO35 - - I - - ADC1_CH7, RTC_GPIO5 - * - 13 - - IO34 - - I - - ADC1_CH6, RTC_GPIO4 - * - 14 - - IO38 - - I - - GPIO38, ADC1_CH2, RTC_GPIO2 - * - 15 - - IO37 - - I - - GPIO37, ADC1_CH1, RTC_GPIO1 - * - 16 - - EN - - I - - CHIP_PU - * - 17 - - GND - - P - - Ground - * - 18 - - VDD33 (3V3) - - P - - 3.3 V power supply - - -Header J3 -""""""""" - -.. list-table:: - :widths: 5 5 5 35 - :header-rows: 1 - - * - No. - - Name - - Type - - Function - * - 1 - - GND - - P - - Ground - * - 2 - - SENSOR_VP (FSVP) - - I - - GPIO36, ADC1_CH0, RTC_GPIO0 - * - 3 - - SENSOR_VN (FSVN) - - I - - GPIO39, ADC1_CH3, RTC_GPIO3 - * - 4 - - IO25 - - I/O - - GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 - * - 5 - - IO26 - - I/O - - GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 - * - 6 - - IO32 - - I/O - - 32K_XP :ref:`(See 2a) `, ADC1_CH4, TOUCH9, RTC_GPIO9 - * - 7 - - IO33 - - I/O - - 32K_XN :ref:`(See 2b) `, ADC1_CH5, TOUCH8, RTC_GPIO8 - * - 8 - - IO27 - - I/O - - GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV - * - 9 - - IO14 - - I/O - - ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 - * - 10 - - IO12 - - I/O - - ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI :ref:`(See 3) `, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 - * - 11 - - IO13 - - I/O - - ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER - * - 12 - - IO15 - - I/O - - ADC2_CH3, TOUCH3, RTC_GPIO13, MTDO, HSPICS0, HS2_CMD, SD_CMD, EMAC_RXD3 - * - 13 - - IO2 - - I/O - - ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 - * - 14 - - IO4 - - I/O - - ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - * - 15 - - IO0 - - I/O - - ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK - * - 16 - - VDD33 (3V3) - - P - - 3.3V power supply - * - 17 - - GND - - P - - Ground - * - 18 - - EXT_5V (5V) - - P - - 5V power supply - - -.. _get-started-pico-kit-1-pin-notes: - -.. note:: - - 1. This pin is connected to the pin of the USB bridge chip on the board. - 2. 32.768 kHz crystal oscillator: - a) input - b) output - 3. The operating voltage of ESP32-PICO-KIT-1's embedded SPI flash is 3.3 V. Therefore, the strapping pin MTDI should be pulled down during the module power-on reset. If connected, please make sure that this pin is not held up on reset. - - -Pin Layout -"""""""""" -.. figure:: ../../../_static/esp32-pico-kit-1-pinout.png - :align: center - :scale: 50% - :alt: ESP32-PICO-KIT-1 (click to enlarge) - :figclass: align-center - - ESP32-PICO-KIT-1 Pin Layout(click to enlarge) - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -* `ESP32-PICO-V3 Datasheet `_ (PDF) -* `ESP Product Selector `_ -* `ESP32-PICO-KIT-1 Schematic `_ (PDF) -* `ESP32-PICO-KIT-1 PCB Layout `_ (PDF) - -For other design documentation for the board, please contact us at sales@espressif.com. diff --git a/docs/en/hw-reference/esp32/get-started-pico-kit-v3.rst b/docs/en/hw-reference/esp32/get-started-pico-kit-v3.rst deleted file mode 100644 index 0b8bd16cfba5..000000000000 --- a/docs/en/hw-reference/esp32/get-started-pico-kit-v3.rst +++ /dev/null @@ -1,80 +0,0 @@ -ESP32-PICO-KIT V3 Getting Started Guide -======================================= - -:link_to_translation:`zh_CN:[中文]` - -This guide shows how to get started with the ESP32-PICO-KIT V3 mini development board. For the description of other ESP32-PICO-KIT versions, please check :doc:`../../hw-reference/index`. - - -What You Need -------------- - -* ESP32-PICO-KIT V3 mini development board -* USB 2.0 A to Micro B cable -* Computer running Windows, Linux, or macOS - -You can skip the introduction sections and go directly to Section `Start Application Development`_. - - -Overview --------- - -ESP32-PICO-KIT V3 is an ESP32-based mini development board produced by `Espressif `_. The core of this board is ESP32-PICO-D4 - a System-in-Package (SiP) module. - -The development board features a USB-UART Bridge circuit, which allows developers to connect the board to a computer's USB port for flashing and debugging. - -All the IO signals and system power on ESP32-PICO-D4 are led out to two rows of 20 x 0.1" header pads on both sides of the development board for easy access. - - -Functional Description ----------------------- - -The following figure and the table below describe the key components, interfaces, and controls of the ESP32-PICO-KIT V3 board. - -.. figure:: ../../../_static/esp32-pico-kit-v3-layout.jpg - :align: center - :alt: ESP32-PICO-KIT V3 board layout - :figclass: align-center - - ESP32-PICO-KIT V3 board layout - -Below is the description of the items identified in the figure starting from the top left corner and going clockwise. - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-PICO-D4 - - Standard ESP32-PICO-D4 module soldered to the ESP32-PICO-KIT V3 board. The complete ESP32 system on a chip (ESP32 SoC) has been integrated into the SiP module, requiring only an external antenna with LC matching network, decoupling capacitors, and a pull-up resistor for EN signals to function properly. - * - LDO - - 5V-to-3.3V Low dropout voltage regulator (LDO). - * - USB-UART bridge - - Single-chip USB-UART bridge provides up to 1 Mbps transfers rates. - * - Micro USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the board. - * - Power On LED - - This red LED turns on when power is supplied to the board. - * - I/O - - All the pins on ESP32-PICO-D4 are broken out to pin headers. You can program ESP32 to enable multiple functions, such as PWM, ADC, DAC, I2C, I2S, SPI, etc. - * - BOOT Button - - Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - EN Button - - Reset button. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-PICO-KIT V3, please make sure that the board is in good condition with no obvious signs of damage. - -After that, proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. - - -Related Documents ------------------ - -* `ESP32-PICO-KIT V3 schematic `_ (PDF) -* `ESP32-PICO-D4 Datasheet `_ (PDF) -* :doc:`../../hw-reference/index` diff --git a/docs/en/hw-reference/esp32/get-started-pico-kit.rst b/docs/en/hw-reference/esp32/get-started-pico-kit.rst deleted file mode 100644 index f3b137a0f50a..000000000000 --- a/docs/en/hw-reference/esp32/get-started-pico-kit.rst +++ /dev/null @@ -1,247 +0,0 @@ -ESP32-PICO-KIT V4/V4.1 Getting Started Guide -============================================ - -:link_to_translation:`zh_CN:[中文]` - -This guide shows how to get started with the ESP32-PICO-KIT V4/V4.1 mini development board. For the description of other ESP32-PICO-KIT versions, please check :doc:`../../hw-reference/index`. - -This particular description covers ESP32-PICO-KIT V4 and V4.1. The difference is the upgraded USB-UART bridge from CP2102 in V4 with up to 1 Mbps transfer rates to CP2102N in V4.1 with up to 3 Mbps transfer rates. - - -What You Need -------------- - -* :ref:`ESP32-PICO-KIT mini development board ` -* USB 2.0 A to Micro B cable -* Computer running Windows, Linux, or macOS - -You can skip the introduction sections and go directly to Section `Start Application Development`_. - - -Overview --------- - -ESP32-PICO-KIT is an ESP32-based mini development board produced by `Espressif `_. - -The core of this board is ESP32-PICO-D4 - a System-in-Package (SiP) module with complete Wi-Fi and Bluetooth® functionalities. Compared to other ESP32 modules, ESP32-PICO-D4 integrates the following peripheral components in one single package, which otherwise would need to be installed separately: - -- 40 MHz crystal oscillator -- 4 MB flash -- Filter capacitors -- RF matching links - -This setup reduces the costs of additional external components as well as the cost of assembly and testing and also increases the overall usability of the product. - -The development board features a USB-UART Bridge circuit which allows developers to connect the board to a computer's USB port for flashing and debugging. - -All the IO signals and system power on ESP32-PICO-D4 are led out to two rows of 20 x 0.1" header pads on both sides of the development board for easy access. For compatibility with Dupont wires, 2 x 17 header pads are populated with two rows of male pin headers. The remaining 2 x 3 header pads beside the antenna are not populated. These pads may be populated later by the user if required. - -.. note:: - - 1. There are two versions of ESP32-PICO-KIT boards, respectively with male headers and female headers. In this guide, the male header version is taken as an example. - 2. The 2 x 3 pads not populated with pin headers are connected to the flash memory embedded in the ESP32-PICO-D4 SiP module. For more details, see module's datasheet in `Related Documents`_. - - -Functionality Overview ----------------------- - -The block diagram below shows the main components of ESP32-PICO-KIT and their interconnections. - -.. figure:: ../../../_static/esp32-pico-kit-v4-functional-block-diagram.png - :align: center - :alt: ESP32-PICO-KIT functional block diagram - :figclass: align-center - - ESP32-PICO-KIT block diagram - - -Functional Description ----------------------- - -The following figure and the table below describe the key components, interfaces, and controls of the ESP32-PICO-KIT board. - -.. _get-started-pico-kit-v4-board-front: - -.. figure:: ../../../_static/esp32-pico-kit-v4.1-f-layout.jpeg - :align: center - :alt: ESP32-PICO-KIT board layout (with female headers) - :figclass: align-center - - ESP32-PICO-KIT board layout (with female headers) - -Below is the description of the items identified in the figure starting from the top left corner and going clockwise. - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-PICO-D4 - - Standard ESP32-PICO-D4 module soldered to the ESP32-PICO-KIT board. The complete ESP32 system on a chip (ESP32 SoC) has been integrated into the SiP module, requiring only an external antenna with LC matching network, decoupling capacitors, and a pull-up resistor for EN signals to function properly. - * - LDO - - 5V-to-3.3V Low dropout voltage regulator (LDO). - * - USB-UART bridge - - Single-chip USB-UART bridge: CP2102 in V4 provides up to 1 Mbps transfer rates and CP2102N in V4.1 offers up to 3 Mbps transfers rates. - * - Micro USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the board. - * - 5V Power On LED - - This red LED turns on when power is supplied to the board. For details, see the schematics in `Related Documents`_. - * - I/O - - All the pins on ESP32-PICO-D4 are broken out to pin headers. You can program ESP32 to enable multiple functions, such as PWM, ADC, DAC, I2C, I2S, SPI, etc. For details, please see Section `Pin Descriptions`_. - * - BOOT Button - - Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - EN Button - - Reset button. - - -Power Supply Options --------------------- - -There are three mutually exclusive ways to provide power to the board: - -* Micro USB port, default power supply -* 5V / GND header pins -* 3V3 / GND header pins - -.. warning:: - - The power supply must be provided using **one and only one of the options above**, otherwise the board and/or the power supply source can be damaged. - - -Pin Descriptions ----------------- - -The two tables below provide the **Name** and **Function** of I/O header pins on both sides of the board, see :ref:`get-started-pico-kit-v4-board-front`. The pin numbering and header names are the same as in the schematic given in `Related Documents`_. - - -Header J2 -""""""""" - -====== ================= ====== ====================================================== -No. Name Type Function -====== ================= ====== ====================================================== -1 FLASH_SD1 (FSD1) I/O | GPIO8, SD_DATA1, SPID, HS1_DATA1 :ref:`(See 1) ` , U2CTS -2 FLASH_SD3 (FSD3) I/O | GPIO7, SD_DATA0, SPIQ, HS1_DATA0 :ref:`(See 1) ` , U2RTS -3 FLASH_CLK (FCLK) I/O | GPIO6, SD_CLK, SPICLK, HS1_CLK :ref:`(See 1) ` , U1CTS -4 IO21 I/O | GPIO21, VSPIHD, EMAC_TX_EN -5 IO22 I/O | GPIO22, VSPIWP, U0RTS, EMAC_TXD1 -6 IO19 I/O | GPIO19, VSPIQ, U0CTS, EMAC_TXD0 -7 IO23 I/O | GPIO23, VSPID, HS1_STROBE -8 IO18 I/O | GPIO18, VSPICLK, HS1_DATA7 -9 IO5 I/O | GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK -10 IO10 I/O | GPIO10, SD_DATA3, SPIWP, HS1_DATA3, U1TXD -11 IO9 I/O | GPIO9, SD_DATA2, SPIHD, HS1_DATA2, U1RXD -12 RXD0 I/O | GPIO3, U0RXD :ref:`(See 3) ` , CLK_OUT2 -13 TXD0 I/O | GPIO1, U0TXD :ref:`(See 3) ` , CLK_OUT3, EMAC_RXD2 -14 IO35 I | ADC1_CH7, RTC_GPIO5 -15 IO34 I | ADC1_CH6, RTC_GPIO4 -16 IO38 I | GPIO38, ADC1_CH2, RTC_GPIO2 -17 IO37 I | GPIO37, ADC1_CH1, RTC_GPIO1 -18 EN I | CHIP_PU -19 GND P | Ground -20 VDD33 (3V3) P | 3.3V power supply -====== ================= ====== ====================================================== - - -Header J3 -""""""""" - -====== ================= ====== ====================================================== -No. Name Type Function -====== ================= ====== ====================================================== -1 FLASH_CS (FCS) I/O | GPIO16, HS1_DATA4 :ref:`(See 1) ` , U2RXD, EMAC_CLK_OUT -2 FLASH_SD0 (FSD0) I/O | GPIO17, HS1_DATA5 :ref:`(See 1) ` , U2TXD, EMAC_CLK_OUT_180 -3 FLASH_SD2 (FSD2) I/O | GPIO11, SD_CMD, SPICS0, HS1_CMD :ref:`(See 1) ` , U1RTS -4 SENSOR_VP (FSVP) I | GPIO36, ADC1_CH0, RTC_GPIO0 -5 SENSOR_VN (FSVN) I | GPIO39, ADC1_CH3, RTC_GPIO3 -6 IO25 I/O | GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 -7 IO26 I/O | GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 -8 IO32 I/O | 32K_XP :ref:`(See 2a) ` , ADC1_CH4, TOUCH9, RTC_GPIO9 -9 IO33 I/O | 32K_XN :ref:`(See 2b) ` , ADC1_CH5, TOUCH8, RTC_GPIO8 -10 IO27 I/O | GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17 - | EMAC_RX_DV -11 IO14 I/O | ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, - | HS2_CLK, SD_CLK, EMAC_TXD2 -12 IO12 I/O | ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI :ref:`(See 4) ` , HSPIQ, - | HS2_DATA2, SD_DATA2, EMAC_TXD3 -13 IO13 I/O | ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, - | HS2_DATA3, SD_DATA3, EMAC_RX_ER -14 IO15 I/O | ADC2_CH3, TOUCH3, RTC_GPIO13, MTDO, HSPICS0 - | HS2_CMD, SD_CMD, EMAC_RXD3 -15 IO2 I/O | ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, - | HS2_DATA0, SD_DATA0 -16 IO4 I/O | ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, - | HS2_DATA1, SD_DATA1, EMAC_TX_ER -17 IO0 I/O | ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1 - | EMAC_TX_CLK -18 VDD33 (3V3) P | 3.3V power supply -19 GND P | Ground -20 EXT_5V (5V) P | 5V power supply -====== ================= ====== ====================================================== - - -.. _get-started-pico-kit-v4-pin-notes: - -.. note:: - - 1. This pin is connected to the flash pin of ESP32-PICO-D4. - 2. 32.768 kHz crystal oscillator: a) input, b) output. - 3. This pin is connected to the pin of the USB bridge chip on the board. - 4. The operating voltage of ESP32-PICO-KIT's embedded SPI flash is 3.3 V. Therefore, the strapping pin MTDI should hold bit zero during the module power-on reset. If connected, please make sure that this pin is not held up on reset. - - -Pin Layout -^^^^^^^^^^ -.. figure:: ../../../_static/esp32-pico-kit-v4-pinout.png - :align: center - :scale: 43% - :alt: ESP32-PICO-KIT (click to enlarge) - - ESP32-PICO-KIT Pin Layout (click to enlarge) - - -Start Application Development ------------------------------ - -Before powering up your ESP32-PICO-KIT, please make sure that the board is in good condition with no obvious signs of damage. - -After that, proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. - - -Board Dimensions ----------------- - -The dimensions are 52 x 20.3 x 10 mm (2.1" x 0.8" x 0.4"). - -.. figure:: ../../../_static/esp32-pico-kit-v4.1-dimensions-back.jpg - :align: center - :alt: ESP32-PICO-KIT dimensions - back (with male headers) - :figclass: align-center - - ESP32-PICO-KIT dimensions - back (with male headers) - -.. figure:: ../../../_static/esp32-pico-kit-v4-dimensions-side.jpg - :align: center - :alt: ESP32-PICO-KIT V4 dimensions - side (with male headers) - :figclass: align-center - - ESP32-PICO-KIT dimensions - side (with male headers) - -For the board physical construction details, please refer to its Reference Design listed below. - - -Related Documents ------------------ - -* `ESP32-PICO-KIT V4 schematic `_ (PDF) -* `ESP32-PICO-KIT V4.1 schematic `_ (PDF) -* `ESP32-PICO-KIT Reference Design `_ containing OrCAD schematic, PCB layout, gerbers and BOM -* `ESP32-PICO-D4 Datasheet `_ (PDF) -* :doc:`../../hw-reference/index` - - -.. toctree:: - :hidden: - - get-started-pico-kit-v3 diff --git a/docs/en/hw-reference/esp32/get-started-wrover-kit-v2.rst b/docs/en/hw-reference/esp32/get-started-wrover-kit-v2.rst deleted file mode 100644 index ecf2e140ce33..000000000000 --- a/docs/en/hw-reference/esp32/get-started-wrover-kit-v2.rst +++ /dev/null @@ -1,199 +0,0 @@ -ESP-WROVER-KIT V2 Getting Started Guide -======================================= - -:link_to_translation:`zh_CN:[中文]` - -This guide shows how to get started with the ESP-WROVER-KIT V2 development board and also provides information about its functionality and configuration options. For the description of other ESP-WROVER-KIT versions, please check :doc:`../../hw-reference/index`. - - -What You Need -------------- - -* ESP-WROVER-KIT V2 board -* USB 2.0 cable (A to Micro-B) -* Computer running Windows, Linux, or macOS - -You can skip the introduction sections and go directly to Section `Start Application Development`_. - - -Overview --------- - -ESP-WROVER-KIT is an ESP32-based development board produced by `Espressif `_. This board features an integrated LCD screen and microSD card slot. - -ESP-WROVER-KIT comes with the following ESP32 modules: - -- ESP32-WROOM-32 -- ESP32-WROVER series - -Its another distinguishing feature is the embedded FTDI FT2232HL chip - an advanced multi-interface USB bridge. This chip enables to use JTAG for direct debugging of ESP32 through the USB interface without a separate JTAG debugger. ESP-WROVER-KIT makes development convenient, easy, and cost-effective. - -Most of the ESP32 I/O pins are broken out to the board's pin headers for easy access. - - .. note:: - - The version with the ESP32-WROVER module uses ESP32's GPIO16 and GPIO17 as chip select and clock signals for PSRAM. By default, the two GPIOs are not broken out to the board's pin headers in order to ensure reliable performance. - - -Functionality Overview ----------------------- - -The block diagram below shows the main components of ESP-WROVER-KIT and their interconnections. - -.. figure:: ../../../_static/esp-wrover-kit-block-diagram.png - :align: center - :alt: ESP-WROVER-KIT block diagram - :figclass: align-center - - ESP-WROVER-KIT block diagram - - -Functional Description ----------------------- - -The following two figures and the table below describe the key components, interfaces, and controls of the ESP-WROVER-KIT board. - -.. _get-started-esp-wrover-kit-v2-board-front: - -.. figure:: ../../../_static/esp-wrover-kit-v2-layout-front.png - :align: center - :alt: ESP-WROVER-KIT board layout - front - :figclass: align-center - - ESP-WROVER-KIT board layout - front - -.. _get-started-esp-wrover-kit-v2-board-back: - -.. figure:: ../../../_static/esp-wrover-kit-v2-layout-back.png - :align: center - :alt: ESP-WROVER-KIT board layout - back - :figclass: align-center - - ESP-WROVER-KIT board layout - back - - -The table below provides description in the following manner: - -- Starting from the first picture's top right corner and going clockwise -- Then moving on to the second picture - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - Key Component - - Description - * - 32.768 kHz - - External precision 32.768 kHz crystal oscillator serves as a clock with low-power consumption while the chip is in Deep-sleep mode. - * - ESP32 Module - - Either ESP32-WROOM-32 or ESP32-WROVER with an integrated ESP32. The ESP32-WROVER module features all the functions of ESP32-WROOM-32 and integrates an external 32-MBit PSRAM for flexible extended storage and data processing capabilities. - * - CTS/RTS - - Serial port flow control signals: the pins are not connected to the circuitry by default. To enable them, short the respective pins of JP14 with jumpers. - * - UART - - Serial port. The serial TX/RX signals of FT2232 and ESP32 are broken out to the inward and outward sides of JP11 respectively. By default, these pairs of pins are connected with jumpers. To use ESP32's serial interface, remove the jumpers and connect another external serial device to the respective pins. - * - SPI - - By default, ESP32 uses its SPI interface to access flash and PSRAM memory inside the module. Use these pins to connect ESP32 to another SPI device. In this case, an extra chip select (CS) signal is needed. Please note that the interface voltage for the version with ESP32-WROVER is 1.8V, while that for the version with ESP32-WROOM-32 is 3.3 V. - * - JTAG - - JTAG interface. JTAG signals of FT2232 and ESP32 are broken out to the inward and outward sides of JP8 respectively. By default, these pairs of pins are disconnected. To enable JTAG, short the respective pins with jumpers as shown in Section `Setup Options`_. - * - FT2232 - - The FT2232 chip serves as a multi-protocol USB-to-serial bridge which can be programmed and controlled via USB to provide communication with ESP32. FT2232 features USB-to-UART and USB-to-JTAG functionalities. - * - EN - - Reset button. - * - Boot - - Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - USB - - USB interface. Power supply for the board as well as the communication interface between a computer and the board. - * - Power Select - - Power supply selector interface. The board can be powered either via USB or via the 5 V Input interface. Select the power source with a jumper. For more details, see Section `Setup Options`_, jumper header JP7. - * - Power Key - - Power On/Off Switch. Toggling toward **USB** powers the board on, toggling away from **USB** powers the board off. - * - 5V Input - - The 5 V power supply interface can be more convenient when the board is operating autonomously (not connected to a computer). - * - LDO - - NCP1117(1 A). 5V-to-3.3V LDO. NCP1117 can provide a maximum current of 1 A. The LDO on the board has a fixed output voltage. Although, the user can install an LDO with adjustable output voltage. For details, please refer to `ESP-WROVER-KIT V2 schematic`_. - * - Camera - - Camera interface, a standard OV7670 camera module. - * - RGB - - Red, green and blue (RGB) light emitting diodes (LEDs), can be controlled by pulse width modulation (PWM). - * - I/O - - All the pins on the ESP32 module are broken out to pin headers. You can program ESP32 to enable multiple functions, such as PWM, ADC, DAC, I2C, I2S, SPI, etc. - * - microSD Card - - microSD card slot for data storage: when ESP32 enters the download mode, GPIO2 cannot be held high. However, a pull-up resistor is required on GPIO2 to enable the microSD Card. By default, GPIO2 and the pull-up resistor R153 are disconnected. To enable the SD Card, use jumpers on JP1 as shown in Section `Setup Options`_. - * - LCD - - Support for mounting and interfacing a 3.2” SPI (standard 4-wire Serial Peripheral Interface) LCD, as shown on figure :ref:`get-started-esp-wrover-kit-v2-board-back`. - - -.. _get-started-esp-wrover-kit-v2-setup-options: - -Setup Options -------------- - -There are five jumper blocks available to set up the board functionality. The most frequently required options are listed in the table below. - -======= ================ ========================================================= -Header Jumper Setting Description of Functionality -======= ================ ========================================================= -JP1 |jp1-sd_io2| Enable pull up for the microSD Card -JP1 |jp1-both| Assert GPIO2 low during each download (by jumping it to GPIO0) -JP7 |jp7-ext_5v| Power ESP-WROVER-KIT via an external power supply -JP7 |jp7-usb_5v| Power ESP-WROVER-KIT via USB -JP8 |jp8| Enable JTAG functionality -JP11 |jp11-tx-rx| Enable UART communication -JP14 |jp14| Enable RTS/CTS flow control for serial communication -======= ================ ========================================================= - - -.. _get-started-esp-wrover-kit-v2-start-development: - -Start Application Development ------------------------------ - -Before powering up your ESP-WROVER-KIT, please make sure that the board is in good condition with no obvious signs of damage. - - -Initial Setup -^^^^^^^^^^^^^ - -Please set only the following jumpers shown in the pictures below: - -- Select USB as the power source using the jumper block JP7. - -- Enable UART communication using the jumper block JP11. - -======================== ========================== -Power up from USB port Enable UART communication -======================== ========================== -|jp7-usb_5v| |jp11-tx-rx| -======================== ========================== - -Do not install any other jumpers. - -Turn the **Power Switch** to ON, the **5V Power On LED** should light up. - - -Now to Development -^^^^^^^^^^^^^^^^^^ - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. - - -Related Documents ------------------ - -* `ESP-WROVER-KIT V2 schematic`_ (PDF) -* `ESP32 Datasheet `_ (PDF) -* `ESP32-WROVER Datasheet `_ (PDF) -* `ESP32-WROOM-32 Datasheet `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - - -.. |jp1-sd_io2| image:: ../../../_static/wrover-jp1-sd_io2.png -.. |jp1-both| image:: ../../../_static/wrover-jp1-both.png -.. |jp7-ext_5v| image:: ../../../_static/wrover-jp7-ext_5v.png -.. |jp7-usb_5v| image:: ../../../_static/wrover-jp7-usb_5v.png -.. |jp8| image:: ../../../_static/wrover-jp8.png -.. |jp11-tx-rx| image:: ../../../_static/wrover-jp11-tx-rx.png -.. |jp14| image:: ../../../_static/wrover-jp14.png - -.. _ESP-WROVER-KIT V2 schematic: https://dl.espressif.com/dl/schematics/ESP-WROVER-KIT_SCH-2.pdf diff --git a/docs/en/hw-reference/esp32/get-started-wrover-kit-v3.rst b/docs/en/hw-reference/esp32/get-started-wrover-kit-v3.rst deleted file mode 100644 index 4a71b7238f4c..000000000000 --- a/docs/en/hw-reference/esp32/get-started-wrover-kit-v3.rst +++ /dev/null @@ -1,384 +0,0 @@ -ESP-WROVER-KIT V3 Getting Started Guide -======================================= - -:link_to_translation:`zh_CN:[中文]` - -This guide shows how to get started with the ESP-WROVER-KIT V3 development board and also provides information about its functionality and configuration options. For the description of other ESP-WROVER-KIT versions, please check :doc:`../../hw-reference/index`. - - -What You Need -------------- - -* :ref:`ESP-WROVER-KIT V3 board ` -* USB 2.0 cable (A to Micro-B) -* Computer running Windows, Linux, or macOS - -You can skip the introduction sections and go directly to Section `Start Application Development`_. - - -Overview --------- - -ESP-WROVER-KIT is an ESP32-based development board produced by `Espressif `_. This board features an integrated LCD screen and microSD card slot. - -ESP-WROVER-KIT comes with the following ESP32 modules: - -- ESP32-WROOM-32 -- ESP32-WROVER series - -Its another distinguishing feature is the embedded FTDI FT2232HL chip - an advanced multi-interface USB bridge. This chip enables to use JTAG for direct debugging of ESP32 through the USB interface without a separate JTAG debugger. ESP-WROVER-KIT makes development convenient, easy, and cost-effective. - -Most of the ESP32 I/O pins are broken out to the board's pin headers for easy access. - - .. note:: - - The version with the ESP32-WROVER module uses ESP32's GPIO16 and GPIO17 as chip select and clock signals for PSRAM. By default, the two GPIOs are not broken out to the board's pin headers in order to ensure reliable performance. - - -Functionality Overview ----------------------- - -The block diagram below shows the main components of ESP-WROVER-KIT and their interconnections. - -.. figure:: ../../../_static/esp-wrover-kit-block-diagram.png - :align: center - :alt: ESP-WROVER-KIT block diagram - :figclass: align-center - - ESP-WROVER-KIT block diagram - - -Functional Description ----------------------- - -The following two figures and the table below describe the key components, interfaces, and controls of the ESP-WROVER-KIT board. - -.. _get-started-esp-wrover-kit-v3-board-front: - -.. figure:: ../../../_static/esp-wrover-kit-v3-layout-front.jpg - :align: center - :alt: ESP-WROVER-KIT board layout - front - :figclass: align-center - - ESP-WROVER-KIT board layout - front - -.. _get-started-esp-wrover-kit-v3-board-back: - -.. figure:: ../../../_static/esp-wrover-kit-v3-layout-back.jpg - :align: center - :alt: ESP-WROVER-KIT board layout - back - :figclass: align-center - - ESP-WROVER-KIT board layout - back - - -The table below provides description in the following manner: - -- Starting from the first picture's top right corner and going clockwise -- Then moving on to the second picture - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - Key Component - - Description - * - 32.768 kHz - - External precision 32.768 kHz crystal oscillator serves as a clock with low-power consumption while the chip is in Deep-sleep mode. - * - 0R - - Zero-ohm resistor intended as a placeholder for a current shunt, can be desoldered or replaced with a current shunt to facilitate the measurement of ESP32's current consumption in different modes. - * - ESP32 Module - - Either ESP32-WROOM-32 or ESP32-WROVER with an integrated ESP32. The ESP32-WROVER module features all the functions of ESP32-WROOM-32 and integrates an external 32-MBit PSRAM for flexible extended storage and data processing capabilities. - * - FT2232 - - The FT2232 chip serves as a multi-protocol USB-to-serial bridge which can be programmed and controlled via USB to provide communication with ESP32. FT2232 also features USB-to-JTAG interface which is available on channel A of the chip, while USB-to-serial is on channel B. The FT2232 chip enhances user-friendliness in terms of application development and debugging. See `ESP-WROVER-KIT V3 schematic`_. - * - UART - - Serial port. The serial TX/RX signals of FT2232 and ESP32 are broken out to the inward and outward sides of JP11 respectively. By default, these pairs of pins are connected with jumpers. To use ESP32's serial interface, remove the jumpers and connect another external serial device to the respective pins. - * - SPI - - By default, ESP32 uses its SPI interface to access flash and PSRAM memory inside the module. Use these pins to connect ESP32 to another SPI device. In this case, an extra chip select (CS) signal is needed. Please note that the interface voltage for the version with ESP32-WROVER is 1.8V, while that for the version with ESP32-WROOM-32 is 3.3V. - * - CTS/RTS - - Serial port flow control signals: the pins are not connected to the circuitry by default. To enable them, short the respective pins of JP14 with jumpers. - * - JTAG - - JTAG interface. JTAG signals of FT2232 and ESP32 are broken out to the inward and outward sides of JP8 respectively. By default, these pairs of pins are disconnected. To enable JTAG, short the respective pins with jumpers as shown in Section `Setup Options`_. - * - EN - - Reset button. - * - Boot - - Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - USB - - USB interface. Power supply for the board as well as the communication interface between a computer and the board. - * - Power Key - - Power On/Off Switch. Toggling toward **USB** powers the board on, toggling away from **USB** powers the board off. - * - Power Select - - Power supply selector interface. The board can be powered either via USB or via the 5V Input interface. Select the power source with a jumper. For more details, see Section `Setup Options`_, jumper header JP7. - * - 5V Input - - The 5 V power supply interface can be more convenient when the board is operating autonomously (not connected to a computer). - * - LDO - - NCP1117(1A). 5V-to-3.3V LDO. NCP1117 can provide a maximum current of 1A. The LDO on the board has a fixed output voltage. Although, the user can install an LDO with adjustable output voltage. For details, please refer to `ESP-WROVER-KIT V3 schematic`_. - * - Camera - - Camera interface, a standard OV7670 camera module. - * - RGB LED - - Red, green and blue (RGB) light emitting diodes (LEDs), can be controlled by pulse width modulation (PWM). - * - I/O - - All the pins on the ESP32 module are broken out to pin headers. You can program ESP32 to enable multiple functions, such as PWM, ADC, DAC, I2C, I2S, SPI, etc. - * - microSD Card Slot - - Useful for developing applications that access microSD card for data storage and retrieval. - * - LCD - - Support for mounting and interfacing a 3.2” SPI (standard 4-wire Serial Peripheral Interface) LCD, as shown on figure :ref:`get-started-esp-wrover-kit-v3-board-back`. - - -.. _get-started-esp-wrover-kit-v3-setup-options: - -Setup Options -------------- - -There are five jumper blocks available to set up the board functionality. The most frequently required options are listed in the table below. - -======= ================ ========================================================= -Header Jumper Setting Description of Functionality -======= ================ ========================================================= -JP7 |jp7-ext_5v| Power ESP-WROVER-KIT via an external power supply -JP7 |jp7-usb_5v| Power ESP-WROVER-KIT via USB -JP8 |jp8| Enable JTAG functionality -JP11 |jp11-tx-rx| Enable UART communication -JP14 |jp14| Enable RTS/CTS flow control for serial communication -======= ================ ========================================================= - - -Allocation of ESP32 Pins ------------------------- - -Some pins/terminals of ESP32 are allocated for use with the onboard or external hardware. If that hardware is not used, e.g., nothing is plugged into the Camera (JP4) header, then these GPIOs can be used for other purposes. - -Some of the pins, such as GPIO0 or GPIO2, have multiple functions and some of them are shared among onboard and external peripheral devices. Certain combinations of peripherals cannot work together. For example, it is not possible to do JTAG debugging of an application that is using SD card, because several pins are shared by JTAG and the SD card slot. - -In other cases, peripherals can coexist under certain conditions. This is applicable to, for example, LCD screen and SD card that share only a single pin GPIO21. This pin is used to provide D/C (Data/Control) signal for the LCD as well as the CD (Card Detect) signal read from the SD card slot. If the card detect functionality is not essential, then it may be disabled by removing R167, so both LCD and SD may operate together. - -For more details on which pins are shared among which peripherals, please refer to the table in the next section. - - -Main I/O Connector/JP1 -^^^^^^^^^^^^^^^^^^^^^^ - -The JP1 connector consists of 14x2 male pins whose functions are shown in the middle two "I/O" columns of the table below. The two "Shared With" columns on both sides describe where else on the board a certain GPIO is used. - -===================== ===== ===== ===================== -Shared With I/O I/O Shared With -===================== ===== ===== ===================== -n/a 3.3V GND n/a -NC/XTAL IO32 IO33 NC/XTAL -JTAG, microSD IO12 IO13 JTAG, microSD -JTAG, microSD IO14 IO27 Camera -Camera IO26 IO25 Camera, LCD -Camera IO35 IO34 Camera -Camera IO39 IO36 Camera -JTAG EN IO23 Camera, LCD -Camera, LCD IO22 IO21 Camera, LCD, microSD -Camera, LCD IO19 IO18 Camera, LCD -Camera, LCD IO5 IO17 PSRAM -PSRAM IO16 IO4 LED, Camera, microSD -Camera, LED, Boot IO0 IO2 LED, microSD -JTAG, microSD IO15 5V -===================== ===== ===== ===================== - -Legend: - -* NC/XTAL - :ref:`32.768 kHz Oscillator ` -* JTAG - :ref:`JTAG / JP8 ` -* Boot - Boot button / SW2 -* Camera - :ref:`Camera / JP4 ` -* LED - :ref:`RGB LED ` -* microSD - :ref:`microSD Card / J4 ` -* LCD - :ref:`LCD / U5 ` -* PSRAM - only in case ESP32-WROVER is installed - - -.. _get-started-esp-wrover-kit-v3-xtal: - -32.768 kHz Oscillator -^^^^^^^^^^^^^^^^^^^^^ - -==== ========== -. ESP32 Pin -==== ========== -1 GPIO32 -2 GPIO33 -==== ========== - -.. note:: - - Since GPIO32 and GPIO33 are connected to the oscillator by default, they are not connected to the JP1 I/O connector to maintain signal integrity. This allocation may be changed from the oscillator to JP1 by desoldering the zero-ohm resistors from positions R11/R23 and re-soldering them to positions R12/R24. - - -.. _get-started-esp-wrover-kit-v3-spi-flash-header: - -SPI Flash/JP13 -^^^^^^^^^^^^^^ - -==== ============= -. ESP32 Pin -==== ============= -1 CLK/GPIO6 -2 SD0/GPIO7 -3 SD1/GPIO8 -4 SD2/GPIO9 -5 SD3/GPIO10 -6 CMD/GPIO11 -==== ============= - -.. important:: - - The module's flash bus is connected to the jumper block JP13 through zero-ohm resistors R140 ~ R145. If the flash memory needs to operate at the frequency of 80 MHz, for reasons such as improving the integrity of bus signals, you can desolder these resistors to disconnect the module's flash bus from the pin header JP13. - - -.. _get-started-esp-wrover-kit-v3-jtag-header: - -JTAG/JP8 -^^^^^^^^^^ - -==== ============== ============= -. ESP32 Pin JTAG Signal -==== ============== ============= -1 EN TRST_N -2 MTMS/GPIO14 TMS -3 MTDO/GPIO15 TDO -4 MTDI/GPIO12 TDI -5 MTCK/GPIO13 TCK -==== ============== ============= - - -.. _get-started-esp-wrover-kit-v3-camera-header: - -Camera/JP4 -^^^^^^^^^^^^ - -==== ========== ============================= -. ESP32 Pin Camera Signal -==== ========== ============================= - 1 n/a 3.3V - 2 n/a Ground - 3 GPIO27 SIO_C/SCCB Clock - 4 GPIO26 SIO_D/SCCB Data - 5 GPIO25 VSYNC/Vertical Sync - 6 GPIO23 HREF/Horizontal Reference - 7 GPIO22 PCLK/Pixel Clock - 8 GPIO21 XCLK/System Clock - 9 GPIO35 D7/Pixel Data Bit 7 -10 GPIO34 D6/Pixel Data Bit 6 -11 GPIO39 D5/Pixel Data Bit 5 -12 GPIO36 D4/Pixel Data Bit 4 -13 GPIO19 D3/Pixel Data Bit 3 -14 GPIO18 D2/Pixel Data Bit 2 -15 GPIO5 D1/Pixel Data Bit 1 -16 GPIO4 D0/Pixel Data Bit 0 -17 GPIO0 RESET/Camera Reset -18 n/a PWDN/Camera Power Down -==== ========== ============================= - -* Signals D0 .. D7 denote camera data bus - - -.. _get-started-esp-wrover-kit-v3-rgb-led-connections: - -RGB LED -^^^^^^^ - -==== ========== ========= -. ESP32 Pin RGB LED -==== ========== ========= -1 GPIO0 Red -2 GPIO2 Green -3 GPIO4 Blue -==== ========== ========= - - -.. _get-started-esp-wrover-kit-v3-microsd-card-slot: - -microSD Card -^^^^^^^^^^^^ - -==== ============== =============== -. ESP32 Pin microSD Signal -==== ============== =============== -1 MTDI/GPIO12 DATA2 -2 MTCK/GPIO13 CD/DATA3 -3 MTDO/GPIO15 CMD -4 MTMS/GPIO14 CLK -5 GPIO2 DATA0 -6 GPIO4 DATA1 -7 GPIO21 CD -==== ============== =============== - - -.. _get-started-esp-wrover-kit-v3-lcd-connector: - -LCD/U5 -^^^^^^ - -==== ============== =============== -. ESP32 Pin LCD Signal -==== ============== =============== -1 GPIO18 RESET -2 GPIO19 SCL -3 GPIO21 D/C -4 GPIO22 CS -5 GPIO23 SDA -6 GPIO25 SDO -7 GPIO5 Backlight -==== ============== =============== - - -.. _get-started-esp-wrover-kit-v3-start-development: - -Start Application Development ------------------------------ - -Before powering up your ESP-WROVER-KIT, please make sure that the board is in good condition with no obvious signs of damage. - - -Initial Setup -^^^^^^^^^^^^^ - -Please set only the following jumpers shown in the pictures below: - -- Select USB as the power source using the jumper block JP7. - -- Enable UART communication using the jumper block JP11. - -======================== ========================== -Power up from USB port Enable UART communication -======================== ========================== -|jp7-usb_5v| |jp11-tx-rx| -======================== ========================== - -Do not install any other jumpers. - -Turn the **Power Switch** to ON, the **5V Power On LED** should light up. - - -Now to Development -^^^^^^^^^^^^^^^^^^ - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. - - -Related Documents ------------------ - -* `ESP-WROVER-KIT V3 schematic`_ (PDF) -* `ESP32 Datasheet `_ (PDF) -* `ESP32-WROVER Datasheet `_ (PDF) -* `ESP32-WROOM-32 Datasheet `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - -.. |jp7-ext_5v| image:: ../../../_static/esp-wrover-kit-v3-jp7-ext_5v.png -.. |jp7-usb_5v| image:: ../../../_static/esp-wrover-kit-v3-jp7-usb_5v.png -.. |jp8| image:: ../../../_static/esp-wrover-kit-v3-jp8.png -.. |jp11-tx-rx| image:: ../../../_static/esp-wrover-kit-v3-jp11-tx-rx.png -.. |jp14| image:: ../../../_static/esp-wrover-kit-v3-jp14.png - -.. _ESP-WROVER-KIT V3 schematic: https://dl.espressif.com/dl/schematics/ESP-WROVER-KIT_SCH-3.pdf - -.. toctree:: - :hidden: - - get-started-wrover-kit-v2.rst diff --git a/docs/en/hw-reference/esp32/get-started-wrover-kit.rst b/docs/en/hw-reference/esp32/get-started-wrover-kit.rst deleted file mode 100644 index 30fd7cde6c36..000000000000 --- a/docs/en/hw-reference/esp32/get-started-wrover-kit.rst +++ /dev/null @@ -1,461 +0,0 @@ -ESP-WROVER-KIT V4.1 Getting Started Guide -========================================= - -:link_to_translation:`zh_CN:[中文]` - -This guide shows how to get started with the ESP-WROVER-KIT V4.1 development board and also provides information about its functionality and configuration options. - - -What You Need -------------- - -* :ref:`ESP-WROVER-KIT V4.1 board ` -* USB 2.0 cable (A to Micro-B) -* Computer running Windows, Linux, or macOS - -You can skip the introduction sections and go directly to Section `Start Application Development`_. - - -Overview --------- - -ESP-WROVER-KIT is an ESP32-based development board produced by `Espressif `_. - -ESP-WROVER-KIT features the following integrated components: - -- ESP32-WROVER-E module -- LCD screen -- microSD card slot - -Another distinguishing feature is the embedded FTDI FT2232HL chip, an advanced multi-interface USB bridge. This chip enables to use JTAG for direct debugging of ESP32 through the USB interface without a separate JTAG debugger. ESP-WROVER-KIT makes development convenient, easy, and cost-effective. - -Most of the ESP32 I/O pins are broken out to the board's pin headers for easy access. - -.. note:: - - ESP32's GPIO16 and GPIO17 are used as chip select and clock signals for PSRAM. By default, the two GPIOs are not broken out to the board's pin headers in order to ensure reliable performance. - - -Functionality Overview ----------------------- - -The block diagram below shows the main components of ESP-WROVER-KIT and their interconnections. - -.. figure:: ../../../_static/esp-wrover-kit-block-diagram.png - :align: center - :alt: ESP-WROVER-KIT block diagram - :figclass: align-center - - ESP-WROVER-KIT block diagram - - -Functional Description ----------------------- - -The following two figures and the table below describe the key components, interfaces, and controls of the ESP-WROVER-KIT board. - -.. _get-started-esp-wrover-kit-v4.1-board-front: - -.. figure:: ../../../_static/esp-wrover-kit-v4.1-layout-front.png - :align: center - :alt: ESP-WROVER-KIT board layout - front - :figclass: align-center - - ESP-WROVER-KIT board layout - front - -.. _get-started-esp-wrover-kit-v4.1-board-back: - -.. figure:: ../../../_static/esp-wrover-kit-v4.1-layout-back.png - :align: center - :alt: ESP-WROVER-KIT board layout - back - :figclass: align-center - - ESP-WROVER-KIT board layout - back - - -The table below provides description in the following manner: - -- Starting from the first picture's top right corner and going clockwise -- Then moving on to the second picture - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - Key Component - - Description - * - FT2232HL - - The FT2232HL chip serves as a multi-protocol USB-to-serial bridge which can be programmed and controlled via USB to provide communication with ESP32. FT2232HL also features USB-to-JTAG interface which is available on channel A of the chip, while USB-to-serial is on channel B. The FT2232HL chip enhances user-friendliness in terms of application development and debugging. See `ESP-WROVER-KIT V4.1 schematic`_. - * - 32.768 kHz - - External precision 32.768 kHz crystal oscillator serves as a clock with low-power consumption while the chip is in Deep-sleep mode. - * - 0R - - Zero-ohm resistor intended as a placeholder for a current shunt, can be desoldered or replaced with a current shunt to facilitate the measurement of ESP32's current consumption in different modes. - * - ESP32-WROVER-E module - - This ESP32 module features 64-Mbit PSRAM for flexible extended storage and data processing capabilities. - * - Diagnostic LEDs - - Four red LEDs connected to the GPIO pins of FT2232HL. Intended for future use. - * - UART - - Serial port. The serial TX/RX signals of FT2232HL and ESP32 are broken out to the inward and outward sides of JP2 respectively. By default, these pairs of pins are connected with jumpers. To use ESP32's serial interface, remove the jumpers and connect another external serial device to the respective pins. - * - SPI - - By default, ESP32 uses its SPI interface to access flash and PSRAM memory inside the module. Use these pins to connect ESP32 to another SPI device. In this case, an extra chip select (CS) signal is needed. Please note that the voltage of this interface is 3.3 V. - * - CTS/RTS - - Serial port flow control signals: the pins are not connected to the circuitry by default. To enable them, short the respective pins of JP14 with jumpers. - * - JTAG - - JTAG interface. JTAG signals of FT2232HL and ESP32 are broken out to the inward and outward sides of JP2 respectively. By default, these pairs of pins are disconnected. To enable JTAG, short the respective pins with jumpers as shown in Section `Setup Options`_. - * - USB Port - - USB interface. Power supply for the board as well as the communication interface between a computer and the board. - * - EN Button - - Reset button. - * - BOOT Button - - Download button. Holding down **Boot** and then pressing **EN** initiates Firmware Download mode for downloading firmware through the serial port. - * - Power Switch - - Power On/Off Switch. Toggling toward the **Boot** button powers the board on, toggling away from **Boot** powers the board off. - * - Power Selector - - Power supply selector interface. The board can be powered either via USB or via the 5V Input interface. Select the power source with a jumper. For more details, see Section `Setup Options`_, jumper header JP7. - * - 5V Input - - 5V power supply interface for a standard coaxial power connector, 5.5 x 2.1 mm, center positive. This interface can be more convenient when the board is operating autonomously (not connected to a computer). - * - 5V Power On LED - - This red LED turns on when power is supplied to the board, either from **USB** or **5V Input**. - * - LDO - - NCP1117(1A). 5V-to-3.3V LDO. NCP1117 can provide a maximum current of 1A. The LDO on the board has a fixed output voltage, but the user can install an LDO with adjustable output voltage. For details, please refer to `ESP-WROVER-KIT V4.1 schematic`_. - * - Camera Connector - - Camera interface, a standard OV7670 camera module. - * - RGB LED - - Red, green and blue (RGB) light emitting diodes (LEDs), can be controlled by pulse width modulation (PWM). - * - I/O Connector - - All the pins on the ESP32 module are broken out to pin headers. You can program ESP32 to enable multiple functions, such as PWM, ADC, DAC, I2C, I2S, SPI, etc. - * - microSD Card Slot - - Useful for developing applications that access microSD card for data storage and retrieval. - * - LCD - - Support for mounting and interfacing a 3.2” SPI (standard 4-wire Serial Peripheral Interface) LCD, as shown in figure :ref:`get-started-esp-wrover-kit-v4.1-board-back`. - - -.. _get-started-esp-wrover-kit-v4.1-setup-options: - -Setup Options -------------- - -There are three jumper blocks available to set up the board functionality. The most frequently required options are listed in the table below. - -.. list-table:: - :widths: 25 35 40 - :header-rows: 1 - - * - Header - - Jumper Setting - - Description of Functionality - * - JP7 - - |jp7-ext_5v| - - Power ESP-WROVER-KIT via an external power supply - * - JP7 - - |jp7-usb_5v| - - Power ESP-WROVER-KIT via USB - * - JP2 - - |jp2-jtag| - - Enable JTAG functionality - * - JP2 - - |jp2-tx-rx| - - Enable UART communication - * - JP14 - - |jp14| - - Enable RTS/CTS flow control for serial communication - - -Allocation of ESP32 Pins ------------------------- - -Some pins or terminals of ESP32 are allocated for use with the onboard or external hardware. If that hardware is not used, e.g., nothing is plugged into the Camera (JP4) header, then these GPIOs can be used for other purposes. - -Some of the pins, such as GPIO0 or GPIO2, have multiple functions and some of them are shared among onboard and external peripheral devices. Certain combinations of peripherals cannot work together. For example, it is not possible to do JTAG debugging of an application that is using SD card, because several pins are shared by JTAG and the SD card slot. - -In other cases, peripherals can coexist under certain conditions. This is applicable to, for example, LCD screen and SD card that share only a single pin GPIO21. This pin is used to provide D/C (Data/Control) signal for the LCD as well as the Card Detect signal read from the SD card slot. If the card detect functionality is not essential, then it may be disabled by removing R167, so both LCD and SD may operate together. - -For more details on which pins are shared among which peripherals, please refer to the table in the next section. - - -Main I/O Connector/JP1 -^^^^^^^^^^^^^^^^^^^^^^ - -The JP1 connector consists of 14x2 male pins whose functions are shown in the middle two "I/O" columns of the table below. The two "Shared With" columns on both sides describe where else on the board a certain GPIO is used. - -.. list-table:: - :widths: 30 20 20 30 - :header-rows: 1 - - * - Shared With - - I/O - - I/O - - Shared With - * - n/a - - 3.3V - - GND - - n/a - * - NC/XTAL - - IO32 - - IO33 - - NC/XTAL - * - JTAG, microSD - - IO12 - - IO13 - - JTAG,microSD - * - JTAG, microSD - - IO14 - - IO27 - - Camera - * - Camera - - IO26 - - IO25 - - Camera, LCD - * - Camera - - IO35 - - IO34 - - Camera - * - Camera - - IO39 - - IO36 - - Camera - * - JTAG - - EN - - IO23 - - Camera, LCD - * - Camera, LCD - - IO22 - - IO21 - - Camera, LCD, microSD - * - Camera, LCD - - IO19 - - IO18 - - Camera, LCD - * - Camera, LCD - - IO5 - - IO17 - - PSRAM - * - PSRAM - - IO16 - - IO4 - - LED, Camera, microSD - * - Camera, LED, Boot - - IO0 - - IO2 - - LED, microSD - * - JTAG, microSD - - IO15 - - 5V - - - -Legend: - -* NC/XTAL - :ref:`32.768 kHz Oscillator ` -* JTAG - :ref:`JTAG/JP2 ` -* Boot - Boot button/SW2 -* Camera - :ref:`Camera/JP4 ` -* LED - :ref:`RGB LED ` -* microSD - :ref:`microSD Card/J4 ` -* LCD - :ref:`LCD/U5 ` -* PSRAM - ESP32-WROVER-E's PSRAM - - -.. _get-started-esp-wrover-kit-v4.1-xtal: - -32.768 kHz Oscillator -^^^^^^^^^^^^^^^^^^^^^ - -==== ========== -. ESP32 Pin -==== ========== -1 GPIO32 -2 GPIO33 -==== ========== - -.. note:: - - Since GPIO32 and GPIO33 are connected to the oscillator by default, they are not connected to the JP1 I/O connector to maintain signal integrity. This allocation may be changed from the oscillator to JP1 by desoldering the zero-ohm resistors from positions R11 or R23 and re-soldering them to positions R12 or R24. - - -.. _get-started-esp-wrover-kit-v4.1-spi-flash-header: - -SPI Flash/JP2 -^^^^^^^^^^^^^ - -==== ============= -. ESP32 Pin -==== ============= -1 CLK/GPIO6 -2 SD0/GPIO7 -3 SD1/GPIO8 -4 SD2/GPIO9 -5 SD3/GPIO10 -6 CMD/GPIO11 -==== ============= - -.. note:: - - SPI Flash pins are used to access the internal flash memory. Therefore, they are not available to connect external SPI devices. Those pins are exposed for monitoring or for advanced usage only. - -.. important:: - - The module's flash bus is connected to the jumper block JP2 through zero-ohm resistors R140 ~ R145. If the flash memory needs to operate at the frequency of 80 MHz, for reasons such as improving the integrity of bus signals, you can desolder these resistors to disconnect the module's flash bus from the pin header JP2. - - -.. _get-started-esp-wrover-kit-v4.1-jtag-header: - -JTAG/JP2 -^^^^^^^^ - -==== ============== ============= -. ESP32 Pin JTAG Signal -==== ============== ============= -1 EN TRST_N -2 MTMS/GPIO14 TMS -3 MTDO/GPIO15 TDO -4 MTDI/GPIO12 TDI -5 MTCK/GPIO13 TCK -==== ============== ============= - - -.. _get-started-esp-wrover-kit-v4.1-camera-header: - -Camera/JP4 -^^^^^^^^^^ - -==== ========== ============================= -. ESP32 Pin Camera Signal -==== ========== ============================= - 1 n/a 3.3V - 2 n/a Ground - 3 GPIO27 SIO_C/SCCB Clock - 4 GPIO26 SIO_D/SCCB Data - 5 GPIO25 VSYNC/Vertical Sync - 6 GPIO23 HREF/Horizontal Reference - 7 GPIO22 PCLK/Pixel Clock - 8 GPIO21 XCLK/System Clock - 9 GPIO35 D7/Pixel Data Bit 7 -10 GPIO34 D6/Pixel Data Bit 6 -11 GPIO39 D5/Pixel Data Bit 5 -12 GPIO36 D4/Pixel Data Bit 4 -13 GPIO19 D3/Pixel Data Bit 3 -14 GPIO18 D2/Pixel Data Bit 2 -15 GPIO5 D1/Pixel Data Bit 1 -16 GPIO4 D0/Pixel Data Bit 0 -17 GPIO0 RESET/Camera Reset -18 n/a PWDN/Camera Power Down -==== ========== ============================= - -* Signals D0 .. D7 denote camera data bus - - -.. _get-started-esp-wrover-kit-v4.1-rgb-led-connections: - -RGB LED -^^^^^^^ - -==== ========== ========= -. ESP32 Pin RGB LED -==== ========== ========= -1 GPIO0 Red -2 GPIO2 Green -3 GPIO4 Blue -==== ========== ========= - - -.. _get-started-esp-wrover-kit-v4.1-microsd-card-slot: - -microSD Card -^^^^^^^^^^^^ - -==== ============== =============== -. ESP32 Pin microSD Signal -==== ============== =============== -1 MTDI/GPIO12 DATA2 -2 MTCK/GPIO13 CD/DATA3 -3 MTDO/GPIO15 CMD -4 MTMS/GPIO14 CLK -5 GPIO2 DATA0 -6 GPIO4 DATA1 -7 GPIO21 Card Detect -==== ============== =============== - - -.. _get-started-esp-wrover-kit-v4.1-lcd-connector: - -LCD/U5 -^^^^^^ - -==== ============== =============== -. ESP32 Pin LCD Signal -==== ============== =============== -1 GPIO18 RESET -2 GPIO19 SCL -3 GPIO21 D/C -4 GPIO22 CS -5 GPIO23 SDA -6 GPIO25 SDO -7 GPIO5 Backlight -==== ============== =============== - - -.. _get-started-esp-wrover-kit-start-development: - -Start Application Development ------------------------------ - -Before powering up your ESP-WROVER-KIT, please make sure that the board is in good condition with no obvious signs of damage. - - -Initial Setup -^^^^^^^^^^^^^ - -Please set only the following jumpers shown in the pictures below: - -- Select USB as the power source using the jumper block JP7. - -- Enable UART communication using the jumper block JP2. - -======================== ========================== -Power up from USB port Enable UART communication -======================== ========================== -|jp7-usb_5v| |jp2-tx-rx| -======================== ========================== - -Do not install any other jumpers. - -Turn the **Power Switch** to ON, and the **5 V Power On LED** should light up. - - -Now to Development -^^^^^^^^^^^^^^^^^^ - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment and then flash an example project onto your board. - -A Board Support Package can be found in `IDF Component Registry `_. - -The application examples that use some hardware specific to your ESP-WROVER-KIT can be found below. - -* On-board LCD example: :example:`peripherals/spi_master/lcd` -* SD card slot example: :example:`storage/sd_card` -* Camera connector example: https://github.com/espressif/esp32-camera - - -Related Documents ------------------ - -* `ESP-WROVER-KIT V4.1 schematic`_ (PDF) -* `ESP-WROVER-KIT V4.1 layout `_ (DXF) may be opened online with `Autodesk Viewer `_ -* `ESP32 Datasheet `_ (PDF) -* `ESP32-WROVER-E Datasheet `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - -.. |jp7-ext_5v| image:: ../../../_static/esp-wrover-kit-v4.1-jp7-ext_5v.jpg -.. |jp7-usb_5v| image:: ../../../_static/esp-wrover-kit-v4.1-jp7-usb_5v.jpg -.. |jp2-jtag| image:: ../../../_static/esp-wrover-kit-v4.1-jp2-jtag.jpg -.. |jp2-tx-rx| image:: ../../../_static/esp-wrover-kit-v4.1-jp2-tx-rx.jpg -.. |jp14| image:: ../../../_static/esp-wrover-kit-v4.1-jp14.jpg - -.. _ESP-WROVER-KIT V4.1 schematic: https://dl.espressif.com/dl/schematics/ESP-WROVER-KIT_V4_1.pdf - -.. toctree:: - :hidden: - - get-started-wrover-kit-v3.rst - get-started-wrover-kit-v2.rst diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.0.rst b/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.0.rst deleted file mode 100644 index e5adc2829bce..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.0.rst +++ /dev/null @@ -1,116 +0,0 @@ -================== -ESP-LyraP-CAM v1.0 -================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide provides information on the ESP-LyraP-CAM extension board. - -This extension board cannot be bought separately and is usually sold together with other Espressif development boards (e.g., ESP32-S2-Kaluga-1), which will be referred to as *main boards* below. - -Currently, ESP-LyraP-CAM v1.0 is sold as part of the :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2`. - -The ESP-LyraP-CAM extends the functionality of your main board by adding a camera. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.0-3d.png - :align: center - :alt: ESP-LyraP-CAM - :figclass: align-center - - ESP-LyraP-CAM - -The document consists of the following major sections: - -- `Overview`_: Provides an overview and hardware/software setup instructions to get started. -- `Hardware reference`_: Provides more detailed information about the ESP-LyraP-CAM's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions of the ESP-LyraP-CAM. -- `Related Documents`_: Gives links to related documentation. - - -Overview -======== - -This extension board adds a camera to your main board. - - -Description of Components -------------------------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.0-layout-front.png - :align: center - :alt: ESP-LyraP-CAM - front and back - :figclass: align-center - - ESP-LyraP-CAM - front and back - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - Main Board Camera Header - - Mount onto main board's Camera Header - * - Power ON LED - - Red LED is on if the power supply voltage is applied - * - Camera Module Connector - - Supports OV2640 and OV3660 camera modules; this extension board is supplied with an OV2640 camera module - * - Power Regulators - - LDO Regulators converting 3.3 V to 2.8 V and 1.5 V - - -Start Application Development ------------------------------ - -Before powering up your ESP-LyraP-CAM, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- Board with a female Camera Header (e.g., ESP32-S2-Kaluga-1) -- ESP-LyraP-CAM extension board -- Computer running Windows, Linux, or macOS - - -Hardware Setup -^^^^^^^^^^^^^^ - -Insert the ESP-LyraP-CAM extension board into your board's female Camera Header. - - -Software Setup -^^^^^^^^^^^^^^ - -See Section :ref:`user-guide-esp32-s2-kaluga-1-kit-v1.2-software-setup` of the ESP32-S2-Kaluga-1 kit user guide. - - -Hardware Reference -================== - -Block Diagram -------------- - -A block diagram below shows the components of the ESP-LyraP-CAM and their interconnections. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.0-block-diagram.png - :align: center - :alt: ESP-LyraP-CAM block diagram - :figclass: align-center - - ESP-LyraP-CAM block diagram - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -- `ESP-LyraP-CAM Schematic `_ (PDF) -- `ESP-LyraP-CAM PCB Layout `_ (PDF) - -For other design documentation for the board, please contact us at sales@espressif.com. diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.1.rst b/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.1.rst deleted file mode 100644 index 00d085a42b01..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.1.rst +++ /dev/null @@ -1,130 +0,0 @@ -================== -ESP-LyraP-CAM v1.1 -================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide provides information on the ESP-LyraP-CAM extension board. - -This extension board cannot be bought separately and is usually sold together with other Espressif development boards (e.g., ESP32-S2-Kaluga-1), which will be referred to as *main boards* below. - -Currently, ESP-LyraP-CAM v1.1 is sold as part of the :doc:`user-guide-esp32-s2-kaluga-1-kit`. - -The ESP-LyraP-CAM extends the functionality of your main board by adding a camera. - -.. Image of v1.0 is used as there are no visual changes - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.0-3d.png - :align: center - :alt: ESP-LyraP-CAM - :figclass: align-center - - ESP-LyraP-CAM - -The document consists of the following major sections: - -- `Overview`_: Provides an overview and hardware/software setup instructions to get started. -- `Hardware reference`_: Provides more detailed information about the ESP-LyraP-CAM's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions of the ESP-LyraP-CAM. -- `Related Documents`_: Gives links to related documentation. - - -Overview -======== - -This extension board adds a camera to your main board. - - -Description of Components -------------------------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.1-layout-front.png - :align: center - :alt: ESP-LyraP-CAM - front and back - :figclass: align-center - - ESP-LyraP-CAM - front and back - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - Main Board Camera Header - - Mount onto main board's Camera Header - * - Power ON LED - - Red LED is on if the power supply voltage is correct - * - Camera Module Connector - - Supports OV2640 and OV3660 camera modules; this extension board is supplied with an OV2640 camera module - * - Power Regulators - - LDO Regulators converting 3.3 V to 2.8 V and 1.5 V - - -Start Application Development ------------------------------ - -Before powering up your ESP-LyraP-CAM, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- Board with a female Camera Header (e.g., ESP32-S2-Kaluga-1) -- ESP-LyraP-CAM extension board -- Computer running Windows, Linux, or macOS - - -Hardware Setup -^^^^^^^^^^^^^^ - -Insert the ESP-LyraP-CAM extension board into your board's female Camera Header. - - -Software Setup -^^^^^^^^^^^^^^ - -See Section :ref:`user-guide-esp32-s2-kaluga-1-kit-software-setup` of the ESP32-S2-Kaluga-1 kit user guide. - - -Hardware Reference -================== - -Block Diagram -------------- - -A block diagram below shows the components of the ESP-LyraP-CAM and their interconnections. - -.. Image of v1.0 is used as there are no visual changes - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.0-block-diagram.png - :align: center - :alt: ESP-LyraP-CAM block diagram - :figclass: align-center - - ESP-LyraP-CAM block diagram - - -Hardware Revision Details -========================= - -ESP-LyraP-CAM v1.1 ------------------- - -* Silk screen updated -* No actual hardware updates - - -ESP-LyraP-CAM v1.0 ------------------- - -:doc:`Initial release ` - - -Related Documents -================= - -- `ESP-LyraP-CAM Schematic `_ (PDF) -- `ESP-LyraP-CAM PCB Layout `_ (PDF) - -For other design documentation for the board, please contact us at sales@espressif.com. diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.1.rst b/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.1.rst deleted file mode 100644 index b5f3863e5434..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.1.rst +++ /dev/null @@ -1,132 +0,0 @@ -==================== -ESP-LyraP-LCD32 v1.1 -==================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide provides information on the ESP-LyraP-LCD32 extension board. - -This extension board cannot be bought separately and is usually sold together with other Espressif development boards (e.g., ESP32-S2-Kaluga-1), which will be referred to as *main boards* below. - -Currently, ESP-LyraP-LCD32 v1.1 is sold as part of the :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2`. - -The ESP-LyraP-LCD32 extends the functionality of your main board by adding an LCD graphic display. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.1-3d.png - :align: center - :width: 2243px - :height: 1534px - :scale: 30% - :alt: ESP-LyraP-LCD32 - :figclass: align-center - - ESP-LyraP-LCD32 (click to enlarge) - -The document consists of the following major sections: - -- `Overview`_: Provides an overview and hardware/software setup instructions to get started. -- `Hardware reference`_: Provides more detailed information about the ESP-LyraP-LCD32's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions of the ESP-LyraP-LCD32. -- `Related Documents`_: Gives links to related documentation. - - -Overview -======== - -This extension board adds a 3.2" LCD graphic display with the resolution of 320x240. This display is connected to ESP32-S2 over the SPI bus. - - -Description of Components -------------------------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.1-layout-front.png - :align: center - :width: 934px - :height: 600px - :scale: 70% - :alt: ESP-LyraP-LCD32 - front - :figclass: align-center - - ESP-LyraP-LCD32 - front (click to enlarge) - - -In the description of components below, **Reserved** means that the functionality is available, but the current version of the kit does not use it. - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - Extension Header - - Male Extension Header for mounting onto a female Extension Header - * - LCD display - - This version has a 3.2" 320x240 SPI LCD display module; the display driver/controller is Sitronix ST7789V - * - Touch Screen Switch - - No support for touch screens, keep the switches to OFF to make the pins available for other uses - * - Main Board 3.2" LCD FPC Connector - - (Reserved) Connect to main board's 3.2" LCD FPC connector - * - Control Switch - - Switch to ON to set Reset/Backlight_control/CS to default high or low; switch to OFF to make the pins available for other uses - - -Start Application Development ------------------------------ - -Before powering up your ESP-LyraP-LCD32, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- Board with a female Extension Header (e.g., ESP32-S2-Kaluga-1, ESP-LyraT-8311A) -- ESP-LyraP-LCD32 extension board -- Four mounting bolts (for stable mounting) -- Computer running Windows, Linux, or macOS - - -Hardware Setup -^^^^^^^^^^^^^^ - -To mount your ESP-LyraP-LCD32 onto the board with a female Extension Header: - -1. Install the four mounting bolts onto the board with a female Extension Header -2. Align the ESP-LyraP-LCD32 with the bolts and Extension Header and insert it carefully - - -Software Setup -^^^^^^^^^^^^^^ - -See Section :ref:`user-guide-esp32-s2-kaluga-1-kit-v1.2-software-setup` of the ESP32-S2-Kaluga-1 kit user guide. - - -Hardware Reference -================== - -Block Diagram -------------- - -A block diagram below shows the components of the ESP-LyraP-LCD32 and their interconnections. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.1-block-diagram.png - :align: center - :alt: ESP-LyraP-LCD32 block diagram - :figclass: align-center - - ESP-LyraP-LCD32 block diagram - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -- `ESP-LyraP-LCD32 Schematic `_ (PDF) -- `ESP-LyraP-LCD32 PCB Layout `_ (PDF) - -For other design documentation for the board, please contact us at sales@espressif.com. diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.2.rst b/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.2.rst deleted file mode 100644 index 058b1bbc19d1..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.2.rst +++ /dev/null @@ -1,154 +0,0 @@ -==================== -ESP-LyraP-LCD32 v1.2 -==================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide provides information on the ESP-LyraP-LCD32 extension board. - -This extension board cannot be bought separately and is usually sold together with other Espressif development boards (e.g., ESP32-S2-Kaluga-1), which will be referred to as *main boards* below. - -Currently, ESP-LyraP-LCD32 v1.2 is sold as part of the :doc:`user-guide-esp32-s2-kaluga-1-kit`. - -The ESP-LyraP-LCD32 extends the functionality of your main board by adding an LCD graphic display. - -.. Image of v1.1 is used as there are no visual changes - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.1-3d.png - :align: center - :width: 2243px - :height: 1534px - :scale: 30% - :alt: ESP-LyraP-LCD32 - :figclass: align-center - - ESP-LyraP-LCD32 (click to enlarge) - -The document consists of the following major sections: - -- `Overview`_: Provides an overview and hardware/software setup instructions to get started. -- `Hardware reference`_: Provides more detailed information about the ESP-LyraP-LCD32's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions of the ESP-LyraP-LCD32. -- `Related Documents`_: Gives links to related documentation. - - -Overview -======== - -This extension board adds a 3.2" LCD graphic display with the resolution of 320x240. This display is connected to ESP32-S2 over the SPI bus. - - -Description of Components -------------------------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.2-layout-front.png - :align: center - :width: 934px - :height: 489px - :scale: 70% - :alt: ESP-LyraP-LCD32 - front - :figclass: align-center - - ESP-LyraP-LCD32 - front (click to enlarge) - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.2-layout-back.png - :align: center - :width: 934px - :height: 600px - :scale: 70% - :alt: ESP-LyraP-LCD32 - back - :figclass: align-center - - ESP-LyraP-LCD32 - back (click to enlarge) - - -In the description of components below, **Reserved** means that the functionality is available, but the current version of the kit does not use it. - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - Extension Header - - Male Extension Header for mounting onto a female Extension Header - * - LCD Display - - This version has a 3.2" 320x240 SPI LCD display module; the display driver/controller is either Sitronix ST7789V or Ilitek ILI9341 - * - Touch Screen Switch - - No support for touch screens, keep the switches to OFF to make the pins available for other uses - * - Main Board 3.2" LCD FPC Connector - - (Reserved) Connect to main board's 3.2" LCD FPC connector - * - Control Switch - - Switch to ON to set Reset/Backlight_control/CS to default high or low; switch to OFF to make the pins available for other uses - - -Start Application Development ------------------------------ - -Before powering up your ESP-LyraP-LCD32, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- Board with a female Extension Header (e.g., ESP32-S2-Kaluga-1, ESP-LyraT-8311A) -- ESP-LyraP-LCD32 extension board -- Four mounting bolts (for stable mounting) -- Computer running Windows, Linux, or macOS - - -Hardware Setup -^^^^^^^^^^^^^^ - -To mount your ESP-LyraP-LCD32 onto the board with a female Extension Header: - -1. Install the four mounting bolts onto the board with a female Extension Header -2. Align the ESP-LyraP-LCD32 with the bolts and Extension Header and insert it carefully - - -Software Setup -^^^^^^^^^^^^^^ - -See Section :ref:`user-guide-esp32-s2-kaluga-1-kit-software-setup` of the ESP32-S2-Kaluga-1 kit user guide. - - -Hardware Reference -================== - -Block Diagram -------------- - -A block diagram below shows the components of the ESP-LyraP-LCD32 and their interconnections. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.2-block-diagram.png - :align: center - :alt: ESP-LyraP-LCD32 block diagram - :figclass: align-center - - ESP-LyraP-LCD32 block diagram - - -Hardware Revision Details -========================= - -ESP-LyraP-LCD32 v1.2 --------------------- - -* LCD backlight default ON, cannot be controlled by MCU -* Touch Driver and related switch removed for major limitations caused by multiplexed pins - - -ESP-LyraP-LCD32 v1.1 --------------------- - -:doc:`Initial release ` - - -Related Documents -================= - -- `ESP-LyraP-LCD32 Schematic `_ (PDF) -- `ESP-LyraP-LCD32 PCB Layout `_ (PDF) - -For other design documentation for the board, please contact us at sales@espressif.com. diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-toucha-v1.1.rst b/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-toucha-v1.1.rst deleted file mode 100644 index 622984c10fde..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrap-toucha-v1.1.rst +++ /dev/null @@ -1,118 +0,0 @@ -===================== -ESP-LyraP-TouchA v1.1 -===================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide provides information on the ESP-LyraP-TouchA extension board. - -This board cannot be bought separately and is usually sold together with other Espressif development boards (e.g., ESP32-S2-Kaluga-1), which will be referred to as *main boards* below. - -Currently, ESP-LyraP-TouchA v1.1 is sold as part of the following kits: - -* :doc:`user-guide-esp32-s2-kaluga-1-kit` -* :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2` - -The ESP-LyraP-TouchA extends the functionality of your main board by adding touch buttons. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-toucha-v1.1-3d.png - :align: center - :alt: ESP-LyraP-TouchA - :figclass: align-center - - ESP-LyraP-TouchA - -The document consists of the following major sections: - -- `Overview`_: Provides an overview and hardware setup instructions. -- `Hardware reference`_: Provides more detailed information about the ESP-LyraP-TouchA's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions of the ESP-LyraP-TouchA. -- `Related Documents`_: Gives links to related documentation. - - -Overview -======== - -The ESP-LyraP-TouchA has six touch buttons and is mainly designed for audio applications. However, the touch buttons can also be used for any other purposes. - - -Description of Components -------------------------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-toucha-v1.1-layout-front.png - :align: center - :alt: ESP-LyraP-TouchA - :figclass: align-center - - ESP-LyraP-TouchA - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - Main Board Touch FPC Connector - - Connect to main board's Touch FPC Connector. - * - Touchpad - - Capacitive touch electrode. - * - Guard Ring - - Connected to a touch sensor, the guard ring triggers an interrupt if wet (Water rejection). It indicates that the sensor array is also wet and most (if not all) touchpads are unusable due to the false detection of touches. After receiving this interrupt, the user might consider disabling all the touch sensors via software. - - -Start Application Development ------------------------------ - -Before powering up your ESP-LyraP-TouchA, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- Board with a Touch FPC connector (e.g., ESP32-S2-Kaluga-1) -- ESP-LyraP-TouchA extension board -- FPC cable -- Computer running Windows, Linux, or macOS - - -Hardware Setup -^^^^^^^^^^^^^^ - -Connect the two FPC connectors with the FPC cable. - - -Software Setup -^^^^^^^^^^^^^^ - -See Section :ref:`user-guide-esp32-s2-kaluga-1-kit-software-setup` of the ESP32-S2-Kaluga-1 kit user guide. - - -Hardware Reference -================== - -Block Diagram -------------- - -A block diagram below shows the components of ESP-LyraP-TouchA and their interconnections. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-toucha-v1.1-block-diagram.png - :align: center - :alt: ESP-LyraP-TouchA-v1.1 block diagram - :figclass: align-center - - ESP-LyraP-TouchA-v1.1 block diagram - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -- `ESP-LyraP-TouchA Schematic `_ (PDF) -- `ESP-LyraP-TouchA PCB Layout `_ (PDF) - -For other design documentation for the board, please contact us at sales@espressif.com. diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.2.rst b/docs/en/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.2.rst deleted file mode 100644 index cce57e3b422a..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.2.rst +++ /dev/null @@ -1,150 +0,0 @@ -==================== -ESP-LyraT-8311A v1.2 -==================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide provides information on the ESP-LyraT-8311A extension board. - -This board cannot be bought separately and is usually sold together with other Espressif development boards (e.g., ESP32-S2-Kaluga-1), which will be referred to as *main boards* below. - -Currently, ESP-LyraT-8311A v1.2 is sold as part of the :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2`. - -The ESP-LyraT-8311A extends the functionality of your main board by adding sound processing functionality: - -- Audio playback/recording -- Processing of audio signals -- Programmable buttons for easy control - -This extension board can be used in many ways. The applications might include voice user interface, voice control, voice authorization, recording and playback of sound, etc. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.2-3d.png - :align: center - :width: 2545px - :height: 1786px - :scale: 30% - :alt: ESP-LyraT-8311A - :figclass: align-center - - ESP-LyraT-8311A (click to enlarge) - -The document consists of the following major sections: - -- `Overview`_: Provides an overview and hardware setup instructions. -- `Hardware reference`_: Provides more detailed information about the ESP-LyraT-8311A's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions of the ESP-LyraT-8311A. -- `Related Documents`_: Gives links to related documentation. - - -Overview -======== - -The ESP-LyraT-8311A is mainly designed for audio applications. However, you can use your creativity to come up with any other use cases. - - -Description of Components -------------------------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.2-layout-front.png - :align: center - :width: 934px - :height: 565px - :scale: 70% - :alt: ESP-LyraT-8311A - front - :figclass: align-center - - ESP-LyraT-8311A - front (click to enlarge) - -The description of components starts from the top right corner and then goes clockwise. - -**Reserved** means that the functionality is available, but the current version of the kit does not use it. - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - Extension Header - - Male Extension Header on the flip side is for mounting onto main board's Extension Header; Female Extension Header is for mounting other boards that have a Male Extension Header - * - Function Button - - This board has six programmable buttons - * - Microphone - - Supports Electret and MEMS microphones; this extension board is supplied with an electret microphone - * - Headphone Connector - - 6.3 mm (1/8") stereo headphone connector - * - Speaker Connector - - Connect an external speaker to the 2-pin connector - * - PA - - 3 W Audio signal amplifier for the external speaker - * - External Mic-Matrix Connector - - (Reserved) FPC connector for external Mic-Matrix (microphone boards) - * - ADC - - (Reserved) high-performance ADC/ES7243: 1 channel for microphone, 1 channel for acoustic echo cancellation (AEC) function - * - Mono Audio Codec - - ES8311 audio ADC and DAC; it can convert the analog signal picked up by the microphone or convert digital signal to play it back through a speaker or headphones - - -Start Application Development ------------------------------ - -Before powering up your ESP-LyraT-8311A, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- Board with a female Extension Header (e.g., ESP32-S2-Kaluga-1) -- ESP-LyraT-8311A extension board -- Four mounting bolts (for stable mounting) -- Computer running Windows, Linux, or macOS - - -Hardware Setup -^^^^^^^^^^^^^^ - -To mount your ESP-LyraT-8311A onto the board with a female Extension Header: - -1. Install the four mounting bolts onto the board with a female Extension Header -2. Align the ESP-LyraT-8311A with the bolts and Extension Header and insert it carefully - - -Software Setup -^^^^^^^^^^^^^^ - -Depending on your application, see: - -* `ESP-ADF Getting Started Guide `_ if you develop with ESP-ADF (Espressif Audio Development Framework). -* Section :ref:`user-guide-esp32-s2-kaluga-1-kit-v1.2-software-setup` of the ESP32-S2-Kaluga-1 kit user guide if you develop directly with ESP-IDF (Espressif IOT Development Framework). - - -Hardware Reference -================== - -Block Diagram -------------- - -A block diagram below shows the components of ESP-LyraT-8311A and their interconnections. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.2-block-diagram.png - :align: center - :alt: ESP-LyraT-8311A block diagram - :figclass: align-center - - ESP-LyraT-8311A block diagram - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -- `ESP-LyraT-8311A Schematic `_ (PDF) -- `ESP-LyraT-8311A PCB Layout `_ (PDF) - -For other design documentation for the board, please contact us at sales@espressif.com. diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.3.rst b/docs/en/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.3.rst deleted file mode 100644 index 8e28abe645dd..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.3.rst +++ /dev/null @@ -1,159 +0,0 @@ -==================== -ESP-LyraT-8311A v1.3 -==================== - -:link_to_translation:`zh_CN:[中文]` - -This user guide provides information on the ESP-LyraT-8311A extension board. - -This board cannot be bought separately and is usually sold together with other Espressif development boards (e.g., ESP32-S2-Kaluga-1), which will be referred to as *main boards* below. - -Currently, ESP-LyraT-8311A v1.3 is sold as part of the :doc:`user-guide-esp32-s2-kaluga-1-kit`. - -The ESP-LyraT-8311A extends the functionality of your main board by adding sound processing functionality: - -- Audio playback/recording -- Processing of audio signals -- Programmable buttons for easy control - -This extension board can be used in many ways. The applications might include voice user interface, voice control, voice authorization, recording and playback of sound, etc. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.3-3d.png - :align: center - :width: 1934px - :height: 1473px - :scale: 30% - :alt: ESP-LyraT-8311A - :figclass: align-center - - ESP-LyraT-8311A (click to enlarge) - -The document consists of the following major sections: - -- `Overview`_: Provides an overview and hardware setup instructions. -- `Hardware reference`_: Provides more detailed information about the ESP-LyraT-8311A's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions of the ESP-LyraT-8311A. -- `Related Documents`_: Gives links to related documentation. - - -Overview -======== - -The ESP-LyraT-8311A is mainly designed for audio applications. However, you can use your creativity to come up with any other use cases. - - -Description of Components -------------------------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.3-layout-front.png - :align: center - :width: 934px - :height: 565px - :scale: 70% - :alt: ESP-LyraT-8311A - front - :figclass: align-center - - ESP-LyraT-8311A - front (click to enlarge) - -The description of components starts from the top right corner and then goes clockwise. - -**Reserved** means that the functionality is available, but the current version of the kit does not use it. - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - Extension Header - - Male Extension Header on the flip side is for mounting onto main board's Extension Header; Female Extension Header is for mounting other boards that have a Male Extension Header - * - Function Button - - This board has six programmable buttons - * - Microphone - - Supports Electret and MEMS microphones; this extension board is supplied with an electret microphone - * - Headphone Connector - - 6.3 mm (1/8") stereo headphone connector - * - Speaker Connector - - Connect an external speaker to the 2-pin connector - * - PA - - 3 W Audio signal amplifier for the external speaker - * - External Mic-Matrix Connector - - (Reserved) FPC connector for external Mic-Matrix (microphone boards) - * - ADC - - (Reserved) high-performance ADC/ES7243: 1 channel for microphone, 1 channel for acoustic echo cancellation (AEC) function - * - Mono Audio Codec - - ES8311 audio ADC and DAC; it can convert the analog signal picked up by the microphone or convert digital signal to play it back through a speaker or headphones - - -Start Application Development ------------------------------ - -Before powering up your ESP-LyraT-8311A, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- Board with a female Extension Header (e.g., ESP32-S2-Kaluga-1) -- ESP-LyraT-8311A extension board -- Four mounting bolts (for stable mounting) -- Computer running Windows, Linux, or macOS - - -Hardware Setup -^^^^^^^^^^^^^^ - -To mount your ESP-LyraT-8311A onto the board with a female Extension Header: - -1. Install the four mounting bolts onto the board with a female Extension Header -2. Align the ESP-LyraT-8311A with the bolts and Extension Header and insert it carefully - - -Software Setup -^^^^^^^^^^^^^^ - -Depending on your application, see: - -* `ESP-ADF Getting Started Guide `_ if you develop with ESP-ADF (Espressif Audio Development Framework). -* Section :ref:`user-guide-esp32-s2-kaluga-1-kit-software-setup` of the ESP32-S2-Kaluga-1 kit user guide if you develop directly with ESP-IDF (Espressif IOT Development Framework). - - -Hardware Reference -================== - -Block Diagram -------------- - -A block diagram below shows the components of ESP-LyraT-8311A and their interconnections. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.3-block-diagram.png - :align: center - :alt: ESP-LyraT-8311A block diagram - :figclass: align-center - - ESP-LyraT-8311A block diagram - - -Hardware Revision Details -========================= - -ESP-LyraT-8311A v1.3 --------------------- - -* ADC/ES7243 and ADC/ES7210 removed as the Mono Audio Codec chip provides all the needed functionality. - - -ESP-LyraT-8311A v1.2 --------------------- - -:doc:`Initial release ` - - -Related Documents -================= - -- `ESP-LyraT-8311A Schematic `_ (PDF) -- `ESP-LyraT-8311A PCB Layout `_ (PDF) - -For other design documentation for the board, please contact us at sales@espressif.com. diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst b/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst deleted file mode 100644 index d2cdb80969d9..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst +++ /dev/null @@ -1,380 +0,0 @@ -========================== -ESP32-S2-Kaluga-1 Kit v1.2 -========================== - -:link_to_translation:`zh_CN:[中文]` - -New version available: :doc:`user-guide-esp32-s2-kaluga-1-kit` - -The ESP32-S2-Kaluga-1 kit v1.2 is a development kit by Espressif that is mainly created to: - -- Demonstrate the ESP32-S2's human-computer interaction functionalities -- Provide the users with the tools for development of human-computer interaction applications based on the ESP32-S2 - -There are many ways of how the ESP32-S2's abundant functionalities can be used. For starters, the possible use cases may include: - -- **Smart home**: From simplest smart lighting, smart door locks, smart sockets, to video streaming devices, security cameras, OTT devices, and home appliances -- **Battery-powered equipment**: Wi-Fi mesh sensor networks, Wi-Fi-networked toys, wearable devices, health management equipment -- **Industrial automation equipment**: Wireless control and robot technology, intelligent lighting, HVAC control equipment, etc. -- **Retail and catering industry**: POS machines and service robots - - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-kit-v1.0-3d.png - :align: center - :width: 3452px - :height: 1590px - :scale: 20% - :alt: ESP32-S2-Kaluga-1-Kit-Assembly - :figclass: align-center - - ESP32-S2-Kaluga-1-Kit Overview (click to enlarge) - - -The ESP32-S2-Kaluga-1 kit consists of the following boards: - -- Main board: *ESP32-S2-Kaluga-1* -- Extension boards: - - - :doc:`user-guide-esp-lyrat-8311a_v1.2` - audio player - - :doc:`user-guide-esp-lyrap-toucha-v1.1` - touch panel - - :doc:`user-guide-esp-lyrap-lcd32-v1.1` - 3.2" LCD screen - - :doc:`user-guide-esp-lyrap-cam-v1.0` - camera board - -Due to the presence of multiplexed pins on ESP32-S2, certain extension board combinations have limited compatibility. For more details, please see :ref:`user-guide-esp32-s2-kaluga-1-kit-v1.2-ext-board-compatibility`. - -This document is **mostly dedicated to the main board** and its interaction with the extension boards. For more detailed information on each extension board, click their respective links. - -This guide covers: - -- `Getting Started`_: Provides an overview of the ESP32-S2-Kaluga-1 and hardware/software setup instructions to get started. -- `Hardware reference`_: Provides more detailed information about the ESP32-S2-Kaluga-1's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions of the ESP32-S2-Kaluga-1. -- `Related Documents`_: Gives links to related documentation. - - -Getting Started -=============== - -This section describes how to get started with the ESP32-S2-Kaluga-1. It begins with a few introductory sections about the ESP32-S2-Kaluga-1, then Section `Start Application Development`_ provides instructions on how to do the initial hardware setup and then how to flash firmware onto the ESP32-S2-Kaluga-1. - - -Overview --------- - -The ESP32-S2-Kaluga-1 main board is the heart of the kit. It integrates the ESP32-S2-WROVER module and all the connectors for extension boards. This board is the key tool in prototyping human-computer interaction interfaces. - -The ESP32-S2-Kaluga-1 board has connectors for boards with: - -- Extension header (ESP-LyraT-8311A, ESP-LyraP-LCD32) -- Camera header (ESP-LyraP-CAM) -- Touch FPC connector (ESP-LyraP-TouchA) -- LCD FPC connector (no official extension boards yet) -- I2C FPC connector (no official extension boards yet) - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-3d.png - :align: center - :width: 2631px - :height: 1966px - :scale: 25% - :alt: ESP32-S2-Kaluga-1 - :figclass: align-center - - ESP32-S2-Kaluga-1 (click to enlarge) - -All the four extension boards are specially designed to support the following features: - -* Touch panel control - * Six touch buttons - * Supports acrylic panels up to 5 mm - * Wet hand operation - * Water rejection, ESP32-S2 can be configured to disable all touchpads automatically if multiple pads are simultaneously covered with water and to re-enable touchpads if the water is removed - -* Audio playback - * Connect speakers to play audio - * Use together with the Touch panel to control audio playback and adjust volume - -* LCD display - * LCD interface (8-bit parallel RGB, 8080, and 6800 interface) - -* Camera image acquisition - * Supports OV2640 and OV3660 camera modules - * 8-bit DVP image sensor interface (ESP32-S2 also supports 16-bit DVP image sensors, you can design it yourself) - * Clock frequency up to 40 MHz - * Optimized DMA transmission bandwidth for easier transmission of high-resolution images - - -Description of Components -------------------------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-layout-front.png - :align: center - :width: 934px - :height: 645px - :scale: 70% - :alt: ESP32-S2-Kaluga-1 - front - :figclass: align-center - - ESP32-S2-Kaluga-1 - front (click to enlarge) - - -The description of components starts from the ESP32-S2 module on the left side and then goes clockwise. - -**Reserved** means that the functionality is available, but the current version of the kit does not use it. - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-S2-WROVER Module - - Module integrating the ESP32-S2 chip that provides Wi-Fi connectivity, data processing power, and flexible data storage. - * - 4.3" LCD FPC Connector - - (Reserved) Connect to a 4.3" LCD extension board using the FPC cable. - * - ESP Prog Connector - - (Reserved) Connection for Espressif's download device (ESP-Prog) to flash ESP32-S2 system. - * - JTAG Switch - - Switch to ON to enable connection between ESP32-S2 and FT2232; JTAG debugging will then be possible using USB-UART/JTAG Port. See also :doc:`../../api-guides/jtag-debugging/index`. - * - Breakout Header 2 - - Some GPIO pins of the ESP32-S2-WROVER module are broken out to this header, see labels on the board. - * - USB-to-UART/JTAG Bridge - - FT2232 adapter board allowing for communication over USB port using UART/JTAG protocols. - * - Camera Header - - Mount a camera extension board here (e.g., ESP-LyraP-CAM). - * - Extension Header - - Mount the extension boards having such connectors here. - * - Reset Button - - Press this button to restart the system. - * - Boot Button - - Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. - * - USB-UART/JTAG Port - - Communication interface (UART or JTAG) between a PC and the ESP32-S2 module. - * - USB Power Port - - Power supply for the board. - * - Battery Port - - Connect an external battery to the 2-pin battery connector. - * - Power On LED - - Turns on when the USB or an external power supply is connected to the board. - * - Power Switch - - Switch to ON to power the system. - * - RGB Jumper - - To have access to the RGB LED, place a jumper onto the pins. - * - RGB LED - - Programmable RGB LED and controlled by GPIO45. Before using it, you need to put RGB Jumper ON. - * - Power Regulator - - Regulator converts 5 V to 3.3 V. - * - I2C FPC Connector - - (Reserved) Connect to other I2C extension boards using the FPC cable. - * - Breakout Header 1 - - Some GPIO pins of the ESP32-S2-WROVER module are broken out to this header, see labels on the board. - * - Touch FPC Connector - - Connect the ESP-LyraP-TouchA extension board using the FPC cable. - * - Touch Switch - - In OFF position, GPIO1 to GPIO14 are used for connection to touch sensors; switch to ON if you want to use them for other purposes. - * - 3.2" LCD FPC connector - - Connect a 3.2" LCD extension board (e.g., ESP-LyraP-LCD32) using the FPC cable. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-S2-Kaluga-1, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- ESP32-S2-Kaluga-1 -- Two USB 2.0 cables (Standard-A to Micro-B) - - - For power supply - - For UART/JTAG communication - -- Computer running Windows, Linux, or macOS -- Any extension boards of your choice - - -Hardware Setup -^^^^^^^^^^^^^^ - -1. Connect the extension board(s) of your choice (go to their respective user guides if necessary) -2. Plug in both USB cables -3. Turn the **Power Switch** to ON - the Power On LED will light up - - -.. _user-guide-esp32-s2-kaluga-1-kit-v1.2-software-setup: - -Software Setup -^^^^^^^^^^^^^^ - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment. - -The programming guide and application examples for your ESP32-S2-Kaluga-1 kit can be found in `esp-dev-kits `_ repository on GitHub. - - -Contents and Packaging ----------------------- - -Retail Orders -^^^^^^^^^^^^^ - -If you order one or several samples of the kit, each ESP32-S2-Kaluga-1 development kit comes in an individual package containing: - -- Main Board - - ESP32-S2-Kaluga-1 -- Extension Boards: - - ESP-LyraT-8311A - - ESP-LyraP-CAM - - ESP-LyraP-TouchA - - ESP-LyraP-LCD32 -- Connectors - - 20-pin FPC cable (to connect ESP32-S2-Kaluga-1 to ESP-LyraP-TouchA) -- Fasteners - - Mounting bolts (x8) - - Screws (x4) - - Nuts (x4) - -For retail orders, please go to https://www.espressif.com/en/contact-us/get-samples. - - -Wholesale Orders -^^^^^^^^^^^^^^^^ - -If you order in bulk, the boards come in large cardboard boxes. - -For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales-questions. - - -Hardware Reference -================== - -Block Diagram -------------- - -A block diagram below shows the components of the ESP32-S2-Kaluga-1 and their interconnections. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-block-diagram.png - :align: center - :alt: ESP32-S2-Kaluga-1 block diagram - :figclass: align-center - - ESP32-S2-Kaluga-1 block diagram - - -Power Supply Options --------------------- - -There are four ways to provide power to the board: - -- Micro USB port, default power supply -- External battery via the 2-pin battery connector -- 5V and GND header pins -- 3V3 and GND header pins - - -.. _user-guide-esp32-s2-kaluga-1-kit-v1.2-ext-board-compatibility: - -Compatibility of Extension Boards ---------------------------------- - -If you want to use more than one extension board at the same time, please check the table given below. - -.. list-table:: - :widths: 20 10 30 40 - :header-rows: 1 - - * - Boards Used - - HW Conflict - - Limitations - - Solution - * - 8311A v1.2 + CAM v1.0 - - I2S Controller, IO46 - - ESP32-S2 has only one I2S interface. But both extension boards require connection via the ESP32-S2's I2S interface (ESP-LyraT-8311A in Standard mode, ESP-LyraP-CAM in Camera mode). If IO46 is used by both extension boards at the same time, ESP-LyraP-CAM experiences interferences when used. - - No ready solution for now. - * - TouchA v1.1 + LCD32 v1.1 - - IO11, IO6 - - Touch actions cannot be triggered because of the multiplexed pin IO11. ESP-LyraP-LCD32 is also affected because its BK (BLCT) pin is connected to pin IO6. - - Do not initialize IO11 (NETWORK) and IO6 (PHOTO) for your ESP-LyraP-TouchA. - * - 8311A v1.2 + LCD32 v1.1 - - IO6 - - The two extension boards can be used at the same time. However, since the BK (BLCT) pin of ESP32-S2-Kaluga-1 is connected to IO6, ESP-LyraT-8311A's pin BT_ADC cannot be used and the board's six buttons will not be available. - - There is a solution that will allow you to use ESP-LyraT-8311A's pin BT_ADC, but will stop you from controlling the display background brightness with software: on your ESP-LyraP-LCD32 board, remove R39, change R41 to 100 Ohm, switch BLCT_L to on. - * - TouchA v1.1 + 8311A v1.2 - - Pin BT_ADC on ESP-LyraT-8311A - - The two extension boards can be used at the same time. However, ESP-LyraP-TouchA cannot be triggered if ESP-LyraT-8311A's pin BT_ADC is used to initialize the board's six buttons. - - If you plan to use ESP-LyraT-8311A's pin BT_ADC, do not initialize pin IO6 (PHOTO) for your ESP-LyraP-TouchA. - * - TouchA v1.1 + CAM v1.0 - - IO1, IO2, IO3 - - Cannot be used simultaneously because of the mentioned multiplexed pins. - - For ESP-LyraP-TouchA, do not initialize IO1 (VOL_UP), IO2 (PLAY), and IO3 (VOL_DOWN). - * - TouchA v1.1 + LCD32 v1.1 + CAM v1.0 - - IO1, IO2, IO3, IO6, IO11 - - Conflicts on the mentioned multiplexed pins. - - **Solution 1**: For ESP-LyraP-TouchA, do not initialize IO1 (VOL_UP), IO2 (PLAY), IO3 (VOL_DOWN), IO6 (PHOTO) and IO11 (NETWORK). **Solution 2**: It will allow you to initialize IO6 (PHOTO) properly, but will stop you from controlling the background brightness with software. On your ESP-LyraP-LCD32, remove R39, change R41 to 100 Ohm, switch BLCT_L to on. - * - TouchA v1.1 + LCD32 v1.1 + 8311A v1.2 - - IO6, IO11 - - IO11 is multiplexed; IO6 is also multiplexed stopping you from using ESP-LyraT-8311A's pin BT_ADC that is needed to initialize the board's six buttons. - - **Solution 1**: For ESP-LyraP-TouchA, do not initialize IO6 (PHOTO) and IO11 (NETWORK). Please note that the six buttons on ESP-LyraT-8311A still cannot be used. **Solution 2**: On your ESP-LyraP-LCD32, remove R39, change R41 to 100 Ohm, switch BLCT_L to on. For your ESP-LyraP-TouchA, do not initialize IO11 (NETWORK). If you want to use the six buttons on your ESP-LyraT-8311A, also do not initialize IO6 (PHOTO). - -Also, all extension boards and the :ref:`JTAG interface ` share the same pins IO39, IO40, IO41 and IO42. For this reason, the following may disturb the JTAG operation: - -* Plugging in any extension board -* Debugging an application that is using an extension board - - -Known Issues -============ - -.. list-table:: - :widths: 22 24 32 22 - :header-rows: 1 - - * - Hardware Issue - - Description - - Reason for Failure - - Solution - * - ESP-LyraP-CAM v1.0, pin IO45, IO46 - - Flashing firmware might be impossible with the extension board connected to the main board. - - Incorrect timing sequence is fed to strapping pins IO45 and IO46 when the board is powered on. It stops the board from booting successfully. - - While flashing the main board, keep the extension board disconnected. - * - ESP-LyraP-CAM v1.0, pin IO45, IO46 - - Rebooting the board by pressing Reset might not lead to desired results. - - Incorrect timing sequence is fed to strapping pins IO45 and IO46 when the board is powered on. It stops the board from booting successfully. - - No ready solution for v1.2. This bug is fixed in ESP32-S2-Kaluga-1 V1.3. - * - ESP-LyraT-8311A v1.2, pin IO46 - - Flashing firmware might be impossible with the extension board connected to the main board. - - Incorrect timing sequence is fed to strapping pin IO46 when the board is powered on. It stops the board from booting successfully. - - While flashing the main board, keep the extension board disconnected. - * - ESP-LyraT-8311A v1.2, pin IO46 - - Rebooting the board by pressing Reset might not lead to desired results. - - Incorrect timing sequence is fed to strapping pin IO46 when the board is powered on. It stops the board from booting successfully. - - No ready solution for v1.2. This bug is fixed in ESP32-S2-Kaluga-1 V1.3. - - -Hardware Revision Details -========================= - -No previous versions available. - - -Related Documents -================= - -.. toctree:: - :hidden: - - user-guide-esp-lyrap-cam-v1.0 - user-guide-esp-lyrap-lcd32-v1.1 - user-guide-esp-lyrap-toucha-v1.1 - user-guide-esp-lyrat-8311a_v1.2 - -- `ESP32-S2-WROVER Datasheet `_ (PDF) -- `ESP Product Selector `_ -- :doc:`../../api-guides/jtag-debugging/index` - -- `ESP32-S2-Kaluga-1 Schematic `_ (PDF) -- `ESP32-S2-Kaluga-1 PCB Layout `_ (PDF) -- `ESP32-S2-Kaluga-1 Pin Mapping `_ (Excel) - -For other design documentation for the board, please contact us at sales@espressif.com. diff --git a/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst b/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst deleted file mode 100644 index e3987699680d..000000000000 --- a/docs/en/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst +++ /dev/null @@ -1,395 +0,0 @@ -========================== -ESP32-S2-Kaluga-1 Kit v1.3 -========================== - -:link_to_translation:`zh_CN:[中文]` - -Older version: :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2` - -The ESP32-S2-Kaluga-1 kit v1.3 is a development kit by Espressif that is mainly created to: - -- Demonstrate the ESP32-S2's human-computer interaction functionalities -- Provide the users with the tools for development of human-computer interaction applications based on the ESP32-S2 - -There are many ways of how the ESP32-S2's abundant functionalities can be used. For starters, the possible use cases may include: - -- **Smart home**: From simplest smart lighting, smart door locks, smart sockets, to video streaming devices, security cameras, OTT devices, and home appliances -- **Battery-powered equipment**: Wi-Fi mesh sensor networks, Wi-Fi-networked toys, wearable devices, health management equipment -- **Industrial automation equipment**: Wireless control and robot technology, intelligent lighting, HVAC control equipment, etc. -- **Retail and catering industry**: POS machines and service robots - -.. Image of v1.2 is used as there are no visual changes - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-kit-v1.0-3d.png - :align: center - :width: 3452px - :height: 1590px - :scale: 20% - :alt: ESP32-S2-Kaluga-1-Kit-Assembly - :figclass: align-center - - ESP32-S2-Kaluga-1-Kit Overview (click to enlarge) - - -The ESP32-S2-Kaluga-1 kit consists of the following boards: - -- Main board: *ESP32-S2-Kaluga-1* -- Extension boards: - - - :doc:`user-guide-esp-lyrat-8311a_v1.3` - audio player - - :doc:`user-guide-esp-lyrap-toucha-v1.1` - touch panel - - :doc:`user-guide-esp-lyrap-lcd32-v1.2` - 3.2" LCD screen - - :doc:`user-guide-esp-lyrap-cam-v1.1` - camera board - -Due to the presence of multiplexed pins on ESP32-S2, certain extension board combinations have limited compatibility. For more details, please see :ref:`user-guide-esp32-s2-kaluga-1-kit-ext-board-compatibility`. - -This document is **mostly dedicated to the main board** and its interaction with the extension boards. For more detailed information on each extension board, click their respective links. - -This guide covers: - -- `Getting Started`_: Provides an overview of the ESP32-S2-Kaluga-1 and hardware/software setup instructions to get started. -- `Hardware reference`_: Provides more detailed information about the ESP32-S2-Kaluga-1's hardware. -- `Hardware Revision Details`_: Covers revision history, known issues, and links to user guides for previous versions of the ESP32-S2-Kaluga-1. -- `Related Documents`_: Gives links to related documentation. - - -Getting Started -=============== - -This section describes how to get started with the ESP32-S2-Kaluga-1. It begins with a few introductory sections about the ESP32-S2-Kaluga-1, then Section `Start Application Development`_ provides instructions on how to do the initial hardware setup and then how to flash firmware onto the ESP32-S2-Kaluga-1. - - -Overview --------- - -The ESP32-S2-Kaluga-1 main board is the heart of the kit. It integrates the ESP32-S2-WROVER module and all the connectors for extension boards. This board is the key tool in prototyping human-computer interaction interfaces. - -The ESP32-S2-Kaluga-1 board has connectors for boards with: - -- Extension header (ESP-LyraT-8311A, ESP-LyraP-LCD32) -- Camera header (ESP-LyraP-CAM) -- Touch FPC connector (ESP-LyraP-TouchA) -- LCD FPC connector (no official extension boards yet) -- I2C FPC connector (no official extension boards yet) - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32s2-kaluga-1-v1.3-3d.png - :align: center - :width: 3089px - :height: 2335px - :scale: 25% - :alt: ESP32-S2-Kaluga-1 - :figclass: align-center - - ESP32-S2-Kaluga-1 (click to enlarge) - -All the four extension boards are specially designed to support the following features: - -* Touch panel control - * Six touch buttons - * Supports acrylic panels up to 5 mm - * Wet hand operation - * Water rejection, ESP32-S2 can be configured to disable all touchpads automatically if multiple pads are simultaneously covered with water and to re-enable touchpads if the water is removed - -* Audio playback - * Connect speakers to play audio - * Use together with the Touch panel to control audio playback and adjust volume - -* LCD display - * LCD interface (8-bit parallel RGB, 8080, and 6800 interface) - -* Camera image acquisition - * Supports OV2640 and OV3660 camera modules - * 8-bit DVP image sensor interface (ESP32-S2 also supports 16-bit DVP image sensors, you can design it yourself) - * Clock frequency up to 40 MHz - * Optimized DMA transmission bandwidth for easier transmission of high-resolution images - - -Description of Components -------------------------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.3-layout-front.png - :align: center - :width: 934px - :height: 645px - :scale: 70% - :alt: ESP32-S2-Kaluga-1 - front - :figclass: align-center - - ESP32-S2-Kaluga-1 - front (click to enlarge) - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.3-layout-back.png - :align: center - :width: 934px - :height: 600px - :scale: 70% - :alt: ESP32-S2-Kaluga-1 - back - :figclass: align-center - - ESP32-S2-Kaluga-1 - back (click to enlarge) - - -The description of components starts from the ESP32-S2 module on the left side and then goes clockwise. - -**Reserved** means that the functionality is available, but the current version of the kit does not use it. - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Key Component - - Description - * - ESP32-S2-WROVER Module - - Module integrating the ESP32-S2 chip that provides Wi-Fi connectivity, data processing power, and flexible data storage. - * - 4.3" LCD FPC Connector - - (Reserved) Connect to a 4.3" LCD extension board using the FPC cable. - * - ESP Prog Connector - - (Reserved) Connection for Espressif's download device (ESP-Prog) to flash ESP32-S2 system. - * - JTAG Switch - - Switch to ON to enable connection between ESP32-S2 and FT2232; JTAG debugging will then be possible using USB-UART/JTAG Port. See also :doc:`../../api-guides/jtag-debugging/index`. - * - Breakout Header 2 - - Some GPIO pins of the ESP32-S2-WROVER module are broken out to this header, see labels on the board. - * - USB-to-UART/JTAG Bridge - - FT2232 adapter board allowing for communication over USB port using UART/JTAG protocols. - * - Camera Header - - Mount a camera extension board here (e.g., ESP-LyraP-CAM). - * - Extension Header - - Mount the extension boards having such connectors here. - * - Reset Button - - Press this button to restart the system - * - Boot Button - - Holding down **Boot** and then pressing **Reset** initiates Firmware Download mode for downloading firmware through the serial port. - * - USB-UART/JTAG Port - - Communication interface (UART or JTAG) between a PC and the ESP32-S2 module. - * - USB Power Port - - Power supply for the board. - * - Battery Port - - Connect an external battery to the 2-pin battery connector. - * - Power On LED - - Turns on when the USB or an external power supply is connected to the board. - * - Power Switch - - Switch to ON to power the system. - * - RGB Jumper - - To have access to the RGB LED, place a jumper onto the pins. - * - RGB LED - - Programmable RGB LED and controlled by GPIO45. Before using it, you need to put RGB Jumper ON. - * - Power Regulator - - Regulator converts 5 V to 3.3 V. - * - I2C FPC Connector - - (Reserved) Connect to other I2C extension boards using the FPC cable. - * - Breakout Header 1 - - Some GPIO pins of the ESP32-S2-WROVER module are broken out to this header, see labels on the board. - * - Touch FPC Connector - - Connect the ESP-LyraP-TouchA extension board using the FPC cable. - * - Touch Switch - - In OFF position, GPIO1 to GPIO14 are used for connection to touch sensors; switch to ON if you want to use them for other purposes. - * - 3.2" LCD FPC connector - - Connect a 3.2" LCD extension board (e.g., ESP-LyraP-LCD32) using the FPC cable. - - -Start Application Development ------------------------------ - -Before powering up your ESP32-S2-Kaluga-1, please make sure that it is in good condition with no obvious signs of damage. - - -Required Hardware -^^^^^^^^^^^^^^^^^ - -- ESP32-S2-Kaluga-1 -- Two USB 2.0 cables (Standard-A to Micro-B) - - - For power supply - - For UART/JTAG communication - -- Computer running Windows, Linux, or macOS -- Any extension boards of your choice - - -Hardware Setup -^^^^^^^^^^^^^^ - -1. Connect the extension board(s) of your choice (go to their respective user guides if necessary) -2. Plug in both USB cables -3. Turn the **Power Switch** to ON - the Power On LED will light up - - -.. _user-guide-esp32-s2-kaluga-1-kit-software-setup: - -Software Setup -^^^^^^^^^^^^^^ - -Please proceed to :doc:`../../get-started/index`, where Section :ref:`get-started-step-by-step` will quickly help you set up the development environment. - -The programming guide and application examples for your ESP32-S2-Kaluga-1 kit can be found in `esp-dev-kits `_ repository on GitHub. - -A Board Support Package can be found in `IDF Component Registry `_. - - -Contents and Packaging ----------------------- - -Retail Orders -^^^^^^^^^^^^^ - -If you order one or several samples of the kit, each ESP32-S2-Kaluga-1 development kit comes in an individual package. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32s2-kaluga-1-kit-v1.3-package-3d.png - :align: center - :alt: ESP32-S2-Kaluga-1 - package - :figclass: align-center - - ESP32-S2-Kaluga-1 - package - - -The contents are as follows: - -- Main Board - - ESP32-S2-Kaluga-1 -- Extension Boards: - - ESP-LyraT-8311A - - ESP-LyraP-CAM - - ESP-LyraP-TouchA - - ESP-LyraP-LCD32 -- Connectors - - 20-pin FPC cable (to connect ESP32-S2-Kaluga-1 to ESP-LyraP-TouchA) -- Fasteners - - Mounting bolts (x8) - - Screws (x4) - - Nuts (x4) - -For retail orders, please go to https://www.espressif.com/en/contact-us/get-samples. - - -Wholesale Orders -^^^^^^^^^^^^^^^^ - -If you order in bulk, the boards come in large cardboard boxes. - -For wholesale orders, please go to https://www.espressif.com/en/contact-us/sales-questions. - - -Hardware Reference -================== - -Block Diagram -------------- - -.. Image of v1.2 is used as there are no visual changes - -A block diagram below shows the components of the ESP32-S2-Kaluga-1 and their interconnections. - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-block-diagram.png - :align: center - :alt: ESP32-S2-Kaluga-1 block diagram - :figclass: align-center - - ESP32-S2-Kaluga-1 block diagram - - -Power Supply Options --------------------- - -There are four ways to provide power to the board: - -- Micro USB port, default power supply -- External battery via the 2-pin battery connector -- 5V and GND header pins -- 3V3 and GND header pins - - -.. _user-guide-esp32-s2-kaluga-1-kit-ext-board-compatibility: - -Compatibility of Extension Boards ---------------------------------- - -If you want to use more than one extension board at the same time, please check the table given below. - -.. list-table:: - :widths: 20 15 33 32 - :header-rows: 1 - - * - Boards Used - - HW Conflict - - Limitations - - Solution - * - 8311A v1.3 + CAM v1.1 - - I2S Controller - - ESP32-S2 has only one I2S interface. But both extension boards require connection via the ESP32-S2's I2S interface (LyraT-8311A in Standard mode, ESP-LyraP-CAM in Camera mode). - - Utilize time division multiple access, or use a different audio module that can be connected via other GPIOs or DAC. - * - TouchA v1.1 + LCD32 v1.2 - - IO11, IO6 - - Touch actions cannot be triggered because of the multiplexed pin IO11. ESP-LyraP-LCD32 will not be affected because its BLCT pin will be disconnected from IO6. - - Do not initialize IO11 (NETWORK) for your ESP-LyraP-TouchA, or configure the BLCT pin to `-1` (= do not use BLCT) for your ESP-LyraP-LCD32. - * - 8311A v1.3 + LCD32 v1.2 - - IO6 - - BLCT pin of ESP32-S2-Kaluga-1 will be disconnected from IO6. - - Configure the BK pin to `-1` (= do not use BLCT) for your ESP-LyraP-LCD32. - * - TouchA v1.1 + 8311A v1.3 - - Pin BT_ADC on ESP-LyraT-8311A - - This pin is required for initialization of the six button on ESP-LyraT-8311A. At the same time, ESP-LyraP-TouchA needs this pin for its touch actions. - - If you plan to use buttons on ESP-LyraT-8311A, do not initialize pin IO6 (PHOTO) for your ESP-LyraP-TouchA. - * - TouchA v1.1 + CAM v1.1 - - IO1, IO2, IO3 - - Cannot be used simultaneously because of the mentioned multiplexed pins. - - For ESP-LyraP-TouchA, do not initialize IO1 (VOL_UP), IO2 (PLAY), and IO3 (VOL_DOWN). - * - TouchA v1.1 + LCD32 v1.2 + CAM v1.1 - - IO1, IO2, IO3, IO11 - - Conflicts on the mentioned multiplexed pins. - - For ESP-LyraP-TouchA, do not initialize IO1 (VOL_UP), IO2 (PLAY), IO3 (VOL_DOWN), and IO11 (NETWORK). - * - TouchA v1.1 + LCD32 v1.2 + 8311A v1.3 - - IO6, IO11 - - If ESP-LyraT-8311A's pin BT_ADC is used to initialize the board's six buttons, IO6 and IO11 will not be available for the other boards. - - Do not initialize IO11 (NETWORK) for your ESP-LyraP-TouchA. Also, if you need to use BT_ADC, do not initialize IO6 (PHOTO). - -Also, all extension boards and the :ref:`JTAG interface ` share the same pins IO39, IO40, IO41 and IO42. For this reason, the following may disturb the JTAG operation: - -* Plugging in any extension board -* Debugging an application that is using an extension board - - -Hardware Revision Details -========================= - -ESP32-S2-Kaluga-1 Kit v1.3 --------------------------- - -* The following pins re-assigned to fix the download issue - - * Camera D2: GPIO36 - * Camera D3: GPIO37 - * AU_I2S1_SDI: GPIO34 - * AU_WAKE_INT: GPIO46 - -* RGB pin header moved to the board's edge -* All dip switches moved to the flip side for convenient operation - - -ESP32-S2-Kaluga-1 Kit v1.2 --------------------------- - -:doc:`Initial release ` - - -Related Documents -================= - -.. toctree:: - :hidden: - - user-guide-esp32-s2-kaluga-1-kit-v1.2.rst - user-guide-esp-lyrap-cam-v1.1 - user-guide-esp-lyrap-lcd32-v1.2 - user-guide-esp-lyrat-8311a_v1.3 - -- `ESP32-S2-WROVER Datasheet `_ (PDF) -- `ESP Product Selector `_ -- :doc:`../../api-guides/jtag-debugging/index` - -- `ESP32-S2-Kaluga-1 Schematic `_ (PDF) -- `ESP32-S2-Kaluga-1 PCB Layout `_ (PDF) -- `ESP32-S2-Kaluga-1 Pin Mapping `_ (Excel) - -For other design documentation for the board, please contact us at sales@espressif.com. - - diff --git a/docs/en/hw-reference/index.rst b/docs/en/hw-reference/index.rst index 3f8b92b1439a..d19e0edc3ee2 100644 --- a/docs/en/hw-reference/index.rst +++ b/docs/en/hw-reference/index.rst @@ -7,7 +7,7 @@ Hardware Reference .. toctree:: :maxdepth: 1 - Technical Reference Manual (PDF) <{IDF_TARGET_TRM_EN_URL}> + :not esp32p4: Technical Reference Manual (PDF) <{IDF_TARGET_TRM_EN_URL}> :esp32: Chip Datasheet (PDF) :esp32s2: Chip Datasheet (PDF) :esp32s3: Chip Datasheet (PDF) @@ -15,7 +15,6 @@ Hardware Reference :esp32c3: Chip Datasheet (PDF) :esp32c6: Chip Datasheet (PDF) :esp32h2: Chip Datasheet (PDF) - :esp32p4: Chip Datasheet (PDF) :esp32: Hardware Design Guidelines (PDF) :esp32s2: Hardware Design Guidelines (PDF) :esp32s3: Hardware Design Guidelines (PDF) @@ -23,7 +22,6 @@ Hardware Reference :esp32c3: Hardware Design Guidelines (PDF) :esp32c6: Hardware Design Guidelines (PDF) :esp32h2: Hardware Design Guidelines (PDF) - :esp32p4: Hardware Design Guidelines (PDF) :esp32: Silicon Errata (PDF) :esp32s2: Silicon Errata (PDF) :esp32s3: Silicon Errata (PDF) @@ -32,10 +30,10 @@ Hardware Reference :esp32c6: Silicon Errata (PDF) :esp32h2: Silicon Errata (PDF) Chip Variants - Modules + :not esp32p4: Modules Development Boards - Espressif KiCad Library + :not esp32p4: Espressif KiCad Library ESP Product Selector - Regulatory Certificates + :not esp32p4: Regulatory Certificates Chip Series Comparison User Forum (Hardware) diff --git a/docs/zh_CN/api-guides/ble/ble-feature-support-status.rst b/docs/zh_CN/api-guides/ble/ble-feature-support-status.rst new file mode 100644 index 000000000000..60d3919ebb2a --- /dev/null +++ b/docs/zh_CN/api-guides/ble/ble-feature-support-status.rst @@ -0,0 +1,338 @@ +主要功能支持状态 +================ + +:link_to_translation:`en:[English]` + +本文档介绍了乐鑫低功耗蓝牙模块主要功能在 {IDF_TARGET_NAME} 上的支持状态。 + +|supported_def| **该功能已完成开发和内部测试。** [1]_ + +|experimental_def| **该功能已完成开发,正在进行内部测试。** +你可以探索这些功能以进行评估和反馈,但应注意可能出现的问题。 + +|developing_def| **该功能目前正在积极开发中, 预计在 YYYY/MM 月底之前支持。** +请关注此表以获得该功能的最新进展。 +如果确实有紧急的开发需求,请联系 `乐鑫客户支持团队 `__ 以了解是否可以进行功能试用。 + +|unsupported_def| **该功能在此芯片上不支持。** 如果你有相关需求,请优先选择其他支持该功能的乐鑫芯片系列。 +如果当前的乐鑫产品都不支持此功能,请联系 `乐鑫客户支持团队 `__ ,我们的研发团队会对你的需求进行内部可行性评估。 + +|NA_def| 具有此标签的功能可能为以下两种类型: + - **Host-only 功能**:该功能仅存在于 HCI 层之上,例如 GATT Caching。此类功能不需要蓝牙控制器的支持。 + - **Controller-only 功能**:该功能仅存在于 HCI 层之下,且无法通过主机API配置或启用,例如 Advertising Channel Index 。此类功能不需要蓝牙主机的支持。 + +.. list-table:: + :width: 100% + :widths: auto + :header-rows: 1 + + * - .. centered:: 核心协议 + - .. centered:: 主要功能 + - .. centered:: ESP 控制器 + - .. centered:: ESP-Bluedroid 主机 + - .. centered:: ESP-NimBLE 主机 + * - .. centered:: |4.2| + - LE Data Packet Length Extension + - |supported| + - |supported| + - |supported| + * - + - LE Secure Connections + - |supported| + - |supported| + - |supported| + * - + - Link Layer Privacy + - |supported| + - |supported| + - |supported| + * - + - Link Layer Extended Filter Policies + - |supported| + - |supported| + - |supported| + * - .. centered:: |5.0| + - 2 Msym/s PHY for LE + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + * - + - LE Long Range (Coded PHY S=2/S=8) + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + * - + - High Duty Cycle Non-Connectable Advertising + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + * - + - LE Advertising Extensions + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + * - + - LE Channel Selection Algorithm #2 + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + - .. only:: esp32 + + |unsupported| + .. only:: not esp32 + + |supported| + * - .. centered:: |5.1| + - Angle of Arrival (AoA)/Angle of Departure (AoD) + - |unsupported| + - |unsupported| + - |unsupported| + * - + - GATT Caching + - |NA| + - |experimental| + - |experimental| + * - + - Advertising Channel Index + - |unsupported| + - |NA| + - |NA| + * - + - Periodic Advertising Sync Transfer + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c2 or esp32c5 + + |experimental| + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c2 or esp32c5 + + |experimental| + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c2 or esp32c5 + + |experimental| + * - .. centered:: |5.2| + - LE Isochronous Channels (BIS/CIS) + - |unsupported| + - |unsupported| + - |unsupported| + * - + - Enhanced Attribute Protocol + - |NA| + - |unsupported| + - |developing202412| + * - + - LE Power Control + - .. only:: esp32 or esp32c2 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c3 or esp32s3 or esp32c5 + + |experimental| + - |unsupported| + - .. only:: esp32 or esp32c2 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c3 or esp32s3 or esp32c5 + + |experimental| + * - .. centered:: |5.3| + - AdvDataInfo in Periodic Advertising + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |supported| + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |supported| + - .. only:: esp32 or esp32c3 or esp32s3 + + |unsupported| + .. only:: esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |supported| + * - + - LE Enhanced Connection Update (Connection Subrating) + - .. only:: esp32 or esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |unsupported| + .. only:: esp32c3 or esp32s3 + + |experimental| + - |unsupported| + - .. only:: esp32 or esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |unsupported| + .. only:: esp32c3 or esp32s3 + + |experimental| + * - + - LE Channel Classification + - .. only:: esp32 or esp32c3 or esp32s3 or esp32c2 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c5 + + |experimental| + - .. only:: esp32 or esp32c3 or esp32s3 or esp32c2 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c5 + + |experimental| + - .. only:: esp32 or esp32c3 or esp32s3 or esp32c2 + + |unsupported| + .. only:: esp32c6 or esp32h2 or esp32c5 + + |experimental| + * - .. centered:: |5.4| + - Advertising Coding Selection + - .. only:: esp32 or esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |unsupported| + .. only:: esp32c3 or esp32s3 + + |experimental| + - |unsupported| + - .. only:: esp32 or esp32c6 or esp32c2 or esp32h2 or esp32c5 + + |unsupported| + .. only:: esp32c3 or esp32s3 + + |experimental| + * - + - Encrypted Advertising Data + - |NA| + - |unsupported| + - |experimental| + * - + - LE GATT Security Levels Characteristic + - |NA| + - |unsupported| + - |developing202412| + * - + - Periodic Advertising with Responses + - |unsupported| + - |unsupported| + - |unsupported| + +.. [1] + 如果想了解支持功能的 Bluetooth SIG 认证状态, + 请查阅 `SIG 蓝牙产品数据库 `__ 。 + +对于大部分开发需要在控制器 (Controller) 完成的功能,其主机层 (Host) 的支持状态将会受限于控制器层的支持状态。 +如果你计划将乐鑫低功耗蓝牙控制器和主机跑在不同的乐鑫芯片上,则主机的功能将不再受限于这颗跑主机的芯片上的控制器的功能支持状态, +请参阅 :doc:`ESP 主机主要功能支持状态 ` 。 + +请注意,本文档不构成对客户的约束性承诺。 +以上所列出来的功能支持状态信息仅供参考,可能会在不通知的情况下发生更改。 +建议联系 `乐鑫客户支持团队 `__ 以获取最新信息,并确认功能是否适合你的特定需求。 + + +.. |supported| image:: ../../../_static/ble/feature_status/supported.svg + :class: align-center + :width: 65px +.. |developing202412| image:: ../../../_static/ble/feature_status/developing202412.svg + :class: align-center + :width: 120px +.. |unsupported| image:: ../../../_static/ble/feature_status/unsupported.svg + :class: align-center + :width: 75px +.. |experimental| image:: ../../../_static/ble/feature_status/experimental.svg + :class: align-center + :width: 75px +.. |NA| image:: ../../../_static/ble/feature_status/NA.svg + :class: align-center + :width: 25px +.. |supported_def| image:: ../../../_static/ble/feature_status/supported.svg +.. |developing_def| image:: ../../../_static/ble/feature_status/developingYYYYMM.svg +.. |unsupported_def| image:: ../../../_static/ble/feature_status/unsupported.svg +.. |experimental_def| image:: ../../../_static/ble/feature_status/experimental.svg +.. |NA_def| image:: ../../../_static/ble/feature_status/NA.svg +.. |4.2| replace:: `4.2 `__ +.. |5.0| replace:: `5.0 `__ +.. |5.1| replace:: `5.1 `__ +.. |5.2| replace:: `5.2 `__ +.. |5.3| replace:: `5.3 `__ +.. |5.4| replace:: `5.4 `__ diff --git a/docs/zh_CN/api-guides/blufi.rst b/docs/zh_CN/api-guides/ble/blufi.rst similarity index 99% rename from docs/zh_CN/api-guides/blufi.rst rename to docs/zh_CN/api-guides/ble/blufi.rst index 4478385e2766..33737b6298c2 100644 --- a/docs/zh_CN/api-guides/blufi.rst +++ b/docs/zh_CN/api-guides/ble/blufi.rst @@ -1,10 +1,10 @@ BluFi -^^^^^ +^^^^^^ :link_to_translation:`en:[English]` 概览 ------ +-------- BluFi 是一项基于蓝牙通道的 Wi-Fi 网络配置功能,适用于 {IDF_TARGET_NAME}。它通过安全协议将 Wi-Fi 的 SSID、密码等配置信息传输到 {IDF_TARGET_NAME}。基于这些信息,{IDF_TARGET_NAME} 可进而连接到 AP 或建立 SoftAP。 @@ -13,7 +13,7 @@ BluFi 流程的关键部分包括数据的分片、加密以及校验和验证 用户可按需自定义用于对称加密、非对称加密以及校验的算法。此处,我们采用 DH 算法进行密钥协商,128-AES 算法用于数据加密,CRC16 算法用于校验和验证。 BluFi 流程 ----------- +----------- BluFi 配网流程包含配置 SoftAP 和配置 Station 两部分。 @@ -46,7 +46,7 @@ BluFi 配网流程包含配置 SoftAP 和配置 Station 两部分。 2. 进行对称加密和解密时,加密和解密前后的数据长度必须一致。支持原地加密和解密。 BluFi 流程图 ---------------- +------------ .. seqdiag:: :caption: BluFi Flow Chart @@ -75,7 +75,7 @@ BluFi 流程图 .. _frame_formats: BluFi 中定义的帧格式 ----------------------------- +--------------------- 手机应用程序与 {IDF_TARGET_NAME} 之间的 BluFi 通信格式定义如下: @@ -431,7 +431,7 @@ ACK 帧格式 (8 bit): 此字段占两个字节,用来校验序列、数据长度以及明文。 {IDF_TARGET_NAME} 端的安全实现 ----------------------------------- +----------------------------- 1. 数据安全 diff --git a/docs/zh_CN/api-guides/ble/host-feature-support-status.rst b/docs/zh_CN/api-guides/ble/host-feature-support-status.rst new file mode 100644 index 000000000000..e1cfdda19f04 --- /dev/null +++ b/docs/zh_CN/api-guides/ble/host-feature-support-status.rst @@ -0,0 +1,159 @@ +:orphan: + +ESP 主机主要功能支持状态 +======================== + +:link_to_translation:`en:[English]` + +本文档介绍了乐鑫低功耗蓝牙主机 ESP-Bluedroid 和 ESP-NimBLE 主要功能的支持状态。 +如果你计划将低功耗蓝牙控制器和主机跑在 {IDF_TARGET_NAME} 上,主机的功能支持可能会受限于控制器的功能支持状态, +请参阅 :doc:`{IDF_TARGET_NAME} 主要功能支持状态 ` 。 + +|supported_def| **该功能已完成开发和内部测试。** [1]_ + +|experimental_def| **该功能已完成开发,正在进行内部测试。** +你可以探索这些功能以进行评估和反馈,但应注意可能出现的问题。 + +|developing_def| **该功能目前正在积极开发中, 预计在 YYYY/MM 月底之前支持。** +请关注此表以获得该功能的最新进展。 +如果确实有紧急的开发需求,请联系 `乐鑫客户支持团队 `__ 以了解是否可以进行功能试用。 + +|unsupported_def| **该功能在该蓝牙主机上不支持。** 如果你有相关需求,请优先选择其他支持该功能的乐鑫蓝牙主机。 +如果当前的乐鑫产品都不支持此功能,请联系 `乐鑫客户支持团队 `__ ,我们的研发团队会对你的需求进行内部可行性评估。 + +|NA_def| 具有此标签的功能可能为以下类型: + - **Controller-only 功能**:该功能仅存在于 HCI 层之下,且无法通过主机API配置或启用,例如 Advertising Channel Index 。 + 此类功能不需要蓝牙主机的支持。 + +.. list-table:: + :width: 100% + :widths: auto + :header-rows: 1 + + * - .. centered:: 核心协议 + - .. centered:: 主要功能 + - .. centered:: ESP-Bluedroid 主机 + - .. centered:: ESP-NimBLE 主机 + * - .. centered:: |4.2| + - LE Data Packet Length Extension + - |supported| + - |supported| + * - + - LE Secure Connections + - |supported| + - |supported| + * - + - Link Layer Privacy + - |supported| + - |supported| + * - + - Link Layer Extended Filter Policies + - |supported| + - |supported| + * - .. centered:: |5.0| + - 2 Msym/s PHY for LE + - |supported| + - |supported| + * - + - LE Long Range (Coded PHY S=2/S=8) + - |supported| + - |supported| + * - + - High Duty Cycle Non-Connectable Advertising + - |supported| + - |supported| + * - + - LE Advertising Extensions + - |supported| + - |supported| + * - + - LE Channel Selection Algorithm #2 + - |supported| + - |supported| + * - .. centered:: |5.1| + - Angle of Arrival (AoA)/Angle of Departure (AoD) + - |unsupported| + - |developing202412| + * - + - GATT Caching + - |experimental| + - |experimental| + * - + - Advertising Channel Index + - |NA| + - |NA| + * - + - Periodic Advertising Sync Transfer + - |supported| + - |supported| + * - .. centered:: |5.2| + - LE Isochronous Channels (BIS/CIS) + - |unsupported| + - |unsupported| + * - + - Enhanced Attribute Protocol + - |unsupported| + - |developing202412| + * - + - LE Power Control + - |unsupported| + - |supported| + * - .. centered:: |5.3| + - AdvDataInfo in Periodic Advertising + - |supported| + - |supported| + * - + - LE Enhanced Connection Update (Connection Subrating) + - |unsupported| + - |supported| + * - + - LE Channel Classification + - |supported| + - |supported| + * - .. centered:: |5.4| + - Advertising Coding Selection + - |unsupported| + - |supported| + * - + - Encrypted Advertising Data + - |unsupported| + - |experimental| + * - + - LE GATT Security Levels Characteristic + - |unsupported| + - |developing202412| + * - + - Periodic Advertising with Responses + - |unsupported| + - |developing202412| + +.. [1] + 如果想了解支持功能的 Bluetooth SIG 认证状态, + 请查阅 `SIG 蓝牙产品数据库 `__ 。 + +请注意,本文档不构成对客户的约束性承诺。 +以上所列出来的功能支持状态信息仅供参考,可能会在不通知的情况下发生更改。 +建议联系 `乐鑫客户支持团队 `__ 以获取最新信息,并确认功能是否适合你的特定需求。 + + +.. |supported| image:: ../../../_static/ble/feature_status/supported.svg + :class: align-center +.. |developing202412| image:: ../../../_static/ble/feature_status/developing202412.svg + :class: align-center +.. |unsupported| image:: ../../../_static/ble/feature_status/unsupported.svg + :class: align-center +.. |experimental| image:: ../../../_static/ble/feature_status/experimental.svg + :class: align-center +.. |NA| image:: ../../../_static/ble/feature_status/NA.svg + :class: align-center +.. |supported_def| image:: ../../../_static/ble/feature_status/supported.svg +.. |developing_def| image:: ../../../_static/ble/feature_status/developingYYYYMM.svg +.. |unsupported_def| image:: ../../../_static/ble/feature_status/unsupported.svg +.. |experimental_def| image:: ../../../_static/ble/feature_status/experimental.svg +.. |NA_def| image:: ../../../_static/ble/feature_status/NA.svg +.. |4.2| replace:: `4.2 `__ +.. |5.0| replace:: `5.0 `__ +.. |5.1| replace:: `5.1 `__ +.. |5.2| replace:: `5.2 `__ +.. |5.3| replace:: `5.3 `__ +.. |5.4| replace:: `5.4 `__ diff --git a/docs/zh_CN/api-guides/ble/index.rst b/docs/zh_CN/api-guides/ble/index.rst new file mode 100644 index 000000000000..f3c9def1519b --- /dev/null +++ b/docs/zh_CN/api-guides/ble/index.rst @@ -0,0 +1,24 @@ +################ +低功耗蓝牙® +################ + +:link_to_translation:`en:[English]` + +***** +概览 +***** +.. toctree:: + :maxdepth: 1 + + overview + ble-feature-support-status + +********** +蓝牙规范 +********** + +.. toctree:: + :maxdepth: 2 + + :SOC_BLE_MESH_SUPPORTED: ../esp-ble-mesh/ble-mesh-index + :SOC_BLUFI_SUPPORTED: blufi diff --git a/docs/zh_CN/api-guides/ble/overview.rst b/docs/zh_CN/api-guides/ble/overview.rst new file mode 100644 index 000000000000..62dbc36db09f --- /dev/null +++ b/docs/zh_CN/api-guides/ble/overview.rst @@ -0,0 +1,203 @@ +介绍 +======= + +:link_to_translation:`en:[English]` + +此文档概述了 ESP-IDF 中低功耗蓝牙协议栈的架构,并提供了一些相关文档和应用示例的快速链接。 + +.. only:: esp32 + + {IDF_TARGET_NAME} 支持双模蓝牙 4.2,并且已经获得双模蓝牙 4.2 认证和蓝牙 LE 5.0 认证 + +.. only:: esp32c3 or esp32s3 + + {IDF_TARGET_NAME} 支持蓝牙 5.0 (LE),并且已经获得蓝牙 LE 5.4 认证。 + +.. only:: esp32c2 or esp32c6 or esp32h2 + + {IDF_TARGET_NAME} 支持蓝牙 5.0 (LE),并且已经获得蓝牙 LE 5.3 认证。 + +ESP-IDF 中的低功耗蓝牙协议栈是一个分层架构,可在 {IDF_TARGET_NAME} 系列芯片上实现低功耗蓝牙功能,详见下。 + +.. only:: esp32 or esp32s3 or esp32c3 or esp32c6 + + .. figure:: ../../../_static/bluetooth-architecture.png + :align: center + :scale: 90% + :alt: {IDF_TARGET_NAME} 蓝牙协议栈架构 + + {IDF_TARGET_NAME} 蓝牙协议栈架构 + +.. only:: esp32c2 + + .. figure:: ../../../_static/bluetooth-architecture-no-ble-mesh.png + :align: center + :scale: 90% + :alt: {IDF_TARGET_NAME} 蓝牙协议栈架构 + + {IDF_TARGET_NAME} 蓝牙协议栈架构 + +.. only:: esp32h2 + + .. figure:: ../../../_static/bluetooth-architecture-no-blufi.png + :align: center + :scale: 90% + :alt: {IDF_TARGET_NAME} 蓝牙协议栈架构 + + {IDF_TARGET_NAME} 蓝牙协议栈架构 + +参考下表可知特定芯片是否支持低功耗蓝牙模块。 + +.. list-table:: + :width: 100% + :widths: auto + :header-rows: 1 + + * - 芯片系列 + - 控制器 + - ESP-Bluedroid + - ESP-NimBLE + - ESP-BLE-MESH + - BluFi + * - ESP32 + - Y + - Y + - Y + - Y + - Y + * - ESP32-S2 + - \– + - \– + - \– + - \– + - \– + * - ESP32-S3 + - Y + - Y + - Y + - Y + - Y + * - ESP32-C2 + - Y + - Y + - Y + - \– + - Y + * - ESP32-C3 + - Y + - Y + - Y + - Y + - Y + * - ESP32-C6 + - Y + - Y + - Y + - Y + - Y + * - ESP32-H2 + - Y + - Y + - Y + - Y + - \– + +以下各节简要介绍了每个层,并提供了相关文档和应用示例的快速链接。 + + +ESP 蓝牙控制器 +-------------- + +底层为 ESP 蓝牙控制器,包含 PHY、基带、链路控制器、链路管理器、设备管理器和 HCI 等各种模块。该层管理硬件接口和链路,以库的形式提供功能,并通过 API 访问,且直接与硬件和低级别蓝牙协议交互。 + +- :doc:`API 参考 <../../api-reference/bluetooth/controller_vhci>` +- :example:`应用示例 ` + + +ESP 蓝牙主机 +------------- + +有 ESP-Bluedroid 和 ESP-NimBLE 两个主机,其主要区别如下: + +- 虽然两者都支持低功耗蓝牙,但 ESP-NimBLE 需要的堆和 flash 空间更少。 + +.. only:: esp32 + + - ESP-Bluedroid 支持经典蓝牙和低功耗蓝牙,而 ESP-NimBLE 仅支持低功耗蓝牙。 + + +ESP-Bluedroid +^^^^^^^^^^^^^ + +ESP-Bluedroid 是原生 Android 蓝牙协议栈 Bluedroid 的修改版,由两层组成:蓝牙上层 (BTU) 和蓝牙传输控制器层 (BTC)。BTU 层负责处理 L2CAP、GATT/ATT、SMP、GAP 等底层蓝牙协议以及其他配置文件,提供以 "bta" 为前缀的接口。BTC 层主要负责向应用层提供以 "esp" 为前缀的支持接口,并处理基于 GATT 的配置文件以及其他任务。所有的 API 都位于 ESP_API 层,开发者应使用以 "esp" 为前缀的低功耗蓝牙 API。 + +.. only:: esp32 + + {IDF_TARGET_NAME} 的 ESP-Bluedroid 支持经典蓝牙和低功耗蓝牙。 + +.. only:: not esp32 + + {IDF_TARGET_NAME} 的 ESP-Bluedroid 仅支持低功耗蓝牙,不支持经典蓝牙。 + +- API 参考 + + - :doc:`../../api-reference/bluetooth/bt_common` + - :doc:`低功耗蓝牙 <../../api-reference/bluetooth/bt_le>` + +.. only:: esp32 + + - :example:`低功耗蓝牙 4.2 应用程序示例 ` + +.. only:: not esp32 + + - :example:`低功耗蓝牙 4.2 应用程序示例 ` + - :example:`低功耗蓝牙 5.0 应用程序示例 ` + +ESP-NimBLE +^^^^^^^^^^ + +ESP-NimBLE 是建立在 Apache Mynewt 开发的 NimBLE 主机协议栈之上的主机协议栈,已经为 {IDF_TARGET_NAME} 系列芯片和 FreeRTOS 进行了移植。通过维持现有 NimBLE API,并添加一个单独的 ESP-NimBLE API 进行初始化,使端口层保持简洁,也便于开发者操作。 + +ESP-NimBLE 仅支持低功耗蓝牙,不支持经典蓝牙。 + +- `Apache Mynewt NimBLE 用户指南 `__ +- API 参考 + + - `NimBLE API 参考 `__ + - :doc:`ESP-NimBLE 初始化 API 参考 initialization <../../api-reference/bluetooth/nimble/index>` + +- :example:`应用程序示例 ` + + +蓝牙规范 +-------- + +主机协议层之上是 Espressif 的蓝牙规范和一些常见的蓝牙规范。根据具体配置,这些规范可以在 ESP-Bluedroid 或 ESP-NimBLE 上运行。 + + +.. only:: SOC_BLE_MESH_SUPPORTED + + ESP-BLE-MESH + ^^^^^^^^^^^^ + + ESP-BLE-MESH 基于 Zephyr 蓝牙 Mesh 协议栈,其实现支持设备配网和节点控制,还支持代理、中继、低功耗和朋友等节点功能。 + + - :doc:`ESP-BLE-MESH 文档 <../esp-ble-mesh/ble-mesh-index>`:功能列表、快速入门、架构、应用示例描述、常见问题等。 + - :example:`应用示例 ` + + +.. only:: SOC_BLUFI_SUPPORTED + + BluFi + ^^^^^ + + {IDF_TARGET_NAME} 的 BluFi 是通过蓝牙信道进行的 Wi-Fi 网络配置功能。BluFi 提供了将 Wi-Fi 配置和凭据传递给 {IDF_TARGET_NAME} 的安全协议,从而使 {IDF_TARGET_NAME} 连接到 AP 或搭建软 AP。 + + - :doc:`BluFi 文档 ` + - :example:`应用示例 ` + + +应用 +---- + +最上层是应用层。利用上述 API 和蓝牙规范,可以在 ESP-Bluedroid 和 ESP-NimBLE 协议栈之上创建特定用例的低功耗蓝牙应用程序。 diff --git a/docs/zh_CN/api-guides/bluetooth.rst b/docs/zh_CN/api-guides/bluetooth.rst deleted file mode 100644 index 78caa506036c..000000000000 --- a/docs/zh_CN/api-guides/bluetooth.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../en/api-guides/bluetooth.rst diff --git a/docs/zh_CN/api-guides/classic-bt/index.rst b/docs/zh_CN/api-guides/classic-bt/index.rst new file mode 100644 index 000000000000..57aba1ca5dc7 --- /dev/null +++ b/docs/zh_CN/api-guides/classic-bt/index.rst @@ -0,0 +1,13 @@ +########### +经典蓝牙® +########### + +:link_to_translation:`en:[English]` + +***** +概览 +***** +.. toctree:: + :maxdepth: 2 + + overview diff --git a/docs/zh_CN/api-guides/classic-bt/overview.rst b/docs/zh_CN/api-guides/classic-bt/overview.rst new file mode 100644 index 000000000000..53a1e3eac3d8 --- /dev/null +++ b/docs/zh_CN/api-guides/classic-bt/overview.rst @@ -0,0 +1,80 @@ +介绍 +======= + +:link_to_translation:`en:[English]` + +此文档概述了 ESP-IDF 中经典蓝牙协议栈的架构,并提供了一些相关文档和应用示例的快速链接。 + +.. only:: esp32 + + {IDF_TARGET_NAME} 支持双模蓝牙 4.2,并且已经获得双模蓝牙 4.2 认证。 + +ESP-IDF 中的经典蓝牙协议栈是一个分层架构,可在 {IDF_TARGET_NAME} 系列芯片上实现经典蓝牙功能,详见下。 + +.. only:: esp32 + + .. figure:: ../../../_static/classic-bluetooth-architecture.png + :align: center + :scale: 90% + :alt: {IDF_TARGET_NAME} 经典蓝牙协议栈架构 + + {IDF_TARGET_NAME} 经典蓝牙协议栈架构 + +参考下表可知特定芯片是否支持经典蓝牙控制器。 + +.. list-table:: + :width: 100% + :widths: auto + :header-rows: 1 + + * - 芯片系列 + - 控制器 + * - ESP32 + - Y + * - ESP32-S2 + - \– + * - ESP32-S3 + - \– + * - ESP32-C2 + - \- + * - ESP32-C3 + - \- + * - ESP32-C6 + - \- + * - ESP32-H2 + - \- + +以下各节简要介绍了每个层,并提供了相关文档和应用示例的快速链接。 + + +ESP 蓝牙控制器 +-------------- + +底层为 ESP 蓝牙控制器,包含 PHY、基带、链路控制器、链路管理器、设备管理器和 HCI 等各种模块。该层管理硬件接口和链路,以库的形式提供功能,并通过 API 访问,且直接与硬件和低级别蓝牙协议交互。 + +- :doc:`API 参考 <../../api-reference/bluetooth/controller_vhci>` +- :example:`应用示例 ` + + +ESP 蓝牙主机 +------------- + +IDF 中的ESP-Bluedroid 主机支持经典蓝牙。 + + +ESP-Bluedroid +^^^^^^^^^^^^^ + +ESP-Bluedroid 是原生 Android 蓝牙协议栈 Bluedroid 的修改版,由两层组成:蓝牙上层 (BTU) 和蓝牙传输控制器层 (BTC)。BTU 层负责处理 L2CAP 等底层蓝牙协议以及其他配置文件,提供以 "bta" 为前缀的接口。BTC 层主要负责向应用层提供以 "esp" 为前缀的支持接口,并处理其他任务。所有的 API 都位于 ESP_API 层,开发者应使用以 "esp" 为前缀的经典蓝牙 API。 + +- API 参考 + + - :doc:`../../api-reference/bluetooth/bt_common` + - :doc:`经典蓝牙 <../../api-reference/bluetooth/classic_bt>` +- :example:`应用程序示例 ` + + +应用 +---- + +最上层是应用层。利用上述 API 和蓝牙规范,可以在 ESP-Bluedroid 协议栈之上创建特定用例的经典蓝牙应用程序。 diff --git a/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-faq.rst b/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-faq.rst index 034c84a90243..e6764ff95593 100644 --- a/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-faq.rst +++ b/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-faq.rst @@ -532,7 +532,7 @@ ESP-BLE-MESH 常见问题手册 .. only:: esp32 - 未搭载 PSRAM 的 :doc:`ESP32-DevKitC <../../hw-reference/esp32/get-started-devkitc>` 开发板,Wi-Fi 和 ESP-BLE-MESH 共存可以正常运行,但是吞吐率较低。当 Wi-Fi 和 ESP-BLE-MESH 共存时,搭载 PSRAM 的 ESP32-DevKitC 速率可以稳定在 1 Mbps 以上。 + 未搭载 PSRAM 的 `ESP32-DevKitC `__ 开发板,Wi-Fi 和 ESP-BLE-MESH 共存可以正常运行,但是吞吐率较低。当 Wi-Fi 和 ESP-BLE-MESH 共存时,搭载 PSRAM 的 ESP32-DevKitC 速率可以稳定在 1 Mbps 以上。 应使能 menuconfig 中的一些配置来支持 PSRAM。 diff --git a/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-feature-list.rst b/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-feature-list.rst index 256cba2cc727..edac2c0b2c14 100644 --- a/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-feature-list.rst +++ b/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-feature-list.rst @@ -1 +1,153 @@ -.. include:: ../../../en/api-guides/esp-ble-mesh/ble-mesh-feature-list.rst +ESP-BLE-MESH 功能列表 +===================== + +:link_to_translation:`en:[English]` + +支持的功能 +---------- + +Mesh 核心 +""""""""" + +* 入网 + * PB-ADV,PB-GATT,PB-Remote + * OOB 验证 + * 基于证书的入网 + * 远程入网 + * 增强入网验证 + +* 网络 + * 中继 + * 分包和重组 + * 密钥更新程序 + * IV 更新程序 + * 朋友节点 + * 低功耗节点 + * 代理服务器 + * 代理客户端 + * 定向转发 + * 私有信标 + * 子网桥 + * 次要增强 + +* 多个客户端模型同时运行 + * 支持多个客户端模型同时向不同节点发送数据包 + * 客户端模型与服务器模型之间无阻塞 + +* NVS 存储 + * 存储 ESP-BLE-MESH 节点的入网和配置信息 + +Mesh 模型 +""""""""" + +* 基础模型 + * 配置服务器模型 + * 配置客户端模型 + * 健康服务器模型 + * 健康客户端模型 + * 远程供应服务器模型 + * 远程供应客户端模型 + * 定向转发配置服务器模型 + * 定向转发配置客户端模型 + * 桥接配置服务器模型 + * 桥接配置客户端模型 + * Mesh 专用信标服务器模型 + * Mesh 专用信标客户端模型 + * 按需提供的专用代理服务器模型 + * 按需提供的专用代理客户端模型 + * SAR 配置服务器模型 + * SAR 配置客户端模型 + * 请求 PDU RPL 配置服务器模型 + * 请求 PDU RPL 配置客户端模型 + * 操作码聚合器服务器模型 + * 操作码聚合器客户端模型 + * 大型合成数据服务器模型 + * 大型合成数据客户端模型 + +* 通用客户端模型 + * 通用开关客户端 + * 通用电平客户端 + * 通用默认过渡时间客户端 + * 通用电源开关客户端 + * 通用功率电平客户端 + * 通用电池客户端 + * 通用位置客户端 + * 通用属性客户端 + +* 传感器客户端模型 + * 传感器客户端 + +* 时间与场景客户端模型 + * 时间客户端 + * 场景客户端 + * 调度器客户端 + +* 照明客户端模型 + * 灯光亮度客户端 + * 灯光 CTL 客户端 + * 灯光 HSL 客户端 + * 灯光 xyL 客户端 + * 灯光 LC 客户端 + +* 通用服务器模型 + * 通用开关服务器 + * 通用电平服务器 + * 通用默认过渡时间服务器 + * 通用电源开关服务器 + * 通用电源开关设置服务器 + * 通用功率电平服务器 + * 通用功率电平设置服务器 + * 通用电池服务器 + * 通用位置服务器 + * 通用位置设置服务器 + * 通用用户属性服务器 + * 通用管理员属性服务器 + * 通用制造商属性服务器 + * 通用客户端属性服务器 + +* 传感器服务器模型 + * 传感器服务器 + * 传感器设置服务器 + +* 时间和场景服务器模型 + * 时间服务器 + * 时间设置服务器 + * 场景服务器 + * 场景设置服务器 + * 调度器服务器 + * 调度器设置服务器 + +* 照明服务器模型 + * 灯光亮度服务器 + * 灯光亮度设置服务器 + * 灯光 CTL 服务器 + * 灯光 CTL 温度服务器 + * 灯光 CTL 设置服务器 + * 灯光 HSL 服务器 + * 灯光 HSL 色调服务器 + * 灯光 HSL 饱和度服务器 + * 灯光 HSL 设置服务器 + * 灯光 xyL 服务器 + * 灯光 xyL 设置服务器 + * 灯光 LC 服务器 + * 灯光 LC 设置服务器 + +Mesh 示例 +""""""""""" + +* ESP-BLE-MESH 节点 + * :example_file:`教程 ` + * :example_file:`教程 ` + * :example:`示例 ` +* ESP-BLE-MESH 供应者 + * :example_file:`教程 ` + * :example:`示例 ` +* ESP-BLE-MESH 快速入网 + * :example_file:`客户端模型快速入网教程 ` + * :example_file:`服务器模型快速入网教程 ` + * :example:`示例 ` + * `演示视频 `__ +* ESP-BLE-MESH 及 Wi-Fi 共存 + * :example_file:`教程 ` + * :example:`示例 ` + * `演示视频 `__ diff --git a/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-index.rst b/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-index.rst index 274c0cd879f9..b0b76717825c 100644 --- a/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-index.rst +++ b/docs/zh_CN/api-guides/esp-ble-mesh/ble-mesh-index.rst @@ -25,8 +25,8 @@ ESP-BLE-MESH 的实现和认证基于最新的 `Mesh Profile v1.0.1 ` - 展示了将 ESP-BLE-MESH 作为拥有 Configuration Server model 和 Generic OnOff Server model 的节点设备的用法。然后,ESP-BLE-MESH Provisioner 可以配网设备,控制表示开/关状态的 RGB 灯,示例请见 :example:`example code `。 @@ -230,15 +230,15 @@ ESP-BLE-MESH 示例 .. _esp-ble-mesh-demo-videos: -ESP-BLE-MESH 演示视频 -====================== +演示视频 +======== * `Espressif Fast Provisioning using ESP-BLE-MESH App `_ * `Espressif ESP-BLE-MESH and Wi-Fi Coexistence `_ -ESP-BLE-MESH 常见问题手册 -========================= +常见问题手册 +============= * :ref:`ble-mesh-faq-provisioner-development` * :ref:`ble-mesh-faq-node-development` diff --git a/docs/zh_CN/api-guides/external-ram.rst b/docs/zh_CN/api-guides/external-ram.rst index 864623b31162..099b9c41ab82 100644 --- a/docs/zh_CN/api-guides/external-ram.rst +++ b/docs/zh_CN/api-guides/external-ram.rst @@ -123,16 +123,14 @@ ESP-IDF 启动过程中,片外 RAM 被映射到数据虚拟地址空间,该 剩余的片外 RAM 也可以通过上述方法添加到堆分配器中。 -.. only:: esp32 - - .. _external_ram_config_noinit: +.. _external_ram_config_noinit: - 允许 .noinit 段放入片外存储器 - ------------------------------------- +允许 .noinit 段放入片外存储器 +------------------------------------- - 通过勾选 :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY` 启用该选项。启用该选项后,PSRAM 被映射到的数据虚拟地址空间将用于存储未初始化的数据。即使在启动或重新启动期间,放置在该段中的值也不会被初始化或修改。 +通过勾选 :ref:`CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY` 启用该选项。启用该选项后,PSRAM 被映射到的数据虚拟地址空间将用于存储未初始化的数据。即使在启动或重新启动期间,放置在该段中的值也不会被初始化或修改。 - 通过应用 ``EXT_RAM_NOINIT_ATTR`` 宏,可以将数据从内部 NOINIT 段移到片外 RAM。剩余的片外 RAM 也可以通过上述方法添加到堆分配器中,具体请参考 :ref:`external_ram_config_capability_allocator`。 +通过应用 ``EXT_RAM_NOINIT_ATTR`` 宏,可以将数据从内部 NOINIT 段移到片外 RAM。剩余的片外 RAM 也可以通过上述方法添加到堆分配器中,具体请参考 :ref:`external_ram_config_capability_allocator`。 .. only:: SOC_SPIRAM_XIP_SUPPORTED diff --git a/docs/zh_CN/api-guides/index.rst b/docs/zh_CN/api-guides/index.rst index 828316b5023f..74c45ffb62b1 100644 --- a/docs/zh_CN/api-guides/index.rst +++ b/docs/zh_CN/api-guides/index.rst @@ -7,8 +7,9 @@ API 指南 app_trace startup - :SOC_BLUFI_SUPPORTED: blufi - :SOC_BT_SUPPORTED: bluetooth + :SOC_BT_CLASSIC_SUPPORTED: classic-bt/index + :SOC_BLE_SUPPORTED: ble/index + :SOC_BLE_MESH_SUPPORTED: esp-ble-mesh/ble-mesh-index bootloader build-system :SOC_SUPPORT_COEXISTENCE: coexist @@ -16,10 +17,9 @@ API 指南 cplusplus core_dump current-consumption-measurement-modules - :SOC_RTC_MEM_SUPPORTED: deep-sleep-stub + :ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB: deep-sleep-stub :SOC_USB_OTG_SUPPORTED and not esp32p4: dfu error-handling - :SOC_BLE_MESH_SUPPORTED: esp-ble-mesh/ble-mesh-index :SOC_WIFI_MESH_SUPPORT: esp-wifi-mesh :SOC_SPIRAM_SUPPORTED: external-ram fatal-errors diff --git a/docs/zh_CN/api-guides/jtag-debugging/esp32.inc b/docs/zh_CN/api-guides/jtag-debugging/esp32.inc index afb1c697f22b..b37cdf585931 100644 --- a/docs/zh_CN/api-guides/jtag-debugging/esp32.inc +++ b/docs/zh_CN/api-guides/jtag-debugging/esp32.inc @@ -165,12 +165,12 @@ .. devkit-defs .. |devkit-name| replace:: ESP-WROVER-KIT -.. |devkit-name-with-link| replace:: :doc:`ESP-WROVER-KIT 开发板 <../../hw-reference/index>` +.. |devkit-name-with-link| replace:: `ESP-WROVER-KIT 开发板 `__ --- .. devkit-hw-config -* 根据 :doc:`../../hw-reference/esp32/get-started-wrover-kit` 文档中 :ref:`get-started-esp-wrover-kit-v4.1-setup-options` 章节所描述的信息,设置 JP8 便可以启用 JTAG 功能。 +* 根据 `ESP-WROVER-KIT 开发板 `__ 文档中所描述的信息,设置 JP2 便可以启用 JTAG 功能。 --- diff --git a/docs/zh_CN/api-guides/linker-script-generation.rst b/docs/zh_CN/api-guides/linker-script-generation.rst index 9fb2469897ed..063327605bb9 100644 --- a/docs/zh_CN/api-guides/linker-script-generation.rst +++ b/docs/zh_CN/api-guides/linker-script-generation.rst @@ -14,7 +14,7 @@ * 将关键代码存放到 RAM 中以提高性能; * 将可执行代码存放到 IRAM 中,以便在缓存被禁用时运行这些代码; - :SOC_RTC_MEM_SUPPORTED: * 将代码存放到 RTC 存储器中,以便在 wake stub 中使用; + :ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB: * 将代码存放到 RTC 存储器中,以便在 wake stub 中使用; :SOC_ULP_SUPPORTED: * 将代码存放到 RTC 内存中,以便 ULP 协处理器使用。 链接器脚本生成机制可以让用户指定代码和数据在 ESP-IDF 组件中的存放区域。组件包含如何存放符号、目标或完整库的信息。在构建应用程序时,组件中的这些信息会被收集、解析并处理;生成的存放规则用于链接应用程序。 diff --git a/docs/zh_CN/api-guides/memory-types.rst b/docs/zh_CN/api-guides/memory-types.rst index 075417e5535c..f1343703cba7 100644 --- a/docs/zh_CN/api-guides/memory-types.rst +++ b/docs/zh_CN/api-guides/memory-types.rst @@ -150,7 +150,9 @@ DROM(数据存储在 flash 中) RTC Slow memory(RTC 慢速存储器) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 从 RTC 存储器运行的代码中使用的全局和静态变量必须放入 RTC Slow memory 中。例如 :doc:`深度睡眠 ` 变量可以放在 RTC Slow memory 中,而不是 RTC FAST memory,或者也可以放入由 :doc:`/api-reference/system/ulp` 访问的代码和变量。 + .. only:: ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB + + 从 RTC 存储器运行的代码中使用的全局和静态变量必须放入 RTC Slow memory 中。例如 :doc:`深度睡眠 ` 变量可以放在 RTC Slow memory 中,而不是 RTC FAST memory,或者也可以放入由 :doc:`/api-reference/system/ulp` 访问的代码和变量。 ``RTC_NOINIT_ATTR`` 属性宏可以用来将数据放入 RTC Slow memory。放入此类型存储器的值从深度睡眠模式中醒来后会保持值不变。 @@ -170,8 +172,9 @@ DROM(数据存储在 flash 中) 对于 {IDF_TARGET_NAME},RTC 存储器已被重新重命名为 LP(低功耗)存储器。在与 {IDF_TARGET_NAME} 相关的 IDF 代码、文档以及技术参考手册中,可能会出现这两个术语混用的情况。 + .. only:: ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB - RTC FAST memory 的同一区域既可以作为指令存储器也可以作为数据存储器进行访问。从深度睡眠模式唤醒后必须要运行的代码要放在 RTC 存储器中,更多信息请查阅文档 :doc:`深度睡眠 `。 + RTC FAST memory 的同一区域既可以作为指令存储器也可以作为数据存储器进行访问。从深度睡眠模式唤醒后必须要运行的代码要放在 RTC 存储器中,更多信息请查阅文档 :doc:`深度睡眠 `。 .. only:: esp32 diff --git a/docs/zh_CN/api-guides/performance/size.rst b/docs/zh_CN/api-guides/performance/size.rst index 86eec89b68a2..f690589f54ae 100644 --- a/docs/zh_CN/api-guides/performance/size.rst +++ b/docs/zh_CN/api-guides/performance/size.rst @@ -18,10 +18,6 @@ ESP-IDF 构建系统会编译项目和 ESP-IDF 中所有源文件,但只有程 使用 :ref:`idf.py` 的子命令 ``size``, ``size-components`` 和 ``size-files`` 可以输出项目使用内存概况: -.. note:: - - 添加 ``-DOUTPUT_FORMAT=csv`` 或 ``-DOUTPUT_FORMAT=json``,即可用 CSV 或 JSON 格式输出文件。 - 数据大小概况 ``idf.py size`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/zh_CN/api-guides/startup.rst b/docs/zh_CN/api-guides/startup.rst index db82ddc7d976..4a49e8f712d1 100644 --- a/docs/zh_CN/api-guides/startup.rst +++ b/docs/zh_CN/api-guides/startup.rst @@ -32,7 +32,7 @@ .. list:: - :SOC_RTC_MEM_SUPPORTED: #. 从深度睡眠模式复位:如果 ``RTC_CNTL_STORE6_REG`` 寄存器的值非零,且 ``RTC_CNTL_STORE7_REG`` 寄存器中的 RTC 内存的 CRC 校验值有效,那么程序会使用 ``RTC_CNTL_STORE6_REG`` 寄存器的值作为入口地址,并立即跳转到该地址运行。如果 ``RTC_CNTL_STORE6_REG`` 的值为零,或 ``RTC_CNTL_STORE7_REG`` 中的 CRC 校验值无效,又或通过 ``RTC_CNTL_STORE6_REG`` 调用的代码返回,那么则像上电复位一样继续启动。 **注意**:如果想在这里运行自定义的代码,可以参考 :doc:`深度睡眠 ` 文档里面介绍的深度睡眠存根机制方法。 + :ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB: #. 从深度睡眠模式复位:如果 ``RTC_CNTL_STORE6_REG`` 寄存器的值非零,且 ``RTC_CNTL_STORE7_REG`` 寄存器中的 RTC 内存的 CRC 校验值有效,那么程序会使用 ``RTC_CNTL_STORE6_REG`` 寄存器的值作为入口地址,并立即跳转到该地址运行。如果 ``RTC_CNTL_STORE6_REG`` 的值为零,或 ``RTC_CNTL_STORE7_REG`` 中的 CRC 校验值无效,又或通过 ``RTC_CNTL_STORE6_REG`` 调用的代码返回,那么则像上电复位一样继续启动。 **注意**:如果想在这里运行自定义的代码,可以参考 :doc:`深度睡眠 ` 文档里面介绍的深度睡眠存根机制方法。 #. 上电复位、软件 SoC 复位、看门狗 SoC 复位:检查 ``GPIO_STRAP_REG`` 寄存器,判断是否请求自定义启动模式,如 UART 下载模式。如果是,ROM 会执行此自定义加载模式,否则会像软件 CPU 复位一样继续启动。请参考 {IDF_TARGET_NAME} 技术规格书了解 SoC 启动模式以及具体执行过程。 diff --git a/docs/zh_CN/api-reference/network/esp_eth.rst b/docs/zh_CN/api-reference/network/esp_eth.rst index 1ed9aca6a73a..bec57f9f3351 100644 --- a/docs/zh_CN/api-reference/network/esp_eth.rst +++ b/docs/zh_CN/api-reference/network/esp_eth.rst @@ -191,7 +191,7 @@ .. only:: not SOC_EMAC_USE_MULTI_IO_MUX .. note:: - 数据平面中使用的信号通过 IO_MUX 连接至特定的 GPIO,这些信号无法配置到其他 GPIO 上。控制平面中使用的信号可以通过矩阵路由到任何空闲的 GPIO 上。相关硬件设计示例,请参阅 :doc:`ESP32-Ethernet-Kit <../../hw-reference/esp32/get-started-ethernet-kit>`。 + 数据平面中使用的信号通过 IO_MUX 连接至特定的 GPIO,这些信号无法配置到其他 GPIO 上。控制平面中使用的信号可以通过矩阵路由到任何空闲的 GPIO 上。相关硬件设计示例,请参阅 `ESP32-Ethernet-Kit `_。 .. only:: SOC_EMAC_USE_MULTI_IO_MUX diff --git a/docs/zh_CN/api-reference/peripherals/adc_oneshot.rst b/docs/zh_CN/api-reference/peripherals/adc_oneshot.rst index 7c8687b480e2..95caf1c869b6 100644 --- a/docs/zh_CN/api-reference/peripherals/adc_oneshot.rst +++ b/docs/zh_CN/api-reference/peripherals/adc_oneshot.rst @@ -142,7 +142,7 @@ ADC 单次转换模式驱动基于 {IDF_TARGET_NAME} SAR ADC 模块实现,不 * - Vmax - 可测量的最大模拟输入电压,与 ADC 衰减相关,请参考 `技术参考手册 <{IDF_TARGET_TRM_CN_URL}>`__ > ``片上传感器与模拟信号处理``。 * - Dmax - - 输出 ADC 原始数字读取结果的最大值,即 2^位宽,位宽即之前配置的 :cpp:member:`adc_digi_pattern_config_t::bit_width`。 + - 输出 ADC 原始数字读取结果的最大值,即 2^位宽,位宽即之前配置的 :cpp:member:`adc_oneshot_chan_cfg_t::bitwidth`。 若需进一步校准,将 ADC 原始结果转换为以 mV 为单位的电压数据,请参考校准文档 :doc:`adc_calibration`。 diff --git a/docs/zh_CN/api-reference/peripherals/gptimer.rst b/docs/zh_CN/api-reference/peripherals/gptimer.rst index ecf9cf4cb49f..3f6b0e6a83a2 100644 --- a/docs/zh_CN/api-reference/peripherals/gptimer.rst +++ b/docs/zh_CN/api-reference/peripherals/gptimer.rst @@ -42,15 +42,12 @@ 要安装一个定时器实例,需要提前提供配置结构体 :cpp:type:`gptimer_config_t`: -- :cpp:member:`gptimer_config_t::clk_src` 选择定时器的时钟源。:cpp:type:`gptimer_clock_source_t` 中列出多个可用时钟,仅可选择其中一个时钟。了解不同时钟源对功耗的影响,请查看章节 :ref:`gptimer-power-management`。 - -- :cpp:member:`gptimer_config_t::direction` 设置定时器的计数方向,:cpp:type:`gptimer_count_direction_t` 中列出多个支持的方向,仅可选择其中一个方向。 - -- :cpp:member:`gptimer_config_t::resolution_hz` 设置内部计数器的分辨率。计数器每滴答一次相当于 **1 / resolution_hz** 秒。 - -- :cpp:member:`gptimer_config::intr_priority` 设置中断的优先级。如果设置为 ``0``,则会分配一个默认优先级的中断,否则会使用指定的优先级。 - -- 选用 :cpp:member:`gptimer_config_t::intr_shared` 设置是否将定时器中断源标记为共享源。了解共享中断的优缺点,请参考 :doc:`Interrupt Handling <../../api-reference/system/intr_alloc>`。 +- :cpp:member:`gptimer_config_t::clk_src` 选择定时器的时钟源。:cpp:type:`gptimer_clock_source_t` 中列出多个可用时钟,仅可选择其中一个时钟。了解不同时钟源对功耗的影响,请查看章节 :ref:`gptimer-power-management`。 +- :cpp:member:`gptimer_config_t::direction` 设置定时器的计数方向,:cpp:type:`gptimer_count_direction_t` 中列出多个支持的方向,仅可选择其中一个方向。 +- :cpp:member:`gptimer_config_t::resolution_hz` 设置内部计数器的分辨率。计数器每滴答一次相当于 **1 / resolution_hz** 秒。 +- :cpp:member:`gptimer_config::intr_priority` 设置中断的优先级。如果设置为 ``0``,则会分配一个默认优先级的中断,否则会使用指定的优先级。 +- :cpp:member:`gptimer_config::backup_before_sleep` 用于使能在进入睡眠模式前备份 GPTimer 寄存器。这个选项需要用户在功耗和内存使用之间取得平衡。如果功耗不是一个问题,可以禁用这个选项来节省内存。但如果想要节省功耗,应该使能这个选项,在进入睡眠模式前备份 GPTimer 寄存器,并在唤醒后恢复它们。这个功能依赖于特定的硬件模块,如果你在不支持的芯片上启用它,你会得到一个错误信息,如 ``register back up is not supported``。 +- 可选地, :cpp:member:`gptimer_config_t::intr_shared` 设置是否将定时器中断源标记为共享源。了解共享中断的优缺点,请参考 :doc:`Interrupt Handling <../../api-reference/system/intr_alloc>`。 完成上述结构配置之后,可以将结构传递给 :cpp:func:`gptimer_new_timer`,用以实例化定时器实例并返回定时器句柄。 @@ -261,7 +258,7 @@ }; ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue)); ESP_ERROR_CHECK(gptimer_enable(gptimer)); - ESP_ERROR_CHECK(gptimer_start(gptimer, &alarm_config)); + ESP_ERROR_CHECK(gptimer_start(gptimer)); .. only:: SOC_ETM_SUPPORTED and SOC_TIMER_SUPPORT_ETM @@ -284,9 +281,13 @@ 电源管理 ^^^^^^^^ -有些电源管理的策略会在某些时刻关闭时钟源,或者改变时钟源的频率,以求降低功耗。比如在启用 DFS 后,APB 时钟源会降低频率。如果浅睡眠 (Light-sleep) 模式也被开启,PLL 和 XTAL 时钟都会被默认关闭,从而导致 GPTimer 的计时不准确。 +当电源管理 :ref:`CONFIG_PM_ENABLE` 被启用的时候,系统在进入睡眠前可能会调整或禁用时钟源。结果导致 GPTimer 的计时不准确。 + +驱动程序可以通过创建一个电源管理锁来防止上述问题。锁的类型会根据不同的时钟源来设置。驱动程序将在 :cpp:func:`gptimer_enable` 中拿锁,并在 :cpp:func:`gptimer_disable` 中释放锁。这意味着,在这两个函数之间,定时器可以正确工作,因为此时时钟源不会被禁用或改变频率。 + +.. only:: SOC_TIMER_SUPPORT_SLEEP_RETENTION -驱动程序会根据具体的时钟源选择,通过创建不同的电源锁来避免上述情况的发生。驱动会在 :cpp:func:`gptimer_enable` 函数中增加电源锁的引用计数,并在 :cpp:func:`gptimer_disable` 函数中减少电源锁的引用计数,从而保证了在 :cpp:func:`gptimer_enable` 和 :cpp:func:`gptimer_disable` 之间,GPTimer 的时钟源始处于稳定工作的状态。 + 除了时钟源的潜在变化外,当启用电源管理时,系统还可以关闭 GPTimer 寄存器所在的电源域。为确保 GPTimer 驱动程序在睡眠后继续工作,用户要么选择将 GPTimer 相关的寄存器备份到 RAM 中,要么拒绝关闭电源域。你可以根据应用需求在 :cpp:member:`gptimer_config_t::backup_before_sleep` 中设置是否需要启用寄存器备份,在功耗和内存使用之间做权衡。 .. _gptimer-iram-safe: diff --git a/docs/zh_CN/api-reference/peripherals/mcpwm.rst b/docs/zh_CN/api-reference/peripherals/mcpwm.rst index 536f32631fdb..87958168b289 100644 --- a/docs/zh_CN/api-reference/peripherals/mcpwm.rst +++ b/docs/zh_CN/api-reference/peripherals/mcpwm.rst @@ -204,11 +204,11 @@ MCPWM 组有一个专用定时器,用于捕获特定事件发生时的时间 - :cpp:member:`mcpwm_capture_channel_config_t::intr_priority` 设置中断的优先级。如果设置为 ``0``,则会分配一个默认优先级的中断,否则会使用指定的优先级。 - :cpp:member:`mcpwm_capture_channel_config_t::gpio_num` 设置捕获通道使用的 GPIO 编号。 - :cpp:member:`mcpwm_capture_channel_config_t::prescale` 设置输入信号的预分频器。 -- :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::pos_edge` 和 :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::neg_edge` 设置是否在输入信号的上升沿和/或下降沿捕获时间戳。 -- :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::pull_up` 和 :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::pull_down` 设置是否在内部拉高和/或拉低 GPIO。 -- :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::invert_cap_signal` 设置是否取反捕获信号。 -- :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::io_loop_back` 设置是否启用回环模式。该模式仅用于调试,使用 GPIO 交换矩阵外设同时启用 GPIO 输入和输出。 -- :cpp:member:`mcpwm_capture_channel_config_t::extra_flags::keep_io_conf_at_exit` 设置是否在删除通道时保留 GPIO 的相关配置。 +- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pos_edge` 和 :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::neg_edge` 设置是否在输入信号的上升沿和/或下降沿捕获时间戳。 +- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_up` 和 :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_down` 设置是否在内部拉高和/或拉低 GPIO。 +- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::invert_cap_signal` 设置是否取反捕获信号。 +- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::io_loop_back` 设置是否启用回环模式。该模式仅用于调试,使用 GPIO 交换矩阵外设同时启用 GPIO 输入和输出。 +- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::keep_io_conf_at_exit` 设置是否在删除通道时保留 GPIO 的相关配置。 分配成功后,:cpp:func:`mcpwm_new_capture_channel` 将返回一个指向已分配捕获通道的指针。否则,函数将返回错误代码。具体来说,当捕获定时器中没有空闲捕获通道时,将返回 :c:macro:`ESP_ERR_NOT_FOUND` 错误。 diff --git a/docs/zh_CN/api-reference/peripherals/rmt.rst b/docs/zh_CN/api-reference/peripherals/rmt.rst index 826a35f7b41e..81aa8f7c8ade 100644 --- a/docs/zh_CN/api-reference/peripherals/rmt.rst +++ b/docs/zh_CN/api-reference/peripherals/rmt.rst @@ -219,7 +219,7 @@ RMT 发射器可以生成载波信号,并将其调制到消息信号上。载 - :cpp:member:`rmt_rx_done_event_data_t::received_symbols` 指向接收到的 RMT 符号,这些符号存储在 :cpp:func:`rmt_receive` 函数的 ``buffer`` 参数中,在回调函数返回前不应释放此接收缓冲区。如果你还启用了部分接收的功能,则这个用户缓冲区会被用作“二级缓冲区”,其中的内容可以被随后传入的数据覆盖。在这种情况下,如果你想要保存或者稍后处理一些数据,则需要将接收到的数据复制到其他位置。 - :cpp:member:`rmt_rx_done_event_data_t::num_symbols` 表示接收到的 RMT 符号数量,该值不会超过 :cpp:func:`rmt_receive` 函数的 ``buffer_size`` 参数。如果 ``buffer_size`` 不足以容纳所有接收到的 RMT 符号,驱动程序将只保存缓冲区能够容纳的最大数量的符号,并丢弃或忽略多余的符号。 -- :cpp:member:`rmt_rx_done_event_data_t::is_last` 指示收到的数据包是否是当前的接收任务中的最后一个。这个标志在你使能 :cpp:member:`rmt_receive_config_t::extra_flags::en_partial_rx` 部分接收功能时非常有用。 +- :cpp:member:`rmt_rx_done_event_data_t::is_last` 指示收到的数据包是否是当前的接收任务中的最后一个。这个标志在你使能 :cpp:member:`rmt_receive_config_t::extra_rmt_receive_flags::en_partial_rx` 部分接收功能时非常有用。 .. _rmt-enable-and-disable-channel: @@ -331,7 +331,7 @@ RMT 是一种特殊的通信外设,无法像 SPI 和 I2C 那样发送原始字 - :cpp:member:`rmt_receive_config_t::signal_range_min_ns` 指定高电平或低电平有效脉冲的最小持续时间。如果脉冲宽度小于指定值,硬件会将其视作干扰信号并忽略。 - :cpp:member:`rmt_receive_config_t::signal_range_max_ns` 指定高电平或低电平有效脉冲的最大持续时间。如果脉冲宽度大于指定值,接收器会将其视作 **停止信号**,并立即生成接收完成事件。 -- 如果传入的数据包很长,无法一次性保存在用户缓冲区中,可以通过将 :cpp:member:`rmt_receive_config_t::extra_flags::en_partial_rx` 设置为 ``true`` 来开启部分接收功能。在这种情况下,当用户缓冲区快满的时候,驱动会多次调用 :cpp:member:`rmt_rx_event_callbacks_t::on_recv_done` 回调函数来通知用户去处理已经收到的数据。你可以检查 :cpp:member::`rmt_rx_done_event_data_t::is_last` 的值来了解当前事务是否已经结束。请注意,并不是所有 ESP 系列芯片都支持这个功能,它依赖硬件提供的 “ping-pong 接收” 或者 “DMA 接收” 的能力。 +- 如果传入的数据包很长,无法一次性保存在用户缓冲区中,可以通过将 :cpp:member:`rmt_receive_config_t::extra_rmt_receive_flags::en_partial_rx` 设置为 ``true`` 来开启部分接收功能。在这种情况下,当用户缓冲区快满的时候,驱动会多次调用 :cpp:member:`rmt_rx_event_callbacks_t::on_recv_done` 回调函数来通知用户去处理已经收到的数据。你可以检查 :cpp:member::`rmt_rx_done_event_data_t::is_last` 的值来了解当前事务是否已经结束。请注意,并不是所有 ESP 系列芯片都支持这个功能,它依赖硬件提供的 “ping-pong 接收” 或者 “DMA 接收” 的能力。 根据以上配置调用 :cpp:func:`rmt_receive` 后,RMT 接收器会启动 RX 机制。注意,以上配置均针对特定事务存在,也就是说,要开启新一轮的接收时,需要再次设置 :cpp:type:`rmt_receive_config_t` 选项。接收器会将传入信号以 :cpp:type:`rmt_symbol_word_t` 的格式保存在内部内存块或 DMA 缓冲区中。 diff --git a/docs/zh_CN/api-reference/peripherals/usb_device.rst b/docs/zh_CN/api-reference/peripherals/usb_device.rst index 90cd2583522f..0498e5637a1a 100644 --- a/docs/zh_CN/api-reference/peripherals/usb_device.rst +++ b/docs/zh_CN/api-reference/peripherals/usb_device.rst @@ -5,9 +5,9 @@ USB 设备栈 {IDF_TARGET_USB_DP_GPIO_NUM:default="20"} {IDF_TARGET_USB_DM_GPIO_NUM:default="19"} -{IDF_TARGET_USB_EP_NUM:default="6"} -{IDF_TARGET_USB_EP_NUM_INOUT:default="5"} -{IDF_TARGET_USB_EP_NUM_IN:default="1"} +{IDF_TARGET_USB_EP_NUM: default="6", esp32p4="15"} +{IDF_TARGET_USB_EP_NUM_INOUT:default="5", esp32p4="8"} +{IDF_TARGET_USB_EP_NUM_IN:default="1", esp32p4="7"} 概述 -------- @@ -34,16 +34,24 @@ USB 设备栈(以下简称设备栈)支持在 {IDF_TARGET_NAME} 上启用 US 硬件连接 -------- -{IDF_TARGET_NAME} 将 USB D+ 和 D- 信号分别路由到 GPIO {IDF_TARGET_USB_DP_GPIO_NUM} 和 {IDF_TARGET_USB_DM_GPIO_NUM}。为了实现 USB 设备功能,这些 GPIO 应通过某种方式连接到总线上(例如,通过 Micro-B 端口、USB-C 端口或直接连接到标准-A 插头)。 +.. only:: esp32s2 or esp32s3 + + {IDF_TARGET_NAME} 将 USB D+ 和 D- 信号分别路由到 GPIO {IDF_TARGET_USB_DP_GPIO_NUM} 和 {IDF_TARGET_USB_DM_GPIO_NUM}。为了实现 USB 设备功能,这些 GPIO 应通过某种方式连接到总线(例如,通过 Micro-B 端口、USB-C 端口或直接连接到标准-A 插头)。 + +.. only:: esp32p4 + + {IDF_TARGET_NAME} 将 USB D+ 和 D- 信号路由到其专用引脚。为了实现 USB 设备功能,这些引脚应通过某种方式连接到总线(例如,通过 Micro-B 端口、USB-C 端口或直接连接到标准-A 插头)。 .. figure:: ../../../_static/usb-board-connection.png :align: center :alt: 将 USB GPIO 直接接连至 USB 标准-A 插头 :figclass: align-center -.. note:: +.. only:: esp32s2 or esp32s3 - 如果你使用带有两个 USB 端口的 {IDF_TARGET_NAME} 开发板,标有 "USB" 的端口已经连接到 D+ 和 D- GPIO。 + .. note:: + + 如果你使用带有两个 USB 端口的 {IDF_TARGET_NAME} 开发板,标有 "USB" 的端口已经连接到 D+ 和 D- GPIO。 .. note:: @@ -90,6 +98,22 @@ USB 设备栈(以下简称设备栈)支持在 {IDF_TARGET_NAME} 上启用 US - :cpp:member:`configuration_descriptor` - :cpp:member:`string_descriptor` +全速 USB 设备应初始化以下字段,以提供相应的配置描述符: + +- :cpp:member:`configuration_descriptor` + +.. only:: esp32p4 + + 高速 USB 设备应初始化以下字段,以提供不同速度下的配置描述符: + + - :cpp:member:`fs_configuration_descriptor` + - :cpp:member:`hs_configuration_descriptor` + - :cpp:member:`qualifier_descriptor` + + .. note:: + + 为符合 USB 2.0 协议规范,需同时初始化 :cpp:member:`fs_configuration_descriptor` 和 :cpp:member:`hs_configuration_descriptor`。 + 调用 :cpp:func:`tinyusb_driver_install` 时,设备栈将基于上述字段中提供的描述符实现 USB 设备。 设备栈还提供了默认描述符,将 :cpp:func:`tinyusb_driver_install` 中的相应字段设置为 ``NULL`` 即可安装。默认描述符包括: diff --git a/docs/zh_CN/api-reference/peripherals/usb_host.rst b/docs/zh_CN/api-reference/peripherals/usb_host.rst index 967f107630cc..632dc91d69ad 100644 --- a/docs/zh_CN/api-reference/peripherals/usb_host.rst +++ b/docs/zh_CN/api-reference/peripherals/usb_host.rst @@ -25,18 +25,26 @@ USB 主机库(以下简称主机库)是 USB 主机栈的最底层,提供 主机库具有以下特性: -- 支持全速 (FS) 和低速 (LS) 设备。 -- 支持四种传输类型,即控制传输、块传输、中断传输和同步传输。 -- 支持多个 Class 驱动程序同时运行,即主机的多个客户端同时运行。 -- 单个设备可以由多个客户端同时使用,如复合设备。 -- 主机库及其底层主机栈不会在内部自动创建操作系统任务,任务数量完全由主机库接口的使用方式决定。一般来说,任务数量为 ``(运行中的主机 Class 驱动程序数量 + 1)``。 +.. list:: + + :esp32s2 or esp32s3: - 支持全速 (FS) 和低速 (LS) 设备。 + :esp32p4: - 支持高速 (HS)、全速 (FS) 和低速 (LS) 设备。 + - 支持四种传输类型,即控制传输、块传输、中断传输和同步传输。 + :esp32p4: - 支持高带宽等时性端点。 + - 支持多个 Class 驱动程序同时运行,即主机的多个客户端同时运行。 + - 单个设备可以由多个客户端同时使用,如复合设备。 + - 主机库及其底层主机栈不会在内部自动创建操作系统任务,任务数量完全由主机库接口的使用方式决定。一般来说,任务数量为 ``(运行中的主机 Class 驱动程序数量 + 1)``。 目前,主机库及其底层主机栈存在以下限制: -- 仅支持单个设备,而主机库的 API 支持多设备。 -- 仅支持异步传输。 -- 仅支持使用发现的首个配置,尚不支持变更为其他配置。 -- 尚不支持传输超时。 +.. list:: + + - 仅支持单个设备,而主机库的 API 支持多设备。 + - 仅支持异步传输。 + - 仅支持使用发现的首个配置,尚不支持变更为其他配置。 + - 尚不支持传输超时。 + :esp32p4: - {IDF_TARGET_NAME} 包含两个 USB-OTG 外设:USB 2.0 OTG 高速和 USB 2.0 OTG 全速。目前仅支持高速实例。 + :esp32p4: - {IDF_TARGET_NAME} 目前无法枚举低速设备。 .. -------------------------------------------------- Architecture ----------------------------------------------------- @@ -89,7 +97,7 @@ USB 主机库(以下简称主机库)是 USB 主机栈的最底层,提供 设备 ^^^^^^^ -主机库隔离了客户端与设备处理的细节,包括连接、内存分配和枚举等,客户端只需提供已连接且已枚举的设备列表供选择。在枚举过程中,每个设备都会自动配置为使用找到的第一个配置,即通过获取配置描述符请求返回的第一个配置描述符。对于大多数标准设备,通常将第一个配置的 ``bConfigurationValue`` 设置为 ``1``。 +主机库隔离了客户端与设备处理的细节,包括连接、内存分配和枚举等,客户端只需提供已连接且已枚举的设备列表供选择。默认情况下,在枚举过程中,每个设备都会自动配置为使用找到的第一个配置,即通过获取配置描述符请求返回的第一个配置描述符。对于大多数标准设备,通常将第一个配置的 ``bConfigurationValue`` 设置为 ``1``。启用选项 :ref:`CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK` 后,可以选择不同的 ``bConfigurationValue``。获取更多详细信息,请参阅 `Multiple configuration Support_`。 只要不与相同接口通信,两个及以上的客户端可以同时与同一设备通信。然而,多个客户端同时与相同设备的默认端点(即 EP0)通信,将导致它们的控制传输序列化。 diff --git a/docs/zh_CN/api-reference/storage/nvs_encryption.rst b/docs/zh_CN/api-reference/storage/nvs_encryption.rst index a5fb70084513..55261bc51230 100644 --- a/docs/zh_CN/api-reference/storage/nvs_encryption.rst +++ b/docs/zh_CN/api-reference/storage/nvs_encryption.rst @@ -35,7 +35,7 @@ NVS 加密:基于 flash 加密的方案 NVS 密钥分区 ^^^^^^^^^^^^^^^^^ -应用如果要使用 NVS 加密(使用基于 flash 加密的方案)编译时,须使用类型为 ``data`` 和子类型为 ``key`` 的密钥分区。该分区应被标记为 ``encrypted`` 且最小为 4 KB (最小分区大小)。参考 :doc:`../../api-guides/partition-tables` 了解详情。在分区表选项 ( ``menuconfig`` > ``Partition Table``) 中,有两个包含 :ref:`nvs_encr_key_partition` 的额外分区表,可以直接用于 NVS 加密。分区的结构如下所示: +应用如果要使用 NVS 加密(使用基于 flash 加密的方案)编译时,须使用类型为 ``data`` 和子类型为 ``nvs_keys`` 的密钥分区。该分区应被标记为 ``encrypted`` 且最小为 4 KB (最小分区大小)。参考 :doc:`../../api-guides/partition-tables` 了解详情。在分区表选项 ( ``menuconfig`` > ``Partition Table``) 中,有两个包含 :ref:`nvs_encr_key_partition` 的额外分区表,可以直接用于 NVS 加密。分区的结构如下所示: .. highlight:: none diff --git a/docs/zh_CN/api-reference/system/inc/power_management_esp32p4.rst b/docs/zh_CN/api-reference/system/inc/power_management_esp32p4.rst index 949099543fea..d420c96eb41d 100644 --- a/docs/zh_CN/api-reference/system/inc/power_management_esp32p4.rst +++ b/docs/zh_CN/api-reference/system/inc/power_management_esp32p4.rst @@ -1 +1,13 @@ -TO BE UPDATED IDF-7672 ++---------------+---------------------------------------+-------------------------------------+ +| CPU 最高频率 | 电源管理锁获取情况 | APB 频率和 CPU 频率 | +| | | | ++---------------+---------------------------------------+-------------------------------------+ +| 360 | 获取 ``ESP_PM_CPU_FREQ_MAX`` | | CPU: 360 MHz | +| | | | APB: 90 Mhz | ++ +---------------------------------------+-------------------------------------+ +| | | 获取 ``ESP_PM_APB_FREQ_MAX``, | | CPU: 90 MHz | +| | | 未获得 ``ESP_PM_CPU_FREQ_MAX`` | | APB: 90 Mhz | ++ +---------------------------------------+-------------------------------------+ +| | 无 | 使用 :cpp:func:`esp_pm_configure` | +| | | 为二者设置最小值 | ++---------------+---------------------------------------+-------------------------------------+ diff --git a/docs/zh_CN/api-reference/system/power_management.rst b/docs/zh_CN/api-reference/system/power_management.rst index 05acedc2c1c0..f723433781f5 100644 --- a/docs/zh_CN/api-reference/system/power_management.rst +++ b/docs/zh_CN/api-reference/system/power_management.rst @@ -55,7 +55,7 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求, 电源管理锁 ---------------------- -{IDF_TARGET_MAX_CPU_FREQ: default="Not updated yet", esp32="80 MHz, 160 MHz, or 240 MHz", esp32s2="80 MHz, 160 MHz, 或 240 MHz", esp32s3="80 MHz, 160 MHz, 或 240 MHz", esp32c2="80 MHz 或 120 MHz", esp32c3="80 MHz 或 160 MHz", esp32c6="80 MHz 或 160 MHz"} +{IDF_TARGET_MAX_CPU_FREQ: default="Not updated yet", esp32="80 MHz, 160 MHz, or 240 MHz", esp32s2="80 MHz, 160 MHz, 或 240 MHz", esp32s3="80 MHz, 160 MHz, 或 240 MHz", esp32c2="80 MHz 或 120 MHz", esp32c3="80 MHz 或 160 MHz", esp32c6="80 MHz 或 160 MHz", esp32p4="360 MHz"} 应用程序可以通过获取或释放管理锁来控制电源管理算法。应用程序获取电源管理锁后,电源管理算法的操作将受到下面的限制。释放电源管理锁后,限制解除。 @@ -114,7 +114,7 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求, - **SPI slave**:从调用 :cpp:func:`spi_slave_initialize` 至 :cpp:func:`spi_slave_free` 期间。 - **GPTimer**:从调用 :cpp:func:`gptimer_enable` 至 :cpp:func:`gptimer_disable` 期间。 - **Ethernet**:从调用 :cpp:func:`esp_eth_driver_install` 至 :cpp:func:`esp_eth_driver_uninstall` 期间。 - - **WiFi**:从调用 :cpp:func:`esp_wifi_start` 至 :cpp:func:`esp_wifi_stop` 期间。如果启用了调制解调器睡眠模式,广播关闭时将释放此管理锁。 + :SOC_WIFI_SUPPORTED: - **WiFi**:从调用 :cpp:func:`esp_wifi_start` 至 :cpp:func:`esp_wifi_stop` 期间。如果启用了调制解调器睡眠模式,广播关闭时将释放此管理锁。 :SOC_TWAI_SUPPORTED: - **TWAI**:从调用 :cpp:func:`twai_driver_install` 至 :cpp:func:`twai_driver_uninstall` 期间 (只有在 TWAI 时钟源选择为 :cpp:enumerator:`TWAI_CLK_SRC_APB` 的时候生效)。 :SOC_BT_SUPPORTED and esp32: - **Bluetooth**:从调用 :cpp:func:`esp_bt_controller_enable` 至 :cpp:func:`esp_bt_controller_disable` 期间。如果启用了蓝牙调制解调器,广播关闭时将释放此管理锁。但依然占用 ``ESP_PM_NO_LIGHT_SLEEP`` 锁,除非将 :ref:`CONFIG_BTDM_CTRL_LOW_POWER_CLOCK` 选项设置为 “外部 32 kHz 晶振”。 :SOC_BT_SUPPORTED and not esp32: - **Bluetooth**:从调用 :cpp:func:`esp_bt_controller_enable` 至 :cpp:func:`esp_bt_controller_disable` 期间。如果启用了蓝牙调制解调器,广播关闭时将释放此管理锁。但依然占用 ``ESP_PM_NO_LIGHT_SLEEP`` 锁。 @@ -129,48 +129,53 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求, :SOC_MCPWM_SUPPORTED: - MCPWM -Light-sleep 外设下电 -------------------------- +.. only:: SOC_PM_SUPPORT_TOP_PD and not esp32c5 -.. only:: esp32c6 or esp32h2 + Light-sleep 外设下电 + ------------------------- - {IDF_TARGET_NAME} 支持在 Light-sleep 时掉电外设的电源域. + {IDF_TARGET_NAME} 支持在 Light-sleep 时掉电外设的电源域. - 如果在 menuconfig 中启用了 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`,在初始化外设时,驱动会将外设工作的寄存器上下文注册到休眠备份链表中,在进入休眠前,``REG_DMA`` 外设会读取休眠备份链表中的配置,根据链表中的配置将外设的寄存器上下文备份至内存,``REG_DMA`` 也会在唤醒时将上下文从内存恢复到外设寄存中。 + 如果在 menuconfig 中启用了 :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`,在初始化外设时,驱动会将外设工作的寄存器上下文注册到休眠备份链表中,在进入休眠前,``REG_DMA`` 外设会读取休眠备份链表中的配置,根据链表中的配置将外设的寄存器上下文备份至内存,``REG_DMA`` 也会在唤醒时将上下文从内存恢复到外设寄存中。 - 目前 IDF 支持以下外设的 Light-sleep 上下文备份: - - INT_MTX - - TEE/APM - - IO_MUX / GPIO - - UART0 - - TIMG0 - - SPI0/1 - - SYSTIMER + 目前 IDF 支持以下外设的 Light-sleep 上下文备份: - 以下外设尚未支持: - - ETM - - TIMG1 - - ASSIST_DEBUG - - Trace - - Crypto: AES/ECC/HMAC/RSA/SHA/DS/XTA_AES/ECDSA - - SPI2 - - I2S - - PCNT - - USB-Serial-JTAG - - TWAI - - LEDC - - MCPWM - - RMT - - SARADC - - SDIO - - PARL_IO - - UART1 + .. list:: + + - INT_MTX + - TEE/APM + - IO_MUX / GPIO + - Timer Group 0 & Timer Group 1 + - SPI0/1 + - SYSTIMER + :SOC_RMT_SUPPORT_SLEEP_RETENTION: - RMT + :SOC_I2C_SUPPORT_SLEEP_RETENTION:- I2C + :SOC_UART_SUPPORT_SLEEP_RETENTION: - All UARTs + + 以下外设尚未支持: + + .. list:: + + - ETM + - ASSIST_DEBUG + - Trace + - Crypto: AES/ECC/HMAC/RSA/SHA/DS/XTA_AES/ECDSA + - SPI2 + - I2S + - PCNT + - USB-Serial-JTAG + - TWAI + - LEDC + - MCPWM + - SARADC + - SDIO + - PARL_IO - 对于未支持 Light-sleep 上下文备份的外设,若启用了电源管理功能,应在外设工作时持有 ``ESP_PM_NO_LIGHT_SLEEP`` 锁以避免进入休眠导致外设工作上下文丢失。 + 对于未支持 Light-sleep 上下文备份的外设,若启用了电源管理功能,应在外设工作时持有 ``ESP_PM_NO_LIGHT_SLEEP`` 锁以避免进入休眠导致外设工作上下文丢失。 - .. note:: + .. note:: - 当外设电源域在睡眠期间断电时,IO_MUX 和 GPIO 模块都处于下电状态,这意味着芯片引脚的状态不会受这些模块控制。要在休眠期间保持 IO 的状态,需要在配置 GPIO 状态前后调用 :cpp:func:`gpio_hold_dis` 和 :cpp:func:`gpio_hold_en`。此操作可确保 IO 配置被锁存,防止 IO 在睡眠期间浮空。 + 当外设电源域在睡眠期间断电时,IO_MUX 和 GPIO 模块都处于下电状态,这意味着芯片引脚的状态不会受这些模块控制。要在休眠期间保持 IO 的状态,需要在配置 GPIO 状态前后调用 :cpp:func:`gpio_hold_dis` 和 :cpp:func:`gpio_hold_en`。此操作可确保 IO 配置被锁存,防止 IO 在睡眠期间浮空。 API 参考 diff --git a/docs/zh_CN/api-reference/system/sleep_modes.rst b/docs/zh_CN/api-reference/system/sleep_modes.rst index 76567ecffea3..1171e7096437 100644 --- a/docs/zh_CN/api-reference/system/sleep_modes.rst +++ b/docs/zh_CN/api-reference/system/sleep_modes.rst @@ -32,7 +32,7 @@ :SOC_RTC_FAST_MEM_SUPPORTED: - RTC 高速内存 :SOC_RTC_SLOW_MEM_SUPPORTED: - RTC 低速内存 -.. only:: SOC_BT_SUPPORTED +.. only:: SOC_WIFI_SUPPORTED and SOC_BT_SUPPORTED 睡眠模式下的 Wi-Fi 和 Bluetooth 功能 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ 如需保持 Wi-Fi 和 Bluetooth 连接,请启用 Wi-Fi 和 Bluetooth Modem-sleep 模式和自动 Light-sleep 模式(请参阅 :doc:`电源管理 API `)。在这两种模式下,Wi-Fi 和 Bluetooth 驱动程序发出请求时,系统将自动从睡眠中被唤醒,从而保持连接。 -.. only:: not SOC_BT_SUPPORTED +.. only:: SOC_WIFI_SUPPORTED and not SOC_BT_SUPPORTED 睡眠模式下的 Wi-Fi 功能 ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -227,7 +227,7 @@ RTC 控制器中内嵌定时器,可用于在预定义的时间到达后唤醒 - 当任意一个所选管脚为高电平时唤醒 (ESP_EXT1_WAKEUP_ANY_HIGH) - 当所有所选管脚为低电平时唤醒 (ESP_EXT1_WAKEUP_ALL_LOW) - .. only:: esp32s2 or esp32s3 or esp32c6 or esp32h2 + .. only:: not esp32 - 当任意一个所选管脚为高电平时唤醒 (ESP_EXT1_WAKEUP_ANY_HIGH) - 当任意一个所选管脚为低电平时唤醒 (ESP_EXT1_WAKEUP_ANY_LOW) @@ -344,7 +344,7 @@ UART 唤醒(仅适用于 Light-sleep 模式) 使用 UART 唤醒之后,在芯片 Active 模式下需要让 UART 接受一些数据用来清零内部的唤醒指示信号。不然的话,下一次 UART 唤醒的触发将只需要比配置的阈值少两个上升沿的数量。 - .. only:: esp32c6 or esp32h2 + .. only:: SOC_PM_SUPPORT_TOP_PD and not esp32c5 .. note:: @@ -471,13 +471,12 @@ UART 输出处理 .. list:: - - :example:`protocols/sntp`:如何实现 Deep-sleep 模式的基本功能,周期性唤醒 ESP 模块,以从 NTP 服务器获取时间。 - - :example:`wifi/power_save`:如何通过 Wi-Fi Modem-sleep 模式和自动 Light-sleep 模式保持 Wi-Fi 连接。 - :SOC_BT_SUPPORTED: - :example:`bluetooth/nimble/power_save`:如何通过 Bluetooth Modem-sleep 模式和自动 Light-sleep 模式保持 Bluetooth 连接。 - :SOC_ULP_SUPPORTED: - :example:`system/deep_sleep`:如何使用 Deep-sleep 唤醒触发器和 ULP 协处理器编程。 - :not SOC_ULP_SUPPORTED: - :example:`system/deep_sleep`:如何通过多种芯片支持的唤醒源,如 RTC 定时器, GPIO, EXT0, EXT1, 触摸传感器等,触发 Deep-sleep 唤醒。 - - :example:`system/light_sleep`: 如何使用多种芯片支持的唤醒源,如定时器,GPIO,触摸传感器等,触发 Light-sleep 唤醒。 - + - :example:`protocols/sntp` 演示如何实现 Deep-sleep 模式的基本功能,周期性唤醒 ESP 模块,以从 NTP 服务器获取时间。 + :SOC_WIFI_SUPPORTED: - :example:`wifi/power_save` 演示如何通过 Wi-Fi Modem-sleep 模式和自动 Light-sleep 模式保持 Wi-Fi 连接。 + :SOC_BT_SUPPORTED: - :example:`bluetooth/nimble/power_save` 演示如何通过 Bluetooth Modem-sleep 模式和自动 Light-sleep 模式保持 Bluetooth 连接。 + :SOC_ULP_SUPPORTED: - :example:`system/deep_sleep` 演示如何使用 Deep-sleep 唤醒触发器和 ULP 协处理器编程。 + :not SOC_ULP_SUPPORTED: - :example:`system/deep_sleep` 演示如何通过 {IDF_TARGET_NAME} 的唤醒源,如 RTC 定时器, GPIO, EXT0, EXT1, 触摸传感器等,触发 Deep-sleep 唤醒。 + - :example:`system/light_sleep` 演示如何使用 {IDF_TARGET_NAME} 的唤醒源,如定时器,GPIO,触摸传感器等,触发 Light-sleep 唤醒。 API 参考 ------------- diff --git a/docs/zh_CN/api-reference/system/ulp-lp-core.rst b/docs/zh_CN/api-reference/system/ulp-lp-core.rst index 02b5aae14c37..b0565d2a3be7 100644 --- a/docs/zh_CN/api-reference/system/ulp-lp-core.rst +++ b/docs/zh_CN/api-reference/system/ulp-lp-core.rst @@ -22,6 +22,8 @@ ULP LP-Core 代码会与 ESP-IDF 项目共同编译,生成一个单独的二 2. 在 CMakeLists.txt 文件中注册组件后,调用 ``ulp_embed_binary`` 函数。例如: +.. code-block:: cmake + idf_component_register() set(ulp_app_name ulp_${COMPONENT_NAME}) @@ -83,7 +85,9 @@ ULP LP-Core 代码会与 ESP-IDF 项目共同编译,生成一个单独的二 注意,所有的符号(变量、数组、函数)都被声明为 ``uint32_t`` 类型。对于函数和数组,获取符号的地址并将其转换为合适的类型。 -生成的链接器脚本文件定义了 LP_MEM 中符号的位置:: +生成的链接器脚本文件定义了 LP_MEM 中符号的位置: + +.. code-block:: none PROVIDE ( ulp_measurement_count = 0x50000060 ); @@ -97,6 +101,10 @@ ULP LP-Core 代码会与 ESP-IDF 项目共同编译,生成一个单独的二 ulp_measurement_count = 64; } +.. note:: + + LP-Core 程序全局变量存储在二进制文件的 ``.bss`` 或者 ``.data`` 部分。这些部分在加载和执行 LP-Core 二进制文件时被初始化。在首次运行 LP-Core 之前,从 HP-Core 主程序访问这些变量可能会导致未定义行为。 + 启动 ULP LP-Core 程序 -------------------------------- @@ -179,6 +187,42 @@ ULP LP-Core 支持的外设 在任何情况下,这些函数都存在于 LP-ROM 中,因此在程序中使用这些函数可以减少 ULP 应用程序的 RAM 占用。 +ULP LP-Core 中断 +---------------- + +配置 LP-Core 协处理器,可以处理各种类型的中断,例如 LP IO 低/高电平中断或是 LP 定时器中断。只需重写 IDF 提供的任何一个弱处理函数,就可以注册一个中断处理程序。所有处理程序可见 :component_file:`ulp_lp_core_interrupts.h `。有关特定目标可使用的中断的详细信息,请参阅 **{IDF_TARGET_NAME} 技术参考手册** [`PDF <{IDF_TARGET_TRM_CN_URL}#ulp>`__]。 + +例如,要重写 LP IO 中断的处理程序,可以在 ULP LP-Core 代码中定义以下函数: + +.. code-block:: c + + void LP_CORE_ISR_ATTR ulp_lp_core_lp_io_intr_handler(void) + { + // 处理中断,清除中断源 + } + +:c:macro:`LP_CORE_ISR_ATTR` 宏用于定义中断处理函数,可确保调用中断处理程序时妥善保存并恢复寄存器。 + +除了为需要处理的中断源配置相关的中断寄存器外,还要调用 :cpp:func:`ulp_lp_core_intr_enable` 函数,在 LP-Core 中断控制器中使能全局中断。 + +调试 ULP LP-Core 应用程序 +------------------------- + +在编程 LP-Core 时,有时很难弄清楚程序未按预期运行的原因。请参考以下策略,调试 LP-Core 程序: + +* 使用 LP-UART 打印:LP-Core 可以访问 LP-UART 外设,在主 CPU 处于睡眠状态时独立打印信息。有关使用此驱动程序的示例,请参阅 :example:`system/ulp/lp_core/lp_uart/lp_uart_print`。 + +* 通过 :ref:`CONFIG_ULP_HP_UART_CONSOLE_PRINT`,将 :cpp:func:`lp_core_printf` 路由到 HP-Core 控制台 UART,可以轻松地将 LP-Core 信息打印到已经连接的 HP-Core 控制台 UART。此方法的缺点是需要主 CPU 处于唤醒状态,并且由于 LP 核与 HP 核未同步,输出可能会交错。 + +* 通过共享变量共享程序状态:如 :ref:`ulp-lp-core-access-variables` 所述,主 CPU 和 ULP 内核都可以轻松访问 RTC 内存中的全局变量。若想了解 ULP 内核的运行状态,可以将状态信息从 ULP 写入变量中,并通过主 CPU 读取信息。这种方法的缺点在于它需要主 CPU 一直处于唤醒状态,而这通常很难实现。另外,若主 CPU 一直处于唤醒状态,可能会掩盖某些问题,因为部分问题只会在特定电源域断电时发生。 + +* 紧急处理程序:当检测到异常时,LP-Core 的紧急处理程序会把 LP-Core 寄存器的状态通过 LP-UART 发送出去。将 :ref:`CONFIG_ULP_PANIC_OUTPUT_ENABLE` 选项设置为 ``y``,可以启用紧急处理程序。禁用此选项将减少 LP-Core 应用程序的 LP-RAM 使用量。若想从紧急转储中解析栈回溯,可以使用 esp-idf-monitor_,例如: + + .. code-block:: bash + + python -m esp_idf_monitor --toolchain-prefix riscv32-esp-elf- --target {IDF_TARGET_NAME} --decode-panic backtrace PATH_TO_ULP_ELF_FILE + + 应用示例 -------------------- @@ -186,6 +230,8 @@ ULP LP-Core 支持的外设 * 在示例 :example:`system/ulp/lp_core/lp_i2c` 中,ULP LP-Core 协处理器在主 CPU 深度睡眠时读取外部 I2C 环境光传感器 (BH1750),并在达到阈值时唤醒主 CPU。 * 在示例 :example:`system/ulp/lp_core/lp_uart/lp_uart_echo` 中,低功耗内核上运行的 LP UART 驱动程序读取并回显写入串行控制台的数据。 * :example:`system/ulp/lp_core/lp_uart/lp_uart_print` 展示了如何在低功耗内核上使用串口打印功能。 +* :example:`system/ulp/lp_core/interrupt` 展示了如何在 LP 内核上注册中断处理程序,接收由主 CPU 触发的中断。 +* :example:`system/ulp/lp_core/gpio_intr_pulse_counter` 展示了如何在主 CPU 处于 Deep-sleep 模式时,使用 GPIO 中断为脉冲计数。 API 参考 ------------- diff --git a/docs/zh_CN/get-started/index.rst b/docs/zh_CN/get-started/index.rst index c5dff638e1de..f4cedfc2115b 100644 --- a/docs/zh_CN/get-started/index.rst +++ b/docs/zh_CN/get-started/index.rst @@ -107,13 +107,13 @@ .. toctree:: :maxdepth: 1 - ESP32-DevKitC <../hw-reference/esp32/get-started-devkitc> - ESP-WROVER-KIT <../hw-reference/esp32/get-started-wrover-kit> - ESP32-PICO-KIT <../hw-reference/esp32/get-started-pico-kit> - ESP32-Ethernet-Kit <../hw-reference/esp32/get-started-ethernet-kit> + ESP32-DevKitC + ESP-WROVER-KIT + ESP32-PICO-KIT + ESP32-Ethernet-Kit ESP32-DevKit-S(-R) <../hw-reference/esp32/user-guide-devkits-r-v1.1> - ESP32-PICO-KIT-1 <../hw-reference/esp32/get-started-pico-kit-1> - ESP32-PICO-DevKitM-2 <../hw-reference/esp32/get-started-pico-devkitm-2> + ESP32-PICO-KIT-1 + ESP32-PICO-DevKitM-2 ESP32-DevKitM-1 <../hw-reference/esp32/user-guide-devkitm-1> .. only:: esp32s2 @@ -124,7 +124,7 @@ ESP32-S2-Saola-1 <../hw-reference/esp32s2/user-guide-saola-1-v1.2> ESP32-S2-DevKitM-1 ESP32-S2-DevKitC-1 - ESP32-S2-Kaluga-Kit <../hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit> + ESP32-S2-Kaluga-Kit .. only:: esp32c3 diff --git a/docs/zh_CN/hw-reference/esp32/get-started-devkitc-v2.rst b/docs/zh_CN/hw-reference/esp32/get-started-devkitc-v2.rst deleted file mode 100644 index b727e27e1d9c..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-devkitc-v2.rst +++ /dev/null @@ -1,85 +0,0 @@ -ESP32-DevKitC V2 入门指南 -================================== - -:link_to_translation:`en: [English]` - -本指南介绍了如何开始使用 ESP32-DevKitC V2 开发板。 - - -准备工作 --------- - -* :ref:`ESP32-DevKitC V2 开发板 ` -* USB A/micro USB B 数据线 -* PC(Windows、Linux 或 macOS) - -你可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 - - -概述 ----- - -ESP32-DevKitC V2 是 `乐鑫 `_ 一款基于 ESP32 的小型开发板,板上模组的绝大部分管脚均已引出,开发人员可根据实际需求,轻松通过跳线连接多种外围器件,或将开发板插在面包板上使用。 - - -功能说明 --------- - -ESP32-DevKitC V2 开发板的主要组件、接口及控制方式见下。 - -.. _get-started-esp32-devkitc-v2-board-front: - -.. figure:: ../../../_static/esp32-devkitc-v2-functional-overview.png - :align: center - :alt: ESP32-DevKitC V2 开发板 - :figclass: align-center - - ESP32-DevKitC V2 开发板 - - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - ESP32-WROOM-32 - - 基于 ESP32 的模组。更多详情,请见 `《ESP32-WROOM-32 技术规格书》`_。 - * - EN - - 复位按键。 - * - Boot - - 下载按键。按下 **Boot** 键并保持,同时按一下 **EN** 键(此时不要松开 **Boot** 键)进入“固件下载”模式,通过串口下载固件。 - * - Micro USB 端口 - - USB 接口。可用作电路板的供电电源,或连接 PC 和 ESP32-WROOM-32 模组的通信接口。 - * - I/O - - 板上模组的绝大部分管脚均已引出至开发板的排针。用户可以对 ESP32 进行编程,实现 PWM、ADC、DAC、I2C、I2S、SPI 等多种功能。 - - -电源选项 --------- - -开发板可从以下三种供电方式中任选其一: - -* Micro USB 供电(默认) -* 5V / GND 管脚供电 -* 3V3 / GND 管脚供电 - -.. warning:: - - 上述供电模式 **不可同时连接**,否则可能会损坏开发板和/或电源。 - - -应用程序开发 ------------- - -ESP32-DevKitC V2 上电前,请首先确认开发板完好无损。 - -现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至你的开发板。 - - -相关文档 --------- - -* `ESP32-DevKitC 原理图 `_ (PDF) -* `《ESP32 技术规格书》 `_ (PDF) -* `《ESP32-WROOM-32 技术规格书》 `_ (PDF) diff --git a/docs/zh_CN/hw-reference/esp32/get-started-devkitc.rst b/docs/zh_CN/hw-reference/esp32/get-started-devkitc.rst deleted file mode 100644 index b21ea71e4079..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-devkitc.rst +++ /dev/null @@ -1,225 +0,0 @@ -ESP32-DevKitC V4 入门指南 -============================================= - -:link_to_translation:`en: [English]` - -本指南介绍了如何开始使用 ESP32-DevKitC V4 开发板。 - - -准备工作 ------------ - -* :ref:`ESP32-DevKitC V4 开发板 ` -* USB A / micro USB B 数据线 -* PC(Windows、Linux 或 Mac OS) - -你可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 - - -.. _DevKitC-Overview: - -概述 ----- - -ESP32-DevKitC V4 是 `乐鑫 `_ 一款基于 ESP32 的小型开发板,板上模组的绝大部分管脚均已引出,开发人员可根据实际需求,轻松通过跳线连接多种外围器件,或将开发板插在面包板上使用。 - -为了更好地满足不同用户需求,ESP32-DevKitC V4 还支持以下不同配置: - -- 可选多款 ESP32 模组 - - - `ESP32-WROOM-32E `_ - - `ESP32-WROOM-32UE `_ - - `ESP32-WROOM-32D `_ - - `ESP32-WROOM-32U `_ - - `ESP32-SOLO-1 `_ - - `ESP32-WROVER-E `_ - - `ESP32-WROVER-IE `_ - - `ESP32-WROOM-DA `_ - -- 可选排针或排母 - -详情请见 `乐鑫产品选型工具 `__。 - - -功能说明 ---------- - -ESP32-DevKitC V4 开发板的主要组件、接口及控制方式见下。 - -.. _get-started-esp32-devkitc-board-front: - -.. figure:: ../../../_static/esp32-devkitc-functional-overview.jpg - :align: center - :alt: ESP32-DevKitC V4(板载 ESP32-WROOM-32) - - ESP32-DevKitC V4(板载 ESP32-WROOM-32) - - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - ESP32-WROOM-32 - - 基于 ESP32 的模组。更多详情,请见 `《ESP32-WROOM-32 技术规格书》`_。 - * - EN - - 复位按键。 - * - Boot - - 下载按键。按下 **Boot** 键并保持,同时按一下 **EN** 键(此时不要松开 **Boot** 键)进入“固件下载”模式,通过串口下载固件。 - * - USB-to-UART 桥接器 - - 单芯片 USB-UART 桥接器,可提供高达 3 Mbps 的传输速率。 - * - Micro USB 接口。 - - USB 接口,可用作电路板的供电电源,或连接 PC 和 ESP32-WROOM-32 模组的通信接口。 - * - 5V Power On LED - - 开发板通电后(USB 或外部 5 V),该指示灯将亮起。更多信息,请见 `相关文档`_ 中的原理图。 - * - I/O - - 板上模组的绝大部分管脚均已引出至开发板的排针。用户可以对 ESP32 进行编程,实现 PWM、ADC、DAC、I2C、I2S、SPI 等多种功能。 - - -电源选项 --------- - -开发板可从以下三种供电方式中任选其一: - -* Micro USB 供电(默认) -* 5V/GND 管脚供电 -* 3V3/GND 管脚供电 - -.. warning:: - - 上述供电模式 **不可同时连接**,否则可能会损坏开发板和/或电源。 - - -排针 ------------- - -下表列出了开发板两侧排针(J1 和 J3)的名称和功能,排针名称如图 :ref:`get-started-esp32-devkitc-board-front` 中所示。 - - -J2 -^^^ -==== ==== ========== =========================================== -编号 名称 类型 [1]_ 功能 -==== ==== ========== =========================================== -1 3V3 P 3.3 V 电源 -2 EN I CHIP_PU, Reset -3 VP I GPIO36, ADC1_CH0, S_VP -4 VN I GPIO39, ADC1_CH3, S_VN -5 IO34 I GPIO34, ADC1_CH6, VDET_1 -6 IO35 I GPIO35, ADC1_CH7, VDET_2 -7 IO32 I/O GPIO32, ADC1_CH4, TOUCH_CH9, XTAL_32K_P -8 IO33 I/O GPIO33, ADC1_CH5, TOUCH_CH8, XTAL_32K_N -9 IO25 I/O GPIO25, ADC1_CH8, DAC_1 -10 IO26 I/O GPIO26, ADC2_CH9, DAC_2 -11 IO27 I/O GPIO27, ADC2_CH7, TOUCH_CH7 -12 IO14 I/O GPIO14, ADC2_CH6, TOUCH_CH6, MTMS -13 IO12 I/O GPIO12, ADC2_CH5, TOUCH_CH5, MTDI -14 GND G 接地 -15 IO13 I/O GPIO13, ADC2_CH4, TOUCH_CH4, MTCK -16 D2 I/O GPIO9, D2 [2]_ -17 D3 I/O GPIO10, D3 [2]_ -18 CMD I/O GPIO11, CMD [2]_ -19 5V P 5 V 电源 -==== ==== ========== =========================================== - - -J3 -^^^ -==== ==== ========== =========================================== -编号 名称 类型 [1]_ 功能 -==== ==== ========== =========================================== -1 GND G 接地 -2 IO23 I/O GPIO23 -3 IO22 I/O GPIO22 -4 TX I/O GPIO1, U0TXD -5 RX I/O GPIO3, U0RXD -6 IO21 I/O GPIO21 -7 GND G 接地 -8 IO19 I/O GPIO19 -9 IO18 I/O GPIO18 -10 IO5 I/O GPIO5 -11 IO17 I/O GPIO17 [3]_ -12 IO16 I/O GPIO16 [3]_ -13 IO4 I/O GPIO4, ADC2_CH0, TOUCH_CH0 -14 IO0 I/O GPIO0, ADC2_CH1, TOUCH_CH1, Boot -15 IO2 I/O GPIO2, ADC2_CH2, TOUCH_CH2 -16 IO15 I/O GPIO15, ADC2_CH3, TOUCH_CH3, MTDO -17 D1 I/O GPIO8, D1 [2]_ -18 D0 I/O GPIO7, D0 [2]_ -19 CLK I/O GPIO6, CLK [2]_ -==== ==== ========== =========================================== - -.. [1] P:电源;I:输入;O:输出。 -.. [2] 管脚 D0、D1、D2、D3、CMD 和 CLK 用于 ESP32 芯片与 SPI flash 间的内部通信,集中分布在开发板两侧靠近 USB 端口的位置。通常而言,这些管脚最好不连,否则可能影响 SPI flash/SPI RAM 的工作。 -.. [3] 管脚 GPIO16 和 GPIO17 仅适用于板载 ESP32-WROOM 系列和 ESP32-SOLO-1 的开发板,板载 ESP32-WROVER 系列开发板的管脚 GPIO16 和 GPIO17 保留内部使用。 - - -管脚布局 -^^^^^^^^^^^ -.. figure:: ../../../_static/esp32-devkitC-v4-pinout.png - :align: center - :scale: 45% - :alt: ESP32-DevKitC 管脚布局(点击放大) - - ESP32-DevKitC 管脚布局(点击放大) - - -有关 C15 的提示 --------------------- - -较早版本 ESP32-DevKitC 开发板上的 C15 可能存在以下问题: - -* 开发板上电后可能进入下载模式; -* 如果用户通过 GPIO0 输出时钟,C15 可能会影响信号。 - -用户如果认为 C15 可能影响开发板的使用,则可以将 C15 完全移除。C15 在开发板上的具体位置见下图黄色部分。 - - -.. figure:: ../../../_static/esp32-devkitc-c15-location.png - :align: center - :alt: C15(黄色)在 ESP32-DevKitC V4 开发板上的位置 - :width: 30% - - C15(黄色)在 ESP32-DevKitC V4 开发板上的位置 - - -应用程序开发 ------------------ - -ESP32-DevKitC V4 上电前,请首先确认开发板完好无损。 - -现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至你的开发板。 - - -开发板尺寸 -------------- - -.. figure:: ../../../_static/esp32-devkitc-dimensions-back.jpg - :align: center - :scale: 80% - :alt: ESP32-DevKitC 开发板尺寸(板载 ESP32-WROOM-32 模组)-- 仰视图 - - ESP32-DevKitC 开发板尺寸(板载 ESP32-WROOM-32 模组)-- 仰视图 - - -相关文档 ------------ - -* `ESP32-DevKitC V4 原理图 `_ (PDF) -* `《ESP32 技术规格书》 `_ (PDF) -* `《ESP32-WROOM-32 技术规格书》 `_ (PDF) -* `《ESP32-WROOM-32D & ESP32-WROOM-32U 技术规格书》 `_ (PDF) -* `《ESP32-WROOM-32E & ESP32-WROOM-32UE 技术规格书》 `_ (PDF) -* `《ESP32-WROOM-DA 技术规格书》 `_ (PDF) -* `《ESP32-WROVER 技术规格书》 `_ (PDF) -* `《ESP32-WROVER-B 技术规格书》 `_ (PDF) -* `乐鑫产品选型工具 `_ - -有关本开发板的更多设计文档,请联系我们的商务部门 `sales@espressif.com `_。 - - -.. toctree:: - :hidden: - - get-started-devkitc-v2 diff --git a/docs/zh_CN/hw-reference/esp32/get-started-ethernet-kit-v1.0.rst b/docs/zh_CN/hw-reference/esp32/get-started-ethernet-kit-v1.0.rst deleted file mode 100644 index 08f2590ad101..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-ethernet-kit-v1.0.rst +++ /dev/null @@ -1,380 +0,0 @@ -ESP32-Ethernet-Kit V1.0 入门指南 -============================================= - -:link_to_translation:`en:[English]` - -本指南介绍了如何使用 ESP32-Ethernet-Kit 开发板以及配置相关功能。 - -:ref:`ESP32-Ethernet-Kit ` 是一款以太网转 Wi-Fi 开发板,可为以太网设备赋予 Wi-Fi 连接功能。为了提供更灵活的电源选项,ESP32-Ethernet-Kit 也同时支持以太网供电 (PoE)。 - - -准备工作 -------------- - -* :ref:`ESP32-Ethernet-Kit V1.0 开发板 ` -* USB 数据线(A 转 Micro-B) -* PC(Windows、Linux 或 macOS) - -你可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 - - -概述 --------- - -ESP32-Ethernet-Kit 是一款来自 `乐鑫 `_ 的开发板。 - -该开发板由以太网母板(A 板)和 PoE 子板(B 板)两部分组成。其中 :ref:`以太网母板(A 板)` 贴蓝牙/Wi-Fi 双模 ESP32-WROVER-B 模组和单端口 10/100 快速以太网收发器 (PHY) IP101GRI。:ref:`PoE 子板(B 板) ` 提供以太网供电功能。ESP32-Ethernet-Kit 的 A 板可在不连接 B 板的情况下独立工作。 - -.. _get-started-esp32-ethernet-kit-b-v1.0: - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.0.png - :align: center - :alt: ESP32-Ethernet-Kit V1.0 - :figclass: align-center - - ESP32-Ethernet-Kit V1.0 - -为了实现程序下载和监控,A 板还集成了一款先进多协议 USB 桥接器(FTDI FT2232H 芯片),进而允许开发人员直接通过 USB 接口,使用 JTAG 对 ESP32 进行调试,无需额外的 JTAG 适配器。 - - -功能概述 ------------ - -ESP32-Ethernet-Kit 开发板的主要组件和连接方式见下。 - -.. figure:: ../../../_static/esp32-ethernet-kit-block-diagram.png - :align: center - :scale: 50% - :alt: ESP32-Ethernet-Kit 功能框图(点击放大) - :figclass: align-center - - ESP32-Ethernet-Kit 功能框图(点击放大) - - -功能说明 ------------ - -ESP32-Ethernet-Kit 开发板的主要组件、接口及控制方式见下。 - - -.. _get-started-esp32-ethernet-kit-a-v1.0-layout: - -以太网母板(A 板) -^^^^^^^^^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-ethernet-kit-a-v1.0-layout.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit - 以太网母板(A 板)布局 - :figclass: align-center - - ESP32-Ethernet-Kit - 以太网母板(A 板)布局(点击放大) - -下表将从图片右上角开始,以顺时针顺序介绍图中的主要组件。 - -======================= ================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== -主要组件 基本介绍 -======================= ================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== -ESP32-WROVER-B 模组 这款 ESP32 模组内置 64-Mbit PSRAM,可提供灵活的额外存储空间和数据处理能力。 - -GPIO Header 2 由 5 个未引出通孔组成,可连接至 ESP32 的部分 GPIO。具体介绍,请见 `GPIO Header 2`_。 - -流控 跳线帽,可接入开发板信号。具体介绍,请见 `流控`_。 - -功能选择开关 DIP 开关,可配置 ESP32 部分 GPIO 的功能。具体介绍,请见 `功能选择开关`_。 - -Tx/Rx LED 2 个 LED,可显示 UART 传输的状态。 - -GPIO Header 3 可连接至 ESP32 的部分 GPIO,根据 `功能选择开关`_ 的位置有不同功能。 - -FT2232H FT2232H 多协议 USB 转串口桥接器。开发人员可通过 USB 接口对 FT2232H 芯片进行控制和编程,与 ESP32 建立连接。FT2232H 芯片可在通道 A 提供 USB-to-JTAG 接口功能,并在通道 B 提供 USB-to-Serial 接口功能,便利开发人员的应用开发与调试。见 `ESP32-Ethernet-Kit V1.0 以太网母板(A 板)原理图`_。 - -USB 端口 USB 接口。可用作开发板的供电电源,或连接 PC 和开发板的通信接口。 - -电源开关 电源开关。拨向 **Boot** 按键一侧,开发板上电;拨离 **Boot** 按键一侧,开发板掉电。 - -5V Input 5V 电源接口建议仅在开发板自动运行(未连接 PC)时使用。仅用于全负荷工作下的后备电源。 - -5V Power On LED 当开发板通电后(USB 或外部 5V 供电),该红色指示灯将亮起。 - -DC/DC 转换器 直流 5 V 转 3.3 V,输出电流高达 2 A。 - -B 板连接器 1 对 2 针排针,用于连接 :ref:`PoE 子板(B 板)`。 - -IP101GRI (PHY) 物理层 (PHY) 单端口 10/100 快速以太网收发器 `IP101GRI`_ ,允许开发人员实现与以太网线缆的物理层连接。PHY 与 ESP32 通过简化媒体独立接口 (RMII) 实现连接。RMII 是 `媒体独立接口 (MII)`_ 的简化版本。PHY 可在 10/100 Mbps 速率下支持 IEEE 802.3/802.3u 标准。 - -RJ45 端口 以太网数据传输端口。 - -网络变压器 网络变压器属于以太网物理层的一部分,可保护电路免受故障和电压瞬变影响,包括防止收发器芯片和线缆之间产生共模信号。同时它也可以在收发器与以太网设备之间提供电流隔绝。 - -Link/Activity LED 2 个 LED(绿色和红色),可分别显示 PHY 处于 "Link" 状态或 "Activity" 状态。 - -BOOT 按键 下载按键。按下 **BOOT** 键并保持,同时按一下 **EN** 键(此时不要松开 **BOOT** 键)进入“固件下载”模式,通过串口下载固件。 - -CH_PU 按键 复位按键。 - -GPIO Header 1 由 6 个未引出通孔组成,可连接至 ESP32 的备用 GPIO。具体介绍,请见 `GPIO Header 1`_。 - -======================= ================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== - - -.. _get-started-esp32-ethernet-kit-b-v1.0-layout: - -PoE 子板(B 板) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -PoE 子板通过以太网电缆传输电能 (PoE),为以太网母板(A 板)提供电源。PoE 子板(B 板)的主要组件见 `功能概述`_ 中的功能框图。 - -PoE 子板(B 板)具有以下特性: - -* 支持 IEEE 802.3at -* 电源输出:5 V,1.4 A - -如需使用 PoE 功能,请用以太网线缆将以太网母板(A 板)上的 **RJ45 端口** 连接至 PoE 的交换机。太网母板(A 板)检测到来自 PoE 子板(B 板)的 5 V 供电后,将从 USB 供电自动切换至 PoE 供电。 - -.. figure:: ../../../_static/esp32-ethernet-kit-b-v1.0-layout.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit - PoE 子板(B 板) - :figclass: align-center - - ESP32-Ethernet-Kit - PoE 子板(B 板)布局(点击放大) - -========================== ================================================================================================================================= -主要组件 基本介绍 -========================== ================================================================================================================================= -A 板连接器 1 个 4 针排母,用于将 B 板连接至 :ref:`以太网母板(A 板)`。 - -外部电源终端 PoE 子板(B 板)备用电源。 - -========================== ================================================================================================================================= - - -.. _get-started-esp32-ethernet-kit-b-v1.0-setup-options: - -设置选项 -------------- - -本节介绍用于 ESP32-Ethernet-Kit 开发板的硬件配置选项。 - - -功能选择开关 -^^^^^^^^^^^^^^^ - -用户可使用 **功能选择开关** 配置特定 GPIO 管脚的功能。 - -======= ================ ================================================================ -DIP SW GPIO 管脚 管脚功能( DIP SW 开启状态) -======= ================ ================================================================ -1. GPIO14 连接至 FT2232H,提供 JTAG 功能 -2. GPIO12 连接至 FT2232H,提供 JTAG 功能 -3. GPIO13 连接至 FT2232H,提供 JTAG 功能 -4. GPIO15 连接至 FT2232H,提供 JTAG 功能 -5. GPIO4 连接至 FT2232H,提供 JTAG 功能 -6. GPIO2 连接至板上 25 MHz 晶振 -7. GPIO5 连接至 IP101GRI 的 RESET_N 输入 -8. n/a -======= ================ ================================================================ - -用户还可以关闭 DIP DW,将部分 GPIO 用于其他用途。 - - -流控 -^^^^^^^^^^^^ - -2 x 2 跳线连接器,可用于 UART 流控功能。 - -==== ======= ================================================= -. 信号 备注 -==== ======= ================================================= -1. MTDO GPIO13,见 `功能选择开关`_。 -2. MTCK GPIO15,见 `功能选择开关`_。 -3. RTS FT2232H 的 RTS 信号 -4. CTS FT2232H 的 CTS 信号 -==== ======= ================================================= - - -GPIO 分配 ---------------- - -本节介绍了 ESP32-Ethernet-Kit 开发板特定接口或功能的 GPIO 分配情况。 - - -IP101GRI (PHY) 接口 -^^^^^^^^^^^^^^^^^^^^^^^^ - -ESP32 (MAC) 与 IP101GRI (PHY) 的管脚对应关系见下。ESP32-Ethernet-Kit 开发板默认使用媒体独立接口 (RMII)。 - -==== ================ =============== -. ESP32 管脚 (MAC) IP101GRI (PHY) -==== ================ =============== -*RMII 接口* ---------------------------------------- -1. GPIO21 TX_EN -2. GPIO19 TXD[0] -3. GPIO22 TXD[1] -4. GPIO25 RXD[0] -5. GPIO26 RXD[1] -6. GPIO27 CRS_DV -7. GPIO0 REF_CLK ----- ---------------- --------------- -*串行管理接口* ---------------------------------------- -8 GPIO23 MDC -9 GPIO18 MDIO ----- ---------------- --------------- -*PHY 复位* ---------------------------------------- -10 GPIO5 Reset_N -==== ================ =============== - -.. note:: - - 除了 REF_CLK 之外,*RMII 接口* 下的所有管脚分配都是固定的,不能通过 IOMUX 或 GPIO 矩阵进行更改。 - - -GPIO Header 1 -^^^^^^^^^^^^^ - -本连接器包括 ESP32-Ethernet-Kit 开发板上部分不用做他用的 GPIO。 - -==== ================ -. ESP32 管脚 -==== ================ -1. GPIO32 -2. GPIO33 -3. GPIO34 -4. GPIO35 -5. GPIO36 -6. GPIO39 -==== ================ - - -GPIO Header 2 -^^^^^^^^^^^^^ - -本连接器包括具有特定 MII 功能的 GPIO(GPIO2 除外)。根据具体情况,部分以太网应用程序可能需要使用此功能。 - -==== ========== ================= ================== -. ESP32 管脚 MII 功能 说明 -==== ========== ================= ================== -1. GPIO17 EMAC_CLK_180 见说明 1。 -2. GPIO16 EMAC_CLK_OUT 见说明 1。 -3. GPIO4 EMAC_TX_ER -4. GPIO2 n/a 见说明 2。 -5. GPIO5 EMAC_RX_CLK 见说明 2。 -==== ========== ================= ================== - -.. note:: - - 1. ESP32 芯片的 GPIO16 和 GPIO17 管脚没有引出至 ESP32-WROVER-B 模组的管脚,因此无法使用。如需使用 ESP32 的 GP1016 和 GPIO17 管脚,建议更换其他不含 SPIRAM 的模组,比如 ESP32-WROOM-32D 或 ESP32-SOLO-1。 - 2. 具体功能取决于 `功能选择开关`_ 的设置。 - - -GPIO Header 3 -^^^^^^^^^^^^^ - -本连接器中 GPIO 的功能取决于 `功能选择开关`_ 的设置。 - -==== =========== -. ESP32 管脚 -==== =========== -1. GPIO15 -2. GPIO13 -3. GPIO12 -4. GPIO14 -5. GND -6. 3V3 -==== =========== - - -GPIO 管脚分配 -^^^^^^^^^^^^^^^^^^^^^^^ - -.. csv-table:: - :header: ESP32-WROVER-B,IP101GRI,UART,JTAG,GPIO,说明 - - S_VP,,,,IO36, - S_VN,,,,IO39, - IO34,,,,IO34, - IO35,,,,IO35, - IO32,,,,IO32, - IO33,,,,IO33, - IO25,RXD[0],,,, - IO26,RXD[1],,,, - IO27,CRS_DV,,,, - IO14,,,TMS,IO14, - IO12,,,TDI,IO12, - IO13,,RTS,TCK,IO13, - IO15,,CTS,TDO,IO15, - IO2,,,,IO2,见下方说明 1 和说明 3。 - IO0,REF_CLK,,,,见下方说明 2 和说明 3。 - IO4,,,nTRST,IO4, - IO16,,,,IO16 (NC),见下方说明 4。 - IO17,,,,IO17 (NC),见下方说明 4。 - IO5,Reset_N,,,IO5, - IO18,MDIO,,,, - IO19,TXD[0],,,, - IO21,TX_EN,,,, - RXD0,,RXD,,, - TXD0,,TXD,,, - IO22,TXD[1],,,, - IO23,MDC,,,, - - -.. note:: - - 1. GPIO2 用于使能 PHY 的外部振荡器。 - 2. GPIO0 用于为 PHY 提供 50 MHz 基准时钟源。为了防止传输线路延迟对时钟相位带来的影响,该时钟信号将首先被反相,而后提供给 PHY。 - 3. 为防止 PHY 端 GPIO0 的上电状态受到时钟输出的影响,PHY 的外部晶振将在 ESP32 上电后通过 GPIO2 使能。 - 4. ESP32 芯片的 GPIO16 和 GPIO17 管脚没有引出至 ESP32-WROVER-B 模组的管脚,因此无法使用。如需使用 ESP32 的 GP1016 和 GPIO17 管脚,建议更换其他不含 SPIRAM 的模组,比如 ESP32-WROOM-32D 或 ESP32-SOLO-1。 - - -应用程序开发 ------------------------------ - -ESP32-Ethernet-Kit 上电前,请首先确认开发板完好无损。 - - -初始设置 -^^^^^^^^^^^^^ - -1. 首先,请将 :ref:`以太网母板(A 板)` 上的所有开关均拨至 **ON** 状态,即使 **功能选择开关** 处于默认状态。 -2. 为了方便应用程序的下载和测试,此时请不要在开发板安装任何跳线帽,也不要为开发板接入任何信号。 -3. 此时可以连接 :ref:`PoE 子板(B 板) `,但不要向 B 板连接任何外部电源。 -4. 使用 USB 数据线将 :ref:`以太网母板(A 板) ` 连接至 PC。 -5. 将 **电源开关** 从 GND 拨至 5V0 一侧。此时,**5V Power On LED** 应点亮。 - - -正式开始开发 -^^^^^^^^^^^^^^^^^^ - -现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至开发板。 - -如需使用较早 GNU Make 编译系统,则请参考 :ref:`get-started-step-by-step` 章节。 - -在进入下一步前,请确保已完成上述所有步骤。 - - -配置与加载以太网示例 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -在完成开发环境设置和开发板测试后,即可配置并烧录 :example:`ethernet/basic` 示例。本示例专门用于测试以太网功能,支持不同 PHY,包括 :ref:`ESP32-Ethernet-Kit V1.0 开发板 ` 使用的 **IP101GRI**。 - - -相关文档 ------------------ - -* `ESP32-Ethernet-Kit V1.0 以太网母板(A 板)原理图`_ (PDF) -* `ESP32-Ethernet-Kit V1.0 PoE 子板(B 板)原理图`_ (PDF) -* `《ESP32 技术规格书》 `_ (PDF) -* `《ESP32-WROVER-B 技术规格书》 `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 - -.. _ESP32-Ethernet-Kit V1.0 以太网母板(A 板)原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_A_V1.0_20190517.pdf -.. _ESP32-Ethernet-Kit V1.0 PoE 子板(B 板)原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_B_V1.0_20190517.pdf -.. _IP101GRI: http://www.bdtic.com/DataSheet/ICplus/IP101G_DS_R01_20121224.pdf -.. _媒体独立接口 (MII): https://en.wikipedia.org/wiki/Media-independent_interface diff --git a/docs/zh_CN/hw-reference/esp32/get-started-ethernet-kit-v1.1.rst b/docs/zh_CN/hw-reference/esp32/get-started-ethernet-kit-v1.1.rst deleted file mode 100644 index ae09a6333b79..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-ethernet-kit-v1.1.rst +++ /dev/null @@ -1,410 +0,0 @@ -ESP32-Ethernet-Kit V1.1 入门指南 -================================= - -:link_to_translation:`en:[English]` - -本指南将介绍 ESP32-Ethernet-Kit 开发板的配置以及相关功能的使用。 - -:ref:`ESP32-Ethernet-Kit ` 是一款以太网转 Wi-Fi 开发板,可为以太网设备赋予 Wi-Fi 连接功能。为了提供更灵活的电源选项,ESP32-Ethernet-Kit 同时也支持以太网供电 (PoE)。 - - -准备工作 --------- - -* :ref:`ESP32-Ethernet-Kit V1.1 开发板 ` -* USB 数据线(A 转 Micro-B) -* PC(Windows、Linux 或 macOS) - -你可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 - - -概述 ----- - -ESP32-Ethernet-Kit 是一款来自 `乐鑫 `_ 的开发板。 - -它由 :ref:`以太网母板(A 板)` 和 `PoE 子板(B 板)`_ 两部分组成。其中 :ref:`以太网母板(A 板)` 集成蓝牙/Wi-Fi 双模 ESP32-WROVER-B 模组和单端口 10/100 Mbps 快速以太网收发器 (PHY) IP101GRI。`PoE 子板(B 板)`_ 提供以太网供电功能。ESP32-Ethernet-Kit 的 A 板可在不连接 B 板的情况下独立工作。 - -.. _get-started-esp32-ethernet-kit-v1.1: - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.1.png - :align: center - :alt: ESP32-Ethernet-Kit V1.1 - :figclass: align-center - - ESP32-Ethernet-Kit V1.1 - -为了实现程序下载和监控,A 板还集成了一款先进多协议 USB 桥接器(FTDI FT2232H 芯片)。FTDI FT2232H 芯片使得开发人员无需额外的 JTAG 适配器,通过 USB 桥接器使用 JTAG 接口便可对 ESP32 直接进行调试。 - - -功能概述 ---------- - -ESP32-Ethernet-Kit 开发板的主要组件和连接方式如下。 - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.1-block-diagram.png - :align: center - :scale: 60% - :alt: ESP32-Ethernet-Kit 功能框图(点击放大) - :figclass: align-center - - ESP32-Ethernet-Kit 功能框图(点击放大) - - -功能说明 --------- - -有关 ESP32-Ethernet-Kit 开发板的主要组件、接口及控制方式,请见下方的图片和表格。 - -.. _get-started-esp32-ethernet-kit-a-v1.1-layout: - - -以太网母板(A 板) -^^^^^^^^^^^^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-ethernet-kit-a-v1.1-layout.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit - Ethernet board (A) layout - :figclass: align-center - - ESP32-Ethernet-Kit - 以太网母板(A 板)布局(点击放大) - -下表将从图片右上角开始,以顺时针顺序介绍图中的主要组件。 - -.. list-table:: 表格1 组件介绍 - :widths: 40 150 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - ESP32-WROVER-B 模组 - - 这款 ESP32 模组内置 64-Mbit PSRAM,可提供灵活的额外存储空间和数据处理能力。 - * - GPIO Header 2 - - 由 5 个未引出通孔组成,可连接至 ESP32 的部分 GPIO。具体介绍,请见 `GPIO Header 2`_。 - * - 功能选择开关 - - 一个 4 位拨码开关,可配置 ESP32 部分 GPIO 的功能。请注意,拨码开关旁边开发板的丝印层上的 GPIO 管脚标记的位置是不正确的。有关详细信息和正确的管脚分配,请见 `功能选择开关`_。 - * - Tx/Rx LEDs - - 2 个 LED,可显示 UART 传输的状态。 - * - FT2232H - - FT2232H 多协议 USB 转串口桥接器。开发人员可通过 USB 接口对 FT2232H 芯片进行控制和编程,与 ESP32 建立连接。FT2232H 芯片可在通道 A 提供 USB-to-JTAG 接口功能,并在通道 B 提供 USB-to-Serial 接口功能,便利开发人员的应用开发与调试。见 `ESP32-Ethernet-Kit V1.1 以太网母板(A 板)原理图`_。 - * - USB 端口 - - USB 接口。可用作开发板的供电电源,或连接 PC 和开发板的通信接口。 - * - 电源开关 - - 电源开关。拨向 **5V0** 按键侧,开发板上电;拨向 **GND** 按键一侧,开发板掉电。 - * - 5V Input - - 5 V 电源接口建议仅在开发板自动运行(未连接 PC)时使用。 - * - 5V Power On LED - - 当开发板通电后(USB 或外部 5 V 供电),该红色指示灯将亮起。 - * - DC/DC 转换器 - - 直流 5 V 转 3.3 V,输出电流最高可达 2 A。 - * - Board B 连接器 - - 1 对 排针和排母,用于连接 `PoE 子板(B 板)`_。 - * - IP101GRI (PHY) - - 物理层 (PHY) 单端口 10/100 快速以太网收发器 `IP101GRI `_ 芯片,允许开发人员实现与以太网线缆的物理层连接。PHY 与 ESP32 通过简化媒体独立接口 (RMII) 实现连接。RMII 是 `媒体独立接口 (MII) `_ 的标准简化版本。PHY 可在 10/100 Mbps 速率下支持 IEEE 802.3 / 802.3u 标准。 - * - RJ45 端口 - - 以太网数据传输端口。 - * - 网络变压器 - - 网络变压器属于以太网物理层的一部分,可保护电路,使其免受故障和电压瞬变影响,包括防止收发器芯片和线缆之间产生共模信号。同时它也可以在收发器与以太网设备之间提供电流隔绝。 - * - Link/Activity LED - - 2 个 LED(绿色和红色),可分别显示 PHY 处于 “Link” 状态或 “Activity” 状态。 - * - BOOT Button - - 下载按键。按下 **BOOT** 键并保持,同时按一下 **EN** 键(此时不要松开 **BOOT** 键)进入“固件下载”模式,通过串口下载固件。 - * - EN 按键 - - 复位按键。 - * - GPIO Header 1 - - 由 6 个未引出通孔组成,可连接至 ESP32 的备用 GPIO。具体介绍,请见 `GPIO Header 1`_。 - - -PoE 子板(B 板) -^^^^^^^^^^^^^^^^^^^ - -PoE 子板转换以太网电缆传输的电能 (PoE),为以太网母板(A 板)提供电源。PoE 子板(B 板)的主要组件见 `功能概述`_ 中的功能框图。 - -PoE 子板(B 板)具有以下特性: - -* 支持 IEEE 802.3at 标准 -* 电源输出:5 V,1.4 A - -如需使用 PoE 功能,请用以太网线缆将以太网母板(A 板)上的 **RJ45 Port** 连接至 PoE 的交换机。以太网母板(A 板)检测到来自 PoE 子板(B 板)的 5 V 供电后,将从 USB 供电自动切换至 PoE 供电。 - -.. figure:: ../../../_static/esp32-ethernet-kit-b-v1.0-layout.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit - PoE board (B) - :figclass: align-center - - ESP32-Ethernet-Kit - PoE 子板(B 板)布局(点击放大) - -.. list-table:: 表格2 PoE 子板(B 板) - :widths: 40 150 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - A 板连接器 - - 4 个排针(左侧)和排母(右侧),用于将 PoE 子板(B 板)连接至 :ref:`Ethernet board (A) `。左侧的管脚接受来自 PoE 交换机的电源。右侧的管脚为 以太网母板(A 板)提供 5 V 电源。 - * - 外部电源终端 - - PoE 子板(B 板)可选电源 (26.6 ~ 54 V)。 - -.. _get-started-esp32-ethernet-kit-v1.1-setup-options: - - -设置选项 --------- - -本节介绍用于 ESP32-Ethernet-Kit 开发板的硬件配置选项。 - - -功能选择开关 -^^^^^^^^^^^^^^ - -拨码开关打开时,拨码开关将列出的 GPIO 路由到 FT2232H 以提供 JTAG 功能。拨码开关关闭时,GPIO 可以用于其他目的。 - -========= ========== -拨码开关 GPIO 管脚 -========= ========== - 1 GPIO13 - 2 GPIO12 - 3 GPIO15 - 4 GPIO14 -========= ========== - -.. note:: - - 拨码开关旁边开发板的丝印层上的 GPIO 管脚标记的位置是不正确的。请以表格中的顺序为准。 - - -RMII 时钟源选择 -^^^^^^^^^^^^^^^^ - -RMII 工作模式下的以太网 MAC 和 PHY 需要一个公共的 50 MHz 同步时钟(即 RMII 时钟),它既可以由外部提供,也可以由内部的 ESP32 APLL 产生。 - -.. note:: - - 有关 RMII 时钟源选择的更多信息,请参见 `ESP32-Ethernet-Kit V1.1 以太网母板(A 板)原理图`_,第 2 页的位置 D2。 - - -PHY 侧提供 RMII 时钟 -""""""""""""""""""""""""""""" - -ESP32-Ethernet-Kit 默认配置为 IP101GRI 的 50M_CLKO 信号线提供 RMII 时钟,该时钟信号由 PHY 外侧连接的 25 MHz 无源晶振经过倍频产生。详情请参见下图。 - -.. figure:: ../../../_static/esp32-ethernet-kit-rmii-clk-from-phy.png - :align: center - :scale: 80% - :alt: RMII Clock from IP101GRI PHY - :figclass: align-center - - PHY 侧提供 RMII 时钟 - -请注意,系统上电时 RESET_N 旁的下拉电阻会将 PHY 置于复位状态,ESP32 需要通过 GPIO5 将 RESET_N 拉高才能启动 PHY,只有这样才能保证系统的正常上电,否则 ESP32 会存在一定几率进入下载模式(当 REF_CLK_50M 时钟信号在 GPIO0 上电采样阶段刚好处于高电平)。 - - -ESP32 APLL 内部提供的 RMII 时钟 -"""""""""""""""""""""""""""""""""""" - -另一种选择是从 ESP32 APLL 内部获取 RMII 时钟,请参见下图。来自 GPIO0 的时钟信号首先被反相,以解决传输线延迟的问题,然后提供给 PHY。 - -.. figure:: ../../../_static/esp32-ethernet-kit-rmii-clk-to-phy.png - :align: center - :scale: 80% - :alt: RMII Clock from ESP Internal APLL - :figclass: align-center - - ESP32 APLL 内部提供的 RMII 时钟 - -要实现此选项,用户需要在板子上移除或添加一些阻容元器件。有关详细信息,请参见 `ESP32-Ethernet-Kit V1.1 以太网母板(A 板)原理图`_,第 2 页,位置 D2。请注意,如果 APLL 已经用于其他用途(如 I2S 外设),那么只能使用外部 RMII 时钟。 - - -GPIO 分配 ---------- - -本节介绍了 ESP32-Ethernet-Kit 开发板特定接口或功能的 GPIO 分配情况。 - - -IP101GRI (PHY) 接口 -^^^^^^^^^^^^^^^^^^^^^^^^^ - -下表显示了 ESP32 (MAC) 与 IP101GRI (PHY) 的管脚对应关系。ESP32-Ethernet-Kit 的实现默认设置为简化媒体独立接口。 - -==== ================ =============== -. ESP32 管脚 (MAC) IP101GRI (PHY) -==== ================ =============== -*RMII 接口* ---------------------------------------- - 1 GPIO21 TX_EN - 2 GPIO19 TXD[0] - 3 GPIO22 TXD[1] - 4 GPIO25 RXD[0] - 5 GPIO26 RXD[1] - 6 GPIO27 CRS_DV - 7 GPIO0 REF_CLK ----- ---------------- --------------- -*串行管理接口* ---------------------------------------- - 8 GPIO23 MDC - 9 GPIO18 MDIO ----- ---------------- --------------- -*PHY 复位* ---------------------------------------- -10 GPIO5 Reset_N -==== ================ =============== - -.. Note:: - - 除了 REF_CLK 之外,ESP32 的 *RMII 接口* 下的所有管脚分配都是固定的,不能通过 IOMUX 或 GPIO 矩阵进行更改。 - - -GPIO Header 1 -^^^^^^^^^^^^^ - -本连接器包括 ESP32-Ethernet-Kit 开发板上部分不用做他用的 GPIO。 - -==== ================ -. ESP32 管脚 -==== ================ - 1 GPIO32 - 2 GPIO33 - 3 GPIO34 - 4 GPIO35 - 5 GPIO36 - 6 GPIO39 -==== ================ - - -GPIO Header 2 -^^^^^^^^^^^^^ - -根据“说明"描述的不同情形,本连接器包含可用做他用的 GPIO。 - -==== ========== ==================== -. ESP32 管脚 说明 -==== ========== ==================== - 1 GPIO17 见下方说明 1 - 2 GPIO16 见下方说明 1 - 3 GPIO4 - 4 GPIO2 - 5 GPIO13 见下方说明 2 - 6 GPIO12 见下方说明 2 - 7 GPIO15 见下方说明 2 - 8 GPIO14 见下方说明 2 - 9 GND Ground -10 3V3 3.3 V 电源 -==== ========== ==================== - -.. note:: - - 1. ESP32 芯片的 GPIO16 和 GPIO17 管脚没有引出至 ESP32-WROVER-B 模组的管脚,因此无法使用。如需使用 ESP32 的 GP1016 和 GPIO17 管脚,建议更换其他不含 PSRAM 的模组,比如 ESP32-WROOM-32D 或 ESP32-SOLO-1。 - - 2. 具体功能取决于 `功能选择开关`_ 的设置。 - - -GPIO 管脚分配总结 -^^^^^^^^^^^^^^^^^^^ - -.. csv-table:: - :header: ESP32-WROVER-B,IP101GRI,UART,JTAG,GPIO,Comments - - S_VP,,,,IO36, - S_VN,,,,IO39, - IO34,,,,IO34, - IO35,,,,IO35, - IO32,,,,IO32, - IO33,,,,IO33, - IO25,RXD[0],,,, - IO26,RXD[1],,,, - IO27,CRS_DV,,,, - IO14,,,TMS,IO14, - IO12,,,TDI,IO12, - IO13,,RTS,TCK,IO13, - IO15,,CTS,TDO,IO15, - IO2,,,,IO2, - IO0,REF_CLK,,,,See note 1 - IO4,,,,IO4, - IO16,,,,IO16 (NC),See note 2 - IO17,,,,IO17 (NC),See note 2 - IO5,Reset_N,,,,See note 1 - IO18,MDIO,,,, - IO19,TXD[0],,,, - IO21,TX_EN,,,, - RXD0,,RXD,,, - TXD0,,TXD,,, - IO22,TXD[1],,,, - IO23,MDC,,,, - -.. note:: - - 1. 为防止 ESP32 侧 GPIO0 的上电状态受 PHY 侧时钟输出的影响,PHY 侧 RESET_N 默认为低,以关闭 PHY 侧时钟输出。上电后,可以通过 GPIO5 控制 RESET_N 以打开该时钟输出。参见 `PHY 侧提供 RMII 时钟`_。对于无法通过 RESET_N 关闭时钟输出的 PHY,PHY 侧建议使用可在外部禁用/使能的有源晶振。与使用 RESET_N 类似,默认情况下晶振模块应禁用,并在上电后由 ESP32 开启。有关参考设计,请参见 `ESP32-Ethernet-Kit V1.1 以太网母板(A 板)原理图`_。 - - 2. ESP32 芯片的 GPIO16 和 GPIO17 管脚没有引出至 ESP32-WROVER-B 模组的管脚,因此无法使用。如需使用 ESP32 的 GP1016 和 GPIO17 管脚,建议更换其他不含 PSRAM 的模组,比如 ESP32-WROOM-32D 或 ESP32-SOLO-1。 - - -应用程序开发 -------------- - -ESP32-Ethernet-Kit 上电前,请首先确认开发板完好无损。 - - -初始设置 -^^^^^^^^^^ - -1. 首先,请将 :ref:`以太网母板(A 板)` 上的所有开关均拨至 **ON** 状态,使 **功能选择开关** 处于默认状态。 -2. 为了方便应用程序的下载和测试,不要为开发板输入任何信号。 -3. 此时可以连接 `PoE 子板(B 板)`_ ,但不要向 B 板连接任何外部电源。 -4. 使用 USB 数据线将 :ref:`以太网母板(A 板)` 连接至 PC。 -5. 将 **电源开关** 从 GND 拨至 5V0 一侧。此时,**5V Power On LED** 应点亮。 - - -正式开始开发 -^^^^^^^^^^^^^ - -现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至你的开发板。 - -在进入下一步前,请确保已完成上述所有步骤。 - - -配置与加载以太网示例 -^^^^^^^^^^^^^^^^^^^^^^^ - -在完成开发环境设置和开发板测试后,即可配置并烧录 :example:`ethernet/basic` 示例。本示例专门用于测试以太网功能,支持不同 PHY,包括 :ref:`get-started-esp32-ethernet-kit-v1.1` 开发板使用的 **IP101GRI** 。 - - -针对 ESP32-Ethernet-Kit V1.0 的主要修改 ------------------------------------------ - -* 原 GPIO0 反相后时钟提供给 PHY 方案改为由 PHY 侧外接无源晶振,提供时钟给 GPIO0。原用于控制有源晶振的 OSC_EN 的 IO2 释放,可用作其他用途。 -* 为防止 ESP32 侧 GPIO0 的上电状态受到 PHY 侧时钟输出的影响,PHY 侧 RESET_N 默认为低,关闭 PHY 侧时钟输出。而后可通过 GPIO5 控制 RESET_N 打开该时钟输出。 -* 移除 FT2232H 芯片的外部 SPI flash U6。 -* 移除流控的测试排针 J4。 -* 移除 nTRST JTAG 信号,相应的 GPIO4 可用作其他用途。 -* GPIO15 线上的上拉电阻 R68 移至 JTAG 的 MTDO 侧。 -* 为了加强 A 板和 B 板连接间的防呆设计(减少反向插入 B 板的机会),将原先 A 板上的 2 排 4 针排针改为 1 排 4 针排母和 1 排 4 针排针。相应的 4 针排针排和排母排则安装在 B 板上。 - - -ESP32-Ethernet-Kit 的其他版本 -------------------------------- - -* :doc:`get-started-ethernet-kit-v1.0` - - -相关文档 ----------- - -* `ESP32-Ethernet-Kit V1.1 以太网母板(A 板)原理图`_ (PDF) -* `ESP32-Ethernet-Kit V1.0 PoE 子板(B 板)原理图`_ (PDF) -* `ESP32 技术规格书 `_ (PDF) -* `ESP32-WROVER-B 技术规格书 `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 - -.. _ESP32-Ethernet-Kit V1.1 以太网母板(A 板)原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_A_V1.1_20190711.pdf -.. _ESP32-Ethernet-Kit V1.0 PoE 子板(B 板)原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_B_V1.0_20190517.pdf -.. _ESP32-Ethernet-Kit V1.0 以太网母板(A 板)原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_A_V1.0_20190517.pdf - -.. toctree:: - :hidden: - - get-started-ethernet-kit-v1.0.rst diff --git a/docs/zh_CN/hw-reference/esp32/get-started-ethernet-kit.rst b/docs/zh_CN/hw-reference/esp32/get-started-ethernet-kit.rst deleted file mode 100644 index ae0cc4c0cd9b..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-ethernet-kit.rst +++ /dev/null @@ -1,423 +0,0 @@ -ESP32-Ethernet-Kit V1.2 入门指南 -================================= - -:link_to_translation:`en:[English]` - -本指南将介绍 ESP32-Ethernet-Kit 开发板的配置以及相关功能的使用。 - -:ref:`ESP32-Ethernet-Kit ` 是一款以太网转 Wi-Fi 开发板,可为以太网设备赋予 Wi-Fi 连接功能。为了提供更灵活的电源选项,ESP32-Ethernet-Kit 同时也支持以太网供电 (PoE)。 - -.. _get-started-esp32-ethernet-kit-v1.2-overview: - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.2-overview.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit V1.2 - :figclass: align-center - - ESP32-Ethernet-Kit V1.2 概图(点击放大) - - -准备工作 --------- - -* :ref:`ESP32-Ethernet-Kit V1.2 开发板 ` -* USB 数据线(A 转 Micro-B) -* PC(Windows、Linux 或 macOS) - -你可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 - - -概述 ----- - -ESP32-Ethernet-Kit 是一款来自 `乐鑫 `_ 的开发板。 - -它由 :ref:`以太网母板(A 板)` 和 `PoE 子板(B 板)`_ 两部分组成。其中 :ref:`以太网母板(A 板)` 集成蓝牙/Wi-Fi 双模 ESP32-WROVER-E 模组和单端口 10/100 Mbps 快速以太网收发器 (PHY) IP101GRI。`PoE 子板(B 板)`_ 提供以太网供电功能。ESP32-Ethernet-Kit 的 A 板可在不连接 B 板的情况下独立工作。 - -.. _get-started-esp32-ethernet-kit-v1.2: - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.2.jpg - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit V1.2 - :figclass: align-center - - ESP32-Ethernet-Kit V1.2(点击放大) - -为了实现程序下载和监控,A 板还集成了一款先进多协议 USB 桥接器(FT2232H 芯片)。FT2232H 芯片使得开发人员无需额外的 JTAG 适配器,通过 USB 桥接器使用 JTAG 接口便可对 ESP32 直接进行调试。 - - -功能概述 ---------- - -ESP32-Ethernet-Kit 开发板的主要组件和连接方式如下。 - -.. figure:: ../../../_static/esp32-ethernet-kit-v1.1-block-diagram.png - :align: center - :scale: 60% - :alt: ESP32-Ethernet-Kit 功能框图(点击放大) - :figclass: align-center - - ESP32-Ethernet-Kit 功能框图(点击放大) - - -功能说明 --------- - -有关 ESP32-Ethernet-Kit 开发板的主要组件、接口及控制方式,请见下方的图片和表格。 - -.. _get-started-esp32-ethernet-kit-a-v1.2-layout: - - -以太网母板(A 板) -^^^^^^^^^^^^^^^^^^^^^ - -.. figure:: ../../../_static/esp32-ethernet-kit-a-v1.2-layout.jpg - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit V1.2 - :figclass: align-center - - ESP32-Ethernet-Kit - 以太网母板(A 板)布局(点击放大) - -下表将从图片右上角开始,以顺时针顺序介绍图中的主要组件。 - -.. list-table:: 表格1 组件介绍 - :widths: 40 150 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - ESP32-WROVER-E 模组 - - 这款 ESP32 模组内置 64-Mbit PSRAM,可提供灵活的额外存储空间和数据处理能力。 - * - GPIO Header 2 - - 由 5 个未引出通孔组成,可连接至 ESP32 的部分 GPIO。具体介绍,请见 `GPIO Header 2`_。 - * - 功能选择开关 - - 一个 4 位拨码开关,可配置 ESP32 部分 GPIO 的功能。具体介绍,请见 `功能选择开关`_。 - * - Tx/Rx LEDs - - 2 个 LED,可显示 UART 传输的状态。 - * - FT2232H - - FT2232H 多协议 USB 转串口桥接器。开发人员可通过 USB 接口对 FT2232H 芯片进行控制和编程,与 ESP32 建立连接。FT2232H 芯片可在通道 A 提供 USB-to-JTAG 接口功能,并在通道 B 提供 USB-to-Serial 接口功能,便利开发人员的应用开发与调试。见 `ESP32-Ethernet-Kit V1.2 以太网母板(A 板)原理图`_。 - * - USB 端口 - - USB 接口。可用作开发板的供电电源,或连接 PC 和开发板的通信接口。 - * - 电源开关 - - 电源开关。拨向 **5V0** 按键侧,开发板上电;拨向 **GND** 按键一侧,开发板掉电。 - * - 5V Input - - 5 V 电源接口建议仅在开发板自动运行(未连接 PC)时使用。 - * - 5V Power On LED - - 当开发板通电后(USB 或外部 5 V 供电),该红色指示灯将亮起。 - * - DC/DC 转换器 - - 直流 5 V 转 3.3 V,输出电流最高可达 2 A。 - * - Board B 连接器 - - 1 对 排针和排母,用于连接 `PoE 子板(B 板)`_。 - * - IP101GRI (PHY) - - 物理层 (PHY) 单端口 10/100 快速以太网收发器 `IP101GRI `_ 芯片,允许开发人员实现与以太网线缆的物理层连接。PHY 与 ESP32 通过简化媒体独立接口 (RMII) 实现连接。RMII 是 `媒体独立接口 (MII) `_ 的标准简化版本。PHY 可在 10/100 Mbps 速率下支持 IEEE 802.3 / 802.3u 标准。 - * - RJ45 端口 - - 以太网数据传输端口。 - * - 网络变压器 - - 网络变压器属于以太网物理层的一部分,可保护电路,使其免受故障和电压瞬变影响,包括防止收发器芯片和线缆之间产生共模信号。同时它也可以在收发器与以太网设备之间提供电流隔绝。 - * - Link/Activity LED - - 2 个 LED(绿色和红色),可分别显示 PHY 处于 “Link” 状态或 “Activity” 状态。 - * - BOOT Button - - 下载按键。按下 **BOOT** 键并保持,同时按一下 **EN** 键(此时不要松开 **BOOT** 键)进入“固件下载”模式,通过串口下载固件。 - * - EN 按键 - - 复位按键。 - * - GPIO Header 1 - - 由 6 个未引出通孔组成,可连接至 ESP32 的备用 GPIO。具体介绍,请见 `GPIO Header 1`_。 - -.. note:: - - 开发板支持固件自动下载模式。若遵循 `应用程序开发`_ 章节中的步骤并使用了规定软件,则无需对 BOOT 或 EN 按键进行任何操作。 - - -PoE 子板(B 板) -^^^^^^^^^^^^^^^^^^^ - -PoE 子板转换以太网电缆传输的电能 (PoE),为以太网母板(A 板)提供电源。PoE 子板(B 板)的主要组件见 `功能概述`_ 中的功能框图。 - -PoE 子板(B 板)具有以下特性: - -* 支持 IEEE 802.3at 标准 -* 电源输出:5 V,1.4 A - -如需使用 PoE 功能,请用以太网线缆将以太网母板(A 板)上的 **RJ45 Port** 连接至 PoE 的交换机。以太网母板(A 板)检测到来自 PoE 子板(B 板)的 5 V 供电后,将从 USB 供电自动切换至 PoE 供电。 - -.. figure:: ../../../_static/esp32-ethernet-kit-b-v1.0-layout.png - :align: center - :scale: 80% - :alt: ESP32-Ethernet-Kit - PoE board (B) - :figclass: align-center - - ESP32-Ethernet-Kit - PoE 子板(B 板)布局(点击放大) - -.. list-table:: 表格2 PoE 子板(B 板) - :widths: 40 150 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - A 板连接器 - - 4 个排针(左侧)和排母(右侧),用于将 PoE 子板(B 板)连接至 :ref:`Ethernet board (A) `。左侧的管脚接受来自 PoE 交换机的电源。右侧的管脚为以太网母板(A 板)提供 5 V 电源。 - * - 外部电源终端 - - PoE 子板(B 板)可选电源 (26.6 ~ 54 V)。 - - -.. _get-started-esp32-ethernet-kit-v1.2-setup-options: - -设置选项 --------- - -本节介绍用于 ESP32-Ethernet-Kit 开发板的硬件配置选项。 - - -功能选择开关 -^^^^^^^^^^^^^^ - -拨码开关打开时,拨码开关将列出的 GPIO 路由到 FT2232H 以提供 JTAG 功能。拨码开关关闭时,GPIO 可以用于其他目的。 - -========= ========== -拨码开关 GPIO 管脚 -========= ========== - 1 GPIO13 - 2 GPIO12 - 3 GPIO15 - 4 GPIO14 -========= ========== - - -RMII 时钟源选择 -^^^^^^^^^^^^^^^^ - -RMII 工作模式下的以太网 MAC 和 PHY 需要一个公共的 50 MHz 同步时钟(即 RMII 时钟),它既可以由外部提供,也可以由内部的 ESP32 APLL 产生(不推荐)。 - -.. note:: - - 有关 RMII 时钟源选择的更多信息,请参见 `ESP32-Ethernet-Kit V1.2 以太网母板(A 板)原理图`_,第 2 页的位置 D2。 - - -PHY 侧提供 RMII 时钟 -""""""""""""""""""""""""""""" - -ESP32-Ethernet-Kit 默认配置为 IP101GRI 的 50M_CLKO 信号线提供 RMII 时钟,该时钟信号由 PHY 外侧连接的 25 MHz 无源晶振经过倍频产生。详情请参见下图。 - -.. figure:: ../../../_static/esp32-ethernet-kit-rmii-clk-from-phy.png - :align: center - :scale: 80% - :alt: RMII Clock from IP101GRI PHY - :figclass: align-center - - PHY 侧提供 RMII 时钟 - -请注意,系统上电时 RESET_N 旁的下拉电阻会将 PHY 置于复位状态,ESP32 需要通过 GPIO5 将 RESET_N 拉高才能启动 PHY,只有这样才能保证系统的正常上电,否则 ESP32 会存在一定几率进入下载模式(当 REF_CLK_50M 时钟信号在 GPIO0 上电采样阶段刚好处于高电平)。 - - -ESP32 APLL 内部提供的 RMII 时钟 -"""""""""""""""""""""""""""""""""""" - -另一种选择是从 ESP32 APLL 内部获取 RMII 时钟,请参见下图。来自 GPIO0 的时钟信号首先被反相,以解决传输线延迟的问题,然后提供给 PHY。 - -.. figure:: ../../../_static/esp32-ethernet-kit-rmii-clk-to-phy.png - :align: center - :scale: 80% - :alt: RMII Clock from ESP Internal APLL - :figclass: align-center - - ESP32 APLL 内部提供的 RMII 时钟 - -要实现此选项,用户需要在板子上移除或添加一些阻容元器件。有关详细信息,请参见 `ESP32-Ethernet-Kit V1.2 以太网母板(A 板)原理图`_,第 2 页,位置 D2。请注意,如果 APLL 已经用于其他用途(如 I2S 外设),那么只能使用外部 RMII 时钟。 - - -GPIO 分配 ---------- - -本节介绍了 ESP32-Ethernet-Kit 开发板特定接口或功能的 GPIO 分配情况。 - - -IP101GRI (PHY) 接口 -^^^^^^^^^^^^^^^^^^^^^^^^^ - -下表显示了 ESP32 (MAC) 与 IP101GRI (PHY) 的管脚对应关系。ESP32-Ethernet-Kit 的实现默认设置为简化媒体独立接口。 - -==== ================ =============== -No. ESP32 管脚 (MAC) IP101GRI (PHY) -==== ================ =============== -*RMII 接口* ---------------------------------------- - 1 GPIO21 TX_EN - 2 GPIO19 TXD[0] - 3 GPIO22 TXD[1] - 4 GPIO25 RXD[0] - 5 GPIO26 RXD[1] - 6 GPIO27 CRS_DV - 7 GPIO0 REF_CLK ----- ---------------- --------------- -*串行管理接口* ---------------------------------------- - 8 GPIO23 MDC - 9 GPIO18 MDIO ----- ---------------- --------------- -*PHY 复位* ---------------------------------------- -10 GPIO5 Reset_N -==== ================ =============== - -.. Note:: - - ESP32 的 *RMII 接口* 下的所有管脚分配都是固定的,不能通过 IOMUX 或 GPIO 矩阵进行更改。REF_CLK 仅可选择 GPIO0、GPIO16 或 GPIO17,且不可通过 GPIO 矩阵进行更改。 - - -GPIO Header 1 -^^^^^^^^^^^^^ - -本连接器包括 ESP32-Ethernet-Kit 开发板上部分不用做他用的 GPIO。 - -==== ================ -No. ESP32 管脚 -==== ================ - 1 GPIO32 - 2 GPIO33 - 3 GPIO34 - 4 GPIO35 - 5 GPIO36 - 6 GPIO39 -==== ================ - - -GPIO Header 2 -^^^^^^^^^^^^^ - -根据“说明”描述的不同情形,本连接器包含可用做他用的 GPIO。 - -==== ========== ==================== -No. ESP32 管脚 说明 -==== ========== ==================== - 1 GPIO17 见下方说明 1 - 2 GPIO16 见下方说明 1 - 3 GPIO4 - 4 GPIO2 - 5 GPIO13 见下方说明 2 - 6 GPIO12 见下方说明 2 - 7 GPIO15 见下方说明 2 - 8 GPIO14 见下方说明 2 - 9 GND Ground -10 3V3 3.3 V 电源 -==== ========== ==================== - -.. note:: - - 1. ESP32 芯片的 GPIO16 和 GPIO17 管脚没有引出至 ESP32-WROVER-E 模组的管脚,因此无法使用。如需使用 ESP32 的 GP1016 和 GPIO17 管脚,建议更换其他不含 PSRAM 的模组,比如 ESP32-WROOM-32D 或 ESP32-SOLO-1。 - - 2. 具体功能取决与 `功能选择开关`_ 的设置。 - - -GPIO 管脚分配总结 -^^^^^^^^^^^^^^^^^^^ - -.. csv-table:: - :header: ESP32-WROVER-E,IP101GRI,UART,JTAG,GPIO,Comments - - S_VP,,,,IO36, - S_VN,,,,IO39, - IO34,,,,IO34, - IO35,,,,IO35, - IO32,,,,IO32, - IO33,,,,IO33, - IO25,RXD[0],,,, - IO26,RXD[1],,,, - IO27,CRS_DV,,,, - IO14,,,TMS,IO14, - IO12,,,TDI,IO12, - IO13,,,TCK,IO13, - IO15,,,TDO,IO15, - IO2,,,,IO2, - IO0,REF_CLK,,,,See note 1 - IO4,,,,IO4, - IO16,,,,IO16 (NC),See note 2 - IO17,,,,IO17 (NC),See note 2 - IO5,Reset_N,,,,See note 1 - IO18,MDIO,,,, - IO19,TXD[0],,,, - IO21,TX_EN,,,, - RXD0,,RXD,,, - TXD0,,TXD,,, - IO22,TXD[1],,,, - IO23,MDC,,,, - -.. note:: - - 1. 为防止 ESP32 侧 GPIO0 的上电状态受 PHY 侧时钟输出的影响,PHY 侧 RESET_N 默认为低,以关闭 PHY 侧时钟输出。上电后,可以通过 GPIO5 控制 RESET_N 以打开该时钟输出。参见 `PHY 侧提供 RMII 时钟`_。对于无法通过 RESET_N 关闭时钟输出的 PHY,PHY 侧建议使用可在外部禁用/使能的有源晶振。与使用 RESET_N 类似,默认情况下晶振模块应禁用,并在上电后由 ESP32 开启。有关参考设计,请参见 `ESP32-Ethernet-Kit V1.2 以太网母板(A 板)原理图`_。 - - 2. ESP32 芯片的 GPIO16 和 GPIO17 管脚没有引出至 ESP32-WROVER-E 模组的管脚,因此无法使用。如需使用 ESP32 的 GP1016 和 GPIO17 管脚,建议更换其他不含 PSRAM 的模组,比如 ESP32-WROOM-32D 或 ESP32-SOLO-1。 - - -应用程序开发 -------------- - -ESP32-Ethernet-Kit 上电前,请首先确认开发板完好无损。 - - -初始设置 -^^^^^^^^^^ - -1. 首先,请将 :ref:`以太网母板(A 板)` 上的所有开关均拨至 **ON** 状态,使 **功能选择开关** 处于默认状态。 -2. 为了方便应用程序的下载和测试,不要为开发板输入任何信号。 -3. 此时可以连接 `PoE 子板(B 板)`_ ,但不要向 B 板连接任何外部电源。 -4. 使用 USB 数据线将 :ref:`以太网母板(A 板)` 连接至 PC。 -5. 将 **电源开关** 从 GND 拨至 5V0 一侧。此时,**5V Power On LED** 应点亮。 - - -正式开始开发 -^^^^^^^^^^^^^ - -现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至你的开发板。 - -在进入下一步前,请确保已完成上述所有步骤。 - - -配置与加载以太网示例 -^^^^^^^^^^^^^^^^^^^^^^^ - -在完成开发环境设置和开发板测试后,即可配置并烧录 :example:`ethernet/basic` 示例。本示例专门用于测试以太网功能,支持不同 PHY,包括 :ref:`get-started-esp32-ethernet-kit-v1.2` 开发板使用的 **IP101GRI** 。 - - -针对 ESP32-Ethernet-Kit V1.1 的主要修改 ------------------------------------------ - -* 更正拨码开关周围 GPIO 编号丝印。 -* C1、C2、C42 和 C43 更新为 20 pF。详细信息见 `ESP32-Ethernet-Kit V1.2 以太网母板(A 板)原理图`_。 -* 模组 ESP32-WROVER-B 替换为 ESP32-WROVER-E。 - - -ESP32-Ethernet-Kit 的其他版本 -------------------------------- - -* :doc:`get-started-ethernet-kit-v1.0` -* :doc:`get-started-ethernet-kit-v1.1` - - -相关文档 ----------- - -* `ESP32-Ethernet-Kit V1.2 以太网母板(A 板)原理图`_ (PDF) -* `ESP32-Ethernet-Kit PoE 子板(B 板)原理图`_ (PDF) -* `ESP32-Ethernet-Kit V1.2 以太网母板(A 板)PCB 布局图 `_ (PDF) -* `ESP32-Ethernet-Kit PoE 子板(B 板)PCB 布局图 `_ (PDF) -* `ESP32 技术规格书 `_ (PDF) -* `ESP32-WROVER-E 技术规格书 `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 - -.. _ESP32-Ethernet-Kit V1.1 以太网母板(A 板)原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_A_V1.1_20190711.pdf -.. _ESP32-Ethernet-Kit PoE 子板(B 板)原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_B_V1.0_20190517.pdf -.. _ESP32-Ethernet-Kit V1.0 以太网母板(A 板)原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-ETHERNET-KIT_A_V1.0_20190517.pdf -.. _ESP32-Ethernet-Kit V1.2 以太网母板(A 板)原理图: https://dl.espressif.com/dl/schematics/SCH_ESP32-Ethernet-Kit_A_V1.2_20200528.pdf - -.. toctree:: - :hidden: - - get-started-ethernet-kit-v1.0.rst - get-started-ethernet-kit-v1.1.rst - diff --git a/docs/zh_CN/hw-reference/esp32/get-started-pico-devkitm-2.rst b/docs/zh_CN/hw-reference/esp32/get-started-pico-devkitm-2.rst deleted file mode 100644 index 662ac2b7532f..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-pico-devkitm-2.rst +++ /dev/null @@ -1,369 +0,0 @@ -ESP32-PICO-DevKitM-2 -********************** - -:link_to_translation:`en:[English]` - -概述 -====== - -ESP32-PICO-DevKitM-2 是一款基于 `ESP32 `_ 的乐鑫开发板,板上搭载 `ESP32-PICO-MINI-02/02U `_ 模组。ESP32-PICO-MINI-02/02U 模组具备完整的 Wi-Fi 和蓝牙功能。 - -ESP32-PICO-DevKitM-2 开发板同时集成了 USB-to-UART 桥接电路,方便开发人员直接通过 PC 的 USB 端口直接进行固件烧录和调试。 - -为方便硬件连接,ESP32-PICO-MINI-02/02U 上的所有 IO 信号和系统电源管脚均引出至开发板两侧焊盘 (18 x 0.1")。上述 18 个焊盘也均引出至排针,可使用杜邦线连接。 - -.. note:: - - ESP32-PICO-DevKitM-2 开发板默认采用排针。 - -ESP32-PICO-DevKitM-2 为用户提供了基于 ESP32 芯片应用开发的硬件,更加方便用户探索 ESP32 芯片的功能。 - -.. figure:: ../../../_static/esp32-pico-devkitm-2-overview.png - :align: center - :scale: 70% - :alt: ESP32-PICO-DevKitM-2 (click to enlarge) - :figclass: align-center - - ESP32-PICO-DevKitM-2 外观图(点击放大) - -本指南包括以下几个章节: - -- `快速入门`_:简要介绍 ESP32-PICO-DevKitM-2 开发板,以及上手这款开发板所需的软件配置; -- `内含组件和包装方式`_:介绍零售订单和批量订单所提供的组件及包装方式; -- `硬件参考`_:提供 ESP32-PICO-DevKitM-2 开发板硬件详细信息; -- `硬件版本`_:介绍硬件历史版本(如有),已知问题(如有),并提供链接至历史版本开发板的入门指南(如有); -- `相关文档`_:提供相关文档的链接。 - - -快速入门 -========= - -本节介绍了如何快速上手 ESP32-PICO-DevKitM-2。首先对 ESP32-PICO-DevKitM-2 开发板进行了简要介绍,然后在 `应用开发`_ 小节介绍如何将固件烧录至开发板。 - - -.. _get-started-pico-devkitm-2-board-front: - -组件描述 ----------- - -ESP32-PICO-DevKitM-2 开发板的主要组件、接口及控制方式见下图。下文以板载 ESP32-PICO-MINI-02 的开发板为例进行说明。 - -.. figure:: ../../../_static/esp32-pico-devkitm-2-layout-front.png - :align: center - :scale: 90% - :alt: ESP32-PICO-DevKitM-2 (click to enlarge) - :figclass: align-center - - ESP32-PICO-DevKitM-2 开发板组件布局 - 正面(点击放大) - -从左上角开始,按顺时针顺序,开发板主要组件的描述见下表。 - -.. list-table:: - :widths: 10 25 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - ESP32-PICO-MINI-02 - - ESP32-PICO-DevKitM-2 开发板的板载模组,搭载 ESP32 SoC 芯片。用户也可选择板载 ESP32-PICO-MINI-02U 的开发板。 - * - LDO - - 5V 转 3.3V 低压差稳压器 - * - USB-to-UART - - CP2102N:单芯片 USB-to-UART 桥接器,数据传输速率可达 3 Mbps。 - * - Micro-B USB 接口 - - USB 接口。可为开发板供电,或连接 PC 进行 USB 通信。 - * - 5V Power On LED - - 开发板上电后,红色指示灯亮起。更多信息,见 `相关文档`_ 中提供的原理图。 - * - I/O Connector - - ESP32-PICO-MINI-02 上的管脚均已引出至开发板排针。用户可对 ESP32 进行编程,实现 PWM、ADC、DAC、I2C、I2S、SPI 等功能。更多信息,见章节 `管脚描述`_。 - * - BOOT 按键 - - 下载按键。按下 **Boot** 键并保持,同时按下 **EN** 键将进入固件下载模式,通过串口下载固件。 - * - EN 按键 - - 复位按键。 - - -应用开发 ---------- - -上电前,请确保 ESP32-PICO-DevKitM-2 完好无损。 - - -所需硬件 -""""""""""" - -- 1 x ESP32-PICO-DevKitM-2 开发板 -- 1 x USB 2.0 A 转 Micro B 数据线 -- 1 x PC,运行 Windows、Linux 或 macOS 系统 - - -.. _user-guide-pico-devkitm-2-software-setup: - -软件配置 -""""""""""" - -请前往 :doc:`../../get-started/index`,在 :ref:`get-started-step-by-step` 一节查看如何快速配置开发环境,将应用程序烧录至 ESP32-PICO-DevKitM-2 开发板。 - - -内含组件和包装方式 -=================== - -零售订单 ----------- - -如购买样品,每个 ESP32-PICO-DevKitM-2 将单独包装。 - -零售订单,请前往 https://www.espressif.com/en/contact-us/get-samples。 - - -批量订单 ------------ - -如批量购买,ESP32-PICO-DevKitM-2 开发板将以大纸板箱包装。 - -批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 - - -硬件参考 -============= - -功能框图 ------------ - -ESP32-PICO-DevKitM-2 的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp32-pico-devkitm-2-block.png - :align: center - :scale: 70% - :alt: ESP32-PICO-DevKitM-2 (click to enlarge) - :figclass: align-center - - ESP32-PICO-DevKitM-2 功能框图(点击放大) - - -供电方式 ------------- - -开发板提供以下三种供电方式,可任意选择一种: - -* Micro USB 供电(默认) -* 5V/GND 管脚供电 -* 3V3/GND 管脚供电 - -.. warning:: - - 上述供电方式只能选择一种方式,不能同时选择,否则可能会损坏开发板和/或电源。 - - -管脚描述 ---------- - -:ref:`get-started-pico-devkitm-2-board-front` 中所示的开发板两侧 I/O 管脚,其具体名称和功能见下表。管脚名称和编号与 `相关文档`_ 中原理图保持一致。 - - -Header J2 -"""""""""""" - -.. list-table:: - :widths: 5 5 5 35 - :header-rows: 1 - - * - 编号 - - 名称 - - 类型 - - 功能 - * - 1 - - IO20 - - I/O - - GPIO20 - * - 2 - - IO21 - - I/O - - GPIO21, VSPIHD, EMAC_TX_EN - * - 3 - - IO22 - - I/O - - GPIO22, VSPIWP, U0RTS, EMAC_TXD1 - * - 4 - - IO19 - - I/O - - GPIO19, VSPIQ, U0CTS, EMAC_TXD0 - * - 5 - - IO8 - - I/O - - GPIO8, SD_DATA1, HS1_DATA1, U2CTS - * - 6 - - IO7 - - I/O - - GPIO7, SD_DATA0, HS1_DATA0, U2RTS - * - 7 - - IO5 - - I/O - - GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK - * - 8 - - NC - - \- - - NC - * - 9 - - NC - - \- - - NC - * - 10 - - RXD0 - - I/O - - GPIO3, U0RXD :ref:`(见注解 1) `, CLK_OUT2 - * - 11 - - TXD0 - - I/O - - GPIO1, U0TXD :ref:`(见注解 1) `, CLK_OUT3, EMAC_RXD2 - * - 12 - - IO35 - - I - - ADC1_CH7, RTC_GPIO5 - * - 13 - - IO34 - - I - - ADC1_CH6, RTC_GPIO4 - * - 14 - - IO38 - - I - - GPIO38, ADC1_CH2, RTC_GPIO2 - * - 15 - - IO37 - - I - - GPIO37, ADC1_CH1, RTC_GPIO1 - * - 16 - - EN - - I - - CHIP_PU - * - 17 - - GND - - P - - 接地 - * - 18 - - VDD33 (3V3) - - P - - 3.3 V 供电 - - -Header J3 -""""""""""""" - -.. list-table:: - :widths: 5 5 5 35 - :header-rows: 1 - - * - 编号 - - 名称 - - 类型 - - 功能 - * - 1 - - GND - - P - - 接地 - * - 2 - - SENSOR_VP (FSVP) - - I - - GPIO36, ADC1_CH0, RTC_GPIO0 - * - 3 - - SENSOR_VN (FSVN) - - I - - GPIO39, ADC1_CH3, RTC_GPIO3 - * - 4 - - IO25 - - I/O - - GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 - * - 5 - - IO26 - - I/O - - GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 - * - 6 - - IO32 - - I/O - - 32K_XP :ref:`(见注解 2a) `, ADC1_CH4, TOUCH9, RTC_GPIO9 - * - 7 - - IO33 - - I/O - - 32K_XN :ref:`(见注解 2b) `, ADC1_CH5, TOUCH8, RTC_GPIO8 - * - 8 - - IO27 - - I/O - - GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV - * - 9 - - IO14 - - I/O - - ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 - * - 10 - - IO12 - - I/O - - ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI :ref:`(见注解 3)`, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 - * - 11 - - IO13 - - I/O - - ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER - * - 12 - - IO15 - - I/O - - ADC2_CH3, TOUCH3, RTC_GPIO13, MTDO, HSPICS0, HS2_CMD, SD_CMD, EMAC_RXD3 - * - 13 - - IO2 - - I/O - - ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 - * - 14 - - IO4 - - I/O - - ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - * - 15 - - IO0 - - I/O - - ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK - * - 16 - - VDD33 (3V3) - - P - - 3.3V 供电 - * - 17 - - GND - - P - - 接地 - * - 18 - - EXT_5V (5V) - - P - - 5V 供电 - - -.. _get-started-pico-devkitm-2-pin-notes: - -.. note:: - - 1. 该管脚已连接至板上 USB 桥接器芯片; - 2. 32.768 kHz 晶振输入输出管脚: - (a) 输入管脚; - (b) 输出管脚; - 3. ESP32-PICO-DevKitM-2 内置 SPI flash 的工作电压为 3.3 V。因此,Strapping 管脚 MTDI 在上电复位过程中应拉低。如果连接了该管脚,请确保该管脚在复位中不要拉高。 - - -管脚布局 -"""""""""""" -.. figure:: ../../../_static/esp32-pico-devkitm-2-pinout.png - :align: center - :scale: 50% - :alt: ESP32-PICO-DevKitM-2 (click to enlarge) - :figclass: align-center - - ESP32-PICO-DevKitM-2 管脚布局(点击放大) - - -硬件版本 -========== - -该开发板为最新硬件,尚未有历史版本。 - - -相关文档 -========= - -* `ESP32-PICO-MINI-02 & ESP32-PICO-MINI-02U 技术规格书 `_ (PDF) -* `乐鑫产品选型工具 `_ -* `ESP32-PICO-DevKitM-2 原理图 `_ (PDF) -* `ESP32-PICO-DevKitM-2 PCB 布局图 `_ (PDF) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32/get-started-pico-kit-1.rst b/docs/zh_CN/hw-reference/esp32/get-started-pico-kit-1.rst deleted file mode 100644 index e9681d7aef44..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-pico-kit-1.rst +++ /dev/null @@ -1,379 +0,0 @@ -ESP32-PICO-KIT-1 -***************** - -:link_to_translation:`en:[English]` - -概述 -====== - -ESP32-PICO-KIT-1 是一款基于 `ESP32 `_ 的乐鑫开发板。 - -该开发板搭载 `ESP32-PICO-V3 `_ (SiP,系统级封装)模组。ESP32-PICO-V3 具备完整的 Wi-Fi 和蓝牙功能,与其它 ESP32 系列模组相比,此模组已集成下述外围组件,无需额外安装: - -- 40 MHz 晶振 -- 4 MB flash -- 滤波电容 -- 射频匹配网络等 - -将上述组件封装至 ESP32-PICO-V3,用户无需额外购买,大大降低了安装和测试的成本,同时也增加了产品的可用性。 - -ESP32-PICO-KIT-1 开发板还集成了 USB-to-UART 桥接电路,方便开发人员直接通过 PC 的 USB 端口直接进行固件烧录和调试。 - -为方便硬件连接,ESP32-PICO-V3 上的所有 IO 信号和系统电源管脚均引出至开发板两侧焊盘 (18 x 0.1")。上述 18 个焊盘也均引出至排针,可使用杜邦线连接。 - -.. note:: - - ESP32-PICO-KIT-1 开发板默认采用排针。 - -ESP32-PICO-KIT-1 为用户提供了基于 ESP32 芯片应用开发的硬件,更加方便用户探索 ESP32 芯片的功能。 - -.. figure:: ../../../_static/esp32-pico-kit-1-overview.png - :align: center - :scale: 70% - :alt: ESP32-PICO-KIT-1 (click to enlarge) - :figclass: align-center - - ESP32-PICO-KIT-1 外观图(点击放大) - -本指南包括以下几个章节: - -- `快速入门`_:简要介绍 ESP32-PICO-KIT-1 开发板,以及上手这款开发板所需的软件配置; -- `内含组件和包装方式`_:介绍零售订单和批量订单所提供的组件及包装方式; -- `硬件参考`_:提供 ESP32-PICO-KIT-1 开发板硬件详细信息; -- `硬件版本`_:介绍硬件历史版本(如有),已知问题(如有),并提供链接至历史版本开发板的入门指南(如有); -- `相关文档`_:提供相关文档的链接。 - - -快速入门 -======== - -本节介绍了如何快速上手 ESP32-PICO-KIT-1。首先对 ESP32-PICO-KIT-1 开发板进行了简要介绍,然后在 `应用开发`_ 小节介绍如何将固件烧录至开发板。 - - -.. _get-started-pico-kit-1-board-front: - -组件描述 --------- - -ESP32-PICO-KIT-1 开发板的主要组件、接口及控制方式见下图。 - -.. figure:: ../../../_static/esp32-pico-kit-1-layout-front.png - :align: center - :scale: 90% - :alt: ESP32-PICO-KIT-1 (click to enlarge) - :figclass: align-center - - ESP32-PICO-KIT-1 开发板布局 - 正面(点击放大) - - -从左上角开始,按顺时针顺序,开发板主要组件的描述见下表。 - -.. list-table:: - :widths: 10 25 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - ESP32-PICO-V3 - - ESP32-PICO-KIT-1 开发板的板载模组 (SiP),搭载 ESP32 SoC 芯片,仅需连接天线、LC 匹配电路、去耦电容和一个 EN 信号上拉电阻即可正常工作。 - * - LDO - - 5 V 转 3.3 V 低压差稳压器 - * - USB-to-UART - - CP2102N:单芯片 USB-to-UART 桥接器,数据传输速率可达 3 Mbps。 - * - Micro-B USB - - USB 接口。可为开发板供电,或连接 PC 进行 USB 通信。 - * - 5V Power On LED - - 开发板上电后,红色指示灯亮起。更多信息,见 `相关文档`_ 中提供的原理图。 - * - I/O Connector - - ESP32-PICO-V3 上的管脚均已引出至开发板排针。用户可对 ESP32 进行编程,实现 PWM、ADC、DAC、I2C、I2S、SPI 等功能。更多信息,见章节 `管脚描述`_。 - * - BOOT 按键 - - 下载按键。按下 **Boot** 键并保持,同时按下 **EN** 键将进入固件下载模式,通过串口下载固件。 - * - EN 按键 - - 复位按键。 - - -应用开发 ---------- - -上电前,请确保 ESP32-PICO-KIT-1 完好无损。 - - -所需硬件 -"""""""" - -- 1 x ESP32-PICO-KIT-1 开发板 -- 1 x USB 2.0 A 转 Micro B 数据线 -- 1 x PC,运行 Windows、Linux 或 macOS 系统 - - -.. _user-guide-pico-kit-1-software-setup: - -软件配置 -""""""""" - -请前往 :doc:`../../get-started/index`,在 :ref:`get-started-step-by-step` 一节查看如何快速配置开发环境,将应用程序烧录至 ESP32-PICO-KIT-1 开发板。 - - -内含组件和包装方式 -==================== - -零售订单 --------- - -如购买样品,每个 ESP32-PICO-KIT-1 将单独包装。 - -零售订单,请前往 https://www.espressif.com/en/contact-us/get-samples。 - - -批量订单 --------- - -如批量购买,ESP32-PICO-KIT-1 开发板将以大纸板箱包装。 - -批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 - - -硬件参考 -======== - -功能框图 ---------- - -ESP32-PICO-KIT-1 的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp32-pico-kit-1-block.png - :align: center - :scale: 70% - :alt: ESP32-PICO-KIT-1 (click to enlarge) - :figclass: align-center - - ESP32-PICO-KIT-1 功能框图(点击放大) - - -供电选项 ---------- - -开发板提供以下三种供电方式,可任意选择一种: - -* Micro USB 供电(默认) -* 5V/GND 管脚供电 -* 3V3/GND 管脚供电 - -.. warning:: - - 上述供电方式只能选择一种方式,不能同时选择,否则可能会损坏开发板和/或电源。 - - -管脚描述 --------- - -:ref:`get-started-pico-kit-1-board-front` 中所示的开发板两侧 I/O 管脚,其具体名称和功能见下表。管脚名称和编号与 `相关文档`_ 中原理图保持一致。 - - -Header J2 -"""""""""""" - -.. list-table:: - :widths: 5 5 5 35 - :header-rows: 1 - - * - 编号 - - 名称 - - 类型 - - 功能 - * - 1 - - IO20 - - I/O - - GPIO20 - * - 2 - - IO21 - - I/O - - GPIO21, VSPIHD, EMAC_TX_EN - * - 3 - - IO22 - - I/O - - GPIO22, VSPIWP, U0RTS, EMAC_TXD1 - * - 4 - - IO19 - - I/O - - GPIO19, VSPIQ, U0CTS, EMAC_TXD0 - * - 5 - - IO8 - - I/O - - GPIO8, SD_DATA1, HS1_DATA1, U2CTS - * - 6 - - IO7 - - I/O - - GPIO7, SD_DATA0, HS1_DATA0, U2RTS - * - 7 - - IO5 - - I/O - - GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK - * - 8 - - IO10 - - I/O - - GPIO10, SD_DATA3, SPIWP, HS1_DATA3, U1TXD - * - 9 - - IO9 - - I/O - - GPIO9, SD_DATA2, SPIHD, HS1_DATA2, U1RXD - * - 10 - - RXD0 - - I/O - - GPIO3, U0RXD :ref:`(见注解 1)`, CLK_OUT2 - * - 11 - - TXD0 - - I/O - - GPIO1, U0TXD :ref:`(见注解 1)`, CLK_OUT3, EMAC_RXD2 - * - 12 - - IO35 - - I - - ADC1_CH7, RTC_GPIO5 - * - 13 - - IO34 - - I - - ADC1_CH6, RTC_GPIO4 - * - 14 - - IO38 - - I - - GPIO38, ADC1_CH2, RTC_GPIO2 - * - 15 - - IO37 - - I - - GPIO37, ADC1_CH1, RTC_GPIO1 - * - 16 - - EN - - I - - CHIP_PU - * - 17 - - GND - - P - - 接地 - * - 18 - - VDD33 (3V3) - - P - - 3.3V 供电 - - -Header J3 -""""""""" - -.. list-table:: - :widths: 5 5 5 35 - :header-rows: 1 - - * - 编号 - - 名称 - - 类型 - - 功能 - * - 1 - - GND - - P - - 接地 - * - 2 - - SENSOR_VP (FSVP) - - I - - GPIO36, ADC1_CH0, RTC_GPIO0 - * - 3 - - SENSOR_VN (FSVN) - - I - - GPIO39, ADC1_CH3, RTC_GPIO3 - * - 4 - - IO25 - - I/O - - GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 - * - 5 - - IO26 - - I/O - - GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 - * - 6 - - IO32 - - I/O - - 32K_XP :ref:`(见注解 2a)`, ADC1_CH4, TOUCH9, RTC_GPIO9 - * - 7 - - IO33 - - I/O - - 32K_XN :ref:`(见注解 2b)`, ADC1_CH5, TOUCH8, RTC_GPIO8 - * - 8 - - IO27 - - I/O - - GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV - * - 9 - - IO14 - - I/O - - ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 - * - 10 - - IO12 - - I/O - - ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI :ref:`(见注解 3)`, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 - * - 11 - - IO13 - - I/O - - ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER - * - 12 - - IO15 - - I/O - - ADC2_CH3, TOUCH3, RTC_GPIO13, MTDO, HSPICS0, HS2_CMD, SD_CMD, EMAC_RXD3 - * - 13 - - IO2 - - I/O - - ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 - * - 14 - - IO4 - - I/O - - ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - * - 15 - - IO0 - - I/O - - ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK - * - 16 - - VDD33 (3V3) - - P - - 3.3V 供电 - * - 17 - - GND - - P - - 接地 - * - 18 - - EXT_5V (5V) - - P - - 5V 供电 - - -.. _get-started-pico-kit-1-pin-notes: - -.. note:: - - 1. 该管脚已连接至板上 USB 桥接器芯片; - 2. 32.768 kHz 晶振输入输出管脚: - - (a) 输入管脚; - - (b) 输出管脚; - 3. ESP32-PICO-KIT-1 内置 SPI flash 的工作电压为 3.3 V。因此,Strapping 管脚 MTDI 在上电复位过程中应拉低。如果连接了该管脚,请确保该管脚在复位中不要拉高。 - - -管脚布局 -"""""""""""" -.. figure:: ../../../_static/esp32-pico-kit-1-pinout.png - :align: center - :scale: 50% - :alt: ESP32-PICO-KIT-1 (click to enlarge) - :figclass: align-center - - ESP32-PICO-KIT-1 管脚布局(点击放大) - - -硬件版本 -========= - -该开发板为最新硬件,尚未有历史版本。 - - -相关文档 -========= - -* `ESP32-PICO-V3 技术规格书 `_ (PDF) -* `乐鑫产品选型工具 `__ -* `ESP32-PICO-KIT-1 原理图 `_ (PDF) -* `ESP32-PICO-KIT-1 PCB 布局图 `_ (PDF) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32/get-started-pico-kit-v3.rst b/docs/zh_CN/hw-reference/esp32/get-started-pico-kit-v3.rst deleted file mode 100644 index a3bd939e6dcf..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-pico-kit-v3.rst +++ /dev/null @@ -1,80 +0,0 @@ -ESP32-PICO-KIT V3 入门指南 -======================================= - -:link_to_translation:`en:[English]` - -本指南介绍了如何开始使用 ESP32-PICO-KIT V3 迷你开发板。有关 ESP32-PICO-KIT 其他版本的介绍,请见::doc:`../../hw-reference/index`。 - - -准备工作 --------- - -* ESP32-PICO-KIT V3 迷你开发板 -* USB 2.0 线(A 型转 Micro-B 型) -* PC(Windows、Linux 或 macOS) - -你可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 - - -概述 ----- - -ESP32-PICO-KIT V3 是一款来自 `乐鑫 `_ 的迷你开发板,其核心是具有完整 Wi-Fi 和蓝牙功能的 ESP32 系列 SiP 模组 ESP32-PICO-D4。 - -ESP32-PICO-KIT 集成了 USB 转 UART 桥接电路,允许开发人员直接通过 PC 的 USB 端口进行下载和调试。 - -为了便于连接,ESP32-PICO-D4 上的所有 IO 信号和系统电源管脚均通过开发板两侧焊盘(每侧 20 个 x 0.1 英寸间隔)引出。 - - -功能说明 --------- - -ESP32-PICO-KIT V3 开发板的主要组件、接口及控制方式见下。 - -.. figure:: ../../../_static/esp32-pico-kit-v3-layout.jpg - :align: center - :alt: ESP32-PICO-KIT V3 开发板布局 - :figclass: align-center - - ESP32-PICO-KIT V3 开发板布局 - -ESP32-PICO-KIT 开发板的主要组件描述见下表。 - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - ESP32-PICO-D4 - - ESP32-PICO-KIT V3 开发板上焊接的标准 ESP32-PICO-D4 模组,集成了 ESP32 芯片的完整系统,仅需连接天线、LC 匹配电路、退耦电容和一个 EN 信号上拉电阻即可正常工作。 - * - LDO - - 5V-to-3.3V 低压差稳压器。 - * - USB-to-UART 桥接器 - - 单芯片 USB-to-UART 桥接器,可提供高达 1 Mbps 的传输速率。 - * - Micro USB 端口 - - USB 接口。可用作开发板的供电电源,或连接 PC 和开发板的通信接口。 - * - Power On LED - - 开发板通电后,该红色指示灯将亮起。 - * - I/O - - ESP32-PICO-D4 的所有管脚均已引出至开发板的排针。用户可以对 ESP32 进行编程,实现 PWM、ADC、DAC、I2C、I2S、SPI 等多种功能。 - * - BOOT - - 下载按键。按下 **Boot** 键并保持,同时按一下 **EN** 键(此时不要松开 **Boot** 键)进入“固件下载”模式,通过串口下载固件。 - * - EN - - 复位按键。 - - -应用程序开发 ------------- - -ESP32-PICO-KIT V3 上电前,请首先确认开发板完好无损。 - -现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至你的开发板。 - - -相关文档 ------------------ - -* `ESP32-PICO-KIT V3 原理图 `_ (PDF) -* `《ESP32-PICO-D4 技术规格书》 `_ (PDF) -* :doc:`../../hw-reference/index` diff --git a/docs/zh_CN/hw-reference/esp32/get-started-pico-kit.rst b/docs/zh_CN/hw-reference/esp32/get-started-pico-kit.rst deleted file mode 100644 index 2683d0b24da2..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-pico-kit.rst +++ /dev/null @@ -1,247 +0,0 @@ -ESP32-PICO-KIT V4/V4.1 入门指南 -======================================================= - -:link_to_translation:`en:[English]` - -本指南介绍了如何开始使用 ESP32-PICO-KIT V4/V4.1 迷你开发板。有关 ESP32-PICO-KIT 其他版本的介绍,请见::doc:`../../hw-reference/index`。 - -本指南仅适用于 ESP32-PICO-KIT V4 和 V4.1。ESP32-PICO-KIT V4.1 与 V4 的最大差别在于桥接器,其中 V4 搭载的 CP2102 USB-to-UART 桥接器最高速率为 1 Mbps,V4.1 搭载的 CP2102N 桥接器最高传输速率 3 Mbps。 - - -准备工作 --------- - -* :ref:`ESP32-PICO-KIT 迷你开发板 ` -* USB 2.0 线(A 型转 Micro-B 型) -* PC(Windows、Linux 或 macOS) - -你可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 - - -概述 ----- - -ESP32-PICO-KIT 是一款来自 `乐鑫 `_ 的迷你开发板。 - -该开发板的核心是具有完整 Wi-Fi 和蓝牙功能的 ESP32 系列 SiP 模组 ESP32-PICO-D4。与其他 ESP32 系列模组相比,ESP32-PICO-D4 模组已完整集成以下外围器件: - -- 40 MHz 晶体振荡器 -- 4 MB flash -- 滤波电容 -- 射频匹配网络等 - -这大大降低了用户额外采购和安装这些元器件的数量和成本,及额外组装测试的复杂度,并增加了可用性。 - -ESP32-PICO-KIT 集成了 USB 转 UART 桥接电路,允许开发人员直接通过 PC 的 USB 端口进行下载和调试。 - -为了便于连接,ESP32-PICO-D4 上的所有 IO 信号和系统电源管脚均通过开发板两侧焊盘(每侧 20 个 x 0.1 英寸间隔)引出。为了方便杜邦线的使用,ESP32-PICO-KIT 开发板每侧的 20 个焊盘中,有 17 个引出至排针,另外 3 个靠近天线的焊盘未引出,可供用户日后焊接使用。 - -.. note:: - - 1. ESP32-PICO-D4 开发板目前有两种版本,分别采用排针与排母。本指南默认以排针版本为例。 - 2. 每排未引出至排针的 3 个管脚已连接至 ESP32-PICO-D4 SiP 模组的内置 flash 模块。更多信息,请见 `相关文档`_ 中的模组技术规格书。 - - -功能概述 --------- - -ESP32-PICO-KIT 开发板的主要组件和连接方式见下。 - -.. figure:: ../../../_static/esp32-pico-kit-v4-functional-block-diagram.png - :align: center - :alt: ESP32-PICO-KIT 功能框图 - :figclass: align-center - - ESP32-PICO-KIT 框图 - - -功能说明 --------- - -ESP32-PICO-KIT 开发板的主要组件、接口及控制方式见下。 - -.. _get-started-pico-kit-v4-board-front: - -.. figure:: ../../../_static/esp32-pico-kit-v4.1-f-layout.jpeg - :align: center - :alt: ESP32-PICO-KIT 开发板布局(排母版) - :figclass: align-center - - ESP32-PICO-KIT 开发板布局(排母版) - -ESP32-PICO-KIT 开发板的主要组件描述见下表(从左上角起顺时针顺序)。 - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - ESP32-PICO-D4 - - ESP32-PICO-KIT 开发板上焊接的标准 ESP32-PICO-D4 模组,集成了 ESP32 芯片的完整系统,仅需连接天线、LC 匹配电路、退耦电容和一个 EN 信号上拉电阻即可正常工作。 - * - LDO - - 5V-to-3.3V 低压差稳压器 - * - USB-to-UART 桥接器 - - 单芯片 USB-to-UART 桥接器。V4 版本搭载的 CP2102 可提供高达 1 Mbps 的传输速率,V4.1 版本搭载的 CP2102N 可提供高达 3 Mbps 的传输速率。 - * - Micro USB 端口 - - USB 接口。可用作开发板的供电电源,或连接 PC 和开发板的通信接口。 - * - 5V Power On LED - - 开发板通电后,该红色指示灯将亮起。更多信息,请见 `相关文档`_ 中的原理图。 - * - I/O - - ESP32-PICO-D4 的所有管脚均已引出至开发板的排针。用户可以对 ESP32 进行编程,实现 PWM、ADC、DAC、I2C、I2S、SPI 等多种功能。更多详情,请见章节 `管脚说明`_。 - * - BOOT - - 下载按键。按下 **Boot** 键并保持,同时按一下 **EN** 键(此时不要松开 **Boot** 键)进入“固件下载”模式,通过串口下载固件。 - * - EN - - 复位按键。 - - -电源选项 --------- - -开发板可任一选用以下三种供电方式: - -* Micro USB 供电(默认) -* 5V / GND 管脚供电 -* 3V3 / GND 管脚供电 - -.. warning:: - - 上述供电模式 **不可同时连接**,否则可能会损坏开发板和/或电源。 - - -管脚说明 ----------- - -下表介绍了开发板 I/O 管脚的 **名称** 和 **功能**,具体布局请见 `相关文档`_ 中的原理图。请参考 :ref:`get-started-pico-kit-v4-board-front`。 - - -Header J2 -""""""""" - -====== ================= ====== ====================================================== -编号 名称 类型 功能 -====== ================= ====== ====================================================== -1 FLASH_SD1 (FSD1) I/O | GPIO8, SD_DATA1, SPID, HS1_DATA1 :ref:`(见说明 1) ` , U2CTS -2 FLASH_SD3 (FSD3) I/O | GPIO7, SD_DATA0, SPIQ, HS1_DATA0 :ref:`(见说明 1) ` , U2RTS -3 FLASH_CLK (FCLK) I/O | GPIO6, SD_CLK, SPICLK, HS1_CLK :ref:`(见说明 1) ` , U1CTS -4 IO21 I/O | GPIO21, VSPIHD, EMAC_TX_EN -5 IO22 I/O | GPIO22, VSPIWP, U0RTS, EMAC_TXD1 -6 IO19 I/O | GPIO19, VSPIQ, U0CTS, EMAC_TXD0 -7 IO23 I/O | GPIO23, VSPID, HS1_STROBE -8 IO18 I/O | GPIO18, VSPICLK, HS1_DATA7 -9 IO5 I/O | GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK -10 IO10 I/O | GPIO10, SD_DATA3, SPIWP, HS1_DATA3, U1TXD -11 IO9 I/O | GPIO9, SD_DATA2, SPIHD, HS1_DATA2, U1RXD -12 RXD0 I/O | GPIO3, U0RXD :ref:`(见说明 3) ` , CLK_OUT2 -13 TXD0 I/O | GPIO1, U0TXD :ref:`(见说明 3) ` , CLK_OUT3, EMAC_RXD2 -14 IO35 I | ADC1_CH7, RTC_GPIO5 -15 IO34 I | ADC1_CH6, RTC_GPIO4 -16 IO38 I | GPIO38, ADC1_CH2, RTC_GPIO2 -17 IO37 I | GPIO37, ADC1_CH1, RTC_GPIO1 -18 EN I | CHIP_PU -19 GND P | Ground -20 VDD33 (3V3) P | 3.3V 电源 -====== ================= ====== ====================================================== - - -Header J3 -""""""""" - -====== ================= ====== ====================================================== -No. Name Type Function -====== ================= ====== ====================================================== -1 FLASH_CS (FCS) I/O | GPIO16, HS1_DATA4 :ref:`(见说明 1) ` , U2RXD, EMAC_CLK_OUT -2 FLASH_SD0 (FSD0) I/O | GPIO17, HS1_DATA5 :ref:`(见说明 1) ` , U2TXD, EMAC_CLK_OUT_180 -3 FLASH_SD2 (FSD2) I/O | GPIO11, SD_CMD, SPICS0, HS1_CMD :ref:`(见说明 1) ` , U1RTS -4 SENSOR_VP (FSVP) I | GPIO36, ADC1_CH0, RTC_GPIO0 -5 SENSOR_VN (FSVN) I | GPIO39, ADC1_CH3, RTC_GPIO3 -6 IO25 I/O | GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 -7 IO26 I/O | GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 -8 IO32 I/O | 32K_XP :ref:`(见说明 2a) ` , ADC1_CH4, TOUCH9, RTC_GPIO9 -9 IO33 I/O | 32K_XN :ref:`(见说明 2b) ` , ADC1_CH5, TOUCH8, RTC_GPIO8 -10 IO27 I/O | GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17 - | EMAC_RX_DV -11 IO14 I/O | ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, - | HS2_CLK, SD_CLK, EMAC_TXD2 -12 IO12 I/O | ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI :ref:`(见说明 4) ` , HSPIQ, - | HS2_DATA2, SD_DATA2, EMAC_TXD3 -13 IO13 I/O | ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, - | HS2_DATA3, SD_DATA3, EMAC_RX_ER -14 IO15 I/O | ADC2_CH3, TOUCH3, RTC_GPIO13, MTDO, HSPICS0 - | HS2_CMD, SD_CMD, EMAC_RXD3 -15 IO2 I/O | ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, - | HS2_DATA0, SD_DATA0 -16 IO4 I/O | ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, - | HS2_DATA1, SD_DATA1, EMAC_TX_ER -17 IO0 I/O | ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1 - | EMAC_TX_CLK -18 VDD33 (3V3) P | 3.3V 电源 -19 GND P | Ground -20 EXT_5V (5V) P | 5V 电源 -====== ================= ====== ====================================================== - - -.. _get-started-pico-kit-v4-pin-notes: - -.. note:: - - 1. 该管脚已连接至 ESP32-PICO-D4 的内置 flash 管脚。 - 2. 32.768 kHz 晶振:(a) 输入;(b) 输出。 - 3. 该管脚已连接至开发板的 USB 桥接器芯片。 - 4. ESP32-PICO-KIT 内置 SPI flash 的工作电压为 3.3 V。因此,strapping 管脚 MTDI 在模组上电复位过程中应保持低电平。如连接该管脚,请确保该管脚在复位中不要保持高电平。 - - -管脚布局 -^^^^^^^^^^^ -.. figure:: ../../../_static/esp32-pico-kit-v4-pinout.png - :align: center - :scale: 43% - :alt: ESP32-PICO-KIT 管脚布局(点击放大) - - ESP32-PICO-KIT 管脚布局(点击放大) - - -应用程序开发 ------------- - -ESP32-PICO-KIT 上电前,请首先确认开发板完好无损。 - -现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至你的开发板。 - - -开发板尺寸 ----------- - -ESP32-PICO-KIT 的尺寸为 52 x 20.3 x 10 mm (2.1" x 0.8" x 0.4")。 - -.. figure:: ../../../_static/esp32-pico-kit-v4.1-dimensions-back.jpg - :align: center - :alt: ESP32-PICO-KIT 尺寸图 -- 背面(排针版) - :figclass: align-center - - ESP32-PICO-KIT 尺寸图 -- 背面(排针版) - -.. figure:: ../../../_static/esp32-pico-kit-v4-dimensions-side.jpg - :align: center - :alt: ESP32-PICO-KIT V4 尺寸图 -- 侧面(排针版) - :figclass: align-center - - ESP32-PICO-KIT 尺寸图 -- 侧面(排针版) - -有关开发板的物理结构细节,请见下方参考设计。 - - -相关文档 ------------------ - -* `ESP32-PICO-KIT V4 原理图 `_ (PDF) -* `ESP32-PICO-KIT V4.1 原理图 `_ (PDF) -* `ESP32-PICO-KIT 参考设计 `_ ,内含 OrCAD 原理图、PCB 布局、Gerbers 和 BOM 表 -* `《ESP32-PICO-D4 技术规格书》 `_ (PDF) -* :doc:`../../hw-reference/index` - - -.. toctree:: - :hidden: - - get-started-pico-kit-v3 diff --git a/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit-v2.rst b/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit-v2.rst deleted file mode 100644 index 0aa7d1f170f5..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit-v2.rst +++ /dev/null @@ -1,199 +0,0 @@ -ESP-WROVER-KIT V2 入门指南 -=========================================== - -:link_to_translation:`en:[English]` - -本指南介绍了如何开始使用 ESP-WROVER-KIT V2 开发板及其功能和相关配置。有关 ESP-WROVER-KIT 其他版本的介绍,请见 :doc:`../../hw-reference/index`。 - - -准备工作 -------------- - -* ESP-WROVER-KIT V2 开发板 -* USB 数据线(A 转 Micro-B) -* PC(Windows、Linux 或 macOS) - -你可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 - - -概述 --------- - -ESP-WROVER-KIT 是 `乐鑫 `_ 一款基于 ESP32 的开发板,集成了 LCD 屏幕和 microSD 卡槽。 - -ESP-WROVER-KIT 可选贴以下 ESP32 模组: - -- ESP32-WROOM-32 -- ESP32-WROVER 系列模组 - -此外,ESP-WROVER-KIT 的独特之处在于集成了一款先进多协议 USB 桥接器 (FTDI FT2232HL),允许开发人员直接通过 USB 接口,使用 JTAG 对 ESP32 进行调试,无需额外的 JTAG 调试器。ESP-WROVER-KIT 可为开发人员提供简单、便捷且极具成本效益的开发体验。 - -为了便于使用,板上模组的绝大部分管脚均已引出至开发板的引脚。 - -.. note:: - - ESP-WROVER-KIT V2 板载 ESP32-WROVER 模组的 GPIO16 和 GPIO17 管脚用作 PSRAM 的片选和时钟信号。默认情况下,为了给用户提供可靠的性能,这两个 GPIO 管脚不引出至开发板引脚。 - - -功能概述 ----------------------- - -ESP-WROVER-KIT 开发板的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp-wrover-kit-block-diagram.png - :align: center - :alt: ESP-WROVER-KIT 功能框图 - :figclass: align-center - - ESP-WROVER-KIT 功能框图 - - -功能说明 ----------------------- - -ESP-WROVER-KIT 开发板的主要组件、接口及控制方式见下。 - -.. _get-started-esp-wrover-kit-v2-board-front: - -.. figure:: ../../../_static/esp-wrover-kit-v2-layout-front.png - :align: center - :alt: ESP-WROVER-KIT 开发板布局 -- 俯视图 - :figclass: align-center - - ESP-WROVER-KIT 开发板布局 -- 俯视图 - -.. _get-started-esp-wrover-kit-v2-board-back: - -.. figure:: ../../../_static/esp-wrover-kit-v2-layout-back.png - :align: center - :alt: ESP-WROVER-KIT 开发板布局 -- 仰视图 - :figclass: align-center - - ESP-WROVER-KIT 开发板布局 -- 仰视图 - - -下表介绍了开发板的主要组件,顺序如下: - -- 从图片右上角开始,以顺时针顺序介绍了图 1 中的主要组件 -- 然后以同样的顺序介绍了图 2 中的主要组件 - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - 32.768 kHz - - 外接 32.768 kHz 晶振,可提供 Deep-sleep 下使用的低功耗时钟。 - * - ESP32 模组 - - 可选贴 ESP32-WROOM-32 或 ESP32-WROVER。ESP32-WROVER 模组完整集成了 ESP32-WROOM-32 的所有功能,且内置 32-Mbit PSRAM,可提供灵活的额外存储空间和数据处理能力。 - * - CTS/RTS - - 串口流控信号。管脚默认不连接至电路。为了使能该功能,必须用跳线帽短路掉 JP14 的相应管脚。 - * - UART - - 串口。FT2232HL 和 ESP32 的串行 TX/RX 信号已引出至 JP11 的两端。默认情况下,这两路信号由跳线帽连接。如果要跳过 FT2232 使用 ESP32 模组串口,则可移除相关跳线帽,将模组连接至其他外部串口设备。 - * - SPI - - 默认情况下,ESP32 使用 SPI 接口访问内置 flash 和 PSRAM。使用这些引脚连接 ESP32 和其他 SPI 设备。这种情况下,需增加额外的片选 (CS) 信号。注意,选贴 ESP32-WROVER 模组时,该接口的工作电压为 1.8 V;选贴 ESP32-WROOM-32 时,该接口的工作电压为 3.3 V。 - * - JTAG - - JTAG 接口。FT2232HL 和 ESP32 的 JTAG 信号已引出至 JP8 的两端。默认情况下,这两路信号不连接。如需使能 JTAG,请按照 `设置选项`_ 的介绍,连接跳线帽。 - * - FT2232 - - FT2232 多协议 USB 转串口桥接器。开发人员可通过 USB 接口对 FT2232 芯片进行控制和编程,与 ESP32 建立连接。FT2232 具有 USB-to-UART 和 USB-to-JTAG 功能。 - * - EN - - 复位按键。 - * - Boot - - 下载按键。按下 **Boot** 键并保持,同时按一下 **EN** 键(此时不要松开 **Boot** 键)进入“固件下载”模式,通过串口下载固件。 - * - USB - - USB 接口。可用作开发板的供电电源,或连接 PC 和开发板的通信接口。 - * - 电源选择开关 - - ESP-WROVER-KIT 开发板可通过 USB 端口或 5 V 输入接口供电。用户可使用跳线帽在两种供电模式中进行选择。更多详细信息,请见章节 `设置选项`_ 中有关 JP7 连接器的描述。 - * - 电源开关 - - 拨向 **USB** 按键一侧,开发板上电;拨离 **USB** 按键一侧,开发板掉电。 - * - 5V Input - - 5 V 电源接口建议仅在开发板自动运行(未连接 PC)时使用。仅用于全负荷工作下的后备电源。 - * - LDO - - 5V-to-3.3V 低压差线型稳压器 NCP1117(1A)。NCP1117 最大电流输出为 1 A。板上 LDO 为固定输出电压,但用户也可以选用具有可变输出电压的 LDO。更多信息,请见 `ESP-WROVER-KIT V2 原理图`_。 - * - 摄像头 - - 摄像头接口,支持标准 OV7670 摄像头模块。 - * - RGB LED - - 红绿蓝发光二极管,可由 PWM(脉冲宽度调制)控制。 - * - I/O - - 板上模组的所有管脚均已引出至开发板的排针。用户可以对 ESP32 进行编程,实现 PWM、ADC、DAC、I2C、I2S、SPI 等多种功能。 - * - microSD 卡槽 - - microSD 卡槽,可扩充存储空间:当 ESP32 进入下载模式时,GPIO2 不可处于高电平。然而,为了使能 microSD 卡功能,需为 GPIO2 增加一个上拉电阻。默认情况下,GPIO2 和上拉电阻 R153 处于断开状态。为了使能 microSD 卡,请按照 `设置选项`_ 章节的要求,连接 JP1 连接器。 - * - LCD 显示屏 - - 支持贴装一款 3.2” 的 SPI(标准四线串行外设接口)LCD 显示器,请见 :ref:`get-started-esp-wrover-kit-v2-board-back`。 - - -.. _get-started-esp-wrover-kit-v2-setup-options: - -设置选项 -------------- - -用户可通过 5 组排针,设置开发板功能,其中常见功能见下表: - -======= ================ ===================================================================================== -排针 跳线设置 功能描述 -======= ================ ===================================================================================== -JP1 |jp1-sd_io2| 使能 microSD Card 功能的上拉电阻 -JP1 |jp1-both| 确保开发板处于下载模式时,GPIO2 时钟处于低位(将 JP1 连接至 GPIO0) -JP7 |jp7-ext_5v| 使用外部电源为 ESP-WROVER-KIT 开发板供电 -JP7 |jp7-usb_5v| 使用 USB 端口为 ESP-WROVER-KIT 开发板供电 -JP8 |jp8| 使能 JTAG 功能 -JP11 |jp11-tx-rx| 使能 UART 通信 -JP14 |jp14| 使能 RTS/CTS 串口流控 -======= ================ ===================================================================================== - - -.. _get-started-esp-wrover-kit-v2-start-development: - -应用程序开发 ------------------------------ - -ESP-WROVER-KIT 上电前,请首先确认开发板完好无损。 - - -初始设置 -^^^^^^^^^^^^^ - -请严格按照下图所示连接跳线帽,注意不要额外连接其他跳线帽。 - -- 使用 JP7 连接器,选择 USB 为开发板供电。 - -- 使用 JP11 连接器,使能 UART 通信。 - -======================== ========================== -USB 供电 使能 UART 通信 -======================== ========================== -|jp7-usb_5v| |jp11-tx-rx| -======================== ========================== - -注意不要连接其他跳线帽。 - -打开 **电源开关**,**5V Power On LED** 应点亮。 - - -正式开始开发 -^^^^^^^^^^^^^^^^^^ - -现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至你的开发板。 - - -相关文档 ------------------ - -* `ESP-WROVER-KIT V2 原理图`_ (PDF) -* `《ESP32 技术规格书》 `_ (PDF) -* `《ESP32-WROVER 技术规格书》 `_ (PDF) -* `《ESP32-WROOM-32 技术规格书》 `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - - -.. |jp1-sd_io2| image:: ../../../_static/wrover-jp1-sd_io2.png -.. |jp1-both| image:: ../../../_static/wrover-jp1-both.png -.. |jp7-ext_5v| image:: ../../../_static/wrover-jp7-ext_5v.png -.. |jp7-usb_5v| image:: ../../../_static/wrover-jp7-usb_5v.png -.. |jp8| image:: ../../../_static/wrover-jp8.png -.. |jp11-tx-rx| image:: ../../../_static/wrover-jp11-tx-rx.png -.. |jp14| image:: ../../../_static/wrover-jp14.png - -.. _ESP-WROVER-KIT V2 原理图: https://dl.espressif.com/dl/schematics/ESP-WROVER-KIT_SCH-2.pdf diff --git a/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit-v3.rst b/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit-v3.rst deleted file mode 100644 index b34315cb0aba..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit-v3.rst +++ /dev/null @@ -1,384 +0,0 @@ -ESP-WROVER-KIT V3 入门指南 -======================================= - -:link_to_translation:`en:[English]` - -本指南介绍了如何开始使用 ESP-WROVER-KIT V3 开发板及其功能和相关配置。有关 ESP-WROVER-KIT 其他版本的介绍,请见::doc:`../../hw-reference/index`。 - - -准备工作 -------------- - -* :ref:`ESP-WROVER-KIT V3 开发板 ` -* USB 数据线(A 转 Micro-B) -* PC(Windows、Linux 或 macOS) - -你可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 - - -概述 --------- - -ESP-WROVER-KIT 是 `乐鑫 `_ 一款基于 ESP32 的开发板,集成了 LCD 屏幕和 micro SD 卡槽。 - -ESP-WROVER-KIT 可选贴以下 ESP32 模组: - -- ESP32-WROOM-32 -- ESP32-WROVER 系列模组 - -此外,ESP-WROVER-KIT 的独特之处在于集成了一款先进多协议 USB 桥接器 (FTDI FT2232HL),允许开发人员直接通过 USB 接口,使用 JTAG 对 ESP32 进行调试,无需额外的 JTAG 调试器。ESP-WROVER-KIT 可为开发人员提供简单、便捷且极具成本效益的开发体验。 - -为了便于使用,板上模组的绝大部分管脚均已引出至开发板的引脚。 - -.. note:: - - 该版本 ESP32-WROVER 模组 的 GPIO16 和 GPIO17 管脚用作 PSRAM 的片选和时钟信号。默认情况下,为了给用户提供可靠的性能,这两个 GPIO 管脚不引出至开发板引脚。 - - -功能概述 ----------------------- - -ESP-WROVER-KIT 开发板的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp-wrover-kit-block-diagram.png - :align: center - :alt: ESP-WROVER-KIT 功能框图 - :figclass: align-center - - ESP-WROVER-KIT 功能框图 - - -功能说明 ----------------------- - -ESP-WROVER-KIT 开发板的主要组件、接口及控制方式见下。 - -.. _get-started-esp-wrover-kit-v3-board-front: - -.. figure:: ../../../_static/esp-wrover-kit-v3-layout-front.jpg - :align: center - :alt: ESP-WROVER-KIT 开发板布局 -- 俯视图 - :figclass: align-center - - ESP-WROVER-KIT 开发板布局 -- 俯视图 - -.. _get-started-esp-wrover-kit-v3-board-back: - -.. figure:: ../../../_static/esp-wrover-kit-v3-layout-back.jpg - :align: center - :alt: ESP-WROVER-KIT 开发板布局 -- 仰视图 - :figclass: align-center - - ESP-WROVER-KIT 开发板布局 -- 仰视图 - - -下表介绍了开发板的主要组件,顺序如下: - -- 从图片右上角开始,以顺时针顺序介绍了图 1 中的主要组件 -- 然后以同样的顺序介绍了图 2 中的主要组件 - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - 32.768 kHz - - 外接 32.768 kHz 晶振,可提供 Deep-sleep 下使用的低功耗时钟。 - * - 0 欧电阻 - - ESP-WROVER-KIT 开发板设计了一个 0 欧电阻,可在测量 ESP32 系列模组在不同功耗模式下的电流时,直接移除或替换为分流器。 - * - ESP32 模组 - - 可选贴 ESP32-WROOM-32 或 ESP32-WROVER。ESP32-WROVER 模组完整集成了 ESP32-WROOM-32 的所有功能,且内置 32-Mbit PSRAM,可提供灵活的额外存储空间和数据处理能力。 - * - FT2232 - - FT2232 多协议 USB 转串口桥接器。开发人员可通过 USB 接口对 FT2232 芯片进行控制和编程,与 ESP32 建立连接。FT2232 芯片可在通道 A 提供 USB-to-JTAG 接口功能,并在通道 B 提供 USB-to-Serial 接口功能,便利开发人员的应用开发与调试。见 `ESP-WROVER-KIT V3 原理图`_。 - * - UART - - 串口。FT2232HL 和 ESP32 的串行 TX/RX 信号已引出至 JP11 的两端。默认情况下,这两路信号由跳线帽连接。如果要跳过 FT2232 使用 ESP32 模组串口,则可移除相关跳线帽,将模组连接至其他外部串口设备。 - * - SPI - - 默认情况下,ESP32 使用 SPI 接口访问内置 flash 和 PSRAM。使用这些引脚连接 ESP32 和其他 SPI 设备。这种情况下,需增加额外的片选 (CS) 信号。注意,选贴 ESP32-WROVER 模组时,该接口的工作电压为 1.8 V;选贴 ESP32-WROOM-32 时,该接口的工作电压为 3.3 V。 - * - CTS/RTS - - 串口流控信号。管脚默认不连接至电路。为了使能该功能,必须用跳线帽短路掉 JP14 的相应管脚。 - * - JTAG - - JTAG 接口。FT2232HL 和 ESP32 的 JTAG 信号已引出至 JP8 的两端。默认情况下,这两路信号不连接。如需使能 JTAG,请按照 `设置选项`_ 的介绍,连接跳线帽。 - * - EN - - 复位按键。 - * - Boot - - 下载按键。按下 **Boot** 键并保持,同时按一下 **EN** 键(此时不要松开 **Boot** 键)进入“固件下载”模式,通过串口下载固件。 - * - USB - - USB 接口。可用作开发板的供电电源,或连接 PC 和开发板的通信接口。 - * - 电源开关 - - 拨向 **USB** 按键一侧,开发板上电;拨离 **USB** 按键一侧,开发板掉电。 - * - 电源选择开关 - - ESP-WROVER-KIT 开发板可通过 USB 端口或 5V 输入接口供电。用户可使用跳线帽在两种供电模式中进行选择。更多详细信息,请见章节 `设置选项`_ 中有关 JP7 连接器的描述。 - * - 5V Input - - 5V 电源接口建议仅在开发板自动运行(未连接 PC)时使用。仅用于全负荷工作下的后备电源。 - * - LDO - - 5V-to-3.3V 低压差线型稳压器 NCP1117(1A)。NCP1117 最大电流输出为 1 A。板上 LDO 为固定输出电压,但用户也可以选用具有可变输出电压的 LDO。更多信息,请见 `ESP-WROVER-KIT V3 原理图`_。 - * - 摄像头 - - 摄像头接口,支持标准 OV7670 摄像头模块。 - * - RGB LED - - 红绿蓝发光二极管,可由 PWM(脉冲宽度调制)控制。 - * - I/O - - 板上模组的所有管脚均已引出至开发板的排针。用户可以对 ESP32 进行编程,实现 PWM、ADC、DAC、I2C、I2S、SPI 等多种功能。 - * - microSD 卡槽 - - 适用于需要扩充数据存储空间或进行备份的应用开发场景。 - * - LCD 显示屏 - - 支持贴装一款 3.2” 的 SPI(标准四线串行外设接口)LCD 显示器,请见 :ref:`get-started-esp-wrover-kit-v3-board-back`。 - - -.. _get-started-esp-wrover-kit-v3-setup-options: - -设置选项 -------------- - -用户可通过 5 组排针,设置开发板功能,其中常见功能见下表: - -======= ================ ========================================================================= -排针 跳线设置 功能描述 -======= ================ ========================================================================= -JP7 |jp7-ext_5v| 使用外部电源为 ESP-WROVER-KIT 开发板供电 -JP7 |jp7-usb_5v| 使用 USB 端口为 ESP-WROVER-KIT 开发板供电 -JP8 |jp8| 使能 JTAG 功能 -JP11 |jp11-tx-rx| 使能 UART 通信 -JP14 |jp14| 使能 RTS/CTS 串口流控 -======= ================ ========================================================================= - - -ESP32 管脚分配 ------------------------- - -ESP32 模组的部分管脚/终端已被板上组件占用或用于外部硬件设备。如果某管脚对应的特定硬件未连接,则该管脚可用作他用。比如,摄像头/JP4 排针未连接相应硬件,则这些 GPIO 可用于其他用途。 - -部分管脚具备多个功能,可供板上组件或外部硬件设备同时使用,比如 GPIO0 和 GPIO2。由于管脚限制,一些外围设备不可同时使用,比如,由于 JTAG 和 SD 卡槽需共用部分管脚,因此一些使用 SD 卡功能的应用无法同时进行 JTAG 调试。 - -其他情况下,不同外设可同时使用。比如,LCD 屏幕和 SD 卡仅共用一个 GPIO21 管脚,可以同时使用。该管脚可为 LCD 屏幕提供 D/C(数据/控制)信号,并用于读取来自 SD 卡槽的 CD 信号(卡检测信号)。如无需使用卡检测功能,开发人员还可以通过移除 R167 来禁用该功能。此时,LCD 和 SD 卡槽可同时使用。 - -更多外设共享管脚的介绍,请见下一章节中的表格。 - - -主要 I/O 连接器/JP1 -^^^^^^^^^^^^^^^^^^^^^^^^ - -JP1 连接器包括 14 x 2 个排针,具体功能可见下表中间 “I/O” 列的介绍。两侧的“共用”列则介绍了这些管脚在板上的其他用途。 - -===================== ===== ===== ===================== -共用 I/O I/O 共用 -===================== ===== ===== ===================== -n/a 3.3V GND n/a -NC/XTAL IO32 IO33 NC/XTAL -JTAG, microSD IO12 IO13 JTAG, microSD -JTAG, microSD IO14 IO27 摄像头 -摄像头 IO26 IO25 摄像头,LCD -摄像头 IO35 IO34 摄像头 -摄像头 IO39 IO36 摄像头 -JTAG EN IO23 摄像头,LCD -摄像头,LCD IO22 IO21 摄像头,LCD,microSD -摄像头,LCD IO19 IO18 摄像头,LCD -摄像头,LCD IO5 IO17 PSRAM -PSRAM IO16 IO4 LED,摄像头,microSD -摄像头,LED,Boot IO0 IO2 LED,microSD -JTAG,microSD IO15 5V -===================== ===== ===== ===================== - -说明: - -* NC/XTAL - :ref:`32.768 kHz Oscillator ` -* JTAG - :ref:`JTAG/JP8 ` -* Boot - Boot 按键/SW2 -* 摄像头 - :ref:`摄像头/JP4 ` -* LED - :ref:`RGB LED ` -* microSD - :ref:`microSD Card / J4 ` -* LCD - :ref:`LCD/U5 ` -* PSRAM - 仅适用于选贴 ESP32-WROVER 的情况。 - - -.. _get-started-esp-wrover-kit-v3-xtal: - -32.768 kHz 晶振 -^^^^^^^^^^^^^^^^^^^^^ - -==== ========== -. ESP32 管脚 -==== ========== -1. GPIO32 -2. GPIO33 -==== ========== - -.. note:: - - 默认情况下,管脚 GPIO32 和 GPIO33 已连接至晶振。因此,为了保证信号的完整性,这两个管脚并未连接至 JP1 I/O 连接器。用户可通过将 R11/R23 处的 0 欧电阻移至 R12/R24 处,以将 GP1O32 和 GPIO33 的连接从晶振移至 JP1。 - - -.. _get-started-esp-wrover-kit-v3-spi-flash-header: - -SPI Flash/JP13 -^^^^^^^^^^^^^^^^ - -==== ============= -. ESP32 管脚 -==== ============= -1. CLK/GPIO6 -2. SD0/GPIO7 -3. SD1/GPIO8 -4. SD2/GPIO9 -5. SD3/GPIO10 -6. CMD/GPIO11 -==== ============= - -.. important:: - - 模组的 flash 总线已通过 0 欧电阻 R140 ~ R145 连接至排针 JP13。如果需要将 flash 的工作频率控制在 80 MHz,为了达到保证总线信号完整性等目的,建议移除 R140 ~ R145 电阻,将模组的 flash 总线与排针 JP2 断开。 - - -.. _get-started-esp-wrover-kit-v3-jtag-header: - -JTAG/JP8 -^^^^^^^^^^ - -==== ============== ============= -. ESP32 管脚 JTAG 信号 -==== ============== ============= -1. EN TRST_N -2. MTMS/GPIO14 TMS -3. MTDO/GPIO15 TDO -4. MTDI/GPIO12 TDI -5. MTCK/GPIO13 TCK -==== ============== ============= - - -.. _get-started-esp-wrover-kit-v3-camera-header: - -摄像头/JP4 -^^^^^^^^^^^^ - -==== ========== ============================= -. ESP32 管脚 摄像头信号 -==== ========== ============================= -1. n/a 3.3V -2. n/a 地 -3. GPIO27 SIO_C/SCCB 时钟 -4. GPIO26 SIO_D/SCCB 数据 -5. GPIO25 VSYNC/垂直同步 -6. GPIO23 HREF/水平参考 -7. GPIO22 PCLK/像素时钟 -8. GPIO21 XCLK/系统时钟 -9. GPIO35 D7/像素数据 Bit 7 -10. GPIO34 D6/像素数据 Bit 6 -11. GPIO39 D5/像素数据 Bit 5 -12. GPIO36 D4/像素数据 Bit 4 -13. GPIO19 D3/像素数据 Bit 3 -14. GPIO18 D2/像素数据 Bit 2 -15. GPIO5 D1/像素数据 Bit 1 -16. GPIO4 D0/像素数据 Bit 0 -17. GPIO0 RESET/摄像头复位 -18. n/a PWDN/摄像头断电 -==== ========== ============================= - -* D0 到 D7 为摄像头的数据总线 - - -.. _get-started-esp-wrover-kit-v3-rgb-led-connections: - -RGB LED -^^^^^^^ - -==== ========== ========= -. ESP32 管脚 RGB LED -==== ========== ========= -1. GPIO0 红色 -2. GPIO2 绿色 -3. GPIO4 蓝色 -==== ========== ========= - - -.. _get-started-esp-wrover-kit-v3-microsd-card-slot: - -microSD 卡 -^^^^^^^^^^^^ - -==== ============== =============== -. ESP32 管脚 microSD 信号 -==== ============== =============== -1. MTDI/GPIO12 DATA2 -2. MTCK/GPIO13 CD/DATA3 -3. MTDO/GPIO15 CMD -4. MTMS/GPIO14 CLK -5. GPIO2 DATA0 -6. GPIO4 DATA1 -7. GPIO21 CD -==== ============== =============== - - -.. _get-started-esp-wrover-kit-v3-lcd-connector: - -LCD/U5 -^^^^^^^^ - -==== ============== =============== -. ESP32 管脚 LCD 信号 -==== ============== =============== -1. GPIO18 复位 -2. GPIO19 SCL -3. GPIO21 D/C -4. GPIO22 CS -5. GPIO23 SDA -6. GPIO25 SDO -7. GPIO5 背光 -==== ============== =============== - - -.. _get-started-esp-wrover-kit-v3-start-development: - -应用程序开发 ------------------------------ - -ESP-WROVER-KIT 上电前,请首先确认开发板完好无损。 - - -初始设置 -^^^^^^^^^^^^^ - -请严格按照下图所示连接跳线帽,注意不要额外连接其他跳线帽。 - -- 使用 JP7 连接器,选择 USB 为开发板供电。 - -- 使用 JP11 连接器,使能 UART 通信。 - -======================== ========================== -USB 供电 使能 UART 通信 -======================== ========================== -|jp7-usb_5v| |jp11-tx-rx| -======================== ========================== - -注意不要连接其他跳线帽。 - -打开 **电源开关**,**5V Power On LED** 应点亮。 - - -正式开始开发 -^^^^^^^^^^^^^^^^^^ - -现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至你的开发板。 - - -相关文档 ------------------ - -* `ESP-WROVER-KIT V3 原理图`_ (PDF) -* `《ESP32 技术规格书》 `_ (PDF) -* `《ESP32-WROVER 技术规格书》 `_ (PDF) -* `《ESP32-WROOM-32 技术规格书》 `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - -.. |jp7-ext_5v| image:: ../../../_static/esp-wrover-kit-v3-jp7-ext_5v.png -.. |jp7-usb_5v| image:: ../../../_static/esp-wrover-kit-v3-jp7-usb_5v.png -.. |jp8| image:: ../../../_static/esp-wrover-kit-v3-jp8.png -.. |jp11-tx-rx| image:: ../../../_static/esp-wrover-kit-v3-jp11-tx-rx.png -.. |jp14| image:: ../../../_static/esp-wrover-kit-v3-jp14.png - -.. _ESP-WROVER-KIT V3 原理图: https://dl.espressif.com/dl/schematics/ESP-WROVER-KIT_SCH-3.pdf - -.. toctree:: - :hidden: - - get-started-wrover-kit-v2.rst diff --git a/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit.rst b/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit.rst deleted file mode 100644 index 0e5eada2044c..000000000000 --- a/docs/zh_CN/hw-reference/esp32/get-started-wrover-kit.rst +++ /dev/null @@ -1,461 +0,0 @@ -ESP-WROVER-KIT V4.1 入门指南 -========================================= - -:link_to_translation:`en:[English]` - -本指南介绍了如何开始使用 ESP-WROVER-KIT V4.1 开发板及其功能和相关配置。 - - -准备工作 -------------- - -* :ref:`ESP-WROVER-KIT V4.1 开发板 ` -* USB 2.0 数据线(A 转 Micro-B) -* PC(Windows、Linux 或 macOS) - -你可以跳过介绍部分,直接前往 `应用程序开发`_ 章节。 - - -概述 --------- - -ESP-WROVER-KIT 是 `乐鑫 `_ 一款基于 ESP32 的开发板。 - -ESP-WROVER-KIT 开发板已集成了如下组件: - -- ESP32-WROVER-E 模组 -- LCD 屏 -- microSD 卡槽 - -此外,ESP-WROVER-KIT 的独特之处在于集成了一款先进多协议 USB 桥接器 (FTDI FT2232HL),允许开发人员直接通过 USB 接口,使用 JTAG 对 ESP32 进行调试,无需额外的 JTAG 调试器。ESP-WROVER-KIT 可为开发人员提供简单、便捷且极具成本效益的开发体验。 - -为了便于使用,板上模组的绝大部分管脚均已引出至开发板的引脚。 - -.. note:: - - ESP32 的 GPIO16 和 GPIO17 管脚用作 PSRAM 的片选和时钟信号。默认情况下,为了给用户提供可靠的性能,这两个 GPIO 管脚不引出至开发板引脚。 - - -功能概述 ----------------------- - -ESP-WROVER-KIT 开发板的主要组件和连接方式如下图所示。 - -.. figure:: ../../../_static/esp-wrover-kit-block-diagram.png - :align: center - :alt: ESP-WROVER-KIT 功能框图 - :figclass: align-center - - ESP-WROVER-KIT 功能框图 - - -功能说明 ----------------------- - -ESP-WROVER-KIT 开发板的主要组件、接口及控制方式见下。 - -.. _get-started-esp-wrover-kit-v4.1-board-front: - -.. figure:: ../../../_static/esp-wrover-kit-v4.1-layout-front.png - :align: center - :alt: ESP-WROVER-KIT 开发板布局 -- 俯视图 - :figclass: align-center - - ESP-WROVER-KIT 开发板布局 -- 俯视图 - -.. _get-started-esp-wrover-kit-v4.1-board-back: - -.. figure:: ../../../_static/esp-wrover-kit-v4.1-layout-back.png - :align: center - :alt: ESP-WROVER-KIT 开发板布局 -- 仰视图 - :figclass: align-center - - ESP-WROVER-KIT 开发板布局 -- 仰视图 - - -下表介绍了开发板的主要组件,顺序如下: - -- 从图片右上角开始,以顺时针顺序介绍了图 1 中的主要组件 -- 然后以同样的顺序介绍了图 2 中的主要组件 - -.. list-table:: - :widths: 25 75 - :header-rows: 1 - - * - 主要组件 - - 基本介绍 - * - FT2232HL - - FT2232HL 多协议 USB 转串口桥接器。开发人员可通过 USB 接口对 FT2232HL 芯片进行控制和编程,与 ESP32 建立连接。FT2232HL 芯片可在通道 A 提供 USB-to-JTAG 接口功能,并在通道 B 提供 USB-to-Serial 接口功能,便利开发人员的应用开发与调试。详见 `ESP-WROVER-KIT V4.1 原理图`_。 - * - 32.768 kHz - - 32.768 kHz 晶振,可提供 Deep-sleep 下使用的低功耗时钟。 - * - 0 欧电阻 - - ESP-WROVER-KIT 开发板设计了一个 0 欧电阻,可在测量 ESP32 系列模组在不同功耗模式下的电流时,直接移除或替换为分流器。 - * - ESP32-WROVER-E 模组 - - 这款 ESP32 模组内置 64-Mbit PSRAM,可提供灵活的额外存储空间和数据处理能力。 - * - 诊断 LED 信号灯 - - 本开发板 FT2232HL 芯片的 GPIO 管脚连接了 4 个红色 LED 信号灯,以备后用。 - * - UART - - 串口。FT2232HL 和 ESP32 的串行 TX/RX 信号已引出至 JP2 的两端。默认情况下,这两路信号由跳线帽连接。如果仅需使用 ESP32 模组串口,则可移除相关跳线帽,将模组连接至其他外部串口设备。 - * - SPI - - 默认情况下,ESP32 使用 SPI 接口访问内置 flash 和 PSRAM。使用这些引脚连接 ESP32 和其他 SPI 设备。这种情况下,需增加额外的片选 (CS) 信号。注意,本接口的工作电压为 3.3 V。 - * - CTS/RTS - - 串口流控信号。管脚默认不连接至电路。为了使能该功能,必须用跳线帽断路掉 JP14 的相应管脚。 - * - JTAG - - JTAG 接口。FT2232HL 和 ESP32 的 JTAG 信号已引出至 JP2 的两端。默认情况下,这两路信号不连接。如需使能 JTAG,请按照 `设置选项`_ 的介绍,连接跳线帽。 - * - USB 端口 - - USB 接口。可用作开发板的供电电源,或连接 PC 和开发板的通信接口。 - * - EN - - 复位按键。 - * - BOOT 按键 - - 下载按键。按下 **Boot** 键并保持,同时按一下 **EN** 键(此时不要松开 **Boot** 键)进入“固件下载”模式,通过串口下载固件。 - * - 电源开关 - - 电源开关。拨向 **Boot** 按键一侧,开发板上电;拨离 **Boot** 按键一侧,开发板掉电。 - * - 电源选择开关 - - ESP-WROVER-KIT 开发板可通过 USB 端口或 5V 输入接口供电。用户可使用跳线帽在两种供电模式中进行选择。更多详细信息,请见章节 `设置选项`_ 中有关 JP7 连接器的描述。 - * - 5V Input - - 5V 电源接口。为标准同轴电源接口,5.5 x 2.1 mm,中心正极。建议仅在开发板自动运行(未连接 PC)时使用。 - * - 5V Power On LED - - 当开发板通电后(USB 或外部 5V 供电),该红色指示灯将亮起。 - * - LDO - - 5V-to-3.3V 低压差线型稳压器 NCP1117(1A)。NCP1117 最大电流输出为 1 A。板上 LDO 为固定输出电压,但用户也可以选用具有可变输出电压的 LDO。更多信息,请见 `ESP-WROVER-KIT V4.1 原理图`_。 - * - 摄像头连接器 - - 摄像头接口,支持标准 OV7670 摄像头模块。 - * - RGB LED - - 红绿蓝发光二极管,可由 PMW 控制。 - * - I/O 连接器 - - 板上模组的所有管脚均已引出至开发板的排针。用户可以对 ESP32 进行编程,实现 PWM、ADC、DAC、I2C、I2S、SPI 等多种功能。 - * - microSD 卡槽 - - 适用于需要扩充数据存储空间或进行备份的应用开发场景。 - * - LCD 显示器 - - 支持贴装一款 3.2” 的 SPI(标准四线串行外设接口)LCD 显示器,请见 :ref:`ESP-WROVER-KIT 开发板布局 -- 仰视图 `。 - - -.. _get-started-esp-wrover-kit-v4.1-setup-options: - -设置选项 -------------- - -用户可通过 3 组排针,设置开发板功能,其中常见功能见下表: - -.. list-table:: - :widths: 25 35 40 - :header-rows: 1 - - * - 排针 - - 跳线设置 - - 功能描述 - * - JP7 - - |jp7-ext_5v| - - 使用外部电源为 ESP-WROVER-KIT 开发板供电 - * - JP7 - - |jp7-usb_5v| - - 使用 USB 端口为 ESP-WROVER-KIT 开发板供电 - * - JP2 - - |jp2-jtag| - - 使能 JTAG 功能 - * - JP2 - - |jp2-tx-rx| - - 使能 UART 通信 - * - JP14 - - |jp14| - - 使能 RTS/CTS 串口流控 - - -ESP32 管脚分配 ------------------------- - -ESP32 模组的部分管脚或终端已被板上组件占用或用于外部硬件设备。如果某管脚对应的特定硬件未连接,则该管脚可用作他用。比如,摄像头/JP4 排针未连接相应硬件,则这些 GPIO 可用于其他用途。 - -部分管脚具备多个功能,可供板上组件或外部硬件设备同时使用,比如 GPIO0 和 GPIO2。由于管脚限制,一些外围设备不可同时使用,比如,由于 JTAG 和 SD 卡槽需共用部分管脚,因此一些使用 SD 卡功能的应用无法同时进行 JTAG 调试。 - -其他情况下,不同外设可同时使用。比如,LCD 屏幕和 SD 卡仅共用一个 GPIO21 管脚,可以同时使用。该管脚可为 LCD 屏幕提供 D/C(数据/控制)信号,并用于读取来自 SD 卡槽的卡检测信号。如无需使用卡检测功能,开发人员还可以通过移除 R167 来禁用该功能。此时,LCD 和 SD 卡槽可同时使用。 - -更多外设共享管脚的介绍,请见下一章节中的表格。 - - -主要 I/O 连接器/JP1 -^^^^^^^^^^^^^^^^^^^^^^^^ - -JP1 连接器包括 14 x 2 个排针,具体功能可见下表中间 “I/O” 列的介绍。两侧的“共用”列则介绍了这些管脚在板上的其他用途。 - -.. list-table:: - :widths: 30 20 20 30 - :header-rows: 1 - - * - 共用 - - I/O - - I/O - - 共用 - * - n/a - - 3.3V - - GND - - n/a - * - NC/XTAL - - IO32 - - IO33 - - NC/XTAL - * - JTAG,microSD - - IO12 - - IO13 - - JTAG,microSD - * - JTAG,microSD - - IO14 - - IO27 - - 摄像头 - * - 摄像头 - - IO26 - - IO25 - - 摄像头,LCD - * - 摄像头 - - IO35 - - IO34 - - 摄像头 - * - 摄像头 - - IO39 - - IO36 - - 摄像头 - * - JTAG - - EN - - IO23 - - 摄像头,LCD - * - 摄像头,LCD - - IO22 - - IO21 - - 摄像头,LCD,microSD - * - 摄像头,LCD - - IO19 - - IO18 - - 摄像头,LCD - * - 摄像头,LCD - - IO5 - - IO17 - - PSRAM - * - PSRAM - - IO16 - - IO4 - - LED,摄像头,microSD - * - 摄像头,LED,Boot - - IO0 - - IO2 - - LED,microSD - * - JTAG,microSD - - IO15 - - 5V - - - -说明: - -* NC/XTAL - :ref:`32.768 kHz 晶振 ` -* JTAG - :ref:`JTAG/JP2 ` -* Boot - Boot 按键/SW2 -* 摄像头 - :ref:`摄像头/JP4 ` -* LED - :ref:`RGB LED ` -* microSD - :ref:`microSD Card/J4 ` -* LCD - :ref:`LCD/U5 ` -* PSRAM - ESP32-WROVER-E 的 PSRAM - - -.. _get-started-esp-wrover-kit-v4.1-xtal: - -32.768 kHz 晶振 -^^^^^^^^^^^^^^^^^^^^^ - -==== ========== - . ESP32 管脚 -==== ========== -1. GPIO32 -2. GPIO33 -==== ========== - -.. note:: - - 默认情况下,管脚 GPIO32 和 GPIO33 已连接至晶振。因此,为了保证信号的完整性,这两个管脚并未连接至 JP1 I/O 连接器。用户可通过将 R11 或 R23 处的 0 欧电阻移至 R12 或 R24 处,以将 GP1O32 和 GPIO33 的连接从晶振移至 JP1。 - - -.. _get-started-esp-wrover-kit-v4.1-spi-flash-header: - -SPI Flash/JP2 -^^^^^^^^^^^^^^^ - -==== ============= -. ESP32 管脚 -==== ============= -1 CLK/GPIO6 -2 SD0/GPIO7 -3 SD1/GPIO8 -4 SD2/GPIO9 -5 SD3/GPIO10 -6 CMD/GPIO11 -==== ============= - -.. note:: - - SPI flash 管脚用于访问内部闪存。因此,这些管脚不支持连接外部 SPI 设备,仅用于监测或高级选项。 - -.. important:: - - 模组的 flash 总线已通过 0 欧电阻 R140 ~ R145 连接至排针 JP2。如果需要将 flash 的工作频率控制在 80 MHz,以达到保证总线信号完整性等目的,建议移除 R140 ~ R145 电阻,将模组的 flash 总线与排针 JP2 断开。 - - -.. _get-started-esp-wrover-kit-v4.1-jtag-header: - -JTAG/JP2 -^^^^^^^^^^ - -==== ============== ============= -. ESP32 管脚 JTAG 信号 -==== ============== ============= -1 EN TRST_N -2 MTMS/GPIO14 TMS -3 MTDO/GPIO15 TDO -4 MTDI/GPIO12 TDI -5 MTCK/GPIO13 TCK -==== ============== ============= - - -.. _get-started-esp-wrover-kit-v4.1-camera-header: - -摄像头/JP4 -^^^^^^^^^^^^ - -==== ========== ============================= -. ESP32 管脚 摄像头信号 -==== ========== ============================= -1 n/a 3.3V -2 n/a 地 -3 GPIO27 SIO_C/SCCB 时钟 -4 GPIO26 SIO_D/SCCB 数据 -5 GPIO25 VSYNC/垂直同步 -6 GPIO23 HREF/水平参考 -7 GPIO22 PCLK/像素时钟 -8 GPIO21 XCLK/系统时钟 -9 GPIO35 D7/像素数据 Bit 7 -10 GPIO34 D6/像素数据 Bit 6 -11 GPIO39 D5/像素数据 Bit 5 -12 GPIO36 D4/像素数据 Bit 4 -13 GPIO19 D3/像素数据 Bit 3 -14 GPIO18 D2/像素数据 Bit 2 -15 GPIO5 D1/像素数据 Bit 1 -16 GPIO4 D0/像素数据 Bit 0 -17 GPIO0 RESET/摄像头复位 -18 n/a PWDN/摄像头断电 -==== ========== ============================= - -* D0 到 D7 为摄像头的数据总线 - - -.. _get-started-esp-wrover-kit-v4.1-rgb-led-connections: - -RGB LED -^^^^^^^ - -==== ========== ========= -. ESP32 管脚 RGB LED -==== ========== ========= -1 GPIO0 红色 -2 GPIO2 绿色 -3 GPIO4 蓝色 -==== ========== ========= - - -.. _get-started-esp-wrover-kit-v4.1-microsd-card-slot: - -microSD 卡 -^^^^^^^^^^^^ - -==== ============== =============== -. ESP32 管脚 microSD 信号 -==== ============== =============== -1. MTDI/GPIO12 DATA2 -2. MTCK/GPIO13 CD/DATA3 -3. MTDO/GPIO15 CMD -4. MTMS/GPIO14 CLK -5. GPIO2 DATA0 -6. GPIO4 DATA1 -7. GPIO21 Card Detect -==== ============== =============== - - -.. _get-started-esp-wrover-kit-v4.1-lcd-connector: - -LCD/U5 -^^^^^^^^ - -==== ============== =============== -. ESP32 管脚 LCD 信号 -==== ============== =============== -1 GPIO18 复位 -2 GPIO19 SCL -3 GPIO21 D/C -4 GPIO22 CS -5 GPIO23 SDA -6 GPIO25 SDO -7 GPIO5 背光 -==== ============== =============== - - -.. _get-started-esp-wrover-kit-start-development: - -应用程序开发 ------------------------------ - -ESP-WROVER-KIT 上电前,请首先确认开发板完好无损。 - - -初始设置 -^^^^^^^^^^^^^ - -请严格按照下图所示连接跳线帽,注意不要额外连接其他跳线帽。 - -- 使用 JP7 连接器,选择 USB 为开发板供电。 - -- 使用 JP2 连接器,使能 UART 通信。 - -======================== ========================== -USB 供电 使能 UART 通信 -======================== ========================== -|jp7-usb_5v| |jp2-tx-rx| -======================== ========================== - -注意不要连接其他跳线帽。 - -打开 **电源开关**,**5V Power On LED** 应点亮。 - - -正式开始开发 -^^^^^^^^^^^^^^^^^^ - -现在,请前往 :doc:`../../get-started/index` 中的 :ref:`get-started-step-by-step` 章节,查看如何设置开发环境,并尝试将示例项目烧录至你的开发板。 - -你可以在 `ESP-IDF 组件注册器 `_ 中下载板级支持包 (BSP)。 - -以下链接提供了与 ESP-WROVER-KIT 开发板硬件相关的示例: - -* 板上 LCD 示例::example:`peripherals/spi_master/lcd` -* SD 卡槽示例: :example:`storage/sd_card` -* 摄像头示例:https://github.com/espressif/esp32-camera - - -相关文档 ------------------ - -* `ESP-WROVER-KIT V4.1 原理图`_ (PDF) -* `ESP-WROVER-KIT V4.1 布局 `_ (DXF) -* `《ESP32 技术规格书》 `_ (PDF) -* `《ESP32-WROVER-E 技术规格书》 `_ (PDF) -* :doc:`../../api-guides/jtag-debugging/index` -* :doc:`../../hw-reference/index` - -.. |jp7-ext_5v| image:: ../../../_static/esp-wrover-kit-v4.1-jp7-ext_5v.jpg -.. |jp7-usb_5v| image:: ../../../_static/esp-wrover-kit-v4.1-jp7-usb_5v.jpg -.. |jp2-jtag| image:: ../../../_static/esp-wrover-kit-v4.1-jp2-jtag.jpg -.. |jp2-tx-rx| image:: ../../../_static/esp-wrover-kit-v4.1-jp2-tx-rx.jpg -.. |jp14| image:: ../../../_static/esp-wrover-kit-v4.1-jp14.jpg - -.. _ESP-WROVER-KIT V4.1 原理图: https://dl.espressif.com/dl/schematics/ESP-WROVER-KIT_V4_1.pdf - -.. toctree:: - :hidden: - - get-started-wrover-kit-v3.rst - get-started-wrover-kit-v2.rst diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.0.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.0.rst deleted file mode 100644 index a7687d2344ff..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.0.rst +++ /dev/null @@ -1,116 +0,0 @@ -================== -ESP-LyraP-CAM v1.0 -================== - -:link_to_translation:`en:[English]` - -本用户指南可提供 ESP-LyraP-CAM 扩展板的相关信息。 - -本扩展板通常仅与乐鑫其他开发板一起销售(即 *主板*,比如 ESP32-S2-Kaluga-1),不可单独购买。 - -目前,ESP-LyraP-CAM v1.0 扩展板正在搭配 :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2` 销售。 - -ESP-LyraP-CAM 可为你的主板增加摄像头功能。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.0-3d.png - :align: center - :alt: ESP-LyraP-CAM - :figclass: align-center - - ESP-LyraP-CAM - -本指南包括如下内容: - -- `概述`_:提供为了使用 ESP-LyraP-CAM 而必须了解的硬件和软件信息。 -- `硬件参考`_:提供 ESP-LyraP-CAM 的详细硬件信息。 -- `硬件修订历史`_:提供该开发版的“修订历史”、“已知问题”以及此前版本开发板的用户指南链接。 -- `相关文档`_:提供相关文档的链接。 - - -概述 -==== - -ESP-LyraP-CAM 扩展板可为你的主板增加一个摄像头。 - - -组件描述 --------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.0-layout-front.png - :align: center - :alt: ESP-LyraP-CAM - 正面和反面 - :figclass: align-center - - ESP-LyraP-CAM - 正面和反面 - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - 主板摄像头排针 - - 连接至主板摄像头连接器 - * - 电源 LED 指示灯 - - 如果电源供电电压正常,则红色 LED 亮起 - * - 摄像头模块连接器 - - 硬件支持 OV2640 和 OV3660 摄像头模块;目前,ESP-LyraP-CAM 扩展板默认提供 OV2640 摄像头模块 - * - 电源调节器 - - LDO 调压器(3.3 V 至 2.8 V 和 1.5 V) - - -应用程序开发 ------------- - -ESP-LyraP-CAM 上电前,请首先确认开发板完好无损。 - - -硬件准备 -^^^^^^^^ - -- 带有摄像头扩展板连接器(排母)的主板(例如 ESP32-S2-Kaluga-1) -- ESP-LyraP-CAM 扩展板 -- PC(Windows、Linux 或 macOS) - - -硬件设置 -^^^^^^^^ - -将 ESP-LyraP-CAM 扩展板插入主板的连接头排母中。 - - -软件设置 -^^^^^^^^ - -请前往 ESP32-S2-Kaluga-1 开发套件用户指南的 :ref:`user-guide-esp32-s2-kaluga-1-kit-v1.2-software-setup` 章节。 - - -硬件参考 -======== - -功能框图 --------- - -ESP-LyraP-CAM 的主要组件和连接方式如下图所示。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.0-block-diagram.png - :align: center - :alt: ESP-LyraP-CAM 功能框图 - :figclass: align-center - - ESP-LyraP-CAM 功能框图 - - -硬件修订历史 -============ - -尚无版本升级历史。 - - -相关文档 -======== - -- `ESP-LyraP-CAM 原理图 `_ (PDF) -- `ESP-LyraP-CAM PCB 布局图 `_ (PDF) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.1.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.1.rst deleted file mode 100644 index 564748dd4c04..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-cam-v1.1.rst +++ /dev/null @@ -1,130 +0,0 @@ -================== -ESP-LyraP-CAM v1.1 -================== - -:link_to_translation:`en:[English]` - -本用户指南可提供 ESP-LyraP-CAM 扩展板的相关信息。 - -本扩展板通常仅与乐鑫其他开发板一起销售(即 *主板*,比如 ESP32-S2-Kaluga-1),不可单独购买。 - -目前,ESP-LyraP-CAM v1.1 扩展板正在搭配 :doc:`user-guide-esp32-s2-kaluga-1-kit` 销售。 - -ESP-LyraP-CAM 可为你的主板增加摄像头功能。 - -.. Image of v1.0 is used as there are no visual changes - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.0-3d.png - :align: center - :alt: ESP-LyraP-CAM - :figclass: align-center - - ESP-LyraP-CAM - -本指南包括如下内容: - -- `概述`_:提供为了使用 ESP-LyraP-CAM 而必须了解的硬件和软件信息。 -- `硬件参考`_:提供 ESP-LyraP-CAM 的详细硬件信息。 -- `硬件修订历史`_:提供该开发版的“修订历史”、“已知问题”以及此前版本开发板的用户指南链接。 -- `相关文档`_:提供相关文档的链接。 - - -概述 -==== - -ESP-LyraP-CAM 扩展板可为你的主板增加一个摄像头。 - - -组件描述 --------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.1-layout-front.png - :align: center - :alt: ESP-LyraP-CAM - 正面和反面 - :figclass: align-center - - ESP-LyraP-CAM - 正面和反面 - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - 主板摄像头排针 - - 连接至主板摄像头连接器 - * - 电源 LED 指示灯 - - 如果电源供电电压正常,则红色 LED 亮起 - * - 摄像头模块连接器 - - 硬件支持 OV2640 和 OV3660 摄像头模块;目前,ESP-LyraP-CAM 扩展板默认提供 OV2640 摄像头模块 - * - 电源调节器 - - LDO 调压器(3.3 V 至 2.8 V 和 1.5 V) - - -应用程序开发 ------------- - -ESP-LyraP-CAM 上电前,请首先确认开发板完好无损。 - - -硬件准备 -^^^^^^^^ - -- 带有摄像头扩展板连接器(排母)的主板(例如 ESP32-S2-Kaluga-1) -- ESP-LyraP-CAM 扩展板 -- PC(Windows、Linux 或 macOS) - - -硬件设置 -^^^^^^^^ - -将 ESP-LyraP-CAM 扩展板插入主板的连接头排母中。 - - -软件设置 -^^^^^^^^ - -请前往 ESP32-S2-Kaluga-1 开发套件用户指南的 :ref:`user-guide-esp32-s2-kaluga-1-kit-software-setup` 章节。 - - -硬件参考 -======== - -功能框图 --------- - -ESP-LyraP-CAM 的主要组件和连接方式如下图所示。 - -.. Image of v1.0 is used as there are no visual changes - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-cam-v1.0-block-diagram.png - :align: center - :alt: ESP-LyraP-CAM 功能框图 - :figclass: align-center - - ESP-LyraP-CAM 功能框图 - - -硬件修订历史 -============ - -ESP-LyraP-CAM v1.1 --------------------- - -* 仅更新丝印 -* 无实际硬件升级 - - -ESP-LyraP-CAM v1.0 --------------------- - -:doc:`首次发布 ` - - -相关文档 -======== - -- `ESP-LyraP-CAM 原理图 `_ (PDF) -- `ESP-LyraP-CAM PCB 布局图 `_ (PDF) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.1.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.1.rst deleted file mode 100644 index 65698bb51ca8..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.1.rst +++ /dev/null @@ -1,132 +0,0 @@ -==================== -ESP-LyraP-LCD32 v1.1 -==================== - -:link_to_translation:`en:[English]` - -本用户指南可提供 ESP-LyraP-LCD32 扩展板的相关信息。 - -本扩展板通常仅与乐鑫其他开发板一起销售(即 *主板*,比如 ESP32-S2-Kaluga-1),不可单独购买。 - -目前,ESP-LyraP-CAM v1.1 扩展板正在搭配 :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2` 销售。 - -ESP-LyraP-LCD32 可为你的主板增加 LCD 图像显示功能。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.1-3d.png - :align: center - :width: 2243px - :height: 1534px - :scale: 30% - :alt: ESP-LyraP-LCD32 - :figclass: align-center - - ESP-LyraP-LCD32(点击放大) - -本指南包括如下内容: - -- `概述`_:提供为了使用 ESP-LyraP-LCD32 而必须了解的硬件和软件信息。 -- `硬件参考`_:提供 ESP-LyraP-LCD32 的详细硬件信息。 -- `硬件修订历史`_:提供该开发版的“修订历史”、“已知问题”以及此前版本开发板的用户指南链接。 -- `相关文档`_:提供相关文档的链接。 - - -概述 -==== - -ESP-LyraP-LCD32 可为你的主板增加一块 3.2" LCD 图形显示屏(320 x 240 分辨率)。该显示屏通过 SPI 总线连接到 ESP32-S2。 - - -组件描述 --------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.1-layout-front.png - :align: center - :width: 934px - :height: 600px - :scale: 70% - :alt: ESP-LyraP-LCD32 - 正面 - :figclass: align-center - - ESP-LyraP-LCD32 - 正面(点击放大) - - -在下面的组件描述中,**保留** 表示该功能可用,但当前版本的套件并未启用该功能。 - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - 扩展板排针 - - 连接器排针,用于插入主板上的排母 - * - LCD 显示屏 - - 本版本支持 3.2" 的 SPI LCD 显示模块(320 x 240 分辨率);显示器驱动(控制器)为 Sitronix ST7789V - * - 触摸屏开关 - - 暂不支持触摸屏,因此请注意保持关闭,确保相关管脚复用不受影响。 - * - 主板 3.2" LCD FPC 连接器 - - (保留)连接到主板的 3.2" LCD FPC 连接器 - * - 控制开关 - - 打开将 Reset/Backlight_control/CS 设置为默认高电平或低电平;关闭允许释放这些管脚用作它用。 - - -应用程序开发 ------------- - -ESP-LyraP-LCD32 上电前,请首先确认开发板完好无损。 - - -硬件准备 -^^^^^^^^ - -- 带有摄像头扩展板连接器(排母)的主板(例如 ESP32-S2-Kaluga-1、ESP-LyraT-8311A) -- ESP-LyraP-LCD32 扩展板 -- 4 x 螺栓,用于保证安装稳定 -- PC(Windows、Linux 或 macOS) - - -硬件设置 -^^^^^^^^ - -请按照以下步骤将 ESP-LyraP-LCD32 安装到带有排母的主板上: - -1. 先将 4 个螺栓固定到主板的相应位置上 -2. 对齐 ESP-LyraP-LCD32 与主板和螺栓的位置,并小心插入 - - -软件设置 -^^^^^^^^ - -请前往 ESP32-S2-Kaluga-1 开发套件用户指南的 :ref:`user-guide-esp32-s2-kaluga-1-kit-v1.2-software-setup` 章节。 - - -硬件参考 -======== - -功能框图 --------- - -ESP-LyraP-LCD32 的主要组件和连接方式如下图所示。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.1-block-diagram.png - :align: center - :alt: ESP-LyraP-LCD32 功能框图 - :figclass: align-center - - ESP-LyraP-LCD32 功能框图 - - -硬件修订历史 -============ - -尚无版本升级历史。 - - -相关文档 -======== - -- `ESP-LyraP-LCD32 原理图 `_ (PDF) -- `ESP-LyraP-LCD32 PCB 布局图 `_ (PDF) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.2.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.2.rst deleted file mode 100644 index 9358f1ad9509..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-lcd32-v1.2.rst +++ /dev/null @@ -1,154 +0,0 @@ -==================== -ESP-LyraP-LCD32 v1.2 -==================== - -:link_to_translation:`en:[English]` - -本用户指南可提供 ESP-LyraP-LCD32 扩展板的相关信息。 - -本扩展板通常仅与乐鑫其他开发板一起销售(即 *主板*,比如 ESP32-S2-Kaluga-1),不可单独购买。 - -目前,ESP-LyraP-LCD32 v1.2 扩展板正在搭配 :doc:`user-guide-esp32-s2-kaluga-1-kit` 销售。 - -ESP-LyraP-LCD32 可为你的主板增加 LCD 图像显示功能。 - -.. Image of v1.1 is used as there are no visual changes - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.1-3d.png - :align: center - :width: 2243px - :height: 1534px - :scale: 30% - :alt: ESP-LyraP-LCD32 - :figclass: align-center - - ESP-LyraP-LCD32(点击放大) - -本指南包括如下内容: - -- `概述`_:提供为了使用 ESP-LyraP-LCD32 而必须了解的硬件和软件信息。 -- `硬件参考`_:提供 ESP-LyraP-LCD32 的详细硬件信息。 -- `硬件修订历史`_:提供该开发版的“修订历史”、“已知问题”以及此前版本开发板的用户指南链接。 -- `相关文档`_:提供相关文档的链接。 - - -概述 -==== - -ESP-LyraP-LCD32 可为你的主板增加了一块 3.2" LCD 图形显示屏(320 x 240 分辨率)。该显示屏通过 SPI 总线连接到 ESP32-S2。 - - -组件描述 --------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.2-layout-front.png - :align: center - :width: 934px - :height: 489px - :scale: 70% - :alt: ESP-LyraP-LCD32 - 正面 - :figclass: align-center - - ESP-LyraP-LCD32 - 正面(点击放大) - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.2-layout-back.png - :align: center - :width: 934px - :height: 600px - :scale: 70% - :alt: ESP-LyraP-LCD32 - 反面 - :figclass: align-center - - ESP-LyraP-LCD32 - 反面(点击放大) - - -在下面的组件描述中,**保留** 表示该功能可用,但当前版本的套件并未启用该功能。 - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - 扩展板排针 - - 连接器排针,用于插入主板上的排母 - * - LCD 显示屏 - - 本版本支持 3.2" 的 SPI LCD 显示模块(320 x 240 分辨率);显示器驱动(控制器)为 Sitronix ST7789V 或 Ilitek ILI9341 - * - 触摸屏开关 - - 暂不支持触摸屏,因此请注意保持关闭,确保相关管脚复用不受影响。 - * - 主板 3.2" LCD FPC 连接器 - - (保留)连接到主板的 3.2" LCD FPC 连接器 - * - 控制开关 - - 打开将 Reset/Backlight_control/CS 设置为默认高电平或低电平;关闭允许释放这些管脚用作它用。 - - -应用程序开发 ------------- - -ESP-LyraP-LCD32 上电前,请首先确认开发板完好无损。 - - -硬件准备 -^^^^^^^^ - -- 带有摄像头扩展板连接器(排母)的主板(例如 ESP32-S2-Kaluga-1、ESP-LyraT-8311A) -- ESP-LyraP-LCD32 扩展板 -- 4 x 螺栓,用于保证安装稳定 -- PC(Windows、Linux 或 macOS) - - -硬件设置 -^^^^^^^^ - -请按照以下步骤将 ESP-LyraP-LCD32 安装到带有排母的主板上: - -1. 先将 4 个螺栓固定到主板的相应位置上 -2. 对齐 ESP-LyraP-LCD32 与主板和螺栓的位置,并小心插入 - - -软件设置 -^^^^^^^^ - -请前往 ESP32-S2-Kaluga-1 开发套件用户指南的 :ref:`user-guide-esp32-s2-kaluga-1-kit-software-setup` 章节。 - - -硬件参考 -======== - -功能框图 --------- - -ESP-LyraP-LCD32 的主要组件和连接方式如下图所示。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-lcd32-v1.2-block-diagram.png - :align: center - :alt: ESP-LyraP-LCD32 功能框图 - :figclass: align-center - - ESP-LyraP-LCD32 功能框图 - - -硬件修订历史 -============ - -ESP-LyraP-LCD32 v1.2 --------------------- - -* LCD 背光默认打开 (ON),无法通过 MCU 实现控制 -* 移除 Touch 驱动及相关开关,以避免管脚复用带来的影响 - - -ESP-LyraP-LCD32 v1.1 --------------------- - -:doc:`首次发布 ` - - -相关文档 -======== - -- `ESP-LyraP-LCD32 原理图 `_ (PDF) -- `ESP-LyraP-LCD32 PCB 布局图 `_ (PDF) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-toucha-v1.1.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-toucha-v1.1.rst deleted file mode 100644 index af786b563bf9..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrap-toucha-v1.1.rst +++ /dev/null @@ -1,118 +0,0 @@ -===================== -ESP-LyraP-TouchA v1.1 -===================== - -:link_to_translation:`en:[English]` - -本用户指南可提供 ESP-LyraP-TouchA 扩展板的相关信息。 - -本扩展板通常仅与乐鑫其他开发板一起销售(即 *主板*,比如 ESP32-S2-Kaluga-1),不可单独购买。 - -目前,ESP-LyraP-TouchA v1.1 扩展板正在搭配以下套件销售: - -* :doc:`user-guide-esp32-s2-kaluga-1-kit` -* :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2` - -ESP-LyraP-TouchA 可为你的主板增加触摸按键功能。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-toucha-v1.1-3d.png - :align: center - :alt: ESP-LyraP-TouchA - :figclass: align-center - - ESP-LyraP-TouchA - -本指南包括如下内容: - -- `概述`_:提供为了使用 ESP-LyraT-8311A 而必须了解的硬件和软件信息。 -- `硬件参考`_:提供 ESP-LyraP-TouchA 的详细硬件信息。 -- `硬件修订历史`_:提供该开发版的“修订历史”、“已知问题”以及此前版本开发板的用户指南链接。 -- `相关文档`_:提供相关文档的链接。 - - -概述 -==== - -ESP-LyraP-TouchA 共有 6 个触摸按钮,主要用于音频应用,但也可以根据实际需要用作它用。 - - -组件描述 --------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-toucha-v1.1-layout-front.png - :align: center - :alt: ESP-LyraP-TouchA - :figclass: align-center - - ESP-LyraP-TouchA - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - 主板触摸 FPC 连接器 - - 用于将子板连接到主板的触摸 FPC 连接器。 - * - 触摸板 - - 电容式触摸电极。 - * - 保护环 - - 连接至触摸传感器,可在开发板遇水时触发中断保护(遇水电路保护)。此时,传感器阵列也将遇水,绝大多数(或全部)触摸板将由于大量误触而无法使用。在接收到此中断后,用户可自行裁决是否通过软件禁用所有触摸传感器。 - - -应用程序开发 ------------- - -ESP-LyraP-TouchA 上电前,请首先确认开发板完好无损。 - - -硬件准备 -^^^^^^^^ - -- 带有触摸 FPC 扩展板连接器的主板(例如 ESP32-S2-Kaluga-1) -- ESP-LyraP-TouchA 扩展板 -- FPC 线 -- PC(Windows、Linux 或 macOS) - - -硬件设置 -^^^^^^^^ - -使用 FPC 连接两个 FPC 连接器。 - - -软件设置 -^^^^^^^^ - -请前往 ESP32-S2-Kaluga-1 开发套件用户指南的 :ref:`user-guide-esp32-s2-kaluga-1-kit-software-setup` 章节。 - - -硬件参考 -======== - -功能框图 --------- - -ESP-LyraP-TouchA 的主要组件和连接方式如下图所示。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrap-toucha-v1.1-block-diagram.png - :align: center - :alt: ESP-LyraP-TouchA-v1.1 功能框图 - :figclass: align-center - - ESP-LyraP-TouchA-v1.1 功能框图 - - -硬件修订历史 -============ - -尚无版本升级历史。 - - -相关文档 -======== - -- `ESP-LyraP-TouchA 原理图 `_ (PDF) -- `ESP-LyraP-TouchA PCB 布局图 `_ (PDF) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.2.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.2.rst deleted file mode 100644 index 8acef68185c9..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.2.rst +++ /dev/null @@ -1,150 +0,0 @@ -==================== -ESP-LyraT-8311A v1.2 -==================== - -:link_to_translation:`en:[English]` - -本用户指南可提供 ESP-LyraT-8311A 扩展板的相关信息。 - -本扩展板通常仅与乐鑫其他开发板一起销售(即 *主板*,比如 ESP32-S2-Kaluga-1),不可单独购买。 - -目前,ESP-LyraT-8311A v1.2 扩展板正在搭配 :doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2` 销售。 - -ESP-LyraT-8311A 扩展板可为你的主板增加音频处理功能。 - -- 音频播放/录音 -- 音频信号处理 -- 支持可编程按钮,可实现轻松控制 - -ESP-LyraT-8311A 扩展板有多种使用方式。该应用程序包括语音用户界面、语音控制、语音授权、录音和播放等功能。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.2-3d.png - :align: center - :width: 2545px - :height: 1786px - :scale: 30% - :alt: ESP-LyraT-8311A - :figclass: align-center - - ESP-LyraT-8311A(点击放大) - -本指南包括如下内容: - -- `概述`_:提供为了使用 ESP-LyraT-8311A 而必须了解的硬件和软件信息。 -- `硬件参考`_:提供 ESP-LyraT-8311A 的详细硬件信息。 -- `硬件修订历史`_:提供该开发版的“修订历史”、“已知问题”以及此前版本开发板的用户指南链接。 -- `相关文档`_:提供相关文档的链接。 - - -概述 -==== - -ESP-LyraT-8311A 主要用于音频应用,但也可根据实际需求用作它用。 - - -组件描述 --------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.2-layout-front.png - :align: center - :width: 934px - :height: 565px - :scale: 70% - :alt: ESP-LyraT-8311A - 正面 - :figclass: align-center - - ESP-LyraT-8311A - 正面(点击放大) - -下表将从图片右上角开始,以顺时针顺序介绍上图中的主要组件。 - -**保留** 表示该功能可用,但当前版本的套件并未启用该功能。 - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - 扩展板排针 - - 反面的排针用于于主板上的排母相连;排母用于连接其他带有排针的主板 - * - 功能按钮 - - 带有 6 个可编程按钮 - * - 麦克风 - - 支持驻极体和 MEMS 麦克风;此扩展板默认带有驻极体麦克风 - * - 耳机接口 - - 6.3 mm (1/8") 立体声耳机接口 - * - 扬声器连接器 - - 2 针连接器,用于连接外部扬声器 - * - PA - - 3 W 音频信号放大器,配合外部扬声器使用 - * - 外部麦克风矩阵连接器 - - (保留)FPC 连接器,用于连接外部麦克风矩阵(麦克风开发板) - * - ADC - - (保留)高性能 ADC/ES7243,包括 1 个麦克风通道、1 个声学回声消除 (AEC) 功能通道 - * - 单声道音频编解器 - - ES8311 音频 ADC 和 DAC,可转换麦克风拾音的模拟信号;或转换数字信号,使其可通过扬声器或耳机进行播放 - - -应用程序开发 ------------- - -ESP-LyraT-8311A 上电前,请首先确认开发板完好无损。 - - -硬件准备 -^^^^^^^^ - -- 带有连接器(排母)的主板(例如 ESP32-S2-Kaluga-1) -- ESP-LyraT-8311A 扩展板 -- 4 x 螺栓,用于保证安装稳定 -- PC(Windows、Linux 或 macOS) - - -硬件设置 -^^^^^^^^ - -请按照以下步骤将 ESP-LyraT-8311A 安装到带有排母的主板上: - -1. 先将 4 个螺栓固定到主板的相应位置上 -2. 对齐 ESP-LyraT-8311A 与主板和螺栓的位置,并小心插入 - - -软件设置 -^^^^^^^^ - -请根据你的具体应用,参考以下部分: - -* ESP-ADF(乐鑫音频开发框架)的用户,请前往 `ESP-ADF 入门指南 `_。 -* ESP32-IDF(乐鑫 IoT 开发框架)的用户,请前往 ESP32-S2-Kaluga-1 开发套件用户指南 :ref:`user-guide-esp32-s2-kaluga-1-kit-v1.2-software-setup` 章节。 - - -硬件参考 -======== - -功能框图 --------- - -ESP-LyraT-8311A 的主要组件和连接方式如下图所示。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.2-block-diagram.png - :align: center - :alt: ESP-LyraT-8311A 功能框图 - :figclass: align-center - - ESP-LyraT-8311A 功能框图 - - -硬件修订历史 -============ - -尚无版本升级历史。 - - -相关文档 -======== - -- `ESP-LyraT-8311A 原理图 `_ (PDF) -- `ESP-LyraT-8311A PCB 布局图 `_ (PDF) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.3.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.3.rst deleted file mode 100644 index b32075e0169a..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp-lyrat-8311a_v1.3.rst +++ /dev/null @@ -1,159 +0,0 @@ -==================== -ESP-LyraT-8311A v1.3 -==================== - -:link_to_translation:`en:[English]` - -本用户指南可提供 ESP-LyraT-8311A 扩展板的相关信息。 - -本扩展板通常仅与乐鑫其他开发板一起销售(即 *主板*,比如 ESP32-S2-Kaluga-1),不可单独购买。 - -目前,ESP-LyraT-8311A v1.3 扩展板正在搭配 :doc:`user-guide-esp32-s2-kaluga-1-kit` 销售。 - -ESP-LyraT-8311A 扩展板可为你的主板增加音频处理功能。 - -- 音频播放/录音 -- 音频信号处理 -- 支持可编程按钮,可实现轻松控制 - -ESP-LyraT-8311A 扩展板有多种使用方式。该应用程序包括语音用户界面、语音控制、语音授权、录音和播放等功能。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.3-3d.png - :align: center - :width: 1934px - :height: 1473px - :scale: 30% - :alt: ESP-LyraT-8311A - :figclass: align-center - - ESP-LyraT-8311A (click to enlarge) - -本指南包括如下内容: - -- `概述`_:提供为了使用 ESP-LyraT-8311A 而必须了解的硬件和软件信息。 -- `硬件参考`_:提供 ESP-LyraT-8311A 的详细硬件信息。 -- `硬件修订历史`_:提供该开发版的“修订历史”、“已知问题”以及此前版本开发板的用户指南链接。 -- `相关文档`_:提供相关文档的链接。 - - -概述 -==== - -ESP-LyraT-8311A 主要用于音频应用,但也可根据实际需求用作它用。 - - -组件描述 --------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.3-layout-front.png - :align: center - :width: 934px - :height: 565px - :scale: 70% - :alt: ESP-LyraT-8311A - 正面 - :figclass: align-center - - ESP-LyraT-8311A - 正面(点击放大) - -下表将从图片右上角开始,以顺时针顺序介绍上图中的主要组件。 - -**保留** 表示该功能可用,但当前版本的套件并未启用该功能。 - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - 扩展板排针 - - 反面的排针用于于主板上的排母相连;排母用于连接其他带有排针的主板 - * - 功能按钮 - - 带有 6 个可编程按钮 - * - 麦克风 - - 支持驻极体和 MEMS 麦克风;此扩展板默认带有驻极体麦克风 - * - 耳机接口 - - 6.3 mm (1/8") 立体声耳机接口 - * - 扬声器连接器 - - 2 针连接器,用于连接外部扬声器 - * - PA - - 3 W 音频信号放大器,配合外部扬声器使用 - * - 外部麦克风矩阵连接器 - - (保留)FPC 连接器,用于连接外部麦克风矩阵(麦克风开发板) - * - ADC - - (保留)高性能 ADC/ES7243,包括 1 个麦克风通道、1 个声学回声消除 (AEC) 功能通道 - * - 单声道音频编解器 - - ES8311 音频 ADC 和 DAC,可转换麦克风拾音的模拟信号;或转换数字信号,使其可通过扬声器或耳机进行播放 - - -应用程序开发 ------------- - -ESP-LyraT-8311A 上电前,请首先确认开发板完好无损。 - - -硬件准备 -^^^^^^^^ - -- 带有连接器(排母)的主板(例如 ESP32-S2-Kaluga-1) -- ESP-LyraT-8311A 扩展板 -- 4 x 螺栓,用于保证安装稳定 -- PC(Windows、Linux 或 macOS) - - -硬件设置 -^^^^^^^^ - -请按照以下步骤将 ESP-LyraT-8311A 安装到带有排母的主板上: - -1. 先将 4 个螺栓固定到主板的相应位置上 -2. 对齐 ESP-LyraT-8311A 与主板和螺栓的位置,并小心插入 - - -软件设置 -^^^^^^^^ - -请根据你的具体应用,参考以下部分: - -* ESP-ADF(乐鑫音频开发框架)的用户,请前往 `ESP-ADF 入门指南 `_。 -* ESP32-IDF(乐鑫 IoT 开发框架)的用户,请前往 ESP32-S2-Kaluga-1 开发套件用户指南 :ref:`user-guide-esp32-s2-kaluga-1-kit-software-setup` 章节。 - - -硬件参考 -======== - -功能框图 --------- - -ESP-LyraT-8311A 的主要组件和连接方式如下图所示。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp-lyrat-8311a-v1.3-block-diagram.png - :align: center - :alt: ESP-LyraT-8311A 功能框图 - :figclass: align-center - - ESP-LyraT-8311A 功能框图 - - -硬件修订历史 -============ - -ESP-LyraT-8311A v1.3 --------------------- - -* 移除 ADC/ES7243 和 ADC/ES7210,相关功能由单声道音频编解器提供。 - - -ESP-LyraT-8311A v1.2 --------------------- - -:doc:`首次发布 ` - - -相关文档 -======== - -- `ESP-LyraT-8311A 原理图 `_ (PDF) -- `ESP-LyraT-8311A PCB 布局图 `_ (PDF) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst deleted file mode 100644 index a498cbf1c488..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit-v1.2.rst +++ /dev/null @@ -1,380 +0,0 @@ -============================= -ESP32-S2-Kaluga-1 套件 v1.2 -============================= - -:link_to_translation:`en:[English]` - -最新版本::doc:`user-guide-esp32-s2-kaluga-1-kit` - -ESP32-S2-Kaluga-1 v1.2 是一款来自乐鑫的开发套件,主要可用于以下目的: - -- 展示 ESP32-S2 芯片的人机交互功能 -- 为用户提供基于 ESP32-S2 的人机交互应用开发工具 - -ESP32-S2 的功能强大,应用场景非常丰富。对于初学者来说,可能的用例包括: - -- **智能家居**:从最简单的智能照明、智能门锁、智能插座,到更复杂的视频流设备、安防摄像头、OTT 设备和家用电器等 -- **电池供电设备**:Wi-Fi mesh 传感器网络、Wi-Fi 网络玩具、可穿戴设备、健康管理设备等 -- **工业自动化设备**:无线控制与机器人技术、智能照明、HVAC 控制设备等 -- **零售和餐饮业**:POS 机和服务机器人 - - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-kit-v1.0-3d.png - :align: center - :width: 3452px - :height: 1590px - :scale: 20% - :alt: ESP32-S2-Kaluga-1-Kit-Assembly - :figclass: align-center - - ESP32-S2-Kaluga-1-Kit 概述(点击放大) - - -ESP32-S2-Kaluga-1 套件包括以下几个开发板: - -- 主板:*ESP32-S2-Kaluga-1* -- 扩展板: - - - :doc:`user-guide-esp-lyrat-8311a_v1.2` - 音频播放器 - - :doc:`user-guide-esp-lyrap-toucha-v1.1` - 触摸板 - - :doc:`user-guide-esp-lyrap-lcd32-v1.1` - 3.2" LCD 屏 - - :doc:`user-guide-esp-lyrap-cam-v1.0` - 摄像头 - -由于 ESP32-S2 的管脚复用,部分扩展板的兼容性有所限制,具体请见 :ref:`user-guide-esp32-s2-kaluga-1-kit-v1.2-ext-board-compatibility`。 - -本文档主要介绍 **ESP32-S2-Kaluga-1 主板** 及其与扩展板的交互。更多有关具体扩展板的信息,请点击相应的链接。 - -本指南包括: - -- `快速入门`_:提供 ESP32-S2-Kaluga-1 的简要概述及必须了解的硬件和软件信息。 -- `硬件参考`_:提供 ESP32-S2-Kaluga-1 的详细硬件信息。 -- `硬件修订历史`_:提供该开发板的“修订历史”、“已知问题”以及此开发板之前版本的用户指南链接。 -- `相关文档`_:提供相关文档的链接。 - - -快速入门 -======== - -本节介绍如何开始使用 ESP32-S2-Kaluga-1,主要包括三大部分:首先,介绍一些关于 ESP32-S2-Kaluga-1 的基本信息;然后,在 `应用程序开发`_ 章节介绍如何进行硬件初始化;最后,介绍如何为 ESP32-S2-Kaluga-1 烧录固件。 - - -概述 ----- - -ESP32-S2-Kaluga-1 主板是整个套件的核心。该主板集成了 ESP32-S2-WROVER 模组,并配备连接至各个扩展板的连接器。ESP32-S2-Kaluga-1 是人机交互接口原型设计的关键工具。 - -ESP32-S2-Kaluga-1 主板配备了多个连接器,可用于连接相应扩展板: - -- 扩展板连接器,用于连接 ESP-LyraT-8311A、ESP-LyraP-LCD32 -- 摄像头连接器,用于连接 ESP-LyraP-CAM -- 触摸 FPC 连接器,用于连接 ESP-LyraP-TouchA -- LCD FPC 连接器(尚无可用官方配套扩展板) -- I2C FPC 连接器(尚无可用官方配套扩展板) - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-3d.png - :align: center - :width: 2631px - :height: 1966px - :scale: 25% - :alt: ESP32-S2-Kaluga-1 - :figclass: align-center - - ESP32-S2-Kaluga-1(点击放大) - -所有四个扩展板都经过特别设计,以支持以下功能: - -* 触摸板控制 - * 带有 6 个触摸按钮 - * 支持最大 5 mm 亚克力板 - * 支持湿手操作 - * 支持防水功能。ESP32-S2 可以配置为在多个触摸板同时被水复盖时自动禁用所有触摸板功能,并在去除水滴后重新启用触摸板 - -* 音频播放 - * 连接扬声器,以播放音频 - * 配合触控板使用,可控制音频播放和调节音量 - -* LCD 显示屏 - * LCD 接口(8 位并行 RGB、8080 和 6800 接口) - -* 摄像头图像采集 - * 支持 OV2640 和 OV3660 摄像头模块 - * 8-bit DVP 图像传感器接口(ESP32-S2 还支持 16 位 DVP 图像传感器,但需要你自行进行二次开发) - * 支持高达 40 MHz 时钟频率 - * 优化 DMA 传输带宽,便于传输高分辨率图像 - - -组件描述 --------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-layout-front.png - :align: center - :width: 934px - :height: 645px - :scale: 70% - :alt: ESP32-S2-Kaluga-1 - 正面 - :figclass: align-center - - ESP32-S2-Kaluga-1 - 正面(点击放大) - - -下表将从左边的 ESP32-S2 模组开始,以顺时针顺序介绍上图中的主要组件。 - -**保留** 表示该功能可用,但当前版本的套件并未启用该功能。 - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - ESP32-S2-WROVER 模组 - - 集成 ESP32-S2 芯片,可提供 Wi-Fi 连接、数据处理和灵活的数据存储功能。 - * - 4.3" LCD FPC 连接器 - - (保留)可使用 FPC 线连接 4.3" LCD 扩展板。 - * - ESP Prog 连接器 - - (保留)用于连接乐鑫固件烧录设备 (ESP-Prog)。 - * - JTAG 开关 - - 切换到 ON 方向,启用 ESP32-S2 和 FT2232 之间的连接。此时,可通过 USB-UART/JTAG 端口进行 JTAG 调试,详见 :doc:`../../api-guides/jtag-debugging/index`。 - * - 引出管脚排针 2 - - ESP32-S2-WROVER 模组的部分 GPIO 直接引出至该开发板(详见开发板上的标记)。 - * - USB-to-UART/JTAG 桥接器 - - FT2232 适配器开发板,允许在 USB 端口使用 UART/JTAG 协议通信。 - * - 摄像头连接器 - - 用于连接摄像头扩展板,比如 ESP-LyraP-CAM。 - * - 扩展板连接器 - - 用于连接带有配套连接器的扩展板。 - * - Reset 复位按钮 - - 用于重启系统。 - * - Boot 按钮 - - 按下 **Boot** 键并保持,同时按一下 **Reset** 键,进入“固件下载”模式,通过串口下载固件。 - * - USB-UART/JTAG 端口 - - PC 和 ESP32-S2 模组之间的通信接口(UART 或 JTAG)。 - * - USB 电源端口 - - 为开发板供电。 - * - 电池端口 - - 2 针连接器,用于连接外部电池。 - * - 电源 LED 指示灯 - - 当 USB 电源或外部电源供电电压正常,则 LED 亮起。 - * - 电源开关 - - 打开可为系统供电。 - * - RGB 跳线 - - 如需使用 RGB LED,需在该位置增加一个跳线。 - * - RGB LED 指示灯 - - 可编程 RGB LED 指示灯,受控于 GPIO45。在使用前需要安装 RGB 跳线。 - * - 调压器 - - 5 V 转 3.3 V 调压器。 - * - I2C FPC 连接器 - - (保留)可通过 FPC 线连接其他 I2C 扩展板。 - * - 引出管脚排针 1 - - ESP32-S2-WROVER 模组的部分 GPIO 直接引出至该开发板(详见开发板上的标记)。 - * - 触摸 FPC 连接器 - - 可通过 FPC 线连接 ESP-LyraP-TouchA 扩展板。 - * - 触摸开关 - - 切换到 OFF 方向,配置 GPIO1 到 GPIO14 连接触摸传感器;切换到 ON 方向,配置 GPIO1 到 GPIO14 用于其他目的。 - * - 3.2" LCD FPC 连接器 - - 可通过 FPC 线连接 3.2" LCD 扩展板,比如 ESP-LyraP-LCD32。 - - -应用程序开发 ------------- - -ESP32-S2-Kaluga-1 上电前,请首先确认开发板完好无损。 - - -硬件准备 -^^^^^^^^ - -- ESP32-S2-Kaluga-1 -- 两根 USB 2.0 电缆(标准 A 转 Micro-B) - - - 电源选项 - - 用于 UART/JTAG 通信 - -- PC(Windows、Linux 或 macOS) -- 你选择的任何扩展板 - - -硬件设置 -^^^^^^^^ - -1. 连接你选择的扩展板(更多信息,请见对应拓展板的用户指南) -2. 插入两根 USB 电缆 -3. 打开 **电源开关** 时,**电源 LED 指示灯** 应点亮。 - - -.. _user-guide-esp32-s2-kaluga-1-kit-v1.2-software-setup: - -软件设置 -^^^^^^^^ - -请前往 :doc:`../../get-started/index`,在 :ref:`get-started-step-by-step` 一节查看如何快速设置开发环境。 - -你还可以点击 `这里 `_,获取有关 ESP32-S2-Kaluga-1 套件编程指南与应用示例的更多内容。 - - -内容和包装 ----------- - -零售订单 -^^^^^^^^ - -每一个零售 ESP32-S2-Kaluga-1 开发套件均有独立包装,内含以下部分: - -- 主板 - - ESP32-S2-Kaluga-1 -- 扩展板: - - ESP-LyraT-8311A - - ESP-LyraP-CAM - - ESP-LyraP-TouchA - - ESP-LyraP-LCD32 -- 连接器 - - 20 针 FPC 线(用于连接 ESP32-S2-Kaluga-1 主板至 ESP-LyraP-TouchA 扩展板) -- 紧固件 - - 安装螺栓 (x 8) - - 螺丝 (x 4) - - 螺母 (x 4) - -零售购买,请前往 https://www.espressif.com/zh-hans/contact-us/get-samples。 - - -批发订单 -^^^^^^^^ - -ESP32-S2-Kaluga-1 开发套件的批发包装为纸板箱。 - -批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 - - -硬件参考 -======== - -功能框图 --------- - -ESP32-S2-Kaluga-1 的主要组件和连接方式如下图所示。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-block-diagram.png - :align: center - :alt: ESP32-S2-Kaluga-1 功能框图 - :figclass: align-center - - ESP32-S2-Kaluga-1 功能框图 - - -电源选项 --------- - -开发板可任一选用以下四种供电方式: - -- Micro USB 端口供电(默认) -- 通过 2 针电池连接器使用外部电池供电 -- 5V / GND 管脚供电 -- 3V3 / GND 管脚供电 - - -.. _user-guide-esp32-s2-kaluga-1-kit-v1.2-ext-board-compatibility: - -扩展板的兼容性 --------------- - -如需同时使用多块扩展板,请首先查看以下兼容性信息: - -.. list-table:: - :widths: 20 10 30 40 - :header-rows: 1 - - * - 扩展板组合 - - 复用接口或管脚 - - 无法运行原因 - - 解决方案 - * - 8311A v1.2 + CAM v1.0 - - I2S 控制、IO46 - - ESP32-S2 仅有 1 个 I2S 接口,但这两个开发板均需使用 ESP32-S2 的 I2S 接口进行通信(ESP-LyraT-8311A 使用标准模式;ESP-LyraP-CAM 使用 Camera 协议)。如两个扩展板同时复用 IO46,ESP-LyraP-CAM 的正常使用将受到干扰。 - - 暂无解决方法。 - * - TouchA v1.1 + LCD32 v1.1 - - IO11、IO6 - - ESP-LyraP-TouchA 因管脚 IO11 复用,导致无法触发触摸动作;ESP-LyraP-LCD32 因 BK (BLCT) 管脚连接至 IO6 管脚复用,因此也无法使用。 - - 不要初始化 ESP-LyraP-TouchA 扩展板的 IO11 (NETWORK) 和 IO6 (PHOTO) 管脚。 - * - 8311A v1.2 + LCD32 v1.1 - - IO6 - - 这两款扩展板可以同时使用,但由于 ESP32-S2-Kaluga-1 的 BK (BLCT) 管脚已连接至 IO6,因此,ESP-LyraT-8311A 的 BT_ADC 管脚和 6 个按钮均无法使用。 - - 用户也可通过以下配置使用 ESP-LyraT-8311A 的 BT_ADC 管脚:移除 ESP-LyraP-LCD32 扩展板上的 R39,将 R41 换为 100 欧,并将 BLCT_L 开关打开。注意,此配置将导致用户无法通过软件控制显示屏的背光亮度。 - * - TouchA v1.1 + 8311A v1.2 - - ESP-LyraT-8311A 的 BT_ADC 管脚 - - 这两款扩展板可以同时使用。然而,当 ESP-LyraT-8311A 的 BT_ADC 管脚用于初始化扩展板的 6 个按钮时,ESP-LyraP-TouchA 无法成功触发。 - - 如果计划使用 ESP-LyraT-8311A 的 BT_ADC 管脚,请不要初始化 ESP-LyraP-TouchA 扩展板的 IO6 管脚 (PHOTO)。 - * - TouchA v1.1 + CAM v1.0 - - IO1、IO2、IO3 - - 由于管脚复用无法同时使用。 - - 不要初始化 ESP-LyraP-TouchA 的 IO1 (VOL_UP)、IO2 (PLAY) 和 IO3 (VOL_DOWN)。 - * - TouchA v1.1 + LCD32 v1.1 + CAM v1.0 - - IO1、IO2、IO3、IO6、IO11 - - 由于管脚复用无法同时使用。 - - **解决方案 1**:不要初始化 ESP-LyraP-TouchA 扩展板的 IO1 (VOL_UP)、IO2 (PLAY)、IO3 (VOL_DOWN)、IO6 (PHOTO) 和 IO11 (NETWORK)。 **解决方案 2**:用户也可通过以下配置正常初始化 IO6 (PHOTO):移除 ESP-LyraP-LCD32 扩展板上的 R39,将 R41 换为 100 欧,并将 BLCT_L 开关打开。注意,此配置将导致用户无法通过软件控制显示屏的背光亮度。 - * - TouchA v1.1 + LCD32 v1.1 + 8311A v1.2 - - IO6、IO11 - - IO11 管脚复用导致无法同时使用;IO6 管脚复用导致 ESP-LyraT-8311A 的 BT_ADC 管脚无法使用,因此无法初始化该扩展板的 6 个按钮。 - - **解决方法 1**:不要初始化 ESP-LyraP-TouchA 扩展板的 IO6 (PHOTO) 和 IO11 (NETWORK)。注意,此时 ESP-LyraT-8311A 的 6 个按钮依然无法使用。**解决方法 2**:移除 ESP-LyraP-LCD32 扩展板上的 R39,将 R41 换为 100 欧,并将 BLCT_L 开关打开。不要初始化 ESP-LyraP-TouchA 的 IO11 (NETWORK)。如果希望使用 ESP-LyraT-8311A 的 6 个按钮,则也不要初始化 IO6 (PHOTO)。 - -另外,所有扩展板和 :ref:`JTAG 接口 ` 共用管脚 IO39、IO40、IO41 和 IO42。因此,以下情况可能会干扰 JTAG 操作: - -* 插上扩展板 -* 调试正在使用扩展板的应用程序 - - -已知问题 -======== - -.. list-table:: - :widths: 22 24 32 22 - :header-rows: 1 - - * - 问题硬件 - - 描述 - - 主要原因 - - 解决方法 - * - ESP-LyraP-CAM v1.0、管脚 IO45、管脚 IO46 - - 当 ESP-LyraP-CAM v1.0 连接至主板时,可能导致主板无法烧录固件。 - - 开发板上电时,strapping 管脚 IO45 和 IO46 的上电时序错误,导致开发板无法正常启动。 - - 主板烧录固件时,不应连接该扩展板。 - * - ESP-LyraP-CAM v1.0、管脚 IO45、管脚 IO46 - - 使用 Reset 复位按键重启开发板可能无法达到期望结果。 - - 开发板上电时,strapping 管脚 IO45 和 IO46 的上电时序错误,导致开发板无法正常启动。 - - v1.2 暂无解决方法。该问题已经在 ESP32-S2-Kaluga-1 V1.3 中进行了修复。 - * - ESP-LyraT-8311A v1.2、管脚 IO46 - - 当 ESP-LyraT-8311A v1.2 连接至主板时,可能导致主板无法烧录固件。 - - 开发板上电时,strapping 管脚 IO46 的上电时序错误,导致开发板无法正常启动。 - - 主板烧录固件时,不应连接该扩展板。 - * - ESP-LyraT-8311A v1.2、管脚 IO46 - - 使用 Reset 复位按键重启开发板可能无法达到期望结果。 - - 开发板上电时,strapping 管脚 IO46 的上电时序错误,导致开发板无法正常启动。 - - v1.2 暂无解决方法。该问题已经在 ESP32-S2-Kaluga-1 V1.3 中进行了修复。 - - -硬件修订历史 -============ - -尚无版本升级历史。 - - -相关文档 -======== - -.. toctree:: - :hidden: - - user-guide-esp-lyrap-cam-v1.0 - user-guide-esp-lyrap-lcd32-v1.1 - user-guide-esp-lyrap-toucha-v1.1 - user-guide-esp-lyrat-8311a_v1.2 - -- `ESP32-S2-WROVER 技术规格书 `_ (PDF) -- `乐鑫产品选型工具 `__ -- :doc:`../../api-guides/jtag-debugging/index` - -- `ESP32-S2-Kaluga-1 原理图 `_ (PDF) -- `ESP32-S2-Kaluga-1 PCB 布局图 `_ (PDF) -- `ESP32-S2-Kaluga-1 管脚映射 `_ (Excel) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 diff --git a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst b/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst deleted file mode 100644 index 3653dff6a97c..000000000000 --- a/docs/zh_CN/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.rst +++ /dev/null @@ -1,395 +0,0 @@ -============================== -ESP32-S2-Kaluga-1 套件 v1.3 -============================== - -:link_to_translation:`en:[English]` - -更早版本::doc:`user-guide-esp32-s2-kaluga-1-kit-v1.2` - -ESP32-S2-Kaluga-1 v1.3 是一款来自乐鑫的开发套件,主要可用于以下目的: - -- 展示 ESP32-S2 芯片的人机交互功能 -- 为用户提供基于 ESP32-S2 的人机交互应用开发工具 - -ESP32-S2 的功能强大,应用场景非常丰富。对于初学者来说,可能的用例包括: - -- **智能家居**:从最简单的智能照明、智能门锁、智能插座,到更复杂的视频流设备、安防摄像头、OTT 设备和家用电器等 -- **电池供电设备**:Wi-Fi mesh 传感器网络、Wi-Fi 网络玩具、可穿戴设备、健康管理设备等 -- **工业自动化设备**:无线控制与机器人技术、智能照明、HVAC 控制设备等 -- **零售和餐饮业**:POS 机和服务机器人 - -.. Image of v1.2 is used as there are no visual changes - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-kit-v1.0-3d.png - :align: center - :width: 3452px - :height: 1590px - :scale: 20% - :alt: ESP32-S2-Kaluga-1-Kit-Assembly - :figclass: align-center - - ESP32-S2-Kaluga-1-Kit 概述(点击放大) - - -ESP32-S2-Kaluga-1 套件包括以下几个开发板: - -- 主板:*ESP32-S2-Kaluga-1* -- 扩展板: - - - :doc:`user-guide-esp-lyrat-8311a_v1.3` - 音频播放器 - - :doc:`user-guide-esp-lyrap-toucha-v1.1` - 触摸板 - - :doc:`user-guide-esp-lyrap-lcd32-v1.2` - 3.2" LCD 屏 - - :doc:`user-guide-esp-lyrap-cam-v1.1` - 摄像头 - -由于 ESP32-S2 的管脚复用,部分扩展板的兼容性有所限制,具体请见 :ref:`user-guide-esp32-s2-kaluga-1-kit-ext-board-compatibility`。 - -本文档主要介绍 **ESP32-S2-Kaluga-1 主板** 及其与扩展板的交互。更多有关具体扩展板的信息,请点击相应的链接。 - -本指南包括: - -- `快速入门`_:提供 ESP32-S2-Kaluga-1 的简要概述及必须了解的硬件和软件信息。 -- `硬件参考`_:提供 ESP32-S2-Kaluga-1 的详细硬件信息。 -- `硬件修订历史`_:提供该开发版的“修订历史”、“已知问题”以及此前版本开发板的用户指南链接。 -- `相关文档`_:提供相关文档的链接。 - - -快速入门 -======== - -本节介绍如何开始使用 ESP32-S2-Kaluga-1,主要包括三大部分:首先,介绍一些关于 ESP32-S2-Kaluga-1 的基本信息;然后,在 `应用程序开发`_ 章节介绍如何进行硬件初始化;最后,介绍如何为 ESP32-S2-Kaluga-1 烧录固件。 - - -概述 ----- - -ESP32-S2-Kaluga-1 主板是整个套件的核心。该主板集成了 ESP32-S2-WROVER 模组,并配备连接至各个扩展板的连接器。ESP32-S2-Kaluga-1 是人机交互接口原型设计的关键工具。 - -ESP32-S2-Kaluga-1 主板配备了多个连接器,可用于连接相应扩展板: - -- 扩展板连接器,用于连接 ESP-LyraT-8311A、ESP-LyraP-LCD32 -- 摄像头连接器,用于连接 ESP-LyraP-CAM -- 触摸 FPC 连接器,用于连接 ESP-LyraP-TouchA -- LCD FPC 连接器(尚无可用官方配套扩展板) -- I2C FPC 连接器(尚无可用官方配套扩展板) - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32s2-kaluga-1-v1.3-3d.png - :align: center - :width: 3089px - :height: 2335px - :scale: 25% - :alt: ESP32-S2-Kaluga-1 - :figclass: align-center - - ESP32-S2-Kaluga-1(点击放大) - -所有四个扩展板都经过特别设计,以支持以下功能: - -* 触摸板控制 - * 带有 6 个触摸按钮 - * 支持最大 5 mm 亚克力板 - * 支持湿手操作 - * 支持防水功能。ESP32-S2 可以配置为在多个触摸板同时被水复盖时自动禁用所有触摸板功能,并在去除水滴后重新启用触摸板 - -* 音频播放 - * 连接扬声器,以播放音频 - * 配合触控板使用,可控制音频播放和调节音量 - -* LCD 显示屏 - * LCD 接口(8 位并行 RGB、8080 和 6800 接口) - -* 摄像头图像采集 - * 支持 OV2640 和 OV3660 摄像头模块 - * 8-bit DVP 图像传感器接口(ESP32-S2 还支持 16 位 DVP 图像传感器,但需要你自行进行二次开发) - * 支持高达 40 MHz 时钟频率 - * 优化 DMA 传输带宽,便于传输高分辨率图像 - - -组件描述 --------- - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.3-layout-front.png - :align: center - :width: 934px - :height: 645px - :scale: 70% - :alt: ESP32-S2-Kaluga-1 - 正面 - :figclass: align-center - - ESP32-S2-Kaluga-1 - 正面(点击放大) - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.3-layout-back.png - :align: center - :width: 934px - :height: 600px - :scale: 70% - :alt: ESP32-S2-Kaluga-1 - 反面 - :figclass: align-center - - ESP32-S2-Kaluga-1 - 反面(点击放大) - - -下表将从左边的 ESP32-S2 模组开始,以顺时针顺序介绍上图中的主要组件。 - -**保留** 表示该功能可用,但当前版本的套件并未启用该功能。 - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - 主要组件 - - 描述 - * - ESP32-S2-WROVER 模组 - - 集成 ESP32-S2 芯片,可提供 Wi-Fi 连接、数据处理和灵活的数据存储功能。 - * - 4.3" LCD FPC 连接器 - - (保留)可使用 FPC 线连接 4.3" LCD 扩展板。 - * - ESP Prog 连接器 - - (保留)用于连接乐鑫固件烧录设备 (ESP-Prog)。 - * - JTAG 开关 - - 切换到 ON 方向,启用 ESP32-S2 和 FT2232 之间的连接。此时,可通过 USB-UART/JTAG 端口进行 JTAG 调试,详见 :doc:`../../api-guides/jtag-debugging/index`。 - * - 引出管脚排针 2 - - ESP32-S2-WROVER 模组的部分 GPIO 直接引出至该开发板(详见开发板上的标记)。 - * - USB-to-UART/JTAG 桥接器 - - FT2232 适配器开发板,允许在 USB 端口使用 UART/JTAG 协议通信。 - * - 摄像头连接器 - - 用于连接摄像头扩展板,比如 ESP-LyraP-CAM。 - * - 扩展板连接器 - - 用于连接带有配套连接器的扩展板。 - * - Reset 复位按钮 - - 用于重启系统。 - * - Boot 按钮 - - 按下 **Boot** 键并保持,同时按一下 **Reset** 键,进入“固件下载”模式,通过串口下载固件。 - * - USB-UART/JTAG 端口 - - PC 和 ESP32-S2 模组之间的通信接口(UART 或 JTAG)。 - * - USB 电源端口 - - 为开发板供电。 - * - 电池端口 - - 2 针连接器,用于连接外部电池。 - * - 电源 LED 指示灯 - - 当 USB 电源或外部电源供电电压正常,则 LED 亮起。 - * - 电源开关 - - 打开可为系统供电。 - * - RGB 跳线 - - 如需使用 RGB LED,需在该位置增加一个跳线。 - * - RGB LED 指示灯 - - 可编程 RGB LED 指示灯,受控于 GPIO45。在使用前需要安装 RGB 跳线。 - * - 调压器 - - 5 V 转 3.3 V 调压器。 - * - I2C FPC 连接器 - - (保留)可通过 FPC 线连接其他 I2C 扩展板。 - * - 引出管脚排针 1 - - ESP32-S2-WROVER 模组的部分 GPIO 直接引出至该开发板(详见开发板上的标记)。 - * - 触摸 FPC 连接器 - - 可通过 FPC 线连接 ESP-LyraP-TouchA 扩展板。 - * - 触摸开关 - - 切换到 OFF 方向,配置 GPIO1 到 GPIO14 连接触摸传感器;切换到 ON 方向,配置 GPIO1 到 GPIO14 用于其他目的。 - * - 3.2" LCD FPC 连接器 - - 可通过 FPC 线连接 3.2" LCD 扩展板,比如 ESP-LyraP-LCD32。 - - -应用程序开发 ------------- - -ESP32-S2-Kaluga-1 上电前,请首先确认开发板完好无损。 - - -硬件准备 -^^^^^^^^ - -- ESP32-S2-Kaluga-1 -- 两根 USB 2.0 电缆(标准 A 转 Micro-B) - - - 电源选项 - - 用于 UART/JTAG 通信 - -- PC(Windows、Linux 或 macOS) -- 你选择的任何扩展板 - - -硬件设置 -^^^^^^^^ - -1. 连接你选择的扩展板(更多信息,请见对应拓展板的用户指南) -2. 插入两根 USB 电缆 -3. 打开 **电源开关** 时,**电源 LED 指示灯** 应点亮。 - - -.. _user-guide-esp32-s2-kaluga-1-kit-software-setup: - -软件设置 -^^^^^^^^ - -请前往 :doc:`../../get-started/index`,在 :ref:`get-started-step-by-step` 一节查看如何快速设置开发环境。 - -你还可以点击 `这里 `_,获取有关 ESP32-S2-Kaluga-1 套件编程指南与应用示例的更多内容。 - -你可以在 `IDF 组件注册器 `_ 中下载板级支持包 (BSP)。 - - -内容和包装 ----------- - -零售订单 -^^^^^^^^ - -每一个零售 ESP32-S2-Kaluga-1 开发套件均有独立包装。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32s2-kaluga-1-kit-v1.3-package-3d.png - :align: center - :alt: ESP32-S2-Kaluga-1 - 包装 - :figclass: align-center - - ESP32-S2-Kaluga-1 - 包装 - - -内含以下部分: - -- 主板 - - ESP32-S2-Kaluga-1 -- 扩展板: - - ESP-LyraT-8311A - - ESP-LyraP-CAM - - ESP-LyraP-TouchA - - ESP-LyraP-LCD32 -- 连接器 - - 20 针 FPC 线(用于连接 ESP32-S2-Kaluga-1 主板至 ESP-LyraP-TouchA 扩展板) -- 紧固件 - - 安装螺栓 (x 8) - - 螺丝 (x 4) - - 螺母 (x 4) - -零售购买,请前往 https://www.espressif.com/zh-hans/contact-us/get-samples。 - - -批发订单 -^^^^^^^^ - -ESP32-S2-Kaluga-1 开发套件的批发包装为纸板箱。 - -批量订单请前往 https://www.espressif.com/zh-hans/contact-us/sales-questions。 - - -硬件参考 -======== - -功能框图 --------- - -.. Image of v1.2 is used as there are no visual changes - -ESP32-S2-Kaluga-1 的主要组件和连接方式如下图所示。 - -.. figure:: https://dl.espressif.com/dl/schematics/pictures/esp32-s2-kaluga-1-v1.2-block-diagram.png - :align: center - :alt: ESP32-S2-Kaluga-1 功能框图 - :figclass: align-center - - ESP32-S2-Kaluga-1 功能框图 - - -电源选项 --------- - -开发板可任一选用以下四种供电方式: - -- Micro USB 端口供电(默认) -- 通过 2 针电池连接器使用外部电池供电 -- 5V / GND 管脚供电 -- 3V3 / GND 管脚供电 - - -.. _user-guide-esp32-s2-kaluga-1-kit-ext-board-compatibility: - -扩展板的兼容性 --------------- - -如需同时使用多块扩展板,请首先查看以下兼容性信息: - -.. list-table:: - :widths: 20 15 33 32 - :header-rows: 1 - - * - 扩展板组合 - - 复用接口或管脚 - - 无法运行原因 - - 解决方案 - * - 8311A v1.3 + CAM v1.1 - - I2S 控制器 - - ESP32-S2 仅有 1 个 I2S 接口,但这两个开发板均需使用 ESP32-S2 的 I2S 接口进行通信(ESP-LyraT-8311A 使用标准模式;ESP-LyraP-CAM 使用 Camera 协议)。 - - 采用分时复用;或另外选择一款可以通过其他 GPIOs 或 DAC 连接的音频扩展板。 - * - TouchA v1.1 + LCD32 v1.2 - - IO11、IO6 - - 由于管脚 IO11 复用,导致无法触发触摸动作;ESP-LyraP-LCD32 则由于其 BLCT 管脚已与 IO6 断开,因此不受影响。 - - 不要初始化 ESP-LyraP-TouchA 扩展板的 IO11 (NETWORK) 管脚;或者配置 ESP-LyraP-LCD32 扩展板的 BLCT 管脚为 `-1` (相当于不使用 BLCT)。 - * - 8311A v1.3 + LCD32 v1.2 - - IO6 - - 配置 ESP-LyraP-LCD32 扩展板的 BK 管脚为 `-1` (相当于不使用 BK)。 - - ESP32-S2-Kaluga-1 的 BLCT 管脚将从 IO6 断开。 - * - TouchA v1.1 + 8311A v1.3 - - ESP-LyraT-8311A 的 BT_ADC 管脚 - - ESP-LyraT-8311A 在初始化 6 个按钮时需要使用 BT_ADC 管脚,而 ESP-LyraP-TouchA 在完成触摸动作时也需要使用 BT_ADC 管脚。 - - 如需使用 ESP-LyraT-8311A 的 6 个按钮,则不要初始化 ESP-LyraP-TouchA 的 IO6 (PHOTO) 管脚。 - * - TouchA v1.1 + CAM v1.1 - - IO1、IO2、IO3 - - 由于管脚复用无法同时使用。 - - 不要初始化 ESP-LyraP-TouchA 的 IO1 (VOL_UP)、IO2 (PLAY) 和 IO3 (VOL_DOWN)。 - * - TouchA v1.1 + LCD32 v1.2 + CAM v1.1 - - IO1、IO2、IO3、IO11 - - 由于管脚复用无法同时使用。 - - 不要初始化 ESP-LyraP-TouchA 的 IO1 (VOL_UP)、IO2 (PLAY)、IO3 (VOL_DOWN) 和 IO11 (NETWORK)。 - * - TouchA v1.1 + LCD32 v1.2 + 8311A v1.3 - - IO6、IO11 - - 如果使用 ESP-LyraT-8311A 的 BT_ADC 管脚初始化开发板的 6 个按钮,其他扩展板则无法使用 IO6 和 IO11。 - - 不要初始化 ESP-LyraP-TouchA 的 IO11 (NETWORK)。此外,如果需要使用 BT_ADC,则不要初始化 IO6 (PHOTO)。 - -另外,所有扩展板和 :ref:`JTAG 接口 ` 共用管脚 IO39、IO40、IO41 和 IO42。因此,以下情况可能会干扰 JTAG 操作: - -* 插上扩展板 -* 调试正在使用扩展板的应用程序 - - -硬件修订历史 -============ - -ESP32-S2-Kaluga-1 Kit v1.3 --------------------------- - -* 以下管脚已重新分配,以解决固件烧录问题: - - * Camera D2:GPIO36 - * Camera D3:GPIO37 - * AU_I2S1_SDI:GPIO34 - * AU_WAKE_INT:GPIO46 - -* RGB 已移动至开发板边缘 -* 所有 dip 开关均移动至开发板的反面,从而便利用户操作 - - -ESP32-S2-Kaluga-1 Kit v1.2 --------------------------- - -:doc:`首次发布 ` - - -相关文档 -======== - -.. toctree:: - :hidden: - - user-guide-esp32-s2-kaluga-1-kit-v1.2.rst - user-guide-esp-lyrap-cam-v1.1 - user-guide-esp-lyrap-lcd32-v1.2 - user-guide-esp-lyrat-8311a_v1.3 - -- `ESP32-S2-WROVER 技术规格书 `_ (PDF) -- `乐鑫产品选型工具 `__ -- :doc:`../../api-guides/jtag-debugging/index` - -- `ESP32-S2-Kaluga-1 原理图 `_ (PDF) -- `ESP32-S2-Kaluga-1 PCB 布局图 `_ (PDF) -- `ESP32-S2-Kaluga-1 管脚映射 `_ (Excel) - -有关本开发板的更多设计文档,请联系我们的商务部门 sales@espressif.com。 - - diff --git a/docs/zh_CN/hw-reference/index.rst b/docs/zh_CN/hw-reference/index.rst index 8ee7f2fa33f3..86cee7cc3497 100644 --- a/docs/zh_CN/hw-reference/index.rst +++ b/docs/zh_CN/hw-reference/index.rst @@ -7,7 +7,7 @@ H/W 硬件参考 .. toctree:: :maxdepth: 1 - 技术参考手册 (PDF) <{IDF_TARGET_TRM_CN_URL}> + :not esp32p4: 技术参考手册 (PDF) <{IDF_TARGET_TRM_CN_URL}> :esp32: 技术规格书 (PDF) :esp32s2: 技术规格书 (PDF) :esp32s3: 技术规格书 (PDF) @@ -15,7 +15,6 @@ H/W 硬件参考 :esp32c3: 技术规格书 (PDF) :esp32c6: 技术规格书 (PDF) :esp32h2: 技术规格书 (PDF) - :esp32p4: 技术规格书 (PDF) :esp32: 硬件设计指南 (PDF) :esp32s2: 硬件设计指南 (PDF) :esp32s3: 硬件设计指南 (PDF) @@ -23,7 +22,6 @@ H/W 硬件参考 :esp32c3: 硬件设计指南 (PDF) :esp32c6: 硬件设计指南 (PDF) :esp32h2: 硬件设计指南 (PDF) - :esp32p4: 硬件设计指南 (PDF) :esp32: 勘误表及解决方法 (PDF) :esp32s2: 勘误表及解决方法 (PDF) :esp32s3: 勘误表及解决方法 (PDF) @@ -32,10 +30,10 @@ H/W 硬件参考 :esp32c6: 勘误表及解决方法 (PDF) :esp32h2: 勘误表及解决方法 (PDF) 芯片变型 - 模组 + :not esp32p4: 模组 开发板 - 乐鑫 KiCad 库 + :not esp32p4: 乐鑫 KiCad 库 乐鑫产品选型工具 - 乐鑫产品证书 + :not esp32p4: 乐鑫产品证书 芯片系列对比 官方论坛硬件版块 diff --git a/examples/bluetooth/.build-test-rules.yml b/examples/bluetooth/.build-test-rules.yml index 16d87cc996bc..121436ecebe5 100644 --- a/examples/bluetooth/.build-test-rules.yml +++ b/examples/bluetooth/.build-test-rules.yml @@ -46,6 +46,9 @@ examples/bluetooth/bluedroid/classic_bt: - esp_driver_uart depends_filepatterns: - components/driver/dac/**/* + - examples/bluetooth/bluedroid/esp_hid_host/**/* + - examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py + - examples/bluetooth/bluedroid/classic_bt/bt_discovery/pytest_classic_bt_discovery_test.py examples/bluetooth/bluedroid/coex/a2dp_gatts_coex: <<: *bt_default_depends @@ -106,6 +109,14 @@ examples/bluetooth/esp_ble_mesh/wifi_coexist: depends_filepatterns: - examples/bluetooth/esp_ble_mesh/common_components/**/* +examples/bluetooth/esp_hid_host: + disable_test: + - if: IDF_TARGET in ["esp32c2", "esp32c3", "esp32c5", "esp32c6", "esp32h2", "esp32s3"] + temporary: true + reason: temporarily test esp32 + disable: + - if: SOC_BT_SUPPORTED != 1 + examples/bluetooth/hci: <<: *bt_default_depends enable: diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/CMakeLists.txt b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/CMakeLists.txt new file mode 100644 index 000000000000..198b0586f02f --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(nimble_beacon) diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/README.md b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/README.md new file mode 100644 index 000000000000..98bb709c07c9 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/README.md @@ -0,0 +1,352 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# NimBLE Beacon Example + +## Overview + +This is a pretty simple example, aiming to introduce + +1. How to initialize NimBLE stack +2. How to configure advertisement and scan response data +3. How to start advertising as a non-connectable beacon + +It uses ESP32's Bluetooth controller and NimBLE host stack. + +To test this demo, any BLE scanner application can be used. + +## Try It Yourself + +### Set Target + +Before project configuration and build, be sure to set the correct chip target using: + +``` shell +idf.py set-target +``` + +For example, if you're using ESP32, then input + +``` Shell +idf.py set-target esp32 +``` + +### Build and Flash + +Run the following command to build, flash and monitor the project. + +``` Shell +idf.py -p flash monitor +``` + +For example, if the corresponding serial port is `/dev/ttyACM0`, then it goes + +``` Shell +idf.py -p /dev/ttyACM0 flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Code Explained + +### Overview + +1. Initialize NVS flash, NimBLE host stack and GAP service; configure NimBLE host stack and start NimBLE host task thread +2. Wait for NimBLE host stack to sync with BLE controller +3. Set advertisement and scan response data, then configure advertising parameters and start advertising + +### Entry Point + +`app_main` in `main.c` is the entry point of all ESP32 applications. In general, application initialization should be done here. + +First, call `nvs_flash_init` function to initialize NVS flash, which is the dependency for BLE module to store configurations. + +``` C +void app_main(void) { + /* Local variables */ + int rc; + esp_err_t ret; + + /* NVS flash initialization */ + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || + ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize nvs flash, error code: %d ", ret); + return; + } + + ... +} +``` + +Then, call `nimble_port_init` function to initialize NimBLE host stack. + +``` C +void app_main(void) { + ... + + /* NimBLE host stack initialization */ + ret = nimble_port_init(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize nimble stack, error code: %d ", + ret); + return; + } + + ... +} +``` + +After that, call `gap_init` defined in `gap.c`. We will initialize GAP service, set GAP device name and appearance in this function. + +``` C +int gap_init(void) { + /* Local variables */ + int rc = 0; + + /* Initialize GAP service */ + ble_svc_gap_init(); + + /* Set GAP device name */ + rc = ble_svc_gap_device_name_set(DEVICE_NAME); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set device name to %s, error code: %d", + DEVICE_NAME, rc); + return rc; + } + + /* Set GAP device appearance */ + rc = ble_svc_gap_device_appearance_set(BLE_GAP_APPEARANCE_GENERIC_TAG); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set device appearance, error code: %d", rc); + return rc; + } + return rc; +} + +void app_main(void) { + ... + + /* GAP service initialization */ + rc = gap_init(); + if (rc != 0) { + ESP_LOGE(TAG, "failed to initialize GAP service, error code: %d", rc); + return; + } + + ... +} +``` + +And we need to configure some callback functions for NimBLE host stack to call and store the configurations in `nimble_host_config_init` in `main.c`. + +``` C +static void nimble_host_config_init(void) { + /* Set host callbacks */ + ble_hs_cfg.reset_cb = on_stack_reset; + ble_hs_cfg.sync_cb = on_stack_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Store host configuration */ + ble_store_config_init(); +} + +void app_main(void) { + ... + + /* NimBLE host configuration initialization */ + nimble_host_config_init(); + + ... +} +``` + +So far, initialization has been done. We can call `xTaskCreate` to create `nimble_host_task` thread, and let NimBLE host stack run in the background. + +``` C +static void nimble_host_task(void *param) { + /* Task entry log */ + ESP_LOGI(TAG, "nimble host task has been started!"); + + /* This function won't return until nimble_port_stop() is executed */ + nimble_port_run(); + + /* Clean up at exit */ + vTaskDelete(NULL); +} + +void app_main(void) { + ... + + /* Start NimBLE host task thread and return */ + xTaskCreate(nimble_host_task, "NimBLE Host", 4*1024, NULL, 5, NULL); + return; +} +``` + +### On Stack Sync + +Once NimBLE host stack is synced with BLE controller, `on_stack_sync` in `gap.c` will be called by NimBLE host stack, which has been configured in `nimble_host_config_init`. + +In this function, we will call `adv_init` function to ask NimBLE host stack to check if device MAC address is available by `ble_hs_util_ensure_addr` and `ble_hs_id_infer_auto` functions. If so, we will copy the address and try to start advertising by calling `start_advertising` in the same source file. + +``` C +static void on_stack_sync(void) { + /* On stack sync, do advertising initialization */ + adv_init(); +} + +void adv_init(void) { + /* Local variables */ + int rc = 0; + char addr_str[18] = {0}; + + /* Make sure we have proper BT identity address set */ + rc = ble_hs_util_ensure_addr(0); + if (rc != 0) { + ESP_LOGE(TAG, "device does not have any available bt address!"); + return; + } + + /* Figure out BT address to use while advertising */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGE(TAG, "failed to infer address type, error code: %d", rc); + return; + } + + /* Copy device address to addr_val */ + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to copy device address, error code: %d", rc); + return; + } + format_addr(addr_str, addr_val); + ESP_LOGI(TAG, "device address: %s", addr_str); + + /* Start advertising. */ + start_advertising(); +} +``` + +### Start Advertising + +As a beacon device, we're going to start advertising and send scan response if a scan request is received. To make it happen, we need to set advertisement and scan response data before advertising starts. So the following are what we do: + +1. Initialize advertisement and scan response fields structs `adv_fields` and `rsp_fields`, as well as advertising parameters struct `adv_params` + +``` C +static void start_advertising(void) { + /* Local variables */ + int rc = 0; + const char *name; + struct ble_hs_adv_fields adv_fields = {0}; + struct ble_hs_adv_fields rsp_fields = {0}; + struct ble_gap_adv_params adv_params = {0}; + + ... +} +``` + +2. Set advertising flags, device name, transmit power, appearance and LE role in `adv_fields`, and call `ble_gap_adv_set_fields` + 1. For adveritisng flags, `BLE_HS_ADV_F_DISC_GEN` means advertising is general discoverable, and `BLE_HS_ADV_F_BREDR_UNSUP` means BLE support only (BR/EDR refers to Bluetooth Classic) + 2. For appearance, it is used to tell scanner what does it look like; we use `BLE_GAP_APPEARANCE_GENERIC_TAG` here to make our device identified as a tag + +``` C +static void start_advertising(void) { + ... + + /* Set advertising flags */ + adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; + + /* Set device name */ + name = ble_svc_gap_device_name(); + adv_fields.name = (uint8_t *)name; + adv_fields.name_len = strlen(name); + adv_fields.name_is_complete = 1; + + /* Set device tx power */ + adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + adv_fields.tx_pwr_lvl_is_present = 1; + + /* Set device appearance */ + adv_fields.appearance = BLE_GAP_APPEARANCE_GENERIC_TAG; + adv_fields.appearance_is_present = 1; + + /* Set device LE role */ + adv_fields.le_role = BLE_GAP_LE_ROLE_PERIPHERAL; + adv_fields.le_role_is_present = 1; + + /* Set advertiement fields */ + rc = ble_gap_adv_set_fields(&adv_fields); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set advertising data, error code: %d", rc); + return; + } + + ... +} +``` + +3. Set device address and URI in `rsp_fields`, and call `ble_gap_adv_rsp_set_fields` + 1. Since `AdvData` in advertisement packet **should not be longer than 31 bytes**, additional information must be placed in scan response packet + 2. We put the official website link of espressif into URI field + +``` C +static void start_advertising(void) { + ... + + /* Set device address */ + rsp_fields.device_addr = addr_val; + rsp_fields.device_addr_type = own_addr_type; + rsp_fields.device_addr_is_present = 1; + + /* Set URI */ + rsp_fields.uri = esp_uri; + rsp_fields.uri_len = sizeof(esp_uri); + + /* Set scan response fields */ + rc = ble_gap_adv_rsp_set_fields(&rsp_fields); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set scan response data, error code: %d", rc); + return; + } + + ... +} +``` + +4. Set advertising mode and discoverable mode to non-connectable and general-discoverable respectively in `adv_params`, and finally, start advertising by calling `ble_gap_adv_start` + +``` C +static void start_advertising(void) { + ... + + /* Set non-connetable 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; + + /* Start advertising */ + rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params, + NULL, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to start advertising, error code: %d", rc); + return; + } + ESP_LOGI(TAG, "advertising started!"); +} +``` + +### Observation + +If everything goes well, you should be able to see `NimBLE_Beacon` on a BLE scanner device, broadcasting a lot of information including an URI of "https://espressif.com" (The official website of espressif), which is exactly what we expect. + +## Troubleshooting + +For any technical queries, please file an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/CMakeLists.txt b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/CMakeLists.txt new file mode 100644 index 000000000000..584111329971 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB_RECURSE srcs "main.c" "src/*.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "./include") diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/include/common.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/include/common.h new file mode 100644 index 000000000000..a460febb8261 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/include/common.h @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef COMMON_H +#define COMMON_H + +/* Includes */ +/* STD APIs */ +#include +#include +#include + +/* ESP APIs */ +#include "esp_log.h" +#include "nvs_flash.h" +#include "sdkconfig.h" + +/* FreeRTOS APIs */ +#include +#include + +/* NimBLE stack APIs */ +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "host/util/util.h" +#include "nimble/ble.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" + +/* Defines */ +#define TAG "NimBLE_Beacon" +#define DEVICE_NAME "NimBLE_Beacon" + +#endif // COMMON_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/include/gap.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/include/gap.h new file mode 100644 index 000000000000..752ec002591a --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/include/gap.h @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef GAP_SVC_H +#define GAP_SVC_H + +/* Includes */ +/* NimBLE GAP APIs */ +#include "services/gap/ble_svc_gap.h" + +/* Defines */ +#define BLE_GAP_APPEARANCE_GENERIC_TAG 0x0200 +#define BLE_GAP_URI_PREFIX_HTTPS 0x17 +#define BLE_GAP_LE_ROLE_PERIPHERAL 0x00 + +/* Public function declarations */ +void adv_init(void); +int gap_init(void); + +#endif // GAP_SVC_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/main.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/main.c new file mode 100644 index 000000000000..2903a67c02fc --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/main.c @@ -0,0 +1,94 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "common.h" +#include "gap.h" + +/* Library function declarations */ +void ble_store_config_init(void); + +/* Private function declarations */ +static void on_stack_reset(int reason); +static void on_stack_sync(void); +static void nimble_host_config_init(void); +static void nimble_host_task(void *param); + +/* Private functions */ +/* + * Stack event callback functions + * - on_stack_reset is called when host resets BLE stack due to errors + * - on_stack_sync is called when host has synced with controller + */ +static void on_stack_reset(int reason) { + /* On reset, print reset reason to console */ + ESP_LOGI(TAG, "nimble stack reset, reset reason: %d", reason); +} + +static void on_stack_sync(void) { + /* On stack sync, do advertising initialization */ + adv_init(); +} + +static void nimble_host_config_init(void) { + /* Set host callbacks */ + ble_hs_cfg.reset_cb = on_stack_reset; + ble_hs_cfg.sync_cb = on_stack_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Store host configuration */ + ble_store_config_init(); +} + +static void nimble_host_task(void *param) { + /* Task entry log */ + ESP_LOGI(TAG, "nimble host task has been started!"); + + /* This function won't return until nimble_port_stop() is executed */ + nimble_port_run(); + + /* Clean up at exit */ + vTaskDelete(NULL); +} + +void app_main(void) { + /* Local variables */ + int rc = 0; + esp_err_t ret = ESP_OK; + + /* NVS flash initialization */ + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || + ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize nvs flash, error code: %d ", ret); + return; + } + + /* NimBLE host stack initialization */ + ret = nimble_port_init(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize nimble stack, error code: %d ", + ret); + return; + } + + /* GAP service initialization */ + rc = gap_init(); + if (rc != 0) { + ESP_LOGE(TAG, "failed to initialize GAP service, error code: %d", rc); + return; + } + + /* NimBLE host configuration initialization */ + nimble_host_config_init(); + + /* Start NimBLE host task thread and return */ + xTaskCreate(nimble_host_task, "NimBLE Host", 4*1024, NULL, 5, NULL); + return; +} 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 new file mode 100644 index 000000000000..71e03ba7c2aa --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/src/gap.c @@ -0,0 +1,146 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "gap.h" +#include "common.h" + +/* Private function declarations */ +inline static void format_addr(char *addr_str, uint8_t addr[]); +static void start_advertising(void); + +/* Private variables */ +static uint8_t own_addr_type; +static uint8_t addr_val[6] = {0}; +static uint8_t esp_uri[] = {BLE_GAP_URI_PREFIX_HTTPS, '/', '/', 'e', 's', 'p', 'r', 'e', 's', 's', 'i', 'f', '.', 'c', 'o', 'm'}; + +/* Private functions */ +inline static void format_addr(char *addr_str, uint8_t addr[]) { + sprintf(addr_str, "%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1], + addr[2], addr[3], addr[4], addr[5]); +} + +static void start_advertising(void) { + /* Local variables */ + int rc = 0; + const char *name; + struct ble_hs_adv_fields adv_fields = {0}; + struct ble_hs_adv_fields rsp_fields = {0}; + struct ble_gap_adv_params adv_params = {0}; + + /* Set advertising flags */ + adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; + + /* Set device name */ + name = ble_svc_gap_device_name(); + adv_fields.name = (uint8_t *)name; + adv_fields.name_len = strlen(name); + adv_fields.name_is_complete = 1; + + /* Set device tx power */ + adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + adv_fields.tx_pwr_lvl_is_present = 1; + + /* Set device appearance */ + adv_fields.appearance = BLE_GAP_APPEARANCE_GENERIC_TAG; + adv_fields.appearance_is_present = 1; + + /* Set device LE role */ + adv_fields.le_role = BLE_GAP_LE_ROLE_PERIPHERAL; + adv_fields.le_role_is_present = 1; + + /* Set advertiement fields */ + rc = ble_gap_adv_set_fields(&adv_fields); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set advertising data, error code: %d", rc); + return; + } + + /* Set device address */ + rsp_fields.device_addr = addr_val; + rsp_fields.device_addr_type = own_addr_type; + rsp_fields.device_addr_is_present = 1; + + /* Set URI */ + rsp_fields.uri = esp_uri; + rsp_fields.uri_len = sizeof(esp_uri); + + /* Set scan response fields */ + rc = ble_gap_adv_rsp_set_fields(&rsp_fields); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set scan response data, error code: %d", rc); + return; + } + + /* Set non-connetable 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; + + /* Start advertising */ + rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params, + NULL, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to start advertising, error code: %d", rc); + return; + } + ESP_LOGI(TAG, "advertising started!"); +} + +/* Public functions */ +void adv_init(void) { + /* Local variables */ + int rc = 0; + char addr_str[18] = {0}; + + /* Make sure we have proper BT identity address set */ + rc = ble_hs_util_ensure_addr(0); + if (rc != 0) { + ESP_LOGE(TAG, "device does not have any available bt address!"); + return; + } + + /* Figure out BT address to use while advertising */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGE(TAG, "failed to infer address type, error code: %d", rc); + return; + } + + /* Copy device address to addr_val */ + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to copy device address, error code: %d", rc); + return; + } + format_addr(addr_str, addr_val); + ESP_LOGI(TAG, "device address: %s", addr_str); + + /* Start advertising. */ + start_advertising(); +} + +int gap_init(void) { + /* Local variables */ + int rc = 0; + + /* Initialize GAP service */ + ble_svc_gap_init(); + + /* Set GAP device name */ + rc = ble_svc_gap_device_name_set(DEVICE_NAME); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set device name to %s, error code: %d", + DEVICE_NAME, rc); + return rc; + } + + /* Set GAP device appearance */ + rc = ble_svc_gap_device_appearance_set(BLE_GAP_APPEARANCE_GENERIC_TAG); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set device appearance, error code: %d", rc); + return rc; + } + return rc; +} diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/sdkconfig.defaults b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/sdkconfig.defaults new file mode 100644 index 000000000000..7ef3780ffe17 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/CMakeLists.txt b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/CMakeLists.txt new file mode 100644 index 000000000000..b42ec984ae70 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(nimble_connection) diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/README.md b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/README.md new file mode 100644 index 000000000000..1bf3fb15ffb0 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/README.md @@ -0,0 +1,268 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# NimBLE Connection Example + +## Overview + +This example is extended from NimBLE Beacon Example, and further introduces + +1. How to advertise as a connectable peripheral device +2. How to capture GAP events and handle them +3. How to update connection parameters + +It uses ESP32's Bluetooth controller and NimBLE host stack. + +To test this demo, any BLE scanner application can be used. + +## Try It Yourself + +### Set Target + +Before project configuration and build, be sure to set the correct chip target using: + +``` shell +idf.py set-target +``` + +For example, if you're using ESP32, then input + +``` Shell +idf.py set-target esp32 +``` + +### Build and Flash + +Run the following command to build, flash and monitor the project. + +``` Shell +idf.py -p flash monitor +``` + +For example, if the corresponding serial port is `/dev/ttyACM0`, then it goes + +``` Shell +idf.py -p /dev/ttyACM0 flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Code Explained + +### Overview + +1. Initialize LED, NVS flash, NimBLE host stack and GAP service; configure NimBLE host stack and start NimBLE host task thread; wait for NimBLE host stack to sync with BLE controller +2. Set advertisement and scan response data, then configure advertising parameters and start advertising +3. On connect event + 1. Turn on the LED on the dev board + 2. Print out connection descriptions + 3. Update connection parameters +4. On connection update event + 1. Print out connection descriptions +5. On disconnect event + 1. Turn off the LED on the dev board + 2. Print out connection descriptions + +### Entry Point & On Stack Sync + +Please refer to the NimBLE Beacon Example for details. + +### Start Advertising + +There're some slight differences in this example when compared to NimBLE Beacon Example. First, in this example we are constructing a connectable peripheral, so connection mode is set to connectable, that is + +``` C +static void start_advertising(void) { + ... + + /* Set non-connetable and general discoverable mode to be a beacon */ + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + + ... +} +``` + +Also, to demonstrate advertising parameters settings, advertising interval parameters are modified to 500ms, and shown in scan response. Please note that the unit of advertising interval is 0.625ms. + +``` C +static void start_advertising(void) { + ... + + /* Set advertising interval */ + rsp_fields.adv_itvl = BLE_GAP_ADV_ITVL_MS(500); + rsp_fields.adv_itvl_is_present = 1; + + ... + + /* Set advertising interval */ + adv_params.itvl_min = BLE_GAP_ADV_ITVL_MS(500); + adv_params.itvl_max = BLE_GAP_ADV_ITVL_MS(510); + + ... +} +``` + +And finally, when calling the advertising start API, a callback function `gap_event_handler` is passed as argument to receive GAP events. We'll talk about it in the next section. + +``` C +static void start_advertising(void) { + ... + + /* Start advertising */ + rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params, + gap_event_handler, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to start advertising, error code: %d", rc); + return; + } + ESP_LOGI(TAG, "advertising started!"); +} +``` + +### On GAP Events + +To keep it simple, we're interested in 3 GAP events at the moment + +- `BLE_GAP_EVENT_CONNECT` - Connect event +- `BLE_GAP_EVENT_DISCONNECT` - Disconnect event +- `BLE_GAP_EVENT_CONN_UPDATE` - Connection update event + +#### Connect Event + +When the device is connected to a peer device or a connection failed, a connect event will be passed to `gap_event_handler` by NimBLE host stack. We'll first check the connection status + +- If succeeded + - Get connection descriptor by connection handle and print out + - Turn on the LED + - Try to update connection parameters +- If failed + - Re-start advertising + +``` C +/* Connect event */ +static int gap_event_handler(struct ble_gap_event *event, void *arg) { + /* Local variables */ + int rc = 0; + struct ble_gap_conn_desc desc; + + /* Handle different GAP event */ + switch (event->type) { + + /* Connect event */ + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + ESP_LOGI(TAG, "connection %s; status=%d", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + + /* Connection succeeded */ + if (event->connect.status == 0) { + /* Check connection handle */ + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, + "failed to find connection by handle, error code: %d", + rc); + return rc; + } + + /* Print connection descriptor and turn on the LED */ + print_conn_desc(&desc); + led_on(); + + /* Try to update connection parameters */ + struct ble_gap_upd_params params = {.itvl_min = desc.conn_itvl, + .itvl_max = desc.conn_itvl, + .latency = 3, + .supervision_timeout = + desc.supervision_timeout}; + rc = ble_gap_update_params(event->connect.conn_handle, ¶ms); + if (rc != 0) { + ESP_LOGE( + TAG, + "failed to update connection parameters, error code: %d", + rc); + return rc; + } + } + /* Connection failed, restart advertising */ + else { + start_advertising(); + } + return rc; + + ... + } +} +``` + +#### Disconnect Event + +On disconnect event, we simply + +1. Print out disconnect reason and connection descriptor +2. Turn off the LED +3. Re-start advertising + +``` C +static int gap_event_handler(struct ble_gap_event *event, void *arg) { + ... + + /* Disconnect event */ + case BLE_GAP_EVENT_DISCONNECT: + /* A connection was terminated, print connection descriptor */ + ESP_LOGI(TAG, "disconnected from peer; reason=%d", + event->disconnect.reason); + + /* Turn off the LED */ + led_off(); + + /* Restart advertising */ + start_advertising(); + return rc; + + ... +} +``` + +#### Connection Update Event + +On connection update event, the operation is also very simple + +1. Print out connection status +2. Get connection descriptor by connection handle and print out + +``` C +static int gap_event_handler(struct ble_gap_event *event, void *arg) { + ... + + /* Connection parameters update event */ + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + ESP_LOGI(TAG, "connection updated; status=%d", + event->conn_update.status); + + /* Print connection descriptor */ + rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, "failed to find connection by handle, error code: %d", + rc); + return rc; + } + print_conn_desc(&desc); + return rc; + + ... +} +``` + +## Observation + +If everything goes well, except for what we have seen in NimBLE Beacon example, you should be able to see LED turned on when device is connected, and see LED turned off on disconnection. + +## Troubleshooting + +For any technical queries, please file an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/CMakeLists.txt b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/CMakeLists.txt new file mode 100644 index 000000000000..584111329971 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB_RECURSE srcs "main.c" "src/*.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "./include") diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/Kconfig.projbuild b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/Kconfig.projbuild new file mode 100644 index 000000000000..0035dc34f0ce --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/Kconfig.projbuild @@ -0,0 +1,42 @@ +menu "Example Configuration" + + orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" + + choice BLINK_LED + prompt "Blink LED type" + default BLINK_LED_GPIO + help + Select the LED type. A normal level controlled LED or an addressable LED strip. + The default selection is based on the Espressif DevKit boards. + You can change the default selection according to your board. + + config BLINK_LED_GPIO + bool "GPIO" + config BLINK_LED_STRIP + bool "LED strip" + endchoice + + choice BLINK_LED_STRIP_BACKEND + depends on BLINK_LED_STRIP + prompt "LED strip backend peripheral" + default BLINK_LED_STRIP_BACKEND_RMT if SOC_RMT_SUPPORTED + default BLINK_LED_STRIP_BACKEND_SPI + help + Select the backend peripheral to drive the LED strip. + + config BLINK_LED_STRIP_BACKEND_RMT + depends on SOC_RMT_SUPPORTED + bool "RMT" + config BLINK_LED_STRIP_BACKEND_SPI + bool "SPI" + endchoice + + config BLINK_GPIO + int "Blink GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX + default 8 + help + GPIO number (IOxx) to blink on and off the LED. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to blink. + +endmenu diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/idf_component.yml b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/idf_component.yml new file mode 100644 index 000000000000..8723a2e11a9f --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/idf_component.yml @@ -0,0 +1,2 @@ +dependencies: + espressif/led_strip: "^2.4.1" diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/include/common.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/include/common.h new file mode 100644 index 000000000000..c38f380ccfa1 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/include/common.h @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef COMMON_H +#define COMMON_H + +/* Includes */ +/* STD APIs */ +#include +#include +#include + +/* ESP APIs */ +#include "esp_log.h" +#include "nvs_flash.h" +#include "sdkconfig.h" + +/* FreeRTOS APIs */ +#include +#include + +/* NimBLE stack APIs */ +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "host/util/util.h" +#include "nimble/ble.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" + +/* Defines */ +#define TAG "NimBLE_Connection" +#define DEVICE_NAME "NimBLE_CONN" + +#endif // COMMON_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/include/gap.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/include/gap.h new file mode 100644 index 000000000000..7f51ac63bd0e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/include/gap.h @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef GAP_SVC_H +#define GAP_SVC_H + +/* Includes */ +/* NimBLE GAP APIs */ +#include "host/ble_gap.h" +#include "services/gap/ble_svc_gap.h" + +/* Defines */ +#define BLE_GAP_APPEARANCE_GENERIC_TAG 0x0200 +#define BLE_GAP_URI_PREFIX_HTTPS 0x17 +#define BLE_GAP_LE_ROLE_PERIPHERAL 0x00 + +/* Public function declarations */ +void adv_init(void); +int gap_init(void); + +#endif // GAP_SVC_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/include/led.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/include/led.h new file mode 100644 index 000000000000..0f6b5f774f2a --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/include/led.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef LED_H +#define LED_H + +/* Includes */ +/* ESP APIs */ +#include "driver/gpio.h" +#include "led_strip.h" +#include "sdkconfig.h" + +/* Defines */ +#define BLINK_GPIO CONFIG_BLINK_GPIO + +/* Public function declarations */ +uint8_t get_led_state(void); +void led_on(void); +void led_off(void); +void led_init(void); + +#endif // LED_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/main.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/main.c new file mode 100644 index 000000000000..b3fa8a9012e5 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/main.c @@ -0,0 +1,98 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "common.h" +#include "gap.h" +#include "led.h" + +/* Library function declarations */ +void ble_store_config_init(void); + +/* Private function declarations */ +static void on_stack_reset(int reason); +static void on_stack_sync(void); +static void nimble_host_config_init(void); +static void nimble_host_task(void *param); + +/* Private functions */ +/* + * Stack event callback functions + * - on_stack_reset is called when host resets BLE stack due to errors + * - on_stack_sync is called when host has synced with controller + */ +static void on_stack_reset(int reason) { + /* On reset, print reset reason to console */ + ESP_LOGI(TAG, "nimble stack reset, reset reason: %d", reason); +} + +static void on_stack_sync(void) { + /* On stack sync, do advertising initialization */ + adv_init(); +} + +static void nimble_host_config_init(void) { + /* Set host callbacks */ + ble_hs_cfg.reset_cb = on_stack_reset; + ble_hs_cfg.sync_cb = on_stack_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Store host configuration */ + ble_store_config_init(); +} + +static void nimble_host_task(void *param) { + /* Task entry log */ + ESP_LOGI(TAG, "nimble host task has been started!"); + + /* This function won't return until nimble_port_stop() is executed */ + nimble_port_run(); + + /* Clean up at exit */ + vTaskDelete(NULL); +} + +void app_main(void) { + /* Local variables */ + int rc = 0; + esp_err_t ret = ESP_OK; + + /* LED initialization */ + led_init(); + + /* NVS flash initialization */ + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || + ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize nvs flash, error code: %d ", ret); + return; + } + + /* NimBLE stack initialization */ + ret = nimble_port_init(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize nimble stack, error code: %d ", + ret); + return; + } + + /* GAP service initialization */ + rc = gap_init(); + if (rc != 0) { + ESP_LOGE(TAG, "failed to initialize GAP service, error code: %d", rc); + return; + } + + /* NimBLE host configuration initialization */ + nimble_host_config_init(); + + /* Start NimBLE host task thread and return */ + xTaskCreate(nimble_host_task, "NimBLE Host", 4*1024, NULL, 5, NULL); + return; +} 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 new file mode 100644 index 000000000000..8788b66f267e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/gap.c @@ -0,0 +1,272 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "gap.h" +#include "common.h" +#include "led.h" + +/* Private function declarations */ +inline static void format_addr(char *addr_str, uint8_t addr[]); +static void print_conn_desc(struct ble_gap_conn_desc *desc); +static void start_advertising(void); +static int gap_event_handler(struct ble_gap_event *event, void *arg); + +/* Private variables */ +static uint8_t own_addr_type; +static uint8_t addr_val[6] = {0}; +static uint8_t esp_uri[] = {BLE_GAP_URI_PREFIX_HTTPS, '/', '/', 'e', 's', 'p', 'r', 'e', 's', 's', 'i', 'f', '.', 'c', 'o', 'm'}; + +/* Private functions */ +inline static void format_addr(char *addr_str, uint8_t addr[]) { + sprintf(addr_str, "%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1], + addr[2], addr[3], addr[4], addr[5]); +} + +static void print_conn_desc(struct ble_gap_conn_desc *desc) { + /* Local variables */ + char addr_str[18] = {0}; + + /* Connection handle */ + ESP_LOGI(TAG, "connection handle: %d", desc->conn_handle); + + /* Local ID address */ + format_addr(addr_str, desc->our_id_addr.val); + ESP_LOGI(TAG, "device id address: type=%d, value=%s", + desc->our_id_addr.type, addr_str); + + /* Peer ID address */ + format_addr(addr_str, desc->peer_id_addr.val); + ESP_LOGI(TAG, "peer id address: type=%d, value=%s", desc->peer_id_addr.type, + addr_str); + + /* Connection info */ + ESP_LOGI(TAG, + "conn_itvl=%d, conn_latency=%d, supervision_timeout=%d, " + "encrypted=%d, authenticated=%d, bonded=%d\n", + desc->conn_itvl, desc->conn_latency, desc->supervision_timeout, + desc->sec_state.encrypted, desc->sec_state.authenticated, + desc->sec_state.bonded); +} + +static void start_advertising(void) { + /* Local variables */ + int rc = 0; + const char *name; + struct ble_hs_adv_fields adv_fields = {0}; + struct ble_hs_adv_fields rsp_fields = {0}; + struct ble_gap_adv_params adv_params = {0}; + + /* Set advertising flags */ + adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; + + /* Set device name */ + name = ble_svc_gap_device_name(); + adv_fields.name = (uint8_t *)name; + adv_fields.name_len = strlen(name); + adv_fields.name_is_complete = 1; + + /* Set device tx power */ + adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + adv_fields.tx_pwr_lvl_is_present = 1; + + /* Set device appearance */ + adv_fields.appearance = BLE_GAP_APPEARANCE_GENERIC_TAG; + adv_fields.appearance_is_present = 1; + + /* Set device LE role */ + adv_fields.le_role = BLE_GAP_LE_ROLE_PERIPHERAL; + adv_fields.le_role_is_present = 1; + + /* Set advertiement fields */ + rc = ble_gap_adv_set_fields(&adv_fields); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set advertising data, error code: %d", rc); + return; + } + + /* Set device address */ + rsp_fields.device_addr = addr_val; + rsp_fields.device_addr_type = own_addr_type; + rsp_fields.device_addr_is_present = 1; + + /* Set URI */ + rsp_fields.uri = esp_uri; + rsp_fields.uri_len = sizeof(esp_uri); + + /* Set advertising interval */ + rsp_fields.adv_itvl = BLE_GAP_ADV_ITVL_MS(500); + rsp_fields.adv_itvl_is_present = 1; + + /* Set scan response fields */ + rc = ble_gap_adv_rsp_set_fields(&rsp_fields); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set scan response data, error code: %d", rc); + return; + } + + /* Set non-connetable and general discoverable mode to be a beacon */ + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + + /* Set advertising interval */ + adv_params.itvl_min = BLE_GAP_ADV_ITVL_MS(500); + adv_params.itvl_max = BLE_GAP_ADV_ITVL_MS(510); + + /* Start advertising */ + rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params, + gap_event_handler, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to start advertising, error code: %d", rc); + return; + } + ESP_LOGI(TAG, "advertising started!"); +} + +/* + * NimBLE applies an event-driven model to keep GAP service going + * gap_event_handler is a callback function registered when calling + * ble_gap_adv_start API and called when a GAP event arrives + */ +static int gap_event_handler(struct ble_gap_event *event, void *arg) { + /* Local variables */ + int rc = 0; + struct ble_gap_conn_desc desc; + + /* Handle different GAP event */ + switch (event->type) { + + /* Connect event */ + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + ESP_LOGI(TAG, "connection %s; status=%d", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + + /* Connection succeeded */ + if (event->connect.status == 0) { + /* Check connection handle */ + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, + "failed to find connection by handle, error code: %d", + rc); + return rc; + } + + /* Print connection descriptor and turn on the LED */ + print_conn_desc(&desc); + led_on(); + + /* Try to update connection parameters */ + struct ble_gap_upd_params params = {.itvl_min = desc.conn_itvl, + .itvl_max = desc.conn_itvl, + .latency = 3, + .supervision_timeout = + desc.supervision_timeout}; + rc = ble_gap_update_params(event->connect.conn_handle, ¶ms); + if (rc != 0) { + ESP_LOGE( + TAG, + "failed to update connection parameters, error code: %d", + rc); + return rc; + } + } + /* Connection failed, restart advertising */ + else { + start_advertising(); + } + return rc; + + /* Disconnect event */ + case BLE_GAP_EVENT_DISCONNECT: + /* A connection was terminated, print connection descriptor */ + ESP_LOGI(TAG, "disconnected from peer; reason=%d", + event->disconnect.reason); + + /* Turn off the LED */ + led_off(); + + /* Restart advertising */ + start_advertising(); + return rc; + + /* Connection parameters update event */ + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + ESP_LOGI(TAG, "connection updated; status=%d", + event->conn_update.status); + + /* Print connection descriptor */ + rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, "failed to find connection by handle, error code: %d", + rc); + return rc; + } + print_conn_desc(&desc); + return rc; + } + + return rc; +} + +/* Public functions */ +void adv_init(void) { + /* Local variables */ + int rc = 0; + char addr_str[18] = {0}; + + /* Make sure we have proper BT identity address set */ + rc = ble_hs_util_ensure_addr(0); + if (rc != 0) { + ESP_LOGE(TAG, "device does not have any available bt address!"); + return; + } + + /* Figure out BT address to use while advertising */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGE(TAG, "failed to infer address type, error code: %d", rc); + return; + } + + /* Copy device address to addr_val */ + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to copy device address, error code: %d", rc); + return; + } + format_addr(addr_str, addr_val); + ESP_LOGI(TAG, "device address: %s", addr_str); + + /* Start advertising. */ + start_advertising(); +} + +int gap_init(void) { + /* Local variables */ + int rc = 0; + + /* Initialize GAP service */ + ble_svc_gap_init(); + + /* Set GAP device name */ + rc = ble_svc_gap_device_name_set(DEVICE_NAME); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set device name to %s, error code: %d", + DEVICE_NAME, rc); + return rc; + } + + /* Set GAP device appearance */ + rc = ble_svc_gap_device_appearance_set(BLE_GAP_APPEARANCE_GENERIC_TAG); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set device appearance, error code: %d", rc); + return rc; + } + return rc; +} diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/led.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/led.c new file mode 100644 index 000000000000..514c509e1bd4 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/led.c @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "led.h" +#include "common.h" + +/* Private variables */ +static uint8_t led_state; + +#ifdef CONFIG_BLINK_LED_STRIP +static led_strip_handle_t led_strip; +#endif + +/* Public functions */ +uint8_t get_led_state(void) { return led_state; } + +#ifdef CONFIG_BLINK_LED_STRIP + +void led_on(void) { + /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */ + led_strip_set_pixel(led_strip, 0, 16, 16, 16); + + /* Refresh the strip to send data */ + led_strip_refresh(led_strip); + + /* Update LED state */ + led_state = true; +} + +void led_off(void) { + /* Set all LED off to clear all pixels */ + led_strip_clear(led_strip); + + /* Update LED state */ + led_state = false; +} + +void led_init(void) { + ESP_LOGI(TAG, "example configured to blink addressable led!"); + /* LED strip initialization with the GPIO and pixels number*/ + led_strip_config_t strip_config = { + .strip_gpio_num = CONFIG_BLINK_GPIO, + .max_leds = 1, // at least one LED on board + }; +#if CONFIG_BLINK_LED_STRIP_BACKEND_RMT + led_strip_rmt_config_t rmt_config = { + .resolution_hz = 10 * 1000 * 1000, // 10MHz + .flags.with_dma = false, + }; + ESP_ERROR_CHECK( + led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); +#elif CONFIG_BLINK_LED_STRIP_BACKEND_SPI + led_strip_spi_config_t spi_config = { + .spi_bus = SPI2_HOST, + .flags.with_dma = true, + }; + ESP_ERROR_CHECK( + led_strip_new_spi_device(&strip_config, &spi_config, &led_strip)); +#else +#error "unsupported LED strip backend" +#endif + /* Set all LED off to clear all pixels */ + led_off(); +} + +#elif CONFIG_BLINK_LED_GPIO + +void led_on(void) { gpio_set_level(CONFIG_BLINK_GPIO, true); } + +void led_off(void) { gpio_set_level(CONFIG_BLINK_GPIO, false); } + +void led_init(void) { + ESP_LOGI(TAG, "example configured to blink gpio led!"); + gpio_reset_pin(CONFIG_BLINK_GPIO); + /* Set the GPIO as a push/pull output */ + gpio_set_direction(CONFIG_BLINK_GPIO, GPIO_MODE_OUTPUT); +} + +#else +#error "unsupported LED type" +#endif diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults new file mode 100644 index 000000000000..551f506530b4 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults @@ -0,0 +1,6 @@ +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n + +CONFIG_BLINK_LED_GPIO=y +CONFIG_BLINK_GPIO=8 diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32 b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32 new file mode 100644 index 000000000000..263ec939b18d --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32 @@ -0,0 +1 @@ +CONFIG_BLINK_GPIO=5 diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32c3 b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32c3 new file mode 100644 index 000000000000..da044304532e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32c3 @@ -0,0 +1 @@ +CONFIG_BLINK_LED_STRIP=y diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32c6 b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32c6 new file mode 100644 index 000000000000..da044304532e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32c6 @@ -0,0 +1 @@ +CONFIG_BLINK_LED_STRIP=y diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32h2 b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32h2 new file mode 100644 index 000000000000..da044304532e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32h2 @@ -0,0 +1 @@ +CONFIG_BLINK_LED_STRIP=y diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32s3 b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32s3 new file mode 100644 index 000000000000..5ac9d30b41fe --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/sdkconfig.defaults.esp32s3 @@ -0,0 +1,2 @@ +CONFIG_BLINK_LED_STRIP=y +CONFIG_BLINK_GPIO=48 diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/CMakeLists.txt b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/CMakeLists.txt new file mode 100644 index 000000000000..604d8b5f681f --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(nimble_gatt_server) diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/README.md b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/README.md new file mode 100644 index 000000000000..f7625cc259cf --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/README.md @@ -0,0 +1,380 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# NimBLE GATT Server Example + +## Overview + +This example is extended from NimBLE Connection Example, and further introduces + +1. How to implement a GATT server using GATT services table +2. How to handle characteristic access requests + 1. Write access demonstrated by LED control + 2. Read and indicate access demonstrated by heart rate measurement(mocked) + +It uses ESP32's Bluetooth controller and NimBLE host stack. + +To test this demo, any BLE scanner application can be used. + +## Try It Yourself + +### Set Target + +Before project configuration and build, be sure to set the correct chip target using: + +``` shell +idf.py set-target +``` + +For example, if you're using ESP32, then input + +``` Shell +idf.py set-target esp32 +``` + +### Build and Flash + +Run the following command to build, flash and monitor the project. + +``` Shell +idf.py -p flash monitor +``` + +For example, if the corresponding serial port is `/dev/ttyACM0`, then it goes + +``` Shell +idf.py -p /dev/ttyACM0 flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Code Explained + +### Overview + +1. Initialization + 1. Initialize LED, NVS flash, NimBLE host stack, GAP service + 2. Initialize GATT service and add services to registration queue + 3. Configure NimBLE host stack and start NimBLE host task thread, GATT services will be registered automatically when NimBLE host stack started + 4. Start heart rate update task thread +2. Wait for NimBLE host stack to sync with BLE controller, and start advertising; wait for connection event to come +3. After connection established, wait for GATT characteristics access events to come + 1. On write LED event, turn on or off the LED accordingly + 2. On read heart rate event, send out current heart rate measurement value + 3. On indicate heart rate event, enable heart rate indication + +### Entry Point + +In this example, we call GATT `gatt_svr_init` function to initialize GATT server in `app_main` before NimBLE host configuration. This is a custom function defined in `gatt_svc.c`, and basically we just call GATT service initialization API and add services to registration queue. + +And there's another code added in `nimble_host_config_init`, which is + +``` C +static void nimble_host_config_init(void) { + ... + + ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; + + ... +} +``` + +That is GATT server register callback function. In this case it will only print out some registration information when services, characteristics or descriptors are registered. + +Then, after NimBLE host task thread is created, we'll create another task defined in `heart_rate_task` to update heart rate measurement mock value and send indication if enabled. + +### GAP Service Updates + +`gap_event_handler` is updated with LED control removed, and more event handling branches, when compared to NimBLE Connection Example, including + +- `BLE_GAP_EVENT_ADV_COMPLETE` - Advertising complete event +- `BLE_GAP_EVENT_NOTIFY_TX` - Notificate event +- `BLE_GAP_EVENT_SUBSCRIBE` - Subscribe event +- `BLE_GAP_EVENT_MTU` - MTU update event + +`BLE_GAP_EVENT_ADV_COMPLETE` and `BLE_GAP_EVENT_MTU` events are actually not involved in this example, but we still put them down there for reference. `BLE_GAP_EVENT_NOTIFY_TX` and `BLE_GAP_EVENT_SUBSCRIBE` events will be discussed in the next section. + +### GATT Services Table + +GATT services are defined in `ble_gatt_svc_def` struct array, with a variable name `gatt_svr_svcs` in this demo. We'll call it as the GATT services table in the following content. + +``` C +/* Heart rate service */ +static const ble_uuid16_t heart_rate_svc_uuid = BLE_UUID16_INIT(0x180D); + +static uint8_t heart_rate_chr_val[2] = {0}; +static uint16_t heart_rate_chr_val_handle; +static const ble_uuid16_t heart_rate_chr_uuid = BLE_UUID16_INIT(0x2A37); + +static uint16_t heart_rate_chr_conn_handle = 0; +static bool heart_rate_chr_conn_handle_inited = false; +static bool heart_rate_ind_status = false; + +/* Automation IO service */ +static const ble_uuid16_t auto_io_svc_uuid = BLE_UUID16_INIT(0x1815); +static uint16_t led_chr_val_handle; +static const ble_uuid128_t led_chr_uuid = + BLE_UUID128_INIT(0x23, 0xd1, 0xbc, 0xea, 0x5f, 0x78, 0x23, 0x15, 0xde, 0xef, + 0x12, 0x12, 0x25, 0x15, 0x00, 0x00); + +/* GATT services table */ +static const struct ble_gatt_svc_def gatt_svr_svcs[] = { + /* Heart rate service */ + {.type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &heart_rate_svc_uuid.u, + .characteristics = + (struct ble_gatt_chr_def[]){ + {/* Heart rate characteristic */ + .uuid = &heart_rate_chr_uuid.u, + .access_cb = heart_rate_chr_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_INDICATE, + .val_handle = &heart_rate_chr_val_handle}, + { + 0, /* No more characteristics in this service. */ + }}}, + + /* Automation IO service */ + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &auto_io_svc_uuid.u, + .characteristics = + (struct ble_gatt_chr_def[]){/* LED characteristic */ + {.uuid = &led_chr_uuid.u, + .access_cb = led_chr_access, + .flags = BLE_GATT_CHR_F_WRITE, + .val_handle = &led_chr_val_handle}, + {0}}, + }, + + { + 0, /* No more services. */ + }, +}; +``` + +In this table, there are two GATT primary services defined + +- Heart rate service with a UUID of `0x180D` +- Automation IO service with a UUID of `0x1815` + +#### Automation IO Service + +Under automation IO service, there's a LED characteristic, with a vendor-specific UUID and write only permission. + +The characteristic is binded with `led_chr_access` callback function, in which the write access event is captured. The LED will be turned on or off according to the write value, quite straight-forward. + +``` C +static int led_chr_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + /* Local variables */ + int rc; + + /* Handle access events */ + /* Note: LED characteristic is write only */ + switch (ctxt->op) { + + /* Write characteristic event */ + case BLE_GATT_ACCESS_OP_WRITE_CHR: + /* Verify connection handle */ + if (conn_handle != BLE_HS_CONN_HANDLE_NONE) { + ESP_LOGI(TAG, "characteristic write; conn_handle=%d attr_handle=%d", + conn_handle, attr_handle); + } else { + ESP_LOGI(TAG, + "characteristic write by nimble stack; attr_handle=%d", + attr_handle); + } + + /* Verify attribute handle */ + if (attr_handle == led_chr_val_handle) { + /* Verify access buffer length */ + if (ctxt->om->om_len == 1) { + /* Turn the LED on or off according to the operation bit */ + if (ctxt->om->om_data[0]) { + led_on(); + ESP_LOGI(TAG, "led turned on!"); + } else { + led_off(); + ESP_LOGI(TAG, "led turned off!"); + } + } else { + goto error; + } + return rc; + } + goto error; + + /* Unknown event */ + default: + goto error; + } + +error: + ESP_LOGE(TAG, + "unexpected access operation to led characteristic, opcode: %d", + ctxt->op); + return BLE_ATT_ERR_UNLIKELY; +} +``` + +#### Heart Rate Service + +Under heart rate service, there's a heart rate measurement characteristic, with a UUID of `0x2A37` and read + indicate access permission. + +The characteristic is binded with `heart_rate_chr_access` callback function, in which the read access event is captured. It should be mentioned that in SIG definition, heart rate measurement is a multi-byte data structure, with the first byte indicating the flags + +- Bit 0: Heart rate value type + - 0: Heart rate value is `uint8_t` type + - 1: Heart rate value is `uint16_t` type +- Bit 1: Sensor contact status +- Bit 2: Sensor contact supported +- Bit 3: Energy expended status +- Bit 4: RR-interval status +- Bit 5-7: Reserved + +and the rest of bytes are data fields. In this case, we use `uint8_t` type and disable other features, making the characteristic value a 2-byte array. So when characteristic read event arrives, we'll get the latest heart rate value and send it back to peer device. + +``` C +static int heart_rate_chr_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + /* Local variables */ + int rc; + + /* Handle access events */ + /* Note: Heart rate characteristic is read only */ + switch (ctxt->op) { + + /* Read characteristic event */ + case BLE_GATT_ACCESS_OP_READ_CHR: + /* Verify connection handle */ + if (conn_handle != BLE_HS_CONN_HANDLE_NONE) { + ESP_LOGI(TAG, "characteristic read; conn_handle=%d attr_handle=%d", + conn_handle, attr_handle); + } else { + ESP_LOGI(TAG, "characteristic read by nimble stack; attr_handle=%d", + attr_handle); + } + + /* Verify attribute handle */ + if (attr_handle == heart_rate_chr_val_handle) { + /* Update access buffer value */ + heart_rate_chr_val[1] = get_heart_rate(); + rc = os_mbuf_append(ctxt->om, &heart_rate_chr_val, + sizeof(heart_rate_chr_val)); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + goto error; + + /* Unknown event */ + default: + goto error; + } + +error: + ESP_LOGE( + TAG, + "unexpected access operation to heart rate characteristic, opcode: %d", + ctxt->op); + return BLE_ATT_ERR_UNLIKELY; +} +``` + +Indicate access, however, is a bit more complicated. As mentioned in *GAP Service Updates*, we'll handle another 2 events namely `BLE_GAP_EVENT_NOTIFY_TX` and `BLE_GAP_EVENT_SUBSCRIBE` in `gap_event_handler`. In this case, if peer device wants to enable heart rate measurement indication, it will send a subscribe request to the local device, and the request will be captured as a subscribe event in `gap_event_handler`. But from the perspective of software layering, the event should be handled in GATT server, so we just pass the event to GATT server by calling `gatt_svr_subscribe_cb`, as demonstrated in the demo + +``` C +static int gap_event_handler(struct ble_gap_event *event, void *arg) { + ... + + /* Subscribe event */ + case BLE_GAP_EVENT_SUBSCRIBE: + /* Print subscription info to log */ + ESP_LOGI(TAG, + "subscribe event; conn_handle=%d attr_handle=%d " + "reason=%d prevn=%d curn=%d previ=%d curi=%d", + event->subscribe.conn_handle, event->subscribe.attr_handle, + event->subscribe.reason, event->subscribe.prev_notify, + event->subscribe.cur_notify, event->subscribe.prev_indicate, + event->subscribe.cur_indicate); + + /* GATT subscribe event callback */ + gatt_svr_subscribe_cb(event); + return rc; + + ... +} +``` + +Then we'll check connection handle and attribute handle, if the attribute handle matches `heart_rate_chr_val_chandle`, `heart_rate_chr_conn_handle` and `heart_rate_ind_status` will be updated together. + +``` C +void gatt_svr_subscribe_cb(struct ble_gap_event *event) { + /* Check connection handle */ + if (event->subscribe.conn_handle != BLE_HS_CONN_HANDLE_NONE) { + ESP_LOGI(TAG, "subscribe event; conn_handle=%d attr_handle=%d", + event->subscribe.conn_handle, event->subscribe.attr_handle); + } else { + ESP_LOGI(TAG, "subscribe by nimble stack; attr_handle=%d", + event->subscribe.attr_handle); + } + + /* Check attribute handle */ + if (event->subscribe.attr_handle == heart_rate_chr_val_handle) { + /* Update heart rate subscription status */ + heart_rate_chr_conn_handle = event->subscribe.conn_handle; + heart_rate_chr_conn_handle_inited = true; + heart_rate_ind_status = event->subscribe.cur_indicate; + } +} +``` + +Notice that heart rate measurement incation is handled in `heart_rate_task` by calling `send_heart_rate_indication` function periodically. Actually, this function will check heart rate indication status and send indication accordingly. In this way, heart rate indication is implemented. + +``` C +void send_heart_rate_indication(void) { + if (heart_rate_ind_status && heart_rate_chr_conn_handle_inited) { + ble_gatts_indicate(heart_rate_chr_conn_handle, + heart_rate_chr_val_handle); + ESP_LOGI(TAG, "heart rate indication sent!"); + } +} + +static void heart_rate_task(void *param) { + /* Task entry log */ + ESP_LOGI(TAG, "heart rate task has been started!"); + + /* Loop forever */ + while (1) { + /* Update heart rate value every 1 second */ + update_heart_rate(); + ESP_LOGI(TAG, "heart rate updated to %d", get_heart_rate()); + + /* Send heart rate indication if enabled */ + send_heart_rate_indication(); + + /* Sleep */ + vTaskDelay(HEART_RATE_TASK_PERIOD); + } + + /* Clean up at exit */ + vTaskDelete(NULL); +} +``` + +## Observation + +If everything goes well, you should be able to see 4 services when connected to ESP32, including + +- Generic Access +- Generic Attribute +- Heart Rate +- Automation IO + +Click on Automation IO Service, you should be able to see LED characteristic. Click on upload button, you should be able to write `ON` or `OFF` value. Send it to the device, LED will be turned on or off following your instruction. + +Click on Heart Rate Service, you should be able to see Heart Rate Measurement characteristic. Click on download button, you should be able to see the latest heart rate measurement mock value, and it should be consistent with what is shown on serial output. Click on subscribe button, you should be able to see the heart rate measurement mock value updated every second. + +## Troubleshooting + +For any technical queries, please file an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/CMakeLists.txt b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/CMakeLists.txt new file mode 100644 index 000000000000..584111329971 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB_RECURSE srcs "main.c" "src/*.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "./include") diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/Kconfig.projbuild b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/Kconfig.projbuild new file mode 100644 index 000000000000..0035dc34f0ce --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/Kconfig.projbuild @@ -0,0 +1,42 @@ +menu "Example Configuration" + + orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" + + choice BLINK_LED + prompt "Blink LED type" + default BLINK_LED_GPIO + help + Select the LED type. A normal level controlled LED or an addressable LED strip. + The default selection is based on the Espressif DevKit boards. + You can change the default selection according to your board. + + config BLINK_LED_GPIO + bool "GPIO" + config BLINK_LED_STRIP + bool "LED strip" + endchoice + + choice BLINK_LED_STRIP_BACKEND + depends on BLINK_LED_STRIP + prompt "LED strip backend peripheral" + default BLINK_LED_STRIP_BACKEND_RMT if SOC_RMT_SUPPORTED + default BLINK_LED_STRIP_BACKEND_SPI + help + Select the backend peripheral to drive the LED strip. + + config BLINK_LED_STRIP_BACKEND_RMT + depends on SOC_RMT_SUPPORTED + bool "RMT" + config BLINK_LED_STRIP_BACKEND_SPI + bool "SPI" + endchoice + + config BLINK_GPIO + int "Blink GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX + default 8 + help + GPIO number (IOxx) to blink on and off the LED. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to blink. + +endmenu diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/idf_component.yml b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/idf_component.yml new file mode 100644 index 000000000000..8723a2e11a9f --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/idf_component.yml @@ -0,0 +1,2 @@ +dependencies: + espressif/led_strip: "^2.4.1" diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/common.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/common.h new file mode 100644 index 000000000000..d5a5eca978cf --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/common.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef COMMON_H +#define COMMON_H + +/* Includes */ +/* STD APIs */ +#include +#include +#include +#include + +/* ESP APIs */ +#include "esp_log.h" +#include "nvs_flash.h" +#include "sdkconfig.h" + +/* FreeRTOS APIs */ +#include +#include + +/* NimBLE stack APIs */ +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "host/util/util.h" +#include "nimble/ble.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" + +/* Defines */ +#define TAG "NimBLE_GATT_Server" +#define DEVICE_NAME "NimBLE_GATT" + +#endif // COMMON_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/gap.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/gap.h new file mode 100644 index 000000000000..7f51ac63bd0e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/gap.h @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef GAP_SVC_H +#define GAP_SVC_H + +/* Includes */ +/* NimBLE GAP APIs */ +#include "host/ble_gap.h" +#include "services/gap/ble_svc_gap.h" + +/* Defines */ +#define BLE_GAP_APPEARANCE_GENERIC_TAG 0x0200 +#define BLE_GAP_URI_PREFIX_HTTPS 0x17 +#define BLE_GAP_LE_ROLE_PERIPHERAL 0x00 + +/* Public function declarations */ +void adv_init(void); +int gap_init(void); + +#endif // GAP_SVC_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/gatt_svc.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/gatt_svc.h new file mode 100644 index 000000000000..70276a26cb7f --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/gatt_svc.h @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef GATT_SVR_H +#define GATT_SVR_H + +/* Includes */ +/* NimBLE GATT APIs */ +#include "host/ble_gatt.h" +#include "services/gatt/ble_svc_gatt.h" + +/* NimBLE GAP APIs */ +#include "host/ble_gap.h" + +/* Public function declarations */ +void send_heart_rate_indication(void); +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +void gatt_svr_subscribe_cb(struct ble_gap_event *event); +int gatt_svc_init(void); + +#endif // GATT_SVR_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/heart_rate.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/heart_rate.h new file mode 100644 index 000000000000..59fca7dbe882 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/heart_rate.h @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef HEART_RATE_H +#define HEART_RATE_H + +/* Includes */ +/* ESP APIs */ +#include "esp_random.h" + +/* Defines */ +#define HEART_RATE_TASK_PERIOD (1000 / portTICK_PERIOD_MS) + +/* Public function declarations */ +uint8_t get_heart_rate(void); +void update_heart_rate(void); + +#endif // HEART_RATE_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/led.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/led.h new file mode 100644 index 000000000000..0f6b5f774f2a --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/include/led.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef LED_H +#define LED_H + +/* Includes */ +/* ESP APIs */ +#include "driver/gpio.h" +#include "led_strip.h" +#include "sdkconfig.h" + +/* Defines */ +#define BLINK_GPIO CONFIG_BLINK_GPIO + +/* Public function declarations */ +uint8_t get_led_state(void); +void led_on(void); +void led_off(void); +void led_init(void); + +#endif // LED_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/main.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/main.c new file mode 100644 index 000000000000..bff677cb6614 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/main.c @@ -0,0 +1,133 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "common.h" +#include "gap.h" +#include "gatt_svc.h" +#include "heart_rate.h" +#include "led.h" + +/* Library function declarations */ +void ble_store_config_init(void); + +/* Private function declarations */ +static void on_stack_reset(int reason); +static void on_stack_sync(void); +static void nimble_host_config_init(void); +static void nimble_host_task(void *param); + +/* Private functions */ +/* + * Stack event callback functions + * - on_stack_reset is called when host resets BLE stack due to errors + * - on_stack_sync is called when host has synced with controller + */ +static void on_stack_reset(int reason) { + /* On reset, print reset reason to console */ + ESP_LOGI(TAG, "nimble stack reset, reset reason: %d", reason); +} + +static void on_stack_sync(void) { + /* On stack sync, do advertising initialization */ + adv_init(); +} + +static void nimble_host_config_init(void) { + /* Set host callbacks */ + ble_hs_cfg.reset_cb = on_stack_reset; + ble_hs_cfg.sync_cb = on_stack_sync; + ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Store host configuration */ + ble_store_config_init(); +} + +static void nimble_host_task(void *param) { + /* Task entry log */ + ESP_LOGI(TAG, "nimble host task has been started!"); + + /* This function won't return until nimble_port_stop() is executed */ + nimble_port_run(); + + /* Clean up at exit */ + vTaskDelete(NULL); +} + +static void heart_rate_task(void *param) { + /* Task entry log */ + ESP_LOGI(TAG, "heart rate task has been started!"); + + /* Loop forever */ + while (1) { + /* Update heart rate value every 1 second */ + update_heart_rate(); + ESP_LOGI(TAG, "heart rate updated to %d", get_heart_rate()); + + /* Send heart rate indication if enabled */ + send_heart_rate_indication(); + + /* Sleep */ + vTaskDelay(HEART_RATE_TASK_PERIOD); + } + + /* Clean up at exit */ + vTaskDelete(NULL); +} + +void app_main(void) { + /* Local variables */ + int rc; + esp_err_t ret; + + /* LED initialization */ + led_init(); + + /* + * NVS flash initialization + * Dependency of BLE stack to store configurations + */ + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || + ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize nvs flash, error code: %d ", ret); + return; + } + + /* NimBLE stack initialization */ + ret = nimble_port_init(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize nimble stack, error code: %d ", + ret); + return; + } + + /* GAP service initialization */ + rc = gap_init(); + if (rc != 0) { + ESP_LOGE(TAG, "failed to initialize GAP service, error code: %d", rc); + return; + } + + /* GATT server initialization */ + rc = gatt_svc_init(); + if (rc != 0) { + ESP_LOGE(TAG, "failed to initialize GATT server, error code: %d", rc); + return; + } + + /* NimBLE host configuration initialization */ + nimble_host_config_init(); + + /* Start NimBLE host task thread and return */ + xTaskCreate(nimble_host_task, "NimBLE Host", 4*1024, NULL, 5, NULL); + xTaskCreate(heart_rate_task, "Heart Rate", 4*1024, NULL, 5, NULL); + return; +} 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 new file mode 100644 index 000000000000..8519028a5d0e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gap.c @@ -0,0 +1,306 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "gap.h" +#include "common.h" +#include "gatt_svc.h" + +/* Private function declarations */ +inline static void format_addr(char *addr_str, uint8_t addr[]); +static void print_conn_desc(struct ble_gap_conn_desc *desc); +static void start_advertising(void); +static int gap_event_handler(struct ble_gap_event *event, void *arg); + +/* Private variables */ +static uint8_t own_addr_type; +static uint8_t addr_val[6] = {0}; +static uint8_t esp_uri[] = {BLE_GAP_URI_PREFIX_HTTPS, '/', '/', 'e', 's', 'p', 'r', 'e', 's', 's', 'i', 'f', '.', 'c', 'o', 'm'}; + +/* Private functions */ +inline static void format_addr(char *addr_str, uint8_t addr[]) { + sprintf(addr_str, "%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1], + addr[2], addr[3], addr[4], addr[5]); +} + +static void print_conn_desc(struct ble_gap_conn_desc *desc) { + /* Local variables */ + char addr_str[18] = {0}; + + /* Connection handle */ + ESP_LOGI(TAG, "connection handle: %d", desc->conn_handle); + + /* Local ID address */ + format_addr(addr_str, desc->our_id_addr.val); + ESP_LOGI(TAG, "device id address: type=%d, value=%s", + desc->our_id_addr.type, addr_str); + + /* Peer ID address */ + format_addr(addr_str, desc->peer_id_addr.val); + ESP_LOGI(TAG, "peer id address: type=%d, value=%s", desc->peer_id_addr.type, + addr_str); + + /* Connection info */ + ESP_LOGI(TAG, + "conn_itvl=%d, conn_latency=%d, supervision_timeout=%d, " + "encrypted=%d, authenticated=%d, bonded=%d\n", + desc->conn_itvl, desc->conn_latency, desc->supervision_timeout, + desc->sec_state.encrypted, desc->sec_state.authenticated, + desc->sec_state.bonded); +} + +static void start_advertising(void) { + /* Local variables */ + int rc = 0; + const char *name; + struct ble_hs_adv_fields adv_fields = {0}; + struct ble_hs_adv_fields rsp_fields = {0}; + struct ble_gap_adv_params adv_params = {0}; + + /* Set advertising flags */ + adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; + + /* Set device name */ + name = ble_svc_gap_device_name(); + adv_fields.name = (uint8_t *)name; + adv_fields.name_len = strlen(name); + adv_fields.name_is_complete = 1; + + /* Set device tx power */ + adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + adv_fields.tx_pwr_lvl_is_present = 1; + + /* Set device appearance */ + adv_fields.appearance = BLE_GAP_APPEARANCE_GENERIC_TAG; + adv_fields.appearance_is_present = 1; + + /* Set device LE role */ + adv_fields.le_role = BLE_GAP_LE_ROLE_PERIPHERAL; + adv_fields.le_role_is_present = 1; + + /* Set advertiement fields */ + rc = ble_gap_adv_set_fields(&adv_fields); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set advertising data, error code: %d", rc); + return; + } + + /* Set device address */ + rsp_fields.device_addr = addr_val; + rsp_fields.device_addr_type = own_addr_type; + rsp_fields.device_addr_is_present = 1; + + /* Set URI */ + rsp_fields.uri = esp_uri; + rsp_fields.uri_len = sizeof(esp_uri); + + /* Set advertising interval */ + rsp_fields.adv_itvl = BLE_GAP_ADV_ITVL_MS(500); + rsp_fields.adv_itvl_is_present = 1; + + /* Set scan response fields */ + rc = ble_gap_adv_rsp_set_fields(&rsp_fields); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set scan response data, error code: %d", rc); + return; + } + + /* Set non-connetable and general discoverable mode to be a beacon */ + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + + /* Set advertising interval */ + adv_params.itvl_min = BLE_GAP_ADV_ITVL_MS(500); + adv_params.itvl_max = BLE_GAP_ADV_ITVL_MS(510); + + /* Start advertising */ + rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params, + gap_event_handler, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to start advertising, error code: %d", rc); + return; + } + ESP_LOGI(TAG, "advertising started!"); +} + +/* + * NimBLE applies an event-driven model to keep GAP service going + * gap_event_handler is a callback function registered when calling + * ble_gap_adv_start API and called when a GAP event arrives + */ +static int gap_event_handler(struct ble_gap_event *event, void *arg) { + /* Local variables */ + int rc = 0; + struct ble_gap_conn_desc desc; + + /* Handle different GAP event */ + switch (event->type) { + + /* Connect event */ + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + ESP_LOGI(TAG, "connection %s; status=%d", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + + /* Connection succeeded */ + if (event->connect.status == 0) { + /* Check connection handle */ + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, + "failed to find connection by handle, error code: %d", + rc); + return rc; + } + + /* Print connection descriptor */ + print_conn_desc(&desc); + + /* Try to update connection parameters */ + struct ble_gap_upd_params params = {.itvl_min = desc.conn_itvl, + .itvl_max = desc.conn_itvl, + .latency = 3, + .supervision_timeout = + desc.supervision_timeout}; + rc = ble_gap_update_params(event->connect.conn_handle, ¶ms); + if (rc != 0) { + ESP_LOGE( + TAG, + "failed to update connection parameters, error code: %d", + rc); + return rc; + } + } + /* Connection failed, restart advertising */ + else { + start_advertising(); + } + return rc; + + /* Disconnect event */ + case BLE_GAP_EVENT_DISCONNECT: + /* A connection was terminated, print connection descriptor */ + ESP_LOGI(TAG, "disconnected from peer; reason=%d", + event->disconnect.reason); + + /* Restart advertising */ + start_advertising(); + return rc; + + /* Connection parameters update event */ + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + ESP_LOGI(TAG, "connection updated; status=%d", + event->conn_update.status); + + /* Print connection descriptor */ + rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, "failed to find connection by handle, error code: %d", + rc); + return rc; + } + print_conn_desc(&desc); + return rc; + + /* Advertising complete event */ + case BLE_GAP_EVENT_ADV_COMPLETE: + /* Advertising completed, restart advertising */ + ESP_LOGI(TAG, "advertise complete; reason=%d", + event->adv_complete.reason); + start_advertising(); + return rc; + + /* Notification sent event */ + case BLE_GAP_EVENT_NOTIFY_TX: + if ((event->notify_tx.status != 0) && + (event->notify_tx.status != BLE_HS_EDONE)) { + /* Print notification info on error */ + ESP_LOGI(TAG, + "notify event; conn_handle=%d attr_handle=%d " + "status=%d is_indication=%d", + event->notify_tx.conn_handle, event->notify_tx.attr_handle, + event->notify_tx.status, event->notify_tx.indication); + } + return rc; + + /* Subscribe event */ + case BLE_GAP_EVENT_SUBSCRIBE: + /* Print subscription info to log */ + ESP_LOGI(TAG, + "subscribe event; conn_handle=%d attr_handle=%d " + "reason=%d prevn=%d curn=%d previ=%d curi=%d", + event->subscribe.conn_handle, event->subscribe.attr_handle, + event->subscribe.reason, event->subscribe.prev_notify, + event->subscribe.cur_notify, event->subscribe.prev_indicate, + event->subscribe.cur_indicate); + + /* GATT subscribe event callback */ + gatt_svr_subscribe_cb(event); + return rc; + + /* MTU update event */ + case BLE_GAP_EVENT_MTU: + /* Print MTU update info to log */ + ESP_LOGI(TAG, "mtu update event; conn_handle=%d cid=%d mtu=%d", + event->mtu.conn_handle, event->mtu.channel_id, + event->mtu.value); + return rc; + } + + return rc; +} + + +/* Public functions */ +void adv_init(void) { + /* Local variables */ + int rc = 0; + char addr_str[18] = {0}; + + /* Make sure we have proper BT identity address set (random preferred) */ + rc = ble_hs_util_ensure_addr(0); + if (rc != 0) { + ESP_LOGE(TAG, "device does not have any available bt address!"); + return; + } + + /* Figure out BT address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGE(TAG, "failed to infer address type, error code: %d", rc); + return; + } + + /* Printing ADDR */ + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to copy device address, error code: %d", rc); + return; + } + format_addr(addr_str, addr_val); + ESP_LOGI(TAG, "device address: %s", addr_str); + + /* Start advertising. */ + start_advertising(); +} + +int gap_init(void) { + /* Local variables */ + int rc = 0; + + /* Call NimBLE GAP initialization API */ + ble_svc_gap_init(); + + /* Set GAP device name */ + rc = ble_svc_gap_device_name_set(DEVICE_NAME); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set device name to %s, error code: %d", + DEVICE_NAME, rc); + return rc; + } + return rc; +} diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gatt_svc.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gatt_svc.c new file mode 100644 index 000000000000..f1f75ecf66b6 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gatt_svc.c @@ -0,0 +1,269 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "gatt_svc.h" +#include "common.h" +#include "heart_rate.h" +#include "led.h" + +/* Private function declarations */ +static int heart_rate_chr_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); +static int led_chr_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +/* Private variables */ +/* Heart rate service */ +static const ble_uuid16_t heart_rate_svc_uuid = BLE_UUID16_INIT(0x180D); + +static uint8_t heart_rate_chr_val[2] = {0}; +static uint16_t heart_rate_chr_val_handle; +static const ble_uuid16_t heart_rate_chr_uuid = BLE_UUID16_INIT(0x2A37); + +static uint16_t heart_rate_chr_conn_handle = 0; +static bool heart_rate_chr_conn_handle_inited = false; +static bool heart_rate_ind_status = false; + +/* Automation IO service */ +static const ble_uuid16_t auto_io_svc_uuid = BLE_UUID16_INIT(0x1815); +static uint16_t led_chr_val_handle; +static const ble_uuid128_t led_chr_uuid = + BLE_UUID128_INIT(0x23, 0xd1, 0xbc, 0xea, 0x5f, 0x78, 0x23, 0x15, 0xde, 0xef, + 0x12, 0x12, 0x25, 0x15, 0x00, 0x00); + +/* GATT services table */ +static const struct ble_gatt_svc_def gatt_svr_svcs[] = { + /* Heart rate service */ + {.type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &heart_rate_svc_uuid.u, + .characteristics = + (struct ble_gatt_chr_def[]){ + {/* Heart rate characteristic */ + .uuid = &heart_rate_chr_uuid.u, + .access_cb = heart_rate_chr_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_INDICATE, + .val_handle = &heart_rate_chr_val_handle}, + { + 0, /* No more characteristics in this service. */ + }}}, + + /* Automation IO service */ + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &auto_io_svc_uuid.u, + .characteristics = + (struct ble_gatt_chr_def[]){/* LED characteristic */ + {.uuid = &led_chr_uuid.u, + .access_cb = led_chr_access, + .flags = BLE_GATT_CHR_F_WRITE, + .val_handle = &led_chr_val_handle}, + {0}}, + }, + + { + 0, /* No more services. */ + }, +}; + +/* Private functions */ +static int heart_rate_chr_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + /* Local variables */ + int rc; + + /* Handle access events */ + /* Note: Heart rate characteristic is read only */ + switch (ctxt->op) { + + /* Read characteristic event */ + case BLE_GATT_ACCESS_OP_READ_CHR: + /* Verify connection handle */ + if (conn_handle != BLE_HS_CONN_HANDLE_NONE) { + ESP_LOGI(TAG, "characteristic read; conn_handle=%d attr_handle=%d", + conn_handle, attr_handle); + } else { + ESP_LOGI(TAG, "characteristic read by nimble stack; attr_handle=%d", + attr_handle); + } + + /* Verify attribute handle */ + if (attr_handle == heart_rate_chr_val_handle) { + /* Update access buffer value */ + heart_rate_chr_val[1] = get_heart_rate(); + rc = os_mbuf_append(ctxt->om, &heart_rate_chr_val, + sizeof(heart_rate_chr_val)); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + goto error; + + /* Unknown event */ + default: + goto error; + } + +error: + ESP_LOGE( + TAG, + "unexpected access operation to heart rate characteristic, opcode: %d", + ctxt->op); + return BLE_ATT_ERR_UNLIKELY; +} + +static int led_chr_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + /* Local variables */ + int rc; + + /* Handle access events */ + /* Note: LED characteristic is write only */ + switch (ctxt->op) { + + /* Write characteristic event */ + case BLE_GATT_ACCESS_OP_WRITE_CHR: + /* Verify connection handle */ + if (conn_handle != BLE_HS_CONN_HANDLE_NONE) { + ESP_LOGI(TAG, "characteristic write; conn_handle=%d attr_handle=%d", + conn_handle, attr_handle); + } else { + ESP_LOGI(TAG, + "characteristic write by nimble stack; attr_handle=%d", + attr_handle); + } + + /* Verify attribute handle */ + if (attr_handle == led_chr_val_handle) { + /* Verify access buffer length */ + if (ctxt->om->om_len == 1) { + /* Turn the LED on or off according to the operation bit */ + if (ctxt->om->om_data[0]) { + led_on(); + ESP_LOGI(TAG, "led turned on!"); + } else { + led_off(); + ESP_LOGI(TAG, "led turned off!"); + } + } else { + goto error; + } + return rc; + } + goto error; + + /* Unknown event */ + default: + goto error; + } + +error: + ESP_LOGE(TAG, + "unexpected access operation to led characteristic, opcode: %d", + ctxt->op); + return BLE_ATT_ERR_UNLIKELY; +} + +/* Public functions */ +void send_heart_rate_indication(void) { + if (heart_rate_ind_status && heart_rate_chr_conn_handle_inited) { + ble_gatts_indicate(heart_rate_chr_conn_handle, + heart_rate_chr_val_handle); + ESP_LOGI(TAG, "heart rate indication sent!"); + } +} + +/* + * Handle GATT attribute register events + * - Service register event + * - Characteristic register event + * - Descriptor register event + */ +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) { + /* Local variables */ + char buf[BLE_UUID_STR_LEN]; + + /* Handle GATT attributes register events */ + switch (ctxt->op) { + + /* Service register event */ + case BLE_GATT_REGISTER_OP_SVC: + ESP_LOGD(TAG, "registered service %s with handle=%d", + ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), + ctxt->svc.handle); + break; + + /* Characteristic register event */ + case BLE_GATT_REGISTER_OP_CHR: + ESP_LOGD(TAG, + "registering characteristic %s with " + "def_handle=%d val_handle=%d", + ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), + ctxt->chr.def_handle, ctxt->chr.val_handle); + break; + + /* Descriptor register event */ + case BLE_GATT_REGISTER_OP_DSC: + ESP_LOGD(TAG, "registering descriptor %s with handle=%d", + ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), + ctxt->dsc.handle); + break; + + /* Unknown event */ + default: + assert(0); + break; + } +} + +/* + * GATT server subscribe event callback + * 1. Update heart rate subscription status + */ + +void gatt_svr_subscribe_cb(struct ble_gap_event *event) { + /* Check connection handle */ + if (event->subscribe.conn_handle != BLE_HS_CONN_HANDLE_NONE) { + ESP_LOGI(TAG, "subscribe event; conn_handle=%d attr_handle=%d", + event->subscribe.conn_handle, event->subscribe.attr_handle); + } else { + ESP_LOGI(TAG, "subscribe by nimble stack; attr_handle=%d", + event->subscribe.attr_handle); + } + + /* Check attribute handle */ + if (event->subscribe.attr_handle == heart_rate_chr_val_handle) { + /* Update heart rate subscription status */ + heart_rate_chr_conn_handle = event->subscribe.conn_handle; + heart_rate_chr_conn_handle_inited = true; + heart_rate_ind_status = event->subscribe.cur_indicate; + } +} + +/* + * GATT server initialization + * 1. Initialize GATT service + * 2. Update NimBLE host GATT services counter + * 3. Add GATT services to server + */ +int gatt_svc_init(void) { + /* Local variables */ + int rc; + + /* 1. GATT service initialization */ + ble_svc_gatt_init(); + + /* 2. Update GATT services counter */ + rc = ble_gatts_count_cfg(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + /* 3. Add GATT services */ + rc = ble_gatts_add_svcs(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + return 0; +} diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/heart_rate_mock.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/heart_rate_mock.c new file mode 100644 index 000000000000..c653f6bb3323 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/heart_rate_mock.c @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "common.h" +#include "heart_rate.h" + +/* Private variables */ +static uint8_t heart_rate; + +/* Public functions */ +uint8_t get_heart_rate(void) { return heart_rate; } + +void update_heart_rate(void) { heart_rate = 60 + (uint8_t)(esp_random() % 21); } diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/led.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/led.c new file mode 100644 index 000000000000..514c509e1bd4 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/led.c @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "led.h" +#include "common.h" + +/* Private variables */ +static uint8_t led_state; + +#ifdef CONFIG_BLINK_LED_STRIP +static led_strip_handle_t led_strip; +#endif + +/* Public functions */ +uint8_t get_led_state(void) { return led_state; } + +#ifdef CONFIG_BLINK_LED_STRIP + +void led_on(void) { + /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */ + led_strip_set_pixel(led_strip, 0, 16, 16, 16); + + /* Refresh the strip to send data */ + led_strip_refresh(led_strip); + + /* Update LED state */ + led_state = true; +} + +void led_off(void) { + /* Set all LED off to clear all pixels */ + led_strip_clear(led_strip); + + /* Update LED state */ + led_state = false; +} + +void led_init(void) { + ESP_LOGI(TAG, "example configured to blink addressable led!"); + /* LED strip initialization with the GPIO and pixels number*/ + led_strip_config_t strip_config = { + .strip_gpio_num = CONFIG_BLINK_GPIO, + .max_leds = 1, // at least one LED on board + }; +#if CONFIG_BLINK_LED_STRIP_BACKEND_RMT + led_strip_rmt_config_t rmt_config = { + .resolution_hz = 10 * 1000 * 1000, // 10MHz + .flags.with_dma = false, + }; + ESP_ERROR_CHECK( + led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); +#elif CONFIG_BLINK_LED_STRIP_BACKEND_SPI + led_strip_spi_config_t spi_config = { + .spi_bus = SPI2_HOST, + .flags.with_dma = true, + }; + ESP_ERROR_CHECK( + led_strip_new_spi_device(&strip_config, &spi_config, &led_strip)); +#else +#error "unsupported LED strip backend" +#endif + /* Set all LED off to clear all pixels */ + led_off(); +} + +#elif CONFIG_BLINK_LED_GPIO + +void led_on(void) { gpio_set_level(CONFIG_BLINK_GPIO, true); } + +void led_off(void) { gpio_set_level(CONFIG_BLINK_GPIO, false); } + +void led_init(void) { + ESP_LOGI(TAG, "example configured to blink gpio led!"); + gpio_reset_pin(CONFIG_BLINK_GPIO); + /* Set the GPIO as a push/pull output */ + gpio_set_direction(CONFIG_BLINK_GPIO, GPIO_MODE_OUTPUT); +} + +#else +#error "unsupported LED type" +#endif diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults new file mode 100644 index 000000000000..551f506530b4 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults @@ -0,0 +1,6 @@ +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n + +CONFIG_BLINK_LED_GPIO=y +CONFIG_BLINK_GPIO=8 diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32 b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32 new file mode 100644 index 000000000000..263ec939b18d --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32 @@ -0,0 +1 @@ +CONFIG_BLINK_GPIO=5 diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32c3 b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32c3 new file mode 100644 index 000000000000..da044304532e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32c3 @@ -0,0 +1 @@ +CONFIG_BLINK_LED_STRIP=y diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32c6 b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32c6 new file mode 100644 index 000000000000..da044304532e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32c6 @@ -0,0 +1 @@ +CONFIG_BLINK_LED_STRIP=y diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32h2 b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32h2 new file mode 100644 index 000000000000..da044304532e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32h2 @@ -0,0 +1 @@ +CONFIG_BLINK_LED_STRIP=y diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32s3 b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32s3 new file mode 100644 index 000000000000..5ac9d30b41fe --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/sdkconfig.defaults.esp32s3 @@ -0,0 +1,2 @@ +CONFIG_BLINK_LED_STRIP=y +CONFIG_BLINK_GPIO=48 diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/CMakeLists.txt b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/CMakeLists.txt new file mode 100644 index 000000000000..d72998f08a44 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(nimble_security) diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/README.md b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/README.md new file mode 100644 index 000000000000..5c7d982a7eec --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/README.md @@ -0,0 +1,224 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# NimBLE Security Example + +## Overview + +This example is extended from NimBLE GATT Server Example, and further introduces + +1. How to set random non-resolvable private address for device +2. How to ask for connection encryption from peripheral side on characteristic access +3. How to bond with peer device using a random generated 6-digit passkey + +It uses ESP32's Bluetooth controller and NimBLE host stack. + +To test this demo, any BLE scanner application can be used. + +## Try It Yourself + +### Set Target + +Before project configuration and build, be sure to set the correct chip target using: + +``` shell +idf.py set-target +``` + +For example, if you're using ESP32, then input + +``` Shell +idf.py set-target esp32 +``` + +### Build and Flash + +Run the following command to build, flash and monitor the project. + +``` Shell +idf.py -p flash monitor +``` + +For example, if the corresponding serial port is `/dev/ttyACM0`, then it goes + +``` Shell +idf.py -p /dev/ttyACM0 flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects. + +## Code Explained + +### Overview + +The following is additional content compared to the NimBLE GATT Server example. + +1. Initialization procedure is generally similar to NimBLE GATT Server Example, but we'll initialize random number generator in the beginning, and in `nimble_host_config_init` we will configure security manager to enable related features +2. On stack sync, a random non-resolvable private address is generated and set as the device address +3. Characteristics' permission modified to require connection encryption when accessing +4. 3 more GAP event branches added in `gap_event_handler` to handle encryption related events + +### Entry Point + +In `nimble_host_config_init` function, we're going to enable some security manager features, including + +- Bonding +- Man-in-the-middle protection +- Key distribution + +Also, we're going to set the IO capability to `BLE_HS_IO_DISPLAY_ONLY`, since it's possible to print out the passkey to serial output. + +``` C +static void nimble_host_config_init(void) { + ... + + /* Security manager configuration */ + ble_hs_cfg.sm_io_cap = BLE_HS_IO_DISPLAY_ONLY; + ble_hs_cfg.sm_bonding = 1; + ble_hs_cfg.sm_mitm = 1; + ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; + ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; + + ... +} +``` + +### GATT Server Updates + +For heart rate characteristic and LED characteristic, `BLE_GATT_CHR_F_READ_ENC` and `BLE_GATT_CHR_F_WRITE_ENC` flag are added respectively to require connection encryption when GATT client tries to access the characteristic. Thanks to NimBLE host stack, the connection encryption will be initiated automatically by adding these flags. + +However, heart rate characteristic is also indicatable, and NimBLE host stack does not offer an implementation for indication access to require connection encryption, so we need to do it ourselves. For GATT server, we simply check connection security status by calling an external function `is_connection_encrypted` in `send_heart_rate_indication` function to determine if the indication should be sent. This external function is defined in GAP layer, and we'll talk about it in *GAP Event Handler Updates* section. + +``` C +void send_heart_rate_indication(void) { + /* Check if connection handle is initialized */ + if (!heart_rate_chr_conn_handle_inited) { + return; + } + + /* Check indication and security status */ + if (heart_rate_ind_status && + is_connection_encrypted(heart_rate_chr_conn_handle)) { + ble_gatts_indicate(heart_rate_chr_conn_handle, + heart_rate_chr_val_handle); + } +} +``` + +### Random Address + +In the following function, we can generate a random non-resolvable private address and set as the device address. We will call it in `adv_init` function before ensuring address availability. + +``` C +static void set_random_addr(void) { + /* Local variables */ + int rc = 0; + ble_addr_t addr; + + /* Generate new non-resolvable private address */ + rc = ble_hs_id_gen_rnd(0, &addr); + assert(rc == 0); + + /* Set address */ + rc = ble_hs_id_set_rnd(addr.val); + assert(rc == 0); +} +``` + +### Check Connection Encryption Status + +By connection handle, we can fetch connection descriptor from NimBLE host stack, and there's a flag indicating connection encryption status, check the following codes + +``` C +bool is_connection_encrypted(uint16_t conn_handle) { + /* Local variables */ + int rc = 0; + struct ble_gap_conn_desc desc; + + /* Print connection descriptor */ + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, "failed to find connection by handle, error code: %d", + rc); + return false; + } + + return desc.sec_state.encrypted; +} +``` + +### GAP Event Handler Updates + +3 more GAP event branches are added in `gap_event_handler`, which are + +- `BLE_GAP_EVENT_ENC_CHANGE` - Encryption change event +- `BLE_GAP_EVENT_REPEAT_PAIRING` - Repeat pairing event +- `BLE_GAP_EVENT_PASSKEY_ACTION` - Passkey action event + +On encryption change event, we're going to print the encryption change status to output. + +``` C +/* Encryption change event */ +case BLE_GAP_EVENT_ENC_CHANGE: + /* Encryption has been enabled or disabled for this connection. */ + if (event->enc_change.status == 0) { + ESP_LOGI(TAG, "connection encrypted!"); + } else { + ESP_LOGE(TAG, "connection encryption failed, status: %d", + event->enc_change.status); + } + return rc; +``` + +On repeat pairing event, to make it simple, we will just delete the old bond and repeat pairing. + +``` C +/* Repeat pairing event */ +case BLE_GAP_EVENT_REPEAT_PAIRING: + /* Delete the old bond */ + rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, "failed to find connection, error code %d", rc); + return rc; + } + ble_store_util_delete_peer(&desc.peer_id_addr); + + /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should + * continue with pairing operation */ + ESP_LOGI(TAG, "repairing..."); + return BLE_GAP_REPEAT_PAIRING_RETRY; +``` + +On passkey action event, a random 6-digit passkey is generated, and you are supposed to enter the same passkey on pairing. If the input is consistent with the generated passkey, you should be able to bond with the device. + +``` C +/* Passkey action event */ +case BLE_GAP_EVENT_PASSKEY_ACTION: + /* Display action */ + if (event->passkey.params.action == BLE_SM_IOACT_DISP) { + /* Generate passkey */ + struct ble_sm_io pkey = {0}; + pkey.action = event->passkey.params.action; + pkey.passkey = 100000 + esp_random() % 900000; + ESP_LOGI(TAG, "enter passkey %" PRIu32 " on the peer side", + pkey.passkey); + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); + if (rc != 0) { + ESP_LOGE(TAG, + "failed to inject security manager io, error code: %d", + rc); + return rc; + } + } + return rc; +``` + +## Observation + +If everything goes well, pairing will be required when you try to access any of the characteristics, that is, read or indicate heart rate characteristic, or write LED characteristic. + +## Troubleshooting + +For any technical queries, please file an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/CMakeLists.txt b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/CMakeLists.txt new file mode 100644 index 000000000000..584111329971 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/CMakeLists.txt @@ -0,0 +1,4 @@ +file(GLOB_RECURSE srcs "main.c" "src/*.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "./include") diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/Kconfig.projbuild b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/Kconfig.projbuild new file mode 100644 index 000000000000..0035dc34f0ce --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/Kconfig.projbuild @@ -0,0 +1,42 @@ +menu "Example Configuration" + + orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" + + choice BLINK_LED + prompt "Blink LED type" + default BLINK_LED_GPIO + help + Select the LED type. A normal level controlled LED or an addressable LED strip. + The default selection is based on the Espressif DevKit boards. + You can change the default selection according to your board. + + config BLINK_LED_GPIO + bool "GPIO" + config BLINK_LED_STRIP + bool "LED strip" + endchoice + + choice BLINK_LED_STRIP_BACKEND + depends on BLINK_LED_STRIP + prompt "LED strip backend peripheral" + default BLINK_LED_STRIP_BACKEND_RMT if SOC_RMT_SUPPORTED + default BLINK_LED_STRIP_BACKEND_SPI + help + Select the backend peripheral to drive the LED strip. + + config BLINK_LED_STRIP_BACKEND_RMT + depends on SOC_RMT_SUPPORTED + bool "RMT" + config BLINK_LED_STRIP_BACKEND_SPI + bool "SPI" + endchoice + + config BLINK_GPIO + int "Blink GPIO number" + range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX + default 8 + help + GPIO number (IOxx) to blink on and off the LED. + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used to blink. + +endmenu diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/idf_component.yml b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/idf_component.yml new file mode 100644 index 000000000000..8723a2e11a9f --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/idf_component.yml @@ -0,0 +1,2 @@ +dependencies: + espressif/led_strip: "^2.4.1" diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/common.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/common.h new file mode 100644 index 000000000000..36ce8ad93d2f --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/common.h @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef COMMON_H +#define COMMON_H + +/* Includes */ +/* STD APIs */ +#include +#include +#include +#include + +/* ESP APIs */ +#include "esp_log.h" +#include "esp_random.h" +#include "nvs_flash.h" +#include "sdkconfig.h" + +/* FreeRTOS APIs */ +#include +#include + +/* NimBLE stack APIs */ +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "host/util/util.h" +#include "nimble/ble.h" +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" + +/* Defines */ +#define TAG "NimBLE_Security" +#define DEVICE_NAME "NimBLE_SEC" + +#endif // COMMON_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/gap.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/gap.h new file mode 100644 index 000000000000..c0af19f3e614 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/gap.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef GAP_SVC_H +#define GAP_SVC_H + +/* Includes */ +/* NimBLE GAP APIs */ +#include "host/ble_gap.h" +#include "services/gap/ble_svc_gap.h" + +/* Defines */ +#define BLE_GAP_APPEARANCE_GENERIC_TAG 0x0200 +#define BLE_GAP_URI_PREFIX_HTTPS 0x17 +#define BLE_GAP_LE_ROLE_PERIPHERAL 0x00 + +/* Public function declarations */ +void adv_init(void); +bool is_connection_encrypted(uint16_t conn_handle); +int gap_init(void); + +#endif // GAP_SVC_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/gatt_svc.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/gatt_svc.h new file mode 100644 index 000000000000..4971525b5584 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/gatt_svc.h @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef GATT_SVR_H +#define GATT_SVR_H + +/* Includes */ +/* NimBLE GATT APIs */ +#include "host/ble_gatt.h" +#include "services/gatt/ble_svc_gatt.h" + +/* NimBLE GAP APIs */ +#include "host/ble_gap.h" + +/* Public function declarations */ +void send_heart_rate_indication(void); +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +int gatt_svr_subscribe_cb(struct ble_gap_event *event); +int gatt_svc_init(void); + +#endif // GATT_SVR_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/heart_rate.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/heart_rate.h new file mode 100644 index 000000000000..59fca7dbe882 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/heart_rate.h @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef HEART_RATE_H +#define HEART_RATE_H + +/* Includes */ +/* ESP APIs */ +#include "esp_random.h" + +/* Defines */ +#define HEART_RATE_TASK_PERIOD (1000 / portTICK_PERIOD_MS) + +/* Public function declarations */ +uint8_t get_heart_rate(void); +void update_heart_rate(void); + +#endif // HEART_RATE_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/led.h b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/led.h new file mode 100644 index 000000000000..0f6b5f774f2a --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/include/led.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#ifndef LED_H +#define LED_H + +/* Includes */ +/* ESP APIs */ +#include "driver/gpio.h" +#include "led_strip.h" +#include "sdkconfig.h" + +/* Defines */ +#define BLINK_GPIO CONFIG_BLINK_GPIO + +/* Public function declarations */ +uint8_t get_led_state(void); +void led_on(void); +void led_off(void); +void led_init(void); + +#endif // LED_H diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/main.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/main.c new file mode 100644 index 000000000000..f271d861ebbd --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/main.c @@ -0,0 +1,142 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "common.h" +#include "gap.h" +#include "gatt_svc.h" +#include "heart_rate.h" +#include "led.h" + +/* Library function declarations */ +void ble_store_config_init(void); + +/* Private function declarations */ +static void nimble_host_config_init(void); +static void nimble_host_task(void *param); + +/* Private functions */ +/* + * Stack event callback functions + * - on_stack_reset is called when host resets BLE stack due to errors + * - on_stack_sync is called when host has synced with controller + */ +static void on_stack_reset(int reason) { + /* On reset, print reset reason to console */ + ESP_LOGI(TAG, "nimble stack reset, reset reason: %d", reason); +} + +static void on_stack_sync(void) { + /* On stack sync, do advertising initialization */ + adv_init(); +} + +static void nimble_host_config_init(void) { + /* Set host callbacks */ + ble_hs_cfg.reset_cb = on_stack_reset; + ble_hs_cfg.sync_cb = on_stack_sync; + ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Security manager configuration */ + ble_hs_cfg.sm_io_cap = BLE_HS_IO_DISPLAY_ONLY; + ble_hs_cfg.sm_bonding = 1; + ble_hs_cfg.sm_mitm = 1; + ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; + ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID; + + /* Store host configuration */ + ble_store_config_init(); +} + +static void nimble_host_task(void *param) { + /* Task entry log */ + ESP_LOGI(TAG, "nimble host task has been started!"); + + /* This function won't return until nimble_port_stop() is executed */ + nimble_port_run(); + + /* Clean up at exit */ + vTaskDelete(NULL); +} + +static void heart_rate_task(void *param) { + /* Task entry log */ + ESP_LOGI(TAG, "heart rate task has been started!"); + + /* Loop forever */ + while (1) { + /* Update heart rate value every 1 second */ + update_heart_rate(); + ESP_LOGI(TAG, "heart rate updated to %d", get_heart_rate()); + + /* Send heart rate indication if enabled */ + send_heart_rate_indication(); + + /* Sleep */ + vTaskDelay(HEART_RATE_TASK_PERIOD); + } + + /* Clean up at exit */ + vTaskDelete(NULL); +} + +void app_main(void) { + /* Local variables */ + int rc; + uint32_t seed = esp_random(); + esp_err_t ret; + + /* LED initialization */ + led_init(); + + /* Random generator initialization */ + srand(seed); + + /* + * NVS flash initialization + * Dependency of BLE stack to store configurations + */ + ret = nvs_flash_init(); + if (ret == ESP_ERR_NVS_NO_FREE_PAGES || + ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize nvs flash, error code: %d ", ret); + return; + } + + /* NimBLE stack initialization */ + ret = nimble_port_init(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "failed to initialize nimble stack, error code: %d ", + ret); + return; + } + + /* GAP service initialization */ + rc = gap_init(); + if (rc != 0) { + ESP_LOGE(TAG, "failed to initialize GAP service, error code: %d", rc); + return; + } + + /* GATT server initialization */ + rc = gatt_svc_init(); + if (rc != 0) { + ESP_LOGE(TAG, "failed to initialize GATT server, error code: %d", rc); + return; + } + + /* NimBLE host configuration initialization */ + nimble_host_config_init(); + + /* Start NimBLE host task thread and return */ + xTaskCreate(nimble_host_task, "NimBLE Host", 4*1024, NULL, 5, NULL); + xTaskCreate(heart_rate_task, "Heart Rate", 4*1024, NULL, 5, NULL); + return; +} 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 new file mode 100644 index 000000000000..d4e7c249b68c --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gap.c @@ -0,0 +1,386 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "gap.h" +#include "common.h" +#include "gatt_svc.h" + +/* Private function declarations */ +inline static void format_addr(char *addr_str, uint8_t addr[]); +static void print_conn_desc(struct ble_gap_conn_desc *desc); +static void start_advertising(void); +static void set_random_addr(void); +static int gap_event_handler(struct ble_gap_event *event, void *arg); + +/* Private variables */ +static uint8_t own_addr_type; +static uint8_t addr_val[6] = {0}; +static uint8_t esp_uri[] = {BLE_GAP_URI_PREFIX_HTTPS, '/', '/', 'e', 's', 'p', 'r', 'e', 's', 's', 'i', 'f', '.', 'c', 'o', 'm'}; + +/* Private functions */ +inline static void format_addr(char *addr_str, uint8_t addr[]) { + sprintf(addr_str, "%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1], + addr[2], addr[3], addr[4], addr[5]); +} + +static void print_conn_desc(struct ble_gap_conn_desc *desc) { + /* Local variables */ + char addr_str[18] = {0}; + + /* Connection handle */ + ESP_LOGI(TAG, "connection handle: %d", desc->conn_handle); + + /* Local ID address */ + format_addr(addr_str, desc->our_id_addr.val); + ESP_LOGI(TAG, "device id address: type=%d, value=%s", + desc->our_id_addr.type, addr_str); + + /* Peer ID address */ + format_addr(addr_str, desc->peer_id_addr.val); + ESP_LOGI(TAG, "peer id address: type=%d, value=%s", desc->peer_id_addr.type, + addr_str); + + /* Connection info */ + ESP_LOGI(TAG, + "conn_itvl=%d, conn_latency=%d, supervision_timeout=%d, " + "encrypted=%d, authenticated=%d, bonded=%d\n", + desc->conn_itvl, desc->conn_latency, desc->supervision_timeout, + desc->sec_state.encrypted, desc->sec_state.authenticated, + desc->sec_state.bonded); +} + +static void set_random_addr(void) { + /* Local variables */ + int rc = 0; + ble_addr_t addr; + + /* Generate new non-resolvable private address */ + rc = ble_hs_id_gen_rnd(0, &addr); + assert(rc == 0); + + /* Set address */ + rc = ble_hs_id_set_rnd(addr.val); + assert(rc == 0); +} + +static void start_advertising(void) { + /* Local variables */ + int rc = 0; + const char *name; + struct ble_hs_adv_fields adv_fields = {0}; + struct ble_hs_adv_fields rsp_fields = {0}; + struct ble_gap_adv_params adv_params = {0}; + + /* Set advertising flags */ + adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; + + /* Set device name */ + name = ble_svc_gap_device_name(); + adv_fields.name = (uint8_t *)name; + adv_fields.name_len = strlen(name); + adv_fields.name_is_complete = 1; + + /* Set device tx power */ + adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + adv_fields.tx_pwr_lvl_is_present = 1; + + /* Set device appearance */ + adv_fields.appearance = BLE_GAP_APPEARANCE_GENERIC_TAG; + adv_fields.appearance_is_present = 1; + + /* Set device LE role */ + adv_fields.le_role = BLE_GAP_LE_ROLE_PERIPHERAL; + adv_fields.le_role_is_present = 1; + + /* Set advertiement fields */ + rc = ble_gap_adv_set_fields(&adv_fields); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set advertising data, error code: %d", rc); + return; + } + + /* Set device address */ + rsp_fields.device_addr = addr_val; + rsp_fields.device_addr_type = own_addr_type; + rsp_fields.device_addr_is_present = 1; + + /* Set URI */ + rsp_fields.uri = esp_uri; + rsp_fields.uri_len = sizeof(esp_uri); + + /* Set advertising interval */ + rsp_fields.adv_itvl = BLE_GAP_ADV_ITVL_MS(500); + rsp_fields.adv_itvl_is_present = 1; + + /* Set scan response fields */ + rc = ble_gap_adv_rsp_set_fields(&rsp_fields); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set scan response data, error code: %d", rc); + return; + } + + /* Set non-connetable and general discoverable mode to be a beacon */ + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + + /* Set advertising interval */ + adv_params.itvl_min = BLE_GAP_ADV_ITVL_MS(500); + adv_params.itvl_max = BLE_GAP_ADV_ITVL_MS(510); + + /* Start advertising */ + rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER, &adv_params, + gap_event_handler, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to start advertising, error code: %d", rc); + return; + } + ESP_LOGI(TAG, "advertising started!"); +} + +/* + * NimBLE applies an event-driven model to keep GAP service going + * gap_event_handler is a callback function registered when calling + * ble_gap_adv_start API and called when a GAP event arrives + */ +static int gap_event_handler(struct ble_gap_event *event, void *arg) { + /* Local variables */ + int rc = 0; + struct ble_gap_conn_desc desc; + + /* Handle different GAP event */ + switch (event->type) { + + /* Connect event */ + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + ESP_LOGI(TAG, "connection %s; status=%d", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + + /* Connection succeeded */ + if (event->connect.status == 0) { + /* Check connection handle */ + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, + "failed to find connection by handle, error code: %d", + rc); + return rc; + } + + /* Print connection descriptor */ + print_conn_desc(&desc); + + /* Try to update connection parameters */ + struct ble_gap_upd_params params = {.itvl_min = desc.conn_itvl, + .itvl_max = desc.conn_itvl, + .latency = 3, + .supervision_timeout = + desc.supervision_timeout}; + rc = ble_gap_update_params(event->connect.conn_handle, ¶ms); + if (rc != 0) { + ESP_LOGE( + TAG, + "failed to update connection parameters, error code: %d", + rc); + return rc; + } + } + /* Connection failed, restart advertising */ + else { + start_advertising(); + } + return rc; + + /* Disconnect event */ + case BLE_GAP_EVENT_DISCONNECT: + /* A connection was terminated, print connection descriptor */ + ESP_LOGI(TAG, "disconnected from peer; reason=%d", + event->disconnect.reason); + + /* Restart advertising */ + start_advertising(); + return rc; + + /* Connection parameters update event */ + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + ESP_LOGI(TAG, "connection updated; status=%d", + event->conn_update.status); + + /* Print connection descriptor */ + rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, "failed to find connection by handle, error code: %d", + rc); + return rc; + } + print_conn_desc(&desc); + return rc; + + /* Advertising complete event */ + case BLE_GAP_EVENT_ADV_COMPLETE: + /* Advertising completed, restart advertising */ + ESP_LOGI(TAG, "advertise complete; reason=%d", + event->adv_complete.reason); + start_advertising(); + return rc; + + /* Notification sent event */ + case BLE_GAP_EVENT_NOTIFY_TX: + if ((event->notify_tx.status != 0) && + (event->notify_tx.status != BLE_HS_EDONE)) { + /* Print notification info on error */ + ESP_LOGI(TAG, + "notify event; conn_handle=%d attr_handle=%d " + "status=%d is_indication=%d", + event->notify_tx.conn_handle, event->notify_tx.attr_handle, + event->notify_tx.status, event->notify_tx.indication); + } + return rc; + + /* Subscribe event */ + case BLE_GAP_EVENT_SUBSCRIBE: + /* Print subscription info to log */ + ESP_LOGI(TAG, + "subscribe event; conn_handle=%d attr_handle=%d " + "reason=%d prevn=%d curn=%d previ=%d curi=%d", + event->subscribe.conn_handle, event->subscribe.attr_handle, + event->subscribe.reason, event->subscribe.prev_notify, + event->subscribe.cur_notify, event->subscribe.prev_indicate, + event->subscribe.cur_indicate); + + /* GATT subscribe event callback */ + rc = gatt_svr_subscribe_cb(event); + if (rc == BLE_ATT_ERR_INSUFFICIENT_AUTHEN) { + /* Request connection encryption */ + return ble_gap_security_initiate(event->subscribe.conn_handle); + } + return rc; + + /* MTU update event */ + case BLE_GAP_EVENT_MTU: + /* Print MTU update info to log */ + ESP_LOGI(TAG, "mtu update event; conn_handle=%d cid=%d mtu=%d", + event->mtu.conn_handle, event->mtu.channel_id, + event->mtu.value); + return rc; + + /* Encryption change event */ + case BLE_GAP_EVENT_ENC_CHANGE: + /* Encryption has been enabled or disabled for this connection. */ + if (event->enc_change.status == 0) { + ESP_LOGI(TAG, "connection encrypted!"); + } else { + ESP_LOGE(TAG, "connection encryption failed, status: %d", + event->enc_change.status); + } + return rc; + + /* Repeat pairing event */ + case BLE_GAP_EVENT_REPEAT_PAIRING: + /* Delete the old bond */ + rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, "failed to find connection, error code %d", rc); + return rc; + } + ble_store_util_delete_peer(&desc.peer_id_addr); + + /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should + * continue with pairing operation */ + ESP_LOGI(TAG, "repairing..."); + return BLE_GAP_REPEAT_PAIRING_RETRY; + + /* Passkey action event */ + case BLE_GAP_EVENT_PASSKEY_ACTION: + /* Display action */ + if (event->passkey.params.action == BLE_SM_IOACT_DISP) { + /* Generate passkey */ + struct ble_sm_io pkey = {0}; + pkey.action = event->passkey.params.action; + pkey.passkey = 100000 + esp_random() % 900000; + ESP_LOGI(TAG, "enter passkey %" PRIu32 " on the peer side", + pkey.passkey); + rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey); + if (rc != 0) { + ESP_LOGE(TAG, + "failed to inject security manager io, error code: %d", + rc); + return rc; + } + } + return rc; + } + return rc; +} + +/* Public functions */ +void adv_init(void) { + /* Local variables */ + int rc = 0; + char addr_str[18] = {0}; + + /* Make sure we have proper BT identity address set */ + set_random_addr(); + rc = ble_hs_util_ensure_addr(1); + if (rc != 0) { + ESP_LOGE(TAG, "device does not have any available bt address!"); + return; + } + + /* Figure out BT address to use while advertising */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + ESP_LOGE(TAG, "failed to infer address type, error code: %d", rc); + return; + } + + /* Copy device address to addr_val */ + rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL); + if (rc != 0) { + ESP_LOGE(TAG, "failed to copy device address, error code: %d", rc); + return; + } + format_addr(addr_str, addr_val); + ESP_LOGI(TAG, "device address: %s", addr_str); + + /* Start advertising. */ + start_advertising(); +} + +bool is_connection_encrypted(uint16_t conn_handle) { + /* Local variables */ + int rc = 0; + struct ble_gap_conn_desc desc; + + /* Print connection descriptor */ + rc = ble_gap_conn_find(conn_handle, &desc); + if (rc != 0) { + ESP_LOGE(TAG, "failed to find connection by handle, error code: %d", + rc); + return false; + } + + return desc.sec_state.encrypted; +} + +int gap_init(void) { + /* Local variables */ + int rc = 0; + + /* Call NimBLE GAP initialization API */ + ble_svc_gap_init(); + + /* Set GAP device name */ + rc = ble_svc_gap_device_name_set(DEVICE_NAME); + if (rc != 0) { + ESP_LOGE(TAG, "failed to set device name to %s, error code: %d", + DEVICE_NAME, rc); + return rc; + } + return rc; +} diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gatt_svc.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gatt_svc.c new file mode 100644 index 000000000000..17d768382f2e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gatt_svc.c @@ -0,0 +1,277 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "gatt_svc.h" +#include "common.h" +#include "gap.h" +#include "heart_rate.h" +#include "led.h" + +/* Private function declarations */ +static int heart_rate_chr_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); +static int led_chr_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg); + +/* Private variables */ +/* Heart rate service */ +static const ble_uuid16_t heart_rate_svc_uuid = BLE_UUID16_INIT(0x180D); + +static uint8_t heart_rate_chr_val[2] = {0}; +static uint16_t heart_rate_chr_val_handle; +static const ble_uuid16_t heart_rate_chr_uuid = BLE_UUID16_INIT(0x2A37); + +static uint16_t heart_rate_chr_conn_handle = 0; +static bool heart_rate_chr_conn_handle_inited = false; +static bool heart_rate_ind_status = false; + +/* Automation IO service */ +static const ble_uuid16_t auto_io_svc_uuid = BLE_UUID16_INIT(0x1815); +static uint16_t led_chr_val_handle; +static const ble_uuid128_t led_chr_uuid = + BLE_UUID128_INIT(0x23, 0xd1, 0xbc, 0xea, 0x5f, 0x78, 0x23, 0x15, 0xde, 0xef, + 0x12, 0x12, 0x25, 0x15, 0x00, 0x00); + +/* GATT services table */ +static const struct ble_gatt_svc_def gatt_svr_svcs[] = { + /* Heart rate service */ + {.type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &heart_rate_svc_uuid.u, + .characteristics = + (struct ble_gatt_chr_def[]){ + {/* Heart rate characteristic */ + .uuid = &heart_rate_chr_uuid.u, + .access_cb = heart_rate_chr_access, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_INDICATE | + BLE_GATT_CHR_F_READ_ENC, + .val_handle = &heart_rate_chr_val_handle}, + { + 0, /* No more characteristics in this service. */ + }}}, + + /* Automation IO service */ + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &auto_io_svc_uuid.u, + .characteristics = + (struct ble_gatt_chr_def[]){ + /* LED characteristic */ + {.uuid = &led_chr_uuid.u, + .access_cb = led_chr_access, + .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC, + .val_handle = &led_chr_val_handle}, + {0}}, + }, + + { + 0, /* No more services. */ + }, +}; + +/* Private functions */ +static int heart_rate_chr_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + /* Local variables */ + int rc; + + /* Handle access events */ + /* Note: Heart rate characteristic is read only */ + switch (ctxt->op) { + + /* Read characteristic event */ + case BLE_GATT_ACCESS_OP_READ_CHR: + /* Verify connection handle */ + if (conn_handle != BLE_HS_CONN_HANDLE_NONE) { + ESP_LOGI(TAG, "characteristic read; conn_handle=%d attr_handle=%d", + conn_handle, attr_handle); + } else { + ESP_LOGI(TAG, "characteristic read by nimble stack; attr_handle=%d", + attr_handle); + } + + /* Verify attribute handle */ + if (attr_handle == heart_rate_chr_val_handle) { + /* Update access buffer value */ + heart_rate_chr_val[1] = get_heart_rate(); + rc = os_mbuf_append(ctxt->om, &heart_rate_chr_val, + sizeof(heart_rate_chr_val)); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + goto error; + + /* Unknown event */ + default: + goto error; + } + +error: + ESP_LOGE( + TAG, + "unexpected access operation to heart rate characteristic, opcode: %d", + ctxt->op); + return BLE_ATT_ERR_UNLIKELY; +} + +static int led_chr_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) { + /* Local variables */ + int rc; + + /* Handle access events */ + /* Note: LED characteristic is write only */ + switch (ctxt->op) { + + /* Write characteristic event */ + case BLE_GATT_ACCESS_OP_WRITE_CHR: + /* Verify connection handle */ + if (conn_handle != BLE_HS_CONN_HANDLE_NONE) { + ESP_LOGI(TAG, "characteristic write; conn_handle=%d attr_handle=%d", + conn_handle, attr_handle); + } else { + ESP_LOGI(TAG, + "characteristic write by nimble stack; attr_handle=%d", + attr_handle); + } + + /* Verify attribute handle */ + if (attr_handle == led_chr_val_handle) { + /* Verify access buffer length */ + if (ctxt->om->om_len == 1) { + /* Turn the LED on or off according to the operation bit */ + if (ctxt->om->om_data[0]) { + led_on(); + ESP_LOGI(TAG, "led turned on!"); + } else { + led_off(); + ESP_LOGI(TAG, "led turned off!"); + } + } else { + goto error; + } + return rc; + } + goto error; + + /* Unknown event */ + default: + goto error; + } + +error: + ESP_LOGE(TAG, + "unexpected access operation to led characteristic, opcode: %d", + ctxt->op); + return BLE_ATT_ERR_UNLIKELY; +} + +/* Public functions */ +void send_heart_rate_indication(void) { + /* Check if connection handle is initialized */ + if (!heart_rate_chr_conn_handle_inited) { + return; + } + + /* Check indication and security status */ + if (heart_rate_ind_status && + is_connection_encrypted(heart_rate_chr_conn_handle)) { + ble_gatts_indicate(heart_rate_chr_conn_handle, + heart_rate_chr_val_handle); + } +} + +/* + * Handle GATT attribute register events + * - Service register event + * - Characteristic register event + * - Descriptor register event + */ +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) { + /* Local variables */ + char buf[BLE_UUID_STR_LEN]; + + /* Handle GATT attributes register events */ + switch (ctxt->op) { + + /* Service register event */ + case BLE_GATT_REGISTER_OP_SVC: + ESP_LOGD(TAG, "registered service %s with handle=%d", + ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), + ctxt->svc.handle); + break; + + /* Characteristic register event */ + case BLE_GATT_REGISTER_OP_CHR: + ESP_LOGD(TAG, + "registering characteristic %s with " + "def_handle=%d val_handle=%d", + ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), + ctxt->chr.def_handle, ctxt->chr.val_handle); + break; + + /* Descriptor register event */ + case BLE_GATT_REGISTER_OP_DSC: + ESP_LOGD(TAG, "registering descriptor %s with handle=%d", + ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), + ctxt->dsc.handle); + break; + + /* Unknown event */ + default: + assert(0); + break; + } +} + +/* + * GATT server subscribe event callback + * 1. Update heart rate subscription status + */ + +int gatt_svr_subscribe_cb(struct ble_gap_event *event) { + /* Check attribute handle */ + if (event->subscribe.attr_handle == heart_rate_chr_val_handle) { + /* Update heart rate subscription status */ + heart_rate_chr_conn_handle = event->subscribe.conn_handle; + heart_rate_chr_conn_handle_inited = true; + heart_rate_ind_status = event->subscribe.cur_indicate; + + /* Check security status */ + if (!is_connection_encrypted(event->subscribe.conn_handle)) { + ESP_LOGE(TAG, "failed to subscribe to heart rate measurement, " + "connection not encrypted!"); + return BLE_ATT_ERR_INSUFFICIENT_AUTHEN; + } + } + return 0; +} + +/* + * GATT server initialization + * 1. Initialize GATT service + * 2. Update NimBLE host GATT services counter + * 3. Add GATT services to server + */ +int gatt_svc_init(void) { + /* Local variables */ + int rc; + + /* 1. GATT service initialization */ + ble_svc_gatt_init(); + + /* 2. Update GATT services counter */ + rc = ble_gatts_count_cfg(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + /* 3. Add GATT services */ + rc = ble_gatts_add_svcs(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + return 0; +} diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/heart_rate_mock.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/heart_rate_mock.c new file mode 100644 index 000000000000..c653f6bb3323 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/heart_rate_mock.c @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "common.h" +#include "heart_rate.h" + +/* Private variables */ +static uint8_t heart_rate; + +/* Public functions */ +uint8_t get_heart_rate(void) { return heart_rate; } + +void update_heart_rate(void) { heart_rate = 60 + (uint8_t)(esp_random() % 21); } diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/led.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/led.c new file mode 100644 index 000000000000..514c509e1bd4 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/led.c @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Includes */ +#include "led.h" +#include "common.h" + +/* Private variables */ +static uint8_t led_state; + +#ifdef CONFIG_BLINK_LED_STRIP +static led_strip_handle_t led_strip; +#endif + +/* Public functions */ +uint8_t get_led_state(void) { return led_state; } + +#ifdef CONFIG_BLINK_LED_STRIP + +void led_on(void) { + /* Set the LED pixel using RGB from 0 (0%) to 255 (100%) for each color */ + led_strip_set_pixel(led_strip, 0, 16, 16, 16); + + /* Refresh the strip to send data */ + led_strip_refresh(led_strip); + + /* Update LED state */ + led_state = true; +} + +void led_off(void) { + /* Set all LED off to clear all pixels */ + led_strip_clear(led_strip); + + /* Update LED state */ + led_state = false; +} + +void led_init(void) { + ESP_LOGI(TAG, "example configured to blink addressable led!"); + /* LED strip initialization with the GPIO and pixels number*/ + led_strip_config_t strip_config = { + .strip_gpio_num = CONFIG_BLINK_GPIO, + .max_leds = 1, // at least one LED on board + }; +#if CONFIG_BLINK_LED_STRIP_BACKEND_RMT + led_strip_rmt_config_t rmt_config = { + .resolution_hz = 10 * 1000 * 1000, // 10MHz + .flags.with_dma = false, + }; + ESP_ERROR_CHECK( + led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); +#elif CONFIG_BLINK_LED_STRIP_BACKEND_SPI + led_strip_spi_config_t spi_config = { + .spi_bus = SPI2_HOST, + .flags.with_dma = true, + }; + ESP_ERROR_CHECK( + led_strip_new_spi_device(&strip_config, &spi_config, &led_strip)); +#else +#error "unsupported LED strip backend" +#endif + /* Set all LED off to clear all pixels */ + led_off(); +} + +#elif CONFIG_BLINK_LED_GPIO + +void led_on(void) { gpio_set_level(CONFIG_BLINK_GPIO, true); } + +void led_off(void) { gpio_set_level(CONFIG_BLINK_GPIO, false); } + +void led_init(void) { + ESP_LOGI(TAG, "example configured to blink gpio led!"); + gpio_reset_pin(CONFIG_BLINK_GPIO); + /* Set the GPIO as a push/pull output */ + gpio_set_direction(CONFIG_BLINK_GPIO, GPIO_MODE_OUTPUT); +} + +#else +#error "unsupported LED type" +#endif diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults new file mode 100644 index 000000000000..551f506530b4 --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults @@ -0,0 +1,6 @@ +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=n + +CONFIG_BLINK_LED_GPIO=y +CONFIG_BLINK_GPIO=8 diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32 b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32 new file mode 100644 index 000000000000..263ec939b18d --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32 @@ -0,0 +1 @@ +CONFIG_BLINK_GPIO=5 diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32c3 b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32c3 new file mode 100644 index 000000000000..da044304532e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32c3 @@ -0,0 +1 @@ +CONFIG_BLINK_LED_STRIP=y diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32c6 b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32c6 new file mode 100644 index 000000000000..da044304532e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32c6 @@ -0,0 +1 @@ +CONFIG_BLINK_LED_STRIP=y diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32h2 b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32h2 new file mode 100644 index 000000000000..da044304532e --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32h2 @@ -0,0 +1 @@ +CONFIG_BLINK_LED_STRIP=y diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32s3 b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32s3 new file mode 100644 index 000000000000..5ac9d30b41fe --- /dev/null +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/sdkconfig.defaults.esp32s3 @@ -0,0 +1,2 @@ +CONFIG_BLINK_LED_STRIP=y +CONFIG_BLINK_GPIO=48 diff --git a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c index ecdce616cf6d..50e111e890e9 100644 --- a/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c +++ b/examples/bluetooth/bluedroid/ble/ble_compatibility_test/main/ble_compatibility_test.c @@ -70,22 +70,23 @@ static prepare_type_env_t prepare_write_env; //#define CONFIG_SET_RAW_ADV_DATA #ifdef CONFIG_SET_RAW_ADV_DATA static uint8_t raw_adv_data[] = { - /* flags */ - 0x02, 0x01, 0x06, - /* tx power*/ - 0x02, 0x0a, 0xeb, - /* service uuid */ - 0x03, 0x03, 0xFF, 0x00, - /* device name */ - 0x0E, 0x09, 'B', 'L', 'E', '_', 'C', 'O','M', 'P', '_', 'T','E', 'S', 'T' + /* Flags */ + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + /* TX Power */ + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xeb, + /* Service UUID */ + 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xFF, 0x00, + /* Device Name */ + 0x0E, ESP_BLE_AD_TYPE_NAME_CMPL, 'B', 'L', 'E', '_', 'C', 'O', 'M', 'P', '_', 'T', 'E', 'S', 'T' }; + static uint8_t raw_scan_rsp_data[] = { - /* flags */ - 0x02, 0x01, 0x06, - /* tx power */ - 0x02, 0x0a, 0xeb, - /* service uuid */ - 0x03, 0x03, 0xFF,0x00 + /* Flags */ + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + /* TX Power */ + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xeb, + /* Service UUID */ + 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xFF, 0x00 }; #else @@ -338,10 +339,8 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param } break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - EXAMPLE_DEBUG(EXAMPLE_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + EXAMPLE_DEBUG(EXAMPLE_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c b/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c index 08549979a7d1..a30fbb0216aa 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c @@ -247,7 +247,10 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par case ESP_GAP_SEARCH_INQ_RES_EVT: esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6); ESP_LOGI(GATTC_TAG, "Searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len); - adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + adv_name = esp_ble_resolve_adv_data_by_type(scan_result->scan_rst.ble_adv, + scan_result->scan_rst.adv_data_len + scan_result->scan_rst.scan_rsp_len, + ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); ESP_LOGI(GATTC_TAG, "Searched Device Name Len %d", adv_name_len); esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len); ESP_LOGI(GATTC_TAG, " "); diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c b/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c index db4906957976..af921b400897 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_spp_server/main/ble_spp_server_demo.c @@ -45,11 +45,11 @@ static const uint16_t spp_service_uuid = 0xABF0; static const uint8_t spp_adv_data[23] = { /* Flags */ - 0x02,0x01,0x06, + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, /* Complete List of 16-bit Service Class UUIDs */ - 0x03,0x03,0xF0,0xAB, + 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xF0, 0xAB, /* Complete Local Name in advertising */ - 0x0F,0x09, 'E', 'S', 'P', '_', 'S', 'P', 'P', '_', 'S', 'E', 'R','V', 'E', 'R' + 0x0F, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'S', 'P', 'P', '_', 'S', 'E', 'R', 'V', 'E', 'R' }; static uint16_t spp_mtu_size = 23; diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c index e7af08ef4341..859b431136a9 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_client/main/example_ble_client_throughput.c @@ -395,8 +395,10 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par case ESP_GAP_SEARCH_INQ_RES_EVT: esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6); ESP_LOGI(GATTC_TAG, "searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len); - adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, - ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + adv_name = esp_ble_resolve_adv_data_by_type(scan_result->scan_rst.ble_adv, + scan_result->scan_rst.adv_data_len + scan_result->scan_rst.scan_rsp_len, + ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); ESP_LOGI(GATTC_TAG, "searched Device Name Len %d", adv_name_len); esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len); ESP_LOGI(GATTC_TAG, " "); @@ -442,10 +444,8 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par ESP_LOGI(GATTC_TAG, "stop adv successfully"); break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(GATTC_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(GATTC_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c index 1fa6f1003cc2..12fa99b2323b 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/throughput_server/main/example_ble_server_throughput.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -98,12 +98,17 @@ static uint8_t adv_config_done = 0; #ifdef CONFIG_EXAMPLE_SET_RAW_ADV_DATA static uint8_t raw_adv_data[] = { - 0x02, 0x01, 0x06, - 0x02, 0x0a, 0xeb, 0x03, 0x03, 0xab, 0xcd + /* Flags */ + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + /* TX Power Level */ + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xEB, + /* Service UUID */ + 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xAB, 0xCD }; + static uint8_t raw_scan_rsp_data[] = { - 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44, - 0x45, 0x4d, 0x4f + /* Complete Local Name */ + 0x0F, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'G', 'A', 'T', 'T', 'S', '_', 'D', 'E', 'M', 'O' }; #else @@ -264,10 +269,8 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param } break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(GATTS_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(GATTS_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); diff --git a/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c b/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c index f8a6253c3f30..a97029b14b98 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c @@ -349,8 +349,10 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par case ESP_GAP_SEARCH_INQ_RES_EVT: esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6); ESP_LOGI(GATTC_TAG, "searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len); - adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, - ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + adv_name = esp_ble_resolve_adv_data_by_type(scan_result->scan_rst.ble_adv, + scan_result->scan_rst.adv_data_len + scan_result->scan_rst.scan_rsp_len, + ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); ESP_LOGI(GATTC_TAG, "searched Device Name Len %d", adv_name_len); esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len); @@ -402,10 +404,8 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par ESP_LOGI(GATTC_TAG, "stop adv successfully"); break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(GATTC_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(GATTC_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); diff --git a/examples/bluetooth/bluedroid/ble/gatt_client/tutorial/Gatt_Client_Example_Walkthrough.md b/examples/bluetooth/bluedroid/ble/gatt_client/tutorial/Gatt_Client_Example_Walkthrough.md index a503f4aee029..dff60a659767 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_client/tutorial/Gatt_Client_Example_Walkthrough.md +++ b/examples/bluetooth/bluedroid/ble/gatt_client/tutorial/Gatt_Client_Example_Walkthrough.md @@ -562,7 +562,7 @@ static esp_gatt_srvc_id_t remote_service_id = { }; ``` -Once defined, we can get the characteristics from that service using the `esp_ble_gattc_get_characteristic()` function, which is called in the `ESP_GATTC_SEARCH_CMPL_EVT` event after the search for services is completed and the client has found the service that it was looking for. +Once defined, we can get the characteristics from that service using the `esp_ble_gattc_get_char_by_uuid()` function, which is called in the `ESP_GATTC_SEARCH_CMPL_EVT` event after the search for services is completed and the client has found the service that it was looking for. ```c case ESP_GATTC_SEARCH_CMPL_EVT: diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c b/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c index f5e60c0939b2..f7b8971e371a 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c @@ -451,8 +451,10 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par case ESP_GAP_SEARCH_INQ_RES_EVT: esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6); ESP_LOGI(GATTC_TAG, "Searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len); - adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, - ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + adv_name = esp_ble_resolve_adv_data_by_type(scan_result->scan_rst.ble_adv, + scan_result->scan_rst.adv_data_len + scan_result->scan_rst.scan_rsp_len, + ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); ESP_LOGI(GATTC_TAG, "Searched Device Name Len %d", adv_name_len); esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len); ESP_LOGI(GATTC_TAG, " "); diff --git a/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c b/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c index fc808471e10e..6f191efdc33f 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_server/main/gatts_demo.c @@ -75,13 +75,17 @@ static uint8_t adv_config_done = 0; #ifdef CONFIG_SET_RAW_ADV_DATA static uint8_t raw_adv_data[] = { - 0x02, 0x01, 0x06, // Length 2, Data Type 1 (Flags), Data 1 (LE General Discoverable Mode, BR/EDR Not Supported) - 0x02, 0x0a, 0xeb, // Length 2, Data Type 10 (TX power level), Data 2 (-21) - 0x03, 0x03, 0xab, 0xcd, // Length 3, Data Type 3 (Complete 16-bit Service UUIDs), Data 3 (UUID) + /* Flags */ + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, // Length 2, Data Type ESP_BLE_AD_TYPE_FLAG, Data 1 (LE General Discoverable Mode, BR/EDR Not Supported) + /* TX Power Level */ + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xEB, // Length 2, Data Type ESP_BLE_AD_TYPE_TX_PWR, Data 2 (-21) + /* Complete 16-bit Service UUIDs */ + 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xAB, 0xCD // Length 3, Data Type ESP_BLE_AD_TYPE_16SRV_CMPL, Data 3 (UUID) }; -static uint8_t raw_scan_rsp_data[] = { // Length 15, Data Type 9 (Complete Local Name), Data 1 (ESP_GATTS_DEMO) - 0x0f, 0x09, 0x45, 0x53, 0x50, 0x5f, 0x47, 0x41, 0x54, 0x54, 0x53, 0x5f, 0x44, - 0x45, 0x4d, 0x4f + +static uint8_t raw_scan_rsp_data[] = { + /* Complete Local Name */ + 0x0F, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'G', 'A', 'T', 'T', 'S', '_', 'D', 'E', 'M', 'O' // Length 15, Data Type ESP_BLE_AD_TYPE_NAME_CMPL, Data (ESP_GATTS_DEMO) }; #else @@ -227,10 +231,8 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param } break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(GATTS_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(GATTS_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); diff --git a/examples/bluetooth/bluedroid/ble/gatt_server/tutorial/Gatt_Server_Example_Walkthrough.md b/examples/bluetooth/bluedroid/ble/gatt_server/tutorial/Gatt_Server_Example_Walkthrough.md index a709c1029cd7..cbfe677af350 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server/tutorial/Gatt_Server_Example_Walkthrough.md +++ b/examples/bluetooth/bluedroid/ble/gatt_server/tutorial/Gatt_Server_Example_Walkthrough.md @@ -649,11 +649,8 @@ The `esp_ble_gap_update_conn_params()` function triggers a GAP event `ESP_GAP_BL ```c case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(GATTS_TAG, "update connection params status = %d, min_int = %d, max_int = %d, - conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(GATTS_TAG, "update connection params status = %d, conn_int = %d,latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); diff --git a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c index 6826a07bda51..d432e58de7fa 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_server_service_table/main/gatts_table_creat_demo.c @@ -62,22 +62,24 @@ static prepare_type_env_t prepare_write_env; #define CONFIG_SET_RAW_ADV_DATA #ifdef CONFIG_SET_RAW_ADV_DATA static uint8_t raw_adv_data[] = { - /* flags */ - 0x02, 0x01, 0x06, - /* tx power*/ - 0x02, 0x0a, 0xeb, - /* service uuid */ - 0x03, 0x03, 0xFF, 0x00, - /* device name */ - 0x0f, 0x09, 'E', 'S', 'P', '_', 'G', 'A', 'T', 'T', 'S', '_', 'D','E', 'M', 'O' + /* Flags */ + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + /* TX Power Level */ + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xEB, + /* Complete 16-bit Service UUIDs */ + 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xFF, 0x00, + /* Complete Local Name */ + 0x0F, ESP_BLE_AD_TYPE_NAME_CMPL, + 'E', 'S', 'P', '_', 'G', 'A', 'T', 'T', 'S', '_', 'D', 'E', 'M', 'O' }; + static uint8_t raw_scan_rsp_data[] = { - /* flags */ - 0x02, 0x01, 0x06, - /* tx power */ - 0x02, 0x0a, 0xeb, - /* service uuid */ - 0x03, 0x03, 0xFF,0x00 + /* Flags */ + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, + /* TX Power Level */ + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xEB, + /* Complete 16-bit Service UUIDs */ + 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xFF, 0x00 }; #else @@ -265,10 +267,8 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param } break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(GATTS_TABLE_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(GATTS_TABLE_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); diff --git a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c index e09ca88cbbf3..5248bede6f5f 100644 --- a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c +++ b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c @@ -768,10 +768,8 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par uint8_t adv_name_len = 0; switch (event) { case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(GATTC_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(GATTC_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); @@ -796,8 +794,10 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par case ESP_GAP_SEARCH_INQ_RES_EVT: esp_log_buffer_hex(GATTC_TAG, scan_result->scan_rst.bda, 6); ESP_LOGI(GATTC_TAG, "Searched Adv Data Len %d, Scan Response Len %d", scan_result->scan_rst.adv_data_len, scan_result->scan_rst.scan_rsp_len); - adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, - ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + adv_name = esp_ble_resolve_adv_data_by_type(scan_result->scan_rst.ble_adv, + scan_result->scan_rst.adv_data_len + scan_result->scan_rst.scan_rsp_len, + ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); ESP_LOGI(GATTC_TAG, "Searched Device Name Len %d", adv_name_len); esp_log_buffer_char(GATTC_TAG, adv_name, adv_name_len); ESP_LOGI(GATTC_TAG, " "); diff --git a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/tutorial/Gatt_Client_Multi_Connection_Example_Walkthrough.md b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/tutorial/Gatt_Client_Multi_Connection_Example_Walkthrough.md index 17614d039162..d368b31ad1ac 100644 --- a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/tutorial/Gatt_Client_Multi_Connection_Example_Walkthrough.md +++ b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/tutorial/Gatt_Client_Multi_Connection_Example_Walkthrough.md @@ -180,42 +180,66 @@ case ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT: ``` If the service is found, an ``ESP_GATTC_SEARCH_RES_EVT`` event is triggered which allows to set the ``get_service_1 flag`` to true. This flag is used to print information and later get the characteristic that the client is interested in. -* Once the search for all services is completed, an ``ESP_GATTC_SEARCH_CMPL_EVT`` event is generated which is used to get the characteristics of the service just discovered. This is done with the ``esp_ble_gattc_get_characteristic()`` function: - +* After the search for all services is completed, an ESP_GATTC_SEARCH_CMPL_EVT event is triggered. This event can be utilized to obtain characteristics or other information. For example, you can retrieve a characteristic by UUID using the esp_ble_gattc_get_char_by_uuid() function: ```c - case ESP_GATTC_SEARCH_CMPL_EVT: + case ESP_GATTC_SEARCH_CMPL_EVT: if (p_data->search_cmpl.status != ESP_GATT_OK){ ESP_LOGE(GATTC_TAG, "search service failed, error status = %x", p_data->search_cmpl.status); break; } - if (get_service_1){ - esp_ble_gattc_get_characteristic(gattc_if, p_data->search_cmpl.conn_id, &remote_service_id, NULL); - } - break; - ``` - The ``esp_ble_gattc_get_characteristic()`` function takes the GATT interface, the connection ID and the remote service ID as parameters. In addition, a NULL value is passed to indicate that we want all the characteristics starting from the first one. If the client is interested in a specific characteristic it could pass the characteristic ID in this field to specify that. - An ``ESP_GATTC_GET_CHAR_EVT`` event is triggered when a characteristic is discovered. This event is used to print information about the characteristic. - -* If the characteristic ID is the same as the one defined by ``REMOTE_NOTIFY_CHAR_UUID``, the client registers for notifications on that characteristic value. -* Finally, the next characteristic is requested using the same ``esp_ble_gattc_get_characteristic()`` function, this time, the last parameter is set to the current characteristic. This triggers another ``ESP_GATTC_GET_CHAR_EVT`` and the process is repeated until all characteristics are obtained. + if (get_service_c){ + uint16_t count = 0; + esp_gatt_status_t status = esp_ble_gattc_get_attr_count( gattc_if, + p_data->search_cmpl.conn_id, + ESP_GATT_DB_CHARACTERISTIC, + gl_profile_tab[PROFILE_C_APP_ID].service_start_handle, + gl_profile_tab[PROFILE_C_APP_ID].service_end_handle, + INVALID_HANDLE, + &count); + if (status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_attr_count error"); + } - ```c - case ESP_GATTC_GET_CHAR_EVT: - if (p_data->get_char.status != ESP_GATT_OK) { - break; - } - ESP_LOGI(GATTC_TAG, "GET CHAR: conn_id = %x, status %d", p_data->get_char.conn_id, p_data->get_char.status); - ESP_LOGI(GATTC_TAG, "GET CHAR: srvc_id = %04x, char_id = %04x", p_data->get_char.srvc_id.id.uuid.uuid.uuid16, p_data->get_char.char_id.uuid.uuid.uuid16); + if (count > 0){ + char_elem_result_c = (esp_gattc_char_elem_t *)malloc(sizeof(esp_gattc_char_elem_t) * count); + if (!char_elem_result_c){ + ESP_LOGE(GATTC_TAG, "gattc no mem"); + break; + }else{ + status = esp_ble_gattc_get_char_by_uuid( gattc_if, + p_data->search_cmpl.conn_id, + gl_profile_tab[PROFILE_C_APP_ID].service_start_handle, + gl_profile_tab[PROFILE_C_APP_ID].service_end_handle, + remote_filter_char_uuid, + char_elem_result_c, + &count); + if (status != ESP_GATT_OK){ + ESP_LOGE(GATTC_TAG, "esp_ble_gattc_get_char_by_uuid error"); + free(char_elem_result_c); + char_elem_result_c = NULL; + break; + } - if (p_data->get_char.char_id.uuid.uuid.uuid16 == REMOTE_NOTIFY_CHAR_UUID) { - ESP_LOGI(GATTC_TAG, "register notify"); - esp_ble_gattc_register_for_notify(gattc_if, gl_profile_tab[PROFILE_A_APP_ID].remote_bda, &remote_service_id, &p_data->get_char.char_id); + /* Every service have only one char in our 'ESP_GATTS_DEMO' demo, so we used first 'char_elem_result' */ + if (count > 0 && (char_elem_result_c[0].properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY)){ + gl_profile_tab[PROFILE_C_APP_ID].char_handle = char_elem_result_c[0].char_handle; + esp_ble_gattc_register_for_notify (gattc_if, gl_profile_tab[PROFILE_C_APP_ID].remote_bda, char_elem_result_c[0].char_handle); + } + } + /* free char_elem_result */ + free(char_elem_result_c); + char_elem_result_c = NULL; + }else{ + ESP_LOGE(GATTC_TAG, "no char found"); + } } - - esp_ble_gattc_get_characteristic(gattc_if, p_data->get_char.conn_id, &remote_service_id, &p_data->get_char.char_id); break; ``` +* The API esp_ble_gattc_get_attr_count retrieves the number of attributes of a specified type based on esp_gatt_db_attr_type_t. + +* The API esp_ble_gattc_register_for_notify is used to register for notifications sent from the server and will trigger the ESP_GATTC_REG_FOR_NOTIFY_EVT event. + At this point the client has acquired all characteristics from the remote device and has subscribed for notifications on the characteristics of interest. Every time a client registers for notifications, an ``ESP_GATTC_REG_FOR_NOTIFY_EVT`` event is triggered. In this example, this event is set to write to the remote device Client Configuration Characteristic (CCC) using the ``esp_ble_gattc_write_char_descr()`` function. In turn, this function is used to write to characteristic descriptors. There are many characteristic descriptors defined by the Bluetooth specification, however, for this example, the descriptor of interest is the one that deals with enabling notifications, that is the Client Configuration descriptor. #### Connecting to the Next Remote Device diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/main/ble50_sec_gattc_demo.c b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/main/ble50_sec_gattc_demo.c index f4a66878a5ae..ad830cbb8d24 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_client/main/ble50_sec_gattc_demo.c +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_client/main/ble50_sec_gattc_demo.c @@ -430,7 +430,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par } case ESP_GAP_BLE_EXT_SCAN_START_COMPLETE_EVT: if (param->ext_scan_start.status != ESP_BT_STATUS_SUCCESS) { - ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x", param->scan_start_cmpl.status); + ESP_LOGE(GATTC_TAG, "scan start failed, error status = %x", param->ext_scan_start.status); break; } ESP_LOGI(GATTC_TAG, "Scan start success"); @@ -494,8 +494,10 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par } else { ESP_LOGI(GATTC_TAG, "extend adv, adv type 0x%x data len %d", param->ext_adv_report.params.event_type, param->ext_adv_report.params.adv_data_len); } - adv_name = esp_ble_resolve_adv_data(param->ext_adv_report.params.adv_data, - ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + adv_name = esp_ble_resolve_adv_data_by_type(param->ext_adv_report.params.adv_data, + param->ext_adv_report.params.adv_data_len, + ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); if (!connect && strlen(remote_device_name) == adv_name_len && strncmp((char *)adv_name, remote_device_name, adv_name_len) == 0) { connect = true; esp_ble_gap_stop_ext_scan(); diff --git a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c index 96b72098ae52..f3af7fb9f65e 100644 --- a/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c +++ b/examples/bluetooth/bluedroid/ble_50/ble50_security_server/main/ble50_sec_gatts_demo.c @@ -352,10 +352,8 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param esp_ble_gap_ext_adv_set_params(EXT_ADV_HANDLE, &ext_adv_params_2M); break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(GATTS_TABLE_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(GATTS_TABLE_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); diff --git a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/main/periodic_sync_demo.c b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/main/periodic_sync_demo.c index 3a7e56f5a1cc..070921564c6b 100644 --- a/examples/bluetooth/bluedroid/ble_50/peroidic_sync/main/periodic_sync_demo.c +++ b/examples/bluetooth/bluedroid/ble_50/peroidic_sync/main/periodic_sync_demo.c @@ -108,7 +108,10 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param case ESP_GAP_BLE_EXT_ADV_REPORT_EVT: { uint8_t *adv_name = NULL; uint8_t adv_name_len = 0; - adv_name = esp_ble_resolve_adv_data(param->ext_adv_report.params.adv_data, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + adv_name = esp_ble_resolve_adv_data_by_type(param->ext_adv_report.params.adv_data, + param->ext_adv_report.params.adv_data_len, + ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); if ((adv_name != NULL) && (memcmp(adv_name, "ESP_MULTI_ADV_80MS", adv_name_len) == 0) && !periodic_sync) { periodic_sync = true; char adv_temp_name[30] = {'0'}; diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/Kconfig.projbuild index 468ad311d6aa..7edc3ead9de0 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/Kconfig.projbuild @@ -48,4 +48,9 @@ menu "A2DP Example Configuration" help GPIO number to use for I2S Data Driver. + config EXAMPLE_LOCAL_DEVICE_NAME + string "Local Device Name" + default "ESP_SPEAKER" + help + Use this option to set local device name. endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c index 894f8862bb5a..81386dee8f2c 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c @@ -26,7 +26,7 @@ #include "esp_avrc_api.h" /* device name */ -#define LOCAL_DEVICE_NAME "ESP_SPEAKER" +static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; /* event for stack up */ enum { @@ -148,7 +148,7 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param) switch (event) { /* when do the stack up, this event comes */ case BT_APP_EVT_STACK_UP: { - esp_bt_gap_set_device_name(LOCAL_DEVICE_NAME); + esp_bt_gap_set_device_name(local_device_name); esp_bt_dev_register_callback(bt_app_dev_cb); esp_bt_gap_register_callback(bt_app_gap_cb); diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.ci.test new file mode 100644 index 000000000000..79e4f555d632 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_LOCAL_DEVICE_NAME="${CI_PIPELINE_ID}_A2DP_SINK" diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/Kconfig.projbuild index ece773895f38..47ea6308ee42 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/Kconfig.projbuild @@ -6,4 +6,10 @@ menu "A2DP Example Configuration" help This enables the Secure Simple Pairing. If disable this option, Bluedroid will only support Legacy Pairing + + config EXAMPLE_PEER_DEVICE_NAME + string "Target Device Name" + default "ESP_SPEAKER" + help + Use this option to set target device name to connect. endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c index 9bad03babffd..88866a57d558 100644 --- a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/main/main.c @@ -30,7 +30,6 @@ #define BT_RC_CT_TAG "RC_CT" /* device name */ -#define TARGET_DEVICE_NAME "ESP_SPEAKER" #define LOCAL_DEVICE_NAME "ESP_A2DP_SRC" /* AVRCP used transaction label */ @@ -112,6 +111,8 @@ static uint32_t s_pkt_cnt = 0; /* count of packet static esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap; /* AVRC target notification event capability bit mask */ static TimerHandle_t s_tmr; /* handle of heart beat timer */ +static const char remote_device_name[] = CONFIG_EXAMPLE_PEER_DEVICE_NAME; + /********************************* * STATIC FUNCTION DEFINITIONS ********************************/ @@ -199,7 +200,7 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param) /* search for target device in its Extended Inqury Response */ if (eir) { get_name_from_eir(eir, s_peer_bdname, NULL); - if (strcmp((char *)s_peer_bdname, TARGET_DEVICE_NAME) == 0) { + if (strcmp((char *)s_peer_bdname, remote_device_name) == 0) { ESP_LOGI(BT_AV_TAG, "Found a target device, address %s, name %s", bda_str, s_peer_bdname); s_a2d_state = APP_AV_STATE_DISCOVERED; memcpy(s_peer_bda, param->disc_res.bda, ESP_BD_ADDR_LEN); diff --git a/examples/bluetooth/bluedroid/classic_bt/a2dp_source/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/sdkconfig.ci.test new file mode 100644 index 000000000000..f1e20630cb81 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/a2dp_source/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_PEER_DEVICE_NAME="${CI_PIPELINE_ID}_A2DP_SINK" diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/pytest_classic_bt_discovery_test.py b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/pytest_classic_bt_discovery_test.py new file mode 100644 index 000000000000..d68b55be8c2d --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/pytest_classic_bt_discovery_test.py @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.generic +def test_bt_discovery(dut: Dut) -> None: + dut.expect_exact('Discovery started.') diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/Kconfig.projbuild index 568ef5ae62ff..d7db1931a0eb 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/Kconfig.projbuild @@ -6,4 +6,10 @@ menu "HID Example Configuration" help This enables the Secure Simple Pairing. If disable this option, Bluedroid will only support Legacy Pairing + + config EXAMPLE_LOCAL_DEVICE_NAME + string "Local Device Name" + default "HID Mouse Example" + help + Use this option to set local device name. endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/main.c index 0d4ca2cf2d1d..6cafc1c0ba54 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/main/main.c @@ -23,6 +23,8 @@ #define REPORT_PROTOCOL_MOUSE_REPORT_SIZE (4) #define REPORT_BUFFER_SIZE REPORT_PROTOCOL_MOUSE_REPORT_SIZE +static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; + typedef struct { esp_hidd_app_param_t app_param; esp_hidd_qos_param_t both_qos; @@ -434,11 +436,12 @@ void app_main(void) } ESP_LOGI(TAG, "setting device name"); - esp_bt_gap_set_device_name("HID Mouse Example"); + esp_bt_gap_set_device_name(local_device_name); ESP_LOGI(TAG, "setting cod major, peripheral"); - esp_bt_cod_t cod; + esp_bt_cod_t cod = {0}; cod.major = ESP_BT_COD_MAJOR_DEV_PERIPHERAL; + cod.minor = ESP_BT_COD_MINOR_PERIPHERAL_POINTING; esp_bt_gap_set_cod(cod, ESP_BT_SET_COD_MAJOR_MINOR); vTaskDelay(2000 / portTICK_PERIOD_MS); @@ -449,7 +452,7 @@ void app_main(void) s_local_param.app_param.name = "Mouse"; s_local_param.app_param.description = "Mouse Example"; s_local_param.app_param.provider = "ESP32"; - s_local_param.app_param.subclass = ESP_HID_CLASS_MIC; + s_local_param.app_param.subclass = ESP_HID_CLASS_MIC; // keep same with minor class of COD s_local_param.app_param.desc_list = hid_mouse_descriptor; s_local_param.app_param.desc_list_len = hid_mouse_descriptor_len; diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/sdkconfig.ci.test new file mode 100644 index 000000000000..f6353b4b369e --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_hid_mouse_device/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_LOCAL_DEVICE_NAME="${CI_PIPELINE_ID}_HID_MOUSE_DEVICE" diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/Kconfig.projbuild index abc0e748ce04..a1b665ef2621 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/Kconfig.projbuild @@ -6,4 +6,10 @@ menu "L2CAP Example Configuration" help This enables the Secure Simple Pairing. If disable this option, Bluedroid will only support Legacy Pairing + + config EXAMPLE_PEER_DEVICE_NAME + string "Target Device Name" + default "ESP_BT_L2CAP_SERVER" + help + Use this option to set target device name to connect. endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c index 4048fd129d47..37fda38a6107 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -30,12 +30,12 @@ #define L2CAP_TAG "L2CAP_TAG" #define SDP_TAG "SDP_TAG" #define EXAMPLE_DEVICE_NAME "ESP_BT_L2CAP_CLIENT" -#define TARGET_DEVICE_NAME "ESP_BT_L2CAP_SERVER" #define L2CAP_DATA_LEN 100 #define BT_L2CAP_DYNMIC_PSM 0x1001 #define BT_UNUSED_RFCOMM -1 #define BT_UNKONWN_PROFILE_VERSION 0x0102 +static const char remote_device_name[] = CONFIG_EXAMPLE_PEER_DEVICE_NAME; static esp_bt_l2cap_cntl_flags_t sec_mask = ESP_BT_L2CAP_SEC_AUTHENTICATE; static char *sdp_service_name = "Unknown_profile"; static const uint8_t UUID_UNKNOWN[] = {0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x00, @@ -125,7 +125,7 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param) /* search for target device in its Extended Inqury Response */ if (eir) { get_name_from_eir(eir, peer_bdname, NULL); - if (strcmp((char *)peer_bdname, TARGET_DEVICE_NAME) == 0) { + if (strcmp((char *)peer_bdname, remote_device_name) == 0) { ESP_LOGI(L2CAP_TAG, "Found a target device, address %s, name %s", bda_str, peer_bdname); ESP_LOGI(L2CAP_TAG, "Cancel device discovery ..."); esp_bt_gap_cancel_discovery(); diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/sdkconfig.ci.test new file mode 100644 index 000000000000..a21a8b5e76db --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_client/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_PEER_DEVICE_NAME="${CI_PIPELINE_ID}_L2CAP_SERVER" diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/Kconfig.projbuild index abc0e748ce04..14824fe72a83 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/Kconfig.projbuild @@ -6,4 +6,10 @@ menu "L2CAP Example Configuration" help This enables the Secure Simple Pairing. If disable this option, Bluedroid will only support Legacy Pairing + + config EXAMPLE_LOCAL_DEVICE_NAME + string "Local Device Name" + default "ESP_BT_L2CAP_SERVER" + help + Use this option to set local device name. endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c index bcfeea5fae1a..0bc87df06dc1 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -29,12 +29,12 @@ #define L2CAP_TAG "L2CAP_TAG" #define SDP_TAG "SDP_TAG" -#define EXAMPLE_DEVICE_NAME "ESP_BT_L2CAP_SERVER" #define L2CAP_DATA_LEN 100 #define BT_UNUSED_RFCOMM -1 #define BT_L2CAP_DYNMIC_PSM 0x1001 #define BT_UNKONWN_PROFILE_VERSION 0x0102 +static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; static esp_bt_l2cap_cntl_flags_t sec_mask = ESP_BT_L2CAP_SEC_AUTHENTICATE; static char *sdp_service_name = "Unknown_profile"; static const uint8_t UUID_UNKNOWN[] = {0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x00, @@ -270,7 +270,7 @@ static void esp_hdl_sdp_cb_evt(uint16_t event, void *p_param) case ESP_SDP_CREATE_RECORD_COMP_EVT: ESP_LOGI(SDP_TAG, "ESP_SDP_CREATE_RECORD_COMP_EVT: status:%d", sdp_param->create_record.status); if (sdp_param->create_record.status == ESP_SDP_SUCCESS) { - esp_bt_gap_set_device_name(EXAMPLE_DEVICE_NAME); + esp_bt_gap_set_device_name(local_device_name); esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); } break; diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/sdkconfig.ci.test new file mode 100644 index 000000000000..205de36eb83a --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_l2cap_server/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_LOCAL_DEVICE_NAME="${CI_PIPELINE_ID}_L2CAP_SERVER" diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/Kconfig.projbuild index 971b124cfc5e..71d6c4a0ee90 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/Kconfig.projbuild @@ -6,4 +6,10 @@ menu "SPP Example Configuration" help This enables the Secure Simple Pairing. If disable this option, Bluedroid will only support Legacy Pairing + + config EXAMPLE_LOCAL_DEVICE_NAME + string "Local Device Name" + default "ESP_SPP_ACCEPTOR" + help + Use this option to set local device name. endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/main.c index 688db21cd58b..d57a144130e5 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -25,11 +25,11 @@ #define SPP_TAG "SPP_ACCEPTOR_DEMO" #define SPP_SERVER_NAME "SPP_SERVER" -#define EXAMPLE_DEVICE_NAME "ESP_SPP_ACCEPTOR" #define SPP_SHOW_DATA 0 #define SPP_SHOW_SPEED 1 #define SPP_SHOW_MODE SPP_SHOW_SPEED /*Choose show mode: show data or speed*/ +static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB; static const bool esp_spp_enable_l2cap_ertm = true; @@ -90,7 +90,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) if (param->start.status == ESP_SPP_SUCCESS) { ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT handle:%"PRIu32" sec_id:%d scn:%d", param->start.handle, param->start.sec_id, param->start.scn); - esp_bt_gap_set_device_name(EXAMPLE_DEVICE_NAME); + esp_bt_gap_set_device_name(local_device_name); esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); } else { ESP_LOGE(SPP_TAG, "ESP_SPP_START_EVT status:%d", param->start.status); diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.ci.test new file mode 100644 index 000000000000..1d9783ea6744 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_LOCAL_DEVICE_NAME="${CI_PIPELINE_ID}_SPP_ACCEPTOR" diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/Kconfig.projbuild index 971b124cfc5e..b942d94d38f2 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/Kconfig.projbuild @@ -6,4 +6,10 @@ menu "SPP Example Configuration" help This enables the Secure Simple Pairing. If disable this option, Bluedroid will only support Legacy Pairing + + config EXAMPLE_PEER_DEVICE_NAME + string "Target Device Name" + default "ESP_SPP_ACCEPTOR" + help + Use this option to set target device name to connect. endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/main.c index df95ba91edbe..f24debc65a06 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/main/main.c @@ -43,7 +43,8 @@ static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER; esp_bd_addr_t peer_bd_addr = {0}; static uint8_t peer_bdname_len; static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; -static const char remote_device_name[] = "ESP_SPP_ACCEPTOR"; +static const char remote_device_name[] = CONFIG_EXAMPLE_PEER_DEVICE_NAME; + static const esp_bt_inq_mode_t inq_mode = ESP_BT_INQ_MODE_GENERAL_INQUIRY; static const uint8_t inq_len = 30; static const uint8_t inq_num_rsps = 0; diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.ci.test new file mode 100644 index 000000000000..35448fa7159f --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_PEER_DEVICE_NAME="${CI_PIPELINE_ID}_SPP_ACCEPTOR" diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/Kconfig.projbuild index 971b124cfc5e..71d6c4a0ee90 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/Kconfig.projbuild @@ -6,4 +6,10 @@ menu "SPP Example Configuration" help This enables the Secure Simple Pairing. If disable this option, Bluedroid will only support Legacy Pairing + + config EXAMPLE_LOCAL_DEVICE_NAME + string "Local Device Name" + default "ESP_SPP_ACCEPTOR" + help + Use this option to set local device name. endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/main.c index 2230fc021474..5c13be3f1158 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -37,8 +37,8 @@ #define SPP_TAG "SPP_ACCEPTOR_DEMO" #define SPP_SERVER_NAME "SPP_SERVER" -#define EXAMPLE_DEVICE_NAME "ESP_SPP_ACCEPTOR" +static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_AUTHENTICATE; static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE; @@ -121,7 +121,7 @@ static void esp_spp_cb(uint16_t e, void *p) if (param->start.status == ESP_SPP_SUCCESS) { ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT handle:%"PRIu32" sec_id:%d scn:%d", param->start.handle, param->start.sec_id, param->start.scn); - esp_bt_gap_set_device_name(EXAMPLE_DEVICE_NAME); + esp_bt_gap_set_device_name(local_device_name); esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); } else { ESP_LOGE(SPP_TAG, "ESP_SPP_START_EVT status:%d", param->start.status); diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.ci.test new file mode 100644 index 000000000000..ff404573a0b5 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_LOCAL_DEVICE_NAME="${CI_PIPELINE_ID}_SPP_VFS_ACCEPTOR" diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/Kconfig.projbuild index 971b124cfc5e..b942d94d38f2 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/Kconfig.projbuild @@ -6,4 +6,10 @@ menu "SPP Example Configuration" help This enables the Secure Simple Pairing. If disable this option, Bluedroid will only support Legacy Pairing + + config EXAMPLE_PEER_DEVICE_NAME + string "Target Device Name" + default "ESP_SPP_ACCEPTOR" + help + Use this option to set target device name to connect. endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/main.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/main.c index 8f811110c614..00958705b68e 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/main.c @@ -44,7 +44,8 @@ static const esp_spp_role_t role_master = ESP_SPP_ROLE_MASTER; static esp_bd_addr_t peer_bd_addr; static uint8_t peer_bdname_len; static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; -static const char remote_device_name[] = "ESP_SPP_ACCEPTOR"; +static const char remote_device_name[] = CONFIG_EXAMPLE_PEER_DEVICE_NAME; + static const esp_bt_inq_mode_t inq_mode = ESP_BT_INQ_MODE_GENERAL_INQUIRY; static const uint8_t inq_len = 30; static const uint8_t inq_num_rsps = 0; diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.ci.test b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.ci.test new file mode 100644 index 000000000000..41775e0f2090 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_PEER_DEVICE_NAME="${CI_PIPELINE_ID}_SPP_VFS_ACCEPTOR" diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/Kconfig.projbuild new file mode 100644 index 000000000000..5d40e1962d50 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/Kconfig.projbuild @@ -0,0 +1,7 @@ +menu "HFP Example Configuration" + config EXAMPLE_LOCAL_DEVICE_NAME + string "Local Device Name" + default "ESP_HFP_AG" + help + Use this option to set local device name. +endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c index c93aac3da220..0e30854b20a4 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/main/main.c @@ -27,6 +27,8 @@ #define BT_HF_AG_TAG "HF_AG_DEMO_MAIN" +static const char local_device_name[] = CONFIG_EXAMPLE_LOCAL_DEVICE_NAME; + /* event for handler "hf_ag_hdl_stack_up */ enum { BT_APP_EVT_STACK_UP = 0, @@ -52,9 +54,7 @@ static void bt_hf_hdl_stack_evt(uint16_t event, void *p_param) { case BT_APP_EVT_STACK_UP: { - /* set up device name */ - char *dev_name = "ESP_HFP_AG"; - esp_bt_gap_set_device_name(dev_name); + esp_bt_gap_set_device_name(local_device_name); esp_hf_ag_register_callback(bt_app_hf_cb); diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_ag/sdkconfig.ci.all b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/sdkconfig.ci.all new file mode 100644 index 000000000000..1d7593af051f --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_ag/sdkconfig.ci.all @@ -0,0 +1,2 @@ +CONFIG_BT_HFP_AUDIO_DATA_PATH_HCI=y +CONFIG_EXAMPLE_LOCAL_DEVICE_NAME="${CI_PIPELINE_ID}_HFP" diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/Kconfig.projbuild index 0b1569390fd9..65e04f08e64b 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/Kconfig.projbuild +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/Kconfig.projbuild @@ -6,4 +6,10 @@ menu "HFP Example Configuration" help This enables the Secure Simple Pairing. If disable this option, Bluedroid will only support Legacy Pairing + + config EXAMPLE_PEER_DEVICE_NAME + string "Target Device Name" + default "ESP_HFP_AG" + help + Use this option to set target device name to connect. endmenu diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c index cdf47d7b2f9d..362879a30f19 100644 --- a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/main/main.c @@ -29,8 +29,7 @@ esp_bd_addr_t peer_addr = {0}; static char peer_bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; static uint8_t peer_bdname_len; - -static const char remote_device_name[] = "ESP_HFP_AG"; +static const char remote_device_name[] = CONFIG_EXAMPLE_PEER_DEVICE_NAME; static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) { diff --git a/examples/bluetooth/bluedroid/classic_bt/hfp_hf/sdkconfig.ci.all b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/sdkconfig.ci.all new file mode 100644 index 000000000000..94fafd42eaf5 --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/hfp_hf/sdkconfig.ci.all @@ -0,0 +1,2 @@ +CONFIG_BT_HFP_AUDIO_DATA_PATH_HCI=y +CONFIG_EXAMPLE_PEER_DEVICE_NAME="${CI_PIPELINE_ID}_HFP" diff --git a/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py b/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py new file mode 100644 index 000000000000..07e1e27f316b --- /dev/null +++ b/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py @@ -0,0 +1,158 @@ +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import os.path +from typing import Tuple + +import pexpect +import pytest +from pytest_embedded_idf.dut import IdfDut + + +# Case 1: SPP +@pytest.mark.esp32 +@pytest.mark.wifi_two_dut +@pytest.mark.parametrize( + 'count, app_path, target, erase_all, config', [ + (2, + f'{os.path.join(os.path.dirname(__file__), "bt_spp_acceptor")}|{os.path.join(os.path.dirname(__file__), "bt_spp_initiator")}', + 'esp32|esp32', 'y', 'test'), + ], + indirect=True, +) +def test_bt_spp_only(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: + acceptor = dut[0] + initiator = dut[1] + + acceptor.expect_exact('ESP_SPP_INIT_EVT', timeout=30) + acceptor.expect_exact('ESP_SPP_START_EVT', timeout=30) + initiator.expect_exact('ESP_SPP_INIT_EVT', timeout=30) + initiator.expect_exact('ESP_SPP_DISCOVERY_COMP_EVT', timeout=30) + initiator_output = initiator.expect(pexpect.TIMEOUT, timeout=5) + + if 'ESP_BT_GAP_KEY_REQ_EVT Please enter passkey!' in str(initiator_output): + passkey = acceptor.expect(r'ESP_BT_GAP_KEY_NOTIF_EVT passkey:(\d+)').group(1).decode('utf8') + initiator.write(f'spp key {passkey};') + acceptor.expect_exact('authentication success', timeout=30) + initiator.expect_exact('authentication success', timeout=30) + acceptor.expect_exact('ESP_SPP_SRV_OPEN_EVT status:0', timeout=30) + initiator.expect_exact('ESP_SPP_OPEN_EVT', timeout=30) + + +# Case 2: SPP_VFS +@pytest.mark.esp32 +@pytest.mark.wifi_two_dut +@pytest.mark.parametrize( + 'count, app_path, target, config', [ + (2, + f'{os.path.join(os.path.dirname(__file__), "bt_spp_vfs_acceptor")}|{os.path.join(os.path.dirname(__file__), "bt_spp_vfs_initiator")}', + 'esp32|esp32', 'test'), + ], + indirect=True, +) +def test_bt_spp_vfs(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: + acceptor = dut[0] + initiator = dut[1] + + acceptor.expect_exact('ESP_SPP_INIT_EVT', timeout=30) + acceptor.expect_exact('ESP_SPP_VFS_REGISTER_EVT', timeout=30) + acceptor.expect_exact('ESP_SPP_START_EVT', timeout=30) + initiator.expect_exact('ESP_SPP_INIT_EVT', timeout=30) + initiator.expect_exact('ESP_SPP_VFS_REGISTER_EVT', timeout=30) + initiator.expect_exact('ESP_SPP_DISCOVERY_COMP_EVT', timeout=30) + initiator.expect_exact('ESP_SPP_OPEN_EVT', timeout=30) + acceptor.expect_exact('ESP_SPP_SRV_OPEN_EVT status:0', timeout=30) + + +# Case 3: A2DP +@pytest.mark.esp32 +@pytest.mark.wifi_two_dut +@pytest.mark.parametrize( + 'count, app_path, target, config', [ + (2, + f'{os.path.join(os.path.dirname(__file__), "a2dp_sink")}|{os.path.join(os.path.dirname(__file__), "a2dp_source")}', + 'esp32|esp32', 'test'), + ], + indirect=True, +) +def test_bt_a2dp(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: + sink_dut = dut[0] + source_dut = dut[1] + source_dut_mac = source_dut.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + sink_dut.expect_exact('A2DP PROF STATE: Init Complete', timeout=30) + source_dut.expect_exact('a2dp connecting to peer', timeout=30) + source_dut.expect_exact('a2dp connected', timeout=30) + source_dut.expect_exact('a2dp media start successfully', timeout=30) + sink_dut.expect_exact(f'A2DP connection state: Connected, [{source_dut_mac}]', timeout=30) + sink_dut.expect_exact('start volume change simulation', timeout=30) + + +# Case 4: HFP +@pytest.mark.esp32 +@pytest.mark.wifi_two_dut +@pytest.mark.parametrize( + 'count, app_path, target, config', [ + (2, + f'{os.path.join(os.path.dirname(__file__), "hfp_ag")}|{os.path.join(os.path.dirname(__file__), "hfp_hf")}', + 'esp32|esp32', 'all'), + ], + indirect=True, +) +def test_bt_hfp(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: + hfp_ag = dut[0] + hfp_hf = dut[1] + + hfp_hf.expect_exact('Found a target device name', timeout=30) + hfp_hf.expect_exact('connection state connected', timeout=30) + hfp_hf.expect_exact('connection state slc_connected', timeout=30) + hfp_ag.expect_exact('connection state CONNECTED', timeout=30) + hfp_ag.expect_exact('connection state SLC_CONNECTED', timeout=30) + + +# # Case 5: HID +@pytest.mark.esp32 +@pytest.mark.wifi_two_dut +@pytest.mark.parametrize( + 'count, app_path, target, config', [ + (2, + f'{os.path.join(os.path.dirname(__file__), "bt_hid_mouse_device")}|' + f'{os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")), "esp_hid_host")}', + 'esp32|esp32', 'test'), + ], + indirect=True, +) +def test_bt_hid(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: + hid_device = dut[0] + hid_host = dut[1] + + hid_host_mac = hid_host.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + hid_device_mac = hid_device.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + + hid_device.expect_exact('setting hid parameters', timeout=30) + hid_device.expect_exact('setting to connectable, discoverable', timeout=30) + hid_device.expect_exact(f'connected to {hid_host_mac}', timeout=30) + hid_device.expect_exact('making self non-discoverable and non-connectable', timeout=30) + hid_host.expect_exact(f'ESP_HIDH_DEMO: {hid_device_mac} OPEN', timeout=30) + + +# Case 6: L2CAP +@pytest.mark.esp32 +@pytest.mark.wifi_two_dut +@pytest.mark.parametrize( + 'count, app_path, target, config', [ + (2, + f'{os.path.join(os.path.dirname(__file__), "bt_l2cap_server")}|{os.path.join(os.path.dirname(__file__), "bt_l2cap_client")}', + 'esp32|esp32', 'test'), + ], + indirect=True, +) +def test_bt_l2cap(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: + server = dut[0] + 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) + 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) + server.expect_exact('ESP_BT_L2CAP_OPEN_EVT: status:0', timeout=30) diff --git a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c index 95efcce1081e..63a5b7d197ea 100644 --- a/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/main/main.c @@ -181,10 +181,8 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param } break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(BT_BLE_COEX_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(BT_BLE_COEX_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); diff --git a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/Kconfig.projbuild new file mode 100644 index 000000000000..912aedf7ea3f --- /dev/null +++ b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/Kconfig.projbuild @@ -0,0 +1,14 @@ +menu "Example 'GATTC_GATTS_COEX' Config" + + config SET_RAW_ADV_DATA + bool "Use raw data for advertising packets and scan response data" + help + If this config item is set, raw binary data will be used to generate advertising & scan response data. + This option uses the esp_ble_gap_config_adv_data_raw() and esp_ble_gap_config_scan_rsp_data_raw() + functions. + + If this config item is unset, advertising & scan response data is provided via a higher-level + esp_ble_adv_data_t structure. The lower layer will generate the BLE packets. This option has higher + overhead at runtime. + +endmenu diff --git a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c index 3d3bbda61100..08d1be99a72d 100644 --- a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c +++ b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c @@ -117,6 +117,22 @@ esp_attr_value_t gatts_demo_char1_val = { .attr_value = char1_str, }; +#ifdef CONFIG_SET_RAW_ADV_DATA +static uint8_t raw_adv_data[] = { + /* Flags */ + 0x02, ESP_BLE_AD_TYPE_FLAG, 0x06, // Length 2, Data Type ESP_BLE_AD_TYPE_FLAG, Data 1 (LE General Discoverable Mode, BR/EDR Not Supported) + /* TX Power Level */ + 0x02, ESP_BLE_AD_TYPE_TX_PWR, 0xEB, // Length 2, Data Type ESP_BLE_AD_TYPE_TX_PWR, Data 2 (-21) + /* Complete 16-bit Service UUIDs */ + 0x03, ESP_BLE_AD_TYPE_16SRV_CMPL, 0xAB, 0xCD // Length 3, Data Type ESP_BLE_AD_TYPE_16SRV_CMPL, Data 3 (UUID) +}; + +static uint8_t raw_scan_rsp_data[] = { + /* Complete Local Name */ + 0x0F, ESP_BLE_AD_TYPE_NAME_CMPL, 'E', 'S', 'P', '_', 'G', 'A', 'T', 'T', 'S', '_', 'D', 'E', 'M', 'O' // Length 15, Data Type ESP_BLE_AD_TYPE_NAME_CMPL, Data (ESP_GATTS_DEMO) +}; + +#else static uint8_t service_uuid128[32] = { /* LSB <--------------------------------------------------------------------------------> MSB */ //first uuid, 16bit, [12],[13] is the value @@ -157,6 +173,7 @@ static esp_ble_adv_data_t scan_rsp_data = { .p_service_uuid = NULL, .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), }; +#endif /* CONFIG_SET_RAW_ADV_DATA */ static esp_ble_adv_params_t adv_params = { .adv_int_min = 0x20, @@ -246,10 +263,8 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param } break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(COEX_TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(COEX_TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); @@ -279,8 +294,10 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param esp_ble_gap_cb_param_t *scan_result = (esp_ble_gap_cb_param_t *)param; switch (scan_result->scan_rst.search_evt) { case ESP_GAP_SEARCH_INQ_RES_EVT: - adv_name = esp_ble_resolve_adv_data(scan_result->scan_rst.ble_adv, - ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + adv_name = esp_ble_resolve_adv_data_by_type(scan_result->scan_rst.ble_adv, + scan_result->scan_rst.adv_data_len + scan_result->scan_rst.scan_rsp_len, + ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); if (adv_name != NULL) { if (strlen(remote_device_name) == adv_name_len && strncmp((char *)adv_name, remote_device_name, adv_name_len) == 0) { if (connect == false) { diff --git a/examples/bluetooth/blufi/README.md b/examples/bluetooth/blufi/README.md index 91c2ffde0b6a..49be5e30f8de 100644 --- a/examples/bluetooth/blufi/README.md +++ b/examples/bluetooth/blufi/README.md @@ -20,7 +20,7 @@ To test this demo, you need to prepare a mobile phone with blufi application ins Blufi is completely open source, here is the download link: * [Blufi source code](https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/blufi) -* [BluFi protocol](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/blufi.html?highlight=blufi#the-frame-formats-defined-in-blufi) +* [BluFi protocol](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/ble/blufi.html) * [iOS source code](https://github.com/EspressifApp/EspBlufiForiOS) * [Android source code](https://github.com/EspressifApp/EspBlufi) * [Bluetooth Network User Guide CN](https://www.espressif.com/sites/default/files/documentation/esp32_bluetooth_networking_user_guide_cn.pdf) @@ -50,7 +50,7 @@ I (708) system_api: read default base MAC address from EFUSE I (718) wifi:wifi firmware version: 44799ff I (718) wifi:wifi certification version: v7.0 I (718) wifi:config NVS flash: enabled -I (718) wifi:config nano formating: disabled +I (718) wifi:config nano formatting: disabled I (728) wifi:Init data frame dynamic rx buffer num: 32 I (728) wifi:Init management frame dynamic rx buffer num: 32 I (738) wifi:Init management short buffer num: 32 diff --git a/examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c b/examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c index d3574bb5e591..b44e2e259bbb 100644 --- a/examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c +++ b/examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c @@ -903,8 +903,9 @@ void app_main(void) ESP_LOGI(TAG, "setting device name"); esp_bt_gap_set_device_name(bt_hid_config.device_name); ESP_LOGI(TAG, "setting cod major, peripheral"); - esp_bt_cod_t cod; + esp_bt_cod_t cod = {0}; cod.major = ESP_BT_COD_MAJOR_DEV_PERIPHERAL; + cod.minor = ESP_BT_COD_MINOR_PERIPHERAL_POINTING; esp_bt_gap_set_cod(cod, ESP_BT_SET_COD_MAJOR_MINOR); vTaskDelay(1000 / portTICK_PERIOD_MS); ESP_LOGI(TAG, "setting bt device"); diff --git a/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c b/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c index 68010a9e3ece..b0998ebb88c4 100644 --- a/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c +++ b/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c @@ -358,22 +358,34 @@ static void handle_ble_device_result(struct ble_scan_result_evt_param *scan_rst) char name[64] = {0}; uint8_t uuid_len = 0; - uint8_t *uuid_d = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_16SRV_CMPL, &uuid_len); + uint8_t *uuid_d = esp_ble_resolve_adv_data_by_type(scan_rst->ble_adv, + scan_rst->adv_data_len + scan_rst->scan_rsp_len, + ESP_BLE_AD_TYPE_16SRV_CMPL, + &uuid_len); if (uuid_d != NULL && uuid_len) { uuid = uuid_d[0] + (uuid_d[1] << 8); } uint8_t appearance_len = 0; - uint8_t *appearance_d = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_APPEARANCE, &appearance_len); + uint8_t *appearance_d = esp_ble_resolve_adv_data_by_type(scan_rst->ble_adv, + scan_rst->adv_data_len + scan_rst->scan_rsp_len, + ESP_BLE_AD_TYPE_APPEARANCE, + &appearance_len); if (appearance_d != NULL && appearance_len) { appearance = appearance_d[0] + (appearance_d[1] << 8); } uint8_t adv_name_len = 0; - uint8_t *adv_name = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + uint8_t *adv_name = esp_ble_resolve_adv_data_by_type(scan_rst->ble_adv, + scan_rst->adv_data_len + scan_rst->scan_rsp_len, + ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); if (adv_name == NULL) { - adv_name = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_NAME_SHORT, &adv_name_len); + adv_name = esp_ble_resolve_adv_data_by_type(scan_rst->ble_adv, + scan_rst->adv_data_len + scan_rst->scan_rsp_len, + ESP_BLE_AD_TYPE_NAME_SHORT, + &adv_name_len); } if (adv_name != NULL && adv_name_len) { diff --git a/examples/bluetooth/esp_hid_host/main/Kconfig.projbuild b/examples/bluetooth/esp_hid_host/main/Kconfig.projbuild index 5b0fa17ed027..c72314895ff7 100644 --- a/examples/bluetooth/esp_hid_host/main/Kconfig.projbuild +++ b/examples/bluetooth/esp_hid_host/main/Kconfig.projbuild @@ -14,4 +14,10 @@ menu "HID Example Configuration" select BT_NIMBLE_HID_SERVICE help This enables Nimble HID Host + + config EXAMPLE_PEER_DEVICE_NAME + string "Target Device Name" + default "HID Mouse Example" + help + Use this option to set target device name to connect. endmenu diff --git a/examples/bluetooth/esp_hid_host/main/esp_hid_gap.c b/examples/bluetooth/esp_hid_host/main/esp_hid_gap.c index ee2225fc5de5..d7c1719a553c 100644 --- a/examples/bluetooth/esp_hid_host/main/esp_hid_gap.c +++ b/examples/bluetooth/esp_hid_host/main/esp_hid_gap.c @@ -341,38 +341,39 @@ static void handle_bt_device_result(struct disc_res_param *disc_res) uint8_t len = 0; uint8_t *data = 0; - data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_16BITS_UUID, &len); - if (data == NULL) { - data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_16BITS_UUID, &len); - } - if (data && len == ESP_UUID_LEN_16) { - uuid.len = ESP_UUID_LEN_16; - uuid.uuid.uuid16 = data[0] + (data[1] << 8); - GAP_DBG_PRINTF(", "); print_uuid(&uuid); - continue; - } + do { + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_16BITS_UUID, &len); + if (data == NULL) { + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_16BITS_UUID, &len); + } + if (data && len == ESP_UUID_LEN_16) { + uuid.len = ESP_UUID_LEN_16; + uuid.uuid.uuid16 = data[0] + (data[1] << 8); + GAP_DBG_PRINTF(", "); print_uuid(&uuid); + break; + } - data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_32BITS_UUID, &len); - if (data == NULL) { - data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_32BITS_UUID, &len); - } - if (data && len == ESP_UUID_LEN_32) { - uuid.len = len; - memcpy(&uuid.uuid.uuid32, data, sizeof(uint32_t)); - GAP_DBG_PRINTF(", "); print_uuid(&uuid); - continue; - } + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_32BITS_UUID, &len); + if (data == NULL) { + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_32BITS_UUID, &len); + } + if (data && len == ESP_UUID_LEN_32) { + uuid.len = len; + memcpy(&uuid.uuid.uuid32, data, sizeof(uint32_t)); + GAP_DBG_PRINTF(", "); print_uuid(&uuid); + break; + } - data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_128BITS_UUID, &len); - if (data == NULL) { - data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_128BITS_UUID, &len); - } - if (data && len == ESP_UUID_LEN_128) { - uuid.len = len; - memcpy(uuid.uuid.uuid128, (uint8_t *)data, len); - GAP_DBG_PRINTF(", "); print_uuid(&uuid); - continue; - } + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_CMPL_128BITS_UUID, &len); + if (data == NULL) { + data = esp_bt_gap_resolve_eir_data((uint8_t *)prop->val, ESP_BT_EIR_TYPE_INCMPL_128BITS_UUID, &len); + } + if (data && len == ESP_UUID_LEN_128) { + uuid.len = len; + memcpy(uuid.uuid.uuid128, (uint8_t *)data, len); + GAP_DBG_PRINTF(", "); print_uuid(&uuid); + } + } while (0); //try to find a name if (name == NULL) { @@ -408,22 +409,34 @@ static void handle_ble_device_result(struct ble_scan_result_evt_param *scan_rst) char name[64] = {0}; uint8_t uuid_len = 0; - uint8_t *uuid_d = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_16SRV_CMPL, &uuid_len); + uint8_t *uuid_d = esp_ble_resolve_adv_data_by_type(scan_rst->ble_adv, + scan_rst->adv_data_len + scan_rst->scan_rsp_len, + ESP_BLE_AD_TYPE_16SRV_CMPL, + &uuid_len); if (uuid_d != NULL && uuid_len) { uuid = uuid_d[0] + (uuid_d[1] << 8); } uint8_t appearance_len = 0; - uint8_t *appearance_d = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_APPEARANCE, &appearance_len); + uint8_t *appearance_d = esp_ble_resolve_adv_data_by_type(scan_rst->ble_adv, + scan_rst->adv_data_len + scan_rst->scan_rsp_len, + ESP_BLE_AD_TYPE_APPEARANCE, + &appearance_len); if (appearance_d != NULL && appearance_len) { appearance = appearance_d[0] + (appearance_d[1] << 8); } uint8_t adv_name_len = 0; - uint8_t *adv_name = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_NAME_CMPL, &adv_name_len); + uint8_t *adv_name = esp_ble_resolve_adv_data_by_type(scan_rst->ble_adv, + scan_rst->adv_data_len + scan_rst->scan_rsp_len, + ESP_BLE_AD_TYPE_NAME_CMPL, + &adv_name_len); if (adv_name == NULL) { - adv_name = esp_ble_resolve_adv_data(scan_rst->ble_adv, ESP_BLE_AD_TYPE_NAME_SHORT, &adv_name_len); + adv_name = esp_ble_resolve_adv_data_by_type(scan_rst->ble_adv, + scan_rst->adv_data_len + scan_rst->scan_rsp_len, + ESP_BLE_AD_TYPE_NAME_SHORT, + &adv_name_len); } if (adv_name != NULL && adv_name_len) { diff --git a/examples/bluetooth/esp_hid_host/main/esp_hid_host_main.c b/examples/bluetooth/esp_hid_host/main/esp_hid_host_main.c index 1643b8a33ea8..681d86e1d087 100644 --- a/examples/bluetooth/esp_hid_host/main/esp_hid_host_main.c +++ b/examples/bluetooth/esp_hid_host/main/esp_hid_host_main.c @@ -51,6 +51,10 @@ static const char *TAG = "ESP_HIDH_DEMO"; +#if CONFIG_BT_HID_HOST_ENABLED +static const char * remote_device_name = CONFIG_EXAMPLE_PEER_DEVICE_NAME; +#endif // CONFIG_BT_HID_HOST_ENABLED + static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) { if (bda == NULL || str == NULL || size < 18) { @@ -148,16 +152,26 @@ void hid_demo_task(void *pvParameters) printf("] srv 0x%03x, ", r->bt.cod.service); print_uuid(&r->bt.uuid); printf(", "); + if (strncmp(r->name, remote_device_name, strlen(remote_device_name)) == 0) { + break; + } } #endif /* CONFIG_BT_HID_HOST_ENABLED */ printf("NAME: %s ", r->name ? r->name : ""); printf("\n"); r = r->next; } + +#if CONFIG_BT_HID_HOST_ENABLED + if (cr && strncmp(cr->name, remote_device_name, strlen(remote_device_name)) == 0) { + esp_hidh_dev_open(cr->bda, cr->transport, cr->ble.addr_type); + } +#else if (cr) { //open the last result esp_hidh_dev_open(cr->bda, cr->transport, cr->ble.addr_type); } +#endif // CONFIG_BT_HID_HOST_ENABLED //free the results esp_hid_scan_results_free(results); } diff --git a/examples/bluetooth/esp_hid_host/sdkconfig.ci.test b/examples/bluetooth/esp_hid_host/sdkconfig.ci.test new file mode 100644 index 000000000000..97b876adffd5 --- /dev/null +++ b/examples/bluetooth/esp_hid_host/sdkconfig.ci.test @@ -0,0 +1 @@ +CONFIG_EXAMPLE_PEER_DEVICE_NAME="${CI_PIPELINE_ID}_HID_MOUSE_DEVICE" diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c b/examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c index fd235c4dfeb7..41bc0899c67b 100644 --- a/examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -303,12 +303,14 @@ ble_cts_cent_connect_if_interesting(void *disc) } #endif +#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN)) /* Scanning must be stopped before a connection can be initiated. */ rc = ble_gap_disc_cancel(); if (rc != 0) { MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); return; } +#endif /* Figure out address to use for connect (no privacy for now) */ rc = ble_hs_id_infer_auto(0, &own_addr_type); @@ -364,14 +366,14 @@ ble_cts_cent_gap_event(struct ble_gap_event *event, void *arg) return 0; } - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ print_adv_fields(&fields); /* Try to connect to the advertiser if it looks interesting. */ ble_cts_cent_connect_if_interesting(&event->disc); return 0; - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { /* Connection successfully established. */ @@ -482,7 +484,7 @@ ble_cts_cent_gap_event(struct ble_gap_event *event, void *arg) #if CONFIG_EXAMPLE_EXTENDED_ADV case BLE_GAP_EVENT_EXT_DISC: - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ ext_print_adv_report(&event->disc); ble_cts_cent_connect_if_interesting(&event->disc); diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c b/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c index 53bb6897bc6a..53f81200ce94 100644 --- a/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c @@ -178,7 +178,7 @@ static int ble_cts_prph_gap_event(struct ble_gap_event *event, void *arg) { switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed */ MODLOG_DFLT(INFO, "connection %s; status=%d\n", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/ble_dynamic_service/main/main.c b/examples/bluetooth/nimble/ble_dynamic_service/main/main.c index b7c915e0695c..d4a736569889 100644 --- a/examples/bluetooth/nimble/ble_dynamic_service/main/main.c +++ b/examples/bluetooth/nimble/ble_dynamic_service/main/main.c @@ -136,7 +136,7 @@ dynamic_service_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ MODLOG_DFLT(INFO, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_cent/main/main.c b/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_cent/main/main.c index 5388a4f49686..127c41231203 100644 --- a/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_cent/main/main.c +++ b/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_cent/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -358,12 +358,14 @@ enc_adv_data_cent_connect_if_interesting(void *disc) return; } +#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN)) /* Scanning must be stopped before a connection can be initiated. */ rc = ble_gap_disc_cancel(); if (rc != 0) { MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); return; } +#endif /* Figure out address to use for connect (no privacy for now) */ rc = ble_hs_id_infer_auto(0, &own_addr_type); @@ -416,14 +418,14 @@ enc_adv_data_cent_gap_event(struct ble_gap_event *event, void *arg) return 0; } - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ print_adv_fields(&fields); /* Try to connect to the advertiser if it looks interesting. */ enc_adv_data_cent_connect_if_interesting(&event->disc); return 0; - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { /* Connection successfully established. */ @@ -514,7 +516,7 @@ enc_adv_data_cent_gap_event(struct ble_gap_event *event, void *arg) return 0; case BLE_GAP_EVENT_EXT_DISC: - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ ext_print_adv_report(&event->disc); enc_adv_data_cent_connect_if_interesting(&event->disc); diff --git a/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/main/main.c b/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/main/main.c index 4e7320a1e0f7..caf2b83cfacb 100644 --- a/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/main/main.c @@ -204,7 +204,7 @@ enc_adv_data_prph_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ MODLOG_DFLT(INFO, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/ble_htp/htp_cent/main/main.c b/examples/bluetooth/nimble/ble_htp/htp_cent/main/main.c index 181990700dc0..798455f230a2 100644 --- a/examples/bluetooth/nimble/ble_htp/htp_cent/main/main.c +++ b/examples/bluetooth/nimble/ble_htp/htp_cent/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -189,7 +189,7 @@ ble_htp_cent_on_read(uint16_t conn_handle, /** * Performs three GATT operations against the specified peer: - * 1. Reads the HTP temparature type characteristic. + * 1. Reads the HTP temperature type characteristic. * 2. After read is completed, writes the HTP temperature measurement interval characteristic. * 3. After write is completed, subscribes to notifications for the HTP intermediate temperature * and temperature measurement characteristic. @@ -205,12 +205,12 @@ ble_htp_cent_read_write_subscribe(const struct peer *peer) const struct peer_chr *chr; int rc; - /* Read the Temparature Type characteristic. */ + /* Read the Temperature Type characteristic. */ chr = peer_chr_find_uuid(peer, BLE_UUID16_DECLARE(BLE_SVC_HTP_UUID16), BLE_UUID16_DECLARE(BLE_SVC_HTP_CHR_UUID16_TEMP_TYPE)); if (chr == NULL) { - MODLOG_DFLT(ERROR, "Error: Peer doesn't support the Temparature Type" + MODLOG_DFLT(ERROR, "Error: Peer doesn't support the Temperature Type" " characteristic\n"); goto err; } @@ -418,12 +418,14 @@ ble_htp_cent_connect_if_interesting(void *disc) } #endif +#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN)) /* Scanning must be stopped before a connection can be initiated. */ rc = ble_gap_disc_cancel(); if (rc != 0) { MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); return; } +#endif /* Figure out address to use for connect (no privacy for now) */ rc = ble_hs_id_infer_auto(0, &own_addr_type); @@ -479,14 +481,14 @@ ble_htp_cent_gap_event(struct ble_gap_event *event, void *arg) return 0; } - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ print_adv_fields(&fields); /* Try to connect to the advertiser if it looks interesting. */ ble_htp_cent_connect_if_interesting(&event->disc); return 0; - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { /* Connection successfully established. */ @@ -613,7 +615,7 @@ ble_htp_cent_gap_event(struct ble_gap_event *event, void *arg) #if CONFIG_EXAMPLE_EXTENDED_ADV case BLE_GAP_EVENT_EXT_DISC: - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ ext_print_adv_report(&event->disc); ble_htp_cent_connect_if_interesting(&event->disc); diff --git a/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c b/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c index 0da9cb939247..df4e8f28d9e6 100644 --- a/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c @@ -230,7 +230,7 @@ static int ble_htp_prph_gap_event(struct ble_gap_event *event, void *arg) { switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed */ MODLOG_DFLT(INFO, "connection %s; status=%d\n", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/main.c b/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/main.c index 6e5f7abe0e22..5b5cba142294 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/main.c +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_blecent/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -77,7 +77,7 @@ blecent_l2cap_coc_send_data(struct ble_l2cap_chan *chan) } /** - * After connetion is established on GAP layer, service discovery is performed. On + * After connection is established on GAP layer, service discovery is performed. On * it's completion, this API is called for making a connection is on L2CAP layer. */ static void @@ -340,12 +340,14 @@ blecent_connect_if_interesting(void *disc) } #endif +#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN)) /* Scanning must be stopped before a connection can be initiated. */ rc = ble_gap_disc_cancel(); if (rc != 0) { MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); return; } +#endif /* Figure out address to use for connect (no privacy for now) */ rc = ble_hs_id_infer_auto(0, &own_addr_type); @@ -403,14 +405,14 @@ blecent_gap_event(struct ble_gap_event *event, void *arg) return 0; } - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ print_adv_fields(&fields); /* Try to connect to the advertiser if it looks interesting. */ blecent_connect_if_interesting(&event->disc); return 0; - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { /* Connection successfully established. */ @@ -470,7 +472,7 @@ blecent_gap_event(struct ble_gap_event *event, void *arg) #if CONFIG_EXAMPLE_EXTENDED_ADV case BLE_GAP_EVENT_EXT_DISC: - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ ext_print_adv_report(&event->disc); blecent_connect_if_interesting(&event->disc); diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c index 96a0bdff9e07..6432c67c6c27 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c @@ -315,7 +315,7 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ MODLOG_DFLT(INFO, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/ble_multi_adv/main/main.c b/examples/bluetooth/nimble/ble_multi_adv/main/main.c index 482a96a1bebd..b1d00f0d8aa6 100644 --- a/examples/bluetooth/nimble/ble_multi_adv/main/main.c +++ b/examples/bluetooth/nimble/ble_multi_adv/main/main.c @@ -302,7 +302,7 @@ ble_multi_advertise(ble_addr_t addr) static void ble_multi_perform_gatt_proc(ble_addr_t addr) { - /* GATT procedures like notify, indicate can be perfomed now */ + /* GATT procedures like notify, indicate can be performed now */ for (int i = 0; i < BLE_ADV_INSTANCES; i++) { if (memcmp(&addr, &ble_instance_cb[i].addr, sizeof(addr)) == 0) { if (ble_instance_cb[i].cb) { @@ -335,7 +335,7 @@ ble_multi_adv_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ MODLOG_DFLT(INFO, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/main/main.c b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/main/main.c index e0fdf4c520dc..eb7bf718e7c7 100644 --- a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/main/main.c +++ b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_cent/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -85,7 +85,7 @@ ble_cent_client_gap_event(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_EXT_DISC: rc = ble_hs_adv_parse_fields(&fields, event->ext_disc.data, event->ext_disc.length_data); - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ if ((rc == 0) && fields.name && (fields.name_len >= strlen(BLE_PEER_NAME)) && !strncmp((const char *)fields.name, BLE_PEER_NAME, strlen(BLE_PEER_NAME))) { ble_cent_connect(&event->ext_disc); @@ -93,7 +93,7 @@ ble_cent_client_gap_event(struct ble_gap_event *event, void *arg) return 0; - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: if (event->connect.status == 0) { ESP_LOGI(TAG, "Connection established. Handle:%d, Total:%d", event->connect.conn_handle, ++s_ble_multi_conn_num); @@ -174,7 +174,7 @@ static int ble_cent_server_gap_event(struct ble_gap_event *event, void *arg) { switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* The connectable adv has been established. We will act as the peripheral. */ if (event->connect.status == 0) { ESP_LOGI(TAG, "Peripheral connected to central. Handle:%d", event->connect.conn_handle); @@ -319,12 +319,14 @@ ble_cent_connect(void *disc) return; } +#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN)) /* Scanning must be stopped before a connection can be initiated. */ rc = ble_gap_disc_cancel(); if (rc != 0) { ESP_LOGE(TAG, "Failed to cancel scan; rc=%d\n", rc); return; } +#endif /* We won't connect to the same device. Change our static random address to simulate * multi-connection with only one central and one peripheral. diff --git a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c index e067f618ff42..5067899880c7 100644 --- a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -163,7 +163,7 @@ ble_prph_restart_adv(void) { #if CONFIG_EXAMPLE_RESTART_ADV_AFTER_CONNECTED if (!xSemaphoreGive(s_sem_restart_adv)) { - ESP_LOGE(TAG, "Failed to give Semaphor"); + ESP_LOGE(TAG, "Failed to give Semaphore"); } #else ble_prph_advertise(); @@ -189,7 +189,7 @@ static int ble_prph_gap_event(struct ble_gap_event *event, void *arg) { switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: if (event->connect.status == 0) { /* A new connection was established. */ ESP_LOGI(TAG, "Connection established. Handle:%d. Total:%d", event->connect.conn_handle, @@ -316,7 +316,7 @@ app_main(void) vTaskDelay(pdMS_TO_TICKS(delay_ms)); ble_prph_advertise(); } else { - ESP_LOGE(TAG, "Failed to take Semaphor"); + ESP_LOGE(TAG, "Failed to take Semaphore"); } } #endif // CONFIG_EXAMPLE_RESTART_ADV_AFTER_CONNECTED diff --git a/examples/bluetooth/nimble/ble_phy/phy_cent/main/main.c b/examples/bluetooth/nimble/ble_phy/phy_cent/main/main.c index dcd434abc6b1..772c0d25bfde 100644 --- a/examples/bluetooth/nimble/ble_phy/phy_cent/main/main.c +++ b/examples/bluetooth/nimble/ble_phy/phy_cent/main/main.c @@ -288,12 +288,14 @@ blecent_connect_if_interesting(void *disc) return; } +#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN)) /* Scanning must be stopped before a connection can be initiated. */ rc = ble_gap_disc_cancel(); if (rc != 0) { MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); return; } +#endif /* Figure out address to use for connect (no privacy for now) */ rc = ble_hs_id_infer_auto(0, &own_addr_type); @@ -345,7 +347,7 @@ blecent_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { /* Connection successfully established. */ @@ -438,7 +440,7 @@ blecent_gap_event(struct ble_gap_event *event, void *arg) return 0; case BLE_GAP_EVENT_EXT_DISC: - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ ext_print_adv_report(&event->disc); blecent_connect_if_interesting(&event->disc); diff --git a/examples/bluetooth/nimble/ble_phy/phy_prph/main/main.c b/examples/bluetooth/nimble/ble_phy/phy_prph/main/main.c index 4a616f922621..f1308fd708e7 100644 --- a/examples/bluetooth/nimble/ble_phy/phy_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_phy/phy_prph/main/main.c @@ -183,7 +183,7 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ MODLOG_DFLT(INFO, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_cent/main/main.c b/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_cent/main/main.c index 643cccb7c01c..b57c17bb7469 100644 --- a/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_cent/main/main.c +++ b/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_cent/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,7 +25,7 @@ static struct ble_prox_cent_link_lost_peer disconn_peer[MYNEWT_VAL(BLE_MAX_CONNE /* Note: Path loss is calculated using formula : threshold - RSSI value * by default threshold is kept -128 as per the spec * high_threshold and low_threshold are hardcoded after testing and noting - * RSSI values when distance betweeen devices are less and more. + * RSSI values when distance between devices are less and more. */ static int8_t high_threshold = -70; static int8_t low_threshold = -100; @@ -335,12 +335,14 @@ ble_prox_cent_connect_if_interesting(void *disc) } #endif +#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN)) /* Scanning must be stopped before a connection can be initiated. */ rc = ble_gap_disc_cancel(); if (rc != 0) { MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); return; } +#endif /* Figure out address to use for connect (no privacy for now) */ rc = ble_hs_id_infer_auto(0, &own_addr_type); @@ -396,14 +398,14 @@ ble_prox_cent_gap_event(struct ble_gap_event *event, void *arg) return 0; } - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ print_adv_fields(&fields); /* Try to connect to the advertiser if it looks interesting. */ ble_prox_cent_connect_if_interesting(&event->disc); return 0; - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { /* Connection successfully established. */ @@ -561,7 +563,7 @@ ble_prox_cent_gap_event(struct ble_gap_event *event, void *arg) #if CONFIG_EXAMPLE_EXTENDED_ADV case BLE_GAP_EVENT_EXT_DISC: - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ ext_print_adv_report(&event->disc); ble_prox_cent_connect_if_interesting(&event->disc); diff --git a/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/main.c b/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/main.c index 835d636213cc..47634029c332 100644 --- a/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -177,18 +177,20 @@ static int ble_prox_prph_gap_event(struct ble_gap_event *event, void *arg) { switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed */ MODLOG_DFLT(INFO, "connection %s; status=%d\n", event->connect.status == 0 ? "established" : "failed", event->connect.status); - /* resume advertising */ + if (event->connect.status != 0) { + /* Connection failed, resume advertising */ #if CONFIG_EXAMPLE_EXTENDED_ADV - ext_ble_prox_prph_advertise(); + ext_ble_prox_prph_advertise(); #else - ble_prox_prph_advertise(); + ble_prox_prph_advertise(); #endif + } break; case BLE_GAP_EVENT_DISCONNECT: diff --git a/examples/bluetooth/nimble/ble_spp/spp_client/main/main.c b/examples/bluetooth/nimble/ble_spp/spp_client/main/main.c index 51a16165624f..0e84d533b9f1 100644 --- a/examples/bluetooth/nimble/ble_spp/spp_client/main/main.c +++ b/examples/bluetooth/nimble/ble_spp/spp_client/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -164,12 +164,14 @@ ble_spp_client_connect_if_interesting(const struct ble_gap_disc_desc *disc) return; } +#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN)) /* Scanning must be stopped before a connection can be initiated. */ rc = ble_gap_disc_cancel(); if (rc != 0) { MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); return; } +#endif /* Figure out address to use for connect (no privacy for now) */ rc = ble_hs_id_infer_auto(0, &own_addr_type); @@ -221,14 +223,14 @@ ble_spp_client_gap_event(struct ble_gap_event *event, void *arg) return 0; } - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ print_adv_fields(&fields); /* Try to connect to the advertiser if it looks interesting. */ ble_spp_client_connect_if_interesting(&event->disc); return 0; - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { /* Connection successfully established. */ @@ -347,7 +349,7 @@ void ble_client_uart_task(void *pvParameters) //Waiting for UART event. if (xQueueReceive(spp_common_uart_queue, (void * )&event, (TickType_t)portMAX_DELAY)) { switch (event.type) { - //Event of UART receving data + //Event of UART receiving data case UART_DATA: if (event.size) { diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c b/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c index 0be28e157423..f2569d230182 100644 --- a/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c @@ -141,7 +141,7 @@ ble_spp_server_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ MODLOG_DFLT(INFO, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/blecent/main/main.c b/examples/bluetooth/nimble/blecent/main/main.c index ef62105893e4..724384e4b8fc 100644 --- a/examples/bluetooth/nimble/blecent/main/main.c +++ b/examples/bluetooth/nimble/blecent/main/main.c @@ -48,7 +48,7 @@ #endif #endif -/*** The UUID of the service containing the subscribable characterstic ***/ +/*** The UUID of the service containing the subscribable characteristic ***/ static const ble_uuid_t * remote_svc_uuid = BLE_UUID128_DECLARE(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59); @@ -203,7 +203,7 @@ blecent_custom_gatt_operations(const struct peer* peer) remote_chr_uuid, BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16)); if (dsc == NULL) { - MODLOG_DFLT(ERROR, "Error: Peer lacks a CCCD for the subscribable characterstic\n"); + MODLOG_DFLT(ERROR, "Error: Peer lacks a CCCD for the subscribable characteristic\n"); goto err; } @@ -601,12 +601,14 @@ blecent_connect_if_interesting(void *disc) } #endif +#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN)) /* Scanning must be stopped before a connection can be initiated. */ rc = ble_gap_disc_cancel(); if (rc != 0) { MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); return; } +#endif /* Figure out address to use for connect (no privacy for now) */ rc = ble_hs_id_infer_auto(0, &own_addr_type); @@ -687,14 +689,14 @@ blecent_gap_event(struct ble_gap_event *event, void *arg) return 0; } - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ print_adv_fields(&fields); /* Try to connect to the advertiser if it looks interesting. */ blecent_connect_if_interesting(&event->disc); return 0; - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { /* Connection successfully established. */ @@ -840,7 +842,7 @@ blecent_gap_event(struct ble_gap_event *event, void *arg) #if CONFIG_EXAMPLE_EXTENDED_ADV case BLE_GAP_EVENT_EXT_DISC: - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ ext_print_adv_report(&event->disc); blecent_connect_if_interesting(&event->disc); diff --git a/examples/bluetooth/nimble/blecsc/main/main.c b/examples/bluetooth/nimble/blecsc/main/main.c index 3b69a930dc17..4e159c922c76 100644 --- a/examples/bluetooth/nimble/blecsc/main/main.c +++ b/examples/bluetooth/nimble/blecsc/main/main.c @@ -213,7 +213,7 @@ static int blecsc_gap_event(struct ble_gap_event *event, void *arg) { switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed */ MODLOG_DFLT(INFO, "connection %s; status=%d\n", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/blehr/main/main.c b/examples/bluetooth/nimble/blehr/main/main.c index b9c7ea991f91..9c9a917334a9 100644 --- a/examples/bluetooth/nimble/blehr/main/main.c +++ b/examples/bluetooth/nimble/blehr/main/main.c @@ -184,7 +184,7 @@ static int blehr_gap_event(struct ble_gap_event *event, void *arg) { switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed */ MODLOG_DFLT(INFO, "connection %s; status=%d\n", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/bleprph/main/main.c b/examples/bluetooth/nimble/bleprph/main/main.c index d86364c41ce0..73d77eecc28c 100644 --- a/examples/bluetooth/nimble/bleprph/main/main.c +++ b/examples/bluetooth/nimble/bleprph/main/main.c @@ -235,7 +235,7 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ MODLOG_DFLT(INFO, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/bleprph_host_only/main/main.c b/examples/bluetooth/nimble/bleprph_host_only/main/main.c index e34b0683fcf6..43a4d14bfffc 100644 --- a/examples/bluetooth/nimble/bleprph_host_only/main/main.c +++ b/examples/bluetooth/nimble/bleprph_host_only/main/main.c @@ -223,7 +223,7 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ MODLOG_DFLT(INFO, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c b/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c index c4eac37c50ca..670bc983b0cd 100644 --- a/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c +++ b/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c @@ -119,7 +119,7 @@ void wifi_init_sta(void) .ssid = EXAMPLE_ESP_WIFI_SSID, .password = EXAMPLE_ESP_WIFI_PASS, /* Setting a password implies station will connect to all security modes including WEP/WPA. - * However these modes are deprecated and not advisable to be used. Incase your Access point + * However these modes are deprecated and not advisable to be used. In case your Access point * doesn't support WPA2, these mode can be enabled by commenting below line */ .threshold.authmode = WIFI_AUTH_WPA2_PSK, }, @@ -389,7 +389,7 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ ESP_LOGI(TAG, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/power_save/main/main.c b/examples/bluetooth/nimble/power_save/main/main.c index 3e1a5acc28a0..cfb2222c8813 100644 --- a/examples/bluetooth/nimble/power_save/main/main.c +++ b/examples/bluetooth/nimble/power_save/main/main.c @@ -282,7 +282,7 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ MODLOG_DFLT(INFO, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/main.c b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/main.c index cf54d96fb869..c1087307e5c2 100644 --- a/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/main.c +++ b/examples/bluetooth/nimble/throughput_app/blecent_throughput/main/main.c @@ -471,12 +471,14 @@ blecent_connect_if_interesting(const struct ble_gap_disc_desc *disc) return; } +#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN)) /* Scanning must be stopped before a connection can be initiated. */ rc = ble_gap_disc_cancel(); if (rc != 0) { MODLOG_DFLT(DEBUG, "Failed to cancel scan; rc=%d\n", rc); return; } +#endif /* Figure out address to use for connect (no privacy for now) */ rc = ble_hs_id_infer_auto(0, &own_addr_type); @@ -529,14 +531,14 @@ blecent_gap_event(struct ble_gap_event *event, void *arg) return 0; } - /* An advertisment report was received during GAP discovery. */ + /* An advertisement report was received during GAP discovery. */ print_adv_fields(&fields); /* Try to connect to the advertiser if it looks interesting. */ blecent_connect_if_interesting(&event->disc); return 0; - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed. */ if (event->connect.status == 0) { /* Connection successfully established. */ diff --git a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c index 50638b04cf45..0a66ea0b6055 100644 --- a/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c +++ b/examples/bluetooth/nimble/throughput_app/bleprph_throughput/main/main.c @@ -239,7 +239,7 @@ gatts_gap_event(struct ble_gap_event *event, void *arg) int rc; switch (event->type) { - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_LINK_ESTAB: /* A new connection was established or a connection attempt failed */ ESP_LOGI(tag, "connection %s; status = %d ", event->connect.status == 0 ? "established" : "failed", diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild index 1b450b923624..800f136a09c9 100644 --- a/examples/common_components/protocol_examples_common/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -236,7 +236,7 @@ menu "Example Connection Configuration" int "SMI MDIO GPIO number" range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX default 18 if IDF_TARGET_ESP32 - default 27 if IDF_TARGET_ESP32P4 + default 52 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SMI MDIO. endif @@ -295,7 +295,7 @@ menu "Example Connection Configuration" config EXAMPLE_ETH_PHY_RST_GPIO int "PHY Reset GPIO number" range -1 ENV_GPIO_OUT_RANGE_MAX - default 26 if IDF_TARGET_ESP32P4 + default 51 if IDF_TARGET_ESP32P4 default 5 help Set the GPIO number used to reset PHY chip. diff --git a/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild b/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild index f2b2fadfede0..8722181eec62 100644 --- a/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild +++ b/examples/ethernet/basic/components/ethernet_init/Kconfig.projbuild @@ -52,7 +52,7 @@ menu "Example Ethernet Configuration" bool "KSZ80xx" help With the KSZ80xx series, Microchip offers single-chip 10BASE-T/100BASE-TX - Ethernet Physical Layer Tranceivers (PHY). + Ethernet Physical Layer Transceivers (PHY). The following chips are supported: KSZ8001, KSZ8021, KSZ8031, KSZ8041, KSZ8051, KSZ8061, KSZ8081, KSZ8091 Goto https://www.microchip.com for more information about them. @@ -70,7 +70,7 @@ menu "Example Ethernet Configuration" int "SMI MDIO GPIO number" range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX default 18 if IDF_TARGET_ESP32 - default 27 if IDF_TARGET_ESP32P4 + default 52 if IDF_TARGET_ESP32P4 help Set the GPIO number used by SMI MDIO. @@ -78,7 +78,7 @@ menu "Example Ethernet Configuration" int "PHY Reset GPIO number" range -1 ENV_GPIO_OUT_RANGE_MAX default 5 if IDF_TARGET_ESP32 - default 26 if IDF_TARGET_ESP32P4 + default 51 if IDF_TARGET_ESP32P4 help Set the GPIO number used to reset PHY chip. Set to -1 to disable PHY chip hardware reset. diff --git a/examples/mesh/ip_internal_network/main/Kconfig.projbuild b/examples/mesh/ip_internal_network/main/Kconfig.projbuild index 28708ae7879f..89de1393e67b 100644 --- a/examples/mesh/ip_internal_network/main/Kconfig.projbuild +++ b/examples/mesh/ip_internal_network/main/Kconfig.projbuild @@ -64,6 +64,12 @@ menu "Example Configuration" help The number of non-mesh stations allowed to connect in. + config MESH_IE_ENCRYPTED + bool "Mesh IE encrypted" + default y + help + The mesh IE is encrypted by default. + config MESH_MAX_LAYER int "Mesh Max Layer" range 1 25 diff --git a/examples/mesh/ip_internal_network/main/mesh_main.c b/examples/mesh/ip_internal_network/main/mesh_main.c index d2870fbf790b..216574209467 100644 --- a/examples/mesh/ip_internal_network/main/mesh_main.c +++ b/examples/mesh/ip_internal_network/main/mesh_main.c @@ -405,7 +405,12 @@ void app_main(void) ESP_ERROR_CHECK(esp_mesh_set_max_layer(CONFIG_MESH_MAX_LAYER)); ESP_ERROR_CHECK(esp_mesh_set_vote_percentage(1)); ESP_ERROR_CHECK(esp_mesh_set_ap_assoc_expire(10)); + /* set blocking time of esp_mesh_send() to 30s, to prevent the esp_mesh_send() from permanently for some reason */ + ESP_ERROR_CHECK(esp_mesh_send_block_time(30000)); mesh_cfg_t cfg = MESH_INIT_CONFIG_DEFAULT(); +#if !MESH_IE_ENCRYPTED + cfg.crypto_funcs = NULL; +#endif /* mesh ID */ memcpy((uint8_t *) &cfg.mesh_id, MESH_ID, 6); /* router */ diff --git a/examples/mesh/ip_internal_network/main/mesh_netif.c b/examples/mesh/ip_internal_network/main/mesh_netif.c index 7a2bd71dadaf..28d73cbfbbbf 100644 --- a/examples/mesh/ip_internal_network/main/mesh_netif.c +++ b/examples/mesh/ip_internal_network/main/mesh_netif.c @@ -66,7 +66,6 @@ static esp_err_t set_dhcps_dns(esp_netif_t *netif, uint32_t addr) dns.ip.u_addr.ip4.addr = addr; dns.ip.type = IPADDR_TYPE_V4; dhcps_offer_t dhcps_dns_value = OFFER_DNS; - ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_stop(netif)); ESP_ERROR_CHECK(esp_netif_dhcps_option(netif, ESP_NETIF_OP_SET, ESP_NETIF_DOMAIN_NAME_SERVER, &dhcps_dns_value, sizeof(dhcps_dns_value))); ESP_ERROR_CHECK(esp_netif_set_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns)); ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_start(netif)); @@ -350,6 +349,20 @@ static esp_netif_t* create_mesh_link_ap(void) return netif; } +/** + * @brief Destroy esp-netif for AP interface over mesh + */ +static void destory_mesh_link_ap(void) +{ + if (netif_ap) { + ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_stop(netif_ap)); + esp_netif_action_disconnected(netif_ap, NULL, 0, NULL); + mesh_delete_if_driver(esp_netif_get_io_driver(netif_ap)); + esp_netif_destroy(netif_ap); + netif_ap = NULL; + } +} + /** * @brief Creates esp-netif for station interface over mesh * @@ -376,12 +389,7 @@ static esp_netif_t* create_mesh_link_sta(void) esp_err_t mesh_netif_start_root_ap(bool is_root, uint32_t addr) { if (is_root) { - if (netif_ap) { - esp_netif_action_disconnected(netif_ap, NULL, 0, NULL); - mesh_delete_if_driver(esp_netif_get_io_driver(netif_ap)); - esp_netif_destroy(netif_ap); - netif_ap = NULL; - } + destory_mesh_link_ap(); netif_ap = create_mesh_link_ap(); mesh_netif_driver_t driver = mesh_create_if_driver(true, true); if (driver == NULL) { @@ -445,13 +453,7 @@ esp_err_t mesh_netifs_start(bool is_root) esp_netif_attach(netif_sta, driver); start_mesh_link_sta(); // If we have a AP on NODE -> stop and remove it! - if (netif_ap) { - esp_netif_action_disconnected(netif_ap, NULL, 0, NULL); - mesh_delete_if_driver(esp_netif_get_io_driver(netif_ap)); - esp_netif_destroy(netif_ap); - netif_ap = NULL; - } - + destory_mesh_link_ap(); } return ESP_OK; } @@ -475,12 +477,7 @@ esp_err_t mesh_netifs_stop(void) netif_sta = NULL; } - if (netif_ap) { - esp_netif_action_disconnected(netif_ap, NULL, 0, NULL); - mesh_delete_if_driver(esp_netif_get_io_driver(netif_ap)); - esp_netif_destroy(netif_ap); - netif_ap = NULL; - } + destory_mesh_link_ap(); // reserve the default (STA gets ready to become root) mesh_netif_init_station(); start_wifi_link_sta(); diff --git a/examples/peripherals/lcd/i80_controller/README.md b/examples/peripherals/lcd/i80_controller/README.md index 81f68ae419d6..f125c9f5c9f8 100644 --- a/examples/peripherals/lcd/i80_controller/README.md +++ b/examples/peripherals/lcd/i80_controller/README.md @@ -1,7 +1,7 @@ -| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -# LVGL porting example (based on i80 interfaced LCD controller) +# i80 LCD LVGL porting example LVGL is an open-source graphics library for creating modern GUIs. It has plenty of built-in graphical elements with low memory footprint, which is friendly for embedded GUI applications. @@ -29,34 +29,25 @@ The connection between ESP Board and the LCD is as follows: ```text ESP Board LCD Screen -┌─────────────┐ ┌────────────────┐ -│ │ │ │ -│ 3V3 ├─────────────►│ VCC │ -│ │ │ │ -│ GND ├──────────────┤ GND │ -│ │ │ │ -│ DATA[0..7] │◄────────────►│ DATA[0..7] │ -│ │ │ │ -│ PCLK ├─────────────►│ PCLK │ -│ │ │ │ -│ CS ├─────────────►│ CS │ -│ │ │ │ -│ D/C ├─────────────►│ D/C │ -│ │ │ │ -│ RST ├─────────────►│ RST │ -│ │ │ │ -│ BK_LIGHT ├─────────────►│ BCKL │ -│ │ │ │ -│ │ └────────────────┘ -│ │ LCD TOUCH -│ │ ┌────────────────┐ -│ │ │ │ -│ I2C SCL ├─────────────►│ I2C SCL │ -│ │ │ │ -│ I2C SDA │◄────────────►│ I2C SDA │ -│ │ │ │ -└─────────────┘ └────────────────┘ - ++-------------+ +----------------+ +| | | | +| 3V3 +------------->| VCC | +| | | | +| GND +--------------+ GND | +| | | | +| DATA[0..7] |<------------>| DATA[0..7] | +| | | | +| PCLK +------------->| PCLK | +| | | | +| CS +------------->| CS | +| | | | +| D/C +------------->| D/C | +| | | | +| RST +------------->| RST | +| | | | +| BK_LIGHT +------------->| BCKL | +| | | | ++-------------+ +----------------+ ``` The GPIO number used by this example can be changed in [i80_controller_example_main.c](main/i80_controller_example_main.c). @@ -69,9 +60,8 @@ Run `idf.py set-target ` to select one supported target that can ru Run `idf.py menuconfig` to open a terminal UI where you can tune specific configuration for this example in the `Example Configuration` menu. * `i80 LCD controller model`: Choose the LCD model to use by the example. If you choose `NT35510`, there will be another relevant configuration `NT35510 Data Width`, to choose the data line width for your NT35510 LCD module. - * `Allocate color data from PSRAM`: Select this option if you want to allocate the LVGL draw buffers from PSRAM. - +* `Pixel clock frequency (Hz)`: Set the pixel clock frequency for the LCD controller. * `LCD image source from`: Select where to load the image resource. See [Image Resource](#image-resource) for more details. Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. A fancy animation will show up on the LCD as expected. @@ -99,16 +89,6 @@ I (558) example: Starting LVGL task I (638) example: Display LVGL animation ``` -## Touch Screen Support - -This example supports touch screen connected via I2C. You can enable it by running `idf.py menuconfig` and navigating to `Example Configuration -> Enable LCD touch`. When touch is enabled, there will be a new button in the GUI that can restart the animation. - -These touch controllers are supported: - -* [GT911](https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch/esp_lcd_touch_gt911) -* [TT21100](https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch/esp_lcd_touch_tt21100) -* [FT5X06](https://github.com/espressif/esp-bsp/tree/master/components/lcd_touch/esp_lcd_touch_ft5x06) - ## Image Resource This example supports two ways of reading images @@ -120,6 +100,6 @@ This example supports two ways of reading images * Can't get a stable UI when `EXAMPLE_LCD_I80_COLOR_IN_PSRAM` is enabled. - This is because of the limited PSRAM bandwidth, compared to the internal SRAM. You can either decrease the PCLK clock `EXAMPLE_LCD_PIXEL_CLOCK_HZ` in [i80_controller_example_main.c](main/i80_controller_example_main.c) or increase the PSRAM working frequency `SPIRAM_SPEED` from the KConfig (e.g. **ESP32S3-Specific** -> **Set RAM clock speed**) or decrease the FPS in LVGL configuration. For illustration, this example has set the refresh period to 100ms in the default sdkconfig file. + This is because of the limited PSRAM bandwidth, compared to the internal SRAM. You can either decrease the PCLK clock `EXAMPLE_LCD_PIXEL_CLOCK_HZ` from the menuconfig or increase the PSRAM working frequency `SPIRAM_SPEED` from the KConfig (e.g. **ESP32S3-Specific** -> **Set RAM clock speed**) or decrease the FPS in LVGL configuration. For illustration, this example has set the refresh period to 100ms in the default sdkconfig file. For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild b/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild index cf4a5e392adb..c88cc250171e 100644 --- a/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild +++ b/examples/peripherals/lcd/i80_controller/main/Kconfig.projbuild @@ -2,11 +2,17 @@ menu "Example Configuration" config EXAMPLE_LCD_I80_COLOR_IN_PSRAM bool "Allocate color data from PSRAM" - depends on IDF_TARGET_ESP32S3 + depends on SOC_PSRAM_DMA_CAPABLE default y help - Enable this option if you wish to allocate the color buffer used by LVGL from PSRAM. - Unmatched PSRAM band width with LCD requirement can lead to blurred image display. + Enable this option if you want to allocate the LVGL draw buffer from PSRAM. + + config EXAMPLE_LCD_PIXEL_CLOCK_HZ + int "Pixel clock frequency (Hz)" + default 2000000 if EXAMPLE_LCD_I80_COLOR_IN_PSRAM && IDF_TARGET_ESP32S3 + default 10000000 + help + Set the pixel clock frequency in Hz. choice EXAMPLE_LCD_I80_CONTROLLER_MODEL prompt "i80 LCD controller model" @@ -45,29 +51,6 @@ menu "Example Configuration" default 16 if EXAMPLE_LCD_NT35510_DATA_WIDTH_16 default 8 - config EXAMPLE_LCD_TOUCH_ENABLED - bool "Enable LCD touch" - default n - help - Enable this option if you wish to use display touch. You can select from three touch controllers. - - choice EXAMPLE_LCD_TOUCH_CONTROLLER - prompt "LCD touch controller model" - depends on EXAMPLE_LCD_TOUCH_ENABLED - default EXAMPLE_LCD_TOUCH_CONTROLLER_FT5X06 - help - Select LCD touch controller model - - config EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 - bool "GT911" - - config EXAMPLE_LCD_TOUCH_CONTROLLER_TT21100 - bool "TT21100" - - config EXAMPLE_LCD_TOUCH_CONTROLLER_FT5X06 - bool "FT5X06" - endchoice - choice EXAMPLE_LCD_IMAGE_SOURCE prompt "LCD image source from" default EXAMPLE_LCD_IMAGE_FROM_EMBEDDED_BINARY diff --git a/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c b/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c index 259dd4bcb5b2..84fa07c9e1d8 100644 --- a/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c +++ b/examples/peripherals/lcd/i80_controller/main/i80_controller_example_main.c @@ -9,36 +9,21 @@ #include "freertos/task.h" #include "freertos/semphr.h" #include "esp_timer.h" -#include "esp_heap_caps.h" +#include "esp_err.h" +#include "esp_log.h" #include "esp_lcd_panel_io.h" #include "esp_lcd_panel_vendor.h" #include "esp_lcd_panel_ops.h" -#include "esp_lcd_touch.h" #include "esp_spiffs.h" #include "driver/gpio.h" -#include "driver/i2c.h" -#include "esp_err.h" -#include "esp_log.h" #include "lvgl.h" -#if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 -#include "esp_lcd_touch_gt911.h" -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_TT21100 -#include "esp_lcd_touch_tt21100.h" -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_FT5X06 -#include "esp_lcd_touch_ft5x06.h" -#endif static const char *TAG = "example"; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////// Please update the following configuration according to your LCD spec ////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#if CONFIG_EXAMPLE_LCD_I80_COLOR_IN_PSRAM -// PCLK frequency can't go too high as the limitation of PSRAM bandwidth -#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (2 * 1000 * 1000) -#else -#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (10 * 1000 * 1000) -#endif // CONFIG_EXAMPLE_LCD_I80_COLOR_IN_PSRAM +#define EXAMPLE_LCD_PIXEL_CLOCK_HZ CONFIG_EXAMPLE_LCD_PIXEL_CLOCK_HZ #define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL 1 #define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL @@ -81,12 +66,6 @@ static const char *TAG = "example"; #define EXAMPLE_LCD_PARAM_BITS 8 #endif -#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED -#define EXAMPLE_I2C_NUM 0 // I2C number -#define EXAMPLE_I2C_SCL 39 -#define EXAMPLE_I2C_SDA 40 -#endif - #define EXAMPLE_LVGL_TICK_PERIOD_MS 2 #define EXAMPLE_LVGL_TASK_MAX_DELAY_MS 500 #define EXAMPLE_LVGL_TASK_MIN_DELAY_MS 1 @@ -117,29 +96,6 @@ static void example_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_ esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map); } -#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED -static void example_lvgl_touch_cb(lv_indev_drv_t *drv, lv_indev_data_t *data) -{ - uint16_t touchpad_x[1] = {0}; - uint16_t touchpad_y[1] = {0}; - uint8_t touchpad_cnt = 0; - - /* Read touch controller data */ - esp_lcd_touch_read_data(drv->user_data); - - /* Get coordinates */ - bool touchpad_pressed = esp_lcd_touch_get_coordinates(drv->user_data, touchpad_x, touchpad_y, NULL, &touchpad_cnt, 1); - - if (touchpad_pressed && touchpad_cnt > 0) { - data->point.x = touchpad_x[0]; - data->point.y = touchpad_y[0]; - data->state = LV_INDEV_STATE_PRESSED; - } else { - data->state = LV_INDEV_STATE_RELEASED; - } -} -#endif - static void example_increase_lvgl_tick(void *arg) { /* Tell LVGL how many milliseconds has elapsed */ @@ -342,64 +298,6 @@ void example_init_lcd_panel(esp_lcd_panel_io_handle_t io_handle, esp_lcd_panel_h *panel = panel_handle; } -#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED -void example_init_lcd_touch(esp_lcd_touch_handle_t *tp_handle) -{ - esp_lcd_touch_handle_t tp = NULL; - esp_lcd_panel_io_handle_t tp_io_handle = NULL; - - const i2c_config_t i2c_conf = { - .mode = I2C_MODE_MASTER, - .sda_io_num = EXAMPLE_I2C_SDA, - .scl_io_num = EXAMPLE_I2C_SCL, - .sda_pullup_en = GPIO_PULLUP_ENABLE, - .scl_pullup_en = GPIO_PULLUP_ENABLE, - .master.clk_speed = 400000, - }; - /* Initialize I2C */ - ESP_ERROR_CHECK(i2c_param_config(EXAMPLE_I2C_NUM, &i2c_conf)); - ESP_ERROR_CHECK(i2c_driver_install(EXAMPLE_I2C_NUM, i2c_conf.mode, 0, 0, 0)); - -#if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 - esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG(); -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_TT21100 - esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_TT21100_CONFIG(); -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_FT5X06 - esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_FT5x06_CONFIG(); -#endif - - ESP_LOGI(TAG, "Initialize touch IO (I2C)"); - - /* Touch IO handle */ - ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)EXAMPLE_I2C_NUM, &tp_io_config, &tp_io_handle)); - - esp_lcd_touch_config_t tp_cfg = { - .x_max = EXAMPLE_LCD_V_RES, - .y_max = EXAMPLE_LCD_H_RES, - .rst_gpio_num = -1, - .int_gpio_num = -1, - .flags = { - .swap_xy = 1, - .mirror_x = 1, - .mirror_y = 0, - }, - }; - - /* Initialize touch */ -#if CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_GT911 - ESP_LOGI(TAG, "Initialize touch controller GT911"); - ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp)); -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_TT21100 - ESP_LOGI(TAG, "Initialize touch controller TT21100"); - ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_tt21100(tp_io_handle, &tp_cfg, &tp)); -#elif CONFIG_EXAMPLE_LCD_TOUCH_CONTROLLER_FT5X06 - ESP_LOGI(TAG, "Initialize touch controller FT5X06"); - ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_ft5x06(tp_io_handle, &tp_cfg, &tp)); -#endif - *tp_handle = tp; -} -#endif // CONFIG_EXAMPLE_LCD_TOUCH_ENABLED - void app_main(void) { static lv_disp_draw_buf_t disp_buf; // contains internal graphic buffer(s) called draw buffer(s) @@ -425,11 +323,6 @@ void app_main(void) esp_lcd_panel_handle_t panel_handle = NULL; example_init_lcd_panel(io_handle, &panel_handle); -#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED - esp_lcd_touch_handle_t tp_handle = NULL; - example_init_lcd_touch(&tp_handle); -#endif // CONFIG_EXAMPLE_LCD_TOUCH_ENABLED - // Stub: user can flush pre-defined pattern to the screen before we turn on the screen or backlight ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); @@ -474,16 +367,6 @@ void app_main(void) ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer)); ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, EXAMPLE_LVGL_TICK_PERIOD_MS * 1000)); -#if CONFIG_EXAMPLE_LCD_TOUCH_ENABLED - static lv_indev_drv_t indev_drv; // Input device driver (Touch) - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_POINTER; - indev_drv.disp = disp; - indev_drv.read_cb = example_lvgl_touch_cb; - indev_drv.user_data = tp_handle; - lv_indev_drv_register(&indev_drv); -#endif // CONFIG_EXAMPLE_LCD_TOUCH_ENABLED - lvgl_mux = xSemaphoreCreateRecursiveMutex(); assert(lvgl_mux); ESP_LOGI(TAG, "Create LVGL task"); diff --git a/examples/peripherals/lcd/i80_controller/main/idf_component.yml b/examples/peripherals/lcd/i80_controller/main/idf_component.yml index feb5edc9c72d..982d037d3757 100644 --- a/examples/peripherals/lcd/i80_controller/main/idf_component.yml +++ b/examples/peripherals/lcd/i80_controller/main/idf_component.yml @@ -1,6 +1,2 @@ dependencies: - idf: ">=4.4" - lvgl/lvgl: "~8.3.0" - esp_lcd_touch_gt911: "^1.0" - esp_lcd_touch_tt21100: "^1.0" - esp_lcd_touch_ft5x06: "^1.0" + lvgl/lvgl: "~8.4.0" diff --git a/examples/peripherals/lcd/i80_controller/main/lvgl_demo_ui.c b/examples/peripherals/lcd/i80_controller/main/lvgl_demo_ui.c index ab5d9a57f33d..8459e366d5bf 100644 --- a/examples/peripherals/lcd/i80_controller/main/lvgl_demo_ui.c +++ b/examples/peripherals/lcd/i80_controller/main/lvgl_demo_ui.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -24,7 +24,6 @@ typedef struct { } my_timer_context_t; static my_timer_context_t my_tim_ctx; -static lv_obj_t *btn; static lv_obj_t *arc[3]; static lv_obj_t *img_logo = NULL; static lv_obj_t *img_text = NULL; @@ -78,9 +77,6 @@ static void anim_timer_cb(lv_timer_t *timer) // Delete timer when all animation finished if ((count += 5) == 220) { lv_timer_del(timer); - - // Enable button - lv_obj_clear_state(btn, LV_STATE_DISABLED); } else { timer_ctx->count_val = count; } @@ -118,15 +114,6 @@ static void start_animation(lv_obj_t *scr) my_tim_ctx.count_val = -90; my_tim_ctx.scr = scr; lv_timer_create(anim_timer_cb, 20, &my_tim_ctx); - - // Disable button - lv_obj_add_state(btn, LV_STATE_DISABLED); -} - -static void btn_cb(lv_event_t *e) -{ - lv_obj_t *scr = lv_event_get_user_data(e); - start_animation(scr); } void example_lvgl_demo_ui(lv_disp_t *disp) @@ -140,13 +127,6 @@ void example_lvgl_demo_ui(lv_disp_t *disp) #elif CONFIG_EXAMPLE_LCD_IMAGE_FROM_EMBEDDED_BINARY lv_img_set_src(img_logo, &esp_logo); #endif - btn = lv_btn_create(scr); - lv_obj_t *lbl = lv_label_create(btn); - lv_label_set_text_static(lbl, LV_SYMBOL_REFRESH" SHOW AGAIN"); - lv_obj_set_style_text_font(lbl, &lv_font_montserrat_20, 0); - lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 30, -30); - // Button event - lv_obj_add_event_cb(btn, btn_cb, LV_EVENT_CLICKED, scr); start_animation(scr); } diff --git a/examples/peripherals/lcd/i80_controller/sdkconfig.defaults b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults index 931fa4c55146..f6df29ce553c 100644 --- a/examples/peripherals/lcd/i80_controller/sdkconfig.defaults +++ b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults @@ -5,3 +5,4 @@ CONFIG_LV_USE_USER_DATA=y CONFIG_LV_COLOR_16_SWAP=y CONFIG_LV_COLOR_DEPTH_16=y CONFIG_LV_FONT_MONTSERRAT_20=y +CONFIG_IDF_EXPERIMENTAL_FEATURES=y diff --git a/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32p4 b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32p4 new file mode 100644 index 000000000000..702fac3342dd --- /dev/null +++ b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32p4 @@ -0,0 +1,3 @@ +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_HEX=y +CONFIG_SPIRAM_SPEED_200M=y diff --git a/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32s3 b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32s3 index 2cfad7e5220a..41d6ae4a71a9 100644 --- a/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32s3 +++ b/examples/peripherals/lcd/i80_controller/sdkconfig.defaults.esp32s3 @@ -3,5 +3,4 @@ CONFIG_SPIRAM_SPEED_80M=y # Enabling the following configurations can help increase the PCLK frequency in the case when # the Frame Buffer is allocated from the PSRAM and fetched by EDMA -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y -CONFIG_SPIRAM_RODATA=y +CONFIG_SPIRAM_XIP_FROM_PSRAM=y diff --git a/examples/peripherals/lcd/mipi_dsi/README.md b/examples/peripherals/lcd/mipi_dsi/README.md index 8b7c760374d6..404d1b98a13e 100644 --- a/examples/peripherals/lcd/mipi_dsi/README.md +++ b/examples/peripherals/lcd/mipi_dsi/README.md @@ -3,7 +3,7 @@ # MIPI DSI LCD Panel Example -[esp_lcd](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/lcd.html) supports MIPI DSI interfaced LCD panel, with frame buffer(s) managed by the driver itself. +[esp_lcd](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/lcd/dsi_lcd.html) supports MIPI DSI interfaced LCD panel, with frame buffer(s) managed by the driver itself. This example shows the general process of installing a MIPI DSI LCD driver, and displays a LVGL widget on the screen. @@ -12,7 +12,7 @@ This example shows the general process of installing a MIPI DSI LCD driver, and ### Hardware Required * An ESP development board, which with MIPI DSI peripheral supported -* A general MIPI DSI LCD panel, with 2 data lanes and 1 clock lane, this example will use the [ILI9881C](https://components.espressif.com/components/espressif/esp_lcd_ili9881c) for demonstration +* A general MIPI DSI LCD panel, with 2 data lanes and 1 clock lane, this example support [ILI9881C](https://components.espressif.com/components/espressif/esp_lcd_ili9881c) and [EK79007](https://components.espressif.com/components/espressif/esp_lcd_ek79007) * An USB cable for power supply and programming ### Hardware Connection @@ -49,6 +49,7 @@ Before testing your LCD, you also need to read your LCD spec carefully, and then Run `idf.py menuconfig` and go to `Example Configuration`: +* Choose the LCD model in `Select MIPI LCD model` according to your board. * Choose whether to `Use DMA2D to copy draw buffer to frame buffer` asynchronously. If you choose `No`, the draw buffer will be copied to the frame buffer synchronously by CPU. * Choose if you want to `Monitor FPS by GPIO`. If you choose `Yes`, then you can attach an oscilloscope or logic analyzer to the GPIO pin to monitor the FPS of the display. Please note, the actual FPS should be **double** the square wave frequency. diff --git a/examples/peripherals/lcd/mipi_dsi/main/Kconfig.projbuild b/examples/peripherals/lcd/mipi_dsi/main/Kconfig.projbuild index fd8d96bf125e..bde4d4b00f10 100644 --- a/examples/peripherals/lcd/mipi_dsi/main/Kconfig.projbuild +++ b/examples/peripherals/lcd/mipi_dsi/main/Kconfig.projbuild @@ -12,4 +12,16 @@ menu "Example Configuration" help Enable this option, you can visualize the FPS by attaching a logic analyzer to a specific GPIO. The GPIO will output a square wave with the frequency of FPS/2. + + choice + prompt "Select MIPI LCD model" + default EXAMPLE_LCD_EK79007_SUPPORT + help + Select LCD controller model. + + config EXAMPLE_LCD_USE_EK79007 + bool "EK79007" + config EXAMPLE_LCD_USE_ILI9881C + bool "ILI9881C" + endchoice endmenu diff --git a/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml b/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml index f4d4be77e464..a0e6249c4d41 100644 --- a/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml +++ b/examples/peripherals/lcd/mipi_dsi/main/idf_component.yml @@ -1,3 +1,4 @@ dependencies: lvgl/lvgl: "^9.0.0" - esp_lcd_ili9881c: "~0.2.0" + esp_lcd_ili9881c: "^1.0.0" + esp_lcd_ek79007: "^1.0.0" diff --git a/examples/peripherals/lcd/mipi_dsi/main/mipi_dsi_lcd_example_main.c b/examples/peripherals/lcd/mipi_dsi/main/mipi_dsi_lcd_example_main.c index 859895d50130..87a2ea04de02 100644 --- a/examples/peripherals/lcd/mipi_dsi/main/mipi_dsi_lcd_example_main.c +++ b/examples/peripherals/lcd/mipi_dsi/main/mipi_dsi_lcd_example_main.c @@ -12,12 +12,13 @@ #include "esp_timer.h" #include "esp_lcd_panel_ops.h" #include "esp_lcd_mipi_dsi.h" -#include "esp_lcd_ili9881c.h" #include "esp_ldo_regulator.h" #include "driver/gpio.h" #include "esp_err.h" #include "esp_log.h" #include "lvgl.h" +#include "esp_lcd_ili9881c.h" +#include "esp_lcd_ek79007.h" static const char *TAG = "example"; @@ -25,6 +26,7 @@ static const char *TAG = "example"; //////////////////// Please update the following configuration according to your LCD Spec ////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if CONFIG_EXAMPLE_LCD_USE_ILI9881C // FPS = 80000000/(40+140+40+800)/(4+16+16+1280) = 60Hz #define EXAMPLE_MIPI_DSI_DPI_CLK_MHZ 80 #define EXAMPLE_MIPI_DSI_LCD_H_RES 800 @@ -35,6 +37,18 @@ static const char *TAG = "example"; #define EXAMPLE_MIPI_DSI_LCD_VSYNC 4 #define EXAMPLE_MIPI_DSI_LCD_VBP 16 #define EXAMPLE_MIPI_DSI_LCD_VFP 16 +#elif CONFIG_EXAMPLE_LCD_USE_EK79007 +// FPS = 48000000/(10+120+120+1024)/(1+20+10+600) = 60Hz +#define EXAMPLE_MIPI_DSI_DPI_CLK_MHZ 48 +#define EXAMPLE_MIPI_DSI_LCD_H_RES 1024 +#define EXAMPLE_MIPI_DSI_LCD_V_RES 600 +#define EXAMPLE_MIPI_DSI_LCD_HSYNC 10 +#define EXAMPLE_MIPI_DSI_LCD_HBP 120 +#define EXAMPLE_MIPI_DSI_LCD_HFP 120 +#define EXAMPLE_MIPI_DSI_LCD_VSYNC 1 +#define EXAMPLE_MIPI_DSI_LCD_VBP 20 +#define EXAMPLE_MIPI_DSI_LCD_VFP 10 +#endif #define EXAMPLE_MIPI_DSI_LANE_NUM 2 // 2 data lanes #define EXAMPLE_MIPI_DSI_LANE_BITRATE_MBPS 1000 // 1Gbps @@ -201,29 +215,18 @@ void app_main(void) }; ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus)); - ESP_LOGI(TAG, "Install MIPI DSI LCD control panel"); + ESP_LOGI(TAG, "Install MIPI DSI LCD control IO"); esp_lcd_panel_io_handle_t mipi_dbi_io; // we use DBI interface to send LCD commands and parameters esp_lcd_dbi_io_config_t dbi_config = { .virtual_channel = 0, - .lcd_cmd_bits = 8, // according to the LCD ILI9881C spec - .lcd_param_bits = 8, // according to the LCD ILI9881C spec + .lcd_cmd_bits = 8, // according to the LCD spec + .lcd_param_bits = 8, // according to the LCD spec }; ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &mipi_dbi_io)); - // create ILI9881C control panel - esp_lcd_panel_handle_t ili9881c_ctrl_panel; - esp_lcd_panel_dev_config_t lcd_dev_config = { - .bits_per_pixel = 24, - .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, - .reset_gpio_num = EXAMPLE_PIN_NUM_LCD_RST, - }; - ESP_ERROR_CHECK(esp_lcd_new_panel_ili9881c(mipi_dbi_io, &lcd_dev_config, &ili9881c_ctrl_panel)); - ESP_ERROR_CHECK(esp_lcd_panel_reset(ili9881c_ctrl_panel)); - ESP_ERROR_CHECK(esp_lcd_panel_init(ili9881c_ctrl_panel)); - ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(ili9881c_ctrl_panel, true)); ESP_LOGI(TAG, "Install MIPI DSI LCD data panel"); - esp_lcd_panel_handle_t mipi_dpi_panel; + esp_lcd_panel_handle_t mipi_dpi_panel = NULL; esp_lcd_dpi_panel_config_t dpi_config = { .virtual_channel = 0, .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, @@ -243,7 +246,39 @@ void app_main(void) .flags.use_dma2d = true, #endif }; - ESP_ERROR_CHECK(esp_lcd_new_panel_dpi(mipi_dsi_bus, &dpi_config, &mipi_dpi_panel)); + +#if CONFIG_EXAMPLE_LCD_USE_ILI9881C + ili9881c_vendor_config_t vendor_config = { + .mipi_config = { + .dsi_bus = mipi_dsi_bus, + .dpi_config = &dpi_config, + .lane_num = EXAMPLE_MIPI_DSI_LANE_NUM, + }, + }; + esp_lcd_panel_dev_config_t lcd_dev_config = { + .reset_gpio_num = EXAMPLE_PIN_NUM_LCD_RST, + .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, + .bits_per_pixel = 24, + .vendor_config = &vendor_config, + }; + ESP_ERROR_CHECK(esp_lcd_new_panel_ili9881c(mipi_dbi_io, &lcd_dev_config, &mipi_dpi_panel)); +#elif CONFIG_EXAMPLE_LCD_USE_EK79007 + ek79007_vendor_config_t vendor_config = { + .mipi_config = { + .dsi_bus = mipi_dsi_bus, + .dpi_config = &dpi_config, + }, + }; + esp_lcd_panel_dev_config_t lcd_dev_config = { + .reset_gpio_num = EXAMPLE_PIN_NUM_LCD_RST, + .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, + .bits_per_pixel = 24, + .vendor_config = &vendor_config, + }; + ESP_ERROR_CHECK(esp_lcd_new_panel_ek79007(mipi_dbi_io, &lcd_dev_config, &mipi_dpi_panel)); +#endif + + ESP_ERROR_CHECK(esp_lcd_panel_reset(mipi_dpi_panel)); ESP_ERROR_CHECK(esp_lcd_panel_init(mipi_dpi_panel)); // turn on backlight example_bsp_set_lcd_backlight(EXAMPLE_LCD_BK_LIGHT_ON_LEVEL); diff --git a/examples/storage/.build-test-rules.yml b/examples/storage/.build-test-rules.yml index cc6f28981be3..9d4905332643 100644 --- a/examples/storage/.build-test-rules.yml +++ b/examples/storage/.build-test-rules.yml @@ -139,9 +139,8 @@ examples/storage/sd_card/sdspi: disable: - if: SOC_GPSPI_SUPPORTED != 1 disable_test: - - if: IDF_TARGET not in ["esp32", "esp32c3"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32s3", "esp32c3", "esp32p4"] + reason: needs special runner, select few typical targets for testing examples/storage/semihost_vfs: depends_components: diff --git a/examples/storage/sd_card/sdspi/main/Kconfig.projbuild b/examples/storage/sd_card/sdspi/main/Kconfig.projbuild index 77fd451ed70c..54e0f70776d8 100644 --- a/examples/storage/sd_card/sdspi/main/Kconfig.projbuild +++ b/examples/storage/sd_card/sdspi/main/Kconfig.projbuild @@ -17,35 +17,35 @@ menu "SD SPI Example Configuration" int "MOSI GPIO number" default 15 if IDF_TARGET_ESP32 default 35 if IDF_TARGET_ESP32S2 - default 35 if IDF_TARGET_ESP32S3 + default 4 if IDF_TARGET_ESP32S3 default 5 if IDF_TARGET_ESP32H2 - default 11 if IDF_TARGET_ESP32P4 + default 36 if IDF_TARGET_ESP32P4 default 4 # C3 and others config EXAMPLE_PIN_MISO int "MISO GPIO number" default 2 if IDF_TARGET_ESP32 default 37 if IDF_TARGET_ESP32S2 - default 37 if IDF_TARGET_ESP32S3 + default 5 if IDF_TARGET_ESP32S3 default 0 if IDF_TARGET_ESP32H2 - default 13 if IDF_TARGET_ESP32P4 + default 47 if IDF_TARGET_ESP32P4 default 6 # C3 and others config EXAMPLE_PIN_CLK int "CLK GPIO number" default 14 if IDF_TARGET_ESP32 default 36 if IDF_TARGET_ESP32S2 - default 36 if IDF_TARGET_ESP32S3 + default 2 if IDF_TARGET_ESP32S3 default 4 if IDF_TARGET_ESP32H2 - default 12 if IDF_TARGET_ESP32P4 + default 53 if IDF_TARGET_ESP32P4 default 5 # C3 and others config EXAMPLE_PIN_CS int "CS GPIO number" default 13 if IDF_TARGET_ESP32 default 34 if IDF_TARGET_ESP32S2 - default 34 if IDF_TARGET_ESP32S3 - default 10 if IDF_TARGET_ESP32P4 + default 8 if IDF_TARGET_ESP32S3 + default 33 if IDF_TARGET_ESP32P4 default 1 # C3 and others config EXAMPLE_DEBUG_PIN_CONNECTIONS diff --git a/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py b/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py index ddec7002bf19..331506918f66 100644 --- a/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py +++ b/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import logging import re @@ -8,14 +8,16 @@ @pytest.mark.esp32 -@pytest.mark.esp32c3 # no runner available at the moment +@pytest.mark.esp32s3 +@pytest.mark.esp32c3 +@pytest.mark.esp32p4 @pytest.mark.sdcard_spimode def test_examples_sd_card_sdspi(dut: Dut) -> None: dut.expect('example: Initializing SD card', timeout=20) dut.expect('example: Using SPI peripheral', timeout=20) # Provide enough time for possible SD card formatting - dut.expect('Filesystem mounted', timeout=60) + dut.expect('Filesystem mounted', timeout=180) # These lines are matched separately because of ASCII color codes in the output name = dut.expect(re.compile(rb'Name: (\w+)\r'), timeout=20).group(1).decode() @@ -42,4 +44,4 @@ def test_examples_sd_card_sdspi(dut: Dut) -> None: dut.expect_exact(msg, timeout=30) dut.expect(sd_card_format, timeout=180) # Provide enough time for SD card FATFS format operation for msg in message_list2: - dut.expect_exact(msg, timeout=30) + dut.expect_exact(msg, timeout=180) diff --git a/examples/storage/sd_card/sdspi/sdkconfig.defaults.esp32p4 b/examples/storage/sd_card/sdspi/sdkconfig.defaults.esp32p4 new file mode 100644 index 000000000000..5e9f8e25bd87 --- /dev/null +++ b/examples/storage/sd_card/sdspi/sdkconfig.defaults.esp32p4 @@ -0,0 +1 @@ +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y diff --git a/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c b/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c index 22e64be4d873..85edc34ebf1d 100644 --- a/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c +++ b/examples/system/ota/advanced_https_ota/main/ble_helper/bluedroid_gatts.c @@ -376,10 +376,8 @@ void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par } break; case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT: - ESP_LOGI(TAG, "update connection params status = %d, min_int = %d, max_int = %d,conn_int = %d,latency = %d, timeout = %d", + ESP_LOGI(TAG, "update connection params status = %d, conn_int = %d, latency = %d, timeout = %d", param->update_conn_params.status, - param->update_conn_params.min_int, - param->update_conn_params.max_int, param->update_conn_params.conn_int, param->update_conn_params.latency, param->update_conn_params.timeout); diff --git a/examples/system/xip_from_psram/sdkconfig.ci.esp32p4_200m b/examples/system/xip_from_psram/sdkconfig.ci.esp32p4_200m new file mode 100644 index 000000000000..1a978368629d --- /dev/null +++ b/examples/system/xip_from_psram/sdkconfig.ci.esp32p4_200m @@ -0,0 +1,3 @@ +CONFIG_IDF_TARGET="esp32p4" +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM_SPEED_200M=y diff --git a/examples/wifi/.build-test-rules.yml b/examples/wifi/.build-test-rules.yml index 1a6e8bc6d678..2d3671707027 100644 --- a/examples/wifi/.build-test-rules.yml +++ b/examples/wifi/.build-test-rules.yml @@ -39,9 +39,10 @@ examples/wifi/getting_started: examples/wifi/iperf: disable: - - if: SOC_WIFI_SUPPORTED != 1 + - if: (SOC_WIFI_SUPPORTED != 1) and (SOC_WIRELESS_HOST_SUPPORTED != 1) + - if: (IDF_TARGET == "esp32p4") and CONFIG_NAME in ["defaults", "99"] disable_test: - - if: IDF_TARGET != "esp32" + - if: IDF_TARGET not in ["esp32"] temporary: true reason: lack of runners depends_components: diff --git a/examples/wifi/iperf/README.md b/examples/wifi/iperf/README.md index b42b7c44405e..0287fa9d0d33 100644 --- a/examples/wifi/iperf/README.md +++ b/examples/wifi/iperf/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # Iperf Example diff --git a/examples/wifi/iperf/main/idf_component.yml b/examples/wifi/iperf/main/idf_component.yml index fa9a6e59d662..fdb795321d22 100644 --- a/examples/wifi/iperf/main/idf_component.yml +++ b/examples/wifi/iperf/main/idf_component.yml @@ -7,3 +7,7 @@ dependencies: version: "~0.1.0" esp-qa/ping-cmd: version: "~0.0.1" + espressif/esp-extconn: + version: "~0.1.0" + rules: + - if: "target in [esp32p4]" diff --git a/examples/wifi/iperf/main/iperf_example_main.c b/examples/wifi/iperf/main/iperf_example_main.c index a856e20ebc0d..a7d8bbea9726 100644 --- a/examples/wifi/iperf/main/iperf_example_main.c +++ b/examples/wifi/iperf/main/iperf_example_main.c @@ -35,6 +35,9 @@ extern int wifi_cmd_get_rx_statistics(int argc, char **argv); extern int wifi_cmd_clr_rx_statistics(int argc, char **argv); #endif +#ifdef CONFIG_ESP_EXT_CONN_ENABLE +#include "esp_extconn.h" +#endif void iperf_hook_show_wifi_stats(iperf_traffic_type_t type, iperf_status_t status) { @@ -69,6 +72,11 @@ void iperf_hook_show_wifi_stats(iperf_traffic_type_t type, iperf_status_t status void app_main(void) { +#if CONFIG_ESP_EXT_CONN_ENABLE + esp_extconn_config_t ext_config = ESP_EXTCONN_CONFIG_DEFAULT(); + esp_extconn_init(&ext_config); +#endif + esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); diff --git a/examples/wifi/iperf/sdkconfig.ci.esp32p4_with_extconn b/examples/wifi/iperf/sdkconfig.ci.esp32p4_with_extconn new file mode 100644 index 000000000000..f675f0a416bb --- /dev/null +++ b/examples/wifi/iperf/sdkconfig.ci.esp32p4_with_extconn @@ -0,0 +1,6 @@ +# +# ESP32-P4 +# +CONFIG_IDF_TARGET="esp32p4" +CONFIG_ESP_HOST_WIFI_ENABLED=y +CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y diff --git a/examples/wifi/itwt/main/wifi_stats_cmd.c b/examples/wifi/itwt/main/wifi_stats_cmd.c index e3b6d934631b..b3a9e10a6d2f 100644 --- a/examples/wifi/itwt/main/wifi_stats_cmd.c +++ b/examples/wifi/itwt/main/wifi_stats_cmd.c @@ -15,7 +15,6 @@ #include "esp_event.h" #include "esp_wifi.h" #include "esp_wifi_types.h" -#include "wifi_stats.h" #include "esp_private/esp_wifi_he_private.h" /******************************************************* diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index db42d9fe3cf0..ff0fadb9aaf6 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1197,7 +1197,6 @@ tools/templates/sample_component/main.c tools/test_apps/build_system/embed_test/main/test_main.c tools/test_apps/build_system/ldgen_test/main/src1.c tools/test_apps/build_system/ldgen_test/main/src2.c -tools/test_apps/build_system/ldgen_test/main/test_main.c tools/test_apps/peripherals/i2c_wifi/main/i2c_wifi_main.c tools/test_apps/protocols/esp_netif/build_config/main/init_macro.h tools/test_apps/protocols/esp_netif/build_config/main/main.cpp diff --git a/tools/ci/check_ldgen_mapping_exceptions.txt b/tools/ci/check_ldgen_mapping_exceptions.txt index 6d470c462d62..6bd2d5330f65 100644 --- a/tools/ci/check_ldgen_mapping_exceptions.txt +++ b/tools/ci/check_ldgen_mapping_exceptions.txt @@ -2,6 +2,9 @@ libc sha256_coredump gcc clang_rt_builtins +freertos_idf +freertos_smp freertos_common esp_psram esp_mm +esp_ringbuf diff --git a/tools/idf_py_actions/hints.yml b/tools/idf_py_actions/hints.yml index f3bd56bf21d2..44d0bfc52125 100644 --- a/tools/idf_py_actions/hints.yml +++ b/tools/idf_py_actions/hints.yml @@ -430,3 +430,7 @@ - re: "unplaced orphan section" hint: "Avoid creating custom sections. Please refer to the 'Linker Script Generation' article in the IDF documentation to address this. Or set option CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE (not recommended)." + +- + re: "the current mclk multiple cannot perform integer division" + hint: "Please adjust the mclk multiple to get the accurate sample rate.\nFor example, if you're using 24-bit slot width or enabled 3 slots, then the mclk multiple should be a multiple of 3, otherwise the sample rate will be inaccurate." diff --git a/tools/ldgen/ldgen/output_commands.py b/tools/ldgen/ldgen/output_commands.py index e7d32dd64e00..a5c58b7a8cfe 100644 --- a/tools/ldgen/ldgen/output_commands.py +++ b/tools/ldgen/ldgen/output_commands.py @@ -60,7 +60,7 @@ class InputSectionDesc: Outputs an input section description as described in https://www.acrc.bris.ac.uk/acrc/RedHat/rhel-ld-en-4/sections.html#INPUT-SECTION. - These commands are emmited from mapping fragment entries, specifically attaching + These commands are emitted from mapping fragment entries, specifically attaching a scheme onto an entity. Mapping fragment flags KEEP, SORT will also affect the emitted input section description. """ @@ -85,9 +85,10 @@ def __init__(self, entity, sections, exclusions=None, keep=False, sort=None, tie self.tied = tied def __str__(self): - sections_string = '( )' + sections_string = '' if self.sections: + sections_string = '( )' exclusion_strings = [] for exc in sorted(self.exclusions): diff --git a/tools/ldgen/test/test_output_commands.py b/tools/ldgen/test/test_output_commands.py index 4a6723626d48..27906d1ed1b5 100755 --- a/tools/ldgen/test/test_output_commands.py +++ b/tools/ldgen/test/test_output_commands.py @@ -1,9 +1,8 @@ #!/usr/bin/env python # -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 # - import os import sys import unittest @@ -122,14 +121,14 @@ def test_exclusions(self): def test_empty_sections(self): # Test empty sections - expected = '*libfreertos.a:croutine.*( )' + expected = '*libfreertos.a:croutine.*' desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), []) self.assertEqual(expected, str(desc)) def test_keep(self): # Test KEEP - expected = 'KEEP(*libfreertos.a:croutine.*( ))' + expected = 'KEEP(*libfreertos.a:croutine.*)' desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), [], keep=True) self.assertEqual(expected, str(desc)) diff --git a/tools/test_apps/build_system/ldgen_test/check_placements.py b/tools/test_apps/build_system/ldgen_test/check_placements.py index 174793e2ebc8..c465f7bf0ea7 100644 --- a/tools/test_apps/build_system/ldgen_test/check_placements.py +++ b/tools/test_apps/build_system/ldgen_test/check_placements.py @@ -80,3 +80,5 @@ def check_location(symbol, expected): check_location('func3', '.flash.text') check_location('func4', '.iram0.text') + +check_location('const_array', '.dram0.data') diff --git a/tools/test_apps/build_system/ldgen_test/main/CMakeLists.txt b/tools/test_apps/build_system/ldgen_test/main/CMakeLists.txt index 466b45c56c58..6f10a09e8095 100644 --- a/tools/test_apps/build_system/ldgen_test/main/CMakeLists.txt +++ b/tools/test_apps/build_system/ldgen_test/main/CMakeLists.txt @@ -1,3 +1,3 @@ -idf_component_register(SRCS "src1.c" "src2.c" "test_main.c" +idf_component_register(SRCS "src1.c" "src2.c" "test_main.c" "consts.c" INCLUDE_DIRS "." LDFRAGMENTS "linker.lf") diff --git a/tools/test_apps/build_system/ldgen_test/main/consts.c b/tools/test_apps/build_system/ldgen_test/main/consts.c new file mode 100644 index 000000000000..47ced231891e --- /dev/null +++ b/tools/test_apps/build_system/ldgen_test/main/consts.c @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +const int const_array[] = { + 10, 20, 30, 40, 50, 60, 70, 80 +}; diff --git a/tools/test_apps/build_system/ldgen_test/main/linker.lf b/tools/test_apps/build_system/ldgen_test/main/linker.lf index 17f049094910..e2b06fb614aa 100644 --- a/tools/test_apps/build_system/ldgen_test/main/linker.lf +++ b/tools/test_apps/build_system/ldgen_test/main/linker.lf @@ -9,3 +9,4 @@ entries: text->iram0_text KEEP() if SOC_RTC_MEM_SUPPORTED = y: src1:func2 (rtc) + consts : const_array (noflash) diff --git a/tools/test_apps/build_system/ldgen_test/main/test_main.c b/tools/test_apps/build_system/ldgen_test/main/test_main.c index 9ebb9689c643..d01bec546e53 100644 --- a/tools/test_apps/build_system/ldgen_test/main/test_main.c +++ b/tools/test_apps/build_system/ldgen_test/main/test_main.c @@ -1,11 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ +#include +#include "esp_memory_utils.h" extern void func2(void); extern void func3(void); extern void func4(void); +extern const int const_array[]; + void app_main(void) { func2(); func3(); func4(); + if (esp_ptr_in_dram(const_array)) { + printf("const_array placed in dram\n"); + } else { + printf("const_array NOT placed in dram\n"); + } } diff --git a/tools/test_apps/system/build_test/sdkconfig.ci.func_in_flash_with_Os b/tools/test_apps/system/build_test/sdkconfig.ci.func_in_flash_with_Os new file mode 100644 index 000000000000..a8af29c1115d --- /dev/null +++ b/tools/test_apps/system/build_test/sdkconfig.ci.func_in_flash_with_Os @@ -0,0 +1,4 @@ +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y +CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y +CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH=y diff --git a/tools/test_apps/system/panic/main/CMakeLists.txt b/tools/test_apps/system/panic/main/CMakeLists.txt index cdbffba4a462..90e5bcf9730d 100644 --- a/tools/test_apps/system/panic/main/CMakeLists.txt +++ b/tools/test_apps/system/panic/main/CMakeLists.txt @@ -13,7 +13,7 @@ endif() idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "include" - REQUIRES spi_flash esp_psram esp_system esp_partition + REQUIRES spi_flash esp_psram esp_system esp_partition espcoredump PRIV_REQUIRES esp_gdbstub) target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-unused-variable" diff --git a/tools/test_apps/system/panic/main/include/test_panic.h b/tools/test_apps/system/panic/main/include/test_panic.h index 64dd22a5bc77..3b52370a34eb 100644 --- a/tools/test_apps/system/panic/main/include/test_panic.h +++ b/tools/test_apps/system/panic/main/include/test_panic.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,6 +67,11 @@ void test_illegal_access(void); void test_capture_dram(void); +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF +void test_setup_coredump_summary(void); +void test_coredump_summary(void); +#endif + #ifdef __cplusplus } #endif diff --git a/tools/test_apps/system/panic/main/test_app_main.c b/tools/test_apps/system/panic/main/test_app_main.c index f1da4f2fd502..6e3931b97b33 100644 --- a/tools/test_apps/system/panic/main/test_app_main.c +++ b/tools/test_apps/system/panic/main/test_app_main.c @@ -116,6 +116,10 @@ void app_main(void) HANDLE_TEST(test_name, test_assert_cache_disabled); HANDLE_TEST(test_name, test_assert_cache_write_back_error_can_print_backtrace); HANDLE_TEST(test_name, test_assert_cache_write_back_error_can_print_backtrace2); +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF + HANDLE_TEST(test_name, test_setup_coredump_summary); + HANDLE_TEST(test_name, test_coredump_summary); +#endif #if CONFIG_IDF_TARGET_ESP32 HANDLE_TEST(test_name, test_illegal_access); #endif diff --git a/tools/test_apps/system/panic/main/test_panic.c b/tools/test_apps/system/panic/main/test_panic.c index 982049c07bfa..5603279d4843 100644 --- a/tools/test_apps/system/panic/main/test_panic.c +++ b/tools/test_apps/system/panic/main/test_panic.c @@ -13,6 +13,7 @@ #include "esp_flash.h" #include "esp_system.h" #include "spi_flash_mmap.h" +#include "esp_core_dump.h" #include "esp_private/cache_utils.h" #include "esp_memory_utils.h" @@ -268,6 +269,38 @@ void test_ub(void) printf("%d\n", stuff[rand()]); } +#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH && CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF +void test_setup_coredump_summary(void) +{ + if (esp_core_dump_image_erase() != ESP_OK) + die("Coredump image can not be erased!"); + assert(0); +} + +void test_coredump_summary(void) +{ + esp_core_dump_summary_t *summary = malloc(sizeof(esp_core_dump_summary_t)); + if (summary) { + esp_err_t err = esp_core_dump_get_summary(summary); + if (err == ESP_OK) { + printf("App ELF file SHA256: %s\n", (char *)summary->app_elf_sha256); + printf("Crashed task: %s\n", summary->exc_task); +#if __XTENSA__ + printf("Exception cause: %ld\n", summary->ex_info.exc_cause); +#else + printf("Exception cause: %ld\n", summary->ex_info.mcause); +#endif + char panic_reason[200]; + err = esp_core_dump_get_panic_reason(panic_reason, sizeof(panic_reason)); + if (err == ESP_OK) { + printf("Panic reason: %s\n", panic_reason); + } + } + free(summary); + } +} +#endif + /* NOTE: The following test verifies the behaviour for the * Xtensa-specific MPU instructions (Refer WDTLB, DSYNC, WDTIB, ISYNC) * used for memory protection. diff --git a/tools/test_apps/system/panic/partitions_coredump_encrypted.csv b/tools/test_apps/system/panic/partitions_coredump_encrypted.csv new file mode 100644 index 000000000000..f02bfea26fab --- /dev/null +++ b/tools/test_apps/system/panic/partitions_coredump_encrypted.csv @@ -0,0 +1,6 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +nvs,data,nvs,0x11000,24K, +phy_init,data,phy,,4K, +factory,app,factory,0x20000,1M, +coredump,data,coredump,,64K,encrypted diff --git a/tools/test_apps/system/panic/partitions_coredump_plain.csv b/tools/test_apps/system/panic/partitions_coredump_plain.csv new file mode 100644 index 000000000000..d6769343d408 --- /dev/null +++ b/tools/test_apps/system/panic/partitions_coredump_plain.csv @@ -0,0 +1,6 @@ +# ESP-IDF Partition Table +# Name, Type, SubType, Offset, Size, Flags +nvs,data,nvs,0x11000,24K, +phy_init,data,phy,,4K, +factory,app,factory,0x20000,1M, +coredump,data,coredump,,64K, diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index b83105b76f6d..c882ba8f9b7d 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -91,6 +91,13 @@ CONFIG_CAPTURE_DRAM = [pytest.param('coredump_flash_capture_dram', marks=TARGETS_ALL)] +CONFIG_COREDUMP_SUMMARY = [pytest.param('coredump_flash_elf_sha', marks=TARGETS_ALL)] + +CONFIG_COREDUMP_SUMMARY_FLASH_ENCRYPTED = [ + pytest.param('coredump_flash_encrypted', marks=[pytest.mark.esp32, pytest.mark.esp32c3]), + pytest.param('coredump_flash_encrypted_coredump_plain', marks=[pytest.mark.esp32, pytest.mark.esp32c3]) +] + # Panic abort information will start with this string. PANIC_ABORT_PREFIX = 'Panic reason: ' @@ -1004,3 +1011,33 @@ def test_capture_dram(dut: PanicTestDut, config: str, test_func_name: str) -> No if dut.target != 'esp32c2': assert int(dut.gdb_data_eval_expr('g_rtc_data_var')) == 0x55AA assert int(dut.gdb_data_eval_expr('g_rtc_fast_var')) == 0xAABBCCDD + + +def _test_coredump_summary(dut: PanicTestDut, flash_encrypted: bool, coredump_encrypted: bool) -> None: + dut.run_test_func('test_setup_coredump_summary') + dut.expect_cpu_reset() + if flash_encrypted: + dut.expect_exact('Flash encryption mode is DEVELOPMENT (not secure)') + dut.run_test_func('test_coredump_summary') + if flash_encrypted and not coredump_encrypted: + dut.expect_exact('Flash encryption enabled in hardware and core dump partition is not encrypted!') + return + dut.expect_elf_sha256('App ELF file SHA256: ') + dut.expect_exact('Crashed task: main') + if dut.is_xtensa: + dut.expect_exact('Exception cause: 29') + else: + dut.expect_exact('Exception cause: 7') + dut.expect(PANIC_ABORT_PREFIX + r'assert failed:[\s\w()]*?\s[.\w/]*\.(?:c|cpp|h|hpp):\d.*$') + + +@pytest.mark.generic +@pytest.mark.parametrize('config', CONFIG_COREDUMP_SUMMARY, indirect=True) +def test_coredump_summary(dut: PanicTestDut) -> None: + _test_coredump_summary(dut, False, False) + + +@pytest.mark.flash_encryption +@pytest.mark.parametrize('config', CONFIG_COREDUMP_SUMMARY_FLASH_ENCRYPTED, indirect=True) +def test_coredump_summary_flash_encrypted(dut: PanicTestDut, config: str) -> None: + _test_coredump_summary(dut, True, config == 'coredump_flash_encrypted') diff --git a/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted new file mode 100644 index 000000000000..b0f4d9619169 --- /dev/null +++ b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted @@ -0,0 +1,15 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_coredump_encrypted.csv" + +CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y + +CONFIG_SECURE_FLASH_ENC_ENABLED=y +CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y +CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y +CONFIG_SECURE_BOOT_ALLOW_JTAG=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y +CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y diff --git a/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted_coredump_plain b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted_coredump_plain new file mode 100644 index 000000000000..da72c14012c3 --- /dev/null +++ b/tools/test_apps/system/panic/sdkconfig.ci.coredump_flash_encrypted_coredump_plain @@ -0,0 +1,15 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_coredump_plain.csv" + +CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH=y +CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF=y +CONFIG_ESP_COREDUMP_CHECKSUM_SHA256=y + +CONFIG_SECURE_FLASH_ENC_ENABLED=y +CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y +CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y +CONFIG_SECURE_BOOT_ALLOW_JTAG=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y +CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y diff --git a/tools/test_apps/system/panic/test_panic_util/panic_dut.py b/tools/test_apps/system/panic/test_panic_util/panic_dut.py index 205035e5b032..d738c307ae78 100644 --- a/tools/test_apps/system/panic/test_panic_util/panic_dut.py +++ b/tools/test_apps/system/panic/test_panic_util/panic_dut.py @@ -106,13 +106,13 @@ def expect_cpu_reset(self) -> None: # no digital system reset for panic handling restarts (see IDF-7255) self.expect(r'.*rst:.*(RTC_SW_CPU_RST|SW_CPU_RESET|SW_CPU)') - def expect_elf_sha256(self) -> None: + def expect_elf_sha256(self, caption: str = 'ELF file SHA256: ') -> None: """Expect method for ELF SHA256 line""" elf_sha256 = sha256(self.app.elf_file) elf_sha256_len = int( self.app.sdkconfig.get('CONFIG_APP_RETRIEVE_LEN_ELF_SHA', '9') ) - self.expect_exact('ELF file SHA256: ' + elf_sha256[0:elf_sha256_len]) + self.expect_exact(caption + elf_sha256[0:elf_sha256_len]) def expect_coredump(self, output_file_name: str, patterns: List[Union[str, re.Pattern]]) -> None: with open(output_file_name, 'r') as file: diff --git a/tools/test_apps/system/unicore_bootloader/main/CMakeLists.txt b/tools/test_apps/system/unicore_bootloader/main/CMakeLists.txt index 34613e8e3cd5..8f8dd1b8d6c0 100644 --- a/tools/test_apps/system/unicore_bootloader/main/CMakeLists.txt +++ b/tools/test_apps/system/unicore_bootloader/main/CMakeLists.txt @@ -1 +1,2 @@ -idf_component_register(SRCS "main.c") +idf_component_register(SRCS "main.c" + PRIV_REQUIRES nvs_flash esp_psram) diff --git a/tools/test_apps/system/unicore_bootloader/main/main.c b/tools/test_apps/system/unicore_bootloader/main/main.c index 50c39ad01611..327754428ef9 100644 --- a/tools/test_apps/system/unicore_bootloader/main/main.c +++ b/tools/test_apps/system/unicore_bootloader/main/main.c @@ -5,8 +5,70 @@ */ #include +#include + +#include "nvs_flash.h" +#include "nvs.h" void app_main(void) { printf("App is running\n"); + + // One difference of multicore bootloader is whether it resets all the MMU. If not, it may cause the nvs fail to + // call mmap. Test code copied from examples/storage/nvs_rw_value. + + // Initialize NVS + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { + // NVS partition was truncated and needs to be erased + // Retry nvs_flash_init + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK( err ); + + // Open + printf("Opening Non-Volatile Storage (NVS) handle... "); + nvs_handle_t my_handle; + err = nvs_open("storage", NVS_READWRITE, &my_handle); + if (err != ESP_OK) { + printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } else { + printf("Done\n"); + + // Read + printf("Reading restart counter from NVS ... "); + int32_t restart_counter = 0; // value will default to 0, if not set yet in NVS + err = nvs_get_i32(my_handle, "restart_counter", &restart_counter); + switch (err) { + case ESP_OK: + printf("Done\n"); + printf("Restart counter = %" PRIu32 "\n", restart_counter); + break; + case ESP_ERR_NVS_NOT_FOUND: + printf("The value is not initialized yet!\n"); + break; + default : + printf("Error (%s) reading!\n", esp_err_to_name(err)); + } + + // Write + printf("Updating restart counter in NVS ... "); + restart_counter++; + err = nvs_set_i32(my_handle, "restart_counter", restart_counter); + printf((err != ESP_OK) ? "Failed!\n" : "Done\n"); + + // Commit written value. + // After setting any values, nvs_commit() must be called to ensure changes are written + // to flash storage. Implementations may write to storage at other times, + // but this is not guaranteed. + printf("Committing updates in NVS ... "); + err = nvs_commit(my_handle); + printf((err != ESP_OK) ? "Failed!\n" : "Done\n"); + + // Close + nvs_close(my_handle); + } + + printf("NVS test done\n"); } diff --git a/tools/test_apps/system/unicore_bootloader/pytest_unicore_bootloader.py b/tools/test_apps/system/unicore_bootloader/pytest_unicore_bootloader.py index f0193dbe04f3..da16ff07dbcf 100644 --- a/tools/test_apps/system/unicore_bootloader/pytest_unicore_bootloader.py +++ b/tools/test_apps/system/unicore_bootloader/pytest_unicore_bootloader.py @@ -1,6 +1,7 @@ # SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import os +import re import pytest from artifacts_handler import ArtifactType @@ -12,13 +13,16 @@ @pytest.mark.esp32s3 @pytest.mark.esp32p4 @pytest.mark.generic -@pytest.mark.parametrize('config', ['multicore'], indirect=True) -def test_multicore_app_and_unicore_bootloader(dut: Dut, app_downloader) -> None: # type: ignore +@pytest.mark.parametrize('config', ['multicore', 'multicore_psram'], indirect=True) +def test_multicore_app_and_unicore_bootloader(dut: Dut, app_downloader, config) -> None: # type: ignore dut.expect('Multicore bootloader') dut.expect('Multicore app') dut.expect('App is running') - path_to_unicore_build = os.path.join(dut.app.app_path, f'build_{dut.target}_unicore') + assert 'multicore' in config + app_config = config.replace('multicore', 'unicore') + + path_to_unicore_build = os.path.join(dut.app.app_path, f'build_{dut.target}_{app_config}') if app_downloader: app_downloader.download_app( os.path.relpath(path_to_unicore_build, IDF_PATH), ArtifactType.BUILD_DIR_WITHOUT_MAP_AND_ELF_FILES @@ -27,20 +31,26 @@ def test_multicore_app_and_unicore_bootloader(dut: Dut, app_downloader) -> None: dut.serial.bootloader_flash(path_to_unicore_build) dut.expect('Unicore bootloader') dut.expect('Multicore app') + if 'psram' in config: + dut.expect(re.compile(r'Adding pool of \d+K of PSRAM memory to heap allocator')) dut.expect('App is running') + dut.expect('NVS test done\n') @pytest.mark.esp32 @pytest.mark.esp32s3 @pytest.mark.esp32p4 @pytest.mark.generic -@pytest.mark.parametrize('config', ['unicore'], indirect=True) -def test_unicore_app_and_multicore_bootloader(dut: Dut, app_downloader) -> None: # type: ignore +@pytest.mark.parametrize('config', ['unicore', 'unicore_psram'], indirect=True) +def test_unicore_app_and_multicore_bootloader(dut: Dut, app_downloader, config) -> None: # type: ignore dut.expect('Unicore bootloader') dut.expect('Unicore app') dut.expect('App is running') - path_to_multicore_build = os.path.join(dut.app.app_path, f'build_{dut.target}_multicore') + assert 'unicore' in config + app_config = config.replace('unicore', 'multicore') + + path_to_multicore_build = os.path.join(dut.app.app_path, f'build_{dut.target}_{app_config}') if app_downloader: app_downloader.download_app( os.path.relpath(path_to_multicore_build, IDF_PATH), ArtifactType.BUILD_DIR_WITHOUT_MAP_AND_ELF_FILES @@ -49,4 +59,7 @@ def test_unicore_app_and_multicore_bootloader(dut: Dut, app_downloader) -> None: dut.serial.bootloader_flash(path_to_multicore_build) dut.expect('Multicore bootloader') dut.expect('Unicore app') + if 'psram' in config: + dut.expect(re.compile(r'Adding pool of \d+K of PSRAM memory to heap allocator')) dut.expect('App is running') + dut.expect('NVS test done\n') diff --git a/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.multicore_psram b/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.multicore_psram new file mode 100644 index 000000000000..cc641ea60330 --- /dev/null +++ b/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.multicore_psram @@ -0,0 +1 @@ +CONFIG_SPIRAM=y diff --git a/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.unicore_psram b/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.unicore_psram new file mode 100644 index 000000000000..4bcf432a6035 --- /dev/null +++ b/tools/test_apps/system/unicore_bootloader/sdkconfig.ci.unicore_psram @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_UNICORE=y +CONFIG_SPIRAM=y diff --git a/tools/tools.json b/tools/tools.json index 09e6053d6fc3..2a5197cb2703 100644 --- a/tools/tools.json +++ b/tools/tools.json @@ -605,46 +605,46 @@ "versions": [ { "linux-amd64": { - "sha256": "cf26c5cef4f6b04aa23cd2778675604e5a74a4ce4d8d17b854d05fbcb782d52c", - "size": 2252682, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240318/openocd-esp32-linux-amd64-0.12.0-esp32-20240318.tar.gz" + "sha256": "f8c68541fa38307bc0c0763b7e1e3fe4e943d5d45da07d817a73b492e103b652", + "size": 2373094, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240821/openocd-esp32-linux-amd64-0.12.0-esp32-20240821.tar.gz" }, "linux-arm64": { - "sha256": "9b97a37aa2cab94424a778c25c0b4aa0f90d6ef9cda764a1d9289d061305f4b7", - "size": 2132904, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240318/openocd-esp32-linux-arm64-0.12.0-esp32-20240318.tar.gz" + "sha256": "4d6e263d84e447354dc685848557d6c284dda7fe007ee451f729a7edfa7baad7", + "size": 2251272, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240821/openocd-esp32-linux-arm64-0.12.0-esp32-20240821.tar.gz" }, "linux-armel": { - "sha256": "b7e82776ec374983807d3389df09c632ad9bc8341f2075690b6b500319dfeaf4", - "size": 2271761, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240318/openocd-esp32-linux-armel-0.12.0-esp32-20240318.tar.gz" + "sha256": "9d45679f2c4cf450d5e2350047cf57bb76dde2487d30cebce0a72c9173b5c45b", + "size": 2390074, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240821/openocd-esp32-linux-armel-0.12.0-esp32-20240821.tar.gz" }, "linux-armhf": { - "sha256": "16f8f65f12e5ba034d328cda2567d6851a2aceb3c957d577f89401c2e1d3f93a", - "size": 2121312, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240318/openocd-esp32-linux-armhf-0.12.0-esp32-20240318.tar.gz" + "sha256": "7f56d6a0c73e3988891a0781adee4973e6b9ea4bb4584cacb88384cb3db59050", + "size": 2232548, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240821/openocd-esp32-linux-armhf-0.12.0-esp32-20240821.tar.gz" }, "macos": { - "sha256": "b16c3082c94df1079367c44d99f7a8605534cd48aabc18898e46e94a2c8c57e7", - "size": 2365588, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240318/openocd-esp32-macos-0.12.0-esp32-20240318.tar.gz" + "sha256": "565c8fabc5f19a6e7a0864a294d74b307eec30b9291d16d3fc90e273f0330cb4", + "size": 2485320, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240821/openocd-esp32-macos-0.12.0-esp32-20240821.tar.gz" }, "macos-arm64": { - "sha256": "534ec925ae6e35e869e4e4e6e4d2c4a1eb081f97ebcc2dd5efdc52d12f4c2f86", - "size": 2406377, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240318/openocd-esp32-macos-arm64-0.12.0-esp32-20240318.tar.gz" + "sha256": "68c5c7cf3d15b9810939a5edabc6ff2c9f4fc32262de91fc292a180bc5cc0637", + "size": 2530336, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240821/openocd-esp32-macos-arm64-0.12.0-esp32-20240821.tar.gz" }, - "name": "v0.12.0-esp32-20240318", + "name": "v0.12.0-esp32-20240821", "status": "recommended", "win32": { - "sha256": "d379329eba052435173ab0d69c9b15bc164a6ce489e2a67cd11169d2dabff633", - "size": 2783915, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240318/openocd-esp32-win32-0.12.0-esp32-20240318.zip" + "sha256": "463fc2903ddaf03f86ff50836c5c63cc696550b0446140159eddfd2e85570c5d", + "size": 2916409, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240821/openocd-esp32-win32-0.12.0-esp32-20240821.zip" }, "win64": { - "sha256": "d379329eba052435173ab0d69c9b15bc164a6ce489e2a67cd11169d2dabff633", - "size": 2783915, - "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240318/openocd-esp32-win32-0.12.0-esp32-20240318.zip" + "sha256": "550f57369f1f1f6cc600b5dffa3378fd6164d8ea8db7c567cf41091771f090cb", + "size": 2916408, + "url": "https://github.com/espressif/openocd-esp32/releases/download/v0.12.0-esp32-20240821/openocd-esp32-win64-0.12.0-esp32-20240821.zip" } } ] diff --git a/version.txt b/version.txt index cb509dba53f0..6ebe9221f986 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -5.3.1.240903 +5.3.1.240910