From 11d53820f2c056f5b61391792f7695f45297194a Mon Sep 17 00:00:00 2001 From: Grigory Kirillov Date: Sun, 21 May 2023 01:34:53 +0300 Subject: [PATCH 001/161] Remove semicolons from ESP_IP4ADDR_INIT and ESP_IP6ADDR_INIT macros There are structs like esp_netif_dns_info_t that have member for generic ip for which the presence of semicolons is problematic, because when trying to initialize an ip member with one of these macroses it results in a syntax error since semicolon is used within curly braces. --- components/esp_netif/include/esp_netif_ip_addr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp_netif/include/esp_netif_ip_addr.h b/components/esp_netif/include/esp_netif_ip_addr.h index 354da5814ba4..b8608c9c755e 100644 --- a/components/esp_netif/include/esp_netif_ip_addr.h +++ b/components/esp_netif/include/esp_netif_ip_addr.h @@ -79,8 +79,8 @@ extern "C" { #define ESP_IP4TOADDR(a,b,c,d) esp_netif_htonl(ESP_IP4TOUINT32(a, b, c, d)) -#define ESP_IP4ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V4, .u_addr = { .ip4 = { .addr = ESP_IP4TOADDR(a, b, c, d) }}}; -#define ESP_IP6ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V6, .u_addr = { .ip6 = { .addr = { a, b, c, d }, .zone = 0 }}}; +#define ESP_IP4ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V4, .u_addr = { .ip4 = { .addr = ESP_IP4TOADDR(a, b, c, d) }}} +#define ESP_IP6ADDR_INIT(a, b, c, d) { .type = ESP_IPADDR_TYPE_V6, .u_addr = { .ip6 = { .addr = { a, b, c, d }, .zone = 0 }}} #ifndef IP4ADDR_STRLEN_MAX #define IP4ADDR_STRLEN_MAX 16 From 1f80a9bb0f3adcc932b9843ae97ded1faade74a4 Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Mon, 2 Oct 2023 08:37:57 +0200 Subject: [PATCH 002/161] fix(lf): fix orphaned .phyiram sections There are orphaned .phyiram sections from components/esp_phy/lib/esp32/libphy.a when ESP_WIFI_SLP_IRAM_OPT is not set on esp32. It can be seen in the wifi_station example examples/wifi/getting_started/station with the default configuration. Even though they seem to be correctly placed in flash(linker got it right), I believe this should be fixed. At least for the esp-idf-size, because these doesn't seem to be accounted. Signed-off-by: Frantisek Hrbata --- components/esp_phy/linker.lf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/esp_phy/linker.lf b/components/esp_phy/linker.lf index a5a355da2e32..40d3b99c9d05 100644 --- a/components/esp_phy/linker.lf +++ b/components/esp_phy/linker.lf @@ -1,7 +1,10 @@ if IDF_TARGET_ESP32 = y: [scheme:phy_iram] entries: + if ESP_WIFI_SLP_IRAM_OPT = y: phy_iram -> iram0_text + else: + phy_iram -> flash_text [sections:phy_iram] entries: @@ -11,7 +14,7 @@ if IDF_TARGET_ESP32 = y: archive: libphy.a entries: * (noflash_data) - if ESP_WIFI_SLP_IRAM_OPT = y && IDF_TARGET_ESP32 = y: + if IDF_TARGET_ESP32 = y: * (phy_iram) [mapping:rtc] From 071d1cf8652749338fd60d90ae921548ec3eba60 Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Wed, 4 Oct 2023 16:00:01 +0800 Subject: [PATCH 003/161] feat(efuse): Adds efuse ADC calibration data for ESP32H2 --- components/efuse/esp32h2/esp_efuse_table.c | 254 +++++++++++++++++- components/efuse/esp32h2/esp_efuse_table.csv | 30 ++- .../efuse/esp32h2/include/esp_efuse_table.h | 30 ++- .../soc/esp32h2/include/soc/efuse_reg.h | 152 +++++++++-- .../soc/esp32h2/include/soc/efuse_struct.h | 80 +++++- 5 files changed, 504 insertions(+), 42 deletions(-) diff --git a/components/efuse/esp32h2/esp_efuse_table.c b/components/efuse/esp32h2/esp_efuse_table.c index f5407c8e484d..f59aa56de8df 100644 --- a/components/efuse/esp32h2/esp_efuse_table.c +++ b/components/efuse/esp32h2/esp_efuse_table.c @@ -9,7 +9,7 @@ #include #include "esp_efuse_table.h" -// md5_digest_table 6b9b5b452050328626d767c44e489b8d +// md5_digest_table e3fb625011fff48d5d8b7569075d0bb3 // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // If you want to change some fields, you need to change esp_efuse_table.csv file // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. @@ -243,6 +243,62 @@ static const esp_efuse_desc_t WR_DIS_DISABLE_BLK_VERSION_MAJOR[] = { {EFUSE_BLK0, 21, 1}, // [] wr_dis of DISABLE_BLK_VERSION_MAJOR, }; +static const esp_efuse_desc_t WR_DIS_TEMP_CALIB[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of TEMP_CALIB, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_AVE_INITCODE_ATTEN0[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_AVE_INITCODE_ATTEN0, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_AVE_INITCODE_ATTEN1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_AVE_INITCODE_ATTEN1, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_AVE_INITCODE_ATTEN2[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_AVE_INITCODE_ATTEN2, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_AVE_INITCODE_ATTEN3[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_AVE_INITCODE_ATTEN3, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_HI_DOUT_ATTEN0[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_HI_DOUT_ATTEN0, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_HI_DOUT_ATTEN1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_HI_DOUT_ATTEN1, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_HI_DOUT_ATTEN2[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_HI_DOUT_ATTEN2, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_HI_DOUT_ATTEN3[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_HI_DOUT_ATTEN3, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF, +}; + static const esp_efuse_desc_t WR_DIS_BLOCK_USR_DATA[] = { {EFUSE_BLK0, 22, 1}, // [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA, }; @@ -553,6 +609,62 @@ static const esp_efuse_desc_t DISABLE_BLK_VERSION_MAJOR[] = { {EFUSE_BLK2, 135, 1}, // [] Disables check of blk version major, }; +static const esp_efuse_desc_t TEMP_CALIB[] = { + {EFUSE_BLK2, 136, 9}, // [] Temperature calibration data, +}; + +static const esp_efuse_desc_t ADC1_AVE_INITCODE_ATTEN0[] = { + {EFUSE_BLK2, 145, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_AVE_INITCODE_ATTEN1[] = { + {EFUSE_BLK2, 155, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_AVE_INITCODE_ATTEN2[] = { + {EFUSE_BLK2, 165, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_AVE_INITCODE_ATTEN3[] = { + {EFUSE_BLK2, 175, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_HI_DOUT_ATTEN0[] = { + {EFUSE_BLK2, 185, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_HI_DOUT_ATTEN1[] = { + {EFUSE_BLK2, 195, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_HI_DOUT_ATTEN2[] = { + {EFUSE_BLK2, 205, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_HI_DOUT_ATTEN3[] = { + {EFUSE_BLK2, 215, 10}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_CH0_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK2, 225, 4}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_CH1_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK2, 229, 4}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_CH2_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK2, 233, 4}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_CH3_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK2, 237, 4}, // [] ADC1 calibration data, +}; + +static const esp_efuse_desc_t ADC1_CH4_ATTEN0_INITCODE_DIFF[] = { + {EFUSE_BLK2, 241, 4}, // [] ADC1 calibration data, +}; + static const esp_efuse_desc_t USER_DATA[] = { {EFUSE_BLK3, 0, 256}, // [BLOCK_USR_DATA] User data, }; @@ -878,6 +990,76 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_BLK_VERSION_MAJOR[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_TEMP_CALIB[] = { + &WR_DIS_TEMP_CALIB[0], // [] wr_dis of TEMP_CALIB + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN0[] = { + &WR_DIS_ADC1_AVE_INITCODE_ATTEN0[0], // [] wr_dis of ADC1_AVE_INITCODE_ATTEN0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN1[] = { + &WR_DIS_ADC1_AVE_INITCODE_ATTEN1[0], // [] wr_dis of ADC1_AVE_INITCODE_ATTEN1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN2[] = { + &WR_DIS_ADC1_AVE_INITCODE_ATTEN2[0], // [] wr_dis of ADC1_AVE_INITCODE_ATTEN2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN3[] = { + &WR_DIS_ADC1_AVE_INITCODE_ATTEN3[0], // [] wr_dis of ADC1_AVE_INITCODE_ATTEN3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN0[] = { + &WR_DIS_ADC1_HI_DOUT_ATTEN0[0], // [] wr_dis of ADC1_HI_DOUT_ATTEN0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN1[] = { + &WR_DIS_ADC1_HI_DOUT_ATTEN1[0], // [] wr_dis of ADC1_HI_DOUT_ATTEN1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN2[] = { + &WR_DIS_ADC1_HI_DOUT_ATTEN2[0], // [] wr_dis of ADC1_HI_DOUT_ATTEN2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN3[] = { + &WR_DIS_ADC1_HI_DOUT_ATTEN3[0], // [] wr_dis of ADC1_HI_DOUT_ATTEN3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF[] = { + &WR_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF[0], // [] wr_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF[] = { + &WR_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF[0], // [] wr_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF[] = { + &WR_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF[0], // [] wr_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF[] = { + &WR_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF[0], // [] wr_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF[] = { + &WR_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF[0], // [] wr_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_USR_DATA[] = { &WR_DIS_BLOCK_USR_DATA[0], // [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA NULL @@ -1264,6 +1446,76 @@ const esp_efuse_desc_t* ESP_EFUSE_DISABLE_BLK_VERSION_MAJOR[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[] = { + &TEMP_CALIB[0], // [] Temperature calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN0[] = { + &ADC1_AVE_INITCODE_ATTEN0[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN1[] = { + &ADC1_AVE_INITCODE_ATTEN1[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN2[] = { + &ADC1_AVE_INITCODE_ATTEN2[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN3[] = { + &ADC1_AVE_INITCODE_ATTEN3[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN0[] = { + &ADC1_HI_DOUT_ATTEN0[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN1[] = { + &ADC1_HI_DOUT_ATTEN1[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN2[] = { + &ADC1_HI_DOUT_ATTEN2[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN3[] = { + &ADC1_HI_DOUT_ATTEN3[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF[] = { + &ADC1_CH0_ATTEN0_INITCODE_DIFF[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF[] = { + &ADC1_CH1_ATTEN0_INITCODE_DIFF[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF[] = { + &ADC1_CH2_ATTEN0_INITCODE_DIFF[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF[] = { + &ADC1_CH3_ATTEN0_INITCODE_DIFF[0], // [] ADC1 calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF[] = { + &ADC1_CH4_ATTEN0_INITCODE_DIFF[0], // [] ADC1 calibration data + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[] = { &USER_DATA[0], // [BLOCK_USR_DATA] User data NULL diff --git a/components/efuse/esp32h2/esp_efuse_table.csv b/components/efuse/esp32h2/esp_efuse_table.csv index 67f3ed78729e..3ddbe98d7f72 100644 --- a/components/efuse/esp32h2/esp_efuse_table.csv +++ b/components/efuse/esp32h2/esp_efuse_table.csv @@ -9,7 +9,7 @@ # this will generate new source files, next rebuild all the sources. # !!!!!!!!!!! # -# This file was generated by regtools.py based on the efuses.yaml file with the version: 4df10f83de85f2d830b7c466aabb28e7 +# This file was generated by regtools.py based on the efuses.yaml file with the version: b69ddcfb39a412df490e3facbbfb46b2 WR_DIS, EFUSE_BLK0, 0, 32, [] Disable programming of individual eFuses WR_DIS.RD_DIS, EFUSE_BLK0, 0, 1, [] wr_dis of RD_DIS @@ -68,6 +68,20 @@ WR_DIS.OPTIONAL_UNIQUE_ID, EFUSE_BLK0, 21, 1, [] wr_dis WR_DIS.BLK_VERSION_MINOR, EFUSE_BLK0, 21, 1, [] wr_dis of BLK_VERSION_MINOR WR_DIS.BLK_VERSION_MAJOR, EFUSE_BLK0, 21, 1, [] wr_dis of BLK_VERSION_MAJOR WR_DIS.DISABLE_BLK_VERSION_MAJOR, EFUSE_BLK0, 21, 1, [] wr_dis of DISABLE_BLK_VERSION_MAJOR +WR_DIS.TEMP_CALIB, EFUSE_BLK0, 21, 1, [] wr_dis of TEMP_CALIB +WR_DIS.ADC1_AVE_INITCODE_ATTEN0, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_AVE_INITCODE_ATTEN0 +WR_DIS.ADC1_AVE_INITCODE_ATTEN1, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_AVE_INITCODE_ATTEN1 +WR_DIS.ADC1_AVE_INITCODE_ATTEN2, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_AVE_INITCODE_ATTEN2 +WR_DIS.ADC1_AVE_INITCODE_ATTEN3, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_AVE_INITCODE_ATTEN3 +WR_DIS.ADC1_HI_DOUT_ATTEN0, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_HI_DOUT_ATTEN0 +WR_DIS.ADC1_HI_DOUT_ATTEN1, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_HI_DOUT_ATTEN1 +WR_DIS.ADC1_HI_DOUT_ATTEN2, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_HI_DOUT_ATTEN2 +WR_DIS.ADC1_HI_DOUT_ATTEN3, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_HI_DOUT_ATTEN3 +WR_DIS.ADC1_CH0_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CH0_ATTEN0_INITCODE_DIFF +WR_DIS.ADC1_CH1_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CH1_ATTEN0_INITCODE_DIFF +WR_DIS.ADC1_CH2_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CH2_ATTEN0_INITCODE_DIFF +WR_DIS.ADC1_CH3_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CH3_ATTEN0_INITCODE_DIFF +WR_DIS.ADC1_CH4_ATTEN0_INITCODE_DIFF, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CH4_ATTEN0_INITCODE_DIFF WR_DIS.BLOCK_USR_DATA, EFUSE_BLK0, 22, 1, [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA WR_DIS.CUSTOM_MAC, EFUSE_BLK0, 22, 1, [WR_DIS.MAC_CUSTOM WR_DIS.USER_DATA_MAC_CUSTOM] wr_dis of CUSTOM_MAC WR_DIS.BLOCK_KEY0, EFUSE_BLK0, 23, 1, [WR_DIS.KEY0] wr_dis of BLOCK_KEY0 @@ -150,6 +164,20 @@ OPTIONAL_UNIQUE_ID, EFUSE_BLK2, 0, 128, [] Option BLK_VERSION_MINOR, EFUSE_BLK2, 130, 3, [] BLK_VERSION_MINOR of BLOCK2. 1: RF Calibration data in BLOCK1 BLK_VERSION_MAJOR, EFUSE_BLK2, 133, 2, [] BLK_VERSION_MAJOR of BLOCK2 DISABLE_BLK_VERSION_MAJOR, EFUSE_BLK2, 135, 1, [] Disables check of blk version major +TEMP_CALIB, EFUSE_BLK2, 136, 9, [] Temperature calibration data +ADC1_AVE_INITCODE_ATTEN0, EFUSE_BLK2, 145, 10, [] ADC1 calibration data +ADC1_AVE_INITCODE_ATTEN1, EFUSE_BLK2, 155, 10, [] ADC1 calibration data +ADC1_AVE_INITCODE_ATTEN2, EFUSE_BLK2, 165, 10, [] ADC1 calibration data +ADC1_AVE_INITCODE_ATTEN3, EFUSE_BLK2, 175, 10, [] ADC1 calibration data +ADC1_HI_DOUT_ATTEN0, EFUSE_BLK2, 185, 10, [] ADC1 calibration data +ADC1_HI_DOUT_ATTEN1, EFUSE_BLK2, 195, 10, [] ADC1 calibration data +ADC1_HI_DOUT_ATTEN2, EFUSE_BLK2, 205, 10, [] ADC1 calibration data +ADC1_HI_DOUT_ATTEN3, EFUSE_BLK2, 215, 10, [] ADC1 calibration data +ADC1_CH0_ATTEN0_INITCODE_DIFF, EFUSE_BLK2, 225, 4, [] ADC1 calibration data +ADC1_CH1_ATTEN0_INITCODE_DIFF, EFUSE_BLK2, 229, 4, [] ADC1 calibration data +ADC1_CH2_ATTEN0_INITCODE_DIFF, EFUSE_BLK2, 233, 4, [] ADC1 calibration data +ADC1_CH3_ATTEN0_INITCODE_DIFF, EFUSE_BLK2, 237, 4, [] ADC1 calibration data +ADC1_CH4_ATTEN0_INITCODE_DIFF, EFUSE_BLK2, 241, 4, [] ADC1 calibration data USER_DATA, EFUSE_BLK3, 0, 256, [BLOCK_USR_DATA] User data USER_DATA.MAC_CUSTOM, EFUSE_BLK3, 200, 48, [MAC_CUSTOM CUSTOM_MAC] Custom MAC KEY0, EFUSE_BLK4, 0, 256, [BLOCK_KEY0] Key0 or user data diff --git a/components/efuse/esp32h2/include/esp_efuse_table.h b/components/efuse/esp32h2/include/esp_efuse_table.h index b8ea18db0fa3..fbe83816b0a1 100644 --- a/components/efuse/esp32h2/include/esp_efuse_table.h +++ b/components/efuse/esp32h2/include/esp_efuse_table.h @@ -10,7 +10,7 @@ extern "C" { #include "esp_efuse.h" -// md5_digest_table 6b9b5b452050328626d767c44e489b8d +// md5_digest_table e3fb625011fff48d5d8b7569075d0bb3 // This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY. // If you want to change some fields, you need to change esp_efuse_table.csv file // then run `efuse_common_table` or `efuse_custom_table` command it will generate this file. @@ -83,6 +83,20 @@ extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OPTIONAL_UNIQUE_ID[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MINOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MAJOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_BLK_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_TEMP_CALIB[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_AVE_INITCODE_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_HI_DOUT_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH0_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH1_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH2_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH3_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CH4_ATTEN0_INITCODE_DIFF[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_USR_DATA[]; #define ESP_EFUSE_WR_DIS_USER_DATA ESP_EFUSE_WR_DIS_BLOCK_USR_DATA extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_CUSTOM_MAC[]; @@ -185,6 +199,20 @@ extern const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[]; extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MINOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MAJOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_BLK_VERSION_MAJOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_HI_DOUT_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF[]; extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[]; #define ESP_EFUSE_BLOCK_USR_DATA ESP_EFUSE_USER_DATA extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[]; diff --git a/components/soc/esp32h2/include/soc/efuse_reg.h b/components/soc/esp32h2/include/soc/efuse_reg.h index 0eb9572fe852..aaaaf8b2127f 100644 --- a/components/soc/esp32h2/include/soc/efuse_reg.h +++ b/components/soc/esp32h2/include/soc/efuse_reg.h @@ -796,49 +796,147 @@ extern "C" { #define EFUSE_DISABLE_BLK_VERSION_MAJOR_M (EFUSE_DISABLE_BLK_VERSION_MAJOR_V << EFUSE_DISABLE_BLK_VERSION_MAJOR_S) #define EFUSE_DISABLE_BLK_VERSION_MAJOR_V 0x00000001U #define EFUSE_DISABLE_BLK_VERSION_MAJOR_S 7 -/** EFUSE_RESERVED_2_136 : R; bitpos: [31:8]; default: 0; - * reserved - */ -#define EFUSE_RESERVED_2_136 0x00FFFFFFU -#define EFUSE_RESERVED_2_136_M (EFUSE_RESERVED_2_136_V << EFUSE_RESERVED_2_136_S) -#define EFUSE_RESERVED_2_136_V 0x00FFFFFFU -#define EFUSE_RESERVED_2_136_S 8 +/** EFUSE_TEMP_CALIB : R; bitpos: [16:8]; default: 0; + * Temperature calibration data + */ +#define EFUSE_TEMP_CALIB 0x000001FFU +#define EFUSE_TEMP_CALIB_M (EFUSE_TEMP_CALIB_V << EFUSE_TEMP_CALIB_S) +#define EFUSE_TEMP_CALIB_V 0x000001FFU +#define EFUSE_TEMP_CALIB_S 8 +/** EFUSE_ADC1_AVE_INITCODE_ATTEN0 : R; bitpos: [26:17]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_AVE_INITCODE_ATTEN0 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN0_M (EFUSE_ADC1_AVE_INITCODE_ATTEN0_V << EFUSE_ADC1_AVE_INITCODE_ATTEN0_S) +#define EFUSE_ADC1_AVE_INITCODE_ATTEN0_V 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN0_S 17 +/** EFUSE_ADC1_AVE_INITCODE_ATTEN1 : R; bitpos: [31:27]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1 0x0000001FU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_M (EFUSE_ADC1_AVE_INITCODE_ATTEN1_V << EFUSE_ADC1_AVE_INITCODE_ATTEN1_S) +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_V 0x0000001FU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_S 27 /** EFUSE_RD_SYS_PART1_DATA5_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA5_REG (DR_REG_EFUSE_BASE + 0x70) -/** EFUSE_SYS_DATA_PART1_5 : RO; bitpos: [31:0]; default: 0; - * Stores the fifth 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_5 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_5_M (EFUSE_SYS_DATA_PART1_5_V << EFUSE_SYS_DATA_PART1_5_S) -#define EFUSE_SYS_DATA_PART1_5_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_5_S 0 +/** EFUSE_ADC1_AVE_INITCODE_ATTEN1_1 : R; bitpos: [4:0]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_1 0x0000001FU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_1_M (EFUSE_ADC1_AVE_INITCODE_ATTEN1_1_V << EFUSE_ADC1_AVE_INITCODE_ATTEN1_1_S) +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_1_V 0x0000001FU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN1_1_S 0 +/** EFUSE_ADC1_AVE_INITCODE_ATTEN2 : R; bitpos: [14:5]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_AVE_INITCODE_ATTEN2 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN2_M (EFUSE_ADC1_AVE_INITCODE_ATTEN2_V << EFUSE_ADC1_AVE_INITCODE_ATTEN2_S) +#define EFUSE_ADC1_AVE_INITCODE_ATTEN2_V 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN2_S 5 +/** EFUSE_ADC1_AVE_INITCODE_ATTEN3 : R; bitpos: [24:15]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_AVE_INITCODE_ATTEN3 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN3_M (EFUSE_ADC1_AVE_INITCODE_ATTEN3_V << EFUSE_ADC1_AVE_INITCODE_ATTEN3_S) +#define EFUSE_ADC1_AVE_INITCODE_ATTEN3_V 0x000003FFU +#define EFUSE_ADC1_AVE_INITCODE_ATTEN3_S 15 +/** EFUSE_ADC1_HI_DOUT_ATTEN0 : R; bitpos: [31:25]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN0 0x0000007FU +#define EFUSE_ADC1_HI_DOUT_ATTEN0_M (EFUSE_ADC1_HI_DOUT_ATTEN0_V << EFUSE_ADC1_HI_DOUT_ATTEN0_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN0_V 0x0000007FU +#define EFUSE_ADC1_HI_DOUT_ATTEN0_S 25 /** EFUSE_RD_SYS_PART1_DATA6_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA6_REG (DR_REG_EFUSE_BASE + 0x74) -/** EFUSE_SYS_DATA_PART1_6 : RO; bitpos: [31:0]; default: 0; - * Stores the sixth 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_6 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_6_M (EFUSE_SYS_DATA_PART1_6_V << EFUSE_SYS_DATA_PART1_6_S) -#define EFUSE_SYS_DATA_PART1_6_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_6_S 0 +/** EFUSE_ADC1_HI_DOUT_ATTEN0_1 : R; bitpos: [2:0]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN0_1 0x00000007U +#define EFUSE_ADC1_HI_DOUT_ATTEN0_1_M (EFUSE_ADC1_HI_DOUT_ATTEN0_1_V << EFUSE_ADC1_HI_DOUT_ATTEN0_1_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN0_1_V 0x00000007U +#define EFUSE_ADC1_HI_DOUT_ATTEN0_1_S 0 +/** EFUSE_ADC1_HI_DOUT_ATTEN1 : R; bitpos: [12:3]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN1 0x000003FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN1_M (EFUSE_ADC1_HI_DOUT_ATTEN1_V << EFUSE_ADC1_HI_DOUT_ATTEN1_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN1_V 0x000003FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN1_S 3 +/** EFUSE_ADC1_HI_DOUT_ATTEN2 : R; bitpos: [22:13]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN2 0x000003FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN2_M (EFUSE_ADC1_HI_DOUT_ATTEN2_V << EFUSE_ADC1_HI_DOUT_ATTEN2_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN2_V 0x000003FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN2_S 13 +/** EFUSE_ADC1_HI_DOUT_ATTEN3 : R; bitpos: [31:23]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN3 0x000001FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN3_M (EFUSE_ADC1_HI_DOUT_ATTEN3_V << EFUSE_ADC1_HI_DOUT_ATTEN3_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN3_V 0x000001FFU +#define EFUSE_ADC1_HI_DOUT_ATTEN3_S 23 /** EFUSE_RD_SYS_PART1_DATA7_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA7_REG (DR_REG_EFUSE_BASE + 0x78) -/** EFUSE_SYS_DATA_PART1_7 : RO; bitpos: [31:0]; default: 0; - * Stores the seventh 32 bits of the first part of system data. +/** EFUSE_ADC1_HI_DOUT_ATTEN3_1 : R; bitpos: [0]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_HI_DOUT_ATTEN3_1 (BIT(0)) +#define EFUSE_ADC1_HI_DOUT_ATTEN3_1_M (EFUSE_ADC1_HI_DOUT_ATTEN3_1_V << EFUSE_ADC1_HI_DOUT_ATTEN3_1_S) +#define EFUSE_ADC1_HI_DOUT_ATTEN3_1_V 0x00000001U +#define EFUSE_ADC1_HI_DOUT_ATTEN3_1_S 0 +/** EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF : R; bitpos: [4:1]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF 0x0000000FU +#define EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF_M (EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF_V << EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF_S) +#define EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF_V 0x0000000FU +#define EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF_S 1 +/** EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF : R; bitpos: [8:5]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF 0x0000000FU +#define EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF_M (EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF_V << EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF_S) +#define EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF_V 0x0000000FU +#define EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF_S 5 +/** EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF : R; bitpos: [12:9]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF 0x0000000FU +#define EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF_M (EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF_V << EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF_S) +#define EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF_V 0x0000000FU +#define EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF_S 9 +/** EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF : R; bitpos: [16:13]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF 0x0000000FU +#define EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF_M (EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF_V << EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF_S) +#define EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF_V 0x0000000FU +#define EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF_S 13 +/** EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF : R; bitpos: [20:17]; default: 0; + * ADC1 calibration data + */ +#define EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF 0x0000000FU +#define EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF_M (EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF_V << EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF_S) +#define EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF_V 0x0000000FU +#define EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF_S 17 +/** EFUSE_RESERVED_2_245 : R; bitpos: [31:21]; default: 0; + * reserved */ -#define EFUSE_SYS_DATA_PART1_7 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_7_M (EFUSE_SYS_DATA_PART1_7_V << EFUSE_SYS_DATA_PART1_7_S) -#define EFUSE_SYS_DATA_PART1_7_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_7_S 0 +#define EFUSE_RESERVED_2_245 0x000007FFU +#define EFUSE_RESERVED_2_245_M (EFUSE_RESERVED_2_245_V << EFUSE_RESERVED_2_245_S) +#define EFUSE_RESERVED_2_245_V 0x000007FFU +#define EFUSE_RESERVED_2_245_S 21 /** EFUSE_RD_USR_DATA0_REG register * Register $n of BLOCK3 (user). diff --git a/components/soc/esp32h2/include/soc/efuse_struct.h b/components/soc/esp32h2/include/soc/efuse_struct.h index 2ceb9fcefc18..a1029528ce6a 100644 --- a/components/soc/esp32h2/include/soc/efuse_struct.h +++ b/components/soc/esp32h2/include/soc/efuse_struct.h @@ -636,10 +636,18 @@ typedef union { * Disables check of blk version major */ uint32_t disable_blk_version_major:1; - /** reserved_2_136 : R; bitpos: [31:8]; default: 0; - * reserved + /** temp_calib : R; bitpos: [16:8]; default: 0; + * Temperature calibration data + */ + uint32_t temp_calib:9; + /** adc1_ave_initcode_atten0 : R; bitpos: [26:17]; default: 0; + * ADC1 calibration data */ - uint32_t reserved_2_136:24; + uint32_t adc1_ave_initcode_atten0:10; + /** adc1_ave_initcode_atten1 : R; bitpos: [31:27]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ave_initcode_atten1:5; }; uint32_t val; } efuse_rd_sys_part1_data4_reg_t; @@ -649,10 +657,22 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_5 : RO; bitpos: [31:0]; default: 0; - * Stores the fifth 32 bits of the first part of system data. + /** adc1_ave_initcode_atten1_1 : R; bitpos: [4:0]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ave_initcode_atten1_1:5; + /** adc1_ave_initcode_atten2 : R; bitpos: [14:5]; default: 0; + * ADC1 calibration data */ - uint32_t sys_data_part1_5:32; + uint32_t adc1_ave_initcode_atten2:10; + /** adc1_ave_initcode_atten3 : R; bitpos: [24:15]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ave_initcode_atten3:10; + /** adc1_hi_dout_atten0 : R; bitpos: [31:25]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_hi_dout_atten0:7; }; uint32_t val; } efuse_rd_sys_part1_data5_reg_t; @@ -662,10 +682,22 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_6 : RO; bitpos: [31:0]; default: 0; - * Stores the sixth 32 bits of the first part of system data. + /** adc1_hi_dout_atten0_1 : R; bitpos: [2:0]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_hi_dout_atten0_1:3; + /** adc1_hi_dout_atten1 : R; bitpos: [12:3]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_hi_dout_atten1:10; + /** adc1_hi_dout_atten2 : R; bitpos: [22:13]; default: 0; + * ADC1 calibration data */ - uint32_t sys_data_part1_6:32; + uint32_t adc1_hi_dout_atten2:10; + /** adc1_hi_dout_atten3 : R; bitpos: [31:23]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_hi_dout_atten3:9; }; uint32_t val; } efuse_rd_sys_part1_data6_reg_t; @@ -675,10 +707,34 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_7 : RO; bitpos: [31:0]; default: 0; - * Stores the seventh 32 bits of the first part of system data. + /** adc1_hi_dout_atten3_1 : R; bitpos: [0]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_hi_dout_atten3_1:1; + /** adc1_ch0_atten0_initcode_diff : R; bitpos: [4:1]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ch0_atten0_initcode_diff:4; + /** adc1_ch1_atten0_initcode_diff : R; bitpos: [8:5]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ch1_atten0_initcode_diff:4; + /** adc1_ch2_atten0_initcode_diff : R; bitpos: [12:9]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ch2_atten0_initcode_diff:4; + /** adc1_ch3_atten0_initcode_diff : R; bitpos: [16:13]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ch3_atten0_initcode_diff:4; + /** adc1_ch4_atten0_initcode_diff : R; bitpos: [20:17]; default: 0; + * ADC1 calibration data + */ + uint32_t adc1_ch4_atten0_initcode_diff:4; + /** reserved_2_245 : R; bitpos: [31:21]; default: 0; + * reserved */ - uint32_t sys_data_part1_7:32; + uint32_t reserved_2_245:11; }; uint32_t val; } efuse_rd_sys_part1_data7_reg_t; From 3f677222747656d38418499b31e068f80b51c607 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Wed, 11 Oct 2023 16:54:24 +0530 Subject: [PATCH 004/161] refactor(tools/test_apps): Move HAL tests for MPU to the `panic` test-app --- components/hal/test/CMakeLists.txt | 3 -- components/hal/test/test_mpu.c | 53 ------------------- tools/ci/check_copyright_ignore.txt | 1 - .../system/panic/main/include/test_panic.h | 2 + .../system/panic/main/test_app_main.c | 3 ++ .../test_apps/system/panic/main/test_panic.c | 30 +++++++++++ tools/test_apps/system/panic/pytest_panic.py | 14 +++++ 7 files changed, 49 insertions(+), 57 deletions(-) delete mode 100644 components/hal/test/CMakeLists.txt delete mode 100644 components/hal/test/test_mpu.c diff --git a/components/hal/test/CMakeLists.txt b/components/hal/test/CMakeLists.txt deleted file mode 100644 index a06f271e1a9f..000000000000 --- a/components/hal/test/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -idf_component_register(SRC_DIRS "." - PRIV_INCLUDE_DIRS "${include_dirs}" - PRIV_REQUIRES cmock test_utils) diff --git a/components/hal/test/test_mpu.c b/components/hal/test/test_mpu.c deleted file mode 100644 index dec5847807a3..000000000000 --- a/components/hal/test/test_mpu.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include "unity.h" - -#include "esp_attr.h" - -#include "hal/mpu_hal.h" - -// TODO ESP32-C3 IDF-2375 -// LL still not implemented - -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2, ESP32C6, ESP32H2) -//IDF-5058 - -volatile static int RTC_NOINIT_ATTR access = 0; - -static void trigger_illegal_access(void) -{ - access = 0; - intptr_t addr = 0x80000000; // MPU region 4 - volatile int __attribute__((unused)) val = 0; - - // Marked as an illegal access region at startup in ESP32, ESP32S2. - // Make accessible temporarily. - mpu_hal_set_region_access(4, MPU_REGION_RW); - - val = *((int*) addr); - ++access; - TEST_ASSERT_EQUAL(1, access); - printf("Sucessfully accessed location %p\r\n", (void*)addr); - - // Make access to region illegal again. - mpu_hal_set_region_access(4, MPU_REGION_ILLEGAL); - ++access; - - // Since access to region is illegal, this should fail (causing a reset), and the increment - // to access count is not performed. - val = *((int*) addr); - ++access; -} - -void check_access(void) -{ - TEST_ASSERT_EQUAL(2, access); -} - -TEST_CASE_MULTIPLE_STAGES("Can set illegal access regions", "[soc][mpu]", - trigger_illegal_access, - check_access); - -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(...) -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3) diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 3caf4d5646c0..1931e22e9c68 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -546,7 +546,6 @@ components/freertos/FreeRTOS-Kernel-SMP/timers.c components/hal/include/hal/dac_types.h components/hal/spi_slave_hal.c components/hal/spi_slave_hal_iram.c -components/hal/test/test_mpu.c components/heap/test_multi_heap_host/main.cpp components/heap/test_multi_heap_host/test_multi_heap.cpp components/idf_test/include/idf_performance.h 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 1121a626481b..6b681a4f5e63 100644 --- a/tools/test_apps/system/panic/main/include/test_panic.h +++ b/tools/test_apps/system/panic/main/include/test_panic.h @@ -53,6 +53,8 @@ void test_assert(void); void test_assert_cache_disabled(void); +void test_illegal_access(void); + #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 d97d7341731b..ac4120d7b6de 100644 --- a/tools/test_apps/system/panic/main/test_app_main.c +++ b/tools/test_apps/system/panic/main/test_app_main.c @@ -100,6 +100,9 @@ void app_main(void) HANDLE_TEST(test_name, test_ub); HANDLE_TEST(test_name, test_assert); HANDLE_TEST(test_name, test_assert_cache_disabled); +#if CONFIG_IDF_TARGET_ESP32 + HANDLE_TEST(test_name, test_illegal_access); +#endif #if CONFIG_TEST_MEMPROT diff --git a/tools/test_apps/system/panic/main/test_panic.c b/tools/test_apps/system/panic/main/test_panic.c index 9c33b74cca2b..655f9bd42aac 100644 --- a/tools/test_apps/system/panic/main/test_panic.c +++ b/tools/test_apps/system/panic/main/test_panic.c @@ -19,6 +19,8 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "hal/mpu_hal.h" + /* Test utility function */ extern void esp_restart_noos(void) __attribute__ ((noreturn)); @@ -202,3 +204,31 @@ void test_ub(void) uint8_t stuff[1] = {rand()}; printf("%d\n", stuff[rand()]); } + +/* NOTE: The following test verifies the behaviour for the + * Xtensa-specific MPU instructions (Refer WDTLB, DSYNC, WDTIB, ISYNC) + * used for memory protection. + * + * However, this test is not valid for S2 and S3, because they have PMS + * enabled on top of this, giving unpredicatable results. + */ +#if CONFIG_IDF_TARGET_ESP32 +void test_illegal_access(void) +{ + intptr_t addr = 0x80000000; // MPU region 4 + volatile int __attribute__((unused)) val = INT16_MAX; + + // Marked as an illegal access region at startup in ESP32, ESP32S2. + // Make accessible temporarily. + mpu_hal_set_region_access(4, MPU_REGION_RW); + + val = *((int*) addr); + printf("[1] val: %d at %p\n", val, (void *)addr); + + // Make access to region illegal again. + mpu_hal_set_region_access(4, MPU_REGION_ILLEGAL); + val = *((int*) addr); + // Does not reach here as device resets due to illegal access + printf("[2] val: %d at %p\n", val, (void *)addr); +} +#endif diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index e1de4a805cce..3f110d4e0180 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -822,3 +822,17 @@ def test_hw_stack_guard_cpu0(dut: PanicTestDut, config: str, test_func_name: str dut.expect_exact('Stack pointer: 0x') dut.expect(r'Stack bounds: 0x(.*) - 0x') common_test(dut, config) + + +@pytest.mark.esp32 +@pytest.mark.parametrize('config', ['panic'], indirect=True) +@pytest.mark.generic +def test_illegal_access(dut: PanicTestDut, config: str, test_func_name: str) -> None: + dut.run_test_func(test_func_name) + if dut.is_xtensa: + dut.expect(r'\[1\] val: (-?\d+) at 0x80000000', timeout=30) + dut.expect_gme('LoadProhibited') + dut.expect_reg_dump(0) + dut.expect_backtrace() + dut.expect_elf_sha256() + dut.expect_none('Guru Meditation') From 1d6f77136d2490fb210c2afc13cc00c9a38f860d Mon Sep 17 00:00:00 2001 From: zwx Date: Mon, 16 Oct 2023 17:35:52 +0800 Subject: [PATCH 005/161] feat(openthread): add config for radio statistic feature --- components/openthread/Kconfig | 8 ++++++++ .../openthread-core-esp32x-ftd-config.h | 11 +++++++++++ .../openthread-core-esp32x-mtd-config.h | 11 +++++++++++ 3 files changed, 30 insertions(+) diff --git a/components/openthread/Kconfig b/components/openthread/Kconfig index 3f0300f07c0c..d18ec6b89242 100644 --- a/components/openthread/Kconfig +++ b/components/openthread/Kconfig @@ -353,4 +353,12 @@ menu "OpenThread" Select this option to enable time synchronization feature, the devices in the same Thread network could sync to the same network time. + config OPENTHREAD_RADIO_STATS_ENABLE + bool "Enable Radio Statistics feature" + depends on OPENTHREAD_FTD || OPENTHREAD_MTD + default n + help + Select this option to enable the radio statistics feature, you can use radio command to print some radio + Statistics informations. + endmenu diff --git a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h index 0da476f5e1a7..b27bc5396344 100644 --- a/components/openthread/private_include/openthread-core-esp32x-ftd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-ftd-config.h @@ -579,4 +579,15 @@ #define OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1 #endif +/** + * @def OPENTHREAD_CONFIG_RADIO_STATS_ENABLE + * + * Set to 1 to enable support for Radio Statistics. Note that this option only works for OPENTHREAD_FTD and + * OPENTHREAD_MTD. + * + */ +#if CONFIG_OPENTHREAD_RADIO_STATS_ENABLE +#define OPENTHREAD_CONFIG_RADIO_STATS_ENABLE 1 +#endif + #define OPENTHREAD_FTD 1 diff --git a/components/openthread/private_include/openthread-core-esp32x-mtd-config.h b/components/openthread/private_include/openthread-core-esp32x-mtd-config.h index e5980244b70f..f706d364e2d7 100644 --- a/components/openthread/private_include/openthread-core-esp32x-mtd-config.h +++ b/components/openthread/private_include/openthread-core-esp32x-mtd-config.h @@ -263,4 +263,15 @@ #define OPENTHREAD_CONFIG_TIME_SYNC_ENABLE 1 #endif +/** + * @def OPENTHREAD_CONFIG_RADIO_STATS_ENABLE + * + * Set to 1 to enable support for Radio Statistics. Note that this option only works for OPENTHREAD_FTD and + * OPENTHREAD_MTD. + * + */ +#if CONFIG_OPENTHREAD_RADIO_STATS_ENABLE +#define OPENTHREAD_CONFIG_RADIO_STATS_ENABLE 1 +#endif + #define OPENTHREAD_MTD 1 From 8aba6a53e4dd7b0c1a2ab05d0510f15626a5b885 Mon Sep 17 00:00:00 2001 From: Jakob Hasse Date: Wed, 5 Jul 2023 14:45:54 +0800 Subject: [PATCH 006/161] feat(freertos): Added private PSRAM stack task creation functions * Added prvTaskCreateDynamicAffinitySetWithCaps and prvTaskCreateDynamicPinnedToCoreWithCaps which allocate the task's stack in PSRAM instead of internal RAM. These functions are only available if PSRAM is enabled. --- .../freertos_tasks_c_additions.h | 100 ++++++++++++ .../esp_private/freertos_idf_additions_priv.h | 96 +++++++++++- .../kernel/tasks/test_freertos_psram.c | 147 ++++++++++++++++++ 3 files changed, 336 insertions(+), 7 deletions(-) create mode 100644 components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c diff --git a/components/freertos/esp_additions/freertos_tasks_c_additions.h b/components/freertos/esp_additions/freertos_tasks_c_additions.h index 6640ece16860..c95512d1b6fa 100644 --- a/components/freertos/esp_additions/freertos_tasks_c_additions.h +++ b/components/freertos/esp_additions/freertos_tasks_c_additions.h @@ -6,6 +6,7 @@ #include "sdkconfig.h" #include "esp_assert.h" +#include "esp_heap_caps.h" #include "freertos/idf_additions.h" #if CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT #include "esp_private/freertos_debug.h" @@ -1236,3 +1237,102 @@ void * pvTaskGetCurrentTCBForCore( BaseType_t xCoreID ) #endif /* CONFIG_FREERTOS_DEBUG_OCDAWARE */ /*----------------------------------------------------------*/ + +/* ----------------------------------------------------- PSRAM ---------------------------------------------------- */ + +#if CONFIG_SPIRAM + + #if CONFIG_FREERTOS_SMP + BaseType_t prvTaskCreateDynamicAffinitySetWithCaps( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + UBaseType_t uxCoreAffinityMask, + UBaseType_t uxStackMemoryCaps, + TaskHandle_t * const pxCreatedTask ) + #else + BaseType_t prvTaskCreateDynamicPinnedToCoreWithCaps( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + const BaseType_t xCoreID, + UBaseType_t uxStackMemoryCaps, + TaskHandle_t * const pxCreatedTask ) + #endif /* if CONFIG_FREERTOS_SMP */ + { + TCB_t * pxNewTCB; + BaseType_t xReturn; + + StackType_t * pxStack; + + configASSERT( uxStackMemoryCaps & ( MALLOC_CAP_8BIT ) ); + configASSERT( ( uxStackMemoryCaps & MALLOC_CAP_SPIRAM ) || + ( uxStackMemoryCaps & MALLOC_CAP_INTERNAL ) ); + + /* Allocate space for the stack used by the task being created. */ + pxStack = heap_caps_malloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), uxStackMemoryCaps ); + + if( pxStack != NULL ) + { + /* Allocate space for the TCB. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + #if CONFIG_FREERTOS_USE_KERNEL_10_5_1 + { + memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); + } + #endif /* CONFIG_FREERTOS_USE_KERNEL_10_5_1 */ + + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxStack; + } + else + { + /* The stack cannot be used as the TCB has not been created. Free it. */ + heap_caps_free( pxStack ); + } + } + else + { + pxNewTCB = NULL; + } + + if( pxNewTCB != NULL ) + { + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + * task was created dynamically in case it is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + #if CONFIG_FREERTOS_SMP + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); + #if ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) + { + /* Set the task's affinity before scheduling it */ + pxNewTCB->uxCoreAffinityMask = uxCoreAffinityMask; + } + #endif + #else + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL, xCoreID ); + #endif + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; + } + +#endif // SPIRAM +/*----------------------------------------------------------*/ diff --git a/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h b/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h index 4f38f5ec997d..596b313c4481 100644 --- a/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h +++ b/components/freertos/esp_additions/include/esp_private/freertos_idf_additions_priv.h @@ -57,16 +57,16 @@ #define prvENTER_CRITICAL_OR_SUSPEND_ALL( x ) ( { vTaskSuspendAll(); ( void ) ( x ); } ) #define prvEXIT_CRITICAL_OR_RESUME_ALL( x ) xTaskResumeAll() - #define prvENTER_CRITICAL_OR_MASK_ISR( pxLock, uxInterruptStatus ) \ + #define prvENTER_CRITICAL_OR_MASK_ISR( pxLock, uxInterruptStatus ) \ + { \ + ( uxInterruptStatus ) = portSET_INTERRUPT_MASK_FROM_ISR(); \ + ( void ) ( pxLock ); \ + } + #define prvEXIT_CRITICAL_OR_UNMASK_ISR( pxLock, uxInterruptStatus ) \ { \ - ( uxInterruptStatus ) = portSET_INTERRUPT_MASK_FROM_ISR(); \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( ( uxInterruptStatus ) ); \ ( void ) ( pxLock ); \ } - #define prvEXIT_CRITICAL_OR_UNMASK_ISR( pxLock, uxInterruptStatus ) \ - { \ - portCLEAR_INTERRUPT_MASK_FROM_ISR( ( uxInterruptStatus ) ); \ - ( void ) ( pxLock ); \ - } #endif /* ( !CONFIG_FREERTOS_SMP && ( configNUM_CORES == 1 ) ) */ @@ -210,6 +210,88 @@ #endif /* INCLUDE_vTaskPrioritySet == 1 */ +#if CONFIG_SPIRAM + +/** + * Create a new task with stack having the desired heap capabilities and add it to the + * list of tasks that are ready to run. + * + * @note: This is an internal function and meant for usage by pthread only. + * @note: Tasks with stacks not having the default heap capabilities for FreeRTOS may + * not be able to run while flash cache is disabled. + * This is the case if, e.g., any task on the chip is reading or writing + * flash memory. + * + * @note: The difference between this function and xTaskCreatePinnedToCoreWithCaps() + * is the following: + * * A FreeRTOS task created by this function is deleted by normal FreeRTOS deletion functions, + * i.e., vTaskDelete(). + * * A FreeRTOS task created by this function can delete itself. + * + * This function behaves like xTaskCreateAffinitySet(), except that it allocates + * the stack from the heap with the desired heap capabilities. + * + * @param pxTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of bytes. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param xCoreID (only IDF SMP FreeRTOS) + * The core to which the task is pinned to, or tskNO_AFFINITY if + * the task can run on any core. + * + * @param uxCoreAffinityMask (only Amazon SMP FreeRTOS) + * A bitwise value that indicates the cores on which the task can run. + * Cores are numbered from 0 to configNUM_CORES - 1. + * For example, to ensure that a task can run on core 0 and core 1, set + * uxCoreAffinityMask to 0x03. Note that only one of the cores will be used when + * using the IDF SMP version of FreeRTOS instead of Amazon FreeRTOS SMP. + * + * @param uxStackMemoryCaps The heap caps bitfield describing the memory capabilities to + * be used for stack memory. Currently, the capabilities have to include MALLOC_CAP_8BIT + * and one of the following: MALLOC_CAP_SPIRAM, MALLOC_CAP_INTERNAL. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + */ + #if CONFIG_FREERTOS_SMP + BaseType_t prvTaskCreateDynamicAffinitySetWithCaps( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + UBaseType_t uxCoreAffinityMask, + UBaseType_t uxStackMemoryCaps, + TaskHandle_t * const pxCreatedTask ); + #else + BaseType_t prvTaskCreateDynamicPinnedToCoreWithCaps( TaskFunction_t pxTaskCode, + const char * const pcName, + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + const BaseType_t xCoreID, + UBaseType_t uxStackMemoryCaps, + TaskHandle_t * const pxCreatedTask ); + #endif // CONFIG_FREERTOS_SMP + +#endif // CONFIG_SPIRAM + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c new file mode 100644 index 000000000000..93919f676cbd --- /dev/null +++ b/components/freertos/test_apps/freertos/kernel/tasks/test_freertos_psram.c @@ -0,0 +1,147 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/idf_additions.h" +#include "esp_private/freertos_idf_additions_priv.h" +#include "unity.h" +#include "esp_heap_caps.h" +#include "unity_test_runner.h" +#include "memory_checks.h" + +#define UNITY_FREERTOS_PRIORITY 5 + +#if CONFIG_SPIRAM + +static void task_delete_itself(void *arg) +{ + printf("starting task\n"); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + xTaskNotifyGive((TaskHandle_t)arg); + vTaskDelete(NULL); +} + +static void task_should_never_run(void *arg) +{ + printf("ERROR: this task should not run, aborting\n"); + abort(); +} + +static BaseType_t create_task(TaskFunction_t function, + size_t stack_size, + void *task_arg, + int core_num, + UBaseType_t heap_caps, + TaskHandle_t *task_handle) +{ +#if CONFIG_FREERTOS_SMP + UBaseType_t core_affinity_mask = (core_num == -1) ? tskNO_AFFINITY : 1 << core_num; + return prvTaskCreateDynamicAffinitySetWithCaps(function, + "self_delete", + stack_size, + task_arg, + UNITY_FREERTOS_PRIORITY + 1, + core_affinity_mask, + heap_caps, + task_handle); +#else + const BaseType_t task_core_num = (core_num == -1) ? tskNO_AFFINITY : core_num; + return prvTaskCreateDynamicPinnedToCoreWithCaps(function, + "self_delete", + stack_size, + task_arg, + UNITY_FREERTOS_PRIORITY + 1, + task_core_num, + heap_caps, + task_handle); +#endif +} + +TEST_CASE("Out of memory failure", "[freertos][psram]") +{ + TaskHandle_t task_handle = NULL; + const size_t STACK_SIZE = 0x80000000; // far larger than the virtual address space on ESP32 + UBaseType_t HEAP_CAPS = (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + + BaseType_t result = create_task(task_should_never_run, + STACK_SIZE, + (void *)xTaskGetCurrentTaskHandle(), + -1, + HEAP_CAPS, + &task_handle); + TEST_ASSERT_EQUAL(errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY, result); + (void)task_handle; +} + +TEST_CASE("Task with stack memory in PSRAM", "[freertos][psram]") +{ + TaskHandle_t task_handle = NULL; + const size_t STACK_SIZE = 0x80000; // value is too large for any internal RAM on current chips + UBaseType_t HEAP_CAPS = (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + + BaseType_t result = create_task(task_delete_itself, + STACK_SIZE, + (void *)xTaskGetCurrentTaskHandle(), + -1, + HEAP_CAPS, + &task_handle); + TEST_ASSERT_EQUAL(pdPASS, result); + + // synchronize with the task to make sure we don't return too early, thus giving it enough time + // to delete itself and giving the idle task time to clean up memory (see delay in tearDown()). + xTaskNotifyGive(task_handle); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); +} + +#if !CONFIG_FREERTOS_UNICORE +typedef struct { + size_t recorded_core_num; + TaskHandle_t parent_handle; +} report_corenum_info_t; + +static void task_report_corenum(void *arg) +{ + report_corenum_info_t *info = (report_corenum_info_t*) arg; + info->recorded_core_num = xTaskGetAffinity(NULL); + xTaskNotifyGive(info->parent_handle); + vTaskSuspend(NULL); +} + +/** + * This test (roughly) verifies that xTaskCreateWithCapsAffinitySet() pins a task to the correct core. + */ +TEST_CASE("Task on specific core works", "[freertos][psram]") +{ + const size_t STACK_SIZE = 0x1000; + report_corenum_info_t corenum_info; + TaskHandle_t task_handle; + + for (int corenum = 0; corenum < CONFIG_SOC_CPU_CORES_NUM; corenum++) { + corenum_info.recorded_core_num = 0xFFFFFFFF; + corenum_info.parent_handle = xTaskGetCurrentTaskHandle(); + UBaseType_t HEAP_CAPS = (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT); + BaseType_t result = create_task(task_report_corenum, + STACK_SIZE, + (void *) &(corenum_info), + corenum, + HEAP_CAPS, + &task_handle); + + TEST_ASSERT_EQUAL(pdPASS, result); + + // Wait for the created task to finish its job + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + TEST_ASSERT_EQUAL((size_t) corenum, corenum_info.recorded_core_num); + + vTaskDelete(task_handle); + } +} +#endif // !CONFIG_FREERTOS_UNICORE + +#endif // SPIRAM From 4f4f32ecf2062ede537d3892dd6983b39c0b38b0 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Wed, 18 Oct 2023 14:39:33 +0800 Subject: [PATCH 007/161] ci(system): restrict number of system examples built in regular pipelines --- examples/system/.build-test-rules.yml | 140 +++++++++++++----- examples/system/esp_timer/README.md | 4 +- examples/system/eventfd/pytest_eventfd.py | 8 +- examples/system/heap_task_tracking/README.md | 4 +- examples/system/select/README.md | 4 +- examples/system/select/pytest_select.py | 3 +- .../task_watchdog/pytest_task_watchdog.py | 8 +- 7 files changed, 115 insertions(+), 56 deletions(-) diff --git a/examples/system/.build-test-rules.yml b/examples/system/.build-test-rules.yml index 84e57b7bc907..897380b8bc05 100644 --- a/examples/system/.build-test-rules.yml +++ b/examples/system/.build-test-rules.yml @@ -6,6 +6,10 @@ examples/system/app_trace_basic: temporary: true reason: target esp32c6, esp32h2 is not supported yet +examples/system/base_mac_address: + depends_components: + - esp_hw_support + examples/system/console/advanced: disable: - if: IDF_TARGET == "esp32p4" @@ -14,10 +18,16 @@ examples/system/console/advanced: disable_test: - if: IDF_TARGET not in ["esp32", "esp32c3"] reason: Sufficient to run this app on one chip with each architecture + depends_components: + - console + - vfs examples/system/console/advanced_usb_cdc: disable: - if: SOC_USB_PERIPH_NUM == 0 + depends_components: + - console + - vfs examples/system/console/basic: disable: @@ -27,6 +37,9 @@ examples/system/console/basic: disable_test: - if: IDF_TARGET not in ["esp32", "esp32c3"] reason: Sufficient to run this app on one chip with each architecture + depends_components: + - console + - vfs examples/system/deep_sleep: disable: @@ -40,15 +53,31 @@ examples/system/deep_sleep_wake_stub: temporary: true reason: target(s) is not supported yet +examples/system/efuse: + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - efuse + - bootloader_support + examples/system/esp_timer: disable: - - if: IDF_TARGET in ["esp32c6", "esp32h2", "esp32p4"] + - if: IDF_TARGET in ["esp32p4"] temporary: true reason: target(s) is not supported yet # TODO: IDF-7529 + depends_components: + - esp_timer examples/system/eventfd: + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient disable: - if: SOC_GPTIMER_SUPPORTED != 1 + depends_components: + - vfs + - driver examples/system/flash_suspend: enable: @@ -56,6 +85,13 @@ examples/system/flash_suspend: temporary: true reason: the other targets are not tested yet +examples/system/freertos: + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - freertos + examples/system/gcov: disable_test: - if: IDF_TARGET != "esp32" @@ -69,28 +105,34 @@ examples/system/gdbstub: reason: not supported yet #TODO: IDF-7510 examples/system/heap_task_tracking: - disable: - - if: IDF_TARGET == "esp32c2" or IDF_TARGET == "esp32h2" - temporary: true - reason: target esp32c2, esp32h2 is not supported yet + enable: + - if: IDF_TARGET == "esp32c3" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - heap examples/system/himem: enable: - if: IDF_TARGET == "esp32" - temporary: true - reason: the other targets are not tested yet + reason: Feature is only needed/supported on ESP32 examples/system/ipc/ipc_isr/riscv: enable: - - if: IDF_TARGET in ["esp32p4"] - temporary: true + - if: IDF_TARGET_ARCH_RISCV == 1 and ESP_IPC_ISR_ENABLE == 1 reason: The test is intended only for multi-core chips + disable_test: + - if: IDF_TARGET == "esp32p4" + temporary: true + reason: lack of runners + depends_components: + - esp_system examples/system/ipc/ipc_isr/xtensa: enable: - - if: IDF_TARGET in ["esp32", "esp32s3"] - temporary: true + - if: IDF_TARGET_ARCH_XTENSA == 1 and ESP_IPC_ISR_ENABLE == 1 reason: The test is intended only for multi-core chips + depends_components: + - esp_system examples/system/light_sleep: disable: @@ -147,21 +189,23 @@ examples/system/ota/simple_ota_example: examples/system/perfmon: enable: - if: IDF_TARGET in ["esp32", "esp32s2", "esp32s3"] - temporary: true - reason: the other targets are not tested yet + reason: xtensa only feature + depends_components: + - perfmon + +examples/system/pthread: + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - pthread examples/system/select: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet - disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3"] - temporary: true - reason: lack of runners - - if: IDF_TARGET == "esp32c6" or IDF_TARGET == "esp32h2" - temporary: true - reason: target esp32c6 is not supported yet + enable: + - if: IDF_TARGET == "esp32c3" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - vfs examples/system/sysview_tracing: disable: @@ -186,72 +230,100 @@ examples/system/sysview_tracing_heap_log: reason: lack of runners examples/system/task_watchdog: - disable_test: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - esp_system examples/system/ulp/lp_core/gpio: enable: - if: SOC_LP_CORE_SUPPORTED == 1 + depends_components: + - ulp examples/system/ulp/lp_core/lp_i2c: enable: - if: SOC_LP_I2C_SUPPORTED == 1 + depends_components: + - ulp examples/system/ulp/lp_core/lp_uart/lp_uart_echo: disable: - if: SOC_ULP_LP_UART_SUPPORTED != 1 + depends_components: + - ulp examples/system/ulp/lp_core/lp_uart/lp_uart_print: disable: - if: SOC_ULP_LP_UART_SUPPORTED != 1 + depends_components: + - ulp examples/system/ulp/ulp_fsm/ulp: disable: - if: SOC_ULP_FSM_SUPPORTED != 1 + depends_components: + - ulp examples/system/ulp/ulp_fsm/ulp_adc: enable: - if: IDF_TARGET in ["esp32", "esp32s3"] temporary: true reason: the other targets are not tested yet + depends_components: + - ulp examples/system/ulp/ulp_riscv/adc: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 - temporary: true - reason: the other targets are not tested yet + depends_components: + - ulp examples/system/ulp/ulp_riscv/ds18b20_onewire: enable: - if: IDF_TARGET == "esp32s2" temporary: true reason: the other targets are not tested yet + depends_components: + - ulp examples/system/ulp/ulp_riscv/gpio: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 - temporary: true - reason: the other targets are not tested yet + depends_components: + - ulp examples/system/ulp/ulp_riscv/gpio_interrupt: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 - temporary: true - reason: the other targets are not tested yet + depends_components: + - ulp examples/system/ulp/ulp_riscv/i2c: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 + depends_components: + - ulp examples/system/ulp/ulp_riscv/touch: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 + depends_components: + - ulp examples/system/ulp/ulp_riscv/uart_print: enable: - if: SOC_RISCV_COPROC_SUPPORTED == 1 + depends_components: + - ulp + +examples/system/unit_test/: + enable: + - if: IDF_TARGET == "esp32" or (NIGHTLY_RUN == "1" and IDF_TARGET != "linux") + reason: no target specific functionality, testing on a single target is sufficient + depends_components: + - unity examples/system/xip_from_psram: enable: diff --git a/examples/system/esp_timer/README.md b/examples/system/esp_timer/README.md index 6a6a075bf6f7..634694934873 100644 --- a/examples/system/esp_timer/README.md +++ b/examples/system/esp_timer/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # High Resolution Timer Example (`esp_timer`) diff --git a/examples/system/eventfd/pytest_eventfd.py b/examples/system/eventfd/pytest_eventfd.py index 3bdb1d5bccde..8c0aa6a10425 100644 --- a/examples/system/eventfd/pytest_eventfd.py +++ b/examples/system/eventfd/pytest_eventfd.py @@ -8,13 +8,7 @@ from pytest_embedded import Dut -@pytest.mark.esp32 -@pytest.mark.esp32c2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 +@pytest.mark.supported_targets @pytest.mark.generic def test_eventfd(dut: Dut) -> None: diff --git a/examples/system/heap_task_tracking/README.md b/examples/system/heap_task_tracking/README.md index 5113b3ea4615..755d754fc57d 100644 --- a/examples/system/heap_task_tracking/README.md +++ b/examples/system/heap_task_tracking/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Heap Task Tracking Example diff --git a/examples/system/select/README.md b/examples/system/select/README.md index 4518f097bb9c..3abeb838b30a 100644 --- a/examples/system/select/README.md +++ b/examples/system/select/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Synchronous I/O multiplexing example diff --git a/examples/system/select/pytest_select.py b/examples/system/select/pytest_select.py index 3cefe3eb15b8..367739d8eb79 100644 --- a/examples/system/select/pytest_select.py +++ b/examples/system/select/pytest_select.py @@ -20,8 +20,7 @@ def get_uart_msgs(i: int) -> List[str]: 'uart_select_example: {} bytes were received through UART1: {}'.format(len(msg), msg)] -@pytest.mark.esp32 -@pytest.mark.esp32c3 +@pytest.mark.supported_targets @pytest.mark.generic def test_examples_select(dut: Dut) -> None: diff --git a/examples/system/task_watchdog/pytest_task_watchdog.py b/examples/system/task_watchdog/pytest_task_watchdog.py index 91028453cedf..0627967675c3 100644 --- a/examples/system/task_watchdog/pytest_task_watchdog.py +++ b/examples/system/task_watchdog/pytest_task_watchdog.py @@ -5,13 +5,7 @@ from pytest_embedded import Dut -# IDF-5055 -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 +@pytest.mark.supported_targets @pytest.mark.generic def test_task_watchdog(dut: Dut) -> None: From ba3d23342dde2ab3a4b747314d55afa2cd680764 Mon Sep 17 00:00:00 2001 From: Fu Hanxi Date: Thu, 19 Oct 2023 11:53:18 +0200 Subject: [PATCH 008/161] ci: improve check pylint get files command --- .gitlab/ci/static-code-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/ci/static-code-analysis.yml b/.gitlab/ci/static-code-analysis.yml index 7ad423e62c05..0ceb6d7ca466 100644 --- a/.gitlab/ci/static-code-analysis.yml +++ b/.gitlab/ci/static-code-analysis.yml @@ -30,7 +30,7 @@ check_pylint: if [ -n "$CI_MERGE_REQUEST_IID" ]; then export files=$(python ${CI_PROJECT_DIR}/tools/ci/ci_get_mr_info.py files ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} | grep ".py$"); else - export files=$(find . -iname "*.py" -print); + export files=$(git ls-files "*.py" | xargs); fi - if [ -z "$files" ]; then echo "No python files found"; exit 0; fi - run_cmd pylint --exit-zero --load-plugins=pylint_gitlab --output-format=gitlab-codeclimate:pylint.json $files From 9b8aa6a792055ff41d05e7634b69178accd0ed29 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Sat, 21 Oct 2023 14:43:46 +0800 Subject: [PATCH 009/161] ci(build_test): add known-failure check --- .gitlab/ci/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab/ci/build.yml b/.gitlab/ci/build.yml index 8103b00d85d8..6ac241a2444e 100644 --- a/.gitlab/ci/build.yml +++ b/.gitlab/ci/build.yml @@ -516,8 +516,10 @@ build_clang_test_apps_esp32c6: script: - ${IDF_PATH}/tools/ci/test_configure_ci_environment.sh - cd ${IDF_PATH}/tools/test_build_system + - retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases - pytest --parallel-count ${CI_NODE_TOTAL:-1} --parallel-index ${CI_NODE_INDEX:-1} --work-dir ${CI_PROJECT_DIR}/test_build_system --junitxml=${CI_PROJECT_DIR}/XUNIT_RESULT.xml + --ignore-result-files known_failure_cases/known_failure_cases.txt pytest_build_system: extends: .test_build_system_template From e151184da7ab2e87087f3c6a23ab886b65bb9486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20M=C3=BAdry?= Date: Tue, 17 Oct 2023 16:13:32 +0200 Subject: [PATCH 010/161] refactor: Remove -Wno-format from storage related components --- components/esp_partition/CMakeLists.txt | 2 - components/esp_partition/partition_linux.c | 31 ++++---- components/esp_partition/test/CMakeLists.txt | 1 - components/nvs_flash/CMakeLists.txt | 2 - components/nvs_flash/src/nvs_page.cpp | 9 ++- components/sdmmc/CMakeLists.txt | 2 - components/sdmmc/sdmmc_cmd.c | 17 ++--- components/sdmmc/sdmmc_common.c | 11 +-- components/sdmmc/sdmmc_io.c | 5 +- components/sdmmc/sdmmc_mmc.c | 5 +- components/sdmmc/sdmmc_sd.c | 17 ++--- components/sdmmc/test/CMakeLists.txt | 1 - components/spi_flash/CMakeLists.txt | 1 - components/spi_flash/test/CMakeLists.txt | 1 - .../flash_encryption/main/CMakeLists.txt | 1 - .../main/test_flash_encryption.c | 17 ++--- components/wear_levelling/CMakeLists.txt | 2 - components/wear_levelling/Partition.cpp | 7 +- components/wear_levelling/SPI_Flash.cpp | 19 ++--- components/wear_levelling/WL_Ext_Perf.cpp | 9 +-- components/wear_levelling/WL_Ext_Safe.cpp | 11 +-- components/wear_levelling/WL_Flash.cpp | 71 ++++++++++--------- .../test_apps/main/CMakeLists.txt | 1 - .../wear_levelling/test_apps/main/test_wl.c | 15 ++-- components/wear_levelling/wear_levelling.cpp | 8 +-- 25 files changed, 135 insertions(+), 131 deletions(-) diff --git a/components/esp_partition/CMakeLists.txt b/components/esp_partition/CMakeLists.txt index 6610d7a4d1e4..1f0ecb38fbb3 100644 --- a/components/esp_partition/CMakeLists.txt +++ b/components/esp_partition/CMakeLists.txt @@ -41,5 +41,3 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU") set_property(SOURCE ${cache_srcs} APPEND_STRING PROPERTY COMPILE_FLAGS " -fno-inline-small-functions -fno-inline-functions-called-once") endif() - -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/esp_partition/partition_linux.c b/components/esp_partition/partition_linux.c index cf3e86491e7f..9303498282e5 100644 --- a/components/esp_partition/partition_linux.c +++ b/components/esp_partition/partition_linux.c @@ -7,6 +7,7 @@ #include #include #include +#include #if __has_include() // for strlcpy #include @@ -106,8 +107,8 @@ esp_err_t esp_partition_file_mmap(const uint8_t **part_desc_addr_start) if (strlen(s_esp_partition_file_mmap_ctrl_input.flash_file_name) > 0) { // Open existing file. If size or partition table file were specified, raise errors if (s_esp_partition_file_mmap_ctrl_input.flash_file_size > 0) { - ESP_LOGE(TAG, "Flash emulation file size: %u was specified while together with the file name: %s (illegal). Use file size = 0", - s_esp_partition_file_mmap_ctrl_input.flash_file_size, + ESP_LOGE(TAG, "Flash emulation file size: %" PRIu32" was specified while together with the file name: %s (illegal). Use file size = 0", + (uint32_t) s_esp_partition_file_mmap_ctrl_input.flash_file_size, s_esp_partition_file_mmap_ctrl_input.flash_file_name); return ESP_ERR_INVALID_ARG; } @@ -133,9 +134,9 @@ esp_err_t esp_partition_file_mmap(const uint8_t **part_desc_addr_start) // conflicting input if (has_partfile != has_len) { - ESP_LOGE(TAG, "Invalid combination of Partition file name: %s flash file size: %u was specified. Use either both parameters or none.", + ESP_LOGE(TAG, "Invalid combination of Partition file name: %s flash file size: %" PRIu32 " was specified. Use either both parameters or none.", s_esp_partition_file_mmap_ctrl_input.partition_file_name, - s_esp_partition_file_mmap_ctrl_input.flash_file_size); + (uint32_t) s_esp_partition_file_mmap_ctrl_input.flash_file_size); return ESP_ERR_INVALID_ARG; } @@ -211,7 +212,7 @@ esp_err_t esp_partition_file_mmap(const uint8_t **part_desc_addr_start) break; } - ESP_LOGV(TAG, "SPIFLASH memory emulation file created: %s (size: %d B)", s_esp_partition_file_mmap_ctrl_act.flash_file_name, s_esp_partition_file_mmap_ctrl_act.flash_file_size); + ESP_LOGV(TAG, "SPIFLASH memory emulation file created: %s (size: %" PRIu32 " B)", s_esp_partition_file_mmap_ctrl_act.flash_file_name, (uint32_t) s_esp_partition_file_mmap_ctrl_act.flash_file_size); // create memory-mapping for the flash holder file if ((s_spiflash_mem_file_buf = mmap(NULL, s_esp_partition_file_mmap_ctrl_act.flash_file_size, PROT_READ | PROT_WRITE, MAP_SHARED, s_spiflash_mem_file_fd, 0)) == MAP_FAILED) { @@ -242,10 +243,10 @@ esp_err_t esp_partition_file_mmap(const uint8_t **part_desc_addr_start) // check whether partition table fits into the memory mapped file if (partition_table_file_size + ESP_PARTITION_TABLE_OFFSET > s_esp_partition_file_mmap_ctrl_act.flash_file_size) { - ESP_LOGE(TAG, "Flash file: %s (size: %d B) cannot hold partition table requiring %d B", + ESP_LOGE(TAG, "Flash file: %s (size: %" PRIu32 " B) cannot hold partition table requiring %d B", s_esp_partition_file_mmap_ctrl_act.flash_file_name, - s_esp_partition_file_mmap_ctrl_act.flash_file_size, - partition_table_file_size + ESP_PARTITION_TABLE_OFFSET); + (uint32_t) s_esp_partition_file_mmap_ctrl_act.flash_file_size, + (int) (partition_table_file_size + ESP_PARTITION_TABLE_OFFSET)); ret = ESP_ERR_INVALID_SIZE; break; } @@ -294,9 +295,9 @@ esp_err_t esp_partition_file_mmap(const uint8_t **part_desc_addr_start) ESP_LOGV(TAG, " label: %s", p_part_item->label); ESP_LOGV(TAG, " type: %s", esp_partition_type_to_str(p_part_item->type)); ESP_LOGV(TAG, " subtype: %s", esp_partition_subtype_to_str(p_part_item->type, p_part_item->subtype)); - ESP_LOGV(TAG, " offset: 0x%08X", p_part_item->pos.offset); - ESP_LOGV(TAG, " size: %d", p_part_item->pos.size); - ESP_LOGV(TAG, " flags: %d", p_part_item->flags); + ESP_LOGV(TAG, " offset: 0x%08" PRIX32, (uint32_t) p_part_item->pos.offset); + ESP_LOGV(TAG, " size: %" PRIu32, (uint32_t) p_part_item->pos.size); + ESP_LOGV(TAG, " flags: %" PRIu32, (uint32_t) p_part_item->flags); part_ptr += sizeof(esp_partition_info_t); } @@ -383,7 +384,7 @@ esp_err_t esp_partition_write(const esp_partition_t *partition, size_t dst_offse } void *dst_addr = s_spiflash_mem_file_buf + partition->address + dst_offset; - ESP_LOGV(TAG, "esp_partition_write(): partition=%s dst_offset=%zu src=%p size=%zu (real dst address: %p)", partition->label, dst_offset, src, size, dst_addr); + ESP_LOGV(TAG, "esp_partition_write(): partition=%s dst_offset=%" PRIu32 " src=%p size=%" PRIu32 " (real dst address: %p)", partition->label, (uint32_t) dst_offset, src, (uint32_t) size, dst_addr); // local size, can be modified by the write hook in case of simulated power-off size_t new_size = size; @@ -428,7 +429,7 @@ esp_err_t esp_partition_read(const esp_partition_t *partition, size_t src_offset } void *src_addr = s_spiflash_mem_file_buf + partition->address + src_offset; - ESP_LOGV(TAG, "esp_partition_read(): partition=%s src_offset=%zu dst=%p size=%zu (real src address: %p)", partition->label, src_offset, dst, size, src_addr); + ESP_LOGV(TAG, "esp_partition_read(): partition=%s src_offset=%" PRIu32 " dst=%p size=%" PRIu32 " (real src address: %p)", partition->label, (uint32_t) src_offset, dst, (uint32_t) size, src_addr); memcpy(dst, src_addr, size); @@ -464,7 +465,7 @@ esp_err_t esp_partition_erase_range(const esp_partition_t *partition, size_t off } void *target_addr = s_spiflash_mem_file_buf + partition->address + offset; - ESP_LOGV(TAG, "esp_partition_erase_range(): partition=%s offset=%zu size=%zu (real target address: %p)", partition->label, offset, size, target_addr); + ESP_LOGV(TAG, "esp_partition_erase_range(): partition=%s offset=%" PRIu32 " size=%" PRIu32 " (real target address: %p)", partition->label, (uint32_t) offset, (uint32_t) size, target_addr); // local size to be potentially updated by the hook in case of power-off event size_t new_size = size; @@ -496,7 +497,7 @@ esp_err_t esp_partition_mmap(const esp_partition_t *partition, size_t offset, si esp_partition_mmap_memory_t memory, const void **out_ptr, esp_partition_mmap_handle_t *out_handle) { - ESP_LOGV(TAG, "esp_partition_mmap(): partition=%s offset=%zu size=%zu", partition->label, offset, size); + ESP_LOGV(TAG, "esp_partition_mmap(): partition=%s offset=%" PRIu32 " size=%" PRIu32 "", partition->label, (uint32_t) offset, (uint32_t) size); assert(partition != NULL); if (offset > partition->size) { diff --git a/components/esp_partition/test/CMakeLists.txt b/components/esp_partition/test/CMakeLists.txt index 56c4de4a73e5..6451ab5bd65f 100644 --- a/components/esp_partition/test/CMakeLists.txt +++ b/components/esp_partition/test/CMakeLists.txt @@ -1,4 +1,3 @@ idf_component_register(SRC_DIRS "." PRIV_INCLUDE_DIRS "." PRIV_REQUIRES test_utils esp_partition esp_system app_update bootloader_support spi_flash) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/nvs_flash/CMakeLists.txt b/components/nvs_flash/CMakeLists.txt index c0d9421f9fb8..d54703ce9b7d 100644 --- a/components/nvs_flash/CMakeLists.txt +++ b/components/nvs_flash/CMakeLists.txt @@ -40,5 +40,3 @@ else() target_sources(${COMPONENT_LIB} PRIVATE "src/nvs_encrypted_partition.cpp") target_link_libraries(${COMPONENT_LIB} PRIVATE idf::mbedtls) endif() - -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index b69bcfbdaf3f..5fcf39c9650c 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "nvs_page.hpp" +#include #include #include #include @@ -1063,7 +1064,8 @@ const char* Page::pageStateToName(PageState ps) void Page::debugDump() const { - printf("state=%x (%s) addr=%x seq=%d\nfirstUsed=%d nextFree=%d used=%d erased=%d\n", (uint32_t) mState, pageStateToName(mState), mBaseAddress, mSeqNumber, static_cast(mFirstUsedEntry), static_cast(mNextFreeEntry), mUsedEntryCount, mErasedEntryCount); + printf("state=%" PRIx32 " (%s) addr=%" PRIx32 " seq=%" PRIu32 "\nfirstUsed=%" PRIu32 " nextFree=%" PRIu32 " used=%" PRIu16 " erased=%" PRIu16 "\n", + static_cast(mState), pageStateToName(mState), mBaseAddress, mSeqNumber, static_cast(mFirstUsedEntry), static_cast(mNextFreeEntry), mUsedEntryCount, mErasedEntryCount); size_t skip = 0; for (size_t i = 0; i < ENTRY_COUNT; ++i) { printf("%3d: ", static_cast(i)); @@ -1080,7 +1082,8 @@ void Page::debugDump() const Item item; readEntry(i, item); if (skip == 0) { - printf("W ns=%2u type=%2u span=%3u key=\"%s\" chunkIdx=%d len=%d\n", item.nsIndex, static_cast(item.datatype), item.span, item.key, item.chunkIndex, (item.span != 1)?((int)item.varLength.dataSize):-1); + printf("W ns=%2" PRIu8 " type=%2" PRIu8 " span=%3" PRIu8 " key=\"%s\" chunkIdx=%" PRIu8 " len=%" PRIi32 "\n", + item.nsIndex, static_cast(item.datatype), item.span, item.key, item.chunkIndex, (item.span != 1)?(static_cast(item.varLength.dataSize)):(-1)); if (item.span > 0 && item.span <= ENTRY_COUNT - i) { skip = item.span - 1; } else { diff --git a/components/sdmmc/CMakeLists.txt b/components/sdmmc/CMakeLists.txt index da638db5771b..0b65cf19b5d5 100644 --- a/components/sdmmc/CMakeLists.txt +++ b/components/sdmmc/CMakeLists.txt @@ -13,5 +13,3 @@ idf_component_register(SRCS "sdmmc_cmd.c" INCLUDE_DIRS include REQUIRES driver PRIV_REQUIRES soc esp_timer) - -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/sdmmc/sdmmc_cmd.c b/components/sdmmc/sdmmc_cmd.c index 4b626129ccd9..1a3e331d542d 100644 --- a/components/sdmmc/sdmmc_cmd.c +++ b/components/sdmmc/sdmmc_cmd.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include "esp_timer.h" #include "sdmmc_common.h" @@ -19,15 +20,15 @@ esp_err_t sdmmc_send_cmd(sdmmc_card_t* card, sdmmc_command_t* cmd) } int slot = card->host.slot; - ESP_LOGV(TAG, "sending cmd slot=%d op=%d arg=%x flags=%x data=%p blklen=%d datalen=%d timeout=%d", - slot, cmd->opcode, cmd->arg, cmd->flags, cmd->data, cmd->blklen, cmd->datalen, cmd->timeout_ms); + ESP_LOGV(TAG, "sending cmd slot=%d op=%" PRIu32 " arg=%" PRIx32 " flags=%x data=%p blklen=%" PRIu32 " datalen=%" PRIu32 " timeout=%" PRIu32, + slot, cmd->opcode, cmd->arg, cmd->flags, cmd->data, (uint32_t) cmd->blklen, (uint32_t) cmd->datalen, cmd->timeout_ms); esp_err_t err = (*card->host.do_transaction)(slot, cmd); if (err != 0) { - ESP_LOGD(TAG, "cmd=%d, sdmmc_req_run returned 0x%x", cmd->opcode, err); + ESP_LOGD(TAG, "cmd=%" PRIu32 ", sdmmc_req_run returned 0x%x", cmd->opcode, err); return err; } int state = MMC_R1_CURRENT_STATE(cmd->response); - ESP_LOGV(TAG, "cmd response %08x %08x %08x %08x err=0x%x state=%d", + ESP_LOGV(TAG, "cmd response %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " %08" PRIx32 " err=0x%x state=%d", cmd->response[0], cmd->response[1], cmd->response[2], @@ -481,7 +482,7 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, return err; } if (++count % 16 == 0) { - ESP_LOGV(TAG, "waiting for card to become ready (%d)", count); + ESP_LOGV(TAG, "waiting for card to become ready (%" PRIu32 ")", (uint32_t) count); } } /* SPI mode: although card busy indication is based on the busy token, @@ -496,12 +497,12 @@ esp_err_t sdmmc_write_sectors_dma(sdmmc_card_t* card, const void* src, return err; } if (status & SD_SPI_R2_CARD_LOCKED) { - ESP_LOGE(TAG, "%s: write failed, card is locked: r2=0x%04x", + ESP_LOGE(TAG, "%s: write failed, card is locked: r2=0x%04" PRIx32, __func__, status); return ESP_ERR_INVALID_STATE; } if (status != 0) { - ESP_LOGE(TAG, "%s: card status indicates an error after write operation: r2=0x%04x", + ESP_LOGE(TAG, "%s: card status indicates an error after write operation: r2=0x%04" PRIx32, __func__, status); return ESP_ERR_INVALID_RESPONSE; } @@ -687,7 +688,7 @@ esp_err_t sdmmc_erase_sectors(sdmmc_card_t* card, size_t start_sector, return err; } if (status != 0) { - ESP_LOGE(TAG, "%s: card status indicates an error after erase operation: r2=0x%04x", + ESP_LOGE(TAG, "%s: card status indicates an error after erase operation: r2=0x%04" PRIx32, __func__, status); return ESP_ERR_INVALID_RESPONSE; } diff --git a/components/sdmmc/sdmmc_common.c b/components/sdmmc/sdmmc_common.c index f55a48f6ba90..b57e67ef1a4d 100644 --- a/components/sdmmc/sdmmc_common.c +++ b/components/sdmmc/sdmmc_common.c @@ -15,6 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "sdmmc_common.h" static const char* TAG = "sdmmc_common"; @@ -52,14 +53,14 @@ esp_err_t sdmmc_init_ocr(sdmmc_card_t* card) return err; } } - ESP_LOGD(TAG, "host_ocr=0x%x card_ocr=0x%x", host_ocr, card->ocr); + ESP_LOGD(TAG, "host_ocr=0x%" PRIx32 " card_ocr=0x%" PRIx32, host_ocr, card->ocr); /* Clear all voltage bits in host's OCR which the card doesn't support. * Don't touch CCS bit because in SPI mode cards don't report CCS in ACMD41 * response. */ host_ocr &= (card->ocr | (~SD_OCR_VOL_MASK)); - ESP_LOGD(TAG, "sdmmc_card_init: host_ocr=%08x, card_ocr=%08x", host_ocr, card->ocr); + ESP_LOGD(TAG, "sdmmc_card_init: host_ocr=%08" PRIx32 ", card_ocr=%08" PRIx32, host_ocr, card->ocr); return ESP_OK; } @@ -286,12 +287,12 @@ void sdmmc_card_print_info(FILE* stream, const sdmmc_card_t* card) if (print_csd) { fprintf(stream, "CSD: ver=%d, sector_size=%d, capacity=%d read_bl_len=%d\n", - (card->is_mmc ? card->csd.csd_ver : card->csd.csd_ver + 1), + (int) (card->is_mmc ? card->csd.csd_ver : card->csd.csd_ver + 1), card->csd.sector_size, card->csd.capacity, card->csd.read_block_len); if (card->is_mmc) { - fprintf(stream, "EXT CSD: bus_width=%d\n", (1 << card->log_bus_width)); + fprintf(stream, "EXT CSD: bus_width=%" PRIu32 "\n", (uint32_t) (1 << card->log_bus_width)); } else if (!card->is_sdio){ // make sure card is SD - fprintf(stream, "SSR: bus_width=%d\n", (card->ssr.cur_bus_width ? 4 : 1)); + fprintf(stream, "SSR: bus_width=%" PRIu32 "\n", (uint32_t) (card->ssr.cur_bus_width ? 4 : 1)); } } if (print_scr) { diff --git a/components/sdmmc/sdmmc_io.c b/components/sdmmc/sdmmc_io.c index 1e2e069f4de6..90051111ee43 100644 --- a/components/sdmmc/sdmmc_io.c +++ b/components/sdmmc/sdmmc_io.c @@ -15,6 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "sdmmc_common.h" #include "esp_attr.h" #include "esp_compiler.h" @@ -240,7 +241,7 @@ esp_err_t sdmmc_io_read_byte(sdmmc_card_t* card, uint32_t function, { esp_err_t ret = sdmmc_io_rw_direct(card, function, addr, SD_ARG_CMD52_READ, out_byte); if (unlikely(ret != ESP_OK)) { - ESP_LOGE(TAG, "%s: sdmmc_io_rw_direct (read 0x%x) returned 0x%x", __func__, addr, ret); + ESP_LOGE(TAG, "%s: sdmmc_io_rw_direct (read 0x%" PRIx32 ") returned 0x%x", __func__, addr, ret); } return ret; } @@ -252,7 +253,7 @@ esp_err_t sdmmc_io_write_byte(sdmmc_card_t* card, uint32_t function, esp_err_t ret = sdmmc_io_rw_direct(card, function, addr, SD_ARG_CMD52_WRITE | SD_ARG_CMD52_EXCHANGE, &tmp_byte); if (unlikely(ret != ESP_OK)) { - ESP_LOGE(TAG, "%s: sdmmc_io_rw_direct (write 0x%x) returned 0x%x", __func__, addr, ret); + ESP_LOGE(TAG, "%s: sdmmc_io_rw_direct (write 0x%" PRIu32 ") returned 0x%x", __func__, addr, ret); return ret; } if (out_byte != NULL) { diff --git a/components/sdmmc/sdmmc_mmc.c b/components/sdmmc/sdmmc_mmc.c index c3940eb37dea..4d0c756f0d58 100644 --- a/components/sdmmc/sdmmc_mmc.c +++ b/components/sdmmc/sdmmc_mmc.c @@ -15,6 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include "sdmmc_common.h" @@ -298,7 +299,7 @@ uint32_t sdmmc_mmc_get_erase_timeout_ms(const sdmmc_card_t* card, int arg, size_ /* TODO: calculate erase timeout based on ext_csd (trim_timeout) */ uint32_t timeout_ms = SDMMC_SD_DISCARD_TIMEOUT * erase_size_kb / card->csd.sector_size; timeout_ms = MAX(1000, timeout_ms); - ESP_LOGD(TAG, "%s: erase timeout %u s (erasing %u kB, %ums per sector)", - __func__, timeout_ms / 1000, erase_size_kb, SDMMC_SD_DISCARD_TIMEOUT); + ESP_LOGD(TAG, "%s: erase timeout %" PRIu32 " s (erasing %" PRIu32 " kB, %" PRIu32 " ms per sector)", + __func__, (uint32_t) (timeout_ms / 1000), (uint32_t) erase_size_kb, (uint32_t) SDMMC_SD_DISCARD_TIMEOUT); return timeout_ms; } diff --git a/components/sdmmc/sdmmc_sd.c b/components/sdmmc/sdmmc_sd.c index 4111ed14e71d..6275e7cf7ff8 100644 --- a/components/sdmmc/sdmmc_sd.c +++ b/components/sdmmc/sdmmc_sd.c @@ -15,6 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "esp_timer.h" #include "sdmmc_common.h" @@ -160,7 +161,7 @@ esp_err_t sdmmc_init_sd_wait_data_ready(sdmmc_card_t* card) return err; } if (++count % 16 == 0) { - ESP_LOGV(TAG, "waiting for card to become ready (%d)", count); + ESP_LOGV(TAG, "waiting for card to become ready (%" PRIu32 ")", count); } } return ESP_OK; @@ -210,12 +211,12 @@ esp_err_t sdmmc_send_cmd_switch_func(sdmmc_card_t* card, /* busy response is never sent */ } else if (resp_ver == 1) { if (SD_SFUNC_BUSY(resp->data, group) & (1 << function)) { - ESP_LOGD(TAG, "%s: response indicates function %d:%d is busy", + ESP_LOGD(TAG, "%s: response indicates function %" PRIu32 ":%" PRIu32 " is busy", __func__, group, function); return ESP_ERR_INVALID_STATE; } } else { - ESP_LOGD(TAG, "%s: got an invalid version of SWITCH_FUNC response: 0x%02x", + ESP_LOGD(TAG, "%s: got an invalid version of SWITCH_FUNC response: 0x%02" PRIx32, __func__, resp_ver); return ESP_ERR_INVALID_RESPONSE; } @@ -446,15 +447,15 @@ uint32_t sdmmc_sd_get_erase_timeout_ms(const sdmmc_card_t* card, int arg, size_t uint32_t timeout_sec = card->ssr.erase_offset + card->ssr.erase_timeout * (erase_size_kb + card->ssr.alloc_unit_kb - 1) / (card->ssr.erase_size_au * card->ssr.alloc_unit_kb); - ESP_LOGD(TAG, "%s: erase timeout %u s (erasing %u kB, ES=%u, ET=%u, EO=%u, AU=%u kB)", - __func__, timeout_sec, erase_size_kb, card->ssr.erase_size_au, - card->ssr.erase_timeout, card->ssr.erase_offset, card->ssr.alloc_unit_kb); + ESP_LOGD(TAG, "%s: erase timeout %" PRIu32 " s (erasing %" PRIu32 " kB, ES=%" PRIu32 ", ET=%" PRIu32 ", EO=%" PRIu32 ", AU=%" PRIu32 " kB)", + __func__, timeout_sec, (uint32_t) erase_size_kb, (uint32_t) card->ssr.erase_size_au, + (uint32_t) card->ssr.erase_timeout, (uint32_t) card->ssr.erase_offset, (uint32_t) card->ssr.alloc_unit_kb); return timeout_sec * 1000; } else { uint32_t timeout_ms = SDMMC_SD_DISCARD_TIMEOUT * erase_size_kb / card->csd.sector_size; timeout_ms = MAX(1000, timeout_ms); - ESP_LOGD(TAG, "%s: erase timeout %u s (erasing %u kB, %ums per sector)", - __func__, timeout_ms / 1000, erase_size_kb, SDMMC_SD_DISCARD_TIMEOUT); + ESP_LOGD(TAG, "%s: erase timeout %" PRIu32 " s (erasing %" PRIu32 " kB, %" PRIu32 " ms per sector)", + __func__, (uint32_t) (timeout_ms / 1000), (uint32_t) erase_size_kb, (uint32_t) SDMMC_SD_DISCARD_TIMEOUT); return timeout_ms; } } else { diff --git a/components/sdmmc/test/CMakeLists.txt b/components/sdmmc/test/CMakeLists.txt index edcf529ce1ee..0648951eec3a 100644 --- a/components/sdmmc/test/CMakeLists.txt +++ b/components/sdmmc/test/CMakeLists.txt @@ -2,4 +2,3 @@ idf_component_register(SRC_DIRS "." PRIV_INCLUDE_DIRS "." PRIV_REQUIRES cmock sdmmc test_utils ) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 013759a3dbd8..608fe4006457 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -71,5 +71,4 @@ if(NOT BOOTLOADER_BUILD AND NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) # will be replaced with MMU requirements idf_component_optional_requires(PRIVATE esp_psram) endif() - target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") endif() diff --git a/components/spi_flash/test/CMakeLists.txt b/components/spi_flash/test/CMakeLists.txt index c475f2d993a3..7ae600b5b2e3 100644 --- a/components/spi_flash/test/CMakeLists.txt +++ b/components/spi_flash/test/CMakeLists.txt @@ -2,4 +2,3 @@ idf_component_register(SRC_DIRS "." PRIV_INCLUDE_DIRS "." PRIV_REQUIRES cmock test_utils spi_flash bootloader_support app_update driver esp_timer) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt b/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt index 491d7e107dea..578f8a60b67c 100644 --- a/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt +++ b/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt @@ -4,4 +4,3 @@ set(srcs "test_app_main.c" idf_component_register(SRCS ${srcs} PRIV_REQUIRES unity spi_flash bootloader_support esp_partition WHOLE_ARCHIVE) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c b/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c index 52cb3171444f..c28c4998752c 100644 --- a/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c +++ b/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ #include #include +#include #include "esp_log.h" #include "unity.h" #include "esp_flash.h" @@ -45,13 +46,13 @@ static void setup_tests(void) { const esp_partition_t *part = get_test_data_partition(); start = part->address; - printf("Test data partition @ 0x%x\n", start); + printf("Test data partition @ 0x%" PRIx32 "\n", (uint32_t) start); } static void verify_erased_flash(size_t offset, size_t length) { uint8_t *readback = (uint8_t *)heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - printf("verify erased 0x%x - 0x%x\n", offset, offset + length); + printf("verify erased 0x%" PRIx32 " - 0x%" PRIx32 "\n", (uint32_t) offset, (uint32_t) (offset + length)); TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_read(NULL, readback, offset, length)); for (int i = 0; i < length; i++) { @@ -111,7 +112,7 @@ TEST_CASE("test 16 byte encrypted writes", "[flash_encryption]") static void test_encrypted_write(size_t offset, const uint8_t *data, size_t length) { uint8_t readback[length]; - printf("encrypt %d bytes at 0x%x\n", length, offset); + printf("encrypt %" PRIu32 " bytes at 0x%" PRIx32 "\n", (uint32_t) length, (uint32_t) offset); TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_write_encrypted(NULL, offset, data, length)); @@ -160,7 +161,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]") len = SPI_FLASH_SEC_SIZE - offset; } - printf("write %d bytes to 0x%08x...\n", len, start + offset); + printf("write %d bytes to 0x%08" PRIx32 "...\n", len, (uint32_t) (start + offset)); err = esp_flash_write_encrypted(NULL, start + offset, data_buf, len); TEST_ESP_OK(err); @@ -178,7 +179,7 @@ TEST_CASE("test read & write random encrypted data", "[flash_encryption]") err = esp_flash_read_encrypted(NULL, start + offset, data_buf, len); TEST_ESP_OK(err); - printf("compare %d bytes at 0x%08x...\n", len, start + offset); + printf("compare %d bytes at 0x%08" PRIx32 "...\n", len, (uint32_t) (start + offset)); TEST_ASSERT_EQUAL_HEX8_ARRAY(cmp_buf + offset, data_buf, len); offset += len; @@ -193,7 +194,7 @@ static const char plainttext_data[] = "$$$$#### Welcome! This is flash encryptio static void test_encrypted_write_new_impl(size_t offset, const uint8_t *data, size_t length) { uint8_t *readback = (uint8_t *)heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - printf("encrypt %d bytes at 0x%x\n", length, offset); + printf("encrypt %" PRIu32 " bytes at 0x%" PRIx32 "\n", (uint32_t) length, (uint32_t) offset); TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_flash_write_encrypted(NULL, offset, data, length)); @@ -289,7 +290,7 @@ TEST_CASE("test read & write encrypted data(16 bytes alianed but 32 bytes unalig if (start % 32 == 0) { start += 16; } - printf("Write data partition @ 0x%x\n", start); + printf("Write data partition @ 0x%" PRIx32 "\n", (uint32_t) start); ESP_LOG_BUFFER_HEXDUMP(TAG, plainttext_data, sizeof(plainttext_data), ESP_LOG_INFO); printf("Encrypteed writting......\n"); diff --git a/components/wear_levelling/CMakeLists.txt b/components/wear_levelling/CMakeLists.txt index 751f68227328..2ca00a42b383 100644 --- a/components/wear_levelling/CMakeLists.txt +++ b/components/wear_levelling/CMakeLists.txt @@ -9,5 +9,3 @@ idf_component_register(SRCS "Partition.cpp" PRIV_INCLUDE_DIRS private_include REQUIRES esp_partition PRIV_REQUIRES spi_flash) - -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/wear_levelling/Partition.cpp b/components/wear_levelling/Partition.cpp index c97f45ba6031..210ef56d9f41 100644 --- a/components/wear_levelling/Partition.cpp +++ b/components/wear_levelling/Partition.cpp @@ -3,8 +3,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ + #include "esp_log.h" #include "Partition.h" +#include + static const char *TAG = "wl_partition"; Partition::Partition(const esp_partition_t *partition) @@ -28,9 +31,9 @@ esp_err_t Partition::erase_range(size_t start_address, size_t size) { esp_err_t result = esp_partition_erase_range(this->partition, start_address, size); if (result == ESP_OK) { - ESP_LOGV(TAG, "erase_range - start_address=0x%08x, size=0x%08x, result=0x%08x", start_address, size, result); + ESP_LOGV(TAG, "erase_range - start_address=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) start_address, (uint32_t) size, result); } else { - ESP_LOGE(TAG, "erase_range - start_address=0x%08x, size=0x%08x, result=0x%08x", start_address, size, result); + ESP_LOGE(TAG, "erase_range - start_address=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) start_address, (uint32_t) size, result); } return result; } diff --git a/components/wear_levelling/SPI_Flash.cpp b/components/wear_levelling/SPI_Flash.cpp index 2c16a6f88b0f..7f0d2d045d4b 100644 --- a/components/wear_levelling/SPI_Flash.cpp +++ b/components/wear_levelling/SPI_Flash.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,7 @@ #include "SPI_Flash.h" #include "spi_flash_mmap.h" #include "esp_flash.h" +#include static const char *TAG = "spi_flash"; @@ -26,9 +27,9 @@ esp_err_t SPI_Flash::erase_sector(size_t sector) { esp_err_t result = esp_flash_erase_region(NULL, sector * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);; if (result == ESP_OK) { - ESP_LOGV(TAG, "erase_sector - sector=0x%08x, result=0x%08x", sector, result); + ESP_LOGV(TAG, "erase_sector - sector=0x%08" PRIx32 ", result=0x%08x", (uint32_t) sector, result); } else { - ESP_LOGE(TAG, "erase_sector - sector=0x%08x, result=0x%08x", sector, result); + ESP_LOGE(TAG, "erase_sector - sector=0x%08" PRIx32 ", result=0x%08x", (uint32_t) sector, result); } return result; } @@ -38,9 +39,9 @@ esp_err_t SPI_Flash::erase_range(size_t start_address, size_t size) size = size * SPI_FLASH_SEC_SIZE; esp_err_t result = esp_flash_erase_region(NULL, start_address, size); if (result == ESP_OK) { - ESP_LOGV(TAG, "erase_range - start_address=0x%08x, size=0x%08x, result=0x%08x", start_address, size, result); + ESP_LOGV(TAG, "erase_range - start_address=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) start_address, (uint32_t) size, result); } else { - ESP_LOGE(TAG, "erase_range - start_address=0x%08x, size=0x%08x, result=0x%08x", start_address, size, result); + ESP_LOGE(TAG, "erase_range - start_address=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) start_address, (uint32_t) size, result); } return result; } @@ -49,9 +50,9 @@ esp_err_t SPI_Flash::write(size_t dest_addr, const void *src, size_t size) { esp_err_t result = esp_flash_write(NULL, src, dest_addr, size); if (result == ESP_OK) { - ESP_LOGV(TAG, "write - dest_addr=0x%08x, size=0x%08x, result=0x%08x", dest_addr, size, result); + ESP_LOGV(TAG, "write - dest_addr=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) dest_addr, (uint32_t) size, result); } else { - ESP_LOGE(TAG, "write - dest_addr=0x%08x, size=0x%08x, result=0x%08x", dest_addr, size, result); + ESP_LOGE(TAG, "write - dest_addr=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) dest_addr, (uint32_t) size, result); } return result; } @@ -60,9 +61,9 @@ esp_err_t SPI_Flash::read(size_t src_addr, void *dest, size_t size) { esp_err_t result = esp_flash_read(NULL, dest, src_addr, size); if (result == ESP_OK) { - ESP_LOGV(TAG, "read - src_addr=0x%08x, size=0x%08x, result=0x%08x", src_addr, size, result); + ESP_LOGV(TAG, "read - src_addr=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) src_addr, (uint32_t) size, result); } else { - ESP_LOGE(TAG, "read - src_addr=0x%08x, size=0x%08x, result=0x%08x", src_addr, size, result); + ESP_LOGE(TAG, "read - src_addr=0x%08" PRIx32 ", size=0x%08" PRIx32 ", result=0x%08x", (uint32_t) src_addr, (uint32_t) size, result); } return result; } diff --git a/components/wear_levelling/WL_Ext_Perf.cpp b/components/wear_levelling/WL_Ext_Perf.cpp index 03fbfdce7e0a..2fc89debacea 100644 --- a/components/wear_levelling/WL_Ext_Perf.cpp +++ b/components/wear_levelling/WL_Ext_Perf.cpp @@ -6,13 +6,14 @@ #include "WL_Ext_Perf.h" #include "Partition.h" #include +#include #include "esp_log.h" static const char *TAG = "wl_ext_perf"; #define WL_EXT_RESULT_CHECK(result) \ if (result != ESP_OK) { \ - ESP_LOGE(TAG,"%s(%d): result = 0x%08x", __FUNCTION__, __LINE__, result); \ + ESP_LOGE(TAG,"%s(%d): result = 0x%08" PRIx32, __FUNCTION__, __LINE__, (uint32_t) result); \ return (result); \ } @@ -76,7 +77,7 @@ esp_err_t WL_Ext_Perf::erase_sector_fit(uint32_t first_erase_sector, uint32_t co { // This method works with one flash device sector and able to erase "count" of fatfs sectors from this first_erase_sector esp_err_t result = ESP_OK; - ESP_LOGV(TAG, "%s begin, first_erase_sector = 0x%08x, count = %i", __func__, first_erase_sector, count); + ESP_LOGV(TAG, "%s begin, first_erase_sector = 0x%08" PRIx32 ", count = %" PRIu32, __func__, first_erase_sector, count); uint32_t flash_sector_base_addr = first_erase_sector / this->flash_fat_sector_size_factor; uint32_t pre_check_start = first_erase_sector % this->flash_fat_sector_size_factor; @@ -136,7 +137,7 @@ esp_err_t WL_Ext_Perf::erase_range(size_t start_address, size_t size) // erase complete sector and restore data of area which should not be erased. // For the rest check area, this operation not needed because complete flash device sector will be erased. - ESP_LOGV(TAG, "%s begin, addr = 0x%08x, size = %i", __func__, start_address, size); + ESP_LOGV(TAG, "%s begin, addr = 0x%08" PRIx32 ", size = %" PRIu32, __func__, (uint32_t) start_address, (uint32_t) size); uint32_t sectors_count = size / this->fat_sector_size; // Calculate pre check values @@ -164,7 +165,7 @@ esp_err_t WL_Ext_Perf::erase_range(size_t start_address, size_t size) result = this->erase_sector_fit(start_address / this->fat_sector_size, pre_check_count); WL_EXT_RESULT_CHECK(result); } - ESP_LOGV(TAG, "%s rest_check_start = %i, pre_check_count=%i, rest_check_count=%i, post_check_count=%i", __func__, rest_check_start, pre_check_count, rest_check_count, post_check_count); + ESP_LOGV(TAG, "%s rest_check_start = %" PRIu32 ", pre_check_count=%" PRIu32 ", rest_check_count=%" PRIu32 ", post_check_count=%" PRIu32, __func__, rest_check_start, pre_check_count, rest_check_count, post_check_count); // Clear rest_check_count sectors if (rest_check_count > 0) { diff --git a/components/wear_levelling/WL_Ext_Safe.cpp b/components/wear_levelling/WL_Ext_Safe.cpp index 695b6829ce12..73edc79c3ca0 100644 --- a/components/wear_levelling/WL_Ext_Safe.cpp +++ b/components/wear_levelling/WL_Ext_Safe.cpp @@ -1,17 +1,18 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "WL_Ext_Safe.h" #include +#include #include "esp_log.h" static const char *TAG = "wl_ext_safe"; #define WL_EXT_RESULT_CHECK(result) \ if (result != ESP_OK) { \ - ESP_LOGE(TAG,"%s(%d): result = 0x%08x", __FUNCTION__, __LINE__, result); \ + ESP_LOGE(TAG,"%s(%d): result = 0x%08" PRIx32, __FUNCTION__, __LINE__, (uint32_t) result); \ return (result); \ } @@ -77,7 +78,7 @@ esp_err_t WL_Ext_Safe::init() size_t WL_Ext_Safe::get_flash_size() { - ESP_LOGV(TAG, "%s size = %i", __func__, WL_Ext_Perf::get_flash_size() - 2 * this->flash_sector_size); + ESP_LOGV(TAG, "%s size = %" PRIu32, __func__, (uint32_t) (WL_Ext_Perf::get_flash_size() - 2 * this->flash_sector_size)); return WL_Ext_Perf::get_flash_size() - 2 * this->flash_sector_size; } @@ -89,7 +90,7 @@ esp_err_t WL_Ext_Safe::recover() WL_Ext_Safe_State state; result = this->read(this->buff_trans_state_addr, &state, sizeof(WL_Ext_Safe_State)); WL_EXT_RESULT_CHECK(result); - ESP_LOGV(TAG, "%s recover, start_addr = 0x%08x, sector_base_addr = 0x%08x, sector_base_addr_offset= %i, count=%i", __func__, state.sector_restore_sign, state.sector_base_addr, state.sector_base_addr_offset, state.count); + ESP_LOGV(TAG, "%s recover, start_addr = 0x%08" PRIx32 ", sector_base_addr = 0x%08" PRIx32 ", sector_base_addr_offset= %" PRIu32 ", count=%" PRIu32, __func__, state.sector_restore_sign, state.sector_base_addr, state.sector_base_addr_offset, state.count); // check if we have any incomplete transaction pending. if (state.sector_restore_sign == WL_EXT_SAFE_OK) { @@ -129,7 +130,7 @@ esp_err_t WL_Ext_Safe::erase_sector_fit(uint32_t first_erase_sector, uint32_t co uint32_t pre_check_start = first_erase_sector % this->flash_fat_sector_size_factor; // Except pre check and post check data area, read and store all other data to sector_buffer - ESP_LOGV(TAG, "%s first_erase_sector=0x%08x, count = %i", __func__, first_erase_sector, count); + ESP_LOGV(TAG, "%s first_erase_sector=0x%08" PRIx32 ", count = %" PRIu32, __func__, first_erase_sector, count); for (int i = 0; i < this->flash_fat_sector_size_factor; i++) { if ((i < pre_check_start) || (i >= count + pre_check_start)) { result = this->read(flash_sector_base_addr * this->flash_sector_size + i * this->fat_sector_size, diff --git a/components/wear_levelling/WL_Flash.cpp b/components/wear_levelling/WL_Flash.cpp index b3fd31e4ff0e..626445c467bd 100644 --- a/components/wear_levelling/WL_Flash.cpp +++ b/components/wear_levelling/WL_Flash.cpp @@ -12,6 +12,7 @@ #include "crc32.h" #include #include +#include static const char *TAG = "wl_flash"; #ifndef WL_CFG_CRC_CONST @@ -20,7 +21,7 @@ static const char *TAG = "wl_flash"; #define WL_RESULT_CHECK(result) \ if (result != ESP_OK) { \ - ESP_LOGE(TAG,"%s(%d): result = 0x%08x", __FUNCTION__, __LINE__, result); \ + ESP_LOGE(TAG,"%s(%d): result = 0x%08" PRIx32, __FUNCTION__, __LINE__, (uint32_t) result); \ return (result); \ } @@ -40,7 +41,7 @@ WL_Flash::~WL_Flash() esp_err_t WL_Flash::config(wl_config_t *cfg, Partition *partition) { - ESP_LOGV(TAG, "%s partition_start_addr=0x%08x, wl_partition_size=0x%08x, wl_page_size=0x%08x, flash_sector_size=0x%08x, wl_update_rate=0x%08x, wl_pos_update_record_size=0x%08x, version=0x%08x, wl_temp_buff_size=0x%08x", __func__, + ESP_LOGV(TAG, "%s partition_start_addr=0x%08" PRIx32 ", wl_partition_size=0x%08" PRIx32 ", wl_page_size=0x%08" PRIx32 ", flash_sector_size=0x%08" PRIx32 ", wl_update_rate=0x%08" PRIx32 ", wl_pos_update_record_size=0x%08" PRIx32 ", version=0x%08" PRIx32 ", wl_temp_buff_size=0x%08" PRIx32 , __func__, (uint32_t) cfg->wl_partition_start_addr, cfg->wl_partition_size, cfg->wl_page_size, @@ -87,7 +88,7 @@ esp_err_t WL_Flash::config(wl_config_t *cfg, Partition *partition) ptrdiff_t flash_sz = ((this->cfg.wl_partition_size - this->state_size * 2 - this->cfg_size) / this->cfg.wl_page_size - 1) * this->cfg.wl_page_size; // -1 remove dummy block this->flash_size = ((this->cfg.wl_partition_size - this->state_size * 2 - this->cfg_size) / this->cfg.wl_page_size - 1) * this->cfg.wl_page_size; // -1 remove dummy block - ESP_LOGD(TAG, "%s - config result: state_size=0x%08x, cfg_size=0x%08x, addr_cfg=0x%08x, addr_state1=0x%08x, addr_state2=0x%08x, flash_size=0x%08x", __func__, + ESP_LOGD(TAG, "%s - config result: state_size=0x%08" PRIx32 ", cfg_size=0x%08" PRIx32 ", addr_cfg=0x%08" PRIx32 ", addr_state1=0x%08" PRIx32 ", addr_state2=0x%08" PRIx32 ", flash_size=0x%08" PRIx32, __func__, (uint32_t) this->state_size, (uint32_t) this->cfg_size, (uint32_t) this->addr_cfg, @@ -130,7 +131,7 @@ esp_err_t WL_Flash::init() uint32_t crc1 = crc32::crc32_le(WL_CFG_CRC_CONST, (uint8_t *)&this->state, check_size); uint32_t crc2 = crc32::crc32_le(WL_CFG_CRC_CONST, (uint8_t *)state_copy, check_size); - ESP_LOGD(TAG, "%s - config ID=%i, stored ID=%i, wl_sec_erase_cycle_count=%i, wl_block_size=%i, wl_max_sec_erase_cycle_count=%i, wl_dummy_sec_pos=%i, wl_dummy_sec_move_count=0x%8.8X", + ESP_LOGD(TAG, "%s - config ID=%" PRIu32 ", stored ID=%" PRIu32 ", wl_sec_erase_cycle_count=%" PRIu32 ", wl_block_size=%" PRIu32 ", wl_max_sec_erase_cycle_count=%" PRIu32 ", wl_dummy_sec_pos=%" PRIu32 ", wl_dummy_sec_move_count=0x%8.8" PRIX32, __func__, this->cfg.version, this->state.version, @@ -140,7 +141,7 @@ esp_err_t WL_Flash::init() this->state.wl_dummy_sec_pos, this->state.wl_dummy_sec_move_count); - ESP_LOGD(TAG, "%s starts: crc1= 0x%08x, crc2 = 0x%08x, this->state.crc= 0x%08x, state_copy->crc= 0x%08x, version=%i, read_version=%i", __func__, crc1, crc2, this->state.crc32, state_copy->crc32, this->cfg.version, this->state.version); + ESP_LOGD(TAG, "%s starts: crc1= 0x%08" PRIx32 ", crc2 = 0x%08" PRIx32 ", this->state.crc= 0x%08" PRIx32 ", state_copy->crc= 0x%08" PRIx32 ", version=%" PRIu32 ", read_version=%" PRIu32, __func__, crc1, crc2, this->state.crc32, state_copy->crc32, this->cfg.version, this->state.version); if ((crc1 == this->state.crc32) && (crc2 == state_copy->crc32)) { // The state is OK. Check the ID if (this->state.version != this->cfg.version) { @@ -167,13 +168,13 @@ esp_err_t WL_Flash::init() } } } - ESP_LOGD(TAG, "%s: crc1=0x%08x, crc2 = 0x%08x, result= 0x%08x", __func__, crc1, crc2, (uint32_t)result); + ESP_LOGD(TAG, "%s: crc1=0x%08" PRIx32 ", crc2 = 0x%08" PRIx32 ", result= 0x%08" PRIx32 , __func__, crc1, crc2, (uint32_t)result); result = this->recoverPos(); WL_RESULT_CHECK(result); } } else if ((crc1 != this->state.crc32) && (crc2 != state_copy->crc32)) { // This is just new flash or new version // Check if this is new version or just new instance of WL - ESP_LOGD(TAG, "%s: try to update version - crc1= 0x%08x, crc2 = 0x%08x, result= 0x%08x", __func__, (uint32_t)crc1, (uint32_t)crc2, (uint32_t)result); + ESP_LOGD(TAG, "%s: try to update version - crc1= 0x%08" PRIx32 ", crc2 = 0x%08" PRIx32 ", result= 0x%08" PRIx32 , __func__, (uint32_t)crc1, (uint32_t)crc2, (uint32_t)result); result = this->updateVersion(); if (result == ESP_FAIL) { ESP_LOGD(TAG, "%s: init flash sections", __func__); @@ -232,11 +233,11 @@ esp_err_t WL_Flash::init() } if (result != ESP_OK) { this->initialized = false; - ESP_LOGE(TAG, "%s: returned 0x%08x", __func__, (uint32_t)result); + ESP_LOGE(TAG, "%s: returned 0x%08" PRIx32 , __func__, (uint32_t)result); return result; } this->initialized = true; - ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08x", __func__, (uint32_t)this->state.wl_dummy_sec_move_count); + ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08" PRIx32 , __func__, (uint32_t)this->state.wl_dummy_sec_move_count); return ESP_OK; } @@ -251,7 +252,7 @@ esp_err_t WL_Flash::recoverPos() result = this->partition->read(this->addr_state1 + sizeof(wl_state_t) + i * this->cfg.wl_pos_update_record_size, this->temp_buff, this->cfg.wl_pos_update_record_size); pos_bits = this->OkBuffSet(i); WL_RESULT_CHECK(result); - ESP_LOGV(TAG, "%s - check pos: result=0x%08x, position= %i, pos_bits= 0x%08x", __func__, (uint32_t)result, (uint32_t)position, (uint32_t)pos_bits); + ESP_LOGV(TAG, "%s - check pos: result=0x%08" PRIx32 ", position= %" PRIu32 ", pos_bits= 0x%08" PRIx32 , __func__, (uint32_t) result, (uint32_t) position, (uint32_t) pos_bits); if (pos_bits == false) { break; // we have found position } @@ -261,7 +262,7 @@ esp_err_t WL_Flash::recoverPos() if (this->state.wl_dummy_sec_pos == this->state.wl_part_max_sec_pos) { this->state.wl_dummy_sec_pos--; } - ESP_LOGD(TAG, "%s - this->state.wl_dummy_sec_pos= 0x%08x, position= 0x%08x, result= 0x%08x, wl_part_max_sec_pos= 0x%08x", __func__, (uint32_t)this->state.wl_dummy_sec_pos, (uint32_t)position, (uint32_t)result, (uint32_t)this->state.wl_part_max_sec_pos); + ESP_LOGD(TAG, "%s - this->state.wl_dummy_sec_pos= 0x%08" PRIx32 ", position= 0x%08" PRIx32 ", result= 0x%08" PRIx32 ", wl_part_max_sec_pos= 0x%08" PRIx32 , __func__, (uint32_t)this->state.wl_dummy_sec_pos, (uint32_t)position, (uint32_t)result, (uint32_t)this->state.wl_part_max_sec_pos); ESP_LOGV(TAG, "%s done", __func__); return result; } @@ -301,8 +302,8 @@ esp_err_t WL_Flash::initSections() result = this->partition->write(this->addr_cfg, &this->cfg, sizeof(wl_config_t)); WL_RESULT_CHECK(result); - ESP_LOGD(TAG, "%s - this->state->wl_max_sec_erase_cycle_count= 0x%08x, this->state->wl_part_max_sec_pos= 0x%08x", __func__, this->state.wl_max_sec_erase_cycle_count, this->state.wl_part_max_sec_pos); - ESP_LOGD(TAG, "%s - result= 0x%08x", __func__, result); + ESP_LOGD(TAG, "%s - this->state->wl_max_sec_erase_cycle_count= 0x%08" PRIx32 ", this->state->wl_part_max_sec_pos= 0x%08" PRIx32 , __func__, this->state.wl_max_sec_erase_cycle_count, this->state.wl_part_max_sec_pos); + ESP_LOGD(TAG, "%s - result= 0x%08x" , __func__, result); return result; } @@ -336,24 +337,24 @@ esp_err_t WL_Flash::updateV1_V2() uint32_t v1_crc1 = this->state.wl_device_id; uint32_t v1_crc2 = state_copy->wl_device_id; - ESP_LOGD(TAG, "%s - process crc1=0x%08x, crc2=0x%08x, v1_crc1=0x%08x, v1_crc2=0x%08x, version=%i", __func__, crc1, crc2, v1_crc1, v1_crc2, this->state.version); + ESP_LOGD(TAG, "%s - process crc1=0x%08" PRIx32 ", crc2=0x%08" PRIx32 ", v1_crc1=0x%08" PRIx32 ", v1_crc2=0x%08" PRIx32 ", version=%" PRIu32, __func__, crc1, crc2, v1_crc1, v1_crc2, this->state.version); if ((crc1 == v1_crc1) && (crc2 == v1_crc2) && (v1_crc1 == v1_crc2) && (this->state.version == 1) && (state_copy->version == 1)) { // Here we have to update all internal structures - ESP_LOGI(TAG, "%s Update from V1 to V2, crc=0x%08x, ", __func__, crc1); + ESP_LOGI(TAG, "%s Update from V1 to V2, crc=0x%08" PRIx32 ", ", __func__, crc1); uint32_t pos = 0; for (size_t i = 0; i < this->state.wl_part_max_sec_pos; i++) { uint8_t pos_bits; result = this->partition->read(this->addr_state1 + sizeof(wl_state_t) + i * this->cfg.wl_pos_update_record_size, &pos_bits, 1); WL_RESULT_CHECK(result); - ESP_LOGV(TAG, "%s- result= 0x%08x, pos= %i, pos_bits= 0x%08x", __func__, (uint32_t)result, (uint32_t)pos, (uint32_t)pos_bits); + ESP_LOGV(TAG, "%s- result= 0x%08" PRIx32 ", pos= %" PRIu32 ", pos_bits= 0x%08" PRIx32 , __func__, (uint32_t) result, (uint32_t) pos, (uint32_t) pos_bits); pos = i; if (pos_bits == 0xff) { break; // we have found position } } - ESP_LOGI(TAG, "%s wl_part_max_sec_pos=%i, pos=%i, state.ver=%i, state2.ver=%i", __func__, (uint32_t)this->state.wl_part_max_sec_pos, (uint32_t)pos, (uint32_t)this->state.version, (uint32_t)state_copy->version); + ESP_LOGI(TAG, "%s wl_part_max_sec_pos=%" PRIu32 ", pos=%" PRIu32 ", state.ver=%" PRIu32 ", state2.ver=%" PRIu32, __func__, (uint32_t) this->state.wl_part_max_sec_pos, (uint32_t) pos, (uint32_t) this->state.version, (uint32_t) state_copy->version); if (pos == this->state.wl_part_max_sec_pos) { pos--; } @@ -381,7 +382,7 @@ esp_err_t WL_Flash::updateV1_V2() WL_RESULT_CHECK(result); result = this->partition->write(this->addr_state2, &this->state, sizeof(wl_state_t)); WL_RESULT_CHECK(result); - ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08x, pos= 0x%08x", __func__, this->state.wl_dummy_sec_move_count, this->state.wl_dummy_sec_pos); + ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08" PRIx32 ", pos= 0x%08" PRIx32 , __func__, this->state.wl_dummy_sec_move_count, this->state.wl_dummy_sec_pos); memset(this->temp_buff, 0, this->cfg.wl_pos_update_record_size); for (uint32_t i = 0 ; i <= pos; i++) { @@ -430,7 +431,7 @@ esp_err_t WL_Flash::updateWL() } // Here we have to move the block and increase the state this->state.wl_sec_erase_cycle_count = 0; - ESP_LOGV(TAG, "%s - wl_sec_erase_cycle_count= 0x%08x, pos= 0x%08x", __func__, this->state.wl_sec_erase_cycle_count, this->state.wl_dummy_sec_pos); + ESP_LOGV(TAG, "%s - wl_sec_erase_cycle_count= 0x%08" PRIx32 ", pos= 0x%08" PRIx32 , __func__, this->state.wl_sec_erase_cycle_count, this->state.wl_dummy_sec_pos); // copy data to dummy block size_t data_addr = this->state.wl_dummy_sec_pos + 1; // next block, [pos+1] copy to [pos] if (data_addr >= this->state.wl_part_max_sec_pos) { @@ -440,7 +441,7 @@ esp_err_t WL_Flash::updateWL() this->dummy_addr = this->cfg.wl_partition_start_addr + this->state.wl_dummy_sec_pos * this->cfg.wl_page_size; result = this->partition->erase_range(this->dummy_addr, this->cfg.wl_page_size); if (result != ESP_OK) { - ESP_LOGE(TAG, "%s - erase wl dummy sector result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - erase wl dummy sector result= 0x%08x" , __func__, result); this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; // we will update next time return result; } @@ -449,13 +450,13 @@ esp_err_t WL_Flash::updateWL() for (size_t i = 0; i < copy_count; i++) { result = this->partition->read(data_addr + i * this->cfg.wl_temp_buff_size, this->temp_buff, this->cfg.wl_temp_buff_size); if (result != ESP_OK) { - ESP_LOGE(TAG, "%s - not possible to read buffer, will try next time, result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - not possible to read buffer, will try next time, result= 0x%08x" , __func__, result); this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; // we will update next time return result; } result = this->partition->write(this->dummy_addr + i * this->cfg.wl_temp_buff_size, this->temp_buff, this->cfg.wl_temp_buff_size); if (result != ESP_OK) { - ESP_LOGE(TAG, "%s - not possible to write buffer, will try next time, result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - not possible to write buffer, will try next time, result= 0x%08x" , __func__, result); this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; // we will update next time return result; } @@ -468,14 +469,14 @@ esp_err_t WL_Flash::updateWL() // write state to mem. We updating only affected bits result |= this->partition->write(this->addr_state1 + sizeof(wl_state_t) + byte_pos, this->temp_buff, this->cfg.wl_pos_update_record_size); if (result != ESP_OK) { - ESP_LOGE(TAG, "%s - update position 1 result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - update position 1 result= 0x%08x" , __func__, result); this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; // we will update next time return result; } this->fillOkBuff(this->state.wl_dummy_sec_pos); result |= this->partition->write(this->addr_state2 + sizeof(wl_state_t) + byte_pos, this->temp_buff, this->cfg.wl_pos_update_record_size); if (result != ESP_OK) { - ESP_LOGE(TAG, "%s - update position 2 result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - update position 2 result= 0x%08x" , __func__, result); this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; // we will update next time return result; } @@ -499,13 +500,13 @@ esp_err_t WL_Flash::updateWL() WL_RESULT_CHECK(result); result = this->partition->write(this->addr_state2, &this->state, sizeof(wl_state_t)); WL_RESULT_CHECK(result); - ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08x, wl_dummy_sec_pos= 0x%08x, ", __func__, this->state.wl_dummy_sec_move_count, this->state.wl_dummy_sec_pos); + ESP_LOGD(TAG, "%s - wl_dummy_sec_move_count= 0x%08" PRIx32 ", wl_dummy_sec_pos= 0x%08" PRIx32 ", ", __func__, this->state.wl_dummy_sec_move_count, this->state.wl_dummy_sec_pos); } // Save structures to the flash... and check result if (result == ESP_OK) { - ESP_LOGV(TAG, "%s - result= 0x%08x", __func__, result); + ESP_LOGV(TAG, "%s - result= 0x%08x" , __func__, result); } else { - ESP_LOGE(TAG, "%s - result= 0x%08x", __func__, result); + ESP_LOGE(TAG, "%s - result= 0x%08x" , __func__, result); } return result; } @@ -518,7 +519,7 @@ size_t WL_Flash::calcAddr(size_t addr) } else { result += this->cfg.wl_page_size; } - ESP_LOGV(TAG, "%s - addr= 0x%08x -> result= 0x%08x, dummy_addr= 0x%08x", __func__, (uint32_t) addr, (uint32_t) result, (uint32_t)dummy_addr); + ESP_LOGV(TAG, "%s - addr= 0x%08" PRIx32 " -> result= 0x%08" PRIx32 ", dummy_addr= 0x%08" PRIx32 , __func__, (uint32_t) addr, (uint32_t) result, (uint32_t)dummy_addr); return result; } @@ -545,7 +546,7 @@ esp_err_t WL_Flash::erase_sector(size_t sector) if (!this->initialized) { return ESP_ERR_INVALID_STATE; } - ESP_LOGD(TAG, "%s - sector= 0x%08x", __func__, (uint32_t) sector); + ESP_LOGD(TAG, "%s - sector= 0x%08" PRIx32 , __func__, (uint32_t) sector); result = this->updateWL(); WL_RESULT_CHECK(result); size_t virt_addr = this->calcAddr(sector * this->cfg.flash_sector_size); @@ -560,14 +561,14 @@ esp_err_t WL_Flash::erase_range(size_t start_address, size_t size) if (!this->initialized) { return ESP_ERR_INVALID_STATE; } - ESP_LOGD(TAG, "%s - start_address= 0x%08x, size= 0x%08x", __func__, (uint32_t) start_address, (uint32_t) size); + ESP_LOGD(TAG, "%s - start_address= 0x%08" PRIx32 ", size= 0x%08" PRIx32 , __func__, (uint32_t) start_address, (uint32_t) size); size_t erase_count = (size + this->cfg.flash_sector_size - 1) / this->cfg.flash_sector_size; size_t start_sector = start_address / this->cfg.flash_sector_size; for (size_t i = 0; i < erase_count; i++) { result = this->erase_sector(start_sector + i); WL_RESULT_CHECK(result); } - ESP_LOGV(TAG, "%s - result= 0x%08x", __func__, result); + ESP_LOGV(TAG, "%s - result= 0x%08x" , __func__, result); return result; } @@ -577,7 +578,7 @@ esp_err_t WL_Flash::write(size_t dest_addr, const void *src, size_t size) if (!this->initialized) { return ESP_ERR_INVALID_STATE; } - ESP_LOGD(TAG, "%s - dest_addr= 0x%08x, size= 0x%08x", __func__, (uint32_t) dest_addr, (uint32_t) size); + ESP_LOGD(TAG, "%s - dest_addr= 0x%08" PRIx32 ", size= 0x%08" PRIx32 , __func__, (uint32_t) dest_addr, (uint32_t) size); uint32_t count = (size - 1) / this->cfg.wl_page_size; for (size_t i = 0; i < count; i++) { size_t virt_addr = this->calcAddr(dest_addr + i * this->cfg.wl_page_size); @@ -596,11 +597,11 @@ esp_err_t WL_Flash::read(size_t src_addr, void *dest, size_t size) if (!this->initialized) { return ESP_ERR_INVALID_STATE; } - ESP_LOGD(TAG, "%s - src_addr= 0x%08x, size= 0x%08x", __func__, (uint32_t) src_addr, (uint32_t) size); + ESP_LOGD(TAG, "%s - src_addr= 0x%08" PRIx32 ", size= 0x%08" PRIx32 , __func__, (uint32_t) src_addr, (uint32_t) size); uint32_t count = (size - 1) / this->cfg.wl_page_size; for (size_t i = 0; i < count; i++) { size_t virt_addr = this->calcAddr(src_addr + i * this->cfg.wl_page_size); - ESP_LOGV(TAG, "%s - real_addr= 0x%08x, size= 0x%08x", __func__, (uint32_t) (this->cfg.wl_partition_start_addr + virt_addr), (uint32_t) size); + ESP_LOGV(TAG, "%s - real_addr= 0x%08" PRIx32 ", size= 0x%08" PRIx32 , __func__, (uint32_t) (this->cfg.wl_partition_start_addr + virt_addr), (uint32_t) size); result = this->partition->read(this->cfg.wl_partition_start_addr + virt_addr, &((uint8_t *)dest)[i * this->cfg.wl_page_size], this->cfg.wl_page_size); WL_RESULT_CHECK(result); } @@ -624,6 +625,6 @@ esp_err_t WL_Flash::flush() esp_err_t result = ESP_OK; this->state.wl_sec_erase_cycle_count = this->state.wl_max_sec_erase_cycle_count - 1; result = this->updateWL(); - ESP_LOGD(TAG, "%s - result= 0x%08x, wl_dummy_sec_move_count= 0x%08x", __func__, result, this->state.wl_dummy_sec_move_count); + ESP_LOGD(TAG, "%s - result= 0x%08x, wl_dummy_sec_move_count= 0x%08" PRIx32, __func__, result, this->state.wl_dummy_sec_move_count); return result; } diff --git a/components/wear_levelling/test_apps/main/CMakeLists.txt b/components/wear_levelling/test_apps/main/CMakeLists.txt index 84359c084b01..9273ee133d23 100644 --- a/components/wear_levelling/test_apps/main/CMakeLists.txt +++ b/components/wear_levelling/test_apps/main/CMakeLists.txt @@ -3,4 +3,3 @@ idf_component_register(SRCS test_wl.c PRIV_REQUIRES wear_levelling unity spi_flash EMBED_FILES test_partition_v1.bin ) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/wear_levelling/test_apps/main/test_wl.c b/components/wear_levelling/test_apps/main/test_wl.c index 6585334027fa..227c6d903727 100644 --- a/components/wear_levelling/test_apps/main/test_wl.c +++ b/components/wear_levelling/test_apps/main/test_wl.c @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include "unity.h" #include "unity_fixture.h" #include "wear_levelling.h" @@ -120,7 +121,7 @@ static void read_write_task(void *param) uint32_t rval; err = wl_read(args->handle, args->offset + i * sizeof(rval), &rval, sizeof(rval)); if (err != ESP_OK || rval != val) { - printf("E: i=%d, cnt=%d rval=%d val=%d\n\n", i, args->word_count, rval, val); + printf("E: i=%" PRIu32 ", cnt=%" PRIu32 " rval=%" PRIu32 " val=%" PRIu32 "\n\n", (uint32_t) i, (uint32_t) args->word_count, rval, val); args->result = ESP_FAIL; goto done; } @@ -225,7 +226,7 @@ TEST(wear_levelling, write_doesnt_touch_other_sectors) // Erase 8 sectors TEST_ESP_OK(wl_erase_range(handle, 0, sector_size * TEST_SECTORS_COUNT)); // Write data to all sectors - printf("Check 1 sector_size=0x%08x\n", sector_size); + printf("Check 1 sector_size=0x%08" PRIx32 "\n", (uint32_t) sector_size); // Set initial random value uint32_t init_val = rand(); @@ -256,7 +257,7 @@ TEST(wear_levelling, write_doesnt_touch_other_sectors) uint32_t end; end = esp_cpu_get_cycle_count(); uint32_t ms = (end - start) / (esp_clk_cpu_freq() / 1000); - printf("loop %4i pass, time= %ims\n", m, ms); + printf("loop %4d pass, time= %" PRIu32 "ms\n", m, ms); if (ms > 10000) { break; } @@ -288,13 +289,13 @@ TEST(wear_levelling, version_update) } fake_partition.size = (size_t)(test_partition_v1_bin_end - test_partition_v1_bin_start); - printf("Data file size = %i, partition address = 0x%08x, file addr=0x%08x\n", (uint32_t)fake_partition.size, (uint32_t)fake_partition.address, (uint32_t)test_partition_v1_bin_start); + printf("Data file size = %" PRIu32 ", partition address = 0x%08" PRIx32 ", file addr=0x%08" PRIx32 "\n", (uint32_t) fake_partition.size, (uint32_t) fake_partition.address, (uint32_t) test_partition_v1_bin_start); esp_partition_erase_range(&fake_partition, 0, fake_partition.size); esp_partition_write(&fake_partition, 0, test_partition_v1_bin_start, fake_partition.size); for (int i = 0; i < 3; i++) { - printf("Pass %i\n", i); + printf("Pass %d\n", i); wl_handle_t handle; TEST_ESP_OK(wl_mount(&fake_partition, &handle)); size_t sector_size = wl_sector_size(handle); @@ -308,7 +309,7 @@ TEST(wear_levelling, version_update) for (int i = 0; i < sector_size / sizeof(uint32_t); i++) { uint32_t compare_val = init_val + i + m * sector_size; if (buff[i] != compare_val) { - printf("error compare: 0x%08x != 0x%08x \n", buff[i], compare_val); + printf("error compare: 0x%08" PRIx32 " != 0x%08" PRIx32 " \n", buff[i], compare_val); } TEST_ASSERT_EQUAL( buff[i], compare_val); } diff --git a/components/wear_levelling/wear_levelling.cpp b/components/wear_levelling/wear_levelling.cpp index cdbdc923c09d..d44e1b484cbd 100644 --- a/components/wear_levelling/wear_levelling.cpp +++ b/components/wear_levelling/wear_levelling.cpp @@ -136,14 +136,14 @@ esp_err_t wl_mount(const esp_partition_t *partition, wl_handle_t *out_handle) // Configure data needed by WL layer for respective flash driver result = wl_flash->config(&cfg, part); if (ESP_OK != result) { - ESP_LOGE(TAG, "%s: config instance=0x%08x, result=0x%x", __func__, *out_handle, result); + ESP_LOGE(TAG, "%s: config instance=0x%08" PRIx32 ", result=0x%x", __func__, *out_handle, result); goto out; } // Initialise sectors used by WL layer for respective flash driver result = wl_flash->init(); if (ESP_OK != result) { - ESP_LOGE(TAG, "%s: init instance=0x%08x, result=0x%x", __func__, *out_handle, result); + ESP_LOGE(TAG, "%s: init instance=0x%08" PRIx32 ", result=0x%x", __func__, *out_handle, result); goto out; } @@ -258,11 +258,11 @@ static esp_err_t check_handle(wl_handle_t handle, const char *func) return ESP_ERR_NOT_FOUND; } if (handle >= MAX_WL_HANDLES) { - ESP_LOGE(TAG, "%s: instance[0x%08x] out of range", func, handle); + ESP_LOGE(TAG, "%s: instance[0x%08" PRIx32 "] out of range", func, handle); return ESP_ERR_INVALID_ARG; } if (s_instances[handle].instance == NULL) { - ESP_LOGE(TAG, "%s: instance[0x%08x] not initialized", func, handle); + ESP_LOGE(TAG, "%s: instance[0x%08" PRIx32 "] not initialized", func, handle); return ESP_ERR_NOT_FOUND; } return ESP_OK; From 98b5ea7bdf953cd30e6d59d86a1f9dc937082106 Mon Sep 17 00:00:00 2001 From: morris Date: Mon, 16 Oct 2023 11:41:02 +0800 Subject: [PATCH 011/161] refactor(pcnt): make pcnt driver as component --- .gitlab/CODEOWNERS | 1 + components/driver/CMakeLists.txt | 9 ++--- components/driver/Kconfig | 2 +- components/driver/linker.lf | 5 --- .../driver/test_apps/.build-test-rules.yml | 4 --- .../dac_test_apps/dac/main/CMakeLists.txt | 2 +- .../i2s_test_apps/i2s/main/CMakeLists.txt | 2 +- .../legacy_i2s_driver/main/CMakeLists.txt | 2 +- .../driver/test_apps/ledc/main/CMakeLists.txt | 2 +- .../legacy_mcpwm_driver/main/CMakeLists.txt | 2 +- components/esp_driver_pcnt/CMakeLists.txt | 17 +++++++++ .../pcnt => esp_driver_pcnt}/Kconfig.pcnt | 0 .../include/driver/pulse_cnt.h | 0 components/esp_driver_pcnt/linker.lf | 8 +++++ .../pcnt => esp_driver_pcnt/src}/pulse_cnt.c | 10 +++--- .../test_apps/.build-test-rules.yml | 7 ++++ .../test_apps/pulse_cnt/CMakeLists.txt | 2 +- .../test_apps/pulse_cnt/README.md | 0 .../test_apps/pulse_cnt/main/CMakeLists.txt | 3 +- .../test_apps/pulse_cnt/main/test_app_main.c | 0 .../test_apps/pulse_cnt/main/test_pulse_cnt.c | 0 .../pulse_cnt/main/test_pulse_cnt_board.h | 0 .../pulse_cnt/main/test_pulse_cnt_iram.c | 0 .../pulse_cnt/main/test_pulse_cnt_simulator.c | 0 .../test_apps/pulse_cnt/pytest_pulse_cnt.py | 0 .../pulse_cnt/sdkconfig.ci.iram_safe | 0 .../test_apps/pulse_cnt/sdkconfig.ci.release | 0 .../test_apps/pulse_cnt/sdkconfig.defaults | 0 components/esp_timer/CMakeLists.txt | 36 +++++++++---------- docs/doxygen/Doxyfile | 2 +- examples/peripherals/.build-test-rules.yml | 2 ++ .../system/g1_components/CMakeLists.txt | 4 +-- .../components/test_utils/CMakeLists.txt | 2 +- 33 files changed, 74 insertions(+), 50 deletions(-) create mode 100644 components/esp_driver_pcnt/CMakeLists.txt rename components/{driver/pcnt => esp_driver_pcnt}/Kconfig.pcnt (100%) rename components/{driver/pcnt => esp_driver_pcnt}/include/driver/pulse_cnt.h (100%) create mode 100644 components/esp_driver_pcnt/linker.lf rename components/{driver/pcnt => esp_driver_pcnt/src}/pulse_cnt.c (98%) create mode 100644 components/esp_driver_pcnt/test_apps/.build-test-rules.yml rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/CMakeLists.txt (87%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/README.md (100%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/main/CMakeLists.txt (71%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/main/test_app_main.c (100%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/main/test_pulse_cnt.c (100%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/main/test_pulse_cnt_board.h (100%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/main/test_pulse_cnt_iram.c (100%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/main/test_pulse_cnt_simulator.c (100%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/pytest_pulse_cnt.py (100%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/sdkconfig.ci.iram_safe (100%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/sdkconfig.ci.release (100%) rename components/{driver => esp_driver_pcnt}/test_apps/pulse_cnt/sdkconfig.defaults (100%) diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index 4dc470e32195..bd0687aaa1c7 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -87,6 +87,7 @@ /components/esp_bootloader_format/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities /components/esp_coex/ @esp-idf-codeowners/wifi @esp-idf-codeowners/bluetooth @esp-idf-codeowners/ieee802154 /components/esp_common/ @esp-idf-codeowners/system +/components/esp_driver_*/ @esp-idf-codeowners/peripherals /components/esp_eth/ @esp-idf-codeowners/network /components/esp_event/ @esp-idf-codeowners/system /components/esp_gdbstub/ @esp-idf-codeowners/debugging diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 9d43f985511e..78c96e3e9aac 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -23,7 +23,6 @@ set(includes "include" "ledc/include" "mcpwm/include" "parlio/include" - "pcnt/include" "rmt/include" "sdio_slave/include" "sdmmc/include" @@ -150,10 +149,9 @@ if(CONFIG_SOC_MCPWM_SUPPORTED) list(APPEND ldfragments "mcpwm/linker.lf") endif() -# PCNT related source files +# PCNT legacy driver if(CONFIG_SOC_PCNT_SUPPORTED) - list(APPEND srcs "pcnt/pulse_cnt.c" - "deprecated/pcnt_legacy.c") + list(APPEND srcs "deprecated/pcnt_legacy.c") endif() # RMT related source files @@ -245,6 +243,9 @@ else() INCLUDE_DIRS ${includes} PRIV_REQUIRES efuse esp_timer esp_mm REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support + # for backward compatibility, the driver component needs to + # have a public dependency on other "esp_driver_foo" components + esp_driver_pcnt LDFRAGMENTS ${ldfragments} ) endif() diff --git a/components/driver/Kconfig b/components/driver/Kconfig index 4936d2fc73d6..0394f995695e 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -227,7 +227,7 @@ menu "Driver Configurations" orsource "./gptimer/Kconfig.gptimer" - orsource "./pcnt/Kconfig.pcnt" + orsource "../esp_driver_pcnt/Kconfig.pcnt" orsource "./rmt/Kconfig.rmt" diff --git a/components/driver/linker.lf b/components/driver/linker.lf index ae09bf19a9c3..6c90eff1f4cf 100644 --- a/components/driver/linker.lf +++ b/components/driver/linker.lf @@ -1,11 +1,6 @@ [mapping:driver] archive: libdriver.a entries: - if PCNT_CTRL_FUNC_IN_IRAM = y: - pulse_cnt: pcnt_unit_start (noflash) - pulse_cnt: pcnt_unit_stop (noflash) - pulse_cnt: pcnt_unit_clear_count (noflash) - pulse_cnt: pcnt_unit_get_count (noflash) if SDM_CTRL_FUNC_IN_IRAM = y: sdm: sdm_channel_set_pulse_density (noflash) if ANA_CMPR_CTRL_FUNC_IN_IRAM = y: diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index 98a33dbdf742..12824f054541 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -113,10 +113,6 @@ components/driver/test_apps/parlio: temporary: true reason: lack of runner -components/driver/test_apps/pulse_cnt: - disable: - - if: SOC_PCNT_SUPPORTED != 1 - components/driver/test_apps/rmt: disable: - if: SOC_RMT_SUPPORTED != 1 diff --git a/components/driver/test_apps/dac_test_apps/dac/main/CMakeLists.txt b/components/driver/test_apps/dac_test_apps/dac/main/CMakeLists.txt index 9ae8264930d4..369886c7ddf0 100644 --- a/components/driver/test_apps/dac_test_apps/dac/main/CMakeLists.txt +++ b/components/driver/test_apps/dac_test_apps/dac/main/CMakeLists.txt @@ -8,5 +8,5 @@ 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} - PRIV_REQUIRES unity driver esp_adc + PRIV_REQUIRES unity esp_driver_pcnt driver esp_adc WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt b/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt index 9e911f818e59..1e48b532a390 100644 --- a/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt +++ b/components/driver/test_apps/i2s_test_apps/i2s/main/CMakeLists.txt @@ -3,5 +3,5 @@ set(srcs "test_app_main.c" "test_i2s_iram.c") idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity driver spi_flash + PRIV_REQUIRES unity esp_driver_pcnt driver spi_flash WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt index 8a091fba5f54..4e1ae63f7d96 100644 --- a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/CMakeLists.txt @@ -2,5 +2,5 @@ set(srcs "test_app_main.c" "test_legacy_i2s.c") idf_component_register(SRCS ${srcs} - PRIV_REQUIRES unity driver + PRIV_REQUIRES unity esp_driver_pcnt driver WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/ledc/main/CMakeLists.txt b/components/driver/test_apps/ledc/main/CMakeLists.txt index 146642e5d3ee..5a5d4f716a4e 100644 --- a/components/driver/test_apps/ledc/main/CMakeLists.txt +++ b/components/driver/test_apps/ledc/main/CMakeLists.txt @@ -4,5 +4,5 @@ set(srcs "test_app_main.c" # 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} - PRIV_REQUIRES unity driver esp_timer esp_psram + PRIV_REQUIRES unity esp_driver_pcnt driver esp_timer esp_psram WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt b/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt index 8e3ba4f80434..bcdc50e5e683 100644 --- a/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt +++ b/components/driver/test_apps/legacy_mcpwm_driver/main/CMakeLists.txt @@ -4,5 +4,5 @@ set(srcs "test_app_main.c" # 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} - PRIV_REQUIRES unity driver + PRIV_REQUIRES unity esp_driver_pcnt driver WHOLE_ARCHIVE) diff --git a/components/esp_driver_pcnt/CMakeLists.txt b/components/esp_driver_pcnt/CMakeLists.txt new file mode 100644 index 000000000000..fa3864076f8c --- /dev/null +++ b/components/esp_driver_pcnt/CMakeLists.txt @@ -0,0 +1,17 @@ +set(srcs) +set(public_include "include") +if(CONFIG_SOC_PCNT_SUPPORTED) + list(APPEND srcs "src/pulse_cnt.c") +endif() + +if(BOOTLOADER_BUILD) + # Bootloader shall NOT depend on the drivers + idf_component_register() +else() + idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${public_include} + PRIV_REQUIRES "esp_pm" + "driver" # will be replaced by esp_driver_gpio + LDFRAGMENTS "linker.lf" + ) +endif() diff --git a/components/driver/pcnt/Kconfig.pcnt b/components/esp_driver_pcnt/Kconfig.pcnt similarity index 100% rename from components/driver/pcnt/Kconfig.pcnt rename to components/esp_driver_pcnt/Kconfig.pcnt diff --git a/components/driver/pcnt/include/driver/pulse_cnt.h b/components/esp_driver_pcnt/include/driver/pulse_cnt.h similarity index 100% rename from components/driver/pcnt/include/driver/pulse_cnt.h rename to components/esp_driver_pcnt/include/driver/pulse_cnt.h diff --git a/components/esp_driver_pcnt/linker.lf b/components/esp_driver_pcnt/linker.lf new file mode 100644 index 000000000000..13556e6a9c1e --- /dev/null +++ b/components/esp_driver_pcnt/linker.lf @@ -0,0 +1,8 @@ +[mapping:pcnt_driver] +archive: libesp_driver_pcnt.a +entries: + if PCNT_CTRL_FUNC_IN_IRAM = y: + pulse_cnt: pcnt_unit_start (noflash) + pulse_cnt: pcnt_unit_stop (noflash) + pulse_cnt: pcnt_unit_clear_count (noflash) + pulse_cnt: pcnt_unit_get_count (noflash) diff --git a/components/driver/pcnt/pulse_cnt.c b/components/esp_driver_pcnt/src/pulse_cnt.c similarity index 98% rename from components/driver/pcnt/pulse_cnt.c rename to components/esp_driver_pcnt/src/pulse_cnt.c index fc2c0a709e83..ce9619de23ae 100644 --- a/components/driver/pcnt/pulse_cnt.c +++ b/components/esp_driver_pcnt/src/pulse_cnt.c @@ -192,7 +192,7 @@ esp_err_t pcnt_new_unit(const pcnt_unit_config_t *config, pcnt_unit_handle_t *re "invalid limit range:[%d,%d]", config->low_limit, config->high_limit); if (config->intr_priority) { ESP_GOTO_ON_FALSE(1 << (config->intr_priority) & PCNT_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, err, - TAG, "invalid interrupt priority:%d", config->intr_priority); + TAG, "invalid interrupt priority:%d", config->intr_priority); } unit = heap_caps_calloc(1, sizeof(pcnt_unit_t), PCNT_MEM_ALLOC_CAPS); @@ -225,8 +225,8 @@ esp_err_t pcnt_new_unit(const pcnt_unit_config_t *config, pcnt_unit_handle_t *re isr_flags |= PCNT_ALLOW_INTR_PRIORITY_MASK; } ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(pcnt_periph_signals.groups[group_id].irq, isr_flags, - (uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id), - pcnt_default_isr, unit, &unit->intr), err, + (uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id), + pcnt_default_isr, unit, &unit->intr), err, TAG, "install interrupt service failed"); } @@ -488,8 +488,8 @@ esp_err_t pcnt_unit_register_event_callbacks(pcnt_unit_handle_t unit, const pcnt isr_flags |= PCNT_ALLOW_INTR_PRIORITY_MASK; } ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(pcnt_periph_signals.groups[group_id].irq, isr_flags, - (uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id), - pcnt_default_isr, unit, &unit->intr), + (uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id), + pcnt_default_isr, unit, &unit->intr), TAG, "install interrupt service failed"); } // enable/disable PCNT interrupt events diff --git a/components/esp_driver_pcnt/test_apps/.build-test-rules.yml b/components/esp_driver_pcnt/test_apps/.build-test-rules.yml new file mode 100644 index 000000000000..d94a1f9237b4 --- /dev/null +++ b/components/esp_driver_pcnt/test_apps/.build-test-rules.yml @@ -0,0 +1,7 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/esp_driver_pcnt/test_apps/pulse_cnt: + disable: + - if: SOC_PCNT_SUPPORTED != 1 + depends_components: + - esp_driver_pcnt diff --git a/components/driver/test_apps/pulse_cnt/CMakeLists.txt b/components/esp_driver_pcnt/test_apps/pulse_cnt/CMakeLists.txt similarity index 87% rename from components/driver/test_apps/pulse_cnt/CMakeLists.txt rename to components/esp_driver_pcnt/test_apps/pulse_cnt/CMakeLists.txt index 46dee2c382ec..aac95204843f 100644 --- a/components/driver/test_apps/pulse_cnt/CMakeLists.txt +++ b/components/esp_driver_pcnt/test_apps/pulse_cnt/CMakeLists.txt @@ -10,7 +10,7 @@ project(pcnt_test) if(CONFIG_COMPILER_DUMP_RTL_FILES) add_custom_target(check_test_app_sections ALL COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py - --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_pcnt/,${CMAKE_BINARY_DIR}/esp-idf/hal/ --elf-file ${CMAKE_BINARY_DIR}/pcnt_test.elf find-refs --from-sections=.iram0.text diff --git a/components/driver/test_apps/pulse_cnt/README.md b/components/esp_driver_pcnt/test_apps/pulse_cnt/README.md similarity index 100% rename from components/driver/test_apps/pulse_cnt/README.md rename to components/esp_driver_pcnt/test_apps/pulse_cnt/README.md diff --git a/components/driver/test_apps/pulse_cnt/main/CMakeLists.txt b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/CMakeLists.txt similarity index 71% rename from components/driver/test_apps/pulse_cnt/main/CMakeLists.txt rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/CMakeLists.txt index a7ee53f40d7a..82fd92109556 100644 --- a/components/driver/test_apps/pulse_cnt/main/CMakeLists.txt +++ b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/CMakeLists.txt @@ -9,5 +9,6 @@ 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} - PRIV_REQUIRES unity driver spi_flash + PRIV_REQUIRES unity esp_driver_pcnt spi_flash + driver # will be replaced by esp_driver_gpio WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/pulse_cnt/main/test_app_main.c b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_app_main.c similarity index 100% rename from components/driver/test_apps/pulse_cnt/main/test_app_main.c rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_app_main.c diff --git a/components/driver/test_apps/pulse_cnt/main/test_pulse_cnt.c b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt.c similarity index 100% rename from components/driver/test_apps/pulse_cnt/main/test_pulse_cnt.c rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt.c diff --git a/components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_board.h b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_board.h similarity index 100% rename from components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_board.h rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_board.h diff --git a/components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_iram.c b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_iram.c similarity index 100% rename from components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_iram.c rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_iram.c diff --git a/components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_simulator.c b/components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_simulator.c similarity index 100% rename from components/driver/test_apps/pulse_cnt/main/test_pulse_cnt_simulator.c rename to components/esp_driver_pcnt/test_apps/pulse_cnt/main/test_pulse_cnt_simulator.c diff --git a/components/driver/test_apps/pulse_cnt/pytest_pulse_cnt.py b/components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py similarity index 100% rename from components/driver/test_apps/pulse_cnt/pytest_pulse_cnt.py rename to components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py diff --git a/components/driver/test_apps/pulse_cnt/sdkconfig.ci.iram_safe b/components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.ci.iram_safe similarity index 100% rename from components/driver/test_apps/pulse_cnt/sdkconfig.ci.iram_safe rename to components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.ci.iram_safe diff --git a/components/driver/test_apps/pulse_cnt/sdkconfig.ci.release b/components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.ci.release similarity index 100% rename from components/driver/test_apps/pulse_cnt/sdkconfig.ci.release rename to components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.ci.release diff --git a/components/driver/test_apps/pulse_cnt/sdkconfig.defaults b/components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.defaults similarity index 100% rename from components/driver/test_apps/pulse_cnt/sdkconfig.defaults rename to components/esp_driver_pcnt/test_apps/pulse_cnt/sdkconfig.defaults diff --git a/components/esp_timer/CMakeLists.txt b/components/esp_timer/CMakeLists.txt index 0129826de1f7..faf80921d3b2 100644 --- a/components/esp_timer/CMakeLists.txt +++ b/components/esp_timer/CMakeLists.txt @@ -1,28 +1,24 @@ idf_build_get_property(target IDF_TARGET) if(${target} STREQUAL "linux") -idf_component_register(INCLUDE_DIRS include) + idf_component_register(INCLUDE_DIRS include) else() + set(srcs "src/esp_timer.c" + "src/ets_timer_legacy.c" + "src/system_time.c" + "src/esp_timer_impl_common.c") -set(srcs "src/esp_timer.c" - "src/ets_timer_legacy.c" - "src/system_time.c" - "src/esp_timer_impl_common.c") + if(CONFIG_ESP_TIMER_IMPL_TG0_LAC) + list(APPEND srcs "src/esp_timer_impl_lac.c") + elseif(CONFIG_ESP_TIMER_IMPL_SYSTIMER) + list(APPEND srcs "src/esp_timer_impl_systimer.c") + endif() -if(CONFIG_ESP_TIMER_IMPL_TG0_LAC) - list(APPEND srcs "src/esp_timer_impl_lac.c") -elseif(CONFIG_ESP_TIMER_IMPL_SYSTIMER) - list(APPEND srcs "src/esp_timer_impl_systimer.c") -endif() - -if(CONFIG_SOC_SYSTIMER_SUPPORT_ETM) - list(APPEND srcs "src/esp_timer_etm.c") -endif() - -idf_component_register(SRCS "${srcs}" - INCLUDE_DIRS include - PRIV_INCLUDE_DIRS private_include - REQUIRES esp_common - PRIV_REQUIRES soc driver) + if(CONFIG_SOC_SYSTIMER_SUPPORT_ETM) + list(APPEND srcs "src/esp_timer_etm.c") + endif() + idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS include + PRIV_INCLUDE_DIRS private_include) endif() diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index f9a4a5cbb223..89d66714aa48 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -106,7 +106,6 @@ INPUT = \ $(PROJECT_PATH)/components/driver/mcpwm/include/driver/mcpwm_types.h \ $(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_tx.h \ $(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_types.h \ - $(PROJECT_PATH)/components/driver/pcnt/include/driver/pulse_cnt.h \ $(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_common.h \ $(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_encoder.h \ $(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_rx.h \ @@ -140,6 +139,7 @@ INPUT = \ $(PROJECT_PATH)/components/esp_common/include/esp_check.h \ $(PROJECT_PATH)/components/esp_common/include/esp_err.h \ $(PROJECT_PATH)/components/esp_common/include/esp_idf_version.h \ + $(PROJECT_PATH)/components/esp_driver_pcnt/include/driver/pulse_cnt.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_com.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_driver.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_mac.h \ diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 5141971ac67d..414bdf75c586 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -193,6 +193,8 @@ examples/peripherals/parlio/simple_rgb_led_matrix: examples/peripherals/pcnt: disable: - if: SOC_PCNT_SUPPORTED != 1 + depends_components: + - esp_driver_pcnt examples/peripherals/rmt: disable: diff --git a/tools/test_apps/system/g1_components/CMakeLists.txt b/tools/test_apps/system/g1_components/CMakeLists.txt index 2c1925c027d2..204005e1cdea 100644 --- a/tools/test_apps/system/g1_components/CMakeLists.txt +++ b/tools/test_apps/system/g1_components/CMakeLists.txt @@ -33,9 +33,9 @@ set(extra_components_which_shouldnt_be_included bootloader_support # [refactor-todo]: should cxx be in G1? Can it exist without FreeRTOS? cxx - # [refactor-todo]: driver is a dependency of esp_pm, esp_timer, spi_flash, vfs, esp_wifi, ${IDF_TARGET} + # [refactor-todo]: driver is a dependency of esp_pm, spi_flash, vfs, esp_wifi # all of these should be removed from G1 except for spi_flash. - driver + driver esp_driver_pcnt # esp_app_format is dependency of bootloader_support, app_update esp_app_format # esp_bootloader_format is dependency of bootloader_support, app_update diff --git a/tools/unit-test-app/components/test_utils/CMakeLists.txt b/tools/unit-test-app/components/test_utils/CMakeLists.txt index 27748db9ed2b..8a50233d5747 100644 --- a/tools/unit-test-app/components/test_utils/CMakeLists.txt +++ b/tools/unit-test-app/components/test_utils/CMakeLists.txt @@ -16,5 +16,5 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS include REQUIRES esp_partition idf_test cmock - PRIV_REQUIRES perfmon driver esp_netif) + PRIV_REQUIRES perfmon esp_driver_pcnt driver esp_netif) target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") From eb37150780cd0943247c47b206abda9d15f10359 Mon Sep 17 00:00:00 2001 From: Fu Hanxi Date: Wed, 18 Oct 2023 10:23:19 +0200 Subject: [PATCH 012/161] ci: add all nightly run env vars while checking --- .gitlab/ci/common.yml | 1 + examples/system/.build-test-rules.yml | 8 +++++++- tools/ci/check_build_test_rules.py | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.gitlab/ci/common.yml b/.gitlab/ci/common.yml index 1d661428c0e4..56b2a767fc16 100644 --- a/.gitlab/ci/common.yml +++ b/.gitlab/ci/common.yml @@ -97,6 +97,7 @@ variables: if echo "$CI_MERGE_REQUEST_LABELS" | egrep "(^|,)include_nightly_run(,|$)"; then export INCLUDE_NIGHTLY_RUN="1" + export NIGHTLY_RUN="1" fi # configure cmake related flags diff --git a/examples/system/.build-test-rules.yml b/examples/system/.build-test-rules.yml index 897380b8bc05..10fc5a153783 100644 --- a/examples/system/.build-test-rules.yml +++ b/examples/system/.build-test-rules.yml @@ -66,6 +66,10 @@ examples/system/esp_timer: - if: IDF_TARGET in ["esp32p4"] temporary: true reason: target(s) is not supported yet # TODO: IDF-7529 + disable_test: + - if: IDF_TARGET in ["esp32c6", "esp32h2"] + temporary: true + reason: lack of runner depends_components: - esp_timer @@ -188,8 +192,10 @@ examples/system/ota/simple_ota_example: examples/system/perfmon: enable: - - if: IDF_TARGET in ["esp32", "esp32s2", "esp32s3"] + - if: IDF_TARGET in ["esp32", "esp32s2", "esp32s3"] and NIGHTLY_RUN == "1" reason: xtensa only feature + - if: IDF_TARGET == "esp32" + reason: testing on a single target is sufficient depends_components: - perfmon diff --git a/tools/ci/check_build_test_rules.py b/tools/ci/check_build_test_rules.py index 11e964d1cb05..080ce2ad550f 100755 --- a/tools/ci/check_build_test_rules.py +++ b/tools/ci/check_build_test_rules.py @@ -481,6 +481,7 @@ def check_exist() -> None: ) if arg.action == 'check-readmes': + os.environ['INCLUDE_NIGHTLY_RUN'] = '1' os.environ['NIGHTLY_RUN'] = '1' check_readme( list(check_dirs), @@ -489,6 +490,7 @@ def check_exist() -> None: ) elif arg.action == 'check-test-scripts': os.environ['INCLUDE_NIGHTLY_RUN'] = '1' + os.environ['NIGHTLY_RUN'] = '1' check_test_scripts( list(check_dirs), exclude_dirs=_exclude_dirs, From 27681a507373522f0a84fa0478eeab4921d1930b Mon Sep 17 00:00:00 2001 From: Harshit Malpani Date: Wed, 4 Oct 2023 12:19:43 +0530 Subject: [PATCH 013/161] fix(esp-tls): Use TLS 1.2 and TLS 1.3 simultaneously This commit fixes the issue with TLS 1.2 connection when TLS 1.3 is enabled in config. --- components/esp-tls/esp_tls.h | 11 ++++++ components/esp-tls/esp_tls_mbedtls.c | 35 +++++++++++++------ components/esp_http_client/esp_http_client.c | 6 ++++ .../esp_http_client/include/esp_http_client.h | 11 ++++++ .../tcp_transport/include/esp_transport_ssl.h | 8 +++++ components/tcp_transport/transport_ssl.c | 6 ++++ 6 files changed, 67 insertions(+), 10 deletions(-) diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index 957792500436..92e7dbfcf73b 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -81,6 +81,16 @@ typedef enum esp_tls_addr_family { ESP_TLS_AF_INET6, /**< IPv6 address family. */ } esp_tls_addr_family_t; +/* +* @brief ESP-TLS TLS Protocol version +*/ +typedef enum { + ESP_TLS_VER_ANY = 0, /* No preference */ + ESP_TLS_VER_TLS_1_2 = 0x1, /* (D)TLS 1.2 */ + ESP_TLS_VER_TLS_1_3 = 0x2, /* (D)TLS 1.3 */ + ESP_TLS_VER_TLS_MAX, /* to indicate max */ +} esp_tls_proto_ver_t; + /** * @brief ESP-TLS configuration parameters * @@ -200,6 +210,7 @@ typedef struct esp_tls_cfg { esp_tls_addr_family_t addr_family; /*!< The address family to use when connecting to a host. */ const int *ciphersuites_list; /*!< Pointer to a zero-terminated array of IANA identifiers of TLS ciphersuites. Please check the list validity by esp_tls_get_ciphersuites_list() API */ + esp_tls_proto_ver_t tls_version; /*!< TLS protocol version of the connection, e.g., TLS 1.2, TLS 1.3 (default - no preference) */ } esp_tls_cfg_t; #ifdef CONFIG_ESP_TLS_SERVER diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index d0a250846095..c2730d2df5b4 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -97,6 +97,24 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const ESP_LOGE(TAG, "Failed to set client configurations, returned [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); goto exit; } + const esp_tls_proto_ver_t tls_ver = ((esp_tls_cfg_t *)cfg)->tls_version; + if (tls_ver == ESP_TLS_VER_TLS_1_3) { +#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 + ESP_LOGD(TAG, "Setting TLS version to 0x%4x", MBEDTLS_SSL_VERSION_TLS1_3); + mbedtls_ssl_conf_min_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3); + mbedtls_ssl_conf_max_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3); +#else + ESP_LOGW(TAG, "TLS 1.3 is not enabled in config, continuing with default TLS protocol"); +#endif + } else if (tls_ver == ESP_TLS_VER_TLS_1_2) { + ESP_LOGD(TAG, "Setting TLS version to 0x%4x", MBEDTLS_SSL_VERSION_TLS1_2); + mbedtls_ssl_conf_min_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_2); + mbedtls_ssl_conf_max_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_2); + } else if (tls_ver != ESP_TLS_VER_ANY) { + ESP_LOGE(TAG, "Unsupported protocol version"); + esp_ret = ESP_ERR_INVALID_ARG; + goto exit; + } } else if (tls->role == ESP_TLS_SERVER) { #ifdef CONFIG_ESP_TLS_SERVER esp_ret = set_server_config((esp_tls_cfg_server_t *) cfg, tls); @@ -125,11 +143,6 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const mbedtls_esp_enable_debug_log(&tls->conf, CONFIG_MBEDTLS_DEBUG_LEVEL); #endif -#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - mbedtls_ssl_conf_min_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3); - mbedtls_ssl_conf_max_tls_version(&tls->conf, MBEDTLS_SSL_VERSION_TLS1_3); -#endif - if ((ret = mbedtls_ssl_setup(&tls->ssl, &tls->conf)) != 0) { ESP_LOGE(TAG, "mbedtls_ssl_setup returned -0x%04X", -ret); mbedtls_print_error_msg(ret); @@ -233,15 +246,17 @@ ssize_t esp_mbedtls_read(esp_tls_t *tls, char *data, size_t datalen) { ssize_t ret = mbedtls_ssl_read(&tls->ssl, (unsigned char *)data, datalen); -#if CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 && CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS +#if CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS // If a post-handshake message is received, connection state is changed to `MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET` // Call mbedtls_ssl_read() till state is `MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET` or return code is `MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET` // to process session tickets in TLS 1.3 connection - while (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET || tls->ssl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET) { - ESP_LOGD(TAG, "got session ticket in TLS 1.3 connection, retry read"); - ret = mbedtls_ssl_read(&tls->ssl, (unsigned char *)data, datalen); + if (mbedtls_ssl_get_version_number(&tls->ssl) == MBEDTLS_SSL_VERSION_TLS1_3) { + while (ret == MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET || tls->ssl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET) { + ESP_LOGD(TAG, "got session ticket in TLS 1.3 connection, retry read"); + ret = mbedtls_ssl_read(&tls->ssl, (unsigned char *)data, datalen); + } } -#endif // CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 && CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS +#endif // CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS if (ret < 0) { if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { diff --git a/components/esp_http_client/esp_http_client.c b/components/esp_http_client/esp_http_client.c index 460470a1f8c7..8f91ef3b05e0 100644 --- a/components/esp_http_client/esp_http_client.c +++ b/components/esp_http_client/esp_http_client.c @@ -9,6 +9,7 @@ #include #include "esp_log.h" +#include "esp_assert.h" #include "esp_check.h" #include "http_parser.h" #include "http_header.h" @@ -20,6 +21,7 @@ #include "esp_http_client.h" #include "errno.h" #include "esp_random.h" +#include "esp_tls.h" #ifdef CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS #include "esp_transport_ssl.h" @@ -29,6 +31,9 @@ ESP_EVENT_DEFINE_BASE(ESP_HTTP_CLIENT_EVENT); static const char *TAG = "HTTP_CLIENT"; +ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_ANY == (int)ESP_TLS_VER_ANY, "Enum mismatch in esp_http_client and esp-tls"); +ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_MAX <= (int)ESP_TLS_VER_TLS_MAX, "HTTP client supported TLS is not supported in esp-tls"); + /** * HTTP Buffer */ @@ -723,6 +728,7 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co esp_transport_ssl_set_client_cert_data_der(ssl, config->client_cert_pem, config->client_cert_len); } } + esp_transport_ssl_set_tls_version(ssl, config->tls_version); #if CONFIG_ESP_TLS_USE_SECURE_ELEMENT if (config->use_secure_element) { diff --git a/components/esp_http_client/include/esp_http_client.h b/components/esp_http_client/include/esp_http_client.h index 6135976d5689..06bee3dda823 100644 --- a/components/esp_http_client/include/esp_http_client.h +++ b/components/esp_http_client/include/esp_http_client.h @@ -78,6 +78,16 @@ typedef enum { HTTP_TRANSPORT_OVER_SSL, /*!< Transport over ssl */ } esp_http_client_transport_t; +/* +* @brief TLS Protocol version +*/ +typedef enum { + ESP_HTTP_CLIENT_TLS_VER_ANY = 0, /* No preference */ + ESP_HTTP_CLIENT_TLS_VER_TLS_1_2 = 0x1, /* (D)TLS 1.2 */ + ESP_HTTP_CLIENT_TLS_VER_TLS_1_3 = 0x2, /* (D)TLS 1.3 */ + ESP_HTTP_CLIENT_TLS_VER_MAX, /* to indicate max */ +} esp_http_client_proto_ver_t; + typedef esp_err_t (*http_event_handle_cb)(esp_http_client_event_t *evt); /** @@ -133,6 +143,7 @@ typedef struct { size_t client_key_len; /*!< Length of the buffer pointed to by client_key_pem. May be 0 for null-terminated pem */ const char *client_key_password; /*!< Client key decryption password string */ size_t client_key_password_len; /*!< String length of the password pointed to by client_key_password */ + esp_http_client_proto_ver_t tls_version; /*!< TLS protocol version of the connection, e.g., TLS 1.2, TLS 1.3 (default - no preference) */ #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN bool use_ecdsa_peripheral; /*!< Use ECDSA peripheral to use private key. */ uint8_t ecdsa_key_efuse_blk; /*!< The efuse block where ECDSA key is stored. */ diff --git a/components/tcp_transport/include/esp_transport_ssl.h b/components/tcp_transport/include/esp_transport_ssl.h index 1d3fbc7d0e47..00a76e043b13 100644 --- a/components/tcp_transport/include/esp_transport_ssl.h +++ b/components/tcp_transport/include/esp_transport_ssl.h @@ -61,6 +61,14 @@ void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((* */ void esp_transport_ssl_enable_global_ca_store(esp_transport_handle_t t); +/** + * @brief Set TLS protocol version for ESP-TLS connection + * + * @param t ssl transport + * @param[in] tls_version TLS version + */ +void esp_transport_ssl_set_tls_version(esp_transport_handle_t t, esp_tls_proto_ver_t tls_version); + /** * @brief Set SSL client certificate data for mutual authentication (as PEM format). * Note that, this function stores the pointer to data, rather than making a copy. diff --git a/components/tcp_transport/transport_ssl.c b/components/tcp_transport/transport_ssl.c index bf484b1b0e4b..0d5228442c5d 100644 --- a/components/tcp_transport/transport_ssl.c +++ b/components/tcp_transport/transport_ssl.c @@ -341,6 +341,12 @@ void esp_transport_ssl_enable_global_ca_store(esp_transport_handle_t t) ssl->cfg.use_global_ca_store = true; } +void esp_transport_ssl_set_tls_version(esp_transport_handle_t t, esp_tls_proto_ver_t tls_version) +{ + GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t); + ssl->cfg.tls_version = tls_version; +} + #ifdef CONFIG_ESP_TLS_PSK_VERIFICATION void esp_transport_ssl_set_psk_key_hint(esp_transport_handle_t t, const psk_hint_key_t *psk_hint_key) { From 2da0b61374b30c0d1ecae6ffd90c6ea4361ccdf5 Mon Sep 17 00:00:00 2001 From: Harshit Malpani Date: Thu, 5 Oct 2023 12:10:46 +0530 Subject: [PATCH 014/161] fix: Update https_mbedtls example to fix TLS v1.2 connection --- .../protocols/https_mbedtls/main/https_mbedtls_example_main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c index e65b656c4bcd..32118ffad588 100644 --- a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c +++ b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c @@ -128,10 +128,6 @@ static void https_get_task(void *pvParameters) mbedtls_esp_enable_debug_log(&conf, CONFIG_MBEDTLS_DEBUG_LEVEL); #endif -#ifdef CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 - mbedtls_ssl_conf_min_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_3); - mbedtls_ssl_conf_max_tls_version(&conf, MBEDTLS_SSL_VERSION_TLS1_3); -#endif if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) { ESP_LOGE(TAG, "mbedtls_ssl_setup returned -0x%x", -ret); From 8bc69e03545c9c91d515b7ec093a60db0c820a90 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 23 Oct 2023 21:24:56 +0800 Subject: [PATCH 015/161] fix(esp_system): increase esp32h2 slow clock calibration timeout watchdog threshold --- components/esp_system/port/soc/esp32h2/clk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index 4aa76ca57bb1..5546b1cd8d68 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -55,13 +55,13 @@ static const char *TAG = "clk"; #ifdef CONFIG_BOOTLOADER_WDT_ENABLE // WDT uses a SLOW_CLK clock source. After a function select_rtc_slow_clk a frequency of this source can changed. // If the frequency changes from 150kHz to 32kHz, then the timeout set for the WDT will increase 4.6 times. - // Therefore, for the time of frequency change, set a new lower timeout value (1.6 sec). + // Therefore, for the time of frequency change, set a new lower timeout value (2 sec). // This prevents excessive delay before resetting in case the supply voltage is drawdown. - // (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 1.6sec * 150/32 = 7.5 sec). + // (If frequency is changed from 150kHz to 32kHz then WDT timeout will increased to 2 sec * 150/32 = 9.375 sec). wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; - uint32_t stage_timeout_ticks = (uint32_t)(1600ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); + uint32_t stage_timeout_ticks = (uint32_t)(2000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); wdt_hal_write_protect_disable(&rtc_wdt_ctx); wdt_hal_feed(&rtc_wdt_ctx); //Bootloader has enabled RTC WDT until now. We're only modifying timeout, so keep the stage and timeout action the same From d98e77a4a7ae9990d6e667ca533bfabe92cc57a5 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Tue, 17 Oct 2023 12:05:22 +0800 Subject: [PATCH 016/161] ci: run build_docs jobs after target tests on protected branches On master running costly build docs jobs for every pipeline uses a lot of resources. This refactor moves the build doc stage after target tests for protected branches. For regular MRs we still get the desired behavior of build docs being independent of targets tests, as we dont want developers to have to pass all target tests to test their doc changes. --- .gitlab/ci/common.yml | 2 +- .gitlab/ci/docs.yml | 62 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/.gitlab/ci/common.yml b/.gitlab/ci/common.yml index 61e71d493b7a..84ba056e7387 100644 --- a/.gitlab/ci/common.yml +++ b/.gitlab/ci/common.yml @@ -6,9 +6,9 @@ stages: - pre_check - build - assign_test - - build_doc - target_test - host_test + - build_doc - test_deploy - deploy - post_deploy diff --git a/.gitlab/ci/docs.yml b/.gitlab/ci/docs.yml index 72409404f2f3..c0b5c6604bf4 100644 --- a/.gitlab/ci/docs.yml +++ b/.gitlab/ci/docs.yml @@ -37,16 +37,25 @@ .if-dev-push: &if-dev-push if: '$CI_COMMIT_REF_NAME != "master" && $CI_COMMIT_BRANCH !~ /^release\/v/ && $CI_COMMIT_TAG !~ /^v\d+\.\d+(\.\d+)?($|-)/ && $CI_COMMIT_TAG !~ /^qa-test/ && ($CI_PIPELINE_SOURCE == "push" || $CI_PIPELINE_SOURCE == "merge_request_event")' +.if-schedule: &if-schedule + if: '$CI_PIPELINE_SOURCE == "schedule"' + .doc-rules:build:docs-full: rules: - <<: *if-qa-test-tag when: never - - <<: *if-protected + - <<: *if-schedule - <<: *if-label-build_docs - <<: *if-label-docs_full - <<: *if-dev-push changes: *patterns-docs-full +.doc-rules:build:docs-full-prod: + rules: + - <<: *if-qa-test-tag + when: never + - <<: *if-protected-no_label + .doc-rules:build:docs-partial: rules: - <<: *if-qa-test-tag @@ -83,10 +92,6 @@ check_docs_lang_sync: stage: build_doc tags: - build_docs - needs: - - job: fast_template_app - artifacts: false - optional: true script: - cd docs - build-docs -t $DOCTGT -bs $DOC_BUILDERS -l $DOCLANG build @@ -110,6 +115,23 @@ build_docs_html_full: extends: - .build_docs_template - .doc-rules:build:docs-full + needs: + - job: fast_template_app + artifacts: false + optional: true + artifacts: + when: always + paths: + - docs/_build/*/*/*.txt + - docs/_build/*/*/html/* + expire_in: 4 days + variables: + DOC_BUILDERS: "html" + +build_docs_html_full_prod: + extends: + - .build_docs_template + - .doc-rules:build:docs-full-prod artifacts: when: always paths: @@ -123,6 +145,10 @@ build_docs_html_partial: extends: - .build_docs_template - .doc-rules:build:docs-partial + needs: + - job: fast_template_app + artifacts: false + optional: true artifacts: when: always paths: @@ -142,6 +168,22 @@ build_docs_pdf: extends: - .build_docs_template - .doc-rules:build:docs-full + needs: + - job: fast_template_app + artifacts: false + optional: true + artifacts: + when: always + paths: + - docs/_build/*/*/latex/* + expire_in: 4 days + variables: + DOC_BUILDERS: "latex" + +build_docs_pdf_prod: + extends: + - .build_docs_template + - .doc-rules:build:docs-full-prod artifacts: when: always paths: @@ -194,13 +236,12 @@ deploy_docs_production: # The DOCS_PROD_* variables used by this job are "Protected" so these branches must all be marked "Protected" in Gitlab settings extends: - .deploy_docs_template - rules: - - <<: *if-protected-no_label + - .doc-rules:build:docs-full-prod stage: post_deploy dependencies: # set dependencies to null to avoid missing artifacts issue needs: # ensure runs after push_to_github succeeded - - build_docs_html_full - - build_docs_pdf + - build_docs_html_full_prod + - build_docs_pdf_prod - job: push_to_github artifacts: false variables: @@ -215,8 +256,7 @@ deploy_docs_production: check_doc_links: extends: - .build_docs_template - rules: - - <<: *if-protected-no_label + - .doc-rules:build:docs-full-prod stage: post_deploy needs: - job: deploy_docs_production From 8c52b0845d36317181ff19f9d4c0ee5aec7466ea Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Tue, 24 Oct 2023 10:04:09 +0800 Subject: [PATCH 017/161] feat(linux_target): enable hello world example for linux target --- components/spi_flash/CMakeLists.txt | 3 +- components/spi_flash/linux/spi_flash_linux.c | 13 +++++ examples/get-started/.build-test-rules.yml | 2 +- examples/get-started/hello_world/README.md | 4 +- .../hello_world/pytest_hello_world.py | 8 ++- tools/test_apps/.build-test-rules.yml | 4 -- .../CMakeLists.txt | 7 --- .../hello_world_linux_compatible/README.md | 45 ----------------- .../main/CMakeLists.txt | 2 - .../main/hello_world_main.c | 49 ------------------- .../pytest_hello_world_linux_compatible.py | 17 ------- .../sdkconfig.defaults | 0 12 files changed, 25 insertions(+), 129 deletions(-) create mode 100644 components/spi_flash/linux/spi_flash_linux.c delete mode 100644 tools/test_apps/linux_compatible/hello_world_linux_compatible/CMakeLists.txt delete mode 100644 tools/test_apps/linux_compatible/hello_world_linux_compatible/README.md delete mode 100644 tools/test_apps/linux_compatible/hello_world_linux_compatible/main/CMakeLists.txt delete mode 100644 tools/test_apps/linux_compatible/hello_world_linux_compatible/main/hello_world_main.c delete mode 100644 tools/test_apps/linux_compatible/hello_world_linux_compatible/pytest_hello_world_linux_compatible.py delete mode 100644 tools/test_apps/linux_compatible/hello_world_linux_compatible/sdkconfig.defaults diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 013759a3dbd8..2d686a25235d 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -1,6 +1,7 @@ idf_build_get_property(target IDF_TARGET) if(${target} STREQUAL "linux") - idf_component_register(INCLUDE_DIRS include + idf_component_register(SRCS "linux/spi_flash_linux.c" + INCLUDE_DIRS include PRIV_INCLUDE_DIRS include/spi_flash) return() endif() diff --git a/components/spi_flash/linux/spi_flash_linux.c b/components/spi_flash/linux/spi_flash_linux.c new file mode 100644 index 000000000000..e40846803432 --- /dev/null +++ b/components/spi_flash/linux/spi_flash_linux.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_flash.h" + +esp_err_t esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size) +{ + (void)chip; + *out_size = UINT32_MAX; + return ESP_OK; +} diff --git a/examples/get-started/.build-test-rules.yml b/examples/get-started/.build-test-rules.yml index 0e70fd65b4b9..0d1df0e98bd8 100644 --- a/examples/get-started/.build-test-rules.yml +++ b/examples/get-started/.build-test-rules.yml @@ -8,4 +8,4 @@ examples/get-started/blink: examples/get-started/hello_world: enable: - - if: INCLUDE_DEFAULT == 1 + - if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "linux" diff --git a/examples/get-started/hello_world/README.md b/examples/get-started/hello_world/README.md index 8bbda44cc6de..29171c316c8c 100644 --- a/examples/get-started/hello_world/README.md +++ b/examples/get-started/hello_world/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | Linux | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | ----- | # Hello World Example diff --git a/examples/get-started/hello_world/pytest_hello_world.py b/examples/get-started/hello_world/pytest_hello_world.py index e7380003dcba..caeeff16b792 100644 --- a/examples/get-started/hello_world/pytest_hello_world.py +++ b/examples/get-started/hello_world/pytest_hello_world.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import hashlib @@ -21,6 +21,12 @@ def test_hello_world( log_minimum_free_heap_size() +@pytest.mark.linux +@pytest.mark.host_test +def test_hello_world_linux(dut: IdfDut) -> None: + dut.expect('Hello world!') + + def verify_elf_sha256_embedding(app: QemuApp, sha256_reported: str) -> None: sha256 = hashlib.sha256() with open(app.elf_file, 'rb') as f: diff --git a/tools/test_apps/.build-test-rules.yml b/tools/test_apps/.build-test-rules.yml index f659a0a6377b..5cf3291d28ff 100644 --- a/tools/test_apps/.build-test-rules.yml +++ b/tools/test_apps/.build-test-rules.yml @@ -15,10 +15,6 @@ tools/test_apps/linux_compatible/driver_mock: enable: - if: IDF_TARGET == "linux" -tools/test_apps/linux_compatible/hello_world_linux_compatible: - enable: - - if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "linux" - tools/test_apps/linux_compatible/linux_freertos: enable: - if: IDF_TARGET == "linux" diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/CMakeLists.txt b/tools/test_apps/linux_compatible/hello_world_linux_compatible/CMakeLists.txt deleted file mode 100644 index 9e0d431d4cea..000000000000 --- a/tools/test_apps/linux_compatible/hello_world_linux_compatible/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# 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(hello_world) diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/README.md b/tools/test_apps/linux_compatible/hello_world_linux_compatible/README.md deleted file mode 100644 index c0152d054161..000000000000 --- a/tools/test_apps/linux_compatible/hello_world_linux_compatible/README.md +++ /dev/null @@ -1,45 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | Linux | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | ----- | - -# Hello World Example Compatible with POSIX-port - -This is a version of the "Hello World" example compatible with the linux target. Just by using `idf.py (--preview) set-target `, it can be compiled for chip targets as well as for the [FreeRTOS POSIX/Linux simulator](https://www.freertos.org/FreeRTOS-simulator-for-Linux.html), i.e., for running it on Linux. The applications can then be run on the chosen target. - -## Requirements - -If you want to use this example on Linux, you need a Linux machine as host. The remaining requirements are the same requirements as for [Unit Testing on Linux (using cmock)](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/linux-host-testing.html#requirements), except you do not need Ruby. - -## How to use example - -### Configure the project - -No special configuration is required, we also do not recommend changing configuration when compiled for the POSIX/Linux simulator as this is still in preview. If you have to configure something, use the usual IDF menuconfig: -``` -idf.py menuconfig -``` - -### Build and Flash - -You can compile this example for chip targets, e.g. ESP32 and then run it by using: -``` -idf.py set-target esp32 -idf.py build -idf.py -p flash monitor -``` - -If you want to build this example for the linux target and run it, use the same commands except setting the linux target and omitting the flash command: -``` -idf.py --preview set-target linux -idf.by build -idf.py monitor -``` -The linux target is still in preview, hence the necessary `--preview` argument. Flashing can be omitted on Linux. - - -## Example folder contents - -The files in this project have the same structure as the files in the [original Hello World application](../../../../examples/get-started/hello_world/). - -## Example Output - -The output is similar to the output of the [original Hello World application](../../../../examples/get-started/hello_world/), except that no chip information is printed and there won't be any bootloader output on the linux target. diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/CMakeLists.txt b/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/CMakeLists.txt deleted file mode 100644 index 07686dc8e114..000000000000 --- a/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "hello_world_main.c" - INCLUDE_DIRS "") diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/hello_world_main.c b/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/hello_world_main.c deleted file mode 100644 index d8696bba6e14..000000000000 --- a/tools/test_apps/linux_compatible/hello_world_linux_compatible/main/hello_world_main.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: CC0-1.0 - */ - -#include -#include -#include "sdkconfig.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_chip_info.h" -#include "esp_system.h" - -void app_main(void) -{ - printf("Hello world!\n"); - - /* Print chip information */ - esp_chip_info_t chip_info; - uint32_t flash_size; - esp_chip_info(&chip_info); - printf("This is %s chip with %d CPU core(s), WiFi%s%s%s, ", - CONFIG_IDF_TARGET, - chip_info.cores, - (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", - (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "", - (chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4 (Zigbee/Thread)" : ""); - - unsigned major_rev = chip_info.revision / 100; - unsigned minor_rev = chip_info.revision % 100; - printf("silicon revision v%d.%d, ", major_rev, minor_rev); - - /* get_flash_size API not available on Linux*/ - flash_size = UINT32_MAX; - - printf("%" PRIu32 "MB %s flash\n", flash_size / (uint32_t)(1024 * 1024), - (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external"); - - printf("Minimum free heap size: %" PRIu32 " bytes\n", esp_get_minimum_free_heap_size()); - - for (int i = 10; i >= 0; i--) { - printf("Restarting in %d seconds...\n", i); - vTaskDelay(1000 / portTICK_PERIOD_MS); - } - printf("Restarting now.\n"); - fflush(stdout); - esp_restart(); -} diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/pytest_hello_world_linux_compatible.py b/tools/test_apps/linux_compatible/hello_world_linux_compatible/pytest_hello_world_linux_compatible.py deleted file mode 100644 index a73a140314b5..000000000000 --- a/tools/test_apps/linux_compatible/hello_world_linux_compatible/pytest_hello_world_linux_compatible.py +++ /dev/null @@ -1,17 +0,0 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: CC0-1.0 - -import pytest -from pytest_embedded_idf.dut import IdfDut - - -@pytest.mark.supported_targets -@pytest.mark.generic -def test_hello_world_linux_compatible(dut: IdfDut) -> None: - dut.expect('Hello world!') - - -@pytest.mark.linux -@pytest.mark.host_test -def test_hello_world_linux(dut: IdfDut) -> None: - dut.expect('Hello world!') diff --git a/tools/test_apps/linux_compatible/hello_world_linux_compatible/sdkconfig.defaults b/tools/test_apps/linux_compatible/hello_world_linux_compatible/sdkconfig.defaults deleted file mode 100644 index e69de29bb2d1..000000000000 From 9804a8b0f9bd21f84c63a68015e6e9abfce16cc8 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Wed, 18 Oct 2023 14:59:29 +0800 Subject: [PATCH 018/161] fix(ble/controller): Fix bugs in setting adv data and scan response data --- components/bt/controller/lib_esp32c3_family | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family index 7fb979154bec..af6be404ea58 160000 --- a/components/bt/controller/lib_esp32c3_family +++ b/components/bt/controller/lib_esp32c3_family @@ -1 +1 @@ -Subproject commit 7fb979154bec81163d55aa4e3134425aea0d52ab +Subproject commit af6be404ea583da57f9a4f0dfe7e02351ff5aa0d From 83152215232b048aa510330eae2ef17d1bd8041d Mon Sep 17 00:00:00 2001 From: Xiao Xufeng Date: Tue, 24 Oct 2023 02:52:51 +0800 Subject: [PATCH 019/161] fix(spi): fixed undesired touching to DMA Closes https://github.com/espressif/esp-idf/issues/12241 --- components/hal/spi_hal.c | 4 +++- components/hal/spi_slave_hal.c | 4 +++- components/hal/spi_slave_hd_hal.c | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/components/hal/spi_hal.c b/components/hal/spi_hal.c index d928fe997e48..25b77b8ef6b3 100644 --- a/components/hal/spi_hal.c +++ b/components/hal/spi_hal.c @@ -71,7 +71,9 @@ void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id, const spi_hal_config spi_ll_set_mosi_free_level(hw, 0); #endif spi_ll_master_init(hw); - s_spi_hal_dma_init_config(hal); + if (config->dma_enabled) { + s_spi_hal_dma_init_config(hal); + } //Force a transaction done interrupt. This interrupt won't fire yet because //we initialized the SPI interrupt as disabled. This way, we can just diff --git a/components/hal/spi_slave_hal.c b/components/hal/spi_slave_hal.c index 7c437a0b3fa3..9d61e12042af 100644 --- a/components/hal/spi_slave_hal.c +++ b/components/hal/spi_slave_hal.c @@ -41,7 +41,9 @@ void spi_slave_hal_init(spi_slave_hal_context_t *hal, const spi_slave_hal_config hal->dma_in = hal_config->dma_in; hal->dma_out = hal_config->dma_out; - s_spi_slave_hal_dma_init_config(hal); + if (hal->use_dma) { + s_spi_slave_hal_dma_init_config(hal); + } spi_ll_slave_init(hal->hw); //Force a transaction done interrupt. This interrupt won't fire yet because we initialized the SPI interrupt as diff --git a/components/hal/spi_slave_hd_hal.c b/components/hal/spi_slave_hd_hal.c index c2bf88a5597b..81a5bf5dfacc 100644 --- a/components/hal/spi_slave_hd_hal.c +++ b/components/hal/spi_slave_hd_hal.c @@ -71,7 +71,9 @@ void spi_slave_hd_hal_init(spi_slave_hd_hal_context_t *hal, const spi_slave_hd_h hal->rx_dma_head = &hal->rx_dummy_head; //Configure slave - s_spi_slave_hd_hal_dma_init_config(hal); + if (hal_config->dma_enabled) { + s_spi_slave_hd_hal_dma_init_config(hal); + } spi_ll_slave_hd_init(hw); spi_ll_set_addr_bitlen(hw, hal_config->address_bits); From 7e8181b976305c29ed74af937ae47258940277ad Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Tue, 24 Oct 2023 12:25:20 +0800 Subject: [PATCH 020/161] ci(heap): reduce the number of test apps built --- .../heap/test_apps/.build-test-rules.yml | 9 ++++ .../heap/test_apps/heap_tests/pytest_heap.py | 43 +++++-------------- .../heap_tests/sdkconfig.ci.abort_alloc_fail | 1 - .../heap_tests/sdkconfig.ci.func_hooks | 1 - ....8bit_access => sdkconfig.ci.misc_options} | 2 + 5 files changed, 22 insertions(+), 34 deletions(-) delete mode 100644 components/heap/test_apps/heap_tests/sdkconfig.ci.abort_alloc_fail delete mode 100644 components/heap/test_apps/heap_tests/sdkconfig.ci.func_hooks rename components/heap/test_apps/heap_tests/{sdkconfig.ci.8bit_access => sdkconfig.ci.misc_options} (59%) diff --git a/components/heap/test_apps/.build-test-rules.yml b/components/heap/test_apps/.build-test-rules.yml index e323365b5619..1e3b8ecd8cf2 100644 --- a/components/heap/test_apps/.build-test-rules.yml +++ b/components/heap/test_apps/.build-test-rules.yml @@ -2,8 +2,17 @@ components/heap/test_apps/heap_tests: disable: + - if: IDF_TARGET == "linux" - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 - if: CONFIG_NAME == "psram_all_ext" and SOC_SPIRAM_SUPPORTED != 1 + # These 3 configs are build only for non-nightly, buildig for a single target is sufficient + - if: CONFIG_NAME == "no_poisoning" and (IDF_TARGET != "esp32" and NIGHTLY_RUN != "1") + - if: CONFIG_NAME == "light_poisoning" and (IDF_TARGET != "esp32" and NIGHTLY_RUN != "1") + - if: CONFIG_NAME == "comprehensive_poisoning" and (IDF_TARGET != "esp32" and NIGHTLY_RUN != "1") + # Non-target specific functionality, only test on a single target in default pipeline + - if: CONFIG_NAME == "in_flash" and (IDF_TARGET != "esp32c6" and NIGHTLY_RUN != "1") + depends_components: + - heap components/heap/test_apps/host_test_linux: enable: diff --git a/components/heap/test_apps/heap_tests/pytest_heap.py b/components/heap/test_apps/heap_tests/pytest_heap.py index 1c51d22fd442..c3684eff2d8c 100644 --- a/components/heap/test_apps/heap_tests/pytest_heap.py +++ b/components/heap/test_apps/heap_tests/pytest_heap.py @@ -39,8 +39,7 @@ def test_heap_poisoning_qemu(dut: Dut) -> None: @pytest.mark.generic -@pytest.mark.esp32 -@pytest.mark.esp32c6 +@pytest.mark.supported_targets @pytest.mark.parametrize( 'config', [ @@ -71,27 +70,21 @@ def test_heap(dut: Dut) -> None: @pytest.mark.parametrize( 'config', [ - 'abort_alloc_fail' + 'misc_options' ] ) -def test_heap_abort_on_alloc_failure(dut: Dut) -> None: +def test_heap_misc_options(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') - dut.write('"When enabled, allocation operation failure generates an abort"') - dut.expect('Backtrace: ') + dut.write('"IRAM_8BIT capability test"') + dut.expect_unity_test_output() + dut.expect_exact("Enter next test, or 'enter' to see menu") + dut.write('"test allocation and free function hooks"') + dut.expect_unity_test_output() -@pytest.mark.generic -@pytest.mark.esp32 -@pytest.mark.parametrize( - 'config', - [ - '8bit_access' - ] -) -def test_heap_8bit_access(dut: Dut) -> None: - dut.expect_exact('Press ENTER to see the list of tests') - dut.write('"IRAM_8BIT capability test"') - dut.expect_unity_test_output(timeout=300) + dut.expect_exact("Enter next test, or 'enter' to see menu") + dut.write('"When enabled, allocation operation failure generates an abort"') + dut.expect('Backtrace: ') @pytest.mark.generic @@ -134,17 +127,3 @@ def test_memory_protection(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('[heap][mem_prot]') dut.expect_unity_test_output(timeout=300) - - -@pytest.mark.generic -@pytest.mark.esp32 -@pytest.mark.parametrize( - 'config', - [ - 'func_hooks' - ] -) -def test_heap_func_hooks(dut: Dut) -> None: - dut.expect_exact('Press ENTER to see the list of tests') - dut.write('"test allocation and free function hooks"') - dut.expect_unity_test_output(timeout=300) diff --git a/components/heap/test_apps/heap_tests/sdkconfig.ci.abort_alloc_fail b/components/heap/test_apps/heap_tests/sdkconfig.ci.abort_alloc_fail deleted file mode 100644 index 1dd2c31d3382..000000000000 --- a/components/heap/test_apps/heap_tests/sdkconfig.ci.abort_alloc_fail +++ /dev/null @@ -1 +0,0 @@ -CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS=y diff --git a/components/heap/test_apps/heap_tests/sdkconfig.ci.func_hooks b/components/heap/test_apps/heap_tests/sdkconfig.ci.func_hooks deleted file mode 100644 index 9a440b80dea7..000000000000 --- a/components/heap/test_apps/heap_tests/sdkconfig.ci.func_hooks +++ /dev/null @@ -1 +0,0 @@ -CONFIG_HEAP_USE_HOOKS=y diff --git a/components/heap/test_apps/heap_tests/sdkconfig.ci.8bit_access b/components/heap/test_apps/heap_tests/sdkconfig.ci.misc_options similarity index 59% rename from components/heap/test_apps/heap_tests/sdkconfig.ci.8bit_access rename to components/heap/test_apps/heap_tests/sdkconfig.ci.misc_options index 3cc667f53229..8e7394bf6801 100644 --- a/components/heap/test_apps/heap_tests/sdkconfig.ci.8bit_access +++ b/components/heap/test_apps/heap_tests/sdkconfig.ci.misc_options @@ -1,3 +1,5 @@ CONFIG_IDF_TARGET="esp32" CONFIG_FREERTOS_UNICORE=y CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY=y +CONFIG_HEAP_USE_HOOKS=y +CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS=y From 001b10ec4592881419b5672de5329add13618a48 Mon Sep 17 00:00:00 2001 From: DevinNorgarb Date: Mon, 23 Oct 2023 16:33:27 +0200 Subject: [PATCH 021/161] fix: corrected typo from disbale to disable in numerous places --- components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h | 2 +- components/bt/host/bluedroid/stack/btm/btm_ble_gap.c | 2 +- components/hal/esp32c3/include/hal/clk_tree_ll.h | 2 +- components/hal/esp32s2/include/hal/clk_tree_ll.h | 2 +- components/hal/esp32s3/include/hal/clk_tree_ll.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) 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 4ee8154affde..85020dbc345e 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 @@ -54,7 +54,7 @@ typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit #define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE 0 /*!< authentication disable*/ #define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE 1 /*!< authentication enable*/ -#define ESP_BLE_OOB_DISABLE 0 /*!< disbale the out of bond*/ +#define ESP_BLE_OOB_DISABLE 0 /*!< disable the out of bond*/ #define ESP_BLE_OOB_ENABLE 1 /*!< enable the out of bond*/ /// relate to BTM_IO_CAP_xxx in stack/btm_api.h 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 2ce4488e38e6..e4e7ec200246 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -4352,7 +4352,7 @@ void btm_ble_read_remote_features_complete(UINT8 *p) *******************************************************************************/ void btm_ble_write_adv_enable_complete(UINT8 *p) { - /* if write adv enable/disbale not succeed */ + /* if write adv enable/disable not succeed */ if (*p != HCI_SUCCESS) { BTM_TRACE_ERROR("%s failed", __func__); } diff --git a/components/hal/esp32c3/include/hal/clk_tree_ll.h b/components/hal/esp32c3/include/hal/clk_tree_ll.h index 57cd49fcdffa..6f1af60f561d 100644 --- a/components/hal/esp32c3/include/hal/clk_tree_ll.h +++ b/components/hal/esp32c3/include/hal/clk_tree_ll.h @@ -120,7 +120,7 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S; /* If xtal xpd software control is on */ bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S; - // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled + // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disabled bool enabled = !xtal_xpd_sw || xtal_xpd_st; return enabled; } diff --git a/components/hal/esp32s2/include/hal/clk_tree_ll.h b/components/hal/esp32s2/include/hal/clk_tree_ll.h index b0505b1ce28f..70aa45d34ef5 100644 --- a/components/hal/esp32s2/include/hal/clk_tree_ll.h +++ b/components/hal/esp32s2/include/hal/clk_tree_ll.h @@ -216,7 +216,7 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S; /* If xtal xpd software control is on */ bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S; - // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled + // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disabled bool enabled = !xtal_xpd_sw || xtal_xpd_st; return enabled; } diff --git a/components/hal/esp32s3/include/hal/clk_tree_ll.h b/components/hal/esp32s3/include/hal/clk_tree_ll.h index 369a4a2ee813..a3a23c41e2a4 100644 --- a/components/hal/esp32s3/include/hal/clk_tree_ll.h +++ b/components/hal/esp32s3/include/hal/clk_tree_ll.h @@ -122,7 +122,7 @@ static inline __attribute__((always_inline)) bool clk_ll_xtal32k_is_enabled(void bool xtal_xpd_sw = (xtal_conf & RTC_CNTL_XTAL32K_XPD_FORCE) >> RTC_CNTL_XTAL32K_XPD_FORCE_S; /* If xtal xpd software control is on */ bool xtal_xpd_st = (xtal_conf & RTC_CNTL_XPD_XTAL_32K) >> RTC_CNTL_XPD_XTAL_32K_S; - // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disbaled + // disabled = xtal_xpd_sw && !xtal_xpd_st; enabled = !disabled bool enabled = !xtal_xpd_sw || xtal_xpd_st; return enabled; } From 5727802497b0504167216932af6d08a392845c6e Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Tue, 24 Oct 2023 14:52:56 +0800 Subject: [PATCH 022/161] fix(bt/bluedroid): Optimize compatibility with IOS and MACOS devices --- components/esp_hid/src/ble_hidd.c | 4 ++-- examples/bluetooth/esp_hid_device/main/esp_hid_device_main.c | 3 +-- examples/bluetooth/esp_hid_device/main/esp_hid_gap.c | 4 +++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/components/esp_hid/src/ble_hidd.c b/components/esp_hid/src/ble_hidd.c index 249ac913e019..358ba7b7240a 100644 --- a/components/esp_hid/src/ble_hidd.c +++ b/components/esp_hid/src/ble_hidd.c @@ -282,7 +282,7 @@ static esp_err_t create_hid_db(esp_ble_hidd_dev_t *dev, int device_index) add_db_record(_last_db, HIDD_LE_IDX_HID_INFO_VAL, (uint8_t *)&s_hid_info_char_uuid, ESP_GATT_PERM_READ, 4, 4, (uint8_t *)hidInfo); add_db_record(_last_db, HIDD_LE_IDX_HID_CTNL_PT_CHAR, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_write_nr); - add_db_record(_last_db, HIDD_LE_IDX_HID_CTNL_PT_VAL, (uint8_t *)&s_hid_control_point_uuid, ESP_GATT_PERM_READ, 1, 0, NULL); + add_db_record(_last_db, HIDD_LE_IDX_HID_CTNL_PT_VAL, (uint8_t *)&s_hid_control_point_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 1, 0, NULL); add_db_record(_last_db, HIDD_LE_IDX_PROTO_MODE_CHAR, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read_write_nr); add_db_record(_last_db, HIDD_LE_IDX_PROTO_MODE_VAL, (uint8_t *)&s_hid_proto_mode_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 1, 1, (uint8_t *)&dev->protocol); @@ -301,7 +301,7 @@ static esp_err_t create_hid_db(esp_ble_hidd_dev_t *dev, int device_index) add_db_record(_last_db, index++, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read_notify); report->index = index; add_db_record(_last_db, index++, (uint8_t *)&s_hid_report_uuid, ESP_GATT_PERM_READ, report->value_len, 0, NULL); - add_db_record(_last_db, index++, (uint8_t *)&s_character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE, 2, 0, NULL); + add_db_record(_last_db, index++, (uint8_t *)&s_character_client_config_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE_ENCRYPTED, 2, 0, NULL); } else if (report->report_type == ESP_HID_REPORT_TYPE_OUTPUT) { //Output Report add_db_record(_last_db, index++, (uint8_t *)&s_character_declaration_uuid, ESP_GATT_PERM_READ, 1, 1, (uint8_t *)&s_char_prop_read_write_write_nr); 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 33bbfbe11dbb..a0f38c8a9289 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -344,7 +344,6 @@ static void ble_hidd_event_callback(void *handler_args, esp_event_base_t base, i } case ESP_HIDD_CONNECT_EVENT: { ESP_LOGI(TAG, "CONNECT"); - ble_hid_task_start_up();//todo: this should be on auth_complete (in GAP) break; } case ESP_HIDD_PROTOCOL_MODE_EVENT: { 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 f47933be25c5..1f0d2a460b7b 100644 --- a/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c +++ b/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c @@ -486,7 +486,7 @@ static esp_err_t start_bt_scan(uint32_t seconds) /* * BLE GAP * */ - +extern void ble_hid_task_start_up(void); static void ble_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { switch (event) { @@ -535,10 +535,12 @@ static void ble_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_p * */ case ESP_GAP_BLE_AUTH_CMPL_EVT: if (!param->ble_security.auth_cmpl.success) { + // if AUTH ERROR,hid maybe don't work. ESP_LOGE(TAG, "BLE GAP AUTH ERROR: 0x%x", param->ble_security.auth_cmpl.fail_reason); } else { ESP_LOGI(TAG, "BLE GAP AUTH SUCCESS"); } + ble_hid_task_start_up(); break; case ESP_GAP_BLE_KEY_EVT: //shows the ble key info share with peer device to the user. From b90dc6a515f69d9b9a2a9401f873186167f5562f Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Tue, 24 Oct 2023 15:17:26 +0800 Subject: [PATCH 023/161] feat(bt/bluedroid): Support hid device control point --- .../esp_hid_device/main/esp_hid_device_main.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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 a0f38c8a9289..94edd4d2c172 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 @@ -318,6 +318,10 @@ void ble_hid_demo_task(void *pvParameters) void ble_hid_task_start_up(void) { + if (s_ble_hid_param.task_hdl) { + // Task already exists + return; + } xTaskCreate(ble_hid_demo_task, "ble_hid_demo_task", 2 * 1024, NULL, configMAX_PRIORITIES - 3, &s_ble_hid_param.task_hdl); } @@ -352,7 +356,15 @@ static void ble_hidd_event_callback(void *handler_args, esp_event_base_t base, i } case ESP_HIDD_CONTROL_EVENT: { ESP_LOGI(TAG, "CONTROL[%u]: %sSUSPEND", param->control.map_index, param->control.control ? "EXIT_" : ""); - break; + if (param->control.control) + { + // exit suspend + ble_hid_task_start_up(); + } else { + // suspend + ble_hid_task_shut_down(); + } + break; } case ESP_HIDD_OUTPUT_EVENT: { ESP_LOGI(TAG, "OUTPUT[%u]: %8s ID: %2u, Len: %d, Data:", param->output.map_index, esp_hid_usage_str(param->output.usage), param->output.report_id, param->output.length); From fa489d3c20e4f652a7789f6240a4175083014ee2 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Fri, 20 Oct 2023 15:02:56 +0800 Subject: [PATCH 024/161] change(Power Management): the xpd_xtal32k value depends on system slow clock source config option when pmu initialize --- components/esp_hw_support/port/esp32c6/pmu_param.c | 10 ++++++++-- .../port/esp32c6/private_include/pmu_param.h | 4 ++-- components/esp_hw_support/port/esp32h2/pmu_param.c | 8 +++++++- .../port/esp32h2/private_include/pmu_param.h | 4 ++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/components/esp_hw_support/port/esp32c6/pmu_param.c b/components/esp_hw_support/port/esp32c6/pmu_param.c index ccfc32b6ef63..af0e1c38b4eb 100644 --- a/components/esp_hw_support/port/esp32c6/pmu_param.c +++ b/components/esp_hw_support/port/esp32c6/pmu_param.c @@ -361,14 +361,20 @@ const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pm /** LP system default parameter */ +#if CONFIG_ESP_SYSTEM_RTC_EXT_XTAL +# define PMU_SLOW_CLK_USE_EXT_XTAL (1) +#else +# define PMU_SLOW_CLK_USE_EXT_XTAL (0) +#endif + #define PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT() { \ .dig_power = { \ .mem_dslp = 0, \ .peri_pd_en = 0, \ }, \ .clk_power = { \ - .xpd_xtal32k = 1, \ - .xpd_rc32k = 1, \ + .xpd_xtal32k = PMU_SLOW_CLK_USE_EXT_XTAL, \ + .xpd_rc32k = 0, \ .xpd_fosc = 1, \ .pd_osc = 0 \ } \ diff --git a/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h b/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h index f340c5ca05d0..0938e058b886 100644 --- a/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h @@ -285,8 +285,8 @@ typedef struct { .mem_dslp = 0 \ }, \ .clk_power = { \ - .xpd_xtal32k = 1, \ - .xpd_rc32k = 1, \ + .xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \ + .xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \ .xpd_fosc = 1 \ } \ }, \ diff --git a/components/esp_hw_support/port/esp32h2/pmu_param.c b/components/esp_hw_support/port/esp32h2/pmu_param.c index 83bf887aa31e..b0662d50f714 100644 --- a/components/esp_hw_support/port/esp32h2/pmu_param.c +++ b/components/esp_hw_support/port/esp32h2/pmu_param.c @@ -359,13 +359,19 @@ const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pm /** LP system default parameter */ +#if CONFIG_ESP_SYSTEM_RTC_EXT_XTAL +# define PMU_SLOW_CLK_USE_EXT_XTAL (1) +#else +# define PMU_SLOW_CLK_USE_EXT_XTAL (0) +#endif + #define PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT() { \ .dig_power = { \ .mem_dslp = 0, \ .peri_pd_en = 0, \ }, \ .clk_power = { \ - .xpd_xtal32k = 0, \ + .xpd_xtal32k = PMU_SLOW_CLK_USE_EXT_XTAL, \ .xpd_rc32k = 0, \ .xpd_fosc = 1, \ .pd_osc = 0 \ diff --git a/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h b/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h index b6f183522e13..824ccb9db71c 100644 --- a/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h @@ -280,8 +280,8 @@ typedef struct { .mem_dslp = 0 \ }, \ .clk_power = { \ - .xpd_xtal32k = 1, \ - .xpd_rc32k = 1, \ + .xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \ + .xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \ .xpd_fosc = 1 \ } \ }, \ From 3589478a9e595de9d890c1e27f654fce68a624f4 Mon Sep 17 00:00:00 2001 From: Zim Kalinowski Date: Tue, 24 Oct 2023 11:30:03 +0200 Subject: [PATCH 025/161] fix(esp_ringbuffer): Enable build on Linix --- components/esp_ringbuf/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/esp_ringbuf/CMakeLists.txt b/components/esp_ringbuf/CMakeLists.txt index 04ed12a0fb97..09bfac678b7d 100644 --- a/components/esp_ringbuf/CMakeLists.txt +++ b/components/esp_ringbuf/CMakeLists.txt @@ -1,9 +1,5 @@ idf_build_get_property(target IDF_TARGET) -if(${target} STREQUAL "linux") - return() # This component is not supported by the POSIX/Linux simulator -endif() - idf_component_register(SRCS "ringbuf.c" INCLUDE_DIRS "include" LDFRAGMENTS linker.lf) From 7532df427ad7c11671b8272981f3fa7040aff64b Mon Sep 17 00:00:00 2001 From: liuning Date: Tue, 24 Oct 2023 18:00:07 +0800 Subject: [PATCH 026/161] fix(rom): remove related rom funcs in c3 rom eco7 MR --- components/esp_rom/esp32c2/ld/esp32c2.rom.ld | 10 +++++----- components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld | 1 + components/esp_rom/esp32c3/ld/esp32c3.rom.ld | 2 +- components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld | 2 +- components/esp_rom/esp32s3/ld/esp32s3.rom.ld | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index 5a2367187e47..347425d8858d 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -1631,7 +1631,7 @@ ppDequeueTxDone_Locked = 0x40001d18; ppProcTxDone = 0x40001d1c; /*pm_tx_data_done_process = 0x40001d20;*/ config_is_cache_tx_buf_enabled = 0x40001d24; -ppMapWaitTxq = 0x40001d28; +//ppMapWaitTxq = 0x40001d28; ppProcessWaitingQueue = 0x40001d2c; ppDisableQueue = 0x40001d30; pm_allow_tx = 0x40001d34; @@ -1729,14 +1729,14 @@ pp_timer_do_process = 0x40001ea0; rcUpdateAMPDUParam = 0x40001ea4; rcUpdatePhyMode = 0x40001ea8; rcGetHighestRateIdx = 0x40001eac; -pm_tx_null_data_done_process = 0x40001eb0; -pm_tx_data_process = 0x40001eb4; +//pm_tx_null_data_done_process = 0x40001eb0; +//pm_tx_data_process = 0x40001eb4; /* pm_attach = 0x40001eb8; */ /* pm_coex_schm_process = 0x40001ebc; */ ppInitTxq = 0x40001ec0; pp_attach = 0x40001ec4; pp_deattach = 0x40001ec8; -pm_on_probe_resp_rx = 0x40001ecc; +//pm_on_probe_resp_rx = 0x40001ecc; hal_set_sta_tsf = 0x40001ed0; ic_update_sta_tsf = 0x40001ed4; ic_tx_pkt = 0x40001ed8; @@ -1915,7 +1915,7 @@ wifi_get_init_state = 0x40002088; /* cnx_coexist_timeout = 0x40002090; */ /* sta_recv_mgmt = 0x40002094;*/ ieee80211_send_setup = 0x40002098; -ieee80211_send_probereq = 0x4000209c; +//ieee80211_send_probereq = 0x4000209c; sta_auth_shared = 0x400020a4; /* cnx_coexist_timeout_process = 0x400020ac; */ ieee80211_alloc_challenge = 0x400020b0; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld index 8a1c7fc5453e..3aacbb3819fa 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld @@ -33,6 +33,7 @@ wDev_ProcessFiq = 0x400017f0; wDev_ProcessRxSucData = 0x400017f4; ppProcTxDone = 0x40001804; pm_tx_data_done_process = 0x40001808; +ppMapWaitTxq = 0x40001810; ieee80211_encap_esfbuf = 0x4000185c; sta_input = 0x40001870; ieee80211_crypto_decap = 0x4000189c; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index f897770b045e..742786df59b0 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -1644,7 +1644,7 @@ wdev_csi_len_align = 0x400017fc; ppDequeueTxDone_Locked = 0x40001800; /*pm_tx_data_done_process = 0x40001808;*/ config_is_cache_tx_buf_enabled = 0x4000180c; -ppMapWaitTxq = 0x40001810; +//ppMapWaitTxq = 0x40001810; ppProcessWaitingQueue = 0x40001814; ppDisableQueue = 0x40001818; pm_allow_tx = 0x4000181c; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld index 418df8e6c28f..8a75b13a0654 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -165,7 +165,7 @@ ppDequeueTxDone_Locked = 0x40000e14; //ppProcTxDone = 0x40000e18; //pm_tx_data_done_process = 0x40000e1c; config_is_cache_tx_buf_enabled = 0x40000e20; -ppMapWaitTxq = 0x40000e24; +//ppMapWaitTxq = 0x40000e24; ppProcessWaitingQueue = 0x40000e28; ppDisableQueue = 0x40000e2c; pm_allow_tx = 0x40000e30; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index af00ff50c22f..6ca2ab5010c1 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -1950,7 +1950,7 @@ ppDequeueTxDone_Locked = 0x40005940; /*ppProcTxDone = 0x4000594c;*/ /*pm_tx_data_done_process = 0x40005958;*/ config_is_cache_tx_buf_enabled = 0x40005964; -ppMapWaitTxq = 0x40005970; +//ppMapWaitTxq = 0x40005970; ppProcessWaitingQueue = 0x4000597c; ppDisableQueue = 0x40005988; pm_allow_tx = 0x40005994; From 8d639492f2f575e3bcc6e4e47bae0605ba5cee1d Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Tue, 24 Oct 2023 18:44:49 +0800 Subject: [PATCH 027/161] feat(i2c_slave): Add new implementation and API for I2C slave --- components/driver/CMakeLists.txt | 3 + components/driver/i2c/i2c_common.c | 48 +- components/driver/i2c/i2c_master.c | 31 +- components/driver/i2c/i2c_private.h | 38 +- components/driver/i2c/i2c_slave.c | 424 ++++++++++++++++++ .../driver/i2c/include/driver/i2c_master.h | 6 +- .../driver/i2c/include/driver/i2c_slave.h | 166 +++++++ .../driver/i2c/include/driver/i2c_types.h | 45 ++ components/hal/esp32/include/hal/i2c_ll.h | 24 +- components/hal/esp32c2/include/hal/i2c_ll.h | 10 +- components/hal/esp32c3/include/hal/i2c_ll.h | 53 ++- components/hal/esp32c6/include/hal/i2c_ll.h | 60 ++- components/hal/esp32h2/include/hal/i2c_ll.h | 60 ++- components/hal/esp32p4/include/hal/i2c_ll.h | 27 +- components/hal/esp32s2/include/hal/i2c_ll.h | 44 +- components/hal/esp32s3/include/hal/i2c_ll.h | 53 ++- components/hal/include/hal/i2c_types.h | 10 + .../esp32c3/include/soc/Kconfig.soc_caps.in | 12 + components/soc/esp32c3/include/soc/soc_caps.h | 3 + .../esp32c6/include/soc/Kconfig.soc_caps.in | 16 + components/soc/esp32c6/include/soc/soc_caps.h | 4 + .../esp32h2/include/soc/Kconfig.soc_caps.in | 16 + components/soc/esp32h2/include/soc/soc_caps.h | 4 + .../esp32p4/include/soc/Kconfig.soc_caps.in | 16 + components/soc/esp32p4/include/soc/soc_caps.h | 4 + .../esp32s3/include/soc/Kconfig.soc_caps.in | 8 + components/soc/esp32s3/include/soc/soc_caps.h | 2 + 27 files changed, 1046 insertions(+), 141 deletions(-) create mode 100644 components/driver/i2c/i2c_slave.c create mode 100644 components/driver/i2c/include/driver/i2c_slave.h diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 9d43f985511e..a6f049db789f 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -108,6 +108,9 @@ if(CONFIG_SOC_I2C_SUPPORTED) "i2c/i2c_master.c" "i2c/i2c_common.c" ) + if(CONFIG_SOC_I2C_SUPPORT_SLAVE) + list(APPEND srcs "i2c/i2c_slave.c") + endif() list(APPEND ldfragments "i2c/linker.lf") endif() diff --git a/components/driver/i2c/i2c_common.c b/components/driver/i2c/i2c_common.c index 5f90a695dfcd..f9cb44da5944 100644 --- a/components/driver/i2c/i2c_common.c +++ b/components/driver/i2c/i2c_common.c @@ -37,7 +37,7 @@ typedef struct i2c_platform_t { static i2c_platform_t s_i2c_platform = {}; // singleton platform -esp_err_t i2c_acquire_bus_handle(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_new_bus, i2c_bus_mode_t mode) +static esp_err_t s_i2c_bus_handle_aquire(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_new_bus, i2c_bus_mode_t mode) { #if CONFIG_I2C_ENABLE_DEBUG_LOG esp_log_level_set(TAG, ESP_LOG_DEBUG); @@ -76,15 +76,41 @@ esp_err_t i2c_acquire_bus_handle(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_ return ret; } -bool i2c_bus_occupied(i2c_port_num_t port_num) +static bool i2c_bus_occupied(i2c_port_num_t port_num) +{ + return s_i2c_platform.buses[port_num] != NULL; +} + +esp_err_t i2c_acquire_bus_handle(i2c_port_num_t port_num, i2c_bus_handle_t *i2c_new_bus, i2c_bus_mode_t mode) { bool bus_occupied = false; + bool bus_found = false; + esp_err_t ret = ESP_OK; _lock_acquire(&s_i2c_platform.mutex); - if (s_i2c_platform.buses[port_num]) { - bus_occupied = true; + if (port_num == -1) { + for (int i = 0; i < SOC_I2C_NUM; i++) { + bus_occupied = i2c_bus_occupied(i); + if (bus_occupied == false) { + ret = s_i2c_bus_handle_aquire(i, i2c_new_bus, mode); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "acquire bus failed"); + _lock_release(&s_i2c_platform.mutex); + return ret; + } + bus_found = true; + port_num = i; + break; + } + } + ESP_RETURN_ON_FALSE((bus_found == true), ESP_ERR_NOT_FOUND, TAG, "acquire bus failed, no free bus"); + } else { + ret = s_i2c_bus_handle_aquire(port_num, i2c_new_bus, mode); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "acquire bus failed"); + } } _lock_release(&s_i2c_platform.mutex); - return bus_occupied; + return ret; } esp_err_t i2c_release_bus_handle(i2c_bus_handle_t i2c_bus) @@ -205,12 +231,8 @@ esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle) .pull_up_en = handle->pull_up_enable ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, .pin_bit_mask = 1ULL << handle->sda_num, }; -#if CONFIG_IDF_TARGET_ESP32 - // on esp32, must enable internal pull-up - sda_conf.pull_up_en = GPIO_PULLUP_ENABLE; -#endif - ESP_RETURN_ON_ERROR(gpio_config(&sda_conf), TAG, "config GPIO failed"); ESP_RETURN_ON_ERROR(gpio_set_level(handle->sda_num, 1), TAG, "i2c sda pin set level failed"); + ESP_RETURN_ON_ERROR(gpio_config(&sda_conf), TAG, "config GPIO failed"); gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[handle->sda_num], PIN_FUNC_GPIO); esp_rom_gpio_connect_out_signal(handle->sda_num, i2c_periph_signal[port_id].sda_out_sig, 0, 0); esp_rom_gpio_connect_in_signal(handle->sda_num, i2c_periph_signal[port_id].sda_in_sig, 0); @@ -224,12 +246,8 @@ esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle) .pull_up_en = handle->pull_up_enable ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, .pin_bit_mask = 1ULL << handle->scl_num, }; -#if CONFIG_IDF_TARGET_ESP32 - // on esp32, must enable internal pull-up - scl_conf.pull_up_en = GPIO_PULLUP_ENABLE; -#endif - ESP_RETURN_ON_ERROR(gpio_config(&scl_conf), TAG, "config GPIO failed"); ESP_RETURN_ON_ERROR(gpio_set_level(handle->scl_num, 1), TAG, "i2c scl pin set level failed"); + ESP_RETURN_ON_ERROR(gpio_config(&scl_conf), TAG, "config GPIO failed"); gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[handle->scl_num], PIN_FUNC_GPIO); esp_rom_gpio_connect_out_signal(handle->scl_num, i2c_periph_signal[port_id].scl_out_sig, 0, 0); esp_rom_gpio_connect_in_signal(handle->scl_num, i2c_periph_signal[port_id].scl_in_sig, 0); diff --git a/components/driver/i2c/i2c_master.c b/components/driver/i2c/i2c_master.c index 929c7b45d95b..2fa24a020adb 100644 --- a/components/driver/i2c/i2c_master.c +++ b/components/driver/i2c/i2c_master.c @@ -35,7 +35,6 @@ #include "freertos/idf_additions.h" static const char *TAG = "i2c.master"; -static _lock_t s_i2c_bus_acquire; #define DIM(array) (sizeof(array)/sizeof(*array)) #define I2C_ADDRESS_TRANS_WRITE(device_address) (((device_address) << 1) | 0) @@ -785,39 +784,13 @@ esp_err_t i2c_new_master_bus(const i2c_master_bus_config_t *bus_config, i2c_mast ESP_RETURN_ON_FALSE(bus_config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE((bus_config->i2c_port < SOC_I2C_NUM || bus_config->i2c_port == -1), ESP_ERR_INVALID_ARG, TAG, "invalid i2c port number"); ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(bus_config->sda_io_num) && GPIO_IS_VALID_GPIO(bus_config->scl_io_num), ESP_ERR_INVALID_ARG, TAG, "invalid SDA/SCL pin number"); - bool bus_occupied = false; - bool bus_found = false; i2c_master = heap_caps_calloc(1, sizeof(i2c_master_bus_t) + 20 * sizeof(i2c_transaction_t), I2C_MEM_ALLOC_CAPS); ESP_RETURN_ON_FALSE(i2c_master, ESP_ERR_NO_MEM, TAG, "no memory for i2c master bus"); - _lock_acquire(&s_i2c_bus_acquire); - if (i2c_port_num == -1) { - for (int i = 0; i < SOC_I2C_NUM; i++) { - bus_occupied = i2c_bus_occupied(i); - if (bus_occupied == false) { - ret = i2c_acquire_bus_handle(i, &i2c_master->base, I2C_BUS_MODE_MASTER); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "acquire bus failed"); - _lock_release(&s_i2c_bus_acquire); - goto err; - } - bus_found = true; - i2c_port_num = i; - break; - } - } - ESP_GOTO_ON_FALSE((bus_found == true), ESP_ERR_NOT_FOUND, err, TAG, "acquire bus failed, no free bus"); - } else { - ret = i2c_acquire_bus_handle(i2c_port_num, &i2c_master->base, I2C_BUS_MODE_MASTER); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "acquire bus failed"); - _lock_release(&s_i2c_bus_acquire); - goto err; - } - } - _lock_release(&s_i2c_bus_acquire); + ESP_GOTO_ON_ERROR(i2c_acquire_bus_handle(i2c_port_num, &i2c_master->base, I2C_BUS_MODE_MASTER), err, TAG, "I2C bus acquire failed"); + i2c_port_num = i2c_master->base->port_num; i2c_hal_context_t *hal = &i2c_master->base->hal; i2c_master->base->scl_num = bus_config->scl_io_num; diff --git a/components/driver/i2c/i2c_private.h b/components/driver/i2c/i2c_private.h index bdf8e09a58de..8d4688562d81 100644 --- a/components/driver/i2c/i2c_private.h +++ b/components/driver/i2c/i2c_private.h @@ -16,6 +16,7 @@ #include "freertos/semphr.h" #include "freertos/task.h" #include "freertos/ringbuf.h" +#include "driver/i2c_slave.h" #include "esp_pm.h" #ifdef __cplusplus @@ -52,6 +53,7 @@ typedef struct i2c_bus_t i2c_bus_t; typedef struct i2c_master_bus_t i2c_master_bus_t; typedef struct i2c_bus_t *i2c_bus_handle_t; typedef struct i2c_master_dev_t i2c_master_dev_t; +typedef struct i2c_slave_dev_t i2c_slave_dev_t; typedef enum { I2C_BUS_MODE_MASTER = 0, @@ -153,6 +155,34 @@ struct i2c_master_dev_t { void *user_ctx; // Callback user context }; +typedef struct { + bool trans_complete; // Event of transaction complete + bool slave_stretch; // Event of slave stretch happens + bool addr_unmatch; // Event of address unmatched +} i2c_slave_evt_t; + +typedef struct { + uint8_t *buffer; // Pointer to the buffer need to be received in ISR + uint32_t rcv_fifo_cnt; // receive fifo count. +} i2c_slave_receive_t; + +struct i2c_slave_dev_t { + i2c_bus_t *base; // bus base class + SemaphoreHandle_t slv_rx_mux; // Mutex for slave rx direction + SemaphoreHandle_t slv_tx_mux; // Mutex for slave tx direction + RingbufHandle_t rx_ring_buf; // Handle for rx ringbuffer + RingbufHandle_t tx_ring_buf; // Handle for tx ringbuffer + uint8_t data_buf[SOC_I2C_FIFO_LEN]; // Data buffer for slave + uint32_t trans_data_length; // Send data length + i2c_slave_event_callbacks_t callbacks; // I2C slave callbacks + void *user_ctx; // Callback user context + i2c_slave_fifo_mode_t fifo_mode; // Slave fifo mode. + QueueHandle_t slv_evt_queue; // Event Queue used in slave nonfifo mode. + i2c_slave_evt_t slave_evt; // Slave event structure. + i2c_slave_receive_t receive_desc; // Slave receive descriptor + uint32_t already_receive_len; // Data length already received in ISR. +}; + /** * @brief Acquire I2C bus handle * @@ -198,14 +228,6 @@ esp_err_t i2c_select_periph_clock(i2c_bus_handle_t handle, i2c_clock_source_t cl */ esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle); -/** - * @brief Check whether I2C bus is occupied - * - * @param port_num I2C port number. - * @return true: occupied, otherwise, false. - */ -bool i2c_bus_occupied(i2c_port_num_t port_num); - #ifdef __cplusplus } #endif diff --git a/components/driver/i2c/i2c_slave.c b/components/driver/i2c/i2c_slave.c new file mode 100644 index 000000000000..e3bae30bc400 --- /dev/null +++ b/components/driver/i2c/i2c_slave.c @@ -0,0 +1,424 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_types.h" +#include "esp_intr_alloc.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/task.h" +#include "freertos/ringbuf.h" +#include "freertos/queue.h" +#include "hal/i2c_hal.h" +#include "soc/i2c_periph.h" +#include "esp_rom_gpio.h" +#include "driver/gpio.h" +#include "hal/gpio_ll.h" +#include "clk_ctrl_os.h" +#include "esp_private/esp_clk.h" +#include "driver/i2c_slave.h" +#include "i2c_private.h" +#include "esp_memory_utils.h" +#include "freertos/idf_additions.h" + +#if CONFIG_I2C_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif +#include "esp_log.h" +#include "esp_check.h" + +#define I2C_SLAVE_TIMEOUT_DEFAULT (32000) /* I2C slave timeout value, APB clock cycle number */ +#define I2C_FIFO_EMPTY_THRESH_VAL_DEFAULT (SOC_I2C_FIFO_LEN/2) +#define I2C_FIFO_FULL_THRESH_VAL_DEFAULT (SOC_I2C_FIFO_LEN/2) + +static const char *TAG = "i2c.slave"; + +static esp_err_t i2c_slave_bus_destroy(i2c_slave_dev_handle_t i2c_slave); + +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE +static IRAM_ATTR void s_i2c_handle_clock_stretch(i2c_slave_dev_handle_t i2c_slave) +{ + i2c_hal_context_t *hal = &i2c_slave->base->hal; + if (i2c_slave->callbacks.on_stretch_occur) { + i2c_slave_stretch_event_data_t evt = { 0 }; + i2c_hal_context_t *hal = &i2c_slave->base->hal; + i2c_ll_slave_get_stretch_cause(hal->dev, &evt.stretch_cause); + i2c_slave->callbacks.on_stretch_occur(i2c_slave, &evt, i2c_slave->user_ctx); + } + i2c_ll_slave_clear_stretch(hal->dev); +} +#endif + +static IRAM_ATTR void s_i2c_handle_rx_fifo_wm(i2c_slave_dev_handle_t i2c_slave, i2c_slave_receive_t *t) +{ + i2c_hal_context_t *hal = &i2c_slave->base->hal; + uint32_t rx_fifo_cnt; + i2c_ll_get_rxfifo_cnt(hal->dev, &rx_fifo_cnt); + i2c_ll_read_rxfifo(hal->dev, i2c_slave->data_buf, rx_fifo_cnt); + memcpy(t->buffer + i2c_slave->already_receive_len, i2c_slave->data_buf, rx_fifo_cnt); + i2c_slave->already_receive_len += rx_fifo_cnt; + t->rcv_fifo_cnt -= rx_fifo_cnt; +} + +static IRAM_ATTR void s_i2c_handle_complete(i2c_slave_dev_handle_t i2c_slave, i2c_slave_receive_t *t, BaseType_t *do_yield) +{ + i2c_hal_context_t *hal = &i2c_slave->base->hal; + uint32_t rx_fifo_cnt; + i2c_ll_get_rxfifo_cnt(hal->dev, &rx_fifo_cnt); + if (rx_fifo_cnt != 0) { + i2c_ll_read_rxfifo(hal->dev, i2c_slave->data_buf, t->rcv_fifo_cnt); + memcpy(t->buffer + i2c_slave->already_receive_len, i2c_slave->data_buf, t->rcv_fifo_cnt); + i2c_slave->already_receive_len += t->rcv_fifo_cnt; + t->rcv_fifo_cnt -= t->rcv_fifo_cnt; + } + if (i2c_slave->callbacks.on_recv_done) { + + i2c_slave_rx_done_event_data_t edata = { + .buffer = t->buffer, + }; + i2c_slave->callbacks.on_recv_done(i2c_slave, &edata, i2c_slave->user_ctx); + xSemaphoreGiveFromISR(i2c_slave->slv_rx_mux, do_yield); + i2c_ll_disable_intr_mask(hal->dev, I2C_LL_SLAVE_RX_EVENT_INTR); + } +} + +static IRAM_ATTR void s_i2c_handle_tx_fifo_wm(i2c_slave_dev_handle_t i2c_slave, BaseType_t *do_yield) +{ + i2c_hal_context_t *hal = &i2c_slave->base->hal; + uint32_t tx_fifo_rem; + i2c_ll_get_txfifo_len(hal->dev, &tx_fifo_rem); + size_t size = 0; + uint8_t *data = (uint8_t *) xRingbufferReceiveUpToFromISR(i2c_slave->tx_ring_buf, &size, tx_fifo_rem); + if (data) { + i2c_ll_write_txfifo(hal->dev, data, size); + vRingbufferReturnItemFromISR(i2c_slave->tx_ring_buf, data, do_yield); + } + if (size <= i2c_slave->trans_data_length) { + portENTER_CRITICAL_ISR(&i2c_slave->base->spinlock); + i2c_slave->trans_data_length -= size; + portEXIT_CRITICAL_ISR(&i2c_slave->base->spinlock); + if (i2c_slave->trans_data_length == 0) { + i2c_ll_slave_disable_tx_it(hal->dev); + } + } else { + ESP_DRAM_LOGE(TAG, "I2C TX BUFFER SIZE ERROR"); + } +} + +static IRAM_ATTR void s_slave_fifo_isr_handler(uint32_t int_mask, void *arg, BaseType_t *do_yield) +{ + i2c_slave_dev_handle_t i2c_slave = (i2c_slave_dev_handle_t) arg; +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + if (int_mask & I2C_INTR_STRETCH) { + s_i2c_handle_clock_stretch(i2c_slave); + } +#endif + i2c_slave_receive_t *t = &i2c_slave->receive_desc; + if (int_mask & I2C_INTR_SLV_RXFIFO_WM) { + s_i2c_handle_rx_fifo_wm(i2c_slave, t); + } + if (int_mask & I2C_INTR_SLV_COMPLETE) { + s_i2c_handle_complete(i2c_slave, t, do_yield); + } + if (int_mask & I2C_INTR_SLV_TXFIFO_WM) { + s_i2c_handle_tx_fifo_wm(i2c_slave, do_yield); + } +} + +static IRAM_ATTR void s_slave_nonfifo_isr_handler(uint32_t int_mask, void *arg, BaseType_t *do_yield) +{ + i2c_slave_dev_handle_t i2c_slave = (i2c_slave_dev_handle_t) arg; + i2c_hal_context_t *hal = &i2c_slave->base->hal; + if (int_mask & I2C_INTR_STRETCH) { + i2c_slave->slave_evt.slave_stretch = 1; + i2c_ll_slave_clear_stretch(hal->dev); + } + + if (int_mask & I2C_INTR_SLV_COMPLETE) { + i2c_slave->slave_evt.trans_complete = 1; + } + xQueueSendFromISR(i2c_slave->slv_evt_queue, &i2c_slave->slave_evt, do_yield); +} + +static IRAM_ATTR void s_slave_isr_handle_default(void *arg) +{ + i2c_slave_dev_handle_t i2c_slave = (i2c_slave_dev_handle_t) arg; + i2c_hal_context_t *hal = &i2c_slave->base->hal; + portBASE_TYPE HPTaskAwoken = pdFALSE; + uint32_t int_mask = 0; + + i2c_ll_get_intr_mask(hal->dev, &int_mask); + i2c_ll_clear_intr_mask(hal->dev, int_mask); + if (int_mask == 0) { + return; + } +#if SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + if (int_mask & I2C_INTR_UNMATCH) { + i2c_slave->slave_evt.addr_unmatch = 1; + ESP_DRAM_LOGE(TAG, "I2C address not match, trans failed"); + } +#endif + + if (i2c_slave->fifo_mode == I2C_SLAVE_NONFIFO) { + s_slave_nonfifo_isr_handler(int_mask, i2c_slave, &HPTaskAwoken); + } else { + s_slave_fifo_isr_handler(int_mask, i2c_slave, &HPTaskAwoken); + } + + //We only need to check here if there is a high-priority task needs to be switched. + if (HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR(); + } + +} + +esp_err_t i2c_new_slave_device(const i2c_slave_config_t *slave_config, i2c_slave_dev_handle_t *ret_handle) +{ +#if CONFIG_I2C_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif + esp_err_t ret = ESP_OK; + i2c_slave_dev_t *i2c_slave = NULL; + ESP_RETURN_ON_FALSE(slave_config && ret_handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(slave_config->sda_io_num) && GPIO_IS_VALID_GPIO(slave_config->scl_io_num), ESP_ERR_INVALID_ARG, TAG, "invalid SDA/SCL pin number"); + ESP_RETURN_ON_FALSE(slave_config->i2c_port < SOC_I2C_NUM || slave_config->i2c_port == -1, ESP_ERR_INVALID_ARG, TAG, "invalid i2c port number"); + ESP_RETURN_ON_FALSE((slave_config->send_buf_depth > 0), ESP_ERR_INVALID_ARG, TAG, "invalid SCL speed"); +#if SOC_I2C_SLAVE_SUPPORT_BROADCAST + ESP_GOTO_ON_FALSE(((slave_config->addr_bit_len != I2C_ADDR_BIT_LEN_10) || (!slave_config->flags.broadcast_en)), ESP_ERR_INVALID_STATE, err, TAG, "10bits address cannot used together with broadcast"); +#endif + + int i2c_port_num = slave_config->i2c_port; + i2c_slave = heap_caps_calloc(1, sizeof(i2c_slave_dev_t), I2C_MEM_ALLOC_CAPS); + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_NO_MEM, TAG, "no memory for i2c slave bus"); + + ESP_GOTO_ON_ERROR(i2c_acquire_bus_handle(i2c_port_num, &i2c_slave->base, I2C_BUS_MODE_SLAVE), err, TAG, "I2C bus acquire failed"); + + i2c_hal_context_t *hal = &i2c_slave->base->hal; + i2c_slave->base->scl_num = slave_config->scl_io_num; + i2c_slave->base->sda_num = slave_config->sda_io_num; +#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + i2c_slave->fifo_mode = (slave_config->flags.access_ram_en == true) ? I2C_SLAVE_NONFIFO : I2C_SLAVE_FIFO; +#endif + +#if SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + if (slave_config->flags.slave_unmatch_en) { + i2c_ll_enable_intr_mask(hal->dev, I2C_SLAVE_ADDR_UNMATCH_INT_ENA_M); + } +#endif + + ESP_GOTO_ON_ERROR(i2c_common_set_pins(i2c_slave->base), err, TAG, "i2c slave set pins failed"); + + i2c_slave->tx_ring_buf = xRingbufferCreateWithCaps(slave_config->send_buf_depth, RINGBUF_TYPE_BYTEBUF, I2C_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(i2c_slave->tx_ring_buf != NULL, ESP_ERR_INVALID_STATE, err, TAG, "ringbuffer create failed"); + + i2c_slave->slv_rx_mux = xSemaphoreCreateBinaryWithCaps(I2C_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(i2c_slave->slv_rx_mux, ESP_ERR_NO_MEM, err, TAG, "No memory for binary semaphore"); + i2c_slave->slv_tx_mux = xSemaphoreCreateBinaryWithCaps(I2C_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE(i2c_slave->slv_tx_mux, ESP_ERR_NO_MEM, err, TAG, "No memory for binary semaphore"); + i2c_slave->slv_evt_queue = xQueueCreateWithCaps(1, sizeof(i2c_slave_evt_t), I2C_MEM_ALLOC_CAPS); + ESP_GOTO_ON_FALSE((i2c_slave->slv_evt_queue != NULL), ESP_ERR_INVALID_STATE, err, TAG, "queue create failed"); + + int isr_flags = I2C_INTR_ALLOC_FLAG; + if (slave_config->intr_priority) { + isr_flags |= 1 << (slave_config->intr_priority); + } + ret = esp_intr_alloc_intrstatus(i2c_periph_signal[i2c_port_num].irq, I2C_INTR_ALLOC_FLAG, (uint32_t)i2c_ll_get_interrupt_status_reg(hal->dev), I2C_LL_SLAVE_EVENT_INTR, s_slave_isr_handle_default, i2c_slave, &i2c_slave->base->intr_handle); + ESP_GOTO_ON_ERROR(ret, err, TAG, "install i2c slave interrupt failed"); + + portENTER_CRITICAL(&i2c_slave->base->spinlock); + i2c_ll_clear_intr_mask(hal->dev, I2C_LL_SLAVE_EVENT_INTR); + i2c_hal_slave_init(hal); + +#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + if (i2c_slave->fifo_mode == I2C_SLAVE_NONFIFO) { + i2c_ll_slave_set_fifo_mode(hal->dev, false); + i2c_ll_enable_mem_access_nonfifo(hal->dev, true); + } else { + i2c_ll_slave_set_fifo_mode(hal->dev, true); + i2c_ll_enable_mem_access_nonfifo(hal->dev, false); + } +#endif + + //Default, we enable hardware filter + i2c_ll_set_source_clk(hal->dev, slave_config->clk_source); + bool addr_10bit_en = slave_config->addr_bit_len != I2C_ADDR_BIT_LEN_7; + i2c_ll_set_slave_addr(hal->dev, slave_config->slave_addr, addr_10bit_en); +#if SOC_I2C_SLAVE_SUPPORT_BROADCAST + i2c_ll_slave_broadcast_enable(hal->dev, slave_config->flags.broadcast_en); +#endif + i2c_ll_set_txfifo_empty_thr(hal->dev, I2C_FIFO_EMPTY_THRESH_VAL_DEFAULT); + i2c_ll_set_rxfifo_full_thr(hal->dev, I2C_FIFO_FULL_THRESH_VAL_DEFAULT); + // set timing for data + i2c_ll_set_sda_timing(hal->dev, 10, 10); + i2c_ll_set_tout(hal->dev, I2C_SLAVE_TIMEOUT_DEFAULT); + +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + i2c_ll_slave_enable_scl_stretch(hal->dev, slave_config->flags.stretch_en); +#endif + i2c_ll_slave_tx_auto_start_en(hal->dev, true); + + i2c_ll_update(hal->dev); + portEXIT_CRITICAL(&i2c_slave->base->spinlock); + + xSemaphoreGive(i2c_slave->slv_rx_mux); + xSemaphoreGive(i2c_slave->slv_tx_mux); + *ret_handle = i2c_slave; + return ESP_OK; + +err: + if (i2c_slave) { + i2c_slave_bus_destroy(i2c_slave); + } + return ret; +} + +static esp_err_t i2c_slave_bus_destroy(i2c_slave_dev_handle_t i2c_slave) +{ + if (i2c_slave) { + if (i2c_slave->slv_rx_mux) { + vSemaphoreDeleteWithCaps(i2c_slave->slv_rx_mux); + i2c_slave->slv_rx_mux = NULL; + } + if (i2c_slave->slv_tx_mux) { + vSemaphoreDeleteWithCaps(i2c_slave->slv_tx_mux); + i2c_slave->slv_tx_mux = NULL; + } + if (i2c_slave->tx_ring_buf) { + vRingbufferDeleteWithCaps(i2c_slave->tx_ring_buf); + i2c_slave->tx_ring_buf = NULL; + } + if (i2c_slave->slv_evt_queue) { + vQueueDeleteWithCaps(i2c_slave->slv_evt_queue); + } + i2c_release_bus_handle(i2c_slave->base); + } + + free(i2c_slave); + return ESP_OK; +} + +esp_err_t i2c_del_slave_device(i2c_slave_dev_handle_t i2c_slave) +{ + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_INVALID_ARG, TAG, "i2c slave not initialized"); + int port_id = i2c_slave->base->port_num; + ESP_LOGD(TAG, "del i2c bus(%d)", port_id); + ESP_RETURN_ON_ERROR(i2c_slave_bus_destroy(i2c_slave), TAG, "destroy i2c bus failed"); + return ESP_OK; +} + +esp_err_t i2c_slave_transmit(i2c_slave_dev_handle_t i2c_slave, const uint8_t *data, int size, int xfer_timeout_ms) +{ + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_INVALID_ARG, TAG, "i2c slave not initialized"); + ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "invalid data buffer"); + ESP_RETURN_ON_FALSE((i2c_slave->fifo_mode == I2C_SLAVE_FIFO), ESP_ERR_NOT_SUPPORTED, TAG, "non-fifo mode is not suppored in this API, please set access_ram_en to false"); + esp_err_t ret = ESP_OK; + i2c_hal_context_t *hal = &i2c_slave->base->hal; + TickType_t wait_ticks = (xfer_timeout_ms == -1) ? portMAX_DELAY : pdMS_TO_TICKS(xfer_timeout_ms); + + ESP_RETURN_ON_FALSE(xSemaphoreTake(i2c_slave->slv_tx_mux, wait_ticks) == pdTRUE, ESP_ERR_TIMEOUT, TAG, "transmit timeout"); + ESP_GOTO_ON_FALSE(xRingbufferSend(i2c_slave->tx_ring_buf, data, size, wait_ticks) == pdTRUE, ESP_ERR_INVALID_STATE, err, TAG, "no space in ringbuffer"); + portENTER_CRITICAL(&i2c_slave->base->spinlock); + i2c_slave->trans_data_length += size; + i2c_ll_enable_intr_mask(hal->dev, I2C_LL_SLAVE_TX_EVENT_INTR); + portEXIT_CRITICAL(&i2c_slave->base->spinlock); +err: + xSemaphoreGive(i2c_slave->slv_tx_mux); + return ret; +} + +esp_err_t i2c_slave_receive(i2c_slave_dev_handle_t i2c_slave, uint8_t *data, size_t receive_size) +{ + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_INVALID_ARG, TAG, "i2c slave not initialized"); + ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "invalid data buffer"); + ESP_RETURN_ON_FALSE((i2c_slave->fifo_mode == I2C_SLAVE_FIFO), ESP_ERR_NOT_SUPPORTED, TAG, "non-fifo mode is not suppored in this API, please set access_ram_en to false"); +#if CONFIG_I2C_ISR_IRAM_SAFE + ESP_RETURN_ON_FALSE(esp_ptr_internal(data), ESP_ERR_INVALID_ARG, TAG, "buffer must locate in internal RAM if IRAM_SAFE is enabled"); +#endif + i2c_hal_context_t *hal = &i2c_slave->base->hal; + + xSemaphoreTake(i2c_slave->slv_rx_mux, portMAX_DELAY); + i2c_slave_receive_t *t = &i2c_slave->receive_desc; + t->buffer = data; + t->rcv_fifo_cnt = receive_size; + i2c_slave->already_receive_len = 0; + // Clear all interrupt raw bits before enable, avoid previous bus data affects interrupt. + i2c_ll_clear_intr_mask(hal->dev, I2C_LL_SLAVE_RX_EVENT_INTR); + i2c_ll_enable_intr_mask(hal->dev, I2C_LL_SLAVE_RX_EVENT_INTR); + + return ESP_OK; +} + +#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + +esp_err_t i2c_slave_read_ram(i2c_slave_dev_handle_t i2c_slave, uint8_t ram_offset, uint8_t *data, size_t receive_size) +{ + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_INVALID_ARG, TAG, "i2c slave not initialized"); + ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "invalid data buffer"); + ESP_RETURN_ON_FALSE((ram_offset + receive_size <= SOC_I2C_FIFO_LEN), ESP_ERR_INVALID_SIZE, TAG, "don't read data cross fifo boundary, see `SOC_I2C_FIFO_LEN`"); + ESP_RETURN_ON_FALSE((i2c_slave->fifo_mode == I2C_SLAVE_NONFIFO), ESP_ERR_NOT_SUPPORTED, TAG, "fifo mode is not suppored in this API, please set access_ram_en to true"); + i2c_hal_context_t *hal = &i2c_slave->base->hal; + + uint32_t fifo_size = 0; + portENTER_CRITICAL(&i2c_slave->base->spinlock); + i2c_ll_get_rxfifo_cnt(hal->dev, &fifo_size); + if (receive_size > fifo_size) { + ESP_LOGE(TAG, "receive size is so large that fifo has not so much data to get"); + portEXIT_CRITICAL(&i2c_slave->base->spinlock); + return ESP_ERR_INVALID_SIZE; + } + i2c_ll_read_by_nonfifo(hal->dev, ram_offset, data, fifo_size); + portEXIT_CRITICAL(&i2c_slave->base->spinlock); + + return ESP_OK; +} + +esp_err_t i2c_slave_write_ram(i2c_slave_dev_handle_t i2c_slave, uint8_t ram_offset, const uint8_t *data, size_t size) +{ + ESP_RETURN_ON_FALSE(i2c_slave, ESP_ERR_INVALID_ARG, TAG, "i2c slave not initialized"); + ESP_RETURN_ON_FALSE(data, ESP_ERR_INVALID_ARG, TAG, "invalid data buffer"); + ESP_RETURN_ON_FALSE((i2c_slave->fifo_mode == I2C_SLAVE_NONFIFO), ESP_ERR_NOT_SUPPORTED, TAG, "fifo mode is not suppored in this API, please set access_ram_en to true"); + + i2c_hal_context_t *hal = &i2c_slave->base->hal; + ESP_RETURN_ON_FALSE(xSemaphoreTake(i2c_slave->slv_tx_mux, portMAX_DELAY) == pdTRUE, ESP_ERR_TIMEOUT, TAG, "write to ram lock timeout"); + uint32_t fifo_size = 0; + i2c_ll_txfifo_rst(hal->dev); + i2c_ll_get_txfifo_len(hal->dev, &fifo_size); + if (ram_offset + fifo_size < size) { + ESP_EARLY_LOGE(TAG, "No extra fifo to fill your buffer, please split your buffer"); + return ESP_ERR_INVALID_SIZE; + } + i2c_ll_write_by_nonfifo(hal->dev, ram_offset, data, size); + xSemaphoreGive(i2c_slave->slv_tx_mux); + return ESP_OK; +} + +#endif + +esp_err_t i2c_slave_register_event_callbacks(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_event_callbacks_t *cbs, void *user_data) +{ + ESP_RETURN_ON_FALSE(i2c_slave != NULL, ESP_ERR_INVALID_ARG, TAG, "i2c slave handle not initialized"); + ESP_RETURN_ON_FALSE(cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); + +#if CONFIG_I2C_ISR_IRAM_SAFE +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + if (cbs->on_stretch_occur) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_stretch_occur), ESP_ERR_INVALID_ARG, TAG, "i2c stretch occur callback not in IRAM"); + } +#endif // SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + if (cbs->on_recv_done) { + ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_recv_done), ESP_ERR_INVALID_ARG, TAG, "i2c receive done callback not in IRAM"); + } + if (user_data) { + ESP_RETURN_ON_FALSE(esp_ptr_internal(user_data), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM"); + } +#endif // CONFIG_I2C_ISR_IRAM_SAFE + + memcpy(&(i2c_slave->callbacks), cbs, sizeof(i2c_slave_event_callbacks_t)); + i2c_slave->user_ctx = user_data; + return ESP_OK; +} diff --git a/components/driver/i2c/include/driver/i2c_master.h b/components/driver/i2c/include/driver/i2c_master.h index 48471ddd67cc..94f3f7883441 100644 --- a/components/driver/i2c/include/driver/i2c_master.h +++ b/components/driver/i2c/include/driver/i2c_master.h @@ -109,7 +109,7 @@ esp_err_t i2c_master_bus_rm_device(i2c_master_dev_handle_t handle); * @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever. * @return * - ESP_OK: I2C master transmit success - * - ESP_ERR_INVALID_ARG: I2c master transmit parameter invalid. + * - ESP_ERR_INVALID_ARG: I2C master transmit parameter invalid. * - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the bus is busy or hardware crash. */ esp_err_t i2c_master_transmit(i2c_master_dev_handle_t i2c_dev, const uint8_t *write_buffer, size_t write_size, int xfer_timeout_ms); @@ -130,7 +130,7 @@ esp_err_t i2c_master_transmit(i2c_master_dev_handle_t i2c_dev, const uint8_t *wr * @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever. * @return * - ESP_OK: I2C master transmit-receive success - * - ESP_ERR_INVALID_ARG: I2c master transmit parameter invalid. + * - ESP_ERR_INVALID_ARG: I2C master transmit parameter invalid. * - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the bus is busy or hardware crash. */ esp_err_t i2c_master_transmit_receive(i2c_master_dev_handle_t i2c_dev, const uint8_t *write_buffer, size_t write_size, uint8_t *read_buffer, size_t read_size, int xfer_timeout_ms); @@ -149,7 +149,7 @@ esp_err_t i2c_master_transmit_receive(i2c_master_dev_handle_t i2c_dev, const uin * @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever. * @return * - ESP_OK: I2C master receive success - * - ESP_ERR_INVALID_ARG: I2c master receive parameter invalid. + * - ESP_ERR_INVALID_ARG: I2C master receive parameter invalid. * - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the bus is busy or hardware crash. */ esp_err_t i2c_master_receive(i2c_master_dev_handle_t i2c_dev, uint8_t *read_buffer, size_t read_size, int xfer_timeout_ms); diff --git a/components/driver/i2c/include/driver/i2c_slave.h b/components/driver/i2c/include/driver/i2c_slave.h new file mode 100644 index 000000000000..70ba813ce691 --- /dev/null +++ b/components/driver/i2c/include/driver/i2c_slave.h @@ -0,0 +1,166 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include "esp_err.h" +#include "driver/i2c_types.h" +#include "hal/gpio_types.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief I2C slave specific configurations + */ +typedef struct { + i2c_port_num_t i2c_port; /*!< I2C port number, `-1` for auto selecting */ + gpio_num_t sda_io_num; /*!< SDA IO number used by I2C bus */ + gpio_num_t scl_io_num; /*!< SCL IO number used by I2C bus */ + i2c_clock_source_t clk_source; /*!< Clock source of I2C bus. */ + uint32_t send_buf_depth; /*!< Depth of internal transfer ringbuffer, increase this value can support more transfers pending in the background */ + uint16_t slave_addr; /*!< I2C slave address */ + i2c_addr_bit_len_t addr_bit_len; /*!< I2C slave address in bit length */ + int intr_priority; /*!< I2C interrupt priority, if set to 0, driver will select the default priority (1,2,3). */ + struct { +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + uint32_t stretch_en:1; /*!< Enable slave stretch */ +#endif +#if SOC_I2C_SLAVE_SUPPORT_BROADCAST + uint32_t broadcast_en:1; /*!< I2C slave enable broadcast */ +#endif +#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + uint32_t access_ram_en:1; /*!< Can get access to I2C RAM directly */ +#endif +#if SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + uint32_t slave_unmatch_en:1; /*!< Can trigger unmatch interrupt when slave address does not match what master sends*/ +#endif + } flags; +} i2c_slave_config_t; + +/** + * @brief Group of I2C slave callbacks (e.g. get i2c slave stretch cause). But take care of potential concurrency issues. + * @note The callbacks are all running under ISR context + * @note When CONFIG_I2C_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. + * The variables used in the function should be in the SRAM as well. + */ +typedef struct { +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + i2c_slave_stretch_callback_t on_stretch_occur; /*!< I2C slave stretched callback */ +#endif + i2c_slave_received_callback_t on_recv_done; /*!< I2C slave receive done callback */ +} i2c_slave_event_callbacks_t; + +/** + * @brief Initialize an I2C slave device + * + * @param[in] slave_config I2C slave device configurations + * @param[out] ret_handle Return a generic I2C device handle + * @return + * - ESP_OK: I2C slave device initialized successfully + * - ESP_ERR_INVALID_ARG: I2C device initialization failed because of invalid argument. + * - ESP_ERR_NO_MEM: Create I2C device failed because of out of memory. + */ +esp_err_t i2c_new_slave_device(const i2c_slave_config_t *slave_config, i2c_slave_dev_handle_t *ret_handle); + +/** + * @brief Deinitialize the I2C slave device + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @return + * - ESP_OK: Delete I2C device successfully. + * - ESP_ERR_INVALID_ARG: I2C device initialization failed because of invalid argument. + */ +esp_err_t i2c_del_slave_device(i2c_slave_dev_handle_t i2c_slave); + +/** + * @brief Read bytes from I2C internal buffer. Start a job to receive I2C data. + * + * @note This function is non-blocking, it initiates a new receive job and then returns. + * User should check the received data from the `on_recv_done` callback that registered by `i2c_slave_register_event_callbacks()`. + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @param[out] data Buffer to store data from I2C fifo. Should be valid until `on_recv_done` is triggered. + * @param[in] buffer_size Buffer size of data that provided by users. + * @return + * - ESP_OK: I2C slave receive success. + * - ESP_ERR_INVALID_ARG: I2C slave receive parameter invalid. + * - ESP_ERR_NOT_SUPPORTED: This function should be work in fifo mode, but I2C_SLAVE_NONFIFO mode is configured + */ +esp_err_t i2c_slave_receive(i2c_slave_dev_handle_t i2c_slave, uint8_t *data, size_t buffer_size); + +/** + * @brief Write bytes to internal ringbuffer of the I2C slave data. When the TX fifo empty, the ISR will + * fill the hardware FIFO with the internal ringbuffer's data. + * + * @note If you connect this slave device to some master device, the data transaction direction is from slave + * device to master device. + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @param[in] data Buffer to write to slave fifo, can pickup by master. Can be freed after this function returns. Equal or larger than `size`. + * @param[in] size In bytes, of `data` buffer. + * @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever. + * @return + * - ESP_OK: I2C slave transmit success. + * - ESP_ERR_INVALID_ARG: I2C slave transmit parameter invalid. + * - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the device is busy or hardware crash. + * - ESP_ERR_NOT_SUPPORTED: This function should be work in fifo mode, but I2C_SLAVE_NONFIFO mode is configured + */ +esp_err_t i2c_slave_transmit(i2c_slave_dev_handle_t i2c_slave, const uint8_t *data, int size, int xfer_timeout_ms); + +/** + * @brief Set I2C slave event callbacks for I2C slave channel. + * + * @note User can deregister a previously registered callback by calling this function and setting the callback member in the `cbs` structure to NULL. + * @note When CONFIG_I2C_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. + * The variables used in the function should be in the SRAM as well. The `user_data` should also reside in SRAM. + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @param[in] cbs Group of callback functions + * @param[in] user_data User data, which will be passed to callback functions directly + * @return + * - ESP_OK: Set I2C transaction callbacks successfully + * - ESP_ERR_INVALID_ARG: Set I2C transaction callbacks failed because of invalid argument + * - ESP_FAIL: Set I2C transaction callbacks failed because of other error + */ +esp_err_t i2c_slave_register_event_callbacks(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_event_callbacks_t *cbs, void *user_data); + +#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS +/** + * @brief Read bytes from I2C internal ram. This can be only used when `access_ram_en` in configuration structure set to true. + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @param[in] ram_address The offset of RAM (Cannot larger than I2C RAM memory) + * @param[out] data Buffer to store data read from I2C ram. + * @param[in] receive_size Received size from RAM. + * @return + * - ESP_OK: I2C slave transmit success. + * - ESP_ERR_INVALID_ARG: I2C slave transmit parameter invalid. + * - ESP_ERR_NOT_SUPPORTED: This function should be work in non-fifo mode, but I2C_SLAVE_FIFO mode is configured + */ +esp_err_t i2c_slave_read_ram(i2c_slave_dev_handle_t i2c_slave, uint8_t ram_address, uint8_t *data, size_t receive_size); + +/** + * @brief Write bytes to I2C internal ram. This can be only used when `access_ram_en` in configuration structure set to true. + * + * @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`. + * @param[in] ram_address The offset of RAM (Cannot larger than I2C RAM memory) + * @param[in] data Buffer to fill. + * @param[in] size Received size from RAM. + * @return + * - ESP_OK: I2C slave transmit success. + * - ESP_ERR_INVALID_ARG: I2C slave transmit parameter invalid. + * - ESP_ERR_INVALID_SIZE: Write size is larger than + * - ESP_ERR_NOT_SUPPORTED: This function should be work in non-fifo mode, but I2C_SLAVE_FIFO mode is configured + */ +esp_err_t i2c_slave_write_ram(i2c_slave_dev_handle_t i2c_slave, uint8_t ram_address, const uint8_t *data, size_t size); + +#endif +#ifdef __cplusplus +} +#endif diff --git a/components/driver/i2c/include/driver/i2c_types.h b/components/driver/i2c/include/driver/i2c_types.h index dd1683852b07..6e11cf8c2e12 100644 --- a/components/driver/i2c/include/driver/i2c_types.h +++ b/components/driver/i2c/include/driver/i2c_types.h @@ -51,6 +51,11 @@ typedef struct i2c_master_bus_t *i2c_master_bus_handle_t; */ typedef struct i2c_master_dev_t *i2c_master_dev_handle_t; +/** + * @brief Type of I2C slave device handle + */ +typedef struct i2c_slave_dev_t *i2c_slave_dev_handle_t; + /** * @brief Data type used in I2C event callback */ @@ -69,6 +74,46 @@ typedef struct { */ typedef bool (*i2c_master_callback_t)(i2c_master_dev_handle_t i2c_dev, const i2c_master_event_data_t *evt_data, void *arg); +/** + * @brief Event structure used in I2C slave + */ +typedef struct { + uint8_t *buffer; +} i2c_slave_rx_done_event_data_t; + +/** + * @brief Callback signature for I2C slave. + * + * @param[in] i2c_slave Handle for I2C slave. + * @param[out] evt_data I2C capture event data, fed by driver + * @param[in] user_ctx User data, set in `i2c_slave_register_event_callbacks()` + * + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*i2c_slave_received_callback_t)(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_rx_done_event_data_t *evt_data, void *arg); + +#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + +/** + * @brief Stretch cause event structure used in I2C slave + */ +typedef struct { + i2c_slave_stretch_cause_t stretch_cause; +} i2c_slave_stretch_event_data_t; + +/** + * @brief Callback signature for I2C slave stretch. + * + * @param[in] i2c_slave Handle for I2C slave. + * @param[out] evt_cause I2C capture event cause, fed by driver + * @param[in] user_ctx User data, set in `i2c_slave_register_event_callbacks()` + * + * @return Whether a high priority task has been waken up by this function + */ +typedef bool (*i2c_slave_stretch_callback_t)(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_stretch_event_data_t *evt_cause, void *arg); + +#endif + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32/include/hal/i2c_ll.h b/components/hal/esp32/include/hal/i2c_ll.h index 4e327b82ba53..9a2e89ebea95 100644 --- a/components/hal/esp32/include/hal/i2c_ll.h +++ b/components/hal/esp32/include/hal/i2c_ll.h @@ -45,24 +45,29 @@ typedef union { #define I2C_LL_CMD_END 4 /*!slave_addr.en_10bit = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) || 0x78; hw->slave_addr.addr = addr_14_7 || addr_6_0; } else { @@ -368,6 +373,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.nonfifo_rx_thres = full_thr; hw->fifo_conf.rx_fifo_full_thrhd = full_thr; } diff --git a/components/hal/esp32c2/include/hal/i2c_ll.h b/components/hal/esp32c2/include/hal/i2c_ll.h index c2d2010f1dbd..8958be0d2edc 100644 --- a/components/hal/esp32c2/include/hal/i2c_ll.h +++ b/components/hal/esp32c2/include/hal/i2c_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -47,23 +47,17 @@ typedef union { #define I2C_LL_CMD_END 4 /*!ctr.addr_broadcasting_en = broadcast_en; } +/** + * @brief Get the cause of SCL clock stretching in slave mode + * + * @param hw Beginning address of the peripheral registers + * @param stretch_cause Pointer to stretch cause in the slave mode. + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) +{ + switch (hw->sr.stretch_cause) + { + case 0: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; + break; + case 1: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY; + break; + case 2: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_RX_FULL; + break; + case 3: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK; + break; + default: + HAL_ASSERT(false); + break; + } +} + /** * @brief Configure I2C slave address * @@ -400,6 +430,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rx_fifo_wm_thrhd = full_thr; } diff --git a/components/hal/esp32c6/include/hal/i2c_ll.h b/components/hal/esp32c6/include/hal/i2c_ll.h index db301dceec85..80e7738b69ab 100644 --- a/components/hal/esp32c6/include/hal/i2c_ll.h +++ b/components/hal/esp32c6/include/hal/i2c_ll.h @@ -49,31 +49,31 @@ typedef union { #define I2C_LL_CMD_END 4 /*!ctr.addr_broadcasting_en = broadcast_en; } +/** + * @brief Get the cause of SCL clock stretching in slave mode + * + * @param hw Beginning address of the peripheral registers + * @param stretch_cause Pointer to stretch cause in the slave mode. + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) +{ + switch (hw->sr.stretch_cause) + { + case 0: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; + break; + case 1: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY; + break; + case 2: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_RX_FULL; + break; + case 3: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK; + break; + default: + HAL_ASSERT(false); + break; + } +} + /** * @brief Configure I2C slave address * @@ -312,7 +343,7 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo { hw->slave_addr.addr_10bit_en = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; hw->slave_addr.slave_addr = addr_14_7 | addr_6_0; hw->ctr.addr_10bit_rw_check_en = addr_10bit_en; @@ -404,6 +435,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rxfifo_wm_thrhd = full_thr; } diff --git a/components/hal/esp32h2/include/hal/i2c_ll.h b/components/hal/esp32h2/include/hal/i2c_ll.h index 70214524fef0..1ed9ecddc0ac 100644 --- a/components/hal/esp32h2/include/hal/i2c_ll.h +++ b/components/hal/esp32h2/include/hal/i2c_ll.h @@ -47,32 +47,32 @@ typedef union { #define I2C_LL_CMD_END 4 /*!ctr.addr_broadcasting_en = broadcast_en; } +/** + * @brief Get the cause of SCL clock stretching in slave mode + * + * @param hw Beginning address of the peripheral registers + * @param stretch_cause Pointer to stretch cause in the slave mode. + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) +{ + switch (hw->sr.stretch_cause) + { + case 0: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; + break; + case 1: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY; + break; + case 2: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_RX_FULL; + break; + case 3: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK; + break; + default: + HAL_ASSERT(false); + break; + } +} + /** * @brief Configure I2C slave address * @@ -308,7 +339,7 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo { hw->slave_addr.addr_10bit_en = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; hw->slave_addr.slave_addr = addr_14_7 | addr_6_0; hw->ctr.addr_10bit_rw_check_en = addr_10bit_en; @@ -400,6 +431,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rxfifo_wm_thrhd = full_thr; } diff --git a/components/hal/esp32p4/include/hal/i2c_ll.h b/components/hal/esp32p4/include/hal/i2c_ll.h index 636f27f4a05f..5888db147ea1 100644 --- a/components/hal/esp32p4/include/hal/i2c_ll.h +++ b/components/hal/esp32p4/include/hal/i2c_ll.h @@ -47,18 +47,24 @@ typedef union { #define I2C_LL_CMD_END 4 /*!slave_addr.addr_10bit_en = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; hw->slave_addr.slave_addr = addr_14_7 | addr_6_0; hw->ctr.addr_10bit_rw_check_en = addr_10bit_en; @@ -411,6 +417,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rxfifo_wm_thrhd = full_thr; } diff --git a/components/hal/esp32s2/include/hal/i2c_ll.h b/components/hal/esp32s2/include/hal/i2c_ll.h index 07fe5b419dc1..d45c4cfd05ed 100644 --- a/components/hal/esp32s2/include/hal/i2c_ll.h +++ b/components/hal/esp32s2/include/hal/i2c_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -44,24 +44,29 @@ typedef union { #define I2C_LL_CMD_END 4 /*!slave_addr.en_10bit = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; - uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) || 0x78; - hw->slave_addr.addr = addr_14_7 || addr_6_0; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; + uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; + hw->slave_addr.addr = addr_14_7 | addr_6_0; } else { hw->slave_addr.addr = slave_addr; } @@ -356,6 +375,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rx_fifo_wm_thrhd = full_thr; } diff --git a/components/hal/esp32s3/include/hal/i2c_ll.h b/components/hal/esp32s3/include/hal/i2c_ll.h index 8c1b862bf74d..374c8c6e0458 100644 --- a/components/hal/esp32s3/include/hal/i2c_ll.h +++ b/components/hal/esp32s3/include/hal/i2c_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -48,18 +48,23 @@ typedef union { #define I2C_LL_CMD_END 4 /*!ctr.addr_broadcasting_en = broadcast_en; } +/** + * @brief Get the cause of SCL clock stretching in slave mode + * + * @param hw Beginning address of the peripheral registers + * @param stretch_cause Pointer to stretch cause in the slave mode. + * + * @return None + */ +__attribute__((always_inline)) +static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) +{ + switch (hw->sr.stretch_cause) + { + case 0: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; + break; + case 1: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY; + break; + case 2: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_RX_FULL; + break; + case 3: + *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK; + break; + default: + HAL_ASSERT(false); + break; + } +} + /** * @brief Configure I2C slave address * @@ -301,7 +337,7 @@ static inline void i2c_ll_set_slave_addr(i2c_dev_t *hw, uint16_t slave_addr, boo { hw->slave_addr.addr_10bit_en = addr_10bit_en; if (addr_10bit_en) { - uint8_t addr_14_7 = (slave_addr & 0xff) << 7; + uint16_t addr_14_7 = (slave_addr & 0xff) << 7; uint8_t addr_6_0 = ((slave_addr & 0x300) >> 8) | 0x78; hw->slave_addr.slave_addr = addr_14_7 | addr_6_0; hw->ctr.addr_10bit_rw_check_en = addr_10bit_en; @@ -393,6 +429,7 @@ static inline void i2c_ll_set_txfifo_empty_thr(i2c_dev_t *hw, uint8_t empty_thr) */ static inline void i2c_ll_set_rxfifo_full_thr(i2c_dev_t *hw, uint8_t full_thr) { + hw->fifo_conf.fifo_prt_en = 1; hw->fifo_conf.rxfifo_wm_thrhd = full_thr; } diff --git a/components/hal/include/hal/i2c_types.h b/components/hal/include/hal/i2c_types.h index ef66199ce3cb..fba2ad0bad00 100644 --- a/components/hal/include/hal/i2c_types.h +++ b/components/hal/include/hal/i2c_types.h @@ -87,6 +87,16 @@ typedef enum { I2C_MASTER_ACK_MAX, } i2c_ack_type_t; +/** + * @brief Enum for I2C slave stretch causes + */ +typedef enum { + I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH = 0, /*!< Stretching SCL low when the slave is read by the master and the address just matched */ + I2C_SLAVE_STRETCH_CAUSE_TX_EMPTY = 1, /*!< Stretching SCL low when TX FIFO is empty in slave mode */ + I2C_SLAVE_STRETCH_CAUSE_RX_FULL = 2, /*!< Stretching SCL low when RX FIFO is full in slave mode */ + I2C_SLAVE_STRETCH_CAUSE_SENDING_ACK = 3, /*!< Stretching SCL low when slave sending ACK */ +} i2c_slave_stretch_cause_t; + #if SOC_I2C_SUPPORTED /** * @brief I2C group clock source diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 0e433b9c2b60..9a5ea3f9fc3a 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -419,6 +419,18 @@ config SOC_I2C_SUPPORT_10BIT_ADDR bool default y +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + config SOC_I2S_NUM int default 1 diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 27ac1025f559..63e518f65496 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -196,6 +196,9 @@ #define SOC_I2C_SUPPORT_XTAL (1) #define SOC_I2C_SUPPORT_RTC (1) #define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (1U) diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index fd64e0629810..cb4f3353cd62 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -539,6 +539,22 @@ config SOC_I2C_SUPPORT_10BIT_ADDR bool default y +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + bool + default y + config SOC_LP_I2C_NUM int default 1 diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index ed69e78246f4..74f167076769 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -239,6 +239,10 @@ #define SOC_I2C_SUPPORT_XTAL (1) #define SOC_I2C_SUPPORT_RTC (1) #define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) +#define SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH (1) /*-------------------------- LP_I2C CAPS -------------------------------------*/ // ESP32-C6 has 1 LP_I2C diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index adc34fbbc83f..82c436d287ad 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -531,6 +531,22 @@ config SOC_I2C_SUPPORT_10BIT_ADDR bool default y +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + bool + default y + config SOC_I2S_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 9a3231707e62..6df8be00681c 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -242,6 +242,10 @@ #define SOC_I2C_SUPPORT_XTAL (1) #define SOC_I2C_SUPPORT_RTC (1) #define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) +#define SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH (1) /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (1U) diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 6d74147ef244..390450dbd7ac 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -479,6 +479,22 @@ config SOC_I2C_SUPPORT_RTC bool default y +config SOC_I2C_SUPPORT_10BIT_ADDR + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH + bool + default y + config SOC_I2S_NUM int default 3 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 4c405a9046d1..1695bb2b7760 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -246,6 +246,10 @@ #define SOC_I2C_SUPPORT_XTAL (1) #define SOC_I2C_SUPPORT_RTC (1) +#define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) +#define SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH (1) /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (3U) diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index 3da46a8c1d19..aa9945311dfd 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -483,6 +483,14 @@ config SOC_I2C_SUPPORT_10BIT_ADDR bool default y +config SOC_I2C_SLAVE_SUPPORT_BROADCAST + bool + default y + +config SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS + bool + default y + config SOC_I2S_NUM int default 2 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 42aeff02e343..bffb96949384 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -201,6 +201,8 @@ #define SOC_I2C_SUPPORT_RTC (1) #define SOC_I2C_SUPPORT_10BIT_ADDR (1) +#define SOC_I2C_SLAVE_SUPPORT_BROADCAST (1) +#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1) /*-------------------------- I2S CAPS ----------------------------------------*/ #define SOC_I2S_NUM (2U) From c9f85d8d1b64a0d6b9836efa17df59ca6a270219 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Tue, 24 Oct 2023 18:46:27 +0800 Subject: [PATCH 028/161] feat(i2c_test): Add multi board test for I2C master and I2C slave --- .../i2c_test_apps/main/CMakeLists.txt | 21 +- .../test_apps/i2c_test_apps/main/test_board.h | 42 ++ .../i2c_test_apps/main/test_i2c_10bit.c | 196 +++++++ .../i2c_test_apps/main/test_i2c_broadcast.c | 121 +++++ .../main/{test_i2c.c => test_i2c_common.c} | 32 +- .../i2c_test_apps/main/test_i2c_iram.c | 141 +++++ .../i2c_test_apps/main/test_i2c_multi.c | 487 ++++++++++++++++++ .../i2c_test_apps/main/test_i2c_ram.c | 215 ++++++++ .../test_apps/i2c_test_apps/pytest_i2c.py | 20 + .../legacy_i2c_driver/main/test_i2c.c | 60 +++ 10 files changed, 1317 insertions(+), 18 deletions(-) create mode 100644 components/driver/test_apps/i2c_test_apps/main/test_board.h create mode 100644 components/driver/test_apps/i2c_test_apps/main/test_i2c_10bit.c create mode 100644 components/driver/test_apps/i2c_test_apps/main/test_i2c_broadcast.c rename components/driver/test_apps/i2c_test_apps/main/{test_i2c.c => test_i2c_common.c} (87%) create mode 100644 components/driver/test_apps/i2c_test_apps/main/test_i2c_iram.c create mode 100644 components/driver/test_apps/i2c_test_apps/main/test_i2c_multi.c create mode 100644 components/driver/test_apps/i2c_test_apps/main/test_i2c_ram.c diff --git a/components/driver/test_apps/i2c_test_apps/main/CMakeLists.txt b/components/driver/test_apps/i2c_test_apps/main/CMakeLists.txt index 61d8e9dae66b..b09b511df0bc 100644 --- a/components/driver/test_apps/i2c_test_apps/main/CMakeLists.txt +++ b/components/driver/test_apps/i2c_test_apps/main/CMakeLists.txt @@ -1,7 +1,26 @@ set(srcs "test_app_main.c" - "test_i2c.c" + "test_i2c_common.c" ) +if(CONFIG_SOC_I2C_SUPPORT_SLAVE) + list(APPEND srcs "test_i2c_multi.c") + if(CONFIG_I2C_ISR_IRAM_SAFE) + list(APPEND srcs "test_i2c_iram.c") + endif() +endif() + +if(CONFIG_SOC_I2C_SLAVE_SUPPORT_BROADCAST) + list(APPEND srcs "test_i2c_broadcast.c") +endif() + +if(CONFIG_SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS) + list(APPEND srcs "test_i2c_ram.c") +endif() + +if(CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR AND CONFIG_SOC_I2C_SUPPORT_SLAVE) + list(APPEND srcs "test_i2c_10bit.c") +endif() + idf_component_register(SRCS ${srcs} PRIV_REQUIRES unity driver test_utils WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/i2c_test_apps/main/test_board.h b/components/driver/test_apps/i2c_test_apps/main/test_board.h new file mode 100644 index 000000000000..e420180d5ace --- /dev/null +++ b/components/driver/test_apps/i2c_test_apps/main/test_board.h @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_IDF_TARGET_ESP32 +#define I2C_SLAVE_SCL_IO 18 /*! +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "soc/gpio_periph.h" +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" +#include "hal/gpio_hal.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/i2c_slave.h" +#include "esp_rom_gpio.h" +#include "esp_log.h" +#include "test_utils.h" +#include "test_board.h" + +static QueueHandle_t s_receive_queue; + +static IRAM_ATTR bool example_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data) +{ + BaseType_t high_task_wakeup = pdFALSE; + QueueHandle_t receive_queue = (QueueHandle_t)user_data; + xQueueSendFromISR(receive_queue, edata, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +static void i2c_master_write_test_10bit(void) +{ + uint8_t data_wr[DATA_LENGTH] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_10, + .device_address = 0x134, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + disp_buf(data_wr, i); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_test_10bit(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_10, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x134, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = example_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(1000)); + + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + vQueueDelete(s_receive_queue); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test 10 bit", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_10bit, i2c_slave_read_test_10bit); + + +static void master_read_slave_test_10bit(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_10, + .device_address = 0x134, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + printf("Slave please write data to buffer\n"); + + unity_send_signal("slave write"); + unity_wait_for_signal("master read"); + + TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1)); + vTaskDelay(100 / portTICK_PERIOD_MS); + for (int i = 0; i < DATA_LENGTH; i++) { + printf("%d\n", data_rd[i]); + TEST_ASSERT(data_rd[i]==i); + } + unity_send_signal("ready to delete 10bit"); + + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void slave_write_buffer_test_10bit(void) +{ + uint8_t data_wr[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_10, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x134, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("slave write"); + for (int i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + TEST_ESP_OK(i2c_slave_transmit(slave_handle, data_wr, DATA_LENGTH, -1)); + disp_buf(data_wr, DATA_LENGTH); + unity_send_signal("master read"); + unity_wait_for_signal("ready to delete 10bit"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + + +TEST_CASE_MULTIPLE_DEVICES("I2C master read slave test 10 bit", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_test_10bit, slave_write_buffer_test_10bit); diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c_broadcast.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c_broadcast.c new file mode 100644 index 000000000000..e6cf562289cb --- /dev/null +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c_broadcast.c @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + +#include +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "soc/gpio_periph.h" +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" +#include "hal/gpio_hal.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/i2c_slave.h" +#include "esp_rom_gpio.h" +#include "esp_log.h" +#include "test_utils.h" +#include "test_board.h" + +static QueueHandle_t s_receive_queue; + +static IRAM_ATTR bool example_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data) +{ + BaseType_t high_task_wakeup = pdFALSE; + QueueHandle_t receive_queue = (QueueHandle_t)user_data; + xQueueSendFromISR(receive_queue, edata, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +static void i2c_master_write_test_broadcast(void) +{ + uint8_t data_wr[DATA_LENGTH] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x00, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + disp_buf(data_wr, i); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_test_broadcast(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x53, + .flags.broadcast_en = true, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = example_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(1000)); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + vQueueDelete(s_receive_queue); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test broadcast", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_broadcast, i2c_slave_read_test_broadcast); diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c_common.c similarity index 87% rename from components/driver/test_apps/i2c_test_apps/main/test_i2c.c rename to components/driver/test_apps/i2c_test_apps/main/test_i2c_common.c index 17152f67c54e..ee307c32a3d1 100644 --- a/components/driver/test_apps/i2c_test_apps/main/test_i2c.c +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c_common.c @@ -22,23 +22,18 @@ #include "esp_rom_gpio.h" #include "esp_log.h" #include "test_utils.h" +#include "test_board.h" static const char TAG[] = "test-i2c"; -#define TEST_I2C_SCL_PIN 2 -#define TEST_I2C_SDA_PIN 4 -#define TEST_I2C_SCL_FREQ (100 * 1000) -#define TEST_I2C_PORT 0 -#define SLAVE_ADDR 0x58 - - TEST_CASE("I2C bus install-uninstall test", "[i2c]") { i2c_master_bus_config_t i2c_mst_config_1 = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = TEST_I2C_PORT, - .scl_io_num = TEST_I2C_SCL_PIN, - .sda_io_num = TEST_I2C_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, }; i2c_master_bus_handle_t i2c_mst_handle1; @@ -46,8 +41,9 @@ TEST_CASE("I2C bus install-uninstall test", "[i2c]") i2c_master_bus_config_t i2c_mst_config_2 = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = 1, - .scl_io_num = TEST_I2C_SCL_PIN, - .sda_io_num = TEST_I2C_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, }; i2c_master_bus_handle_t i2c_mst_handle2; #endif @@ -75,8 +71,9 @@ TEST_CASE("I2C driver memory leaking check", "[i2c]") i2c_master_bus_config_t i2c_mst_config_1 = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = TEST_I2C_PORT, - .scl_io_num = TEST_I2C_SCL_PIN, - .sda_io_num = TEST_I2C_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, }; i2c_master_bus_handle_t bus_handle; @@ -95,8 +92,9 @@ TEST_CASE("I2C device add & remove check", "[i2c]") i2c_master_bus_config_t i2c_mst_config_1 = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = TEST_I2C_PORT, - .scl_io_num = TEST_I2C_SCL_PIN, - .sda_io_num = TEST_I2C_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, }; i2c_master_bus_handle_t bus_handle; @@ -137,8 +135,8 @@ TEST_CASE("I2C master probe device test", "[i2c]") i2c_master_bus_config_t i2c_mst_config_1 = { .clk_source = I2C_CLK_SRC_DEFAULT, .i2c_port = TEST_I2C_PORT, - .scl_io_num = TEST_I2C_SCL_PIN, - .sda_io_num = TEST_I2C_SDA_PIN, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, .flags.enable_internal_pullup = true, }; i2c_master_bus_handle_t bus_handle; diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c_iram.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c_iram.c new file mode 100644 index 000000000000..d59967fb0e51 --- /dev/null +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c_iram.c @@ -0,0 +1,141 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "soc/gpio_periph.h" +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" +#include "hal/gpio_hal.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/i2c_slave.h" +#include "esp_rom_gpio.h" +#include "esp_log.h" +#include "test_utils.h" +#include "test_board.h" +#include "unity_test_utils_cache.h" + +static QueueHandle_t s_send_queue; +static QueueHandle_t s_receive_queue; + +static IRAM_ATTR bool test_master_tx_done_callback(i2c_master_dev_handle_t i2c_dev, const i2c_master_event_data_t *evt_data, void *arg) +{ + BaseType_t high_task_wakeup = pdFALSE; + QueueHandle_t s_send_queue = (QueueHandle_t)arg; + xQueueSendFromISR(s_send_queue, evt_data, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +static IRAM_ATTR bool test_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data) +{ + BaseType_t high_task_wakeup = pdFALSE; + QueueHandle_t receive_queue = (QueueHandle_t)user_data; + xQueueSendFromISR(receive_queue, edata, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +static void IRAM_ATTR test_delay_post_cache_disable(void *args) +{ + esp_rom_delay_us(10000); +} + +static void i2c_master_write_test_iram_safe(void) +{ + uint8_t data_wr[DATA_LENGTH] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + .trans_queue_depth = 200, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + s_send_queue = xQueueCreate(1, sizeof(i2c_master_event_data_t)); + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + i2c_master_event_callbacks_t cbs = { + .on_trans_done = test_master_tx_done_callback, + }; + i2c_master_event_data_t evt_data; + i2c_master_register_event_callbacks(dev_handle, &cbs, s_send_queue); + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + disp_buf(data_wr, i); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL); + xQueueReceive(s_send_queue, &evt_data, pdMS_TO_TICKS(10000)); + unity_wait_for_signal("ready to delete"); + vQueueDelete(s_send_queue); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_test_iram_safe(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = test_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL); + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000)); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + vQueueDelete(s_receive_queue); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test iram safe", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_iram_safe, i2c_slave_read_test_iram_safe); diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c_multi.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c_multi.c new file mode 100644 index 000000000000..eaf026f0c8d2 --- /dev/null +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c_multi.c @@ -0,0 +1,487 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + +#include +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "soc/gpio_periph.h" +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" +#include "hal/gpio_hal.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/i2c_slave.h" +#include "esp_rom_gpio.h" +#include "esp_log.h" +#include "test_utils.h" +#include "test_board.h" + +void disp_buf(uint8_t *buf, int len) +{ + int i; + for (i = 0; i < len; i++) { + printf("%02x ", buf[i]); + if (( i + 1 ) % 16 == 0) { + printf("\n"); + } + } + printf("\n"); +} + +#define DATA_LENGTH 100 + +static QueueHandle_t s_receive_queue; + +static IRAM_ATTR bool test_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data) +{ + BaseType_t high_task_wakeup = pdFALSE; + QueueHandle_t receive_queue = (QueueHandle_t)user_data; + xQueueSendFromISR(receive_queue, edata, &high_task_wakeup); + return high_task_wakeup == pdTRUE; +} + +static void i2c_master_write_test(void) +{ + uint8_t data_wr[DATA_LENGTH] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + disp_buf(data_wr, i); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_test(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = test_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000)); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + vQueueDelete(s_receive_queue); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test, i2c_slave_read_test); + + +static void master_read_slave_test(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + printf("Slave please write data to buffer\n"); + + unity_send_signal("slave write"); + unity_wait_for_signal("master read"); + + TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1)); + vTaskDelay(100 / portTICK_PERIOD_MS); + for (int i = 0; i < DATA_LENGTH; i++) { + printf("%d\n", data_rd[i]); + TEST_ASSERT(data_rd[i]==i); + } + unity_send_signal("ready to delete master read test"); + + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void slave_write_buffer_test(void) +{ + uint8_t data_wr[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("slave write"); + for (int i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + TEST_ESP_OK(i2c_slave_transmit(slave_handle, data_wr, DATA_LENGTH, -1)); + disp_buf(data_wr, DATA_LENGTH); + unity_send_signal("master read"); + unity_wait_for_signal("ready to delete master read test"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + + +TEST_CASE_MULTIPLE_DEVICES("I2C master read slave test", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_test, slave_write_buffer_test); + +static void i2c_master_write_read_test(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + uint8_t data_wr[DATA_LENGTH] = {0}; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + printf("master read buffer\n"); + + unity_send_signal("slave write"); + unity_wait_for_signal("master read and write"); + + TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1)); + vTaskDelay(100 / portTICK_PERIOD_MS); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + + for (int i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + vTaskDelay(100 / portTICK_PERIOD_MS); + unity_send_signal("slave read"); + unity_wait_for_signal("ready to read"); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_send_signal("sent done"); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_write_test(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + uint8_t data_wr[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = test_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + unity_send_signal("i2c slave init finish"); + unity_wait_for_signal("slave write"); + + for (int i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + TEST_ESP_OK(i2c_slave_transmit(slave_handle, data_wr, DATA_LENGTH, -1)); + disp_buf(data_wr, DATA_LENGTH); + unity_send_signal("master read and write"); + unity_wait_for_signal("slave read"); + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + unity_send_signal("ready to read"); + unity_wait_for_signal("sent done"); + i2c_slave_rx_done_event_data_t rx_data; + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(1000)); + + printf("slave read data is:\n"); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + unity_send_signal("ready to delete"); + vQueueDelete(s_receive_queue); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C read and write test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_read_test, i2c_slave_read_write_test); + + +static void i2c_master_repeat_write(void) +{ + uint8_t data_wr[DATA_LENGTH] = {0}; + int times = 3; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + + i2c_master_bus_handle_t bus_handle; + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + for (int j = 0; j < times; j++) { + for (int i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = j + i; + } + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + disp_buf(data_wr, DATA_LENGTH); + } + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_repeat_read(void) +{ + uint32_t size = 0; + int times = 3; + uint8_t data_rd[DATA_LENGTH * 3] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = test_i2c_rx_done_callback, + }; + TEST_ESP_OK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + unity_send_signal("i2c slave init finish"); + + while (times > 0) { + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd + size, DATA_LENGTH)); + xQueueReceive(s_receive_queue, &rx_data, (TickType_t)portMAX_DELAY); + + size += DATA_LENGTH; + times--; + } + + disp_buf(data_rd, size); + for (int j = 0; j < times; j++) { + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i + DATA_LENGTH * j] == (i + j)); + } + } + unity_send_signal("ready to delete"); + vQueueDelete(s_receive_queue); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C repeat write test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_repeat_write, i2c_slave_repeat_read); + +#if SOC_I2C_NUM > 1 +// Now chips with mutiple I2C controllers are up to 2, can change this to interation when we have more I2C controllers. +static void i2c_master_write_test_more_port(void) +{ + uint8_t data_wr[DATA_LENGTH] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = 1, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH; i++) { + data_wr[i] = i; + } + + disp_buf(data_wr, i); + TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1)); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_test_more_port(void) +{ + uint8_t data_rd[DATA_LENGTH] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = 1, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t)); + i2c_slave_event_callbacks_t cbs = { + .on_recv_done = test_i2c_rx_done_callback, + }; + ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue)); + + i2c_slave_rx_done_event_data_t rx_data; + TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000)); + disp_buf(data_rd, DATA_LENGTH); + for (int i = 0; i < DATA_LENGTH; i++) { + TEST_ASSERT(data_rd[i] == i); + } + vQueueDelete(s_receive_queue); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test, more ports", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_more_port, i2c_slave_read_test_more_port); +#endif diff --git a/components/driver/test_apps/i2c_test_apps/main/test_i2c_ram.c b/components/driver/test_apps/i2c_test_apps/main/test_i2c_ram.c new file mode 100644 index 000000000000..165d3afb3b0d --- /dev/null +++ b/components/driver/test_apps/i2c_test_apps/main/test_i2c_ram.c @@ -0,0 +1,215 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + +#include +#include +#include "sdkconfig.h" +#include "unity.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "esp_err.h" +#include "soc/gpio_periph.h" +#include "soc/clk_tree_defs.h" +#include "soc/soc_caps.h" +#include "hal/gpio_hal.h" +#include "hal/uart_ll.h" +#include "esp_private/periph_ctrl.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/i2c_slave.h" +#include "esp_rom_gpio.h" +#include "esp_log.h" +#include "test_utils.h" +#include "test_board.h" + +static esp_err_t i2c_master_write_to_addr(i2c_master_dev_handle_t device_handle, uint8_t address, const uint8_t *data, uint32_t size, int xfer_timeout_ms) +{ + esp_err_t ret = ESP_OK; + uint8_t *buffer = (uint8_t*)calloc(1, size + 1); + buffer[0] = address; + memcpy(buffer + 1, data, size); + ret = i2c_master_transmit(device_handle, buffer, 1 + size, xfer_timeout_ms); + return ret; +} + +#define DATA_LENGTH_RAM 6 + +static void i2c_master_write_to_ram_test(void) +{ + uint8_t data_wr[DATA_LENGTH_RAM] = { 0 }; + int i; + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH_RAM; i++) { + data_wr[i] = i + 1; + } + disp_buf(data_wr, i); + // Write slave ram address is 0x5. + i2c_master_write_to_addr(dev_handle, 0x5, data_wr, DATA_LENGTH_RAM, -1); + + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void i2c_slave_read_from_ram_test(void) +{ + uint8_t data_rd[DATA_LENGTH_RAM] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + .flags.access_ram_en = true, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + + TEST_ESP_OK(i2c_slave_read_ram(slave_handle, 0x5, data_rd, DATA_LENGTH_RAM)); + + disp_buf(data_rd, DATA_LENGTH_RAM); + for (int i = 0; i < DATA_LENGTH_RAM; i++) { + TEST_ASSERT(data_rd[i] == (i + 1)); + } + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test - slave directly read from ram", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_to_ram_test, i2c_slave_read_from_ram_test); + + +static void master_read_slave_from_ram_test(void) +{ + uint8_t data_rd[DATA_LENGTH_RAM] = {0}; + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_io_num = I2C_MASTER_SDA_IO, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t bus_handle; + TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = 0x58, + .scl_speed_hz = 100000, + }; + + i2c_master_dev_handle_t dev_handle; + TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle)); + + unity_wait_for_signal("i2c slave init finish"); + + printf("Slave please write data to buffer\n"); + + unity_send_signal("slave write"); + unity_wait_for_signal("master read"); + + uint8_t *buffer = (uint8_t*)malloc(sizeof(uint8_t)); + buffer[0] = 0x2; // Means write offset 2 in I2C ram. + TEST_ESP_OK(i2c_master_transmit_receive(dev_handle, buffer, 1, data_rd, DATA_LENGTH_RAM, -1)); + vTaskDelay(100 / portTICK_PERIOD_MS); + for (int i = 0; i < DATA_LENGTH_RAM; i++) { + printf("%d\n", data_rd[i]); + TEST_ASSERT(data_rd[i]==i); + } + unity_send_signal("ready to delete ram test"); + + TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle)); + TEST_ESP_OK(i2c_del_master_bus(bus_handle)); +} + +static void slave_write_buffer_to_ram_test(void) +{ + uint8_t data_wr[DATA_LENGTH_RAM] = {0}; + + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + .flags.access_ram_en = true, + }; + + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("slave write"); + for (int i = 0; i < DATA_LENGTH_RAM; i++) { + data_wr[i] = i; + } + + TEST_ESP_OK(i2c_slave_write_ram(slave_handle, 0x2, data_wr, DATA_LENGTH_RAM)); + disp_buf(data_wr, DATA_LENGTH_RAM); + unity_send_signal("master read"); + unity_wait_for_signal("ready to delete ram test"); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} + + +TEST_CASE_MULTIPLE_DEVICES("I2C master read slave ram test", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_from_ram_test, slave_write_buffer_to_ram_test); + +TEST_CASE("I2C slave init as ram but read by fifo", "[i2c]") +{ + uint8_t data_rd[10] = {0}; + i2c_slave_config_t i2c_slv_config = { + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = TEST_I2C_PORT, + .send_buf_depth = 256, + .scl_io_num = I2C_SLAVE_SCL_IO, + .sda_io_num = I2C_SLAVE_SDA_IO, + .slave_addr = 0x58, + .flags.access_ram_en = true, + }; + i2c_slave_dev_handle_t slave_handle; + TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle)); + + TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, i2c_slave_receive(slave_handle, data_rd, 10)); + TEST_ESP_OK(i2c_del_slave_device(slave_handle)); +} diff --git a/components/driver/test_apps/i2c_test_apps/pytest_i2c.py b/components/driver/test_apps/i2c_test_apps/pytest_i2c.py index 21bd8b43484e..afcf27563fdf 100644 --- a/components/driver/test_apps/i2c_test_apps/pytest_i2c.py +++ b/components/driver/test_apps/i2c_test_apps/pytest_i2c.py @@ -17,3 +17,23 @@ ) def test_i2c(dut: Dut) -> None: dut.run_all_single_board_cases() + + +@pytest.mark.esp32 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic_multi_device +@pytest.mark.parametrize( + 'count, config', + [ + (2, 'defaults',), + ], + indirect=True +) +def test_i2c_multi_device(case_tester) -> None: # type: ignore + for case in case_tester.test_menu: + if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': + case_tester.run_multi_dev_case(case=case, reset=True) diff --git a/components/driver/test_apps/legacy_i2c_driver/main/test_i2c.c b/components/driver/test_apps/legacy_i2c_driver/main/test_i2c.c index b8f4257a3184..ea4b03da85a4 100644 --- a/components/driver/test_apps/legacy_i2c_driver/main/test_i2c.c +++ b/components/driver/test_apps/legacy_i2c_driver/main/test_i2c.c @@ -508,6 +508,66 @@ static void i2c_slave_repeat_read(void) TEST_CASE_MULTIPLE_DEVICES("I2C repeat write test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_repeat_write, i2c_slave_repeat_read); +#if SOC_I2C_NUM > 1 + +static void i2c_master_write_test_more_ports(void) +{ + uint8_t *data_wr = (uint8_t *) malloc(DATA_LENGTH); + int i; + + i2c_config_t conf_master = i2c_master_init(); + TEST_ESP_OK(i2c_param_config(I2C_NUM_1, &conf_master)); + + TEST_ESP_OK(i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, + I2C_MASTER_RX_BUF_DISABLE, + I2C_MASTER_TX_BUF_DISABLE, 0)); + unity_wait_for_signal("i2c slave init finish"); + + unity_send_signal("master write"); + for (i = 0; i < DATA_LENGTH / 2; i++) { + data_wr[i] = i; + } + i2c_master_write_slave(I2C_NUM_1, data_wr, DATA_LENGTH / 2); + disp_buf(data_wr, i); + free(data_wr); + unity_wait_for_signal("ready to delete"); + TEST_ESP_OK(i2c_driver_delete(I2C_NUM_1)); +} + +static void i2c_slave_read_test_more_ports(void) +{ + uint8_t *data_rd = (uint8_t *) malloc(DATA_LENGTH); + int size_rd = 0; + int len = 0; + + i2c_config_t conf_slave = i2c_slave_init(); + TEST_ESP_OK(i2c_param_config( I2C_NUM_1, &conf_slave)); + TEST_ESP_OK(i2c_driver_install(I2C_NUM_1, I2C_MODE_SLAVE, + I2C_SLAVE_RX_BUF_LEN, + I2C_SLAVE_TX_BUF_LEN, 0)); + unity_send_signal("i2c slave init finish"); + + unity_wait_for_signal("master write"); + while (1) { + len = i2c_slave_read_buffer( I2C_NUM_1, data_rd + size_rd, DATA_LENGTH, 10000 / portTICK_PERIOD_MS); + if (len == 0) { + break; + } + size_rd += len; + } + disp_buf(data_rd, size_rd); + for (int i = 0; i < size_rd; i++) { + TEST_ASSERT(data_rd[i] == i); + } + free(data_rd); + unity_send_signal("ready to delete"); + TEST_ESP_OK(i2c_driver_delete(I2C_NUM_1)); +} + +TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test, more ports", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_more_ports, i2c_slave_read_test_more_ports); + +#endif + static volatile bool exit_flag; static bool test_read_func; From a8e175364a8cfdcf0a3935794076ac2491065d32 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 24 Oct 2023 13:29:15 +0200 Subject: [PATCH 029/161] fix(console): switch USB PHY to OTG when OTG is used for console On ESP32-S3 with the default efuse settings, USB PHY is connected to the USB_SERIAL_JTAG peripheral. If USB OTG peripheral is used for the console, we need to additionally switch the PHY to USB OTG, otherwise we won't get any output. Closes https://github.com/espressif/esp-idf/issues/12437 --- components/bootloader_support/src/bootloader_console.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index 7df9824d6785..086394a876b0 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,9 @@ #include "esp32s2/rom/usb/cdc_acm.h" #include "esp32s2/rom/usb/usb_common.h" #endif +#if SOC_USB_SERIAL_JTAG_SUPPORTED +#include "hal/usb_phy_ll.h" +#endif #include "esp_rom_gpio.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" @@ -98,6 +101,9 @@ void bootloader_console_init(void) esp_rom_uart_usb_acm_init(s_usb_cdc_buf, sizeof(s_usb_cdc_buf)); esp_rom_uart_set_as_console(ESP_ROM_USB_OTG_NUM); esp_rom_install_channel_putc(1, bootloader_console_write_char_usb); +#if SOC_USB_SERIAL_JTAG_SUPPORTED + usb_phy_ll_int_otg_enable(&USB_WRAP); +#endif } #endif //CONFIG_ESP_CONSOLE_USB_CDC From 6e92fc04164bff9d5bb6fc61936c896efba503d9 Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Wed, 4 Oct 2023 20:42:39 +0200 Subject: [PATCH 030/161] feature(examples/usb): Define maximum opend files in MSC device example --- .../peripherals/usb/device/tusb_msc/main/idf_component.yml | 2 +- .../peripherals/usb/device/tusb_msc/main/tusb_msc_main.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/peripherals/usb/device/tusb_msc/main/idf_component.yml b/examples/peripherals/usb/device/tusb_msc/main/idf_component.yml index 06b047d6a2de..1659a1ebe3ed 100644 --- a/examples/peripherals/usb/device/tusb_msc/main/idf_component.yml +++ b/examples/peripherals/usb/device/tusb_msc/main/idf_component.yml @@ -1,4 +1,4 @@ ## IDF Component Manager Manifest File dependencies: - espressif/esp_tinyusb: "^1.2" + espressif/esp_tinyusb: "^1.4.2" idf: "^5.0" diff --git a/examples/peripherals/usb/device/tusb_msc/main/tusb_msc_main.c b/examples/peripherals/usb/device/tusb_msc/main/tusb_msc_main.c index 7c157bf03719..89f3dd9ef9db 100644 --- a/examples/peripherals/usb/device/tusb_msc/main/tusb_msc_main.c +++ b/examples/peripherals/usb/device/tusb_msc/main/tusb_msc_main.c @@ -347,7 +347,8 @@ void app_main(void) const tinyusb_msc_spiflash_config_t config_spi = { .wl_handle = wl_handle, - .callback_mount_changed = storage_mount_changed_cb /* First way to register the callback. This is while initializing the storage. */ + .callback_mount_changed = storage_mount_changed_cb, /* First way to register the callback. This is while initializing the storage. */ + .mount_config.max_files = 5, }; ESP_ERROR_CHECK(tinyusb_msc_storage_init_spiflash(&config_spi)); ESP_ERROR_CHECK(tinyusb_msc_register_callback(TINYUSB_MSC_EVENT_MOUNT_CHANGED, storage_mount_changed_cb)); /* Other way to register the callback i.e. registering using separate API. If the callback had been already registered, it will be overwritten. */ @@ -357,7 +358,8 @@ void app_main(void) const tinyusb_msc_sdmmc_config_t config_sdmmc = { .card = card, - .callback_mount_changed = storage_mount_changed_cb /* First way to register the callback. This is while initializing the storage. */ + .callback_mount_changed = storage_mount_changed_cb, /* First way to register the callback. This is while initializing the storage. */ + .mount_config.max_files = 5, }; ESP_ERROR_CHECK(tinyusb_msc_storage_init_sdmmc(&config_sdmmc)); ESP_ERROR_CHECK(tinyusb_msc_register_callback(TINYUSB_MSC_EVENT_MOUNT_CHANGED, storage_mount_changed_cb)); /* Other way to register the callback i.e. registering using separate API. If the callback had been already registered, it will be overwritten. */ From e6fde2e13e667281932effccb7324814b558075d Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Wed, 28 Jun 2023 13:45:15 +0200 Subject: [PATCH 031/161] refactor(usb/host_msc_example): Increase transfer speeds - Upgrade to MSC driver 1.1.1 for zero copy transfers - Use setvbuf() to increase size of VFS file buffer - Add example test --- examples/peripherals/usb/host/msc/README.md | 52 ++- .../usb/host/msc/main/idf_component.yml | 2 +- .../usb/host/msc/main/msc_example_main.c | 306 ++++++++++++------ .../usb/host/msc/pytest_usb_host_msc.py | 27 ++ 4 files changed, 271 insertions(+), 116 deletions(-) create mode 100644 examples/peripherals/usb/host/msc/pytest_usb_host_msc.py diff --git a/examples/peripherals/usb/host/msc/README.md b/examples/peripherals/usb/host/msc/README.md index ad2f78240197..873554fa9af8 100644 --- a/examples/peripherals/usb/host/msc/README.md +++ b/examples/peripherals/usb/host/msc/README.md @@ -5,15 +5,24 @@ ## Overview -This example demonstrates usage of Mass Storage Class to get access to storage on USB memory stick. -Upon connection of USB stick, storage is mounted to Virtual filesystem. Example then creates `ESP` subdirectory(if not present already), as well as `text.txt` file. Its content is then repetitively printed to monitor until USB stick is manually ejected. User can decide whether or not to deinitialize the whole -USB stack or not by shorting GPIO10 to ground. When GPIO10 is left unconnected USB stack is not deinitialized, USB stick can be plugged-in again. +This example demonstrates usage of the MSC (Mass Storage Class) to access storage on a USB flash drive. Upon connection of the flash drive, it is mounted to the Virtual filesystem. The following example operations are then performed: + +1. Print device info (capacity, sectors size, and count...) +2. List all folders and files in the root directory of the USB flash drive +3. Create `ESP` subdirectory (if not present already), as well as a `text.txt` file +4. Run read/write benchmarks by transferring 1 MB of data to a `dummy` file + + +### USB Reconnections + +The example is run in a loop so that it can demonstrate USB connection and reconnection handling. If you want to deinitialize the entire USB Host Stack, you can short GPIO0 to GND. GPIO0 is usually mapped to a BOOT button, thus pressing the button will deinitialize the stack. + ### Hardware Required * Development board with USB capable ESP SoC (ESP32-S2/ESP32-S3) * A USB cable for Power supply and programming -* A USB memory stick +* A USB flash drive ### Common Pin Assignments @@ -30,7 +39,7 @@ ESP BOARD USB CONNECTOR (type A) -- ``` -Additionally, GPIO10 can be shorted to ground in order to deinitialize USB stack after ejecting USB stick. +Additionally, GPIO0 can be shorted to ground in order to deinitialize USB stack. ### Build and Flash @@ -48,16 +57,27 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ``` ... -I (274) cpu_start: Starting scheduler on PRO CPU. -I (339) APP: Waiting for USB stick to be connected +I (380) example: Waiting for USB flash drive to be connected +I (790) example: MSC device connected +... Device info: - PID: 0x5678 - VID: 0xFFFF - iProduct: Disk 2.0 - iManufacturer: USB - iSerialNumber: 92072836B2589224378 -I (719) APP: Writing file -I (749) APP: Reading file -I (749) APP: Read from file: 'Hello World!' -I (759) APP: Done + Capacity: 29339 MB + Sector size: 512 + Sector count: 60088319 + PID: 0x5595 + VID: 0x0781 + iProduct: SanDisk 3.2Gen1 + iManufacturer: USB + iSerialNumber: 0401545df64623a907abf299bae54c9 +I (990) example: ls command output: +SYSTEM~1 +ESP +DUMMY +I (1000) example: Reading file +I (1010) example: Read from file '/usb/esp/test.txt': 'Hello World!' +I (1030) example: Writing to file /usb/esp/dummy +I (2160) example: Write speed 0.93 MiB/s +I (2160) example: Reading from file /usb/esp/dummy +I (3110) example: Read speed 1.10 MiB/s +I (3140) example: Example finished, you can disconnect the USB flash drive ``` diff --git a/examples/peripherals/usb/host/msc/main/idf_component.yml b/examples/peripherals/usb/host/msc/main/idf_component.yml index fc50aa0adfcf..198a93bbf4c5 100644 --- a/examples/peripherals/usb/host/msc/main/idf_component.yml +++ b/examples/peripherals/usb/host/msc/main/idf_component.yml @@ -1,4 +1,4 @@ ## IDF Component Manager Manifest File dependencies: idf: ">=4.4" - usb_host_msc: "^1.0.4" + usb_host_msc: "^1.1.1" diff --git a/examples/peripherals/usb/host/msc/main/msc_example_main.c b/examples/peripherals/usb/host/msc/main/msc_example_main.c index 1fbe55afc8ae..c6be757d9c18 100644 --- a/examples/peripherals/usb/host/msc/main/msc_example_main.c +++ b/examples/peripherals/usb/host/msc/main/msc_example_main.c @@ -8,43 +8,87 @@ #include #include #include +#include +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/event_groups.h" +#include "freertos/queue.h" +#include "esp_timer.h" #include "esp_err.h" #include "esp_log.h" #include "usb/usb_host.h" -#include "msc_host.h" -#include "msc_host_vfs.h" +#include "usb/msc_host.h" +#include "usb/msc_host_vfs.h" #include "ffconf.h" #include "errno.h" #include "driver/gpio.h" -#include "esp_vfs_fat.h" -#define USB_DISCONNECT_PIN GPIO_NUM_10 +static const char *TAG = "example"; +#define MNT_PATH "/usb" // Path in the Virtual File System, where the USB flash drive is going to be mounted +#define APP_QUIT_PIN GPIO_NUM_0 // BOOT button on most boards +#define BUFFER_SIZE 4096 // The read/write performance can be improved with larger buffer for the cost of RAM, 4kB is enough for most usecases -#define READY_TO_UNINSTALL (HOST_NO_CLIENT | HOST_ALL_FREE) +/** + * @brief Application Queue and its messages ID + */ +static QueueHandle_t app_queue; +typedef struct { + enum { + APP_QUIT, // Signals request to exit the application + APP_DEVICE_CONNECTED, // USB device connect event + APP_DEVICE_DISCONNECTED, // USB device disconnect event + } id; + union { + uint8_t new_dev_address; // Address of new USB device for APP_DEVICE_CONNECTED event if + } data; +} app_message_t; + +/** + * @brief BOOT button pressed callback + * + * Signal application to exit the main task + * + * @param[in] arg Unused + */ +static void gpio_cb(void *arg) +{ + BaseType_t xTaskWoken = pdFALSE; + app_message_t message = { + .id = APP_QUIT, + }; -typedef enum { - HOST_NO_CLIENT = 0x1, - HOST_ALL_FREE = 0x2, - DEVICE_CONNECTED = 0x4, - DEVICE_DISCONNECTED = 0x8, - DEVICE_ADDRESS_MASK = 0xFF0, -} app_event_t; + if (app_queue) { + xQueueSendFromISR(app_queue, &message, &xTaskWoken); + } -static const char *TAG = "example"; -static EventGroupHandle_t usb_flags; + if (xTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} +/** + * @brief MSC driver callback + * + * Signal device connection/disconnection to the main task + * + * @param[in] event MSC event + * @param[in] arg MSC event data + */ static void msc_event_cb(const msc_host_event_t *event, void *arg) { if (event->event == MSC_DEVICE_CONNECTED) { ESP_LOGI(TAG, "MSC device connected"); - // Obtained USB device address is placed after application events - xEventGroupSetBits(usb_flags, DEVICE_CONNECTED | (event->device.address << 4)); + app_message_t message = { + .id = APP_DEVICE_CONNECTED, + .data.new_dev_address = event->device.address, + }; + xQueueSend(app_queue, &message, portMAX_DELAY); } else if (event->event == MSC_DEVICE_DISCONNECTED) { - xEventGroupSetBits(usb_flags, DEVICE_DISCONNECTED); ESP_LOGI(TAG, "MSC device disconnected"); + app_message_t message = { + .id = APP_DEVICE_DISCONNECTED, + }; + xQueueSend(app_queue, &message, portMAX_DELAY); } } @@ -57,24 +101,19 @@ static void print_device_info(msc_host_device_info_t *info) printf("\t Capacity: %llu MB\n", capacity); printf("\t Sector size: %"PRIu32"\n", info->sector_size); printf("\t Sector count: %"PRIu32"\n", info->sector_count); - printf("\t PID: 0x%4X \n", info->idProduct); - printf("\t VID: 0x%4X \n", info->idVendor); + printf("\t PID: 0x%04X \n", info->idProduct); + printf("\t VID: 0x%04X \n", info->idVendor); wprintf(L"\t iProduct: %S \n", info->iProduct); wprintf(L"\t iManufacturer: %S \n", info->iManufacturer); wprintf(L"\t iSerialNumber: %S \n", info->iSerialNumber); } -static bool file_exists(const char *file_path) -{ - struct stat buffer; - return stat(file_path, &buffer) == 0; -} - static void file_operations(void) { const char *directory = "/usb/esp"; const char *file_path = "/usb/esp/test.txt"; + // Create /usb/esp directory struct stat s = {0}; bool directory_exists = stat(directory, &s) == 0; if (!directory_exists) { @@ -83,7 +122,8 @@ static void file_operations(void) } } - if (!file_exists(file_path)) { + // Create /usb/esp/test.txt file, if it doesn't exist + if (stat(file_path, &s) != 0) { ESP_LOGI(TAG, "Creating file"); FILE *f = fopen(file_path, "w"); if (f == NULL) { @@ -94,6 +134,7 @@ static void file_operations(void) fclose(f); } + // Read back the file FILE *f; ESP_LOGI(TAG, "Reading file"); f = fopen(file_path, "r"); @@ -109,69 +150,64 @@ static void file_operations(void) if (pos) { *pos = '\0'; } - ESP_LOGI(TAG, "Read from file: '%s'", line); + ESP_LOGI(TAG, "Read from file '%s': '%s'", file_path, line); } -// Handles common USB host library events -static void handle_usb_events(void *args) +void speed_test(void) { - while (1) { - uint32_t event_flags; - usb_host_lib_handle_events(portMAX_DELAY, &event_flags); +#define TEST_FILE "/usb/esp/dummy" +#define ITERATIONS 256 // 256 * 4kb = 1MB + int64_t test_start, test_end; - // Release devices once all clients has deregistered - if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { - usb_host_device_free_all(); - xEventGroupSetBits(usb_flags, HOST_NO_CLIENT); - } - // Give ready_to_uninstall_usb semaphore to indicate that USB Host library - // can be deinitialized, and terminate this task. - if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { - xEventGroupSetBits(usb_flags, HOST_ALL_FREE); - } + FILE *f = fopen(TEST_FILE, "wb+"); + if (f == NULL) { + ESP_LOGE(TAG, "Failed to open file for writing"); + return; } + // Set larger buffer for this file. It results in larger and more effective USB transfers + setvbuf(f, NULL, _IOFBF, BUFFER_SIZE); - vTaskDelete(NULL); -} + // Allocate application buffer used for read/write + uint8_t *data = malloc(BUFFER_SIZE); + assert(data); -static uint8_t wait_for_msc_device(void) -{ - EventBits_t event; - - ESP_LOGI(TAG, "Waiting for USB stick to be connected"); - event = xEventGroupWaitBits(usb_flags, DEVICE_CONNECTED | DEVICE_ADDRESS_MASK, - pdTRUE, pdFALSE, portMAX_DELAY); - ESP_LOGI(TAG, "connection..."); - // Extract USB device address from event group bits - return (event & DEVICE_ADDRESS_MASK) >> 4; -} + ESP_LOGI(TAG, "Writing to file %s", TEST_FILE); + test_start = esp_timer_get_time(); + for (int i = 0; i < ITERATIONS; i++) { + if (fwrite(data, BUFFER_SIZE, 1, f) == 0) { + return; + } + } + test_end = esp_timer_get_time(); + ESP_LOGI(TAG, "Write speed %1.2f MiB/s", (BUFFER_SIZE * ITERATIONS) / (float)(test_end - test_start)); + rewind(f); + + ESP_LOGI(TAG, "Reading from file %s", TEST_FILE); + test_start = esp_timer_get_time(); + for (int i = 0; i < ITERATIONS; i++) { + if (0 == fread(data, BUFFER_SIZE, 1, f)) { + return; + } + } + test_end = esp_timer_get_time(); + ESP_LOGI(TAG, "Read speed %1.2f MiB/s", (BUFFER_SIZE * ITERATIONS) / (float)(test_end - test_start)); -static bool wait_for_event(EventBits_t event, TickType_t timeout) -{ - return xEventGroupWaitBits(usb_flags, event, pdTRUE, pdTRUE, timeout) & event; + fclose(f); + free(data); } -void app_main(void) +/** + * @brief USB task + * + * Install USB Host Library and MSC driver. + * Handle USB Host Library events + * + * @param[in] args Unused + */ +static void usb_task(void *args) { - msc_host_device_handle_t msc_device; - msc_host_vfs_handle_t vfs_handle; - msc_host_device_info_t info; - BaseType_t task_created; - - const gpio_config_t input_pin = { - .pin_bit_mask = BIT64(USB_DISCONNECT_PIN), - .mode = GPIO_MODE_INPUT, - .pull_up_en = GPIO_PULLUP_ENABLE, - }; - ESP_ERROR_CHECK(gpio_config(&input_pin)); - - usb_flags = xEventGroupCreate(); - assert(usb_flags); - const usb_host_config_t host_config = { .intr_flags = ESP_INTR_FLAG_LEVEL1 }; ESP_ERROR_CHECK(usb_host_install(&host_config)); - task_created = xTaskCreate(handle_usb_events, "usb_events", 2048, NULL, 2, NULL); - assert(task_created); const msc_host_driver_config_t msc_config = { .create_backround_task = true, @@ -181,37 +217,109 @@ void app_main(void) }; ESP_ERROR_CHECK(msc_host_install(&msc_config)); - const esp_vfs_fat_mount_config_t mount_config = { - .format_if_mount_failed = false, - .max_files = 3, - .allocation_unit_size = 1024, - }; + while (true) { + uint32_t event_flags; + usb_host_lib_handle_events(portMAX_DELAY, &event_flags); - do { - uint8_t device_address = wait_for_msc_device(); + // Release devices once all clients has deregistered + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + if (usb_host_device_free_all() == ESP_OK) { + break; + }; + } + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + break; + } + } - ESP_ERROR_CHECK(msc_host_install_device(device_address, &msc_device)); + vTaskDelay(10); // Give clients some time to uninstall + ESP_LOGI(TAG, "Deinitializing USB"); + ESP_ERROR_CHECK(usb_host_uninstall()); + vTaskDelete(NULL); +} - msc_host_print_descriptors(msc_device); +void app_main(void) +{ + // Create FreeRTOS primitives + app_queue = xQueueCreate(5, sizeof(app_message_t)); + assert(app_queue); - ESP_ERROR_CHECK(msc_host_get_device_info(msc_device, &info)); - print_device_info(&info); + BaseType_t task_created = xTaskCreate(usb_task, "usb_task", 4096, NULL, 2, NULL); + assert(task_created); - ESP_ERROR_CHECK(msc_host_vfs_register(msc_device, "/usb", &mount_config, &vfs_handle)); + // Init BOOT button: Pressing the button simulates app request to exit + // It will disconnect the USB device and uninstall the MSC driver and USB Host Lib + const gpio_config_t input_pin = { + .pin_bit_mask = BIT64(APP_QUIT_PIN), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .intr_type = GPIO_INTR_NEGEDGE, + }; + ESP_ERROR_CHECK(gpio_config(&input_pin)); + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1)); + ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_cb, NULL)); + + ESP_LOGI(TAG, "Waiting for USB flash drive to be connected"); + msc_host_device_handle_t msc_device = NULL; + msc_host_vfs_handle_t vfs_handle = NULL; - while (!wait_for_event(DEVICE_DISCONNECTED, 200)) { + // Perform all example operations in a loop to allow USB reconnections + while (1) { + app_message_t msg; + xQueueReceive(app_queue, &msg, portMAX_DELAY); + + if (msg.id == APP_DEVICE_CONNECTED) { + // 1. MSC flash drive connected. Open it and map it to Virtual File System + ESP_ERROR_CHECK(msc_host_install_device(msg.data.new_dev_address, &msc_device)); + const esp_vfs_fat_mount_config_t mount_config = { + .format_if_mount_failed = false, + .max_files = 3, + .allocation_unit_size = 8192, + }; + ESP_ERROR_CHECK(msc_host_vfs_register(msc_device, MNT_PATH, &mount_config, &vfs_handle)); + + // 2. Print information about the connected disk + msc_host_device_info_t info; + ESP_ERROR_CHECK(msc_host_get_device_info(msc_device, &info)); + msc_host_print_descriptors(msc_device); + print_device_info(&info); + + // 3. List all the files in root directory + ESP_LOGI(TAG, "ls command output:"); + struct dirent *d; + DIR *dh = opendir(MNT_PATH); + assert(dh); + while ((d = readdir(dh)) != NULL) { + printf("%s\n", d->d_name); + } + closedir(dh); + + // 4. The disk is mounted to Virtual File System, perform some basic demo file operation file_operations(); - } - xEventGroupClearBits(usb_flags, READY_TO_UNINSTALL); - ESP_ERROR_CHECK(msc_host_vfs_unregister(vfs_handle)); - ESP_ERROR_CHECK(msc_host_uninstall_device(msc_device)); + // 5. Perform speed test + speed_test(); - } while (gpio_get_level(USB_DISCONNECT_PIN) != 0); + ESP_LOGI(TAG, "Example finished, you can disconnect the USB flash drive"); + } + if ((msg.id == APP_DEVICE_DISCONNECTED) || (msg.id == APP_QUIT)) { + if (vfs_handle) { + ESP_ERROR_CHECK(msc_host_vfs_unregister(vfs_handle)); + vfs_handle = NULL; + } + if (msc_device) { + ESP_ERROR_CHECK(msc_host_uninstall_device(msc_device)); + msc_device = NULL; + } + if (msg.id == APP_QUIT) { + // This will cause the usb_task to exit + ESP_ERROR_CHECK(msc_host_uninstall()); + break; + } + } + } - ESP_LOGI(TAG, "Uninitializing USB ..."); - ESP_ERROR_CHECK(msc_host_uninstall()); - wait_for_event(READY_TO_UNINSTALL, portMAX_DELAY); - ESP_ERROR_CHECK(usb_host_uninstall()); ESP_LOGI(TAG, "Done"); + gpio_isr_handler_remove(APP_QUIT_PIN); + vQueueDelete(app_queue); } diff --git a/examples/peripherals/usb/host/msc/pytest_usb_host_msc.py b/examples/peripherals/usb/host/msc/pytest_usb_host_msc.py new file mode 100644 index 000000000000..744742262933 --- /dev/null +++ b/examples/peripherals/usb/host/msc/pytest_usb_host_msc.py @@ -0,0 +1,27 @@ + +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.usb_host_flash_disk +def test_usb_host_msc_example(dut: Dut) -> None: + # Check result of file_operations() + dut.expect_exact("example: Read from file '/usb/esp/test.txt': 'Hello World!'") + + # Check result of speed_test() + write_throughput = float(dut.expect(r'example: Write speed ([0-9]*[.]?[0-9]+) MiB')[1].decode()) + read_throughput = float(dut.expect(r'example: Read speed ([0-9]*[.]?[0-9]+) MiB')[1].decode()) + + # These values should be updated for HS targets + if write_throughput > 0.9: + print('Write throughput put OK') + else: + print('write throughput too slow!') + if read_throughput > 1.0: + print('Read throughput put OK') + else: + print('Read throughput too slow!') From 32fd50fa7f4f051d7b7bc9579e1bc03d2085bd65 Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Tue, 24 Oct 2023 21:30:58 +0800 Subject: [PATCH 032/161] ci: remove unused integration test files --- tools/ci/integration_test/KnownIssues | 12 ------------ tools/ci/integration_test/README.md | 12 ------------ 2 files changed, 24 deletions(-) delete mode 100644 tools/ci/integration_test/KnownIssues delete mode 100644 tools/ci/integration_test/README.md diff --git a/tools/ci/integration_test/KnownIssues b/tools/ci/integration_test/KnownIssues deleted file mode 100644 index 186b7a90c396..000000000000 --- a/tools/ci/integration_test/KnownIssues +++ /dev/null @@ -1,12 +0,0 @@ -# CI -ESP32.BLUEDROID_GAP_03003 -ESP32.NIMBLE_GAP_11002 -ESP32.NIMBLE_GAP_14007 - -ESP32C3.NIMBLE_GAP_14009 - -ESP32C2.NIMBLE_GAP_03001 -ESP32C2.NIMBLE_GAP_03004 -ESP32C2.BLUEDROID_GAP_23004 -ESP32C2.BLUEDROID_GAP_03001 -ESP32C2.BLUEDROID_GAP_03004 diff --git a/tools/ci/integration_test/README.md b/tools/ci/integration_test/README.md deleted file mode 100644 index 40d81e78c492..000000000000 --- a/tools/ci/integration_test/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Integration Test Description - -## Case Lists -- WiFi Standard cases for only esp32. -- BLE Standard cases for esp32 and esp32c3. - -## Trigger -- By labels: - - `integration_test[_wifi/ble]` -- By file changes: - - integration test related files - - See `patterns-integration_test[_wifi/ble]` in `.gitlab/ci/rules.yml` From cde207e996b9a5e2facd18018a521ba10f91db62 Mon Sep 17 00:00:00 2001 From: Jakub Kocka Date: Mon, 23 Oct 2023 10:51:26 +0200 Subject: [PATCH 033/161] feat(tools): Added IDF path order check for Windows platform This relates to old GH issue: https://github.com/espressif/esp-idf/issues/5994 --- tools/idf.py | 9 +++++++++ tools/idf_tools.py | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/tools/idf.py b/tools/idf.py index 9ab0d90f57c4..1ddf6b0c95b1 100755 --- a/tools/idf.py +++ b/tools/idf.py @@ -105,6 +105,15 @@ def check_environment() -> List: debug_print_idf_version() raise SystemExit(1) + # Check used Python interpreter + checks_output.append('Checking used Python interpreter...') + try: + python_venv_path = os.environ['IDF_PYTHON_ENV_PATH'] + if python_venv_path and not sys.executable.startswith(python_venv_path): + print_warning(f'WARNING: Python interpreter "{sys.executable}" used to start idf.py is not from installed venv "{python_venv_path}"') + except KeyError: + print_warning('WARNING: The IDF_PYTHON_ENV_PATH is missing in environmental variables!') + return checks_output diff --git a/tools/idf_tools.py b/tools/idf_tools.py index e4be2a98402b..f55a8811f1f8 100755 --- a/tools/idf_tools.py +++ b/tools/idf_tools.py @@ -1802,6 +1802,15 @@ def action_export(args): # type: ignore if paths_to_export: export_vars['PATH'] = path_sep.join(to_shell_specific_paths(paths_to_export) + [old_path]) + # Correct PATH order check for Windows platform + # idf-exe has to be before \tools in PATH + if sys.platform == 'win32': + paths_to_check = rf"{export_vars['PATH']}{os.environ['PATH']}" + try: + if paths_to_check.index(r'\tools;') < paths_to_check.index(r'\idf-exe'): + warn('The PATH is not in correct order (idf-exe should be before esp-idf\\tools)') + except ValueError: + fatal(f'Both of the directories (..\\idf-exe\\.. and ..\\tools) has to be in the PATH:\n\n{paths_to_check}\n') if export_vars: # if not copy of export_vars is given to function, it brekas the formatting string for 'export_statements' From 57f5343462cd1ec1e5e1fbbcde10139ba4f79c14 Mon Sep 17 00:00:00 2001 From: Shang Zhou Date: Wed, 25 Oct 2023 10:25:36 +0800 Subject: [PATCH 034/161] docs: Provide CN translation for api-reference/peripherals/ds.rst --- docs/en/api-reference/peripherals/ds.rst | 79 +++++++++------------ docs/zh_CN/api-reference/peripherals/ds.rst | 74 ++++++++++++++++++- 2 files changed, 107 insertions(+), 46 deletions(-) diff --git a/docs/en/api-reference/peripherals/ds.rst b/docs/en/api-reference/peripherals/ds.rst index 118147c73f16..4f027ff3d7ae 100644 --- a/docs/en/api-reference/peripherals/ds.rst +++ b/docs/en/api-reference/peripherals/ds.rst @@ -1,83 +1,72 @@ Digital Signature (DS) ====================== -The Digital Signature (DS) module provides hardware acceleration of signing messages based on RSA. -It uses pre-encrypted parameters to calculate a signature. -The parameters are encrypted using HMAC as a key-derivation function. -In turn, the HMAC uses eFuses as input key. -The whole process happens in hardware so that neither the decryption key for the RSA parameters nor the input key for the HMAC key derivation function can be seen by the software while calculating the signature. +:link_to_translation:`zh_CN:[中文]` -For more detailed information on the hardware involved in signature calculation and the registers used, see *{IDF_TARGET_NAME} Technical Reference Manual* > *Digital Signature (DS)* [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. +The Digital Signature (DS) module provides hardware acceleration of signing messages based on RSA. It uses pre-encrypted parameters to calculate a signature. The parameters are encrypted using HMAC as a key-derivation function. In turn, the HMAC uses eFuses as the input key. The whole process happens in hardware so that neither the decryption key for the RSA parameters nor the input key for the HMAC key derivation function can be seen by the software while calculating the signature. + +For more detailed information on the hardware involved in the signature calculation and the registers used, see **{IDF_TARGET_NAME} Technical Reference Manual** > **Digital Signature (DS)** [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. Private Key Parameters ---------------------- -The private key parameters for the RSA signature are stored in flash. -To prevent unauthorized access, they are AES-encrypted. -The HMAC module is used as a key-derivation function to calculate the AES encryption key for the private key parameters. -In turn, the HMAC module uses a key from the eFuses key block which can be read-protected to prevent unauthorized access as well. -Upon signature calculation invocation, the software only specifies which eFuse key to use, the corresponding eFuse key purpose, the location of the encrypted RSA parameters and the message. +The private key parameters for the RSA signature are stored in flash. To prevent unauthorized access, they are AES-encrypted. The HMAC module is used as a key-derivation function to calculate the AES encryption key for the private key parameters. In turn, the HMAC module uses a key from the eFuses key block which can be read-protected to prevent unauthorized access as well. + +Upon signature calculation invocation, the software only specifies which eFuse key to use, the corresponding eFuse key purpose, the location of the encrypted RSA parameters, and the message. Key Generation -------------- -Both the HMAC key and the RSA private key have to be created and stored before the DS peripheral can be used. -This needs to be done in software on the {IDF_TARGET_NAME} or alternatively on a host. -For this context, the IDF provides :cpp:func:`esp_efuse_write_block` to set the HMAC key and :cpp:func:`esp_hmac_calculate` to encrypt the private RSA key parameters. -You can find instructions on how to calculate and assemble the private key parameters in *{IDF_TARGET_NAME} Technical Reference Manual* > *Digital Signature (DS)* [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. +Both the HMAC key and the RSA private key have to be created and stored before the DS peripheral can be used. This needs to be done in software on the {IDF_TARGET_NAME} or alternatively on a host. For this context, ESP-IDF provides :cpp:func:`esp_efuse_write_block` to set the HMAC key and :cpp:func:`esp_hmac_calculate` to encrypt the private RSA key parameters. + +You can find instructions on how to calculate and assemble the private key parameters in **{IDF_TARGET_NAME} Technical Reference Manual** > **Digital Signature (DS)** [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. -Signature Calculation with IDF ------------------------------- +Signature Calculation with ESP-IDF +---------------------------------- -For more detailed information on the workflow and the registers used, see *{IDF_TARGET_NAME} Technical Reference Manual* > *Digital Signature (DS)* [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. +For more detailed information on the workflow and the registers used, see **{IDF_TARGET_NAME} Technical Reference Manual** > **Digital Signature (DS)** [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. Three parameters need to be prepared to calculate the digital signature: -#. the eFuse key block ID which is used as key for the HMAC, -#. the location of the encrypted private key parameters, -#. and the message to be signed. +#. The eFuse key block ID which is used as the key for the HMAC +#. The location of the encrypted private key parameters +#. The message to be signed -Since the signature calculation takes some time, there are two possible API versions to use in IDF. -The first one is :cpp:func:`esp_ds_sign` and simply blocks until the calculation is finished. -If software needs to do something else during the calculation, :cpp:func:`esp_ds_start_sign` can be called, followed by periodic calls to :cpp:func:`esp_ds_is_busy` to check when the calculation has finished. -Once the calculation has finished, :cpp:func:`esp_ds_finish_sign` can be called to get the resulting signature. +Since the signature calculation takes some time, there are two possible API versions to use in ESP-IDF. The first one is :cpp:func:`esp_ds_sign` and simply blocks until the calculation is finished. If software needs to do something else during the calculation, :cpp:func:`esp_ds_start_sign` can be called, followed by periodic calls to :cpp:func:`esp_ds_is_busy` to check when the calculation has finished. Once the calculation has finished, :cpp:func:`esp_ds_finish_sign` can be called to get the resulting signature. -The APIs :cpp:func:`esp_ds_sign` and :cpp:func:`esp_ds_start_sign` calculate a plain RSA signature with help of the DS peripheral. This signature needs to be converted to appropriate format for further use. For example, MbedTLS SSL stack supports PKCS#1 format. The API :cpp:func:`esp_ds_rsa_sign` can be used to obtain the signature directly in the PKCS#1 v1.5 format. It internally uses :cpp:func:`esp_ds_start_sign` and converts the signature into PKCS#1 v1.5 format. +The APIs :cpp:func:`esp_ds_sign` and :cpp:func:`esp_ds_start_sign` calculate a plain RSA signature with the help of the DS peripheral. This signature needs to be converted to an appropriate format for further use. For example, the MbedTLS SSL stack supports PKCS#1 format. The API :cpp:func:`esp_ds_rsa_sign` can be used to obtain the signature directly in the PKCS#1 v1.5 format. It internally uses :cpp:func:`esp_ds_start_sign` and converts the signature into PKCS#1 v1.5 format. .. note:: - Note that this is only the basic DS building block, the message length is fixed. - To create signatures of arbitrary messages, the input is normally a hash of the actual message, padded up to the required length. - An API to do this is planned in the future. + + This is only the basic DS building block, the message length is fixed. To create signatures of arbitrary messages, the input is normally a hash of the actual message, padded up to the required length. An API to do this is planned in the future. .. _configure-the-ds-peripheral: -Configure the DS peripheral for a TLS connection +Configure the DS Peripheral for a TLS Connection ------------------------------------------------ -The DS peripheral on {IDF_TARGET_NAME} chip must be configured before it can be used for a TLS connection. -The configuration involves the following steps - +The DS peripheral on {IDF_TARGET_NAME} chip must be configured before it can be used for a TLS connection. The configuration involves the following steps: -1) Randomly generate a 256 bit value called the `Initialization Vector` (IV). -2) Randomly generate a 256 bit value called the `HMAC_KEY`. -3) Calculate the encrypted private key paramters from the client private key (RSA) and the parameters generated in the above steps. -4) Then burn the 256 bit `HMAC_KEY` on the efuse, which can only be read by the DS peripheral. +1) Randomly generate a 256-bit value called the ``Initialization Vector`` (IV). +2) Randomly generate a 256-bit value called the ``HMAC_KEY``. +3) Calculate the encrypted private key parameters from the client private key (RSA) and the parameters generated in the above steps. +4) Then burn the 256-bit ``HMAC_KEY`` on the eFuse, which can only be read by the DS peripheral. -For more details, see *{IDF_TARGET_NAME} Technical Reference Manual* > *Digital Signature (DS)* [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. +For more details, see **{IDF_TARGET_NAME} Technical Reference Manual** > **Digital Signature (DS)** [`PDF <{IDF_TARGET_TRM_EN_URL}#digsig>`__]. To configure the DS peripheral for development purposes, you can use the `esp-secure-cert-tool `_. -The encrypted private key parameters obtained after the DS peripheral configuration are then to be kept in flash. Furthermore, they are to be passed to the DS peripheral which makes use of those parameters for the Digital Signature operation. The application then needs to read the ds data from the flash which has been done through the API's provided by the `esp_secure_cert_mgr `_ component. Please refer the `component/README. `_ for more details. +The encrypted private key parameters obtained after the DS peripheral configuration are then to be kept in flash. Furthermore, they are to be passed to the DS peripheral which makes use of those parameters for the Digital Signature operation. The application then needs to read the DS data from the flash, which has been done through the APIs provided by the `esp_secure_cert_mgr `_ component. Please refer to the `component/README `_ for more details. + +The process of initializing the DS peripheral and then performing the Digital Signature operation is done internally with the help of `ESP-TLS`. Please refer to :ref:`digital-signature-with-esp-tls` for more details. -The process of initializing the DS peripheral and then performing the Digital Signature operation is done internally with help of `ESP-TLS`. Please refer to `Digital Signature with ESP-TLS` in :doc:`ESP-TLS <../protocols/esp_tls>` for more details. -As mentioned in the `ESP-TLS` documentation, the application only needs to provide the encrypted private key parameters to the esp_tls context (as `ds_data`), which internally performs -all necessary operations for initializing the DS peripheral and then performing the DS operation. +As mentioned in the `ESP-TLS` documentation, the application only needs to provide the encrypted private key parameters to the esp_tls context (as `ds_data`), which internally performs all necessary operations for initializing the DS peripheral and then performing the DS operation. -Example for SSL Mutual Authentication using DS +Example for SSL Mutual Authentication Using DS ---------------------------------------------- -The example :example:`ssl_ds` shows how to use the DS peripheral for mutual authentication. The example uses `mqtt_client` (Implemented through `ESP-MQTT`) -to connect to broker test.mosquitto.org using ssl transport with mutual authentication. The ssl part is internally performed with `ESP-TLS`. -See :example_file:`example README` for more details. + +The example :example:`protocols/mqtt/ssl_ds` shows how to use the DS peripheral for mutual authentication. The example uses `mqtt_client` (Implemented through `ESP-MQTT`) to connect to broker ``test.mosquitto.org`` using SSL transport with mutual authentication. The SSL part is internally performed with `ESP-TLS`. See :example_file:`protocols/mqtt/ssl_ds/README.md` for more details. API Reference ------------- diff --git a/docs/zh_CN/api-reference/peripherals/ds.rst b/docs/zh_CN/api-reference/peripherals/ds.rst index b4b133d0e65a..3b147c213e86 100644 --- a/docs/zh_CN/api-reference/peripherals/ds.rst +++ b/docs/zh_CN/api-reference/peripherals/ds.rst @@ -1,2 +1,74 @@ -.. include:: ../../../en/api-reference/peripherals/ds.rst +数字签名 (DS) +============= +:link_to_translation:`en:[English]` + +数字签名 (DS) 模块利用 RSA 硬件加速器为信息签名。HMAC 作为密钥派生函数,使用 eFuse 作为输入密钥,输出一组加密参数。随后,数字签名模块利用这组预加密的参数,计算出签名。以上过程均在硬件中完成,因此在计算签名时,软件无法获取 RSA 参数的解密密钥,也无法获取 HMAC 密钥派生函数的输入密钥。 + +签名计算所涉及的硬件信息以及所用寄存器的有关信息,请参阅 **{IDF_TARGET_NAME} 技术参考手册** > **数字签名 (DS)** [`PDF <{IDF_TARGET_TRM_CN_URL}#digsig>`__]。 + + +私钥参数 +-------- + +RSA 签名的私钥参数存储在 flash 中。为防止发生未经授权的访问,这些参数都进行了 AES 加密。此时,HMAC 模块被作为密钥派生函数,用于计算 AES 加密了的私钥参数。同时,HMAC 模块本身使用的来自 eFuse 密钥块的密钥也具有读取保护,可以防止发生未经授权的访问。 + +调用签名计算时,软件只需指定使用的 eFuse 密钥、相应的 eFuse 密钥用途、加密的 RSA 参数位置以及待签名的数据或信息。 + +密钥生成 +--------- + +在使用 DS 外设前,需首先创建并存储 HMAC 密钥和 RSA 私钥,此步骤可在 {IDF_TARGET_NAME} 上通过软件完成,也可在主机上进行。在 ESP-IDF 中,可以使用 :cpp:func:`esp_efuse_write_block` 设置 HMAC 密钥,并使用 :cpp:func:`esp_hmac_calculate` 对 RSA 私钥参数进行加密。 + +计算并组装私钥参数的详细信息,请参阅 **{IDF_TARGET_NAME} 技术参考手册** > **数字签名 (DS)** [`PDF <{IDF_TARGET_TRM_CN_URL}#digsig>`__]。 + +在 ESP-IDF 中进行数字签名计算 +---------------------------------- + +在 ESP-IDF 中进行数字签名计算的工作流程,以及所用寄存器的有关信息,请参阅 **{IDF_TARGET_NAME} 技术参考手册** > **数字签名 (DS)** [`PDF <{IDF_TARGET_TRM_CN_URL}#digsig>`__]。 + +要进行数字签名计算,需要准备以下三个参数: + +#. 用作 HMAC 密钥的 eFuse 密钥块 ID +#. 加密私钥参数的位置 +#. 待签名的数据或信息 + +由于签名计算需要一些时间,ESP-IDF 提供了两种可用的 API。第一种是 :cpp:func:`esp_ds_sign`,调用此 API 后,程序会在计算完成前保持阻塞状态。如果在计算过程中,软件需要执行其他操作,则可以调用 :cpp:func:`esp_ds_start_sign`,用另一种方式启动签名计算,然后周期性地调用 :cpp:func:`esp_ds_is_busy`,检查计算是否已完成。一旦计算完成,即可调用 :cpp:func:`esp_ds_finish_sign` 来获取签名结果。 + +API :cpp:func:`esp_ds_sign` 和 :cpp:func:`esp_ds_start_sign` 会借助 DS 外设计算明文 RSA 签名。RSA 签名需要转换成合适的格式,以供进一步使用。例如,MbedTLS SSL 栈支持 PKCS#1 格式,使用 API :cpp:func:`esp_ds_rsa_sign` 可以直接获得 PKCS#1 v1.5 格式的签名,该 API 内部调用了 :cpp:func:`esp_ds_start_sign` 函数,并将签名转换成 PKCS#1 v1.5 格式。 + +.. note:: + + 此处只是最基本的 DS 构造块,其消息必须是固定长度。为在任意消息上创建签名,通常会将实际消息的哈希值作为输入,并将其填充到所需长度。乐鑫计划在未来提供一个 API 来实现这个功能。 + +.. _configure-the-ds-peripheral: + +TLS 连接所需的 DS 外设配置 +------------------------------ + +在 {IDF_TARGET_NAME} 芯片上使用 TLS 连接之前,必须先配置 DS 外设,具体步骤如下: + +1) 随机生成一个 256 位的值,作为 ``初始化向量`` (IV)。 +2) 随机生成一个 256 位的值,作为 ``HMAC_KEY``。 +3) 使用客户端私钥 (RAS) 和上述步骤生成的参数,计算加密的私钥参数。 +4) 将 256 位的 ``HMAC_KEY`` 烧录到 eFuse 中,只支持 DS 外设读取。 + +更多细节,请参阅 **{IDF_TARGET_NAME} 技术参考手册** > **数字签名 (DS)** [`PDF <{IDF_TARGET_TRM_CN_URL}#digsig>`__]。 + +如果要以开发为目的配置 DS 外设,可以使用 `esp-secure-cert-tool `_。 + +配置完 DS 外设后获取的加密私钥参数需要保存在 flash 中并传递给 DS 外设,DS 外设将使用这些参数完成数字签名。随后,应用程序需要从 flash 中读取 DS 数据,这可以通过 `esp_secure_cert_mgr `_ 组件提供的 API 完成。更多细节,请参阅 `component/README `_。 + +在 esp_tls 仓库内部,`ESP-TLS` 负责完成初始化 DS 外设、执行数字签名的过程。更多细节,请参阅 :ref:`digital-signature-with-esp-tls`。 + +如 `ESP-TLS` 文档所述,应用程序只需将加密私钥参数作为 `ds_data` 传递给 esp_tls 上下文,esp_tls 仓库内部就会执行所有必要操作,以初始化 DS 外设,并执行数字签名。 + +使用 DS 外设进行 SSL 双向认证 +----------------------------- + +示例 :example:`protocols/mqtt/ssl_ds` 展示了如何使用 DS 外设进行 SSL 双向认证。在示例中,使用了 `mqtt_client` (通过 `ESP-MQTT` 实现),通过 SSL 传输连接到代理服务器 ``test.mosquitto.org``,并进行 SSL 双向认证。SSL 部分在内部使用 `ESP-TLS` 完成。更多细节,请参阅 :example_file:`protocols/mqtt/ssl_ds/README.md`。 + +API 参考 +-------- + +.. include-build-file:: inc/esp_ds.inc From 53939de34ede197b12fd44ae8bda26627fc04867 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Wed, 25 Oct 2023 09:55:12 +0530 Subject: [PATCH 035/161] fix(wpa_supplicant): Fix compilation issue in EAP disabled --- components/wpa_supplicant/src/rsn_supp/wpa.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 06f564e0840d..94cfa95fbc03 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -655,6 +655,7 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, u8 *kde, *kde_buf = NULL; size_t kde_len; +#ifdef CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT if (is_wpa2_enterprise_connection()) { wpa2_ent_eap_state_t state = eap_client_get_eap_state(); if (state == WPA2_ENT_EAP_STATE_IN_PROGRESS) { @@ -663,6 +664,8 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, return; } } +#endif + wpa_sm_set_state(WPA_FIRST_HALF_4WAY_HANDSHAKE); wpa_printf(MSG_DEBUG, "WPA 1/4-Way Handshake"); From 81665b27c3ef5add075c81393466e3c568944c61 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Thu, 19 Oct 2023 11:01:56 +0530 Subject: [PATCH 036/161] fix(docs): Disable the NVS encryption HMAC scheme section for unsupported SoCs --- .../api-reference/storage/nvs_encryption.rst | 64 +++++++++---------- .../api-reference/storage/nvs_encryption.rst | 62 +++++++++--------- 2 files changed, 63 insertions(+), 63 deletions(-) diff --git a/docs/en/api-reference/storage/nvs_encryption.rst b/docs/en/api-reference/storage/nvs_encryption.rst index 97efccdf9c58..9a22844fba8f 100644 --- a/docs/en/api-reference/storage/nvs_encryption.rst +++ b/docs/en/api-reference/storage/nvs_encryption.rst @@ -86,18 +86,18 @@ It is possible for an application to use different keys for different NVS partit .. only:: SOC_HMAC_SUPPORTED -NVS Encryption: HMAC Peripheral-Based Scheme --------------------------------------------- + NVS Encryption: HMAC Peripheral-Based Scheme + -------------------------------------------- -In this scheme, the XTS keys required for NVS encryption are derived from an HMAC key programmed in eFuse with the purpose :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`. Since the encryption keys are derived at runtime, they are not stored anywhere in the flash. Thus, this feature does not require a separate :ref:`nvs_encr_key_partition`. + In this scheme, the XTS keys required for NVS encryption are derived from an HMAC key programmed in eFuse with the purpose :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`. Since the encryption keys are derived at runtime, they are not stored anywhere in the flash. Thus, this feature does not require a separate :ref:`nvs_encr_key_partition`. -.. note:: + .. note:: - This scheme enables us to achieve secure storage on {IDF_TARGET_NAME} **without enabling flash encryption**. + This scheme enables us to achieve secure storage on {IDF_TARGET_NAME} **without enabling flash encryption**. -.. important:: + .. important:: - Please take note that this scheme uses one eFuse block for storing the HMAC key required for deriving the encryption keys. + Please take note that this scheme uses one eFuse block for storing the HMAC key required for deriving the encryption keys. - When NVS encryption is enabled, the :cpp:func:`nvs_flash_init` API function can be used to initialize the encrypted default NVS partition. The API function first checks whether an HMAC key is present at :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID`. @@ -146,37 +146,37 @@ Alternatively, :cpp:func:`nvs_flash_secure_init` API function can also be used t .. only:: SOC_HMAC_SUPPORTED - * For the HMAC-based scheme + * For the HMAC-based scheme - - Set the scheme-specific config data with :cpp:type:`nvs_sec_config_hmac_t` and register the HMAC-based scheme with the API :cpp:func:`nvs_sec_provider_register_hmac` which will also populate the scheme-specific handle (see :cpp:type:`nvs_sec_scheme_t`). - - Populate the :cpp:type:`nvs_sec_cfg_t` struct using the :cpp:func:`nvs_flash_read_security_cfg_v2` or :cpp:func:`nvs_flash_generate_keys_v2` API functions. + - Set the scheme-specific config data with :cpp:type:`nvs_sec_config_hmac_t` and register the HMAC-based scheme with the API :cpp:func:`nvs_sec_provider_register_hmac` which will also populate the scheme-specific handle (see :cpp:type:`nvs_sec_scheme_t`). + - Populate the :cpp:type:`nvs_sec_cfg_t` struct using the :cpp:func:`nvs_flash_read_security_cfg_v2` or :cpp:func:`nvs_flash_generate_keys_v2` API functions. - .. code-block:: c + .. code-block:: c - nvs_sec_cfg_t cfg = {}; - nvs_sec_scheme_t *sec_scheme_handle = NULL; + nvs_sec_cfg_t cfg = {}; + nvs_sec_scheme_t *sec_scheme_handle = NULL; - nvs_sec_config_hmac_t sec_scheme_cfg = {}; - hmac_key_id_t hmac_key = HMAC_KEY0; - sec_scheme_cfg.hmac_key_id = hmac_key; + nvs_sec_config_hmac_t sec_scheme_cfg = {}; + hmac_key_id_t hmac_key = HMAC_KEY0; + sec_scheme_cfg.hmac_key_id = hmac_key; - ret = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle); - if (ret != ESP_OK) { - return ret; - } + ret = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle); + if (ret != ESP_OK) { + return ret; + } - ret = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); - if (ret != ESP_OK) { - if (ret == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) { - ret = nvs_flash_generate_keys_v2(&sec_scheme_handle, &cfg); - if (ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to generate NVS encr-keys!"); - return ret; + ret = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); + if (ret != ESP_OK) { + if (ret == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) { + ret = nvs_flash_generate_keys_v2(&sec_scheme_handle, &cfg); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to generate NVS encr-keys!"); + return ret; + } } + ESP_LOGE(TAG, "Failed to read NVS security cfg!"); + return ret; } - ESP_LOGE(TAG, "Failed to read NVS security cfg!"); - return ret; - } 2. Initialise NVS flash partition using the :cpp:func:`nvs_flash_secure_init` or :cpp:func:`nvs_flash_secure_init_partition` API functions. 3. Open a namespace using the :cpp:func:`nvs_open` or :cpp:func:`nvs_open_from_partition` API functions. @@ -185,8 +185,8 @@ Alternatively, :cpp:func:`nvs_flash_secure_init` API function can also be used t .. only:: SOC_HMAC_SUPPORTED -.. note:: - While using the HMAC-based scheme, the above workflow can be used without enabling any of the config options for NVS encryption - :ref:`CONFIG_NVS_ENCRYPTION`, :ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> ``CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC`` and :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` to encrypt the default as well as custom NVS partitions with :cpp:func:`nvs_flash_secure_init` API. + .. note:: + While using the HMAC-based scheme, the above workflow can be used without enabling any of the config options for NVS encryption - :ref:`CONFIG_NVS_ENCRYPTION`, :ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> ``CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC`` and :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` to encrypt the default as well as custom NVS partitions with :cpp:func:`nvs_flash_secure_init` API. NVS Security Provider diff --git a/docs/zh_CN/api-reference/storage/nvs_encryption.rst b/docs/zh_CN/api-reference/storage/nvs_encryption.rst index d36be49c5781..589dfb143ec5 100644 --- a/docs/zh_CN/api-reference/storage/nvs_encryption.rst +++ b/docs/zh_CN/api-reference/storage/nvs_encryption.rst @@ -69,7 +69,7 @@ NVS 密钥分区 idf.py partition-table partition-table-flash - 1. 使用 :component_file:`parttool.py` (参见 :doc:`/api-guides/partition-tables` 中分区工具相关章节)将密钥存储在 flash 上的 :ref:`nvs_encr_key_partition` 中 + 2. 使用 :component_file:`parttool.py` (参见 :doc:`/api-guides/partition-tables` 中分区工具相关章节)将密钥存储在 flash 上的 :ref:`nvs_encr_key_partition` 中 :: parttool.py --port PORT --partition-table-offset PARTITION_TABLE_OFFSET write_partition --partition-name="name of nvs_key partition" --input NVS_KEY_PARTITION_FILE @@ -86,18 +86,18 @@ NVS 密钥分区 .. only:: SOC_HMAC_SUPPORTED -NVS 加密:基于 HMAC 外设的方案 --------------------------------------------- + NVS 加密:基于 HMAC 外设的方案 + -------------------------------------------- -此方案中,用于 NVS 加密的 XTS 密钥来自 eFuse 中编程的 HMAC 密钥,其目的是 :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`。由于加密密钥在运行时生成,不存储在 flash 中,因此这个功能不需要单独的 :ref:`nvs_encr_key_partition`。 + 此方案中,用于 NVS 加密的 XTS 密钥来自 eFuse 中编程的 HMAC 密钥,其目的是 :cpp:enumerator:`esp_efuse_purpose_t::ESP_EFUSE_KEY_PURPOSE_HMAC_UP`。由于加密密钥在运行时生成,不存储在 flash 中,因此这个功能不需要单独的 :ref:`nvs_encr_key_partition`。 -.. note:: + .. note:: - 通过这个方案, **无需启用 flash 加密** 就能在 {IDF_TARGET_NAME} 上实现安全存储。 + 通过这个方案, **无需启用 flash 加密** 就能在 {IDF_TARGET_NAME} 上实现安全存储。 -.. important:: + .. important:: - 注意,此方案使用一个 eFuse 块来存储获取加密密钥所需的 HMAC 密钥。 + 注意,此方案使用一个 eFuse 块来存储获取加密密钥所需的 HMAC 密钥。 - NVS 加密启用时后,可用 API 函数 :cpp:func:`nvs_flash_init` 来初始化加密的默认 NVS 分区。该 API 函数首先检查 :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID` 处是否存在一个 HMAC 密钥。 @@ -146,37 +146,37 @@ NVS API 函数 ``nvs_get_*`` 或 ``nvs_set_*`` 也可用于读取和写入加密 .. only:: SOC_HMAC_SUPPORTED - * 对基于 HMAC 的方案 + * 对基于 HMAC 的方案 - - 用 :cpp:type:`nvs_sec_config_hmac_t` 为设置特定方案配置数据,并使用 API :cpp:func:`nvs_sec_provider_register_hmac` 注册此基于 HMAC 的方案。该 API 也将用于填充特定方案的句柄(参见 :cpp:type:`nvs_sec_scheme_t`)。 - - 使用 API 函数 :cpp:func:`nvs_flash_read_security_cfg_v2` 或 :cpp:func:`nvs_flash_generate_keys_v2` 填充 :cpp:type:`nvs_sec_cfg_t` 结构体。 + - 用 :cpp:type:`nvs_sec_config_hmac_t` 为设置特定方案配置数据,并使用 API :cpp:func:`nvs_sec_provider_register_hmac` 注册此基于 HMAC 的方案。该 API 也将用于填充特定方案的句柄(参见 :cpp:type:`nvs_sec_scheme_t`)。 + - 使用 API 函数 :cpp:func:`nvs_flash_read_security_cfg_v2` 或 :cpp:func:`nvs_flash_generate_keys_v2` 填充 :cpp:type:`nvs_sec_cfg_t` 结构体。 - .. code-block:: c + .. code-block:: c - nvs_sec_cfg_t cfg = {}; - nvs_sec_scheme_t *sec_scheme_handle = NULL; + nvs_sec_cfg_t cfg = {}; + nvs_sec_scheme_t *sec_scheme_handle = NULL; - nvs_sec_config_hmac_t sec_scheme_cfg = {}; - hmac_key_id_t hmac_key = HMAC_KEY0; - sec_scheme_cfg.hmac_key_id = hmac_key; + nvs_sec_config_hmac_t sec_scheme_cfg = {}; + hmac_key_id_t hmac_key = HMAC_KEY0; + sec_scheme_cfg.hmac_key_id = hmac_key; - ret = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle); - if (ret != ESP_OK) { + ret = nvs_sec_provider_register_hmac(&sec_scheme_cfg, &sec_scheme_handle); + if (ret != ESP_OK) { return ret; - } + } - ret = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); - if (ret != ESP_OK) { - if (ret == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) { - ret = nvs_flash_generate_keys_v2(&sec_scheme_handle, &cfg); - if (ret != ESP_OK) { + ret = nvs_flash_read_security_cfg_v2(sec_scheme_handle, &cfg); + if (ret != ESP_OK) { + if (ret == ESP_ERR_NVS_SEC_HMAC_KEY_NOT_FOUND) { + ret = nvs_flash_generate_keys_v2(&sec_scheme_handle, &cfg); + if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to generate NVS encr-keys!"); - return ret; + return ret; + } } + ESP_LOGE(TAG, "Failed to read NVS security cfg!"); + return ret; } - ESP_LOGE(TAG, "Failed to read NVS security cfg!"); - return ret; - } 2. 使用 API 函数 :cpp:func:`nvs_flash_secure_init` 或 :cpp:func:`nvs_flash_secure_init_partition` 初始化 NVS flash 分区。 3. 使用 API 函数 :cpp:func:`nvs_open` 或 :cpp:func:`nvs_open_from_partition` 打开一个命名空间。 @@ -185,8 +185,8 @@ NVS API 函数 ``nvs_get_*`` 或 ``nvs_set_*`` 也可用于读取和写入加密 .. only:: SOC_HMAC_SUPPORTED -.. note:: - 在采用基于 HMAC 的方案时,可以在不启用任何 NVS 加密的配置选项的情况下开始上述工作流::ref:`CONFIG_NVS_ENCRYPTION`,:ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> `CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC` 和 :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID`,以使用 :cpp:func:`nvs_flash_secure_init` API 加密默认分区及自定义的 NVS 分区。 + .. note:: + 在采用基于 HMAC 的方案时,可以在不启用任何 NVS 加密的配置选项的情况下开始上述工作流::ref:`CONFIG_NVS_ENCRYPTION`,:ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME` -> `CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC` 和 :ref:`CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID`,以使用 :cpp:func:`nvs_flash_secure_init` API 加密默认分区及自定义的 NVS 分区。 NVS Security Provider From 263e39c32b447f7832744f2458f13abbfe2033a9 Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 20 Oct 2023 11:39:47 +0800 Subject: [PATCH 037/161] fix(sdmmc): fix ll layer wrong assertion --- components/hal/esp32/include/hal/sdmmc_ll.h | 4 ++-- components/hal/esp32p4/include/hal/sdmmc_ll.h | 4 ++-- components/hal/esp32s3/include/hal/sdmmc_ll.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/hal/esp32/include/hal/sdmmc_ll.h b/components/hal/esp32/include/hal/sdmmc_ll.h index 497b950d9a35..424528b3a6de 100644 --- a/components/hal/esp32/include/hal/sdmmc_ll.h +++ b/components/hal/esp32/include/hal/sdmmc_ll.h @@ -197,10 +197,10 @@ static inline uint32_t sdmmc_ll_get_card_clock_div(sdmmc_dev_t *hw, uint32_t slo uint32_t card_div = 0; if (slot == 0) { - HAL_ASSERT(hw->clksrc.card0 = 0); + HAL_ASSERT(hw->clksrc.card0 == 0); card_div = hw->clkdiv.div0; } else if (slot == 1) { - HAL_ASSERT(hw->clksrc.card1 = 1); + HAL_ASSERT(hw->clksrc.card1 == 1); card_div = hw->clkdiv.div1; } else { HAL_ASSERT(false); diff --git a/components/hal/esp32p4/include/hal/sdmmc_ll.h b/components/hal/esp32p4/include/hal/sdmmc_ll.h index a3c5d099861f..4a447433af7d 100644 --- a/components/hal/esp32p4/include/hal/sdmmc_ll.h +++ b/components/hal/esp32p4/include/hal/sdmmc_ll.h @@ -245,10 +245,10 @@ static inline uint32_t sdmmc_ll_get_card_clock_div(sdmmc_dev_t *hw, uint32_t slo uint32_t card_div = 0; if (slot == 0) { - HAL_ASSERT(hw->clksrc.card0 = 0); + HAL_ASSERT(hw->clksrc.card0 == 0); card_div = hw->clkdiv.clk_divider0; } else if (slot == 1) { - HAL_ASSERT(hw->clksrc.card1 = 1); + HAL_ASSERT(hw->clksrc.card1 == 1); card_div = hw->clkdiv.clk_divider1; } else { HAL_ASSERT(false); diff --git a/components/hal/esp32s3/include/hal/sdmmc_ll.h b/components/hal/esp32s3/include/hal/sdmmc_ll.h index 4581aeb9924d..101bb970fc21 100644 --- a/components/hal/esp32s3/include/hal/sdmmc_ll.h +++ b/components/hal/esp32s3/include/hal/sdmmc_ll.h @@ -233,10 +233,10 @@ static inline uint32_t sdmmc_ll_get_card_clock_div(sdmmc_dev_t *hw, uint32_t slo uint32_t card_div = 0; if (slot == 0) { - HAL_ASSERT(hw->clksrc.card0 = 0); + HAL_ASSERT(hw->clksrc.card0 == 0); card_div = hw->clkdiv.div0; } else if (slot == 1) { - HAL_ASSERT(hw->clksrc.card1 = 1); + HAL_ASSERT(hw->clksrc.card1 == 1); card_div = hw->clkdiv.div1; } else { HAL_ASSERT(false); From e32bdb66e35f565e806847e4f423565b57d570af Mon Sep 17 00:00:00 2001 From: Djordje Nedic Date: Wed, 25 Oct 2023 08:09:33 +0200 Subject: [PATCH 038/161] fix: Fix ESP32-P4 lp_reserved_seg origin Apparently, this part of the linker script was copied from elsewhere and the origin was not corrected. --- components/esp_system/ld/esp32p4/memory.ld.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_system/ld/esp32p4/memory.ld.in b/components/esp_system/ld/esp32p4/memory.ld.in index 41ed1d38477b..a4e1c17c62ff 100644 --- a/components/esp_system/ld/esp32p4/memory.ld.in +++ b/components/esp_system/ld/esp32p4/memory.ld.in @@ -95,7 +95,7 @@ MEMORY - (higher addr) bootloader rtc data (s_bootloader_retain_mem, when a Kconfig option is on). The aim of this is to keep data that will not be moved around and have a fixed address. */ - lp_reserved_seg(RW) : org = 0x50000000 + 0x8000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM + lp_reserved_seg(RW) : org = 0x50108000 + 0x8000 - RESERVE_RTC_MEM, len = RESERVE_RTC_MEM } /* Heap ends at top of dram0_0_seg */ From f1c6bc9e68267433d27dcfa624e4f9b26e6f3ac4 Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Tue, 24 Oct 2023 21:40:38 +0800 Subject: [PATCH 039/161] ci: remove unused integration test rules --- .gitlab/ci/README.md | 2 +- .gitlab/ci/dependencies/dependencies.yml | 27 -------------------- .gitlab/ci/rules.yml | 32 ------------------------ 3 files changed, 1 insertion(+), 60 deletions(-) diff --git a/.gitlab/ci/README.md b/.gitlab/ci/README.md index a3ff2bbb9869..ab138c09433b 100644 --- a/.gitlab/ci/README.md +++ b/.gitlab/ci/README.md @@ -59,7 +59,7 @@ - `example_test[_esp32/esp32s2/...]` - `fuzzer_test` - `host_test` -- `integration_test[_wifi/ble]` +- `integration_test` - `iperf_stress_test` - `macos` - `macos_test` diff --git a/.gitlab/ci/dependencies/dependencies.yml b/.gitlab/ci/dependencies/dependencies.yml index 87d3f539020a..5905f5be9fba 100644 --- a/.gitlab/ci/dependencies/dependencies.yml +++ b/.gitlab/ci/dependencies/dependencies.yml @@ -83,16 +83,6 @@ - "build:{0}" - build:target_test -build:integration_test: - labels: - - build - patterns: - - build_components - - build_system - included_in: - - build:target_test - - #################### # Target Test Jobs # #################### @@ -173,23 +163,6 @@ build:integration_test: - "build:example_test" - build:target_test -"test:integration_test_{0}": - matrix: - - - wifi - - ble - labels: - - integration_test_{0} - - integration_test - - target_test - patterns: - - integration_test-{0} - - target_test-{0} - # - maybe others - included_in: - - test:integration_test - - build:integration_test - - build:target_test - "test:host_test": labels: - host_test diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 9f39debe8b4e..9202f59ddc02 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -112,22 +112,6 @@ .patterns-component_ut-wifi: &patterns-component_ut-wifi - "components/esp_wifi/**/*" -.patterns-integration_test-ble: &patterns-integration_test-ble - - "tools/ci/python_packages/gitlab_api.py" - - "tools/ci/integration_test/**/*" - - "components/bt/controller/lib_esp32" - - "components/bt/controller/lib_esp32c3_family" - - "components/bt/controller/lib_esp32h2/esp32h2-bt-lib" - - "components/bt/host/nimble/nimble" - - "components/esp_phy/lib" - - "components/esp_coex/??[!s][!t]*/**/*" - - "components/esp_coex/???/**/*" - - "components/esp_coex/*" - -.patterns-integration_test-wifi: &patterns-integration_test-wifi - - "tools/ci/python_packages/gitlab_api.py" - - "tools/ci/integration_test/**/*" - .patterns-build_macos: &patterns-build_macos - "tools/ci/test_configure_ci_environment.sh" @@ -571,15 +555,6 @@ .if-label-host_test: &if-label-host_test if: '$BOT_LABEL_HOST_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*host_test(?:,[^,\n\r]+)*$/i' -.if-label-integration_test: &if-label-integration_test - if: '$BOT_LABEL_INTEGRATION_TEST || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*integration_test(?:,[^,\n\r]+)*$/i' - -.if-label-integration_test_ble: &if-label-integration_test_ble - if: '$BOT_LABEL_INTEGRATION_TEST_BLE || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*integration_test_ble(?:,[^,\n\r]+)*$/i' - -.if-label-integration_test_wifi: &if-label-integration_test_wifi - if: '$BOT_LABEL_INTEGRATION_TEST_WIFI || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*integration_test_wifi(?:,[^,\n\r]+)*$/i' - .if-label-macos: &if-label-macos if: '$BOT_LABEL_MACOS || $CI_MERGE_REQUEST_LABELS =~ /^(?:[^,\n\r]+,)*macos(?:,[^,\n\r]+)*$/i' @@ -1584,9 +1559,6 @@ - <<: *if-label-example_test_esp32p4 - <<: *if-label-example_test_esp32s2 - <<: *if-label-example_test_esp32s3 - - <<: *if-label-integration_test - - <<: *if-label-integration_test_ble - - <<: *if-label-integration_test_wifi - <<: *if-label-target_test - <<: *if-dev-push changes: *patterns-build-example_test @@ -1634,10 +1606,6 @@ changes: *patterns-example_test-usb - <<: *if-dev-push changes: *patterns-example_test-wifi - - <<: *if-dev-push - changes: *patterns-integration_test-ble - - <<: *if-dev-push - changes: *patterns-integration_test-wifi - <<: *if-dev-push changes: *patterns-target_test-adc - <<: *if-dev-push From 375907299ea5bd69ee229c07a2fb7bebfa65d354 Mon Sep 17 00:00:00 2001 From: Roman Leonov Date: Mon, 11 Sep 2023 12:27:48 +0200 Subject: [PATCH 040/161] fix(usb/host): added hid_driver_uninstall call during APP_QUIT for HID Host example --- .../usb/host/hid/main/hid_host_example.c | 158 +++++++++++------- .../usb/host/hid/main/idf_component.yml | 2 +- 2 files changed, 102 insertions(+), 58 deletions(-) diff --git a/examples/peripherals/usb/host/hid/main/hid_host_example.c b/examples/peripherals/usb/host/hid/main/hid_host_example.c index 2ed93839199b..ca8783f0b250 100644 --- a/examples/peripherals/usb/host/hid/main/hid_host_example.c +++ b/examples/peripherals/usb/host/hid/main/hid_host_example.c @@ -26,19 +26,37 @@ #define APP_QUIT_PIN GPIO_NUM_0 static const char *TAG = "example"; -QueueHandle_t hid_host_event_queue; -bool user_shutdown = false; + +QueueHandle_t app_event_queue = NULL; + +/** + * @brief APP event group + * + * Application logic can be different. There is a one among other ways to distingiush the + * event by application event group. + * In this example we have two event groups: + * APP_EVENT - General event, which is APP_QUIT_PIN press event (Generally, it is IO0). + * APP_EVENT_HID_HOST - HID Host Driver event, such as device connection/disconnection or input report. + */ +typedef enum { + APP_EVENT = 0, + APP_EVENT_HID_HOST +} app_event_group_t; /** - * @brief HID Host event + * @brief APP event queue * * This event is used for delivering the HID Host event from callback to a task. */ typedef struct { - hid_host_device_handle_t hid_device_handle; - hid_host_driver_event_t event; - void *arg; -} hid_host_event_queue_t; + app_event_group_t event_group; + /* HID Host - Device related info */ + struct { + hid_host_device_handle_t handle; + hid_host_driver_event_t event; + void *arg; + } hid_host_device; +} app_event_queue_t; /** * @brief HID Protocol string names @@ -437,13 +455,6 @@ void hid_host_device_event(hid_host_device_handle_t hid_device_handle, */ static void usb_lib_task(void *arg) { - const gpio_config_t input_pin = { - .pin_bit_mask = BIT64(APP_QUIT_PIN), - .mode = GPIO_MODE_INPUT, - .pull_up_en = GPIO_PULLUP_ENABLE, - }; - ESP_ERROR_CHECK(gpio_config(&input_pin)); - const usb_host_config_t host_config = { .skip_phy_setup = false, .intr_flags = ESP_INTR_FLAG_LEVEL1, @@ -452,22 +463,17 @@ static void usb_lib_task(void *arg) ESP_ERROR_CHECK(usb_host_install(&host_config)); xTaskNotifyGive(arg); - while (gpio_get_level(APP_QUIT_PIN) != 0) { + while (true) { uint32_t event_flags; usb_host_lib_handle_events(portMAX_DELAY, &event_flags); - - // Release devices once all clients has deregistered + // In this example, there is only one client registered + // So, once we deregister the client, this call must succeed with ESP_OK if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { - usb_host_device_free_all(); - ESP_LOGI(TAG, "USB Event flags: NO_CLIENTS"); - } - // All devices were removed - if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { - ESP_LOGI(TAG, "USB Event flags: ALL_FREE"); + ESP_ERROR_CHECK(usb_host_device_free_all()); + break; } } - // App Button was pressed, trigger the flag - user_shutdown = true; + ESP_LOGI(TAG, "USB shutdown"); // Clean up USB Host vTaskDelay(10); // Short delay to allow clients clean-up @@ -476,30 +482,26 @@ static void usb_lib_task(void *arg) } /** - * @brief HID Host main task + * @brief BOOT button pressed callback * - * Creates queue and get new event from the queue + * Signal application to exit the HID Host task * - * @param[in] pvParameters Not used + * @param[in] arg Unused */ -void hid_host_task(void *pvParameters) +static void gpio_isr_cb(void *arg) { - hid_host_event_queue_t evt_queue; - // Create queue - hid_host_event_queue = xQueueCreate(10, sizeof(hid_host_event_queue_t)); - - // Wait queue - while (!user_shutdown) { - if (xQueueReceive(hid_host_event_queue, &evt_queue, pdMS_TO_TICKS(50))) { - hid_host_device_event(evt_queue.hid_device_handle, - evt_queue.event, - evt_queue.arg); - } + BaseType_t xTaskWoken = pdFALSE; + const app_event_queue_t evt_queue = { + .event_group = APP_EVENT, + }; + + if (app_event_queue) { + xQueueSendFromISR(app_event_queue, &evt_queue, &xTaskWoken); } - xQueueReset(hid_host_event_queue); - vQueueDelete(hid_host_event_queue); - vTaskDelete(NULL); + if (xTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } } /** @@ -515,19 +517,37 @@ void hid_host_device_callback(hid_host_device_handle_t hid_device_handle, const hid_host_driver_event_t event, void *arg) { - const hid_host_event_queue_t evt_queue = { - .hid_device_handle = hid_device_handle, - .event = event, - .arg = arg + const app_event_queue_t evt_queue = { + .event_group = APP_EVENT_HID_HOST, + // HID Host Device related info + .hid_host_device.handle = hid_device_handle, + .hid_host_device.event = event, + .hid_host_device.arg = arg }; - xQueueSend(hid_host_event_queue, &evt_queue, 0); + + if (app_event_queue) { + xQueueSend(app_event_queue, &evt_queue, 0); + } } void app_main(void) { BaseType_t task_created; + app_event_queue_t evt_queue; ESP_LOGI(TAG, "HID Host example"); + // Init BOOT button: Pressing the button simulates app request to exit + // It will disconnect the USB device and uninstall the HID driver and USB Host Lib + const gpio_config_t input_pin = { + .pin_bit_mask = BIT64(APP_QUIT_PIN), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .intr_type = GPIO_INTR_NEGEDGE, + }; + ESP_ERROR_CHECK(gpio_config(&input_pin)); + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1)); + ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_isr_cb, NULL)); + /* * Create usb_lib_task to: * - initialize USB Host library @@ -559,14 +579,38 @@ void app_main(void) ESP_ERROR_CHECK(hid_host_install(&hid_host_driver_config)); - // Task is working until the devices are gone (while 'user_shutdown' if false) - user_shutdown = false; + // Create queue + app_event_queue = xQueueCreate(10, sizeof(app_event_queue_t)); + + ESP_LOGI(TAG, "Waiting for HID Device to be connected"); + + while (1) { + // Wait queue + if (xQueueReceive(app_event_queue, &evt_queue, portMAX_DELAY)) { + if (APP_EVENT == evt_queue.event_group) { + // User pressed button + usb_host_lib_info_t lib_info; + ESP_ERROR_CHECK(usb_host_lib_info(&lib_info)); + if (lib_info.num_devices == 0) { + // End while cycle + break; + } else { + ESP_LOGW(TAG, "To shutdown example, remove all USB devices and press button again."); + // Keep polling + } + } - /* - * Create HID Host task process for handle events - * IMPORTANT: Task is necessary here while there is no possibility to interact - * with USB device from the callback. - */ - task_created = xTaskCreate(&hid_host_task, "hid_task", 4 * 1024, NULL, 2, NULL); - assert(task_created == pdTRUE); + if (APP_EVENT_HID_HOST == evt_queue.event_group) { + hid_host_device_event(evt_queue.hid_host_device.handle, + evt_queue.hid_host_device.event, + evt_queue.hid_host_device.arg); + } + } + } + + ESP_LOGI(TAG, "HID Driver uninstall"); + ESP_ERROR_CHECK(hid_host_uninstall()); + gpio_isr_handler_remove(APP_QUIT_PIN); + xQueueReset(app_event_queue); + vQueueDelete(app_event_queue); } diff --git a/examples/peripherals/usb/host/hid/main/idf_component.yml b/examples/peripherals/usb/host/hid/main/idf_component.yml index 46a1c21a43d6..0c3620e3d575 100644 --- a/examples/peripherals/usb/host/hid/main/idf_component.yml +++ b/examples/peripherals/usb/host/hid/main/idf_component.yml @@ -1,4 +1,4 @@ ## IDF Component Manager Manifest File dependencies: idf: ">=4.4" - usb_host_hid: "1.0.0" + usb_host_hid: "^1.0.1" From 91eada4accdef58f636d4dce15e2803a7a42083f Mon Sep 17 00:00:00 2001 From: "sonika.rathi" Date: Fri, 8 Sep 2023 13:28:04 +0200 Subject: [PATCH 041/161] fix(fatfs): free allocated memory for base path before unmounting the card --- components/fatfs/vfs/vfs_fat_sdmmc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/fatfs/vfs/vfs_fat_sdmmc.c b/components/fatfs/vfs/vfs_fat_sdmmc.c index f3625a2f0e7d..1a5ac2150b93 100644 --- a/components/fatfs/vfs/vfs_fat_sdmmc.c +++ b/components/fatfs/vfs/vfs_fat_sdmmc.c @@ -439,6 +439,8 @@ esp_err_t esp_vfs_fat_sdcard_unmount(const char *base_path, sdmmc_card_t *card) if (!found) { return ESP_ERR_INVALID_ARG; } + free(s_ctx[id]->base_path); + s_ctx[id]->base_path = NULL; free(s_ctx[id]); s_ctx[id] = NULL; From c8f4fa286673c96681e93fb62357a022094e4b8a Mon Sep 17 00:00:00 2001 From: xiaqilin Date: Wed, 25 Oct 2023 16:10:27 +0800 Subject: [PATCH 042/161] fix(esp_phy): update esp32c6 libphy for coex zb rx and sleep bug --- components/esp_phy/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_phy/lib b/components/esp_phy/lib index ecd88d5ce357..8673ea44a5ae 160000 --- a/components/esp_phy/lib +++ b/components/esp_phy/lib @@ -1 +1 @@ -Subproject commit ecd88d5ce3578e45402b80b78c26969ef8732839 +Subproject commit 8673ea44a5aebaf46b7c95251ed3392bce549433 From bb329accd7407caf8d7dbee39d63ee76ba3c9bcc Mon Sep 17 00:00:00 2001 From: "sonika.rathi" Date: Mon, 25 Sep 2023 15:03:13 +0200 Subject: [PATCH 043/161] fix(sd_card): update hints.yml to provide SD troubleshooting hints --- tools/idf_py_actions/hints.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tools/idf_py_actions/hints.yml b/tools/idf_py_actions/hints.yml index e1053bcf7f89..28020658b5b8 100644 --- a/tools/idf_py_actions/hints.yml +++ b/tools/idf_py_actions/hints.yml @@ -275,6 +275,35 @@ re: "warning: 'esp_vfs_fat_sdmmc_unmount' is deprecated: Please use esp_vfs_fat_sdcard_unmount instead [-Wdeprecated-declarations]" hint: "``esp_vfs_fat_sdmmc_unmount()`` is now deprecated, you can use :cpp:func:`esp_vfs_fat_sdcard_unmount()` instead. See Storage migration guide 5.1 for more details" +- + re: "vfs_fat_sdmmc: sdmmc_card_init failed" + hint: "Please verify if there is an SD card inserted into the SD slot. Then, try rebooting the board." + +- + re: "sdmmc_common: sdmmc_init_ocr: send_op_cond" + hint: "Please reboot the board and then try again" + +- + re: "sdmmc_io: sdmmc_io_read_byte: sdmmc_io_rw_direct" + hint: "Please verify that card supports IO capabilities. Refer 'IDF_PATH/examples/peripherals/sdio/host/README.md' for more details" + +- + re: "example: Failed to initialize the card \\({}\\). Make sure SD card lines have pull-up resistors in place." + hint: "Please refer ./README.md for details" + variables: + - + re_variables: ['ESP_ERR_TIMEOUT'] + hint_variables: [] + - + re_variables: ['ESP_ERR_INVALID_RESPONSE'] + hint_variables: [] + - + re_variables: ['ESP_ERR_INVALID_STATE'] + hint_variables: [] + - + re_variables: ['ESP_ERR_INVALID_ARG'] + hint_variables: [] + - re: "esp_usb_jtag: could not find or open device!" hint: "Please check the wire connection to debugging device or access rights to a serial port." From 360f7b1e147c5ee814ad1defd8875ca2d066b4db Mon Sep 17 00:00:00 2001 From: "sonika.rathi" Date: Fri, 8 Sep 2023 09:14:22 +0200 Subject: [PATCH 044/161] fix(sd_card): update sd_card troubleshooting notes in readme.md --- examples/peripherals/sdio/host/README.md | 16 +++++++++++++ examples/storage/README.md | 22 +++++++++++++++++ examples/storage/sd_card/sdspi/README.md | 30 ++++++++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/examples/peripherals/sdio/host/README.md b/examples/peripherals/sdio/host/README.md index 1796fd93b4f3..213ba44961d7 100644 --- a/examples/peripherals/sdio/host/README.md +++ b/examples/peripherals/sdio/host/README.md @@ -1,4 +1,20 @@ | Supported Targets | ESP32 | ESP32-S3 | | ----------------- | ----- | -------- | + +## Troubleshooting + +### Getting the following error + +> `E (2562) sdmmc_io: sdmmc_io_read_byte: sdmmc_io_rw_direct (read 0x2) returned 0x107` + +Kindly activate the debug log from `idf.py menuconfig -> Component config -> Log output -> Default log verbosity` option and verify the card's IO type status. If the card does not possess IO capabilities, it will encounter issues while attempting to read IO buffers. + +To identify the card type, please inspect the following lines in the debug log. + +``` +D (659) sdmmc_io: sdmmc_init_io: io_send_op_cond (1) returned 0x106; not IO card +D (729) sdmmc_init: sdmmc_card_init: card type is SD +``` + See README.md in the parent folder diff --git a/examples/storage/README.md b/examples/storage/README.md index 5618ee20b385..bb5c821fe89d 100644 --- a/examples/storage/README.md +++ b/examples/storage/README.md @@ -1,5 +1,27 @@ # Storage Examples Storage and management of user and system data in module’s flash and on external memory / devices. +This directory contains a range of examples ESP-IDF projects. These are intended to demonstrate the storage features, and to provide code that you can copy and adapt into your own projects. + +# Example Layout + +The examples are grouped into sub-directories by category. Each category directory contains one or more example projects: + +* `custom_flash_driver` example demonstrates how to implement your own flash chip driver by overriding the default driver. +* `emmc` example demonstrates how to use an eMMC chip with an ESP device. +* `ext_flash_fatfs` example demonstrates how to use FATFS partition with external SPI FLASH chip. +* `fatfsgen` example demonstrates how to use FATFS partition +* `nvs_rw_blob` example demonstrates how to read and write a single integer value and a blob (binary large object) using NVS to preserve them between ESP module restarts. +* `nvs_rw_value` example demonstrates how to read and write a single integer value using NVS. +* `nvs_rw_value_cxx` example demonstrates how to read and write a single integer value using NVS (it uses the C++ NVS handle API). +* `partition_api` examples demonstrate how to use different partition APIs. +* `parttool` example demonstrates common operations the partitions tool allows the user to perform. +* `sd_card` examples demonstrate how to use an SD card with an ESP device. +* `semihost_vfs` example demonstrates how to use semihosting VFS driver with ESP device. +* `spiffs` example demonstrates how to use SPIFFS with ESP device. +* `spiffsgen` example demonstrates how to use the SPIFFS image generation tool spiffsgen.py to automatically create a SPIFFS. +* `wear_levelling` example demonstrates how to use wear levelling library and FATFS library to store files in a partition inside SPI flash. + +# More See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. diff --git a/examples/storage/sd_card/sdspi/README.md b/examples/storage/sd_card/sdspi/README.md index 334ff29f388b..c8a223ab1154 100644 --- a/examples/storage/sd_card/sdspi/README.md +++ b/examples/storage/sd_card/sdspi/README.md @@ -111,6 +111,19 @@ I (7396) example: Card unmounted The example will be able to mount only cards formatted using FAT32 filesystem. If the card is formatted as exFAT or some other filesystem, you have an option to format it in the example code. Enable the `CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED` menuconfig option, then build and flash the example. +> Once you've enabled the `CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED` option, if you continue to encounter the following error: + +``` +E (600) sdmmc_cmd: sdmmc_read_sectors_dma: sdmmc_send_cmd returned 0x108 +E (600) diskio_sdmmc: sdmmc_read_blocks failed (264) +W (610) vfs_fat_sdmmc: failed to mount card (1) +E (610) vfs_fat_sdmmc: mount_to_vfs failed (0xffffffff). +I (620) gpio: GPIO[13]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +E (630) example: Failed to mount filesystem. If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option. +``` + +Please ensure that your SD card is operational and not experiencing any malfunctions. + ### Unable to flash the example, or serial port not available (ESP32 only) @@ -125,3 +138,20 @@ An attempt to download a new firmware under this conditions may also result in t `esptool --port PORT --before no_reset --baud 115200 --chip esp32 erase_flash` to erase your board's flash, then flash the firmware again. + +> If you insert an SD card into the slot and encounter issues when attempting to flash a supported target using the `idf.py flash` command, please consider removing the SD card and attempting to flash the target again. If the flashing process succeeds after removing the SD card, it suggests potential issues with power supply. + +Ensure that the board and SD card adapter you are using are powered using the appropriate power source. + + +### Getting the following errors + +> `vfs_fat_sdmmc: slot init failed (0x103)` + +> `vfs_fat_sdmmc: sdmmc_card_init failed (0x102)` + +> `sdmmc_init_ocr: send_op_cond (1) returned 0x107` + +Attempt to reboot the board. This error may occur if you reset the ESP board or host controller without power-cycling it. In such cases, the card may remain in its previous state, causing it to potentially not respond to commands sent by the host controller. + +Additionally, if the example works with certain SD cards but encounters issues with others, please confirm the read/write speed of the SD card. If the card is not compatible with the host frequency, consider lowering the host frequency and then attempting the operation again. From d63f83d279f04b84d90bfeeec5b9b498862f5e96 Mon Sep 17 00:00:00 2001 From: Zim Kalinowski Date: Wed, 25 Oct 2023 14:43:45 +0200 Subject: [PATCH 045/161] fix(example/http): Fixed potential memory leak/crash in when handling error condition --- .../protocols/https_request/main/time_sync.c | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/examples/protocols/https_request/main/time_sync.c b/examples/protocols/https_request/main/time_sync.c index 5e158c17ceab..63416e7b3fdb 100644 --- a/examples/protocols/https_request/main/time_sync.c +++ b/examples/protocols/https_request/main/time_sync.c @@ -54,14 +54,15 @@ static esp_err_t obtain_time(void) esp_err_t fetch_and_store_time_in_nvs(void *args) { + nvs_handle_t my_handle = 0; + esp_err_t err; + initialize_sntp(); if (obtain_time() != ESP_OK) { - return ESP_FAIL; + err = ESP_FAIL; + goto exit; } - nvs_handle_t my_handle; - esp_err_t err; - time_t now; time(&now); @@ -82,10 +83,12 @@ esp_err_t fetch_and_store_time_in_nvs(void *args) goto exit; } - nvs_close(my_handle); +exit: + if (my_handle != 0) { + nvs_close(my_handle); + } esp_netif_deinit(); -exit: if (err != ESP_OK) { ESP_LOGE(TAG, "Error updating time in nvs"); } else { @@ -96,7 +99,7 @@ esp_err_t fetch_and_store_time_in_nvs(void *args) esp_err_t update_time_from_nvs(void) { - nvs_handle_t my_handle; + nvs_handle_t my_handle = 0; esp_err_t err; err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle); @@ -122,6 +125,8 @@ esp_err_t update_time_from_nvs(void) } exit: - nvs_close(my_handle); + if (my_handle != 0) { + nvs_close(my_handle); + } return err; } From 811a790aaf718a8bac8a77baacd8a0a8c6cd5fb9 Mon Sep 17 00:00:00 2001 From: gaoxu Date: Wed, 25 Oct 2023 14:15:21 +0800 Subject: [PATCH 046/161] fix(adc): fix adc oneshot mod do not split clk --- components/hal/adc_oneshot_hal.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/hal/adc_oneshot_hal.c b/components/hal/adc_oneshot_hal.c index ce6cb193c662..fb5f46076fec 100644 --- a/components/hal/adc_oneshot_hal.c +++ b/components/hal/adc_oneshot_hal.c @@ -60,6 +60,8 @@ void adc_oneshot_hal_setup(adc_oneshot_hal_ctx_t *hal, adc_channel_t chan) #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED adc_ll_digi_clk_sel(hal->clk_src); + adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT); + adc_ll_digi_set_clk_div(ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT); #else adc_ll_set_sar_clk_div(unit, ADC_LL_SAR_CLK_DIV_DEFAULT(unit)); if (unit == ADC_UNIT_2) { From 15cefab479640ce656d2f14d63ff77d3fbc510b0 Mon Sep 17 00:00:00 2001 From: morris Date: Wed, 18 Oct 2023 15:50:58 +0800 Subject: [PATCH 047/161] fix(rmt): a disabled channel may pick up a pending transaction because in the trans_done interrupt, the driver didn't check the channel FSM --- components/driver/rmt/include/driver/rmt_tx.h | 17 +- components/driver/rmt/rmt_common.c | 3 - components/driver/rmt/rmt_private.h | 7 +- components/driver/rmt/rmt_rx.c | 50 ++- components/driver/rmt/rmt_tx.c | 327 +++++++++--------- .../driver/test_apps/rmt/main/test_rmt_tx.c | 3 +- docs/en/api-reference/peripherals/rmt.rst | 23 +- docs/zh_CN/api-reference/peripherals/rmt.rst | 1 + 8 files changed, 237 insertions(+), 194 deletions(-) diff --git a/components/driver/rmt/include/driver/rmt_tx.h b/components/driver/rmt/include/driver/rmt_tx.h index 80b08a025414..3cf273cfc4c1 100644 --- a/components/driver/rmt/include/driver/rmt_tx.h +++ b/components/driver/rmt/include/driver/rmt_tx.h @@ -16,7 +16,6 @@ extern "C" { #endif - /** * @brief Group of RMT TX callbacks * @note The callbacks are all running under ISR environment @@ -38,14 +37,14 @@ typedef struct { In the DMA mode, this field controls the DMA buffer size, it can be set to a large value; In the normal mode, this field controls the number of RMT memory block that will be used by the channel. */ size_t trans_queue_depth; /*!< Depth of internal transfer queue, increase this value can support more transfers pending in the background */ + int intr_priority; /*!< RMT interrupt priority, + if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */ struct { uint32_t invert_out: 1; /*!< Whether to invert the RMT channel signal before output to GPIO pad */ uint32_t with_dma: 1; /*!< If set, the driver will allocate an RMT channel with DMA capability */ uint32_t io_loop_back: 1; /*!< The signal output from the GPIO will be fed to the input path as well */ uint32_t io_od_mode: 1; /*!< Configure the GPIO as open-drain mode */ } flags; /*!< TX channel config flags */ - int intr_priority; /*!< RMT interrupt priority, - if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */ } rmt_tx_channel_config_t; /** @@ -54,8 +53,9 @@ typedef struct { typedef struct { int loop_count; /*!< Specify the times of transmission in a loop, -1 means transmitting in an infinite loop */ struct { - uint32_t eot_level : 1; /*!< Set the output level for the "End Of Transmission" */ - } flags; /*!< Transmit config flags */ + uint32_t eot_level : 1; /*!< Set the output level for the "End Of Transmission" */ + uint32_t queue_nonblocking : 1; /*!< If set, when the transaction queue is full, driver will not block the thread but return directly */ + } flags; /*!< Transmit specific config flags */ } rmt_transmit_config_t; /** @@ -84,8 +84,11 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_ /** * @brief Transmit data by RMT TX channel * - * @note This function will construct a transaction descriptor and push to a queue. The transaction will not start immediately until it's dispatched in the ISR. - * If there're too many transactions pending in the queue, this function will block until the queue has free space. + * @note This function constructs a transaction descriptor then pushes to a queue. + * The transaction will not start immediately if there's another one under processing. + * Based on the setting of `rmt_transmit_config_t::queue_nonblocking`, + * if there're too many transactions pending in the queue, this function can block until it has free slot, + * otherwise just return quickly. * @note The data to be transmitted will be encoded into RMT symbols by the specific `encoder`. * * @param[in] tx_channel RMT TX channel that created by `rmt_new_tx_channel()` diff --git a/components/driver/rmt/rmt_common.c b/components/driver/rmt/rmt_common.c index 2176f771ea58..b280fa93fa7e 100644 --- a/components/driver/rmt/rmt_common.c +++ b/components/driver/rmt/rmt_common.c @@ -205,7 +205,6 @@ esp_err_t rmt_apply_carrier(rmt_channel_handle_t channel, const rmt_carrier_conf esp_err_t rmt_del_channel(rmt_channel_handle_t channel) { ESP_RETURN_ON_FALSE(channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); gpio_reset_pin(channel->gpio_num); return channel->del(channel); } @@ -213,14 +212,12 @@ esp_err_t rmt_del_channel(rmt_channel_handle_t channel) esp_err_t rmt_enable(rmt_channel_handle_t channel) { ESP_RETURN_ON_FALSE(channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); return channel->enable(channel); } esp_err_t rmt_disable(rmt_channel_handle_t channel) { ESP_RETURN_ON_FALSE(channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); - ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "channel not in enable state"); return channel->disable(channel); } diff --git a/components/driver/rmt/rmt_private.h b/components/driver/rmt/rmt_private.h index 5e05b192f84b..ac1e4bbd22c6 100644 --- a/components/driver/rmt/rmt_private.h +++ b/components/driver/rmt/rmt_private.h @@ -6,6 +6,7 @@ #pragma once +#include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -80,8 +81,12 @@ typedef enum { } rmt_channel_direction_t; typedef enum { + RMT_FSM_INIT_WAIT, RMT_FSM_INIT, + RMT_FSM_ENABLE_WAIT, RMT_FSM_ENABLE, + RMT_FSM_RUN_WAIT, + RMT_FSM_RUN, } rmt_fsm_t; enum { @@ -119,7 +124,7 @@ struct rmt_channel_t { portMUX_TYPE spinlock; // prevent channel resource accessing by user and interrupt concurrently uint32_t resolution_hz; // channel clock resolution intr_handle_t intr; // allocated interrupt handle for each channel - rmt_fsm_t fsm; // channel life cycle specific FSM + _Atomic rmt_fsm_t fsm; // channel life cycle specific FSM rmt_channel_direction_t direction; // channel direction rmt_symbol_word_t *hw_mem_base; // base address of RMT channel hardware memory rmt_symbol_word_t *dma_mem_base; // base address of RMT channel DMA buffer diff --git a/components/driver/rmt/rmt_rx.c b/components/driver/rmt/rmt_rx.c index 8176dfcc00e6..742b23d2d9ee 100644 --- a/components/driver/rmt/rmt_rx.c +++ b/components/driver/rmt/rmt_rx.c @@ -285,10 +285,10 @@ esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_ gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[config->gpio_num], PIN_FUNC_GPIO); // initialize other members of rx channel + portMUX_INITIALIZE(&rx_channel->base.spinlock); + atomic_init(&rx_channel->base.fsm, RMT_FSM_INIT); rx_channel->base.direction = RMT_CHANNEL_DIRECTION_RX; - rx_channel->base.fsm = RMT_FSM_INIT; rx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + RMT_RX_CHANNEL_OFFSET_IN_GROUP].symbols[0]; - rx_channel->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; // polymorphic methods rx_channel->base.del = rmt_del_rx_channel; rx_channel->base.set_carrier_action = rmt_rx_demodulate_carrier; @@ -310,6 +310,8 @@ esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_ static esp_err_t rmt_del_rx_channel(rmt_channel_handle_t channel) { + ESP_RETURN_ON_FALSE(atomic_load(&channel->fsm) == RMT_FSM_INIT, + ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); rmt_rx_channel_t *rx_chan = __containerof(channel, rmt_rx_channel_t, base); rmt_group_t *group = channel->group; int group_id = group->group_id; @@ -344,7 +346,6 @@ esp_err_t rmt_receive(rmt_channel_handle_t channel, void *buffer, size_t buffer_ { ESP_RETURN_ON_FALSE(channel && buffer && buffer_size && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(channel->direction == RMT_CHANNEL_DIRECTION_RX, ESP_ERR_INVALID_ARG, TAG, "invalid channel direction"); - ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "channel not in enable state"); rmt_rx_channel_t *rx_chan = __containerof(channel, rmt_rx_channel_t, base); if (channel->dma_chan) { @@ -369,6 +370,11 @@ esp_err_t rmt_receive(rmt_channel_handle_t channel, void *buffer, size_t buffer_ ESP_RETURN_ON_FALSE(filter_reg_value <= RMT_LL_MAX_FILTER_VALUE, ESP_ERR_INVALID_ARG, TAG, "signal_range_min_ns too big"); ESP_RETURN_ON_FALSE(idle_reg_value <= RMT_LL_MAX_IDLE_VALUE, ESP_ERR_INVALID_ARG, TAG, "signal_range_max_ns too big"); + // check if we're in a proper state to start the receiver + rmt_fsm_t expected_fsm = RMT_FSM_ENABLE; + ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_RUN_WAIT), + ESP_ERR_INVALID_STATE, TAG, "channel not in enable state"); + // fill in the transaction descriptor rmt_rx_trans_desc_t *t = &rx_chan->trans_desc; t->buffer = buffer; @@ -396,6 +402,11 @@ esp_err_t rmt_receive(rmt_channel_handle_t channel, void *buffer, size_t buffer_ // turn on RMT RX machine rmt_ll_rx_enable(hal->regs, channel_id, true); portEXIT_CRITICAL(&channel->spinlock); + + // saying we're in running state, this state will last until the receiving is done + // i.e., we will switch back to the enable state in the receive done interrupt handler + atomic_store(&channel->fsm, RMT_FSM_RUN); + return ESP_OK; } @@ -440,13 +451,18 @@ static esp_err_t rmt_rx_demodulate_carrier(rmt_channel_handle_t channel, const r static esp_err_t rmt_rx_enable(rmt_channel_handle_t channel) { + // can only enable the channel when it's in "init" state + rmt_fsm_t expected_fsm = RMT_FSM_INIT; + ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_ENABLE_WAIT), + ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); + rmt_group_t *group = channel->group; rmt_hal_context_t *hal = &group->hal; int channel_id = channel->channel_id; // acquire power manager lock if (channel->pm_lock) { - ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(channel->pm_lock), TAG, "acquire pm_lock failed"); + esp_pm_lock_acquire(channel->pm_lock); } if (channel->dma_chan) { #if SOC_RMT_SUPPORT_DMA @@ -462,12 +478,26 @@ static esp_err_t rmt_rx_enable(rmt_channel_handle_t channel) rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_RX_MASK(channel_id), true); portEXIT_CRITICAL(&group->spinlock); } - channel->fsm = RMT_FSM_ENABLE; + + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + return ESP_OK; } static esp_err_t rmt_rx_disable(rmt_channel_handle_t channel) { + // can disable the channel when it's in `enable` or `run` state + bool valid_state = false; + rmt_fsm_t expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_INIT_WAIT)) { + valid_state = true; + } + expected_fsm = RMT_FSM_RUN; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_INIT_WAIT)) { + valid_state = true; + } + ESP_RETURN_ON_FALSE(valid_state, ESP_ERR_INVALID_STATE, TAG, "channel not in enable or run state"); + rmt_group_t *group = channel->group; rmt_hal_context_t *hal = &group->hal; int channel_id = channel->channel_id; @@ -493,9 +523,11 @@ static esp_err_t rmt_rx_disable(rmt_channel_handle_t channel) // release power manager lock if (channel->pm_lock) { - ESP_RETURN_ON_ERROR(esp_pm_lock_release(channel->pm_lock), TAG, "release pm_lock failed"); + esp_pm_lock_release(channel->pm_lock); } - channel->fsm = RMT_FSM_INIT; + + // now we can switch the state to init + atomic_store(&channel->fsm, RMT_FSM_INIT); return ESP_OK; } @@ -563,6 +595,8 @@ static bool IRAM_ATTR rmt_isr_handle_rx_done(rmt_rx_channel_t *rx_chan) need_yield = true; } } + // switch back to the enable state, then user can call `rmt_receive` to start a new receive + atomic_store(&channel->fsm, RMT_FSM_ENABLE); return need_yield; } @@ -674,6 +708,8 @@ static bool IRAM_ATTR rmt_dma_rx_eof_cb(gdma_channel_handle_t dma_chan, gdma_eve need_yield = true; } } + // switch back to the enable state, then user can call `rmt_receive` to start a new receive + atomic_store(&channel->fsm, RMT_FSM_ENABLE); return need_yield; } #endif // SOC_RMT_SUPPORT_DMA diff --git a/components/driver/rmt/rmt_tx.c b/components/driver/rmt/rmt_tx.c index f44eb9a0842c..95188e8daa20 100644 --- a/components/driver/rmt/rmt_tx.c +++ b/components/driver/rmt/rmt_tx.c @@ -40,6 +40,7 @@ static esp_err_t rmt_tx_modulate_carrier(rmt_channel_handle_t channel, const rmt static esp_err_t rmt_tx_enable(rmt_channel_handle_t channel); static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel); static void rmt_tx_default_isr(void *args); +static void rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_trans_desc_t *t); #if SOC_RMT_SUPPORT_DMA static bool rmt_dma_tx_eof_cb(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data); @@ -310,10 +311,10 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_ config->flags.invert_out, false); gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[config->gpio_num], PIN_FUNC_GPIO); + portMUX_INITIALIZE(&tx_channel->base.spinlock); + atomic_init(&tx_channel->base.fsm, RMT_FSM_INIT); tx_channel->base.direction = RMT_CHANNEL_DIRECTION_TX; - tx_channel->base.fsm = RMT_FSM_INIT; tx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + RMT_TX_CHANNEL_OFFSET_IN_GROUP].symbols[0]; - tx_channel->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; // polymorphic methods tx_channel->base.del = rmt_del_tx_channel; tx_channel->base.set_carrier_action = rmt_tx_modulate_carrier; @@ -335,6 +336,8 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_ static esp_err_t rmt_del_tx_channel(rmt_channel_handle_t channel) { + ESP_RETURN_ON_FALSE(atomic_load(&channel->fsm) == RMT_FSM_INIT, + ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); rmt_group_t *group = channel->group; int group_id = group->group_id; @@ -373,7 +376,7 @@ esp_err_t rmt_new_sync_manager(const rmt_sync_manager_config_t *config, rmt_sync channel = config->tx_channel_array[i]; ESP_GOTO_ON_FALSE(channel->direction == RMT_CHANNEL_DIRECTION_TX, ESP_ERR_INVALID_ARG, err, TAG, "sync manager supports TX channel only"); ESP_GOTO_ON_FALSE(channel->group == group, ESP_ERR_INVALID_ARG, err, TAG, "channels to be managed should locate in the same group"); - ESP_GOTO_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, err, TAG, "channel should be started before creating sync manager"); + ESP_GOTO_ON_FALSE(atomic_load(&channel->fsm) == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, err, TAG, "channel not in enable state"); channel_mask |= 1 << channel->channel_id; } synchro->channel_mask = channel_mask; @@ -480,7 +483,6 @@ esp_err_t rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, con { ESP_RETURN_ON_FALSE(channel && encoder && payload && payload_bytes && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument"); ESP_RETURN_ON_FALSE(channel->direction == RMT_CHANNEL_DIRECTION_TX, ESP_ERR_INVALID_ARG, TAG, "invalid channel direction"); - ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "channel not in enable state"); #if !SOC_RMT_SUPPORT_TX_LOOP_COUNT ESP_RETURN_ON_FALSE(config->loop_count <= 0, ESP_ERR_NOT_SUPPORTED, TAG, "loop count is not supported"); #endif // !SOC_RMT_SUPPORT_TX_LOOP_COUNT @@ -488,22 +490,20 @@ esp_err_t rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, con // payload is retrieved by the encoder, we should make sure it's still accessible even when the cache is disabled ESP_RETURN_ON_FALSE(esp_ptr_internal(payload), ESP_ERR_INVALID_ARG, TAG, "payload not in internal RAM"); #endif - rmt_group_t *group = channel->group; - rmt_hal_context_t *hal = &group->hal; - int channel_id = channel->channel_id; + TickType_t queue_wait_ticks = portMAX_DELAY; + if (config->flags.queue_nonblocking) { + queue_wait_ticks = 0; + } rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); rmt_tx_trans_desc_t *t = NULL; - // acquire one transaction description from ready_queue or done_queue - if (tx_chan->num_trans_inflight < tx_chan->queue_size) { - ESP_RETURN_ON_FALSE(xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, portMAX_DELAY) == pdTRUE, - ESP_FAIL, TAG, "no transaction in the ready queue"); - } else { - ESP_RETURN_ON_FALSE(xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &t, portMAX_DELAY) == pdTRUE, - ESP_FAIL, TAG, "recycle transaction from done queue failed"); - tx_chan->num_trans_inflight--; + // acquire one transaction description from ready queue or complete queue + if (xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, 0) != pdTRUE) { + if (xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &t, queue_wait_ticks) == pdTRUE) { + tx_chan->num_trans_inflight--; + } } - // sanity check - assert(t); + ESP_RETURN_ON_FALSE(t, ESP_ERR_INVALID_STATE, TAG, "no free transaction descriptor, please consider increasing trans_queue_depth"); + // fill in the transaction descriptor memset(t, 0, sizeof(rmt_tx_trans_desc_t)); t->encoder = encoder; @@ -514,7 +514,7 @@ esp_err_t rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, con t->flags.eot_level = config->flags.eot_level; // send the transaction descriptor to queue - if (xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, portMAX_DELAY) == pdTRUE) { + if (xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, 0) == pdTRUE) { tx_chan->num_trans_inflight++; } else { // put the trans descriptor back to ready_queue @@ -522,13 +522,18 @@ esp_err_t rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, con ESP_ERR_INVALID_STATE, TAG, "ready queue full"); } - // we don't know which "transmission complete" event will be triggered, but must be one of them: trans_done, loop_done - // when we run at here, the interrupt status bit for tx_done or loop_end should already up (ensured by `rmt_tx_enable()`) - // that's why we can go into ISR as soon as we enable the interrupt bit - // in the ISR, we will fetch the transactions from trans_queue and start it - portENTER_CRITICAL(&group->spinlock); - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id) | RMT_LL_EVENT_TX_LOOP_END(channel_id), true); - portEXIT_CRITICAL(&group->spinlock); + // check if we need to start one pending transaction + rmt_fsm_t expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_RUN_WAIT)) { + // check if we need to start one transaction + if (xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, 0) == pdTRUE) { + atomic_store(&channel->fsm, RMT_FSM_RUN); + rmt_tx_do_transaction(tx_chan, t); + } else { + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + } + } + return ESP_OK; } @@ -625,6 +630,9 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr rmt_hal_context_t *hal = &group->hal; int channel_id = channel->channel_id; + // update current transaction + tx_chan->cur_trans = t; + #if SOC_RMT_SUPPORT_DMA if (channel->dma_chan) { gdma_reset(channel->dma_chan); @@ -638,7 +646,7 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr #endif // SOC_RMT_SUPPORT_DMA // set transaction specific parameters - portENTER_CRITICAL_ISR(&channel->spinlock); + portENTER_CRITICAL_SAFE(&channel->spinlock); rmt_ll_tx_reset_pointer(hal->regs, channel_id); // reset pointer for new transaction rmt_ll_tx_enable_loop(hal->regs, channel_id, t->loop_count != 0); #if SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP @@ -654,10 +662,10 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr t->remain_loop_count -= this_loop_count; } #endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT - portEXIT_CRITICAL_ISR(&channel->spinlock); + portEXIT_CRITICAL_SAFE(&channel->spinlock); // enable/disable specific interrupts - portENTER_CRITICAL_ISR(&group->spinlock); + portENTER_CRITICAL_SAFE(&group->spinlock); #if SOC_RMT_SUPPORT_TX_LOOP_COUNT rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), t->loop_count > 0); #endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT @@ -671,7 +679,7 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr } // don't generate trans done event for loop transmission rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), t->loop_count == 0); - portEXIT_CRITICAL_ISR(&group->spinlock); + portEXIT_CRITICAL_SAFE(&group->spinlock); // at the beginning of a new transaction, encoding memory offset should start from zero. // It will increase in the encode function e.g. `rmt_encode_copy()` @@ -691,39 +699,29 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr } #endif // turn on the TX machine - portENTER_CRITICAL_ISR(&channel->spinlock); + portENTER_CRITICAL_SAFE(&channel->spinlock); rmt_ll_tx_fix_idle_level(hal->regs, channel_id, t->flags.eot_level, true); rmt_ll_tx_start(hal->regs, channel_id); - portEXIT_CRITICAL_ISR(&channel->spinlock); + portEXIT_CRITICAL_SAFE(&channel->spinlock); } static esp_err_t rmt_tx_enable(rmt_channel_handle_t channel) { + // can enable the channel when it's in "init" state + rmt_fsm_t expected_fsm = RMT_FSM_INIT; + ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_ENABLE_WAIT), + ESP_ERR_INVALID_STATE, TAG, "channel not in init state"); rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base); - rmt_group_t *group = channel->group; - rmt_hal_context_t *hal = &group->hal; - int channel_id = channel->channel_id; + // acquire power manager lock if (channel->pm_lock) { - ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(channel->pm_lock), TAG, "acquire pm_lock failed"); + esp_pm_lock_acquire(channel->pm_lock); } - portENTER_CRITICAL(&channel->spinlock); - rmt_ll_tx_reset_pointer(hal->regs, channel_id); - rmt_ll_tx_enable_loop(hal->regs, channel_id, false); -#if SOC_RMT_SUPPORT_TX_LOOP_COUNT - rmt_ll_tx_reset_loop_count(hal->regs, channel_id); - rmt_ll_tx_enable_loop_count(hal->regs, channel_id, false); -#endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT - // trigger a quick trans done event by sending a EOF symbol, no signal should appear on the GPIO - tx_chan->cur_trans = NULL; - channel->hw_mem_base[0].val = 0; - rmt_ll_tx_start(hal->regs, channel_id); - portEXIT_CRITICAL(&channel->spinlock); - - // wait the RMT interrupt line goes active, we won't go into the ISR handler until we enable the `RMT_LL_EVENT_TX_DONE` interrupt - while (!(rmt_ll_tx_get_interrupt_status_raw(hal->regs, channel_id) & RMT_LL_EVENT_TX_DONE(channel_id))) {} #if SOC_RMT_SUPPORT_DMA + rmt_group_t *group = channel->group; + rmt_hal_context_t *hal = &group->hal; + int channel_id = channel->channel_id; if (channel->dma_chan) { // enable the DMA access mode portENTER_CRITICAL(&channel->spinlock); @@ -734,12 +732,22 @@ static esp_err_t rmt_tx_enable(rmt_channel_handle_t channel) } #endif // SOC_RMT_SUPPORT_DMA - channel->fsm = RMT_FSM_ENABLE; + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + + // check if we need to start one pending transaction + rmt_tx_trans_desc_t *t = NULL; + expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_RUN_WAIT)) { + if (xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, 0) == pdTRUE) { + // sanity check + assert(t); + atomic_store(&channel->fsm, RMT_FSM_RUN); + rmt_tx_do_transaction(tx_chan, t); + } else { + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + } + } - // enable channel interrupt, dispatch transactions in ISR (in case there're transaction descriptors in the queue, then we should start them) - portENTER_CRITICAL(&group->spinlock); - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), true); - portEXIT_CRITICAL(&group->spinlock); return ESP_OK; } @@ -750,24 +758,37 @@ static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel) rmt_hal_context_t *hal = &group->hal; int channel_id = channel->channel_id; - portENTER_CRITICAL(&channel->spinlock); - rmt_ll_tx_enable_loop(hal->regs, channel->channel_id, false); + // can disable the channel when it's in `enable` or `run` state + bool valid_state = false; + rmt_fsm_t expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_INIT_WAIT)) { + valid_state = true; + } + expected_fsm = RMT_FSM_RUN; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_INIT_WAIT)) { + valid_state = true; + // disable the hardware + portENTER_CRITICAL(&channel->spinlock); + rmt_ll_tx_enable_loop(hal->regs, channel->channel_id, false); #if SOC_RMT_SUPPORT_TX_ASYNC_STOP - rmt_ll_tx_stop(hal->regs, channel->channel_id); + rmt_ll_tx_stop(hal->regs, channel->channel_id); #endif - portEXIT_CRITICAL(&channel->spinlock); + portEXIT_CRITICAL(&channel->spinlock); - portENTER_CRITICAL(&group->spinlock); - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id), false); + portENTER_CRITICAL(&group->spinlock); + rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id), false); #if !SOC_RMT_SUPPORT_TX_ASYNC_STOP - // we do a trick to stop the undergoing transmission - // stop interrupt, insert EOF marker to the RMT memory, polling the trans_done event - channel->hw_mem_base[0].val = 0; - while (!(rmt_ll_tx_get_interrupt_status_raw(hal->regs, channel_id) & RMT_LL_EVENT_TX_DONE(channel_id))) {} + // we do a trick to stop the undergoing transmission + // stop interrupt, insert EOF marker to the RMT memory, polling the trans_done event + channel->hw_mem_base[0].val = 0; + while (!(rmt_ll_tx_get_interrupt_status_raw(hal->regs, channel_id) & RMT_LL_EVENT_TX_DONE(channel_id))) {} #endif - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id)); - portEXIT_CRITICAL(&group->spinlock); + rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id)); + portEXIT_CRITICAL(&group->spinlock); + } + ESP_RETURN_ON_FALSE(valid_state, ESP_ERR_INVALID_STATE, TAG, "channel can't be disabled in state %d", expected_fsm); + // disable the DMA #if SOC_RMT_SUPPORT_DMA if (channel->dma_chan) { gdma_stop(channel->dma_chan); @@ -779,9 +800,10 @@ static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel) portEXIT_CRITICAL(&channel->spinlock); } #endif + // recycle the interrupted transaction if (tx_chan->cur_trans) { - xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &tx_chan->cur_trans, portMAX_DELAY); + xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &tx_chan->cur_trans, 0); // reset corresponding encoder rmt_encoder_reset(tx_chan->cur_trans->encoder); } @@ -792,7 +814,9 @@ static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel) ESP_RETURN_ON_ERROR(esp_pm_lock_release(channel->pm_lock), TAG, "release pm_lock failed"); } - channel->fsm = RMT_FSM_INIT; + // finally we switch to the INIT state + atomic_store(&channel->fsm, RMT_FSM_INIT); + return ESP_OK; } @@ -836,12 +860,7 @@ static esp_err_t rmt_tx_modulate_carrier(rmt_channel_handle_t channel, const rmt static bool IRAM_ATTR rmt_isr_handle_tx_threshold(rmt_tx_channel_t *tx_chan) { - rmt_channel_t *channel = &tx_chan->base; - rmt_group_t *group = channel->group; - rmt_hal_context_t *hal = &group->hal; - uint32_t channel_id = channel->channel_id; - - // continue pingpong transmission + // continue ping-pong transmission rmt_tx_trans_desc_t *t = tx_chan->cur_trans; size_t encoded_symbols = t->transmitted_symbol_num; // encoding finished, only need to send the EOF symbol @@ -854,73 +873,54 @@ static bool IRAM_ATTR rmt_isr_handle_tx_threshold(rmt_tx_channel_t *tx_chan) t->transmitted_symbol_num = encoded_symbols; tx_chan->mem_end = tx_chan->ping_pong_symbols * 3 - tx_chan->mem_end; // mem_end equals to either ping_pong_symbols or ping_pong_symbols*2 - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_THRES(channel_id)); - return false; } static bool IRAM_ATTR rmt_isr_handle_tx_done(rmt_tx_channel_t *tx_chan) { rmt_channel_t *channel = &tx_chan->base; - rmt_group_t *group = channel->group; - rmt_hal_context_t *hal = &group->hal; - uint32_t channel_id = channel->channel_id; BaseType_t awoken = pdFALSE; rmt_tx_trans_desc_t *trans_desc = NULL; bool need_yield = false; - portENTER_CRITICAL_ISR(&group->spinlock); - // disable interrupt temporarily, re-enable it when there is transaction unhandled in the queue - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), false); - portEXIT_CRITICAL_ISR(&group->spinlock); - - trans_desc = tx_chan->cur_trans; - // process finished transaction - if (trans_desc) { - // don't care of the tx done event for any undergoing loop transaction - // mostly it's triggered when a loop transmission is undergoing and user calls `rmt_transmit()` where tx done interrupt is generated by accident - if (trans_desc->loop_count != 0) { - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id)); - return need_yield; - } - if (tx_chan->on_trans_done) { - rmt_tx_done_event_data_t edata = { - .num_symbols = trans_desc->transmitted_symbol_num, - }; - if (tx_chan->on_trans_done(channel, &edata, tx_chan->user_data)) { - need_yield = true; - } - } - // move transaction to done_queue + rmt_fsm_t expected_fsm = RMT_FSM_RUN; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_ENABLE_WAIT)) { + trans_desc = tx_chan->cur_trans; + // move current finished transaction to the complete queue xQueueSendFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &trans_desc, &awoken); if (awoken == pdTRUE) { need_yield = true; } + tx_chan->cur_trans = NULL; + atomic_store(&channel->fsm, RMT_FSM_ENABLE); } - // fetch new transaction description from trans_queue - if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) { - // sanity check - assert(trans_desc); - // update current transaction - tx_chan->cur_trans = trans_desc; - portENTER_CRITICAL_ISR(&group->spinlock); - // only clear the trans done status when we're sure there still remains transaction to handle - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id)); - // enable interrupt again, because the new transaction can trigger another trans done event - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), trans_desc->loop_count == 0); - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), trans_desc->loop_count > 0); - portEXIT_CRITICAL_ISR(&group->spinlock); - - // begin a new transaction - rmt_tx_do_transaction(tx_chan, trans_desc); - } else { // No transactions left in the queue - // don't clear interrupt status, so when next time user push new transaction to the queue and call esp_intr_enable, - // we can go to this ISR handler again - tx_chan->cur_trans = NULL; + // invoke callback + rmt_tx_done_callback_t done_cb = tx_chan->on_trans_done; + if (done_cb) { + rmt_tx_done_event_data_t edata = { + .num_symbols = trans_desc->transmitted_symbol_num, + }; + if (done_cb(channel, &edata, tx_chan->user_data)) { + need_yield = true; + } } - if (awoken == pdTRUE) { - need_yield = true; + + // let's try start the next pending transaction + expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_RUN_WAIT)) { + if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) { + // sanity check + assert(trans_desc); + atomic_store(&channel->fsm, RMT_FSM_RUN); + // begin a new transaction + rmt_tx_do_transaction(tx_chan, trans_desc); + if (awoken == pdTRUE) { + need_yield = true; + } + } else { + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + } } return need_yield; @@ -941,16 +941,16 @@ static bool IRAM_ATTR rmt_isr_handle_tx_loop_end(rmt_tx_channel_t *tx_chan) if (trans_desc) { #if !SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP portENTER_CRITICAL_ISR(&channel->spinlock); - // This is a workaround for chips that don't support auto stop + // This is a workaround for chips that don't support loop auto stop // Although we stop the transaction immediately in ISR handler, it's still possible that some rmt symbols have sneaked out rmt_ll_tx_stop(hal->regs, channel_id); portEXIT_CRITICAL_ISR(&channel->spinlock); #endif // SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP + // continue unfinished loop transaction if (trans_desc->remain_loop_count) { uint32_t this_loop_count = MIN(trans_desc->remain_loop_count, RMT_LL_MAX_LOOP_COUNT_PER_BATCH); trans_desc->remain_loop_count -= this_loop_count; - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id)); portENTER_CRITICAL_ISR(&channel->spinlock); rmt_ll_tx_set_loop_count(hal->regs, channel_id, this_loop_count); rmt_ll_tx_reset_pointer(hal->regs, channel_id); @@ -958,51 +958,49 @@ static bool IRAM_ATTR rmt_isr_handle_tx_loop_end(rmt_tx_channel_t *tx_chan) rmt_ll_tx_start(hal->regs, channel_id); portEXIT_CRITICAL_ISR(&channel->spinlock); return need_yield; - } else { - if (tx_chan->on_trans_done) { - rmt_tx_done_event_data_t edata = { - .num_symbols = trans_desc->transmitted_symbol_num, - }; - if (tx_chan->on_trans_done(channel, &edata, tx_chan->user_data)) { - need_yield = true; - } - } - // move transaction to done_queue + } + + // loop transaction finished + rmt_fsm_t expected_fsm = RMT_FSM_RUN; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_ENABLE_WAIT)) { + // move current finished transaction to the complete queue xQueueSendFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &trans_desc, &awoken); if (awoken == pdTRUE) { need_yield = true; } + tx_chan->cur_trans = NULL; + atomic_store(&channel->fsm, RMT_FSM_ENABLE); } - } - // trans_done and loop_done should be considered as one "transmission complete" - // but sometimes the trans done event might also be triggered together with loop done event, by accident, so clear it first - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id)); - portENTER_CRITICAL_ISR(&group->spinlock); - // disable interrupt temporarily, re-enable it when there is transaction unhandled in the queue - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), false); - portEXIT_CRITICAL_ISR(&group->spinlock); - - // fetch new transaction description from trans_queue - if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) { - // sanity check - assert(trans_desc); - tx_chan->cur_trans = trans_desc; - // clear the loop end status when we're sure there still remains transaction to handle - rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id)); - portENTER_CRITICAL_ISR(&group->spinlock); - // enable interrupt again, because the new transaction can trigger new trans done event - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), trans_desc->loop_count == 0); - rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), trans_desc->loop_count > 0); - portEXIT_CRITICAL_ISR(&group->spinlock); + // invoke callback + rmt_tx_done_callback_t done_cb = tx_chan->on_trans_done; + if (done_cb) { + rmt_tx_done_event_data_t edata = { + .num_symbols = trans_desc->transmitted_symbol_num, + }; + if (done_cb(channel, &edata, tx_chan->user_data)) { + need_yield = true; + } + } - // begin a new transaction - rmt_tx_do_transaction(tx_chan, trans_desc); - } else { // No transactions left in the queue - // don't clear interrupt status, so when next time user push new transaction to the queue and call esp_intr_enable, - // we can go into ISR handler again - tx_chan->cur_trans = NULL; + // let's try start the next pending transaction + expected_fsm = RMT_FSM_ENABLE; + if (atomic_compare_exchange_strong(&channel->fsm, &expected_fsm, RMT_FSM_RUN_WAIT)) { + if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) { + // sanity check + assert(trans_desc); + atomic_store(&channel->fsm, RMT_FSM_RUN); + // begin a new transaction + rmt_tx_do_transaction(tx_chan, trans_desc); + if (awoken == pdTRUE) { + need_yield = true; + } + } else { + atomic_store(&channel->fsm, RMT_FSM_ENABLE); + } + } } + if (awoken == pdTRUE) { need_yield = true; } @@ -1020,6 +1018,7 @@ static void IRAM_ATTR rmt_tx_default_isr(void *args) bool need_yield = false; uint32_t status = rmt_ll_tx_get_interrupt_status(hal->regs, channel_id); + rmt_ll_clear_interrupt_status(hal->regs, status); // Tx threshold interrupt if (status & RMT_LL_EVENT_TX_THRES(channel_id)) { diff --git a/components/driver/test_apps/rmt/main/test_rmt_tx.c b/components/driver/test_apps/rmt/main/test_rmt_tx.c index 92892c35ebc9..8fbca6f6a2e7 100644 --- a/components/driver/test_apps/rmt/main/test_rmt_tx.c +++ b/components/driver/test_apps/rmt/main/test_rmt_tx.c @@ -367,7 +367,7 @@ TEST_CASE("rmt infinite loop transaction", "[rmt]") .resolution_hz = 1000000, // 1MHz, 1 tick = 1us .mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL, .gpio_num = TEST_RMT_GPIO_NUM_B, - .trans_queue_depth = 3, + .trans_queue_depth = 5, .intr_priority = 1 }; printf("install tx channel\r\n"); @@ -384,6 +384,7 @@ TEST_CASE("rmt infinite loop transaction", "[rmt]") rmt_transmit_config_t transmit_config = { .loop_count = -1, // infinite loop transmission + .flags.queue_nonblocking = true, // return immediately if the queue is full }; printf("infinite loop transmission: keep spinning stepper motor\r\n"); diff --git a/docs/en/api-reference/peripherals/rmt.rst b/docs/en/api-reference/peripherals/rmt.rst index aff150490541..f1585ecf11a1 100644 --- a/docs/en/api-reference/peripherals/rmt.rst +++ b/docs/en/api-reference/peripherals/rmt.rst @@ -56,7 +56,7 @@ The description of the RMT functionality is divided into the following sections: - :ref:`rmt-resource-allocation` - covers how to allocate and properly configure RMT channels. It also covers how to recycle channels and other resources when they are no longer used. - :ref:`rmt-carrier-modulation-and demodulation` - describes how to modulate and demodulate the carrier signals for TX and RX channels respectively. -- :ref:`rmt-register-event-callbacks` - covers how to register user-provided event callbacks in order to receive RMT channel events. +- :ref:`rmt-register-event-callbacks` - covers how to register user-provided event callbacks to receive RMT channel events. - :ref:`rmt-enable-and-disable-channel` - shows how to enable and disable the RMT channel. - :ref:`rmt-initiate-tx-transaction` - describes the steps to initiate a transaction for a TX channel. - :ref:`rmt-initiate-rx-transaction` - describes the steps to initiate a transaction for an RX channel. @@ -84,7 +84,7 @@ To install an RMT TX channel, there is a configuration structure that needs to b - :cpp:member:`rmt_tx_channel_config_t::resolution_hz` sets the resolution of the internal tick counter. The timing parameter of the RMT signal is calculated based on this **tick**. - :cpp:member:`rmt_tx_channel_config_t::mem_block_symbols` has a slightly different meaning based on if the DMA backend is enabled or not. - - If the DMA is enabled via :cpp:member:`rmt_tx_channel_config_t::with_dma`, then this field controls the size of the internal DMA buffer. To achieve a better throughput and smaller CPU overhead, we recommend you set a large value, e.g., ``1024``. + - If the DMA is enabled via :cpp:member:`rmt_tx_channel_config_t::with_dma`, then this field controls the size of the internal DMA buffer. To achieve a better throughput and smaller CPU overhead, you can set a larger value, e.g., ``1024``. - If DMA is not used, this field controls the size of the dedicated memory block owned by the channel, which should be at least {IDF_TARGET_SOC_RMT_MEM_WORDS_PER_CHANNEL}. - :cpp:member:`rmt_tx_channel_config_t::trans_queue_depth` sets the depth of the internal transaction queue, the deeper the queue, the more transactions can be prepared in the backlog. @@ -205,7 +205,7 @@ The RX channel-supported event callbacks are listed in the :cpp:type:`rmt_rx_eve Users can save their own context in :cpp:func:`rmt_tx_register_event_callbacks` and :cpp:func:`rmt_rx_register_event_callbacks` as well, via the parameter ``user_data``. The user data is directly passed to each callback function. -In the callback function, users can fetch the event-specific data that is filled by the driver in the ``edata``. Note that the ``edata`` pointer is only valid for the duration of the callback. +In the callback function, users can fetch the event-specific data that is filled by the driver in the ``edata``. Note that the ``edata`` pointer is only valid during the callback. The TX-done event data is defined in :cpp:type:`rmt_tx_done_event_data_t`: @@ -237,7 +237,7 @@ Initiate TX Transaction RMT is a special communication peripheral, as it is unable to transmit raw byte streams like SPI and I2C. RMT can only send data in its own format :cpp:type:`rmt_symbol_word_t`. However, the hardware does not help to convert the user data into RMT symbols, this can only be done in software by the so-called **RMT Encoder**. The encoder is responsible for encoding user data into RMT symbols and then writing to the RMT memory block or the DMA buffer. For how to create an RMT encoder, please refer to :ref:`rmt-rmt-encoder`. -Once we got an encoder, we can initiate a TX transaction by calling :cpp:func:`rmt_transmit`. This function takes several positional parameters like channel handle, encoder handle, and payload buffer. Besides, we also need to provide a transmission-specific configuration in :cpp:type:`rmt_transmit_config_t`: +Once you created an encoder, you can initiate a TX transaction by calling :cpp:func:`rmt_transmit`. This function takes several positional parameters like channel handle, encoder handle, and payload buffer. Besides, you also need to provide a transmission-specific configuration in :cpp:type:`rmt_transmit_config_t`: - :cpp:member:`rmt_transmit_config_t::loop_count` sets the number of transmission loops. After the transmitter has finished one round of transmission, it can restart the same transmission again if this value is not set to zero. As the loop is controlled by hardware, the RMT channel can be used to generate many periodic sequences with minimal CPU intervention. @@ -249,6 +249,7 @@ Once we got an encoder, we can initiate a TX transaction by calling :cpp:func:`r The **loop transmit** feature is not supported on all ESP chips, please refer to [`TRM <{IDF_TARGET_TRM_EN_URL}#rmt>`__] before you configure this option, or you might encounter :c:macro:`ESP_ERR_NOT_SUPPORTED` error. - :cpp:member:`rmt_transmit_config_t::eot_level` sets the output level when the transmitter finishes working or stops working by calling :cpp:func:`rmt_disable`. +- :cpp:member:`rmt_transmit_config_t::queue_nonblocking` sets whether to wait for a free slot in the transaction queue when it is full. If this value is set to ``true``, then the function will return with an error code :c:macro:`ESP_ERR_INVALID_STATE` when the queue is full. Otherwise, the function will block until a free slot is available in the queue. .. note:: @@ -264,7 +265,7 @@ Internally, :cpp:func:`rmt_transmit` constructs a transaction descriptor and sen Multiple Channels Simultaneous Transmission ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In some real-time control applications (e.g., to make two robotic arms move simultaneously), we do not want any time drift in between when startup multiple TX channels. The RMT driver can help to manage this by creating a so-called **Sync Manager**. The sync manager is represented by :cpp:type:`rmt_sync_manager_handle_t` in the driver. The procedure of RMT sync transmission is shown as follows: +In some real-time control applications (e.g., to make two robotic arms move simultaneously), you do not want any time drift between different channels. The RMT driver can help to manage this by creating a so-called **Sync Manager**. The sync manager is represented by :cpp:type:`rmt_sync_manager_handle_t` in the driver. The procedure of RMT sync transmission is shown as follows: .. figure:: /../_static/rmt_tx_sync.png :align: center @@ -380,20 +381,20 @@ RMT Encoder An RMT encoder is part of the RMT TX transaction, whose responsibility is to generate and write the correct RMT symbols into hardware memory or DMA buffer at a specific time. There are some special restrictions for an encoding function: -- During a single transaction, the encoding function may be called multiple times. This is necessary because the target RMT memory block cannot hold all the artifacts at once. To overcome this limitation, we utilize a **ping-pong** approach, where the encoding session is divided into multiple parts. This means that the encoder needs to **keep track of its state** in order to continue encoding from where it left off in the previous part. +- During a single transaction, the encoding function may be called multiple times. This is necessary because the target RMT memory block cannot hold all the artifacts at once. To overcome this limitation, the driver utilizes a **ping-pong** approach, where the encoding session is divided into multiple parts. This means that the encoder needs to **keep track of its state** to continue encoding from where it left off in the previous part. - The encoding function is running in the ISR context. To speed up the encoding session, it is highly recommended to put the encoding function into IRAM. This can also avoid the cache miss during encoding. -To help get started with the RMT driver faster, some commonly-used encoders are provided out-of-the-box. They can either work alone or be chained together into a new encoder. See also `Composite Pattern `__ for the principle behind it. The driver has defined the encoder interface in :cpp:type:`rmt_encoder_t`, it contains the following functions: +To help get started with the RMT driver faster, some commonly used encoders are provided out-of-the-box. They can either work alone or be chained together into a new encoder. See also `Composite Pattern `__ for the principle behind it. The driver has defined the encoder interface in :cpp:type:`rmt_encoder_t`, it contains the following functions: - :cpp:member:`rmt_encoder_t::encode` is the fundamental function of an encoder. This is where the encoding session happens. - The function might be called multiple times within a single transaction. The encode function should return the state of the current encoding session. - The supported states are listed in the :cpp:type:`rmt_encode_state_t`. If the result contains :cpp:enumerator:`RMT_ENCODING_COMPLETE`, it means the current encoder has finished work. - - If the result contains :cpp:enumerator:`RMT_ENCODING_MEM_FULL`, we need to yield from the current session, as there is no space to save more encoding artifacts. + - If the result contains :cpp:enumerator:`RMT_ENCODING_MEM_FULL`, the program needs to yield from the current session, as there is no space to save more encoding artifacts. - :cpp:member:`rmt_encoder_t::reset` should reset the encoder state back to the initial state (the RMT encoder is stateful). - - If the RMT transmitter is manually stopped without resetting its corresponding encoder, subsequent encoding session can be erroneous. + - If the RMT transmitter is manually stopped without resetting its corresponding encoder, subsequent encoding session can be erroneous. - This function is also called implicitly in :cpp:func:`rmt_disable`. - :cpp:member:`rmt_encoder_t::del` should free the resources allocated by the encoder. @@ -424,7 +425,7 @@ Besides the primitive encoders provided by the driver, the user can implement hi Customize RMT Encoder for NEC Protocol ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In this section, we demonstrates how to write an NEC encoder. The NEC IR protocol uses pulse distance encoding of the message bits. Each pulse burst is ``562.5 µs`` in length, logical bits are transmitted as follows. It is worth mentioning that the least significant bit of each byte is sent first. +This section demonstrates how to write an NEC encoder. The NEC IR protocol uses pulse distance encoding of the message bits. Each pulse burst is ``562.5 µs`` in length, logical bits are transmitted as follows. It is worth mentioning that the least significant bit of each byte is sent first. - Logical ``0``: a ``562.5 µs`` pulse burst followed by a ``562.5 µs`` space, with a total transmit time of ``1.125 ms`` - Logical ``1``: a ``562.5 µs`` pulse burst followed by a ``1.6875 ms`` space, with a total transmit time of ``2.25 ms`` @@ -445,7 +446,7 @@ When a key is pressed on the remote controller, the transmitted message includes - 8-bit logical inverse of the command - a final ``562.5 µs`` pulse burst to signify the end of message transmission -Then we can construct the NEC :cpp:member:`rmt_encoder_t::encode` function in the same order, for example: +Then you can construct the NEC :cpp:member:`rmt_encoder_t::encode` function in the same order, for example: .. code:: c diff --git a/docs/zh_CN/api-reference/peripherals/rmt.rst b/docs/zh_CN/api-reference/peripherals/rmt.rst index c67db090b6a5..9008dd44a26d 100644 --- a/docs/zh_CN/api-reference/peripherals/rmt.rst +++ b/docs/zh_CN/api-reference/peripherals/rmt.rst @@ -249,6 +249,7 @@ RMT 是一种特殊的通信外设,无法像 SPI 和 I2C 那样发送原始字 注意,不是所有 ESP 芯片都支持 **循环发送** 功能,在配置此选项前,请参阅 [`TRM <{IDF_TARGET_TRM_EN_URL}#rmt>`__]。若所选芯片不支持配置此选项,可能会报告 :c:macro:`ESP_ERR_NOT_SUPPORTED` 错误。 - :cpp:member:`rmt_transmit_config_t::eot_level` 设置发射器完成工作时的输出电平,该设置同时适用于调用 :cpp:func:`rmt_disable` 停止发射器工作时的输出电平。 +- :cpp:member:`rmt_transmit_config_t::queue_nonblocking` 设置当传输队列满的时候该函数是否需要等待。如果该值设置为 ``true`` 那么当遇到队列满的时候,该函数会立即返回错误代码 :c:macro:`ESP_ERR_INVALID_STATE`。否则,函数会阻塞当前线程,直到传输队列有空档。 .. note:: From 4f24d3a39cfe748ea0b1522fc7c65f7e3a2590e7 Mon Sep 17 00:00:00 2001 From: Mo Fei Fei Date: Thu, 26 Oct 2023 12:19:25 +0800 Subject: [PATCH 048/161] Docs: Update CN trans for components/nvs_flash/nvs_partition_generator/README.rst --- .../nvs_partition_generator/README.rst | 220 +++++----- .../nvs_partition_generator/README_CN.rst | 391 +++++++++++------- .../api-reference/storage/nvs_encryption.rst | 2 +- 3 files changed, 379 insertions(+), 234 deletions(-) diff --git a/components/nvs_flash/nvs_partition_generator/README.rst b/components/nvs_flash/nvs_partition_generator/README.rst index 21689c5334ff..f91918b56b40 100644 --- a/components/nvs_flash/nvs_partition_generator/README.rst +++ b/components/nvs_flash/nvs_partition_generator/README.rst @@ -6,7 +6,7 @@ NVS Partition Generator Utility Introduction ------------ -The utility :component_file:`nvs_flash/nvs_partition_generator/nvs_partition_gen.py` creates a binary file, compatible with the NVS architecture defined in :doc:`Non-Volatile Storage `, based on the key-value pairs provided in a CSV file. +The utility :component_file:`nvs_flash/nvs_partition_generator/nvs_partition_gen.py` creates a binary file, compatible with the NVS architecture defined in :doc:`nvs_flash`, based on the key-value pairs provided in a CSV file. This utility is ideally suited for generating a binary blob, containing data specific to ODM/OEM, which can be flashed externally at the time of device manufacturing. This allows manufacturers to generate many instances of the same application firmware with customized parameters for each device, such as a serial number. @@ -81,7 +81,7 @@ By default, binary blobs are allowed to span over multiple pages and are written Encryption-Decryption Support ----------------------------- -The NVS Partition Generator utility also allows you to create an encrypted binary file and decrypt an encrypted one. The utility uses the XTS-AES encryption. Please refer to :doc:`NVS Encryption ` for more details. +The NVS Partition Generator utility also allows you to create an encrypted binary file and decrypt an encrypted one. The utility uses the XTS-AES encryption. Please refer to :ref:`nvs_encryption` for more details. Running the Utility @@ -93,27 +93,40 @@ Running the Utility **Optional Arguments**: -+-----+------------------------+---------------------------------------------------------------+ -| No. | Parameter | Description | -+=====+========================+===============================================================+ -| 1 | ``-h`` \ ``--help`` | Show the help message and exit | -+-----+------------------------+---------------------------------------------------------------+ +.. list-table:: + :widths: 20 40 40 + :header-rows: 1 -**Commands**:: + * - No. + - Parameter + - Description + * - 1 + - ``-h`` / ``--help`` + - Show the help message and exit - Run nvs_partition_gen.py {command} -h for additional help +**Commands**: -+-----+---------------------+---------------------------------------------------------------+ -| No. | Parameter | Description | -+=====+=====================+===============================================================+ -| 1 | ``generate`` | Generate NVS partition | -+-----+---------------------+---------------------------------------------------------------+ -| 2 | ``generate-key`` | Generate keys for encryption | -+-----+---------------------+---------------------------------------------------------------+ -| 3 | ``encrypt`` | Generate NVS encrypted partition | -+-----+---------------------+---------------------------------------------------------------+ -| 4 | ``decrypt`` | Decrypt NVS encrypted partition | -+-----+---------------------+---------------------------------------------------------------+ + Run ``nvs_partition_gen.py {command} -h`` for additional help + +.. list-table:: + :widths: 20 40 40 + :header-rows: 1 + + * - No. + - Parameter + - Description + * - 1 + - ``generate`` + - Generate NVS partition + * - 2 + - ``generate-key`` + - Generate keys for encryption + * - 3 + - ``encrypt`` + - Generate NVS encrypted partition + * - 4 + - ``decrypt`` + - Decrypt NVS encrypted partition Generate NVS Partition (Default) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -124,22 +137,25 @@ Generate NVS Partition (Default) **Positional Arguments**: -+--------------+---------------------------------------------------------------+ -| Parameter | Description | -+==============+===============================================================+ -| ``input`` | Path to CSV file to parse | -+--------------+---------------------------------------------------------------+ -| ``output`` | Path to output NVS binary file | -+--------------+---------------------------------------------------------------+ -| ``size`` | Size of NVS partition in bytes (must be multiple of 4096) | -+--------------+---------------------------------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``input`` + - Path to CSV file to parse + * - ``output`` + - Path to output NVS binary file + * - ``size`` + - Size of NVS partition in bytes (must be multiple of 4096) **Optional Arguments**: +------------------------+----------------------------------------------------------------------+ | Parameter | Description | +========================+======================================================================+ -| ``-h`` \ ``--help`` | Show the help message and exit | +| ``-h`` / ``--help`` | Show the help message and exit | +------------------------+----------------------------------------------------------------------+ | ``--version {1,2}`` | Set multipage blob version (Default: Version 2) | | | | @@ -174,33 +190,37 @@ Generate Encryption Keys Partition **Optional Arguments**: -+---------------------------------------------+-----------------------------------------------------------------------------------+ -| Parameter | Description | -+=============================================+===================================================================================+ -| ``-h`` \ ``--help`` | Show the help message and exit | -+---------------------------------------------+-----------------------------------------------------------------------------------+ -| ``--keyfile KEYFILE`` | Path to output encryption keys file | -+---------------------------------------------+-----------------------------------------------------------------------------------+ -| ``--outdir OUTDIR`` | Output directory to store files created. (Default: current directory) | -+---------------------------------------------+-----------------------------------------------------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``-h`` / ``--help`` + - Show the help message and exit + * - ``--keyfile KEYFILE`` + - Path to output encryption keys file + * - ``--outdir OUTDIR`` + - Output directory to store files created. (Default: current directory) .. only:: SOC_HMAC_SUPPORTED **Optional Arguments (HMAC scheme-specific)**: - +---------------------------------------------+-----------------------------------------------------------------------------------+ - | Parameter | Description | - +=============================================+===================================================================================+ - | ``--key_protect_hmac`` | If set, the NVS encryption key protection scheme based on HMAC | - | | peripheral is used; else the default scheme based on Flash Encryption | - | | is used | - +---------------------------------------------+-----------------------------------------------------------------------------------+ - | ``--kp_hmac_keygen`` | Generate the HMAC key for HMAC-based encryption scheme | - +---------------------------------------------+-----------------------------------------------------------------------------------+ - | ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` | Path to output HMAC key file | - +---------------------------------------------+-----------------------------------------------------------------------------------+ - | ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` | File having the HMAC key for generating the NVS encryption keys | - +---------------------------------------------+-----------------------------------------------------------------------------------+ + .. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``--key_protect_hmac`` + - If set, the NVS encryption key protection scheme based on HMAC peripheral is used; else the default scheme based on flash encryption is used + * - ``--kp_hmac_keygen`` + - Generate the HMAC key for HMAC-based encryption scheme + * - ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` + - Path to output the HMAC key file + * - ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` + - File having the HMAC key for generating the NVS encryption keys You can run the utility to generate only the encryption key partition using the command below:: @@ -216,7 +236,7 @@ You can run the utility to generate only the encryption key partition using the .. note:: Encryption key of the format ``/keys/keys-.bin`` and HMAC key of the format ``/keys/hmac-keys-.bin`` are created. - - Generate the NVS encryption keys, given the HMAC-key:: + - Generate the NVS encryption keys, given the HMAC key:: python nvs_partition_gen.py generate-key --key_protect_hmac --kp_hmac_inputkey testdata/sample_hmac_key.bin @@ -246,22 +266,25 @@ Generate Encrypted NVS Partition **Positional Arguments**: -+--------------+---------------------------------------------------------------+ -| Parameter | Description | -+==============+===============================================================+ -| ``input`` | Path to CSV file to parse | -+--------------+---------------------------------------------------------------+ -| ``output`` | Path to output NVS binary file | -+--------------+---------------------------------------------------------------+ -| ``size`` | Size of NVS partition in bytes (must be multiple of 4096) | -+--------------+---------------------------------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``input`` + - Path to CSV file to parse + * - ``output`` + - Path to output NVS binary file + * - ``size`` + - Size of NVS partition in bytes (must be multiple of 4096) **Optional Arguments**: +---------------------------------------------+-------------------------------------------------------------------------------+ | Parameter | Description | +=============================================+===============================================================================+ -| ``-h`` \ ``--help`` | Show the help message and exit | +| ``-h`` / ``--help`` | Show the help message and exit | +---------------------------------------------+-------------------------------------------------------------------------------+ | ``--version {1,2}`` | Set multipage blob version (Default: Version 2) | | | | @@ -282,19 +305,20 @@ Generate Encrypted NVS Partition **Optional Arguments (HMAC scheme-specific)**: - +---------------------------------------------+-------------------------------------------------------------------------------+ - | Parameter | Description | - +=============================================+===============================================================================+ - | ``--key_protect_hmac`` | If set, the NVS encryption key protection scheme based on HMAC | - | | peripheral is used; else the default scheme based on Flash Encryption | - | | is used | - +---------------------------------------------+-------------------------------------------------------------------------------+ - | ``--kp_hmac_keygen`` | Generate the HMAC key for HMAC-based encryption scheme | - +---------------------------------------------+-------------------------------------------------------------------------------+ - | ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` | Path to output HMAC key file | - +---------------------------------------------+-------------------------------------------------------------------------------+ - | ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` | File having the HMAC key for generating the NVS encryption keys | - +---------------------------------------------+-------------------------------------------------------------------------------+ + .. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``--key_protect_hmac`` + - If set, the NVS encryption key protection scheme based on HMAC peripheral is used; else the default scheme based on flash encryption is used + * - ``--kp_hmac_keygen`` + - Generate the HMAC key for HMAC-based encryption scheme + * - ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` + - Path to output HMAC key file + * - ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` + - File having the HMAC key for generating the NVS encryption keys You can run the utility to encrypt NVS partition using the command below. A sample CSV file is provided with the utility: @@ -306,7 +330,7 @@ You can run the utility to encrypt NVS partition using the command below. A samp .. only:: SOC_HMAC_SUPPORTED - - To generate an encrypted partition using the HMAC-based scheme, the above command can be used alongwith some additional parameters. + - To generate an encrypted partition using the HMAC-based scheme, the above command can be used along with some additional parameters. - Encrypt by allowing the utility to generate encryption keys and the HMAC-key:: @@ -343,33 +367,39 @@ Decrypt Encrypted NVS Partition **Positional Arguments**: -+--------------+---------------------------------------------------------------+ -| Parameter | Description | -+==============+===============================================================+ -| ``input`` | Path to encrypted NVS partition file to parse | -+--------------+---------------------------------------------------------------+ -| ``key`` | Path to file having keys for decryption | -+--------------+---------------------------------------------------------------+ -| ``output`` | Path to output decrypted binary file | -+--------------+---------------------------------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``input`` + - Path to encrypted NVS partition file to parse + * - ``key`` + - Path to file having keys for decryption + * - ``output`` + - Path to output decrypted binary file **Optional Arguments**: -+------------------------+----------------------------------------------------------------------+ -| Parameter | Description | -+========================+======================================================================+ -| ``-h`` / ``--help`` | Show the help message and exit | -+------------------------+----------------------------------------------------------------------+ -| ``--outdir OUTDIR`` | Output directory to store file created (Default: current directory) | -+------------------------+----------------------------------------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Parameter + - Description + * - ``-h`` / ``--help`` + - Show the help message and exit + * - ``--outdir OUTDIR`` + - Output directory to store files created. (Default: current directory) You can run the utility to decrypt encrypted NVS partition using the command below:: python nvs_partition_gen.py decrypt sample_encr.bin sample_keys.bin sample_decr.bin You can also provide the format version number: - - Multipage Blob Support Disabled (Version 1) - - Multipage Blob Support Enabled (Version 2) + - Multipage blob support disabled (Version 1) + - Multipage blob support enabled (Version 2) Multipage Blob Support Disabled (Version 1) diff --git a/components/nvs_flash/nvs_partition_generator/README_CN.rst b/components/nvs_flash/nvs_partition_generator/README_CN.rst index 05615c03475a..785a49bbe5a1 100644 --- a/components/nvs_flash/nvs_partition_generator/README_CN.rst +++ b/components/nvs_flash/nvs_partition_generator/README_CN.rst @@ -1,23 +1,25 @@ NVS 分区生成程序 -=============================== +================ :link_to_translation:`en:[English]` 介绍 ------------- +---- -NVS 分区生成程序 (:component_file:`nvs_flash/nvs_partition_generator/nvs_partition_gen.py`) 根据 CSV 文件中的键值对生成二进制文件。该二进制文件与 :doc:`非易失性存储器 (NVS) ` 中定义的 NVS 结构兼容。NVS 分区生成程序适合用于生成二进制数据(Blob),其中包括设备生产时可从外部烧录的 ODM/OEM 数据。这也使得生产制造商在使用同一个应用固件的基础上,通过自定义参数,如序列号,为每个设备生成不同配置的二进制 NVS 分区。 +NVS 分区生成程序 (:component_file:`nvs_flash/nvs_partition_generator/nvs_partition_gen.py`) 根据 CSV 文件中的键值对生成二进制文件。该二进制文件与 :doc:`nvs_flash` 中定义的 NVS 结构兼容。 + +NVS 分区生成程序适合用于生成二进制数据 (blob),其中包括设备生产时可从外部烧录的 ODM/OEM 数据。这也使得生产制造商在使用同一个应用固件的基础上,通过自定义参数,如序列号,为每个设备生成不同配置的二进制 NVS 分区。 准备工作 -------------- +-------- 在加密模式下使用该程序,需安装下列软件包: - - cryptography package + - ``cryptography`` 根目录下的 `requirements.txt` 包含必需 python 包,请预先安装。 CSV 文件格式 ---------------- +~~~~~~~~~~~~ CSV 文件每行需包含四个参数,以逗号隔开。具体参数描述见下表: @@ -63,31 +65,27 @@ CSV 文件每行需包含四个参数,以逗号隔开。具体参数描述见 NVS 条目和命名空间 (namespace) 的关联 ------------------------------------------ +------------------------------------- 如 CSV 文件中出现命名空间条目,后续条目均会被视为该命名空间的一部分,直至找到下一个命名空间条目。找到新命名空间条目后,后续所有条目都会被视为新命名空间的一部分。 .. note:: CSV 文件中第一个条目应始终为 ``namespace``。 -支持多页 Blob ----------------------- - -默认情况下,二进制 Blob 可跨多页,格式参考 :ref:`structure_of_entry` 章节。如需使用旧版格式,可在程序中禁用该功能。 +支持多页 blob +------------- +默认情况下,二进制 blob 可跨多页,格式参考 :ref:`structure_of_entry` 章节。如需使用旧版格式,可在程序中禁用该功能。 -支持加密 -------------------- -NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件。更多信息详见 :ref:`nvs_encryption`。 +支持加解密 +---------- +NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件或对此类文件进行解密。更多信息详见 :ref:`nvs_encryption`。 -支持解密 -------------------- -如果 NVS 二进制文件采用了 XTS-AES 加密,该程序还可对此类文件进行解密,更多信息详见 :ref:`nvs_encryption`。 运行程序 -------------------- +-------- **使用方法**:: @@ -95,77 +93,100 @@ NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件。 **可选参数**: -+------+------------+----------------------+ -| 序号 | 参数 | 描述 | -+------+------------+----------------------+ -| 1 | -h, --help | 显示帮助信息并退出 | -+------+------------+----------------------+ +.. list-table:: + :widths: 20 40 40 + :header-rows: 1 + + * - 序号 + - 参数 + - 描述 + * - 1 + - ``-h`` / ``--help`` + - 显示帮助信息并退出 -**命令**:: +**命令**: - 运行 nvs_partition_gen.py {command} -h 查看更多帮助信息 + 运行 ``nvs_partition_gen.py {command} -h`` 查看更多帮助信息 -+------+--------------+---------------+ -| 序号 | 参数 | 描述 | -+------+--------------+---------------+ -| 1 | generate | 生成 NVS 分区 | -+------+--------------+---------------+ -| 2 | generate-key | 生成加密密钥 | -+------+--------------+---------------+ -| 3 | encrypt | 加密 NVS 分区 | -+------+--------------+---------------+ -| 4 | decrypt | 解密 NVS 分区 | -+------+--------------+---------------+ +.. list-table:: + :widths: 20 40 40 + :header-rows: 1 + + * - 序号 + - 参数 + - 描述 + * - 1 + - ``generate`` + - 生成 NVS 分区 + * - 2 + - ``generate-key`` + - 生成加密密钥 + * - 3 + - ``encrypt`` + - 加密 NVS 分区 + * - 4 + - ``decrypt`` + - 解密 NVS 分区 生成 NVS 分区(默认模式) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~ **使用方法**:: - python nvs_partition_gen.py generate [-h] [--version {1,2}] [--outdir OUTDIR] - input output size + python nvs_partition_gen.py generate [-h] [--version {1,2}] [--outdir OUTDIR] input output size **位置参数**: -+--------+--------------------------------------------------+ -| 参数 | 描述 | -+--------+--------------------------------------------------+ -| input | 待解析的 CSV 文件路径 | -+--------+--------------------------------------------------+ -| output | NVS 二进制文件的输出路径 | -+--------+--------------------------------------------------+ -| size | NVS 分区大小(以字节为单位,且为 4096 的整数倍) | -+--------+--------------------------------------------------+ - -**可选参数**: +.. list-table:: + :widths: 30 70 + :header-rows: 1 -+-----------------+------------------------------------------------+ -| 参数 | 描述 | -+-----------------+------------------------------------------------+ -| -h, --help | 显示帮助信息并退出 | -+-----------------+------------------------------------------------+ -| --version {1,2} | - 设置多页 Blob 版本。 | -| | - 版本 1:禁用多页 Blob; | -| | - 版本 2:启用多页 Blob; | -| | - 默认版本:版本 2。 | -+-----------------+------------------------------------------------+ -| --outdir OUTDIR | 输出目录,用于存储创建的文件。(默认当前目录) | -+-----------------+------------------------------------------------+ + * - 参数 + - 描述 + * - ``input`` + - 待解析的 CSV 文件路径 + * - ``output`` + - NVS 二进制文件的输出路径 + * - ``size`` + - NVS 分区大小(以字节为单位,且为 4096 的整数倍) +**可选参数**: ++--------------------------+------------------------------------------------+ +| 参数 | 描述 | ++--------------------------+------------------------------------------------+ +| ``-h`` / ``--help`` | 显示帮助信息并退出 | ++--------------------------+------------------------------------------------+ +| ``--version {1,2}`` | - 设置多页 blob 版本,默认为版本 2。 | +| | | +| | - 版本 1:禁用多页 blob; | +| | | +| | - 版本 2:启用多页 blob。 | ++--------------------------+------------------------------------------------+ +| ``--outdir OUTDIR`` | 输出目录,用于存储创建的文件。(默认当前目录) | ++--------------------------+------------------------------------------------+ 运行如下命令创建 NVS 分区,该程序同时会提供 CSV 示例文件:: python nvs_partition_gen.py generate sample_singlepage_blob.csv sample.bin 0x3000 -仅生成加密密钥分区 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +生成加密密钥分区 +~~~~~~~~~~~~~~~~ -**使用方法**:: +.. only:: SOC_HMAC_SUPPORTED + + **使用方法**:: + + python nvs_partition_gen.py generate-key [-h] [--key_protect_hmac] [--kp_hmac_keygen] + [--kp_hmac_keyfile KP_HMAC_KEYFILE] [--kp_hmac_inputkey KP_HMAC_INPUTKEY] + [--keyfile KEYFILE] [--outdir OUTDIR] - python nvs_partition_gen.py generate-key [-h] [--keyfile KEYFILE] - [--outdir OUTDIR] +.. only:: not SOC_HMAC_SUPPORTED + + **使用方法**:: + + python nvs_partition_gen.py generate-key [-h] [--keyfile KEYFILE] [--outdir OUTDIR] **可选参数**: @@ -175,61 +196,129 @@ NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件。 * - 参数 - 描述 - * - -h, --help + * - ``-h`` / ``--help`` - 显示帮助信息并退出 - * - --keyfile KEYFILE + * - ``--keyfile KEYFILE`` - 加密密钥分区文件的输出路径 - * - --outdir OUTDIR + * - ``--outdir OUTDIR`` - 输出目录,用于存储创建的文件(默认当前目录) +.. only:: SOC_HMAC_SUPPORTED + + **可选参数(仅适用于 HMAC 方案)**: + + .. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 参数 + - 描述 + * - ``--key_protect_hmac`` + - 设置后使用基于 HMAC 的 NVS 加密密钥保护方案,否则使用基于 flash 加密的默认方案 + * - ``--kp_hmac_keygen`` + - 为基于 HMAC 的加密方案生成 HMAC 密钥 + * - ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` + - HMAC 密钥文件的输出路径 + * - ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` + - 包含 HMAC 密钥的文件,用于生成 NVS 加密密钥 + 运行以下命令仅生成加密密钥分区:: python nvs_partition_gen.py generate-key +.. only:: SOC_HMAC_SUPPORTED + + 运行以下命令,为基于 HMAC 的方案生成加密密钥: + + - 生成 HMAC 密钥和 NVS 加密密钥:: + + python nvs_partition_gen.py generate-key --key_protect_hmac --kp_hmac_keygen + + .. note:: 上述命令生成 ``/keys/keys-.bin`` 格式的加密密钥和 ``/keys/hmac-keys-.bin`` 格式的 HMAC 密钥。 + + - 基于 HMAC 密钥生成 NVS 加密密钥:: + + python nvs_partition_gen.py generate-key --key_protect_hmac --kp_hmac_inputkey testdata/sample_hmac_key.bin + + .. note:: 可将自定义文件名作为参数提供给 HMAC 密钥和加密密钥。 + 生成 NVS 加密分区 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~ -**使用方法**:: +.. only:: SOC_HMAC_SUPPORTED + + **使用方法**:: + + python nvs_partition_gen.py encrypt [-h] [--version {1,2}] [--keygen] + [--keyfile KEYFILE] [--inputkey INPUTKEY] [--outdir OUTDIR] + [--key_protect_hmac] [--kp_hmac_keygen] + [--kp_hmac_keyfile KP_HMAC_KEYFILE] [--kp_hmac_inputkey KP_HMAC_INPUTKEY] + input output size + +.. only:: not SOC_HMAC_SUPPORTED + + **使用方法**:: + + python nvs_partition_gen.py encrypt [-h] [--version {1,2}] [--keygen] + [--keyfile KEYFILE] [--inputkey INPUTKEY] [--outdir OUTDIR] + input output size - python nvs_partition_gen.py encrypt [-h] [--version {1,2}] [--keygen] - [--keyfile KEYFILE] [--inputkey INPUTKEY] - [--outdir OUTDIR] - input output size **位置参数**: -+--------+--------------------------------------+ -| 参数 | 描述 | -+--------+--------------------------------------+ -| input | 待解析 CSV 文件的路径 | -+--------+--------------------------------------+ -| output | NVS 二进制文件的输出路径 | -+--------+--------------------------------------+ -| size | NVS 分区大小 | -| | (以字节为单位,且为 4096 的整数倍) | -+--------+--------------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 参数 + - 描述 + * - ``input`` + - 待解析的 CSV 文件路径 + * - ``output`` + - NVS 二进制文件的输出路径 + * - ``size`` + - NVS 分区大小(以字节为单位,且为 4096 的整数倍) **可选参数**: -+---------------------+------------------------------+ -| 参数 | 描述 | -+---------------------+------------------------------+ -| -h, --help | 显示帮助信息并退出 | -+---------------------+------------------------------+ -| --version {1,2} | - 设置多页 Blob 版本。 | -| | - 版本 1:禁用多页 Blob; | -| | - 版本 2:启用多页 Blob; | -| | - 默认版本:版本 2。 | -+---------------------+------------------------------+ -| --keygen | 生成 NVS 分区加密密钥 | -+---------------------+------------------------------+ -| --keyfile KEYFILE | 密钥文件的输出路径 | -+---------------------+------------------------------+ -| --inputkey INPUTKEY | 内含 NVS 分区加密密钥的文件 | -+---------------------+------------------------------+ -| --outdir OUTDIR | 输出目录,用于存储创建的文件 | -| | (默认当前目录) | -+---------------------+------------------------------+ ++--------------------------+------------------------------------------------+ +| 参数 | 描述 | ++--------------------------+------------------------------------------------+ +| ``-h`` / ``--help`` | 显示帮助信息并退出 | ++--------------------------+------------------------------------------------+ +| ``--version {1,2}`` | - 设置多页 blob 版本,默认为版本 2。 | +| | | +| | - 版本 1:禁用多页 blob; | +| | | +| | - 版本 2:启用多页 blob。 | ++--------------------------+------------------------------------------------+ +| ``--keygen`` | 生成 NVS 分区加密密钥 | ++--------------------------+------------------------------------------------+ +| ``--keyfile KEYFILE`` | 密钥文件的输出路径 | ++--------------------------+------------------------------------------------+ +| ``--inputkey INPUTKEY`` | 内含 NVS 分区加密密钥的文件 | ++--------------------------+------------------------------------------------+ +| ``--outdir OUTDIR`` | 输出目录,用于存储创建的文件。(默认当前目录) | ++--------------------------+------------------------------------------------+ + +.. only:: SOC_HMAC_SUPPORTED + + **可选参数(仅适用于 HMAC 方案)**: + + .. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 参数 + - 描述 + * - ``--key_protect_hmac`` + - 设置后使用基于 HMAC 的 NVS 加密密钥保护方案,否则使用基于 flash 加密的默认方案 + * - ``--kp_hmac_keygen`` + - 为基于 HMAC 的加密方案生成 HMAC 密钥 + * - ``--kp_hmac_keyfile KP_HMAC_KEYFILE`` + - HMAC 密钥文件的输出路径 + * - ``--kp_hmac_inputkey KP_HMAC_INPUTKEY`` + - 包含 HMAC 密钥的文件,用于生成 NVS 加密密钥 运行以下命令加密 NVS 分区,该程序同时会提供一个 CSV 示例文件。 @@ -237,21 +326,40 @@ NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件。 python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen -.. note:: 创建的加密密钥格式为 ``/keys/keys-.bin``。 + .. note:: 创建的加密密钥格式为 ``/keys/keys-.bin``。 + +.. only:: SOC_HMAC_SUPPORTED + + - 要使用基于 HMAC 的方案生成加密分区,可将上述命令与附加参数搭配使用。 + + - 通过 NVS 分区生成程序生成加密密钥和 HMAC 密钥,从而进行加密:: + + python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen --key_protect_hmac --kp_hmac_keygen + + .. note:: 上述命令生成 ``/keys/keys-.bin`` 格式的加密密钥和 ``/keys/hmac-keys-.bin`` 格式的 HMAC 密钥。 + + - 通过 NVS 分区生成程序使用用户提供的 HMAC 密钥生成加密密钥,从而进行加密:: + + python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen --key_protect_hmac --kp_hmac_inputkey testdata/sample_hmac_key.bin + + .. note:: 可将自定义文件名作为参数提供给 HMAC 密钥和加密密钥。 - 通过 NVS 分区生成程序生成加密密钥,并将密钥存储于自定义的文件中:: python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --keygen --keyfile sample_keys.bin -.. note:: 创建的加密密钥格式为 ``/keys/keys-.bin``。 -.. note:: 加密密钥存储于新建文件的 ``keys/`` 目录下,与 NVS 密钥分区结构兼容。更多信息请参考 :ref:`nvs_encr_key_partition`。 +.. note:: + + - 创建的加密密钥格式为 ``/keys/sample_keys.bin``。 + + - 加密密钥存储于新建文件的 ``keys/`` 目录下,与 NVS 密钥分区结构兼容。更多信息请参考 :ref:`nvs_encr_key_partition`。 - 将加密密钥用作二进制输入文件来进行加密:: python nvs_partition_gen.py encrypt sample_singlepage_blob.csv sample_encr.bin 0x3000 --inputkey sample_keys.bin 解密 NVS 分区 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~ **使用方法**:: @@ -259,58 +367,65 @@ NVS 分区生成程序还可使用 XTS-AES 加密生成二进制加密文件。 **位置参数**: -+--------+-------------------------------+ -| 参数 | 描述 | -+--------+-------------------------------+ -| input | 待解析的 NVS 加密分区文件路径 | -+--------+-------------------------------+ -| key | 含有解密密钥的文件路径 | -+--------+-------------------------------+ -| output | 已解密的二进制文件输出路径 | -+--------+-------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 参数 + - 描述 + * - ``input`` + - 待解析的 NVS 加密分区文件路径 + * - ``key`` + - 含有解密密钥的文件路径 + * - ``output`` + - 已解密的二进制文件输出路径 **可选参数**: -+-----------------+------------------------------+ -| 参数 | 描述 | -+-----------------+------------------------------+ -| -h, --help | 显示帮助信息并退出 | -+-----------------+------------------------------+ -| --outdir OUTDIR | 输出目录,用于存储创建的文件 | -| | (默认当前目录) | -+-----------------+------------------------------+ +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - 参数 + - 描述 + * - ``-h`` / ``--help`` + - 显示帮助信息并退出 + * - ``--outdir OUTDIR`` + - 输出目录,用于存储创建的文件(默认当前目录) 运行以下命令解密已加密的 NVS 分区:: python nvs_partition_gen.py decrypt sample_encr.bin sample_keys.bin sample_decr.bin -您可以自定义格式版本号: -- 版本 1:禁用多页 Blob -- 版本 2:启用多页 Blob +可以在命令中提供版本参数,选择格式版本号: + - 版本 1:禁用多页 blob + - 版本 2:启用多页 blob -版本 1:禁用多页 Blob -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +版本 1:禁用多页 blob +~~~~~~~~~~~~~~~~~~~~~ -如需禁用多页 Blob,请按照如下命令将版本参数设置为 1,以此格式运行分区生成程序。该程序同时会提供一个 CSV 示例文件:: +如需禁用多页 blob,请按照如下命令将版本参数设置为 1,以此格式运行分区生成程序。该程序同时会提供一个 CSV 示例文件:: python nvs_partition_gen.py generate sample_singlepage_blob.csv sample.bin 0x3000 --version 1 -版本 2:启用多页 Blob -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +版本 2:启用多页 blob +~~~~~~~~~~~~~~~~~~~~~ -如需启用多页 Blob,请按照如下命令将版本参数设置为 2,以此格式运行分区生成程序。该程序同时会提供一个 CSV 示例文件:: +如需启用多页 blob,请按照如下命令将版本参数设置为 2,以此格式运行分区生成程序。该程序同时会提供一个 CSV 示例文件:: python nvs_partition_gen.py generate sample_multipage_blob.csv sample.bin 0x4000 --version 2 -.. note:: NVS 分区最小为 0x3000 字节。 +.. note:: + + - NVS 分区最小为 0x3000 字节。 -.. note:: 将二进制文件烧录至设备时,请确保与应用的 sdkconfig 设置一致。 + - 将二进制文件烧录至设备时,请确保与应用的 sdkconfig 设置一致。 说明 -------- +---- - 分区生成程序不会对重复键进行检查,而将数据同时写入这两个重复键中。请注意不要使用同名的键; - 新页面创建后,前一页的空白处不会再写入数据。CSV 文件中的字段须按次序排列以优化内存; diff --git a/docs/en/api-reference/storage/nvs_encryption.rst b/docs/en/api-reference/storage/nvs_encryption.rst index 97efccdf9c58..42b12c718050 100644 --- a/docs/en/api-reference/storage/nvs_encryption.rst +++ b/docs/en/api-reference/storage/nvs_encryption.rst @@ -1,7 +1,7 @@ NVS Encryption ============== -:link_to_translation:`en:[English]` +:link_to_translation:`zh_CN:[中文]` Overview -------- From a8e3122866eb2456fd904c96855589751da72760 Mon Sep 17 00:00:00 2001 From: gaoxu Date: Thu, 26 Oct 2023 12:22:09 +0800 Subject: [PATCH 049/161] fix(adc): fix adc read zero after getting done signal on h2 --- components/hal/adc_oneshot_hal.c | 35 +++++++++++++-------- components/hal/esp32/include/hal/adc_ll.h | 1 + components/hal/esp32c2/include/hal/adc_ll.h | 1 + components/hal/esp32c3/include/hal/adc_ll.h | 1 + components/hal/esp32c6/include/hal/adc_ll.h | 1 + components/hal/esp32h2/include/hal/adc_ll.h | 1 + components/hal/esp32s2/include/hal/adc_ll.h | 1 + components/hal/esp32s3/include/hal/adc_ll.h | 1 + 8 files changed, 29 insertions(+), 13 deletions(-) diff --git a/components/hal/adc_oneshot_hal.c b/components/hal/adc_oneshot_hal.c index fb5f46076fec..feddc3178ca0 100644 --- a/components/hal/adc_oneshot_hal.c +++ b/components/hal/adc_oneshot_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -85,33 +85,42 @@ static void adc_hal_onetime_start(adc_unit_t unit, uint32_t clk_src_freq_hz) { #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED (void)unit; - uint32_t delay = 0; /** * There is a hardware limitation. If the APB clock frequency is high, the step of this reg signal: ``onetime_start`` may not be captured by the * ADC digital controller (when its clock frequency is too slow). A rough estimate for this step should be at least 3 ADC digital controller * clock cycle. */ - uint32_t digi_clk = clk_src_freq_hz / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1); + uint32_t adc_ctrl_clk = clk_src_freq_hz / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1); //Convert frequency to time (us). Since decimals are removed by this division operation. Add 1 here in case of the fact that delay is not enough. - delay = (1000 * 1000) / digi_clk + 1; - //3 ADC digital controller clock cycle - delay = delay * 3; - HAL_EARLY_LOGD("adc_hal", "clk_src_freq_hz: %"PRIu32", digi_clk: %"PRIu32", delay: %"PRIu32"", clk_src_freq_hz, digi_clk, delay); + uint32_t sample_delay_us = ((1000 * 1000) / adc_ctrl_clk + 1) * 3; + HAL_EARLY_LOGD("adc_hal", "clk_src_freq_hz: %"PRIu32", adc_ctrl_clk: %"PRIu32", sample_delay_us: %"PRIu32"", clk_src_freq_hz, adc_ctrl_clk, sample_delay_us); //This coefficient (8) is got from test, and verified from DT. When digi_clk is not smaller than ``APB_CLK_FREQ/8``, no delay is needed. - if (digi_clk >= APB_CLK_FREQ/8) { - delay = 0; + if (adc_ctrl_clk >= APB_CLK_FREQ/8) { + sample_delay_us = 0; } - HAL_EARLY_LOGD("adc_hal", "delay: %"PRIu32"", delay); + HAL_EARLY_LOGD("adc_hal", "delay for `onetime_start` signal captured: %"PRIu32"", sample_delay_us); adc_oneshot_ll_start(false); - esp_rom_delay_us(delay); + esp_rom_delay_us(sample_delay_us); adc_oneshot_ll_start(true); - //No need to delay here. Becuase if the start signal is not seen, there won't be a done intr. +#if ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL + /** + * There is a hardware limitation. + * After ADC get DONE signal, it still need a delay to synchronize ADC raw data or it may get zero. + * A rough estimate for this step should be at least ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL ADC sar clock cycle. + */ + uint32_t sar_clk = adc_ctrl_clk / ADC_LL_DIGI_SAR_CLK_DIV_DEFAULT; + uint32_t read_delay_us = ((1000 * 1000) / sar_clk + 1) * ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL; + HAL_EARLY_LOGD("adc_hal", "clk_src_freq_hz: %"PRIu32", sar_clk: %"PRIu32", read_delay_us: %"PRIu32"", clk_src_freq_hz, sar_clk, read_delay_us); + esp_rom_delay_us(read_delay_us); + +#endif //ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL + #else adc_oneshot_ll_start(unit); -#endif +#endif // SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED } bool adc_oneshot_hal_convert(adc_oneshot_hal_ctx_t *hal, int *out_raw) diff --git a/components/hal/esp32/include/hal/adc_ll.h b/components/hal/esp32/include/hal/adc_ll.h index 6e5ef9bbcc60..08e93a0c6d04 100644 --- a/components/hal/esp32/include/hal/adc_ll.h +++ b/components/hal/esp32/include/hal/adc_ll.h @@ -30,6 +30,7 @@ extern "C" { ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (1) #define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) /*--------------------------------------------------------------- DMA diff --git a/components/hal/esp32c2/include/hal/adc_ll.h b/components/hal/esp32c2/include/hal/adc_ll.h index 96c3e58bdef6..9427b0e4c421 100644 --- a/components/hal/esp32c2/include/hal/adc_ll.h +++ b/components/hal/esp32c2/include/hal/adc_ll.h @@ -33,6 +33,7 @@ extern "C" { Oneshot ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) /*--------------------------------------------------------------- DMA diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index eb3a42651c7c..f62ffb538c63 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -41,6 +41,7 @@ extern "C" { Oneshot ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) /*--------------------------------------------------------------- DMA diff --git a/components/hal/esp32c6/include/hal/adc_ll.h b/components/hal/esp32c6/include/hal/adc_ll.h index c8c52aadfd3d..d7d689e74a6a 100644 --- a/components/hal/esp32c6/include/hal/adc_ll.h +++ b/components/hal/esp32c6/include/hal/adc_ll.h @@ -42,6 +42,7 @@ extern "C" { Oneshot ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) /*--------------------------------------------------------------- DMA diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index 269194b69072..31b8976c4090 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -42,6 +42,7 @@ extern "C" { Oneshot ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (2) /*--------------------------------------------------------------- DMA diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index 2985503a52cc..ad24bbed46b5 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -39,6 +39,7 @@ extern "C" { ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) #define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) /*--------------------------------------------------------------- DMA diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index f647f4c677bc..e0886a1db3b7 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -42,6 +42,7 @@ extern "C" { ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) #define ADC_LL_SAR_CLK_DIV_DEFAULT(PERIPH_NUM) (1) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) /*--------------------------------------------------------------- DMA From f7e174e9487cc218b92cffee9dc5953e962e0ff4 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Mon, 23 Oct 2023 15:47:13 +0800 Subject: [PATCH 050/161] fix(bt/bluedroid): Optimize compatibility with Android 10 and later devices --- components/esp_hid/src/ble_hidd.c | 2 +- .../esp_hid_device/main/esp_hid_device_main.c | 29 ++----------------- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/components/esp_hid/src/ble_hidd.c b/components/esp_hid/src/ble_hidd.c index 358ba7b7240a..e0c22adb857d 100644 --- a/components/esp_hid/src/ble_hidd.c +++ b/components/esp_hid/src/ble_hidd.c @@ -463,7 +463,7 @@ static void hid_event_handler(esp_ble_hidd_dev_t *dev, int device_index, esp_gat link_report_handles(&dev->devices[device_index], param->add_attr_tab.handles); esp_ble_gatts_start_service(dev->devices[device_index].hid_svc.handle); if ((device_index + 1) < dev->devices_len) { - create_hid_db(dev, device_index + 1);//add next device + create_hid_db(dev, device_index + 1);//add next device if support } break; } 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 94edd4d2c172..7e95cdb65f12 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 @@ -42,27 +42,6 @@ typedef struct #if CONFIG_BT_BLE_ENABLED static local_param_t s_ble_hid_param = {0}; -const unsigned char hidapiReportMap[] = { //8 bytes input, 8 bytes feature - 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00) - 0x0A, 0x00, 0x01, // Usage (0x0100) - 0xA1, 0x01, // Collection (Application) - 0x85, 0x01, // Report ID (1) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x75, 0x08, // Report Size (8) - 0x95, 0x08, // Report Count (8) - 0x09, 0x01, // Usage (0x01) - 0x82, 0x02, 0x01, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Buffered Bytes) - 0x95, 0x08, // Report Count (8) - 0x09, 0x02, // Usage (0x02) - 0xB2, 0x02, 0x01, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes) - 0x95, 0x08, // Report Count (8) - 0x09, 0x03, // Usage (0x03) - 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) - 0xC0, // End Collection - - // 38 bytes -}; const unsigned char mediaReportMap[] = { 0x05, 0x0C, // Usage Page (Consumer) @@ -125,10 +104,6 @@ const unsigned char mediaReportMap[] = { }; static esp_hid_raw_report_map_t ble_report_maps[] = { - { - .data = hidapiReportMap, - .len = sizeof(hidapiReportMap) - }, { .data = mediaReportMap, .len = sizeof(mediaReportMap) @@ -143,7 +118,7 @@ static esp_hid_device_config_t ble_hid_config = { .manufacturer_name = "Espressif", .serial_number = "1234567890", .report_maps = ble_report_maps, - .report_maps_len = 2 + .report_maps_len = 1 }; #define HID_CC_RPT_MUTE 1 @@ -293,7 +268,7 @@ void esp_hidd_send_consumer_value(uint8_t key_cmd, bool key_pressed) break; } } - esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 1, HID_RPT_ID_CC_IN, buffer, HID_CC_IN_RPT_LEN); + esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, HID_RPT_ID_CC_IN, buffer, HID_CC_IN_RPT_LEN); return; } From 418494800cc851dbe6ba7e35e7c3f7c918058228 Mon Sep 17 00:00:00 2001 From: morris Date: Wed, 25 Oct 2023 11:57:01 +0800 Subject: [PATCH 051/161] fix(i2c): read write FIFO memory by volatile --- components/hal/esp32c3/include/hal/i2c_ll.h | 28 +++------- components/hal/esp32c6/include/hal/i2c_ll.h | 14 ++--- components/hal/esp32h2/include/hal/i2c_ll.h | 22 +++----- components/hal/esp32p4/include/hal/i2c_ll.h | 26 ++++----- components/hal/esp32s3/include/hal/i2c_ll.h | 22 +++----- .../soc/esp32c3/include/soc/i2c_struct.h | 53 +++---------------- .../soc/esp32c6/include/soc/i2c_struct.h | 35 ++---------- .../soc/esp32h2/include/soc/i2c_struct.h | 35 ++---------- .../soc/esp32p4/include/soc/i2c_struct.h | 35 ++---------- .../soc/esp32s3/include/soc/i2c_struct.h | 36 ++----------- tools/ci/check_copyright_ignore.txt | 1 - 11 files changed, 53 insertions(+), 254 deletions(-) diff --git a/components/hal/esp32c3/include/hal/i2c_ll.h b/components/hal/esp32c3/include/hal/i2c_ll.h index f199940382b3..bce34f325f38 100644 --- a/components/hal/esp32c3/include/hal/i2c_ll.h +++ b/components/hal/esp32c3/include/hal/i2c_ll.h @@ -24,7 +24,6 @@ extern "C" { #endif - /** * @brief I2C hardware cmd register fields. */ @@ -89,7 +88,7 @@ typedef enum { */ static inline void i2c_ll_master_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal) { - uint32_t clkm_div = source_clk / (bus_freq * 1024) +1; + uint32_t clkm_div = source_clk / (bus_freq * 1024) + 1; uint32_t sclk_freq = source_clk / clkm_div; uint32_t half_cycle = sclk_freq / bus_freq / 2; //SCL @@ -98,7 +97,7 @@ static inline void i2c_ll_master_cal_bus_clk(uint32_t source_clk, uint32_t bus_f // default, scl_wait_high < scl_high // Make 80KHz as a boundary here, because when working at lower frequency, too much scl_wait_high will faster the frequency // according to some hardware behaviors. - clk_cal->scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); + clk_cal->scl_wait_high = (bus_freq >= 80 * 1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high; clk_cal->sda_hold = half_cycle / 4; clk_cal->sda_sample = half_cycle / 2; @@ -305,8 +304,7 @@ static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_e __attribute__((always_inline)) static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) { - switch (hw->sr.stretch_cause) - { + switch (hw->sr.stretch_cause) { case 0: *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; break; @@ -594,7 +592,7 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h __attribute__((always_inline)) static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len) { - for (int i = 0; i< len; i++) { + for (int i = 0; i < len; i++) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->fifo_data, data, ptr[i]); } } @@ -611,7 +609,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_ __attribute__((always_inline)) static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) { - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->fifo_data, data); } } @@ -623,14 +621,11 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs to be writen - * - * @return None. */ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr; for (int i = 0; i < len; i++) { - fifo_addr[i + ram_offset] = ptr[i]; + hw->txfifo_mem[i + ram_offset] = ptr[i]; } } @@ -641,15 +636,11 @@ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, co * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs read - * - * @return None */ static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr; - for (int i = 0; i < len; i++) { - ptr[i] = fifo_addr[i + ram_offset]; + ptr[i] = hw->rxfifo_mem[i + ram_offset]; } } @@ -700,8 +691,6 @@ static inline void i2c_ll_master_get_filter(i2c_dev_t *hw, uint8_t *filter_conf) *filter_conf = hw->filter_cfg.scl_thres; } - - /** * @brief Reste I2C master FSM. When the master FSM is stuck, call this function to reset the FSM * @@ -920,7 +909,7 @@ static inline void i2c_ll_master_get_event(i2c_dev_t *hw, i2c_intr_event_t *even *event = I2C_INTR_EVENT_ARBIT_LOST; } else if (int_sts.nack) { *event = I2C_INTR_EVENT_NACK; - } else if (int_sts.time_out||int_sts.scl_st_to||int_sts.scl_main_st_to) { + } else if (int_sts.time_out || int_sts.scl_st_to || int_sts.scl_main_st_to) { *event = I2C_INTR_EVENT_TOUT; } else if (int_sts.end_detect) { *event = I2C_INTR_EVENT_END_DET; @@ -1057,7 +1046,6 @@ static inline void i2c_ll_slave_disable_rx_it(i2c_dev_t *hw) hw->int_ena.val &= (~I2C_LL_SLAVE_RX_INT); } - /** * @brief Configure I2C SCL timing * diff --git a/components/hal/esp32c6/include/hal/i2c_ll.h b/components/hal/esp32c6/include/hal/i2c_ll.h index 80e7738b69ab..b6dadfa47737 100644 --- a/components/hal/esp32c6/include/hal/i2c_ll.h +++ b/components/hal/esp32c6/include/hal/i2c_ll.h @@ -310,8 +310,7 @@ static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_e __attribute__((always_inline)) static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) { - switch (hw->sr.stretch_cause) - { + switch (hw->sr.stretch_cause) { case 0: *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; break; @@ -628,14 +627,11 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs to be writen - * - * @return None. */ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr; for (int i = 0; i < len; i++) { - fifo_addr[i + ram_offset] = ptr[i]; + hw->txfifo_mem[i + ram_offset] = ptr[i]; } } @@ -646,15 +642,11 @@ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, co * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs read - * - * @return None */ static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr; - for (int i = 0; i < len; i++) { - ptr[i] = fifo_addr[i + ram_offset]; + ptr[i] = hw->rxfifo_mem[i + ram_offset]; } } diff --git a/components/hal/esp32h2/include/hal/i2c_ll.h b/components/hal/esp32h2/include/hal/i2c_ll.h index 1ed9ecddc0ac..d6833dca44e7 100644 --- a/components/hal/esp32h2/include/hal/i2c_ll.h +++ b/components/hal/esp32h2/include/hal/i2c_ll.h @@ -89,7 +89,7 @@ typedef enum { */ static inline void i2c_ll_master_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal) { - uint32_t clkm_div = source_clk / (bus_freq * 1024) +1; + uint32_t clkm_div = source_clk / (bus_freq * 1024) + 1; uint32_t sclk_freq = source_clk / clkm_div; uint32_t half_cycle = sclk_freq / bus_freq / 2; //SCL @@ -98,7 +98,7 @@ static inline void i2c_ll_master_cal_bus_clk(uint32_t source_clk, uint32_t bus_f // default, scl_wait_high < scl_high // Make 80KHz as a boundary here, because when working at lower frequency, too much scl_wait_high will faster the frequency // according to some hardware behaviors. - clk_cal->scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); + clk_cal->scl_wait_high = (bus_freq >= 80 * 1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high; clk_cal->sda_hold = half_cycle / 4; clk_cal->sda_sample = half_cycle / 2; @@ -306,8 +306,7 @@ static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_e __attribute__((always_inline)) static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) { - switch (hw->sr.stretch_cause) - { + switch (hw->sr.stretch_cause) { case 0: *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; break; @@ -595,7 +594,7 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h __attribute__((always_inline)) static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len) { - for (int i = 0; i< len; i++) { + for (int i = 0; i < len; i++) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]); } } @@ -612,7 +611,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_ __attribute__((always_inline)) static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) { - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->data, fifo_rdata); } } @@ -624,14 +623,11 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs to be writen - * - * @return None. */ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr; for (int i = 0; i < len; i++) { - fifo_addr[i + ram_offset] = ptr[i]; + hw->txfifo_mem[i + ram_offset] = ptr[i]; } } @@ -642,15 +638,11 @@ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, co * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs read - * - * @return None */ static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr; - for (int i = 0; i < len; i++) { - ptr[i] = fifo_addr[i + ram_offset]; + ptr[i] = hw->rxfifo_mem[i + ram_offset]; } } diff --git a/components/hal/esp32p4/include/hal/i2c_ll.h b/components/hal/esp32p4/include/hal/i2c_ll.h index 5888db147ea1..5983c5a930dd 100644 --- a/components/hal/esp32p4/include/hal/i2c_ll.h +++ b/components/hal/esp32p4/include/hal/i2c_ll.h @@ -94,7 +94,7 @@ typedef enum { */ static inline void i2c_ll_master_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal) { - uint32_t clkm_div = source_clk / (bus_freq * 1024) +1; + uint32_t clkm_div = source_clk / (bus_freq * 1024) + 1; uint32_t sclk_freq = source_clk / clkm_div; uint32_t half_cycle = sclk_freq / bus_freq / 2; //SCL @@ -103,7 +103,7 @@ static inline void i2c_ll_master_cal_bus_clk(uint32_t source_clk, uint32_t bus_f // default, scl_wait_high < scl_high // Make 80KHz as a boundary here, because when working at lower frequency, too much scl_wait_high will faster the frequency // according to some hardware behaviors. - clk_cal->scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); + clk_cal->scl_wait_high = (bus_freq >= 80 * 1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high; clk_cal->sda_hold = half_cycle / 4; clk_cal->sda_sample = half_cycle / 2; @@ -142,7 +142,7 @@ static inline void i2c_ll_update(i2c_dev_t *hw) static inline void i2c_ll_master_set_bus_timing(i2c_dev_t *hw, i2c_hal_clk_config_t *bus_cfg) { if (hw == &I2C0) { - HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl10, reg_i2c0_clk_div_num, bus_cfg->clkm_div - 1); + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl10, reg_i2c0_clk_div_num, bus_cfg->clkm_div - 1); HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl10, reg_i2c0_clk_div_numerator, 0); HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.peri_clk_ctrl10, reg_i2c0_clk_div_denominator, 0); } else if (hw == &I2C1) { @@ -581,7 +581,7 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h __attribute__((always_inline)) static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len) { - for (int i = 0; i< len; i++) { + for (int i = 0; i < len; i++) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]); } } @@ -598,7 +598,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_ __attribute__((always_inline)) static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) { - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->data, fifo_rdata); } } @@ -610,14 +610,11 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs to be writen - * - * @return None. */ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr; for (int i = 0; i < len; i++) { - fifo_addr[i + ram_offset] = ptr[i]; + hw->txfifo_mem[i + ram_offset] = ptr[i]; } } @@ -628,15 +625,11 @@ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, co * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs read - * - * @return None */ static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr; - for (int i = 0; i < len; i++) { - ptr[i] = fifo_addr[i + ram_offset]; + ptr[i] = hw->rxfifo_mem[i + ram_offset]; } } @@ -748,9 +741,9 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c { // src_clk : (1) for RTC_CLK, (0) for XTAL if (hw == &I2C0) { - HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c0_clk_src_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1: 0; + HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c0_clk_src_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0; } else if (hw == &I2C1) { - HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c1_clk_src_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1: 0; + HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c1_clk_src_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0; } else if (hw == &LP_I2C) { // Do nothing return; @@ -835,7 +828,6 @@ static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev) return &dev->int_status; } - /** * @brief Enable I2C slave clock stretch. * diff --git a/components/hal/esp32s3/include/hal/i2c_ll.h b/components/hal/esp32s3/include/hal/i2c_ll.h index 374c8c6e0458..b747db00097f 100644 --- a/components/hal/esp32s3/include/hal/i2c_ll.h +++ b/components/hal/esp32s3/include/hal/i2c_ll.h @@ -88,7 +88,7 @@ typedef enum { */ static inline void i2c_ll_master_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal) { - uint32_t clkm_div = source_clk / (bus_freq * 1024) +1; + uint32_t clkm_div = source_clk / (bus_freq * 1024) + 1; uint32_t sclk_freq = source_clk / clkm_div; uint32_t half_cycle = sclk_freq / bus_freq / 2; //SCL @@ -97,7 +97,7 @@ static inline void i2c_ll_master_cal_bus_clk(uint32_t source_clk, uint32_t bus_f // default, scl_wait_high < scl_high // Make 80KHz as a boundary here, because when working at lower frequency, too much scl_wait_high will faster the frequency // according to some hardware behaviors. - clk_cal->scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); + clk_cal->scl_wait_high = (bus_freq >= 80 * 1000) ? (half_cycle / 2 - 2) : (half_cycle / 4); clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high; clk_cal->sda_hold = half_cycle / 4; clk_cal->sda_sample = half_cycle / 2; @@ -304,8 +304,7 @@ static inline void i2c_ll_slave_broadcast_enable(i2c_dev_t *hw, bool broadcast_e __attribute__((always_inline)) static inline void i2c_ll_slave_get_stretch_cause(i2c_dev_t *hw, i2c_slave_stretch_cause_t *stretch_cause) { - switch (hw->sr.stretch_cause) - { + switch (hw->sr.stretch_cause) { case 0: *stretch_cause = I2C_SLAVE_STRETCH_CAUSE_ADDRESS_MATCH; break; @@ -593,7 +592,7 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h __attribute__((always_inline)) static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len) { - for (int i = 0; i< len; i++) { + for (int i = 0; i < len; i++) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]); } } @@ -610,7 +609,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_ __attribute__((always_inline)) static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) { - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->data, fifo_rdata); } } @@ -622,14 +621,11 @@ static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len) * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs to be writen - * - * @return None. */ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, const uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->txfifo_start_addr; for (int i = 0; i < len; i++) { - fifo_addr[i + ram_offset] = ptr[i]; + hw->txfifo_mem[i + ram_offset] = ptr[i]; } } @@ -640,15 +636,11 @@ static inline void i2c_ll_write_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, co * @param ram_offset Offset value of I2C RAM. * @param ptr Pointer to data buffer * @param len Amount of data needs read - * - * @return None */ static inline void i2c_ll_read_by_nonfifo(i2c_dev_t *hw, uint8_t ram_offset, uint8_t *ptr, uint8_t len) { - uint32_t *fifo_addr = (uint32_t *)&hw->rxfifo_start_addr; - for (int i = 0; i < len; i++) { - ptr[i] = fifo_addr[i + ram_offset]; + ptr[i] = hw->rxfifo_mem[i + ram_offset]; } } diff --git a/components/soc/esp32c3/include/soc/i2c_struct.h b/components/soc/esp32c3/include/soc/i2c_struct.h index ccd5fdb5b05c..1009fedd6e07 100644 --- a/components/soc/esp32c3/include/soc/i2c_struct.h +++ b/components/soc/esp32c3/include/soc/i2c_struct.h @@ -1,16 +1,8 @@ -// Copyright 2020 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _SOC_I2C_STRUCT_H_ #define _SOC_I2C_STRUCT_H_ @@ -363,39 +355,8 @@ typedef volatile struct i2c_dev_s { uint32_t reserved_f4; uint32_t date; uint32_t reserved_fc; - uint32_t txfifo_start_addr; - uint32_t reserved_104; - uint32_t reserved_108; - uint32_t reserved_10c; - uint32_t reserved_110; - uint32_t reserved_114; - uint32_t reserved_118; - uint32_t reserved_11c; - uint32_t reserved_120; - uint32_t reserved_124; - uint32_t reserved_128; - uint32_t reserved_12c; - uint32_t reserved_130; - uint32_t reserved_134; - uint32_t reserved_138; - uint32_t reserved_13c; - uint32_t reserved_140; - uint32_t reserved_144; - uint32_t reserved_148; - uint32_t reserved_14c; - uint32_t reserved_150; - uint32_t reserved_154; - uint32_t reserved_158; - uint32_t reserved_15c; - uint32_t reserved_160; - uint32_t reserved_164; - uint32_t reserved_168; - uint32_t reserved_16c; - uint32_t reserved_170; - uint32_t reserved_174; - uint32_t reserved_178; - uint32_t reserved_17c; - uint32_t rxfifo_start_addr; + uint32_t txfifo_mem[32]; + uint32_t rxfifo_mem[32]; } i2c_dev_t; extern i2c_dev_t I2C0; #ifdef __cplusplus diff --git a/components/soc/esp32c6/include/soc/i2c_struct.h b/components/soc/esp32c6/include/soc/i2c_struct.h index e6617dcf5e46..dce4371af420 100644 --- a/components/soc/esp32c6/include/soc/i2c_struct.h +++ b/components/soc/esp32c6/include/soc/i2c_struct.h @@ -948,34 +948,6 @@ typedef union { } i2c_date_reg_t; -/** Group: Address register */ -/** Type of txfifo_start_addr register - * I2C TXFIFO base address register - */ -typedef union { - struct { - /** txfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * This is the I2C txfifo first address. - */ - uint32_t txfifo_start_addr:32; - }; - uint32_t val; -} i2c_txfifo_start_addr_reg_t; - -/** Type of rxfifo_start_addr register - * I2C RXFIFO base address register - */ -typedef union { - struct { - /** rxfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * This is the I2C rxfifo first address. - */ - uint32_t rxfifo_start_addr:32; - }; - uint32_t val; -} i2c_rxfifo_start_addr_reg_t; - - typedef struct i2c_dev_t { volatile i2c_scl_low_period_reg_t scl_low_period; volatile i2c_ctr_reg_t ctr; @@ -1007,16 +979,15 @@ typedef struct i2c_dev_t { uint32_t reserved_088[28]; volatile i2c_date_reg_t date; uint32_t reserved_0fc; - volatile i2c_txfifo_start_addr_reg_t txfifo_start_addr; - uint32_t reserved_104[31]; - volatile i2c_rxfifo_start_addr_reg_t rxfifo_start_addr; + volatile uint32_t txfifo_mem[32]; + volatile uint32_t rxfifo_mem[32]; } i2c_dev_t; extern i2c_dev_t I2C0; extern i2c_dev_t LP_I2C; #ifndef __cplusplus -_Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); +_Static_assert(sizeof(i2c_dev_t) == 0x200, "Invalid size of i2c_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32h2/include/soc/i2c_struct.h b/components/soc/esp32h2/include/soc/i2c_struct.h index c0d20904aa01..eec5081e80a6 100644 --- a/components/soc/esp32h2/include/soc/i2c_struct.h +++ b/components/soc/esp32h2/include/soc/i2c_struct.h @@ -948,34 +948,6 @@ typedef union { } i2c_date_reg_t; -/** Group: Address register */ -/** Type of txfifo_start_addr register - * I2C TXFIFO base address register - */ -typedef union { - struct { - /** txfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * This is the I2C txfifo first address. - */ - uint32_t txfifo_start_addr:32; - }; - uint32_t val; -} i2c_txfifo_start_addr_reg_t; - -/** Type of rxfifo_start_addr register - * I2C RXFIFO base address register - */ -typedef union { - struct { - /** rxfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * This is the I2C rxfifo first address. - */ - uint32_t rxfifo_start_addr:32; - }; - uint32_t val; -} i2c_rxfifo_start_addr_reg_t; - - typedef struct i2c_dev_t { volatile i2c_scl_low_period_reg_t scl_low_period; volatile i2c_ctr_reg_t ctr; @@ -1007,16 +979,15 @@ typedef struct i2c_dev_t { uint32_t reserved_088[28]; volatile i2c_date_reg_t date; uint32_t reserved_0fc; - volatile i2c_txfifo_start_addr_reg_t txfifo_start_addr; - uint32_t reserved_104[31]; - volatile i2c_rxfifo_start_addr_reg_t rxfifo_start_addr; + volatile uint32_t txfifo_mem[32]; + volatile uint32_t rxfifo_mem[32]; } i2c_dev_t; extern i2c_dev_t I2C0; extern i2c_dev_t I2C1; #ifndef __cplusplus -_Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); +_Static_assert(sizeof(i2c_dev_t) == 0x200, "Invalid size of i2c_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/include/soc/i2c_struct.h b/components/soc/esp32p4/include/soc/i2c_struct.h index 876eba6a7054..747686285a65 100644 --- a/components/soc/esp32p4/include/soc/i2c_struct.h +++ b/components/soc/esp32p4/include/soc/i2c_struct.h @@ -1047,34 +1047,6 @@ typedef union { } i2c_date_reg_t; -/** Group: Address register */ -/** Type of txfifo_start_addr register - * I2C TXFIFO base address register - */ -typedef union { - struct { - /** txfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * Represents the I2C txfifo first address. - */ - uint32_t txfifo_start_addr:32; - }; - uint32_t val; -} i2c_txfifo_start_addr_reg_t; - -/** Type of rxfifo_start_addr register - * I2C RXFIFO base address register - */ -typedef union { - struct { - /** rxfifo_start_addr : HRO; bitpos: [31:0]; default: 0; - * Represents the I2C rxfifo first address. - */ - uint32_t rxfifo_start_addr:32; - }; - uint32_t val; -} i2c_rxfifo_start_addr_reg_t; - - typedef struct { volatile i2c_scl_low_period_reg_t scl_low_period; volatile i2c_ctr_reg_t ctr; @@ -1106,9 +1078,8 @@ typedef struct { uint32_t reserved_088[28]; volatile i2c_date_reg_t date; uint32_t reserved_0fc; - volatile i2c_txfifo_start_addr_reg_t txfifo_start_addr; - uint32_t reserved_104[31]; - volatile i2c_rxfifo_start_addr_reg_t rxfifo_start_addr; + volatile uint32_t txfifo_mem[32]; + volatile uint32_t rxfifo_mem[32]; } i2c_dev_t; extern i2c_dev_t I2C0; @@ -1116,7 +1087,7 @@ extern i2c_dev_t I2C1; extern i2c_dev_t LP_I2C; #ifndef __cplusplus -_Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); +_Static_assert(sizeof(i2c_dev_t) == 0x200, "Invalid size of i2c_dev_t structure"); #endif #ifdef __cplusplus diff --git a/components/soc/esp32s3/include/soc/i2c_struct.h b/components/soc/esp32s3/include/soc/i2c_struct.h index 513f55770faa..807ffa508d14 100644 --- a/components/soc/esp32s3/include/soc/i2c_struct.h +++ b/components/soc/esp32s3/include/soc/i2c_struct.h @@ -941,35 +941,6 @@ typedef union { uint32_t val; } i2c_date_reg_t; - -/** Group: Address register */ -/** Type of txfifo_start_addr register - * I2C TXFIFO base address register - */ -typedef union { - struct { - /** txfifo_start_addr : RO; bitpos: [31:0]; default: 0; - * This is the I2C txfifo first address. - */ - uint32_t txfifo_start_addr:32; - }; - uint32_t val; -} i2c_txfifo_start_addr_reg_t; - -/** Type of rxfifo_start_addr register - * I2C RXFIFO base address register - */ -typedef union { - struct { - /** rxfifo_start_addr : RO; bitpos: [31:0]; default: 0; - * This is the I2C rxfifo first address. - */ - uint32_t rxfifo_start_addr:32; - }; - uint32_t val; -} i2c_rxfifo_start_addr_reg_t; - - typedef struct { volatile i2c_scl_low_period_reg_t scl_low_period; volatile i2c_ctr_reg_t ctr; @@ -1001,16 +972,15 @@ typedef struct { uint32_t reserved_088[28]; volatile i2c_date_reg_t date; uint32_t reserved_0fc; - volatile i2c_txfifo_start_addr_reg_t txfifo_start_addr; - uint32_t reserved_104[31]; - volatile i2c_rxfifo_start_addr_reg_t rxfifo_start_addr; + volatile uint32_t txfifo_mem[32]; + volatile uint32_t rxfifo_mem[32]; } i2c_dev_t; extern i2c_dev_t I2C0; extern i2c_dev_t I2C1; #ifndef __cplusplus -_Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure"); +_Static_assert(sizeof(i2c_dev_t) == 0x200, "Invalid size of i2c_dev_t structure"); #endif #ifdef __cplusplus diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index d50a18ca49ce..f7cb594c324a 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -667,7 +667,6 @@ components/soc/esp32c3/include/soc/fe_reg.h components/soc/esp32c3/include/soc/gpio_reg.h components/soc/esp32c3/include/soc/gpio_struct.h components/soc/esp32c3/include/soc/i2c_reg.h -components/soc/esp32c3/include/soc/i2c_struct.h components/soc/esp32c3/include/soc/interrupt_core0_reg.h components/soc/esp32c3/include/soc/ledc_reg.h components/soc/esp32c3/include/soc/nrx_reg.h From 04d874d6a3de668f31319fa97edac69c08c9b774 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Thu, 26 Oct 2023 10:59:56 +0530 Subject: [PATCH 052/161] fix(wpa_supplicant): implement sha1_finish for fastpbkdf2 --- .../esp_supplicant/src/crypto/fastpbkdf2.c | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c index 8ac2abbe5688..24fc706c638c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c @@ -304,6 +304,65 @@ static int mbedtls_sha1_init_start(mbedtls_sha1_context *ctx) return 0; } +#ifndef MBEDTLS_SHA1_ALT +static int sha1_finish(mbedtls_sha1_context *ctx, + unsigned char output[20]) +{ + int ret = -1; + uint32_t used; + uint32_t high, low; + + /* + * Add padding: 0x80 then 0x00 until 8 bytes remain for the length + */ + used = ctx->MBEDTLS_PRIVATE(total)[0] & 0x3F; + + ctx->MBEDTLS_PRIVATE(buffer)[used++] = 0x80; + + if (used <= 56) { + /* Enough room for padding + length in current block */ + memset(ctx->MBEDTLS_PRIVATE(buffer) + used, 0, 56 - used); + } else { + /* We'll need an extra block */ + memset(ctx->MBEDTLS_PRIVATE(buffer) + used, 0, 64 - used); + + if ((ret = mbedtls_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) { + goto exit; + } + + memset(ctx->MBEDTLS_PRIVATE(buffer), 0, 56); + } + + /* + * Add message length + */ + high = (ctx->MBEDTLS_PRIVATE(total)[0] >> 29) + | (ctx->MBEDTLS_PRIVATE(total)[1] << 3); + low = (ctx->MBEDTLS_PRIVATE(total)[0] << 3); + + write32_be(high, ctx->MBEDTLS_PRIVATE(buffer) + 56); + write32_be(low, ctx->MBEDTLS_PRIVATE(buffer) + 60); + + if ((ret = mbedtls_internal_sha1_process(ctx, ctx->MBEDTLS_PRIVATE(buffer))) != 0) { + goto exit; + } + + /* + * Output final state + */ + write32_be(ctx->MBEDTLS_PRIVATE(state)[0], output); + write32_be(ctx->MBEDTLS_PRIVATE(state)[1], output + 4); + write32_be(ctx->MBEDTLS_PRIVATE(state)[2], output + 8); + write32_be(ctx->MBEDTLS_PRIVATE(state)[3], output + 12); + write32_be(ctx->MBEDTLS_PRIVATE(state)[4], output + 16); + + ret = 0; + +exit: + return ret; +} +#endif + DECL_PBKDF2(sha1, // _name 64, // _blocksz 20, // _hashsz @@ -311,7 +370,11 @@ DECL_PBKDF2(sha1, // _name mbedtls_sha1_init_start, // _init mbedtls_sha1_update, // _update mbedtls_internal_sha1_process, // _xform +#if defined(MBEDTLS_SHA1_ALT) mbedtls_sha1_finish, // _final +#else + sha1_finish, // _final +#endif sha1_cpy, // _xcpy sha1_extract, // _xtract sha1_xor) // _xxor From d9d6f5a17a6ae19b4d3012d265de8442ec3e3234 Mon Sep 17 00:00:00 2001 From: wanlei Date: Thu, 19 Oct 2023 14:43:17 +0800 Subject: [PATCH 053/161] feat(twai): support legacy twai(can) driver for esp32p4 --- components/driver/test_apps/twai/README.md | 4 +- .../test_apps/twai/main/test_app_main.c | 35 +- .../twai/main/test_twai_interactive.c | 32 +- .../driver/test_apps/twai/pytest_twai.py | 6 +- components/driver/twai/twai.c | 14 + components/hal/esp32/include/hal/twai_ll.h | 12 +- components/hal/esp32c3/include/hal/twai_ll.h | 12 +- components/hal/esp32c6/include/hal/twai_ll.h | 12 +- components/hal/esp32h2/include/hal/twai_ll.h | 10 +- .../hal/esp32p4/include/hal/clk_gate_ll.h | 18 - components/hal/esp32p4/include/hal/twai_ll.h | 816 ++++++++++++++++++ components/hal/esp32s2/include/hal/twai_ll.h | 12 +- components/hal/esp32s3/include/hal/twai_ll.h | 12 +- components/hal/twai_hal.c | 14 +- .../esp32p4/include/soc/Kconfig.soc_caps.in | 6 +- .../soc/esp32p4/include/soc/clk_tree_defs.h | 15 + .../soc/esp32p4/include/soc/gpio_sig_map.h | 24 +- .../esp32p4/include/soc/hp_sys_clkrst_reg.h | 60 +- .../include/soc/hp_sys_clkrst_struct.h | 24 +- .../soc/esp32p4/include/soc/interrupts.h | 6 +- components/soc/esp32p4/include/soc/soc_caps.h | 4 +- .../soc/esp32p4/include/soc/twai_struct.h | 249 +----- components/soc/esp32p4/interrupts.c | 6 +- components/soc/esp32p4/twai_periph.c | 30 +- docs/docs_not_updated/esp32p4.txt | 1 - docs/en/api-reference/peripherals/twai.rst | 2 +- .../twai/twai_alert_and_recovery/README.md | 4 +- .../twai_alert_and_recovery_example_main.c | 16 +- .../peripherals/twai/twai_network/README.md | 4 +- .../peripherals/twai/twai_self_test/README.md | 4 +- 30 files changed, 1061 insertions(+), 403 deletions(-) create mode 100644 components/hal/esp32p4/include/hal/twai_ll.h diff --git a/components/driver/test_apps/twai/README.md b/components/driver/test_apps/twai/README.md index 2eccd3e551ac..bf6a3f380d30 100644 --- a/components/driver/test_apps/twai/README.md +++ b/components/driver/test_apps/twai/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # Enable Socket CAN Device with bitrate 250Kbps diff --git a/components/driver/test_apps/twai/main/test_app_main.c b/components/driver/test_apps/twai/main/test_app_main.c index 8d0972047f5f..5743bdfde588 100644 --- a/components/driver/test_apps/twai/main/test_app_main.c +++ b/components/driver/test_apps/twai/main/test_app_main.c @@ -1,38 +1,25 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "unity.h" -#include "unity_test_runner.h" +#include "unity_test_utils.h" #include "esp_heap_caps.h" // Some resources are lazy allocated in the TWAI driver, the threshold is left for that case -#define TEST_MEMORY_LEAK_THRESHOLD (-200) - -static size_t before_free_8bit; -static size_t before_free_32bit; - -static void check_leak(size_t before_free, size_t after_free, const char *type) -{ - ssize_t delta = after_free - before_free; - printf("MALLOC_CAP_%s: Before %u bytes free, After %u bytes free (delta %d)\n", type, before_free, after_free, delta); - TEST_ASSERT_MESSAGE(delta >= TEST_MEMORY_LEAK_THRESHOLD, "memory leak"); -} +#define TEST_MEMORY_LEAK_THRESHOLD (200) void setUp(void) { - before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + unity_utils_record_free_mem(); } void tearDown(void) { - size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); - check_leak(before_free_8bit, after_free_8bit, "8BIT"); - check_leak(before_free_32bit, after_free_32bit, "32BIT"); + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD); } void app_main(void) @@ -42,10 +29,10 @@ void app_main(void) // | | \ \ /\ / / _ \ | | | |/ _ \/ __| __| // | | \ V V / ___ \ | | | | __/\__ \ |_ // |_| \_/\_/_/ \_\___| |_|\___||___/\__| - printf(" _______ ___ ___ _____ _\r\n"); - printf("|_ _\\ \\ / / \\ |_ _| |_ _|__ ___| |_\r\n"); - printf(" | | \\ \\ /\\ / / _ \\ | | | |/ _ \\/ __| __|\r\n"); - printf(" | | \\ V V / ___ \\ | | | | __/\\__ \\ |_\r\n"); - printf(" |_| \\_/\\_/_/ \\_\\___| |_|\\___||___/\\__|\r\n"); + printf(" _______ ___ ___ _____ _\n"); + printf("|_ _\\ \\ / / \\ |_ _| |_ _|__ ___| |_\n"); + printf(" | | \\ \\ /\\ / / _ \\ | | | |/ _ \\/ __| __|\n"); + printf(" | | \\ V V / ___ \\ | | | | __/\\__ \\ |_\n"); + printf(" |_| \\_/\\_/_/ \\_\\___| |_|\\___||___/\\__|\n"); unity_run_menu(); } diff --git a/components/driver/test_apps/twai/main/test_twai_interactive.c b/components/driver/test_apps/twai/main/test_twai_interactive.c index d72a0e0847b9..88b74af55bb9 100644 --- a/components/driver/test_apps/twai/main/test_twai_interactive.c +++ b/components/driver/test_apps/twai/main/test_twai_interactive.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,7 @@ #include "unity_test_utils.h" #include "driver/twai.h" #include "soc/soc_caps.h" -#include "esp_attr.h" +#include "esp_log.h" #if CONFIG_TWAI_ISR_IN_IRAM static void IRAM_ATTR test_delay_post_cache_disable(void *args) @@ -37,7 +37,7 @@ TEST_CASE("twai_listen_only", "[twai]") TEST_ESP_OK(twai_start()); #if CONFIG_TWAI_ISR_IN_IRAM - printf("disable flash cache and check if we can still receive the frame\r\n"); + printf("disable flash cache and check if we can still receive the frame\n"); for (int i = 0; i < 100; i++) { unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL); } @@ -48,9 +48,8 @@ TEST_CASE("twai_listen_only", "[twai]") TEST_ESP_OK(twai_receive(&rx_msg, portMAX_DELAY)); TEST_ASSERT_EQUAL(0x123, rx_msg.identifier); - for (int i = 0; i < rx_msg.data_length_code; i++) { - TEST_ASSERT_EQUAL_HEX8(expected_data[i], rx_msg.data[i]); - } + ESP_LOG_BUFFER_HEX("rx", rx_msg.data, rx_msg.data_length_code); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, rx_msg.data, rx_msg.data_length_code); TEST_ESP_OK(twai_stop()); TEST_ESP_OK(twai_driver_uninstall()); @@ -58,11 +57,13 @@ TEST_CASE("twai_listen_only", "[twai]") TEST_CASE("twai_remote_request", "[twai]") { + twai_handle_t bus_handle; twai_timing_config_t t_config = TWAI_TIMING_CONFIG_250KBITS(); twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(0, 2, TWAI_MODE_NORMAL); - TEST_ESP_OK(twai_driver_install(&g_config, &t_config, &f_config)); - TEST_ESP_OK(twai_start()); + g_config.controller_id = 2; + TEST_ESP_OK(twai_driver_install_v2(&g_config, &t_config, &f_config, &bus_handle)); + TEST_ESP_OK(twai_start_v2(bus_handle)); twai_message_t req_msg = { .identifier = 0x6688, @@ -70,16 +71,17 @@ TEST_CASE("twai_remote_request", "[twai]") .rtr = true, // remote request .extd = true,// extended ID }; - TEST_ESP_OK(twai_transmit(&req_msg, portMAX_DELAY)); + TEST_ESP_OK(twai_transmit_v2(bus_handle, &req_msg, portMAX_DELAY)); + ESP_LOGI("TWAI", "send remote frame"); uint8_t expected_data[8] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}; twai_message_t res_msg; - TEST_ESP_OK(twai_receive(&res_msg, portMAX_DELAY)); + TEST_ESP_OK(twai_receive_v2(bus_handle, &res_msg, portMAX_DELAY)); + ESP_LOGI("TWAI", "receive with id %lx\n", res_msg.identifier); TEST_ASSERT_EQUAL(0x6688, res_msg.identifier); - for (int i = 0; i < 8; i++) { - TEST_ASSERT_EQUAL_HEX8(expected_data[i], res_msg.data[i]); - } + ESP_LOG_BUFFER_HEX("rx", res_msg.data, res_msg.data_length_code); + TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_data, res_msg.data, res_msg.data_length_code); - TEST_ESP_OK(twai_stop()); - TEST_ESP_OK(twai_driver_uninstall()); + TEST_ESP_OK(twai_stop_v2(bus_handle)); + TEST_ESP_OK(twai_driver_uninstall_v2(bus_handle)); } diff --git a/components/driver/test_apps/twai/pytest_twai.py b/components/driver/test_apps/twai/pytest_twai.py index 454511f2a623..d3d8ddeca352 100644 --- a/components/driver/test_apps/twai/pytest_twai.py +++ b/components/driver/test_apps/twai/pytest_twai.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import logging @@ -15,6 +15,7 @@ @pytest.mark.esp32h2 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -41,6 +42,7 @@ def fixture_create_socket_can() -> Bus: @pytest.mark.esp32h2 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.skip(reason='Runner not set up yet') @pytest.mark.parametrize( 'config', @@ -73,6 +75,7 @@ def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None: @pytest.mark.esp32h2 @pytest.mark.esp32s2 @pytest.mark.esp32s3 +@pytest.mark.esp32p4 @pytest.mark.skip(reason='Runner not set up yet') @pytest.mark.parametrize( 'config', @@ -101,5 +104,6 @@ def test_twai_remote_request(dut: Dut, socket_can: Bus) -> None: data=[0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80], ) socket_can.send(reply, timeout=0.2) + print('send', reply) dut.expect_unity_test_output() diff --git a/components/driver/twai/twai.c b/components/driver/twai/twai.c index 976a4dc33663..eb0ebfcd3a14 100644 --- a/components/driver/twai/twai.c +++ b/components/driver/twai/twai.c @@ -58,6 +58,12 @@ #define TWAI_RCC_ATOMIC() #endif +#if SOC_PERIPH_CLK_CTRL_SHARED +#define TWAI_PERI_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define TWAI_PERI_ATOMIC() +#endif + /* ------------------ Typedefs, structures, and variables ------------------- */ //Control structure for TWAI driver @@ -453,6 +459,11 @@ esp_err_t twai_driver_install_v2(const twai_general_config_t *g_config, const tw twai_ll_enable_bus_clock(controller_id, true); twai_ll_reset_register(controller_id); } + TWAI_PERI_ATOMIC() { + //Enable functional clock + twai_ll_set_clock_source(p_twai_obj->controller_id, clk_src); + twai_ll_enable_clock(p_twai_obj->controller_id, true); + } //Initialize TWAI HAL layer twai_hal_config_t hal_config = { @@ -514,6 +525,9 @@ esp_err_t twai_driver_uninstall_v2(twai_handle_t handle) //Clear registers by reading twai_hal_deinit(&p_twai_obj->hal); + TWAI_PERI_ATOMIC() { + twai_ll_enable_clock(controller_id, false); + } TWAI_RCC_ATOMIC() { twai_ll_enable_bus_clock(controller_id, false); } diff --git a/components/hal/esp32/include/hal/twai_ll.h b/components/hal/esp32/include/hal/twai_ll.h index 8c35c5e5bafd..6fc14529f66c 100644 --- a/components/hal/esp32/include/hal/twai_ll.h +++ b/components/hal/esp32/include/hal/twai_ll.h @@ -194,25 +194,25 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { - (void)hw; + (void)group_id; } /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { - (void)hw; + (void)group_id; HAL_ASSERT(clk_src == TWAI_CLK_SRC_APB); } diff --git a/components/hal/esp32c3/include/hal/twai_ll.h b/components/hal/esp32c3/include/hal/twai_ll.h index 3283425dfef6..d2d713f206a2 100644 --- a/components/hal/esp32c3/include/hal/twai_ll.h +++ b/components/hal/esp32c3/include/hal/twai_ll.h @@ -124,25 +124,25 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { - (void)hw; + (void)group_id; } /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { - (void)hw; + (void)group_id; HAL_ASSERT(clk_src == TWAI_CLK_SRC_APB); } diff --git a/components/hal/esp32c6/include/hal/twai_ll.h b/components/hal/esp32c6/include/hal/twai_ll.h index b70f92d62e96..f6a893ea1ded 100644 --- a/components/hal/esp32c6/include/hal/twai_ll.h +++ b/components/hal/esp32c6/include/hal/twai_ll.h @@ -123,13 +123,13 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { - if (hw == &TWAI0) { + if (group_id == 0) { PCR.twai0_func_clk_conf.twai0_func_clk_en = en; } else { PCR.twai1_func_clk_conf.twai1_func_clk_en = en; @@ -139,11 +139,11 @@ static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { uint32_t clk_id = 0; bool valid = true; @@ -158,7 +158,7 @@ static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t } if (valid) { - if (hw == &TWAI0) { + if (group_id == 0) { PCR.twai0_func_clk_conf.twai0_func_clk_sel = clk_id; } else { PCR.twai1_func_clk_conf.twai1_func_clk_sel = clk_id; diff --git a/components/hal/esp32h2/include/hal/twai_ll.h b/components/hal/esp32h2/include/hal/twai_ll.h index e66bc0a27a16..653404fdb4f8 100644 --- a/components/hal/esp32h2/include/hal/twai_ll.h +++ b/components/hal/esp32h2/include/hal/twai_ll.h @@ -116,24 +116,26 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { + (void)group_id; PCR.twai0_func_clk_conf.twai0_func_clk_en = en; } /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { + (void)group_id; switch (clk_src) { case TWAI_CLK_SRC_DEFAULT: PCR.twai0_func_clk_conf.twai0_func_clk_sel = 0; diff --git a/components/hal/esp32p4/include/hal/clk_gate_ll.h b/components/hal/esp32p4/include/hal/clk_gate_ll.h index 324e16bbe725..b431dd9186e7 100644 --- a/components/hal/esp32p4/include/hal/clk_gate_ll.h +++ b/components/hal/esp32p4/include/hal/clk_gate_ll.h @@ -38,12 +38,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) return HP_SYS_CLKRST_REG_I2C1_APB_CLK_EN; case PERIPH_LCD_MODULE: return HP_SYS_CLKRST_REG_LCD_CLK_EN; - case PERIPH_TWAI0_MODULE: - return HP_SYS_CLKRST_REG_TWAI0_CLK_EN; - case PERIPH_TWAI1_MODULE: - return HP_SYS_CLKRST_REG_TWAI1_CLK_EN; - case PERIPH_TWAI2_MODULE: - return HP_SYS_CLKRST_REG_TWAI2_CLK_EN; case PERIPH_I3C_MODULE: return HP_SYS_CLKRST_REG_I3C_MST_CLK_EN; case PERIPH_CAM_MODULE: @@ -109,12 +103,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en return HP_SYS_CLKRST_REG_RST_EN_I2C0; case PERIPH_I2C1_MODULE: return HP_SYS_CLKRST_REG_RST_EN_I2C1; - case PERIPH_TWAI0_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_CAN0; - case PERIPH_TWAI1_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_CAN1; - case PERIPH_TWAI2_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_CAN2; case PERIPH_LCD_MODULE: return HP_SYS_CLKRST_REG_RST_EN_LCDCAM; case PERIPH_SARADC_MODULE: @@ -174,9 +162,6 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) return HP_SYS_CLKRST_SOC_CLK_CTRL2_REG; case PERIPH_LCD_MODULE: return HP_SYS_CLKRST_PERI_CLK_CTRL110_REG; - case PERIPH_TWAI0_MODULE: - case PERIPH_TWAI1_MODULE: - case PERIPH_TWAI2_MODULE: return HP_SYS_CLKRST_PERI_CLK_CTRL116_REG; case PERIPH_I3C_MODULE: case PERIPH_CAM_MODULE: @@ -221,9 +206,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) case PERIPH_I2C0_MODULE: case PERIPH_I2C1_MODULE: return HP_SYS_CLKRST_HP_RST_EN1_REG; - case PERIPH_TWAI0_MODULE: - case PERIPH_TWAI1_MODULE: - case PERIPH_TWAI2_MODULE: case PERIPH_CAM_MODULE: case PERIPH_SARADC_MODULE: case PERIPH_AES_MODULE: diff --git a/components/hal/esp32p4/include/hal/twai_ll.h b/components/hal/esp32p4/include/hal/twai_ll.h new file mode 100644 index 000000000000..7dc878ec0c4c --- /dev/null +++ b/components/hal/esp32p4/include/hal/twai_ll.h @@ -0,0 +1,816 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * 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 + ******************************************************************************/ + +// The Lowlevel layer for TWAI + +#pragma once + +#include +#include +#include +#include "esp_assert.h" +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/twai_types.h" +#include "soc/twai_struct.h" +#include "soc/hp_sys_clkrst_struct.h" + +#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI0) : \ + (controller_id == 1) ? (&TWAI1) : \ + (&TWAI2)) + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------- Defines and Typedefs --------------------------- */ + +#define TWAI_LL_STATUS_RBS (0x1 << 0) //Receive Buffer Status +#define TWAI_LL_STATUS_DOS (0x1 << 1) //Data Overrun Status +#define TWAI_LL_STATUS_TBS (0x1 << 2) //Transmit Buffer Status +#define TWAI_LL_STATUS_TCS (0x1 << 3) //Transmission Complete Status +#define TWAI_LL_STATUS_RS (0x1 << 4) //Receive Status +#define TWAI_LL_STATUS_TS (0x1 << 5) //Transmit Status +#define TWAI_LL_STATUS_ES (0x1 << 6) //Error Status +#define TWAI_LL_STATUS_BS (0x1 << 7) //Bus Status +#define TWAI_LL_STATUS_MS (0x1 << 8) //Miss Status + +#define TWAI_LL_INTR_RI (0x1 << 0) //Receive Interrupt +#define TWAI_LL_INTR_TI (0x1 << 1) //Transmit Interrupt +#define TWAI_LL_INTR_EI (0x1 << 2) //Error Interrupt +//Data overrun interrupt not supported in SW due to HW peculiarities +#define TWAI_LL_INTR_EPI (0x1 << 5) //Error Passive Interrupt +#define TWAI_LL_INTR_ALI (0x1 << 6) //Arbitration Lost Interrupt +#define TWAI_LL_INTR_BEI (0x1 << 7) //Bus Error Interrupt +#define TWAI_LL_INTR_BISI (0x1 << 8) //Bus Idle Status Interrupt + +/* + * The following frame structure has an NEARLY identical bit field layout to + * each byte of the TX buffer. This allows for formatting and parsing frames to + * be done outside of time critical regions (i.e., ISRs). All the ISR needs to + * do is to copy byte by byte to/from the TX/RX buffer. The two reserved bits in + * TX buffer are used in the frame structure to store the self_reception and + * single_shot flags which in turn indicate the type of transmission to execute. + */ +typedef union { + struct { + struct { + uint8_t dlc: 4; //Data length code (0 to 8) of the frame + uint8_t self_reception: 1; //This frame should be transmitted using self reception command + uint8_t single_shot: 1; //This frame should be transmitted using single shot command + uint8_t rtr: 1; //This frame is a remote transmission request + uint8_t frame_format: 1; //Format of the frame (1 = extended, 0 = standard) + }; + union { + struct { + uint8_t id[2]; //11 bit standard frame identifier + uint8_t data[8]; //Data bytes (0 to 8) + uint8_t reserved8[2]; + } standard; + struct { + uint8_t id[4]; //29 bit extended frame identifier + uint8_t data[8]; //Data bytes (0 to 8) + } extended; + }; + }; + uint8_t bytes[13]; +} __attribute__((packed)) twai_ll_frame_buffer_t; + +ESP_STATIC_ASSERT(sizeof(twai_ll_frame_buffer_t) == 13, "TX/RX buffer type should be 13 bytes"); + +/* ---------------------------- Reset and Clock Control ------------------------------ */ + +/** + * @brief Enable the bus clock for twai module + * + * @param group_id Group ID + * @param enable true to enable, false to disable + */ +static inline void twai_ll_enable_bus_clock(int group_id, bool enable) +{ + switch (group_id) + { + case 0: HP_SYS_CLKRST.soc_clk_ctrl2.reg_twai0_apb_clk_en = enable; break; + case 1: HP_SYS_CLKRST.soc_clk_ctrl2.reg_twai1_apb_clk_en = enable; break; + case 2: HP_SYS_CLKRST.soc_clk_ctrl2.reg_twai2_apb_clk_en = enable; break; + default: HAL_ASSERT(false); + } +} + +/// 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 twai_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; twai_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the twai module + * + * @param group_id Group ID + */ +static inline void twai_ll_reset_register(int group_id) +{ + switch (group_id) + { + case 0: HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai0 = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai0 = 0; + break; + case 1: HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai1 = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai1 = 0; + break; + case 2: HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai2 = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_twai2 = 0; + break; + default: HAL_ASSERT(false); + } +} + +/// 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 twai_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; twai_ll_reset_register(__VA_ARGS__) + +/* ---------------------------- Peripheral Control Register ----------------- */ + +/** + * @brief Enable TWAI module clock + * + * @param group_id Group ID + * @param en true to enable, false to disable + */ +__attribute__((always_inline)) +static inline void twai_ll_enable_clock(int group_id, bool en) +{ + switch (group_id) { + case 0: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai0_clk_en = en; break; + case 1: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai1_clk_en = en; break; + case 2: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai2_clk_en = en; break; + default: HAL_ASSERT(false); + } +} + +/// 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 twai_ll_enable_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; twai_ll_enable_clock(__VA_ARGS__) + +/** + * @brief Set clock source for TWAI module + * + * @param group_id Group ID + * @param clk_src Clock source + */ +__attribute__((always_inline)) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) +{ + uint32_t clk_id = 0; + + switch (clk_src) { + case TWAI_CLK_SRC_XTAL: clk_id = 0; break; +#if SOC_CLK_TREE_SUPPORTED + case TWAI_CLK_SRC_RC_FAST: clk_id = 1; break; +#endif + default: HAL_ASSERT(false); + } + + switch (group_id) { + case 0: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai0_clk_src_sel = clk_id; break; + case 1: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai1_clk_src_sel = clk_id; break; + case 2: HP_SYS_CLKRST.peri_clk_ctrl115.reg_twai2_clk_src_sel = clk_id; break; + default: HAL_ASSERT(false); + } +} + +/// 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 twai_ll_set_clock_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; twai_ll_set_clock_source(__VA_ARGS__) + +/* ---------------------------- Mode Register ------------------------------- */ +/** + * @brief Enter reset mode + * + * When in reset mode, the TWAI controller is effectively disconnected from the + * TWAI bus and will not participate in any bus activates. Reset mode is required + * in order to write the majority of configuration registers. + * + * @param hw Start address of the TWAI registers + * + * @note Reset mode is automatically entered on BUS OFF condition + */ +__attribute__((always_inline)) +static inline void twai_ll_enter_reset_mode(twai_dev_t *hw) +{ + hw->mode.reset_mode = 1; +} + +/** + * @brief Exit reset mode + * + * When not in reset mode, the TWAI controller will take part in bus activities + * (e.g., send/receive/acknowledge messages and error frames) depending on the + * operating mode. + * + * @param hw Start address of the TWAI registers + * + * @note Reset mode must be exit to initiate BUS OFF recovery + */ +__attribute__((always_inline)) +static inline void twai_ll_exit_reset_mode(twai_dev_t *hw) +{ + hw->mode.reset_mode = 0; +} + +/** + * @brief Check if in reset mode + * @param hw Start address of the TWAI registers + * @return true if in reset mode + */ +__attribute__((always_inline)) +static inline bool twai_ll_is_in_reset_mode(twai_dev_t *hw) +{ + return hw->mode.reset_mode; +} + +/** + * @brief Set operating mode of TWAI controller + * + * @param hw Start address of the TWAI registers + * @param mode Operating mode + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_mode(twai_dev_t *hw, twai_mode_t mode) +{ + if (mode == TWAI_MODE_NORMAL) { //Normal Operating mode + hw->mode.listen_only_mode = 0; + hw->mode.self_test_mode = 0; + } else if (mode == TWAI_MODE_NO_ACK) { //Self Test Mode (No Ack) + hw->mode.listen_only_mode = 0; + hw->mode.self_test_mode = 1; + } else if (mode == TWAI_MODE_LISTEN_ONLY) { //Listen Only Mode + hw->mode.listen_only_mode = 1; + hw->mode.self_test_mode = 0; + } +} + +/* --------------------------- Command Register ----------------------------- */ + +/** + * @brief Set TX command + * + * Setting the TX command will cause the TWAI controller to attempt to transmit + * the frame stored in the TX buffer. The TX buffer will be occupied (i.e., + * locked) until TX completes. + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_tx(twai_dev_t *hw) +{ + hw->cmd.tx_request = 1; +} + +/** + * @brief Set single shot TX command + * + * Similar to setting TX command, but the TWAI controller will not automatically + * retry transmission upon an error (e.g., due to an acknowledgement error). + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_tx_single_shot(twai_dev_t *hw) +{ + hw->cmd.val = 0x03; //Set cmd.tx_request and cmd.abort_tx simultaneously for single shot transmitting request +} + +/** + * @brief Aborts TX + * + * Frames awaiting TX will be aborted. Frames already being TX are not aborted. + * Transmission Complete Status bit is automatically set to 1. + * Similar to setting TX command, but the TWAI controller will not automatically + * retry transmission upon an error (e.g., due to acknowledge error). + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_abort_tx(twai_dev_t *hw) +{ + hw->cmd.abort_tx = 1; +} + +/** + * @brief Release RX buffer + * + * Rotates RX buffer to the next frame in the RX FIFO. + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_release_rx_buffer(twai_dev_t *hw) +{ + hw->cmd.release_buffer = 1; +} + +/** + * @brief Clear data overrun + * + * Clears the data overrun status bit + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_clear_data_overrun(twai_dev_t *hw) +{ + hw->cmd.clear_data_overrun = 1; +} + +/** + * @brief Set self reception single shot command + * + * Similar to setting TX command, but the TWAI controller also simultaneously + * receive the transmitted frame and is generally used for self testing + * purposes. The TWAI controller will not ACK the received message, so consider + * using the NO_ACK operating mode. + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_self_rx_request(twai_dev_t *hw) +{ + hw->cmd.self_rx_request = 1; +} + +/** + * @brief Set self reception request command + * + * Similar to setting the self reception request, but the TWAI controller will + * not automatically retry transmission upon an error (e.g., due to and + * acknowledgement error). + * + * @param hw Start address of the TWAI registers + * + * @note Transmit commands should be called last (i.e., after handling buffer + * release and clear data overrun) in order to prevent the other commands + * overwriting this latched TX bit with 0. + */ +__attribute__((always_inline)) +static inline void twai_ll_set_cmd_self_rx_single_shot(twai_dev_t *hw) +{ + hw->cmd.val = 0x12; //Set cmd.self_rx_request and cmd.abort_tx simultaneously for single shot self reception request +} + +/* --------------------------- Status Register ------------------------------ */ + +/** + * @brief Get all status bits + * + * @param hw Start address of the TWAI registers + * @return Status bits + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_status(twai_dev_t *hw) +{ + return hw->status.val; +} + +/** + * @brief Check if RX FIFO overrun status bit is set + * + * @param hw Start address of the TWAI registers + * @return Overrun status bit + */ +__attribute__((always_inline)) +static inline bool twai_ll_is_fifo_overrun(twai_dev_t *hw) +{ + return hw->status.status_overrun; +} + +/** + * @brief Check if previously TX was successful + * + * @param hw Start address of the TWAI registers + * @return Whether previous TX was successful + */ +__attribute__((always_inline)) +static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw) +{ + return hw->status.status_transmission_complete; +} + +/* -------------------------- Interrupt Register ---------------------------- */ + +/** + * @brief Get currently set interrupts + * + * Reading the interrupt registers will automatically clear all interrupts + * except for the Receive Interrupt. + * + * @param hw Start address of the TWAI registers + * @return Bit mask of set interrupts + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_and_clear_intrs(twai_dev_t *hw) +{ + return hw->interrupt_st.val; +} + +/* ----------------------- Interrupt Enable Register ------------------------ */ + +/** + * @brief Set which interrupts are enabled + * + * @param hw Start address of the TWAI registers + * @param Bit mask of interrupts to enable + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask) +{ + hw->interrupt_ena.val = intr_mask; +} + +/* ------------------------ Bus Timing Registers --------------------------- */ + +/** + * @brief Check if the brp value valid + * + * @param brp Bit rate prescaler value + * @return true or False + */ +__attribute__((always_inline)) +static inline bool twai_ll_check_brp_validation(uint32_t brp) +{ + bool valid = (brp >= SOC_TWAI_BRP_MIN) && (brp <= SOC_TWAI_BRP_MAX); + // should be an even number + valid = valid && !(brp & 0x01); + return valid; +} + +/** + * @brief Set bus timing + * + * @param hw Start address of the TWAI registers + * @param brp Baud Rate Prescaler + * @param sjw Synchronization Jump Width + * @param tseg1 Timing Segment 1 + * @param tseg2 Timing Segment 2 + * @param triple_sampling Triple Sampling enable/disable + * + * @note Must be called in reset mode + * @note ESP32C6 brp can be any even number between 2 to 32768 + */ +__attribute__((always_inline)) +static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2, bool triple_sampling) +{ + hw->bus_timing_0.baud_presc = (brp / 2) - 1; + hw->bus_timing_0.sync_jump_width = sjw - 1; + hw->bus_timing_1.time_segment1 = tseg1 - 1; + hw->bus_timing_1.time_segment2 = tseg2 - 1; + hw->bus_timing_1.time_sampling = triple_sampling; +} + +/* ----------------------------- ALC Register ------------------------------- */ + +/** + * @brief Clear Arbitration Lost Capture Register + * + * Reading the ALC register rearms the Arbitration Lost Interrupt + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw) +{ + (void)hw->arb_lost_cap.val; +} + +/* ----------------------------- ECC Register ------------------------------- */ + +/** + * @brief Clear Error Code Capture register + * + * Reading the ECC register rearms the Bus Error Interrupt + * + * @param hw Start address of the TWAI registers + */ +__attribute__((always_inline)) +static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw) +{ + (void)hw->err_code_cap.val; +} + +/* ----------------------------- EWL Register ------------------------------- */ + +/** + * @brief Set Error Warning Limit + * + * @param hw Start address of the TWAI registers + * @param ewl Error Warning Limit + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_err_warn_lim(twai_dev_t *hw, uint32_t ewl) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->err_warning_limit, err_warning_limit, ewl); +} + +/** + * @brief Get Error Warning Limit + * + * @param hw Start address of the TWAI registers + * @return Error Warning Limit + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_err_warn_lim(twai_dev_t *hw) +{ + return hw->err_warning_limit.val; +} + +/* ------------------------ RX Error Count Register ------------------------- */ + +/** + * @brief Get RX Error Counter + * + * @param hw Start address of the TWAI registers + * @return REC value + * + * @note REC is not frozen in reset mode. Listen only mode will freeze it. A BUS + * OFF condition automatically sets the REC to 0. + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_rec(twai_dev_t *hw) +{ + return hw->rx_err_cnt.val; +} + +/** + * @brief Set RX Error Counter + * + * @param hw Start address of the TWAI registers + * @param rec REC value + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_rec(twai_dev_t *hw, uint32_t rec) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_err_cnt, rx_err_cnt, rec); +} + +/* ------------------------ TX Error Count Register ------------------------- */ + +/** + * @brief Get TX Error Counter + * + * @param hw Start address of the TWAI registers + * @return TEC value + * + * @note A BUS OFF condition will automatically set this to 128 + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_tec(twai_dev_t *hw) +{ + return hw->tx_err_cnt.val; +} + +/** + * @brief Set TX Error Counter + * + * @param hw Start address of the TWAI registers + * @param tec TEC value + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_tec(twai_dev_t *hw, uint32_t tec) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_err_cnt, tx_err_cnt, tec); +} + +/* ---------------------- Acceptance Filter Registers ----------------------- */ + +/** + * @brief Set Acceptance Filter + * @param hw Start address of the TWAI registers + * @param code Acceptance Code + * @param mask Acceptance Mask + * @param single_filter Whether to enable single filter mode + * + * @note Must be called in reset mode + */ +__attribute__((always_inline)) +static inline void twai_ll_set_acc_filter(twai_dev_t *hw, uint32_t code, uint32_t mask, bool single_filter) +{ + uint32_t code_swapped = HAL_SWAP32(code); + uint32_t mask_swapped = HAL_SWAP32(mask); + for (int i = 0; i < 4; i++) { + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->acceptance_filter.acr[i], byte, ((code_swapped >> (i * 8)) & 0xFF)); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->acceptance_filter.amr[i], byte, ((mask_swapped >> (i * 8)) & 0xFF)); + } + hw->mode.acceptance_filter_mode = single_filter; +} + +/* ------------------------- TX/RX Buffer Registers ------------------------- */ + +/** + * @brief Copy a formatted TWAI frame into TX buffer for transmission + * + * @param hw Start address of the TWAI registers + * @param tx_frame Pointer to formatted frame + * + * @note Call twai_ll_format_frame_buffer() to format a frame + */ +__attribute__((always_inline)) +static inline void twai_ll_set_tx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t *tx_frame) +{ + //Copy formatted frame into TX buffer + for (int i = 0; i < 13; i++) { + hw->tx_rx_buffer[i].val = tx_frame->bytes[i]; + } +} + +/** + * @brief Copy a received frame from the RX buffer for parsing + * + * @param hw Start address of the TWAI registers + * @param rx_frame Pointer to store formatted frame + * + * @note Call twai_ll_parse_frame_buffer() to parse the formatted frame + */ +__attribute__((always_inline)) +static inline void twai_ll_get_rx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t *rx_frame) +{ + //Copy RX buffer registers into frame + for (int i = 0; i < 13; i++) { + rx_frame->bytes[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->tx_rx_buffer[i], byte); + } +} + +/** + * @brief Format contents of a TWAI frame into layout of TX Buffer + * + * This function encodes a message into a frame structure. The frame structure + * has an identical layout to the TX buffer, allowing the frame structure to be + * directly copied into TX buffer. + * + * @param[in] 11bit or 29bit ID + * @param[in] dlc Data length code + * @param[in] data Pointer to an 8 byte array containing data. NULL if no data + * @param[in] format Type of TWAI frame + * @param[in] single_shot Frame will not be retransmitted on failure + * @param[in] self_rx Frame will also be simultaneously received + * @param[out] tx_frame Pointer to store formatted frame + */ +__attribute__((always_inline)) +static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const uint8_t *data, uint32_t flags, twai_ll_frame_buffer_t *tx_frame) +{ + bool is_extd = flags & TWAI_MSG_FLAG_EXTD; + bool is_rtr = flags & TWAI_MSG_FLAG_RTR; + + //Set frame information + tx_frame->dlc = dlc; + tx_frame->frame_format = is_extd; + tx_frame->rtr = is_rtr; + tx_frame->self_reception = (flags & TWAI_MSG_FLAG_SELF) ? 1 : 0; + tx_frame->single_shot = (flags & TWAI_MSG_FLAG_SS) ? 1 : 0; + + //Set ID. The ID registers are big endian and left aligned, therefore a bswap will be required + if (is_extd) { + uint32_t id_temp = HAL_SWAP32((id & TWAI_EXTD_ID_MASK) << 3); //((id << 3) >> 8*(3-i)) + for (int i = 0; i < 4; i++) { + tx_frame->extended.id[i] = (id_temp >> (8 * i)) & 0xFF; + } + } else { + uint32_t id_temp = HAL_SWAP16((id & TWAI_STD_ID_MASK) << 5); //((id << 5) >> 8*(1-i)) + for (int i = 0; i < 2; i++) { + tx_frame->standard.id[i] = (id_temp >> (8 * i)) & 0xFF; + } + } + + uint8_t *data_buffer = (is_extd) ? tx_frame->extended.data : tx_frame->standard.data; + if (!is_rtr) { //Only copy data if the frame is a data frame (i.e not a remote frame) + for (int i = 0; (i < dlc) && (i < TWAI_FRAME_MAX_DLC); i++) { + data_buffer[i] = data[i]; + } + } +} + +/** + * @brief Parse formatted TWAI frame (RX Buffer Layout) into its constituent contents + * + * @param[in] rx_frame Pointer to formatted frame + * @param[out] id 11 or 29bit ID + * @param[out] dlc Data length code + * @param[out] data Data. Left over bytes set to 0. + * @param[out] format Type of TWAI frame + */ +__attribute__((always_inline)) +static inline void twai_ll_parse_frame_buffer(twai_ll_frame_buffer_t *rx_frame, uint32_t *id, uint8_t *dlc, uint8_t *data, uint32_t *flags) +{ + //Copy frame information + *dlc = rx_frame->dlc; + uint32_t flags_temp = 0; + flags_temp |= (rx_frame->frame_format) ? TWAI_MSG_FLAG_EXTD : 0; + flags_temp |= (rx_frame->rtr) ? TWAI_MSG_FLAG_RTR : 0; + flags_temp |= (rx_frame->dlc > TWAI_FRAME_MAX_DLC) ? TWAI_MSG_FLAG_DLC_NON_COMP : 0; + *flags = flags_temp; + + //Copy ID. The ID registers are big endian and left aligned, therefore a bswap will be required + if (rx_frame->frame_format) { + uint32_t id_temp = 0; + for (int i = 0; i < 4; i++) { + id_temp |= rx_frame->extended.id[i] << (8 * i); + } + id_temp = HAL_SWAP32(id_temp) >> 3; //((byte[i] << 8*(3-i)) >> 3) + *id = id_temp & TWAI_EXTD_ID_MASK; + } else { + uint32_t id_temp = 0; + for (int i = 0; i < 2; i++) { + id_temp |= rx_frame->standard.id[i] << (8 * i); + } + id_temp = HAL_SWAP16(id_temp) >> 5; //((byte[i] << 8*(1-i)) >> 5) + *id = id_temp & TWAI_STD_ID_MASK; + } + + uint8_t *data_buffer = (rx_frame->frame_format) ? rx_frame->extended.data : rx_frame->standard.data; + //Only copy data if the frame is a data frame (i.e. not a remote frame) + int data_length = (rx_frame->rtr) ? 0 : ((rx_frame->dlc > TWAI_FRAME_MAX_DLC) ? TWAI_FRAME_MAX_DLC : rx_frame->dlc); + for (int i = 0; i < data_length; i++) { + data[i] = data_buffer[i]; + } + //Set remaining bytes of data to 0 + for (int i = data_length; i < TWAI_FRAME_MAX_DLC; i++) { + data[i] = 0; + } +} + +/* ----------------------- RX Message Count Register ------------------------ */ + +/** + * @brief Get RX Message Counter + * + * @param hw Start address of the TWAI registers + * @return RX Message Counter + */ +__attribute__((always_inline)) +static inline uint32_t twai_ll_get_rx_msg_count(twai_dev_t *hw) +{ + return hw->rx_message_counter.val; +} + +/* ------------------------- Clock Divider Register ------------------------- */ + +/** + * @brief Set CLKOUT Divider and enable/disable + * + * Configure CLKOUT. CLKOUT is a pre-scaled version of peripheral source clock. Divider can be + * 1, or any even number from 2 to 490. Set the divider to 0 to disable CLKOUT. + * + * @param hw Start address of the TWAI registers + * @param divider Divider for CLKOUT (any even number from 2 to 490). Set to 0 to disable CLKOUT + */ +__attribute__((always_inline)) +static inline void twai_ll_set_clkout(twai_dev_t *hw, uint32_t divider) +{ + if (divider >= 2 && divider <= 490) { + hw->clock_divider.clock_off = 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, (divider / 2) - 1); + } else if (divider == 1) { + //Setting the divider reg to max value (255) means a divider of 1 + hw->clock_divider.clock_off = 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, 255); + } else { + hw->clock_divider.clock_off = 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, 0); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s2/include/hal/twai_ll.h b/components/hal/esp32s2/include/hal/twai_ll.h index 10d4d8bc4d62..3d05c5b0bec8 100644 --- a/components/hal/esp32s2/include/hal/twai_ll.h +++ b/components/hal/esp32s2/include/hal/twai_ll.h @@ -127,25 +127,25 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { - (void)hw; + (void)group_id; } /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { - (void)hw; + (void)group_id; HAL_ASSERT(clk_src == TWAI_CLK_SRC_APB); } diff --git a/components/hal/esp32s3/include/hal/twai_ll.h b/components/hal/esp32s3/include/hal/twai_ll.h index fc23d354851d..7f921438fa14 100644 --- a/components/hal/esp32s3/include/hal/twai_ll.h +++ b/components/hal/esp32s3/include/hal/twai_ll.h @@ -124,25 +124,25 @@ static inline void twai_ll_reset_register(int group_id) /** * @brief Enable TWAI module clock * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param en true to enable, false to disable */ __attribute__((always_inline)) -static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) +static inline void twai_ll_enable_clock(int group_id, bool en) { - (void)hw; + (void)group_id; } /** * @brief Set clock source for TWAI module * - * @param hw Start address of the TWAI registers + * @param group_id Group ID * @param clk_src Clock source */ __attribute__((always_inline)) -static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) +static inline void twai_ll_set_clock_source(int group_id, twai_clock_source_t clk_src) { - (void)hw; + (void)group_id; HAL_ASSERT(clk_src == TWAI_CLK_SRC_APB); } diff --git a/components/hal/twai_hal.c b/components/hal/twai_hal.c index e0ff94d51a19..25d0de61a804 100644 --- a/components/hal/twai_hal.c +++ b/components/hal/twai_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,8 +23,6 @@ bool twai_hal_init(twai_hal_context_t *hal_ctx, const twai_hal_config_t *config) hal_ctx->dev = TWAI_LL_GET_HW(config->controller_id); hal_ctx->state_flags = 0; hal_ctx->clock_source_hz = config->clock_source_hz; - //Enable functional clock - twai_ll_enable_clock(hal_ctx->dev, true); //Initialize TWAI controller, and set default values to registers twai_ll_enter_reset_mode(hal_ctx->dev); if (!twai_ll_is_in_reset_mode(hal_ctx->dev)) { //Must enter reset mode to write to config registers @@ -48,8 +46,6 @@ void twai_hal_deinit(twai_hal_context_t *hal_ctx) twai_ll_set_enabled_intrs(hal_ctx->dev, 0); twai_ll_clear_arb_lost_cap(hal_ctx->dev); twai_ll_clear_err_code_cap(hal_ctx->dev); - //Disable functional clock - twai_ll_enable_clock(hal_ctx->dev, false); hal_ctx->dev = NULL; } @@ -62,14 +58,6 @@ void twai_hal_configure(twai_hal_context_t *hal_ctx, const twai_timing_config_t brp = hal_ctx->clock_source_hz / t_config->quanta_resolution_hz; } - // set clock source - twai_clock_source_t clk_src = t_config->clk_src; - //for backward compatible, zero value means default a default clock source - if (t_config->clk_src == 0) { - clk_src = TWAI_CLK_SRC_DEFAULT; - } - twai_ll_set_clock_source(hal_ctx->dev, clk_src); - //Configure bus timing, acceptance filter, CLKOUT, and interrupts twai_ll_set_bus_timing(hal_ctx->dev, brp, t_config->sjw, t_config->tseg_1, t_config->tseg_2, t_config->triple_sampling); twai_ll_set_acc_filter(hal_ctx->dev, f_config->acceptance_code, f_config->acceptance_mask, f_config->single_filter); diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 37bf7397360c..bf0195faf9ce 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -35,6 +35,10 @@ config SOC_MCPWM_SUPPORTED bool default y +config SOC_TWAI_SUPPORTED + bool + default y + config SOC_ETM_SUPPORTED bool default y @@ -1009,7 +1013,7 @@ config SOC_MWDT_SUPPORT_XTAL config SOC_TWAI_CONTROLLER_NUM int - default 2 + default 3 config SOC_TWAI_CLK_SUPPORT_XTAL bool diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index b386fc9d07a7..c218ff496e3e 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32p4/include/soc/clk_tree_defs.h @@ -464,6 +464,21 @@ typedef enum { } soc_periph_ana_cmpr_clk_src_t; //////////////////////////////////////////////////TWAI////////////////////////////////////////////////////////////////// +/** + * @brief Array initializer for all supported clock sources of TWAI + */ +#define SOC_TWAI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST} + +/** + * @brief TWAI clock source + */ +typedef enum { + TWAI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ +#if SOC_CLK_TREE_SUPPORTED + TWAI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST /*!< Select RC_FAST as the source clock */ +#endif + TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */ +} soc_periph_twai_clk_src_t; //////////////////////////////////////////////////ADC/////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32p4/include/soc/gpio_sig_map.h b/components/soc/esp32p4/include/soc/gpio_sig_map.h index 99bd0360b5b3..d0653170fdd1 100644 --- a/components/soc/esp32p4/include/soc/gpio_sig_map.h +++ b/components/soc/esp32p4/include/soc/gpio_sig_map.h @@ -159,18 +159,18 @@ #define UART4_SLP_CLK_PAD_IN_IDX 78 #define GPIO_SD6_OUT_IDX 78 #define GPIO_SD7_OUT_IDX 79 -#define CAN0_RX_PAD_IN_IDX 80 -#define CAN0_TX_PAD_OUT_IDX 80 -#define CAN0_BUS_OFF_ON_PAD_OUT_IDX 81 -#define CAN0_CLKOUT_PAD_OUT_IDX 82 -#define CAN1_RX_PAD_IN_IDX 83 -#define CAN1_TX_PAD_OUT_IDX 83 -#define CAN1_BUS_OFF_ON_PAD_OUT_IDX 84 -#define CAN1_CLKOUT_PAD_OUT_IDX 85 -#define CAN2_RX_PAD_IN_IDX 86 -#define CAN2_TX_PAD_OUT_IDX 86 -#define CAN2_BUS_OFF_ON_PAD_OUT_IDX 87 -#define CAN2_CLKOUT_PAD_OUT_IDX 88 +#define TWAI0_RX_PAD_IN_IDX 80 +#define TWAI0_TX_PAD_OUT_IDX 80 +#define TWAI0_BUS_OFF_ON_PAD_OUT_IDX 81 +#define TWAI0_CLKOUT_PAD_OUT_IDX 82 +#define TWAI1_RX_PAD_IN_IDX 83 +#define TWAI1_TX_PAD_OUT_IDX 83 +#define TWAI1_BUS_OFF_ON_PAD_OUT_IDX 84 +#define TWAI1_CLKOUT_PAD_OUT_IDX 85 +#define TWAI2_RX_PAD_IN_IDX 86 +#define TWAI2_TX_PAD_OUT_IDX 86 +#define TWAI2_BUS_OFF_ON_PAD_OUT_IDX 87 +#define TWAI2_CLKOUT_PAD_OUT_IDX 88 #define PWM0_SYNC0_PAD_IN_IDX 89 #define PWM0_CH0_A_PAD_OUT_IDX 89 #define PWM0_SYNC1_PAD_IN_IDX 90 diff --git a/components/soc/esp32p4/include/soc/hp_sys_clkrst_reg.h b/components/soc/esp32p4/include/soc/hp_sys_clkrst_reg.h index 4bfc63fc2e31..8a7ad9c6af2d 100644 --- a/components/soc/esp32p4/include/soc/hp_sys_clkrst_reg.h +++ b/components/soc/esp32p4/include/soc/hp_sys_clkrst_reg.h @@ -3473,27 +3473,27 @@ extern "C" { #define HP_SYS_CLKRST_REG_RST_EN_PWM1_M (HP_SYS_CLKRST_REG_RST_EN_PWM1_V << HP_SYS_CLKRST_REG_RST_EN_PWM1_S) #define HP_SYS_CLKRST_REG_RST_EN_PWM1_V 0x00000001U #define HP_SYS_CLKRST_REG_RST_EN_PWM1_S 25 -/** HP_SYS_CLKRST_REG_RST_EN_CAN0 : R/W; bitpos: [26]; default: 0; +/** HP_SYS_CLKRST_REG_RST_EN_TWAI0 : R/W; bitpos: [26]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_RST_EN_CAN0 (BIT(26)) -#define HP_SYS_CLKRST_REG_RST_EN_CAN0_M (HP_SYS_CLKRST_REG_RST_EN_CAN0_V << HP_SYS_CLKRST_REG_RST_EN_CAN0_S) -#define HP_SYS_CLKRST_REG_RST_EN_CAN0_V 0x00000001U -#define HP_SYS_CLKRST_REG_RST_EN_CAN0_S 26 -/** HP_SYS_CLKRST_REG_RST_EN_CAN1 : R/W; bitpos: [27]; default: 0; +#define HP_SYS_CLKRST_REG_RST_EN_TWAI0 (BIT(26)) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI0_M (HP_SYS_CLKRST_REG_RST_EN_TWAI0_V << HP_SYS_CLKRST_REG_RST_EN_TWAI0_S) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI0_V 0x00000001U +#define HP_SYS_CLKRST_REG_RST_EN_TWAI0_S 26 +/** HP_SYS_CLKRST_REG_RST_EN_TWAI1 : R/W; bitpos: [27]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_RST_EN_CAN1 (BIT(27)) -#define HP_SYS_CLKRST_REG_RST_EN_CAN1_M (HP_SYS_CLKRST_REG_RST_EN_CAN1_V << HP_SYS_CLKRST_REG_RST_EN_CAN1_S) -#define HP_SYS_CLKRST_REG_RST_EN_CAN1_V 0x00000001U -#define HP_SYS_CLKRST_REG_RST_EN_CAN1_S 27 -/** HP_SYS_CLKRST_REG_RST_EN_CAN2 : R/W; bitpos: [28]; default: 0; +#define HP_SYS_CLKRST_REG_RST_EN_TWAI1 (BIT(27)) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI1_M (HP_SYS_CLKRST_REG_RST_EN_TWAI1_V << HP_SYS_CLKRST_REG_RST_EN_TWAI1_S) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI1_V 0x00000001U +#define HP_SYS_CLKRST_REG_RST_EN_TWAI1_S 27 +/** HP_SYS_CLKRST_REG_RST_EN_TWAI2 : R/W; bitpos: [28]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_RST_EN_CAN2 (BIT(28)) -#define HP_SYS_CLKRST_REG_RST_EN_CAN2_M (HP_SYS_CLKRST_REG_RST_EN_CAN2_V << HP_SYS_CLKRST_REG_RST_EN_CAN2_S) -#define HP_SYS_CLKRST_REG_RST_EN_CAN2_V 0x00000001U -#define HP_SYS_CLKRST_REG_RST_EN_CAN2_S 28 +#define HP_SYS_CLKRST_REG_RST_EN_TWAI2 (BIT(28)) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI2_M (HP_SYS_CLKRST_REG_RST_EN_TWAI2_V << HP_SYS_CLKRST_REG_RST_EN_TWAI2_S) +#define HP_SYS_CLKRST_REG_RST_EN_TWAI2_V 0x00000001U +#define HP_SYS_CLKRST_REG_RST_EN_TWAI2_S 28 /** HP_SYS_CLKRST_REG_RST_EN_LEDC : R/W; bitpos: [29]; default: 0; * Reserved */ @@ -3971,27 +3971,27 @@ extern "C" { #define HP_SYS_CLKRST_REG_FORCE_NORST_PWM1_M (HP_SYS_CLKRST_REG_FORCE_NORST_PWM1_V << HP_SYS_CLKRST_REG_FORCE_NORST_PWM1_S) #define HP_SYS_CLKRST_REG_FORCE_NORST_PWM1_V 0x00000001U #define HP_SYS_CLKRST_REG_FORCE_NORST_PWM1_S 5 -/** HP_SYS_CLKRST_REG_FORCE_NORST_CAN0 : R/W; bitpos: [6]; default: 0; +/** HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0 : R/W; bitpos: [6]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN0 (BIT(6)) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN0_M (HP_SYS_CLKRST_REG_FORCE_NORST_CAN0_V << HP_SYS_CLKRST_REG_FORCE_NORST_CAN0_S) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN0_V 0x00000001U -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN0_S 6 -/** HP_SYS_CLKRST_REG_FORCE_NORST_CAN1 : R/W; bitpos: [7]; default: 0; +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0 (BIT(6)) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0_M (HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0_V << HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0_S) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0_V 0x00000001U +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI0_S 6 +/** HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1 : R/W; bitpos: [7]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN1 (BIT(7)) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN1_M (HP_SYS_CLKRST_REG_FORCE_NORST_CAN1_V << HP_SYS_CLKRST_REG_FORCE_NORST_CAN1_S) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN1_V 0x00000001U -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN1_S 7 -/** HP_SYS_CLKRST_REG_FORCE_NORST_CAN2 : R/W; bitpos: [8]; default: 0; +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1 (BIT(7)) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1_M (HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1_V << HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1_S) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1_V 0x00000001U +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI1_S 7 +/** HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2 : R/W; bitpos: [8]; default: 0; * Reserved */ -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN2 (BIT(8)) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN2_M (HP_SYS_CLKRST_REG_FORCE_NORST_CAN2_V << HP_SYS_CLKRST_REG_FORCE_NORST_CAN2_S) -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN2_V 0x00000001U -#define HP_SYS_CLKRST_REG_FORCE_NORST_CAN2_S 8 +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2 (BIT(8)) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2_M (HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2_V << HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2_S) +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2_V 0x00000001U +#define HP_SYS_CLKRST_REG_FORCE_NORST_TWAI2_S 8 /** HP_SYS_CLKRST_REG_FORCE_NORST_LEDC : R/W; bitpos: [9]; default: 0; * Reserved */ diff --git a/components/soc/esp32p4/include/soc/hp_sys_clkrst_struct.h b/components/soc/esp32p4/include/soc/hp_sys_clkrst_struct.h index d672ecc62952..2837628cd607 100644 --- a/components/soc/esp32p4/include/soc/hp_sys_clkrst_struct.h +++ b/components/soc/esp32p4/include/soc/hp_sys_clkrst_struct.h @@ -2350,18 +2350,18 @@ typedef union { * Reserved */ uint32_t reg_rst_en_pwm1:1; - /** reg_rst_en_can0 : R/W; bitpos: [26]; default: 0; + /** reg_rst_en_twai0 : R/W; bitpos: [26]; default: 0; * Reserved */ - uint32_t reg_rst_en_can0:1; - /** reg_rst_en_can1 : R/W; bitpos: [27]; default: 0; + uint32_t reg_rst_en_twai0:1; + /** reg_rst_en_twai1 : R/W; bitpos: [27]; default: 0; * Reserved */ - uint32_t reg_rst_en_can1:1; - /** reg_rst_en_can2 : R/W; bitpos: [28]; default: 0; + uint32_t reg_rst_en_twai1:1; + /** reg_rst_en_twai2 : R/W; bitpos: [28]; default: 0; * Reserved */ - uint32_t reg_rst_en_can2:1; + uint32_t reg_rst_en_twai2:1; /** reg_rst_en_ledc : R/W; bitpos: [29]; default: 0; * Reserved */ @@ -2656,18 +2656,18 @@ typedef union { * Reserved */ uint32_t reg_force_norst_pwm1:1; - /** reg_force_norst_can0 : R/W; bitpos: [6]; default: 0; + /** reg_force_norst_twai0 : R/W; bitpos: [6]; default: 0; * Reserved */ - uint32_t reg_force_norst_can0:1; - /** reg_force_norst_can1 : R/W; bitpos: [7]; default: 0; + uint32_t reg_force_norst_twai0:1; + /** reg_force_norst_twai1 : R/W; bitpos: [7]; default: 0; * Reserved */ - uint32_t reg_force_norst_can1:1; - /** reg_force_norst_can2 : R/W; bitpos: [8]; default: 0; + uint32_t reg_force_norst_twai1:1; + /** reg_force_norst_twai2 : R/W; bitpos: [8]; default: 0; * Reserved */ - uint32_t reg_force_norst_can2:1; + uint32_t reg_force_norst_twai2:1; /** reg_force_norst_ledc : R/W; bitpos: [9]; default: 0; * Reserved */ diff --git a/components/soc/esp32p4/include/soc/interrupts.h b/components/soc/esp32p4/include/soc/interrupts.h index 881aee45195e..685da9861dc6 100644 --- a/components/soc/esp32p4/include/soc/interrupts.h +++ b/components/soc/esp32p4/include/soc/interrupts.h @@ -55,9 +55,9 @@ typedef enum { ETS_ADC_INTR_SOURCE, ETS_PWM0_INTR_SOURCE, ETS_PWM1_INTR_SOURCE, - ETS_CAN0_INTR_SOURCE, - ETS_CAN1_INTR_SOURCE, - ETS_CAN2_INTR_SOURCE, + ETS_TWAI0_INTR_SOURCE, + ETS_TWAI1_INTR_SOURCE, + ETS_TWAI2_INTR_SOURCE, ETS_RMT_INTR_SOURCE, ETS_I2C0_INTR_SOURCE, ETS_I2C1_INTR_SOURCE, diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 35685464f654..5d3c43821697 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -35,7 +35,7 @@ #define SOC_GPTIMER_SUPPORTED 1 #define SOC_PCNT_SUPPORTED 1 #define SOC_MCPWM_SUPPORTED 1 -// #define SOC_TWAI_SUPPORTED 1 //TODO: IDF-7470 +#define SOC_TWAI_SUPPORTED 1 #define SOC_ETM_SUPPORTED 1 #define SOC_PARLIO_SUPPORTED 1 //TODO: IDF-7471 #define SOC_ASYNC_MEMCPY_SUPPORTED 1 @@ -458,7 +458,7 @@ #define SOC_MWDT_SUPPORT_XTAL (1) /*-------------------------- TWAI CAPS ---------------------------------------*/ -#define SOC_TWAI_CONTROLLER_NUM 2 +#define SOC_TWAI_CONTROLLER_NUM 3 #define SOC_TWAI_CLK_SUPPORT_XTAL 1 #define SOC_TWAI_BRP_MIN 2 #define SOC_TWAI_BRP_MAX 32768 diff --git a/components/soc/esp32p4/include/soc/twai_struct.h b/components/soc/esp32p4/include/soc/twai_struct.h index 758d6462fcb4..902905130924 100644 --- a/components/soc/esp32p4/include/soc/twai_struct.h +++ b/components/soc/esp32p4/include/soc/twai_struct.h @@ -434,7 +434,7 @@ typedef union { uint32_t reserved_9:23; }; uint32_t val; -} twai_interrupt_reg_t; +} twai_interrupt_status_reg_t; /** Type of interrupt_enable register * Interrupt enable register. @@ -493,214 +493,43 @@ typedef union { /** Group: Data Registers */ -/** Type of data_0 register - * Data register 0. +/** Type of buffer register + * TX RX Buffer. */ typedef union { struct { - /** data_0 : R/W; bitpos: [7:0]; default: 0; + /** byte : R/W; bitpos: [7:0]; default: 0; * In reset mode, it is acceptance code register 0 with R/W Permission. In operation * mode, when software initiate write operation, it is tx data register 0 and when * software initiate read operation, it is rx data register 0. */ - uint32_t data_0:8; + uint32_t byte:8; uint32_t reserved_8:24; }; uint32_t val; -} twai_data_0_reg_t; - -/** Type of data_1 register - * Data register 1. - */ -typedef union { - struct { - /** data_1 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance code register 1 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 1 and when - * software initiate read operation, it is rx data register 1. - */ - uint32_t data_1:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_1_reg_t; - -/** Type of data_2 register - * Data register 2. - */ -typedef union { - struct { - /** data_2 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance code register 2 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 2 and when - * software initiate read operation, it is rx data register 2. - */ - uint32_t data_2:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_2_reg_t; - -/** Type of data_3 register - * Data register 3. - */ -typedef union { - struct { - /** data_3 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance code register 3 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 3 and when - * software initiate read operation, it is rx data register 3. - */ - uint32_t data_3:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_3_reg_t; - -/** Type of data_4 register - * Data register 4. - */ -typedef union { - struct { - /** data_4 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance mask register 0 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 4 and when - * software initiate read operation, it is rx data register 4. - */ - uint32_t data_4:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_4_reg_t; - -/** Type of data_5 register - * Data register 5. - */ -typedef union { - struct { - /** data_5 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance mask register 1 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 5 and when - * software initiate read operation, it is rx data register 5. - */ - uint32_t data_5:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_5_reg_t; - -/** Type of data_6 register - * Data register 6. - */ -typedef union { - struct { - /** data_6 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance mask register 2 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 6 and when - * software initiate read operation, it is rx data register 6. - */ - uint32_t data_6:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_6_reg_t; - -/** Type of data_7 register - * Data register 7. - */ -typedef union { - struct { - /** data_7 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, it is acceptance mask register 3 with R/W Permission. In operation - * mode, when software initiate write operation, it is tx data register 7 and when - * software initiate read operation, it is rx data register 7. - */ - uint32_t data_7:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_7_reg_t; - -/** Type of data_8 register - * Data register 8. - */ -typedef union { - struct { - /** data_8 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, reserved with RO. In operation mode, when software initiate write - * operation, it is tx data register 8 and when software initiate read operation, it - * is rx data register 8. - */ - uint32_t data_8:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_8_reg_t; - -/** Type of data_9 register - * Data register 9. - */ -typedef union { - struct { - /** data_9 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, reserved with RO. In operation mode, when software initiate write - * operation, it is tx data register 9 and when software initiate read operation, it - * is rx data register 9. - */ - uint32_t data_9:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_9_reg_t; - -/** Type of data_10 register - * Data register 10. - */ -typedef union { - struct { - /** data_10 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, reserved with RO. In operation mode, when software initiate write - * operation, it is tx data register 10 and when software initiate read operation, it - * is rx data register 10. - */ - uint32_t data_10:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_10_reg_t; - -/** Type of data_11 register - * Data register 11. - */ -typedef union { - struct { - /** data_11 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, reserved with RO. In operation mode, when software initiate write - * operation, it is tx data register 11 and when software initiate read operation, it - * is rx data register 11. - */ - uint32_t data_11:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_11_reg_t; - -/** Type of data_12 register - * Data register 12. - */ -typedef union { - struct { - /** data_12 : R/W; bitpos: [7:0]; default: 0; - * In reset mode, reserved with RO. In operation mode, when software initiate write - * operation, it is tx data register 12 and when software initiate read operation, it - * is rx data register 12. - */ - uint32_t data_12:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} twai_data_12_reg_t; +} twai_tx_rx_buffer_reg_t; +typedef struct { + union { + struct { + uint32_t byte: 8; /* ACRx[7:0] Acceptance Code */ + uint32_t reserved8: 24; /* Internal Reserved */ + }; + uint32_t val; + } acr[4]; + union { + struct { + uint32_t byte: 8; /* AMRx[7:0] Acceptance Mask */ + uint32_t reserved8: 24; /* Internal Reserved */ + }; + uint32_t val; + } amr[4]; + uint32_t reserved_60; + uint32_t reserved_64; + uint32_t reserved_68; + uint32_t reserved_6c; + uint32_t reserved_70; +} acceptance_filter_reg_t; /** Group: Timestamp Register */ /** Type of timestamp_data register @@ -749,8 +578,8 @@ typedef struct { volatile twai_mode_reg_t mode; volatile twai_cmd_reg_t cmd; volatile twai_status_reg_t status; - volatile twai_interrupt_reg_t interrupt; - volatile twai_interrupt_enable_reg_t interrupt_enable; + volatile twai_interrupt_status_reg_t interrupt_st; + volatile twai_interrupt_enable_reg_t interrupt_ena; uint32_t reserved_014; volatile twai_bus_timing_0_reg_t bus_timing_0; volatile twai_bus_timing_1_reg_t bus_timing_1; @@ -760,19 +589,10 @@ typedef struct { volatile twai_err_warning_limit_reg_t err_warning_limit; volatile twai_rx_err_cnt_reg_t rx_err_cnt; volatile twai_tx_err_cnt_reg_t tx_err_cnt; - volatile twai_data_0_reg_t data_0; - volatile twai_data_1_reg_t data_1; - volatile twai_data_2_reg_t data_2; - volatile twai_data_3_reg_t data_3; - volatile twai_data_4_reg_t data_4; - volatile twai_data_5_reg_t data_5; - volatile twai_data_6_reg_t data_6; - volatile twai_data_7_reg_t data_7; - volatile twai_data_8_reg_t data_8; - volatile twai_data_9_reg_t data_9; - volatile twai_data_10_reg_t data_10; - volatile twai_data_11_reg_t data_11; - volatile twai_data_12_reg_t data_12; + volatile union { + acceptance_filter_reg_t acceptance_filter; + twai_tx_rx_buffer_reg_t tx_rx_buffer[13]; + }; volatile twai_rx_message_counter_reg_t rx_message_counter; uint32_t reserved_078; volatile twai_clock_divider_reg_t clock_divider; @@ -786,6 +606,9 @@ typedef struct { volatile twai_timestamp_cfg_reg_t timestamp_cfg; } twai_dev_t; +extern twai_dev_t TWAI0; +extern twai_dev_t TWAI1; +extern twai_dev_t TWAI2; #ifndef __cplusplus _Static_assert(sizeof(twai_dev_t) == 0xa0, "Invalid size of twai_dev_t structure"); diff --git a/components/soc/esp32p4/interrupts.c b/components/soc/esp32p4/interrupts.c index be8694e6b947..6d76d073e560 100644 --- a/components/soc/esp32p4/interrupts.c +++ b/components/soc/esp32p4/interrupts.c @@ -47,9 +47,9 @@ const char *const esp_isr_names[] = { [ETS_ADC_INTR_SOURCE] = "ADC", [ETS_PWM0_INTR_SOURCE] = "PWM0", [ETS_PWM1_INTR_SOURCE] = "PWM1", - [ETS_CAN0_INTR_SOURCE] = "CAN0", - [ETS_CAN1_INTR_SOURCE] = "CAN1", - [ETS_CAN2_INTR_SOURCE] = "CAN2", + [ETS_TWAI0_INTR_SOURCE] = "TWAI0", + [ETS_TWAI1_INTR_SOURCE] = "TWAI1", + [ETS_TWAI2_INTR_SOURCE] = "TWAI2", [ETS_RMT_INTR_SOURCE] = "RMT", [ETS_I2C0_INTR_SOURCE] = "I2C0", [ETS_I2C1_INTR_SOURCE] = "I2C1", diff --git a/components/soc/esp32p4/twai_periph.c b/components/soc/esp32p4/twai_periph.c index 061cd4a4d788..67b016fa0d66 100644 --- a/components/soc/esp32p4/twai_periph.c +++ b/components/soc/esp32p4/twai_periph.c @@ -8,5 +8,33 @@ #include "soc/gpio_sig_map.h" const twai_controller_signal_conn_t twai_controller_periph_signals = { - + .controllers = { + [0] = { + .module = PERIPH_TWAI0_MODULE, + .irq_id = ETS_TWAI0_INTR_SOURCE, + .tx_sig = TWAI0_TX_PAD_OUT_IDX, + .rx_sig = TWAI0_RX_PAD_IN_IDX, + .bus_off_sig = TWAI0_BUS_OFF_ON_PAD_OUT_IDX, + .clk_out_sig = TWAI0_CLKOUT_PAD_OUT_IDX, + .stand_by_sig = TWAI0_STANDBY_PAD_OUT_IDX, + }, + [1] = { + .module = PERIPH_TWAI1_MODULE, + .irq_id = ETS_TWAI1_INTR_SOURCE, + .tx_sig = TWAI1_TX_PAD_OUT_IDX, + .rx_sig = TWAI1_RX_PAD_IN_IDX, + .bus_off_sig = TWAI1_BUS_OFF_ON_PAD_OUT_IDX, + .clk_out_sig = TWAI1_CLKOUT_PAD_OUT_IDX, + .stand_by_sig = TWAI1_STANDBY_PAD_OUT_IDX, + }, + [2] = { + .module = PERIPH_TWAI2_MODULE, + .irq_id = ETS_TWAI2_INTR_SOURCE, + .tx_sig = TWAI2_TX_PAD_OUT_IDX, + .rx_sig = TWAI2_RX_PAD_IN_IDX, + .bus_off_sig = TWAI2_BUS_OFF_ON_PAD_OUT_IDX, + .clk_out_sig = TWAI2_CLKOUT_PAD_OUT_IDX, + .stand_by_sig = TWAI2_STANDBY_PAD_OUT_IDX, + } + } }; diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index 2f190dd54401..64aa2b98fe32 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -82,7 +82,6 @@ api-reference/peripherals/gpio/esp32p4.inc api-reference/peripherals/adc_continuous.rst api-reference/peripherals/adc_oneshot.rst api-reference/peripherals/usb_host.rst -api-reference/peripherals/twai.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 diff --git a/docs/en/api-reference/peripherals/twai.rst b/docs/en/api-reference/peripherals/twai.rst index f55f76efd2e8..3a19a7f03a6e 100644 --- a/docs/en/api-reference/peripherals/twai.rst +++ b/docs/en/api-reference/peripherals/twai.rst @@ -164,7 +164,7 @@ The operating bit rate of the TWAI driver is configured using the :cpp:type:`twa 2. **Timing Segment 1** consists of 1 to 16 time quanta before sample point 3. **Timing Segment 2** consists of 1 to 8 time quanta after sample point -{IDF_TARGET_MAX_BRP:default="128", esp32="128", esp32s2="32768", esp32s3="16384", esp32c3="16384", esp32c6="32768", esp32h2="32768"} +{IDF_TARGET_MAX_BRP:default="32768", esp32="128", esp32s3="16384", esp32c3="16384"} The **Baudrate Prescaler** is used to determine the period of each time quantum by dividing the TWAI controller's source clock. On the {IDF_TARGET_NAME}, the ``brp`` can be **any even number from 2 to {IDF_TARGET_MAX_BRP}**. Alternatively, you can decide the resolution of each quantum, by setting :cpp:member:`twai_timing_config_t::quanta_resolution_hz` to a non-zero value. In this way, the driver can calculate the underlying ``brp`` value for you. It is useful when you set different clock sources but want the bitrate to keep the same. diff --git a/examples/peripherals/twai/twai_alert_and_recovery/README.md b/examples/peripherals/twai/twai_alert_and_recovery/README.md index 0c8b1c9a9632..860c76d49497 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/README.md +++ b/examples/peripherals/twai/twai_alert_and_recovery/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # TWAI Alert and Recovery Example diff --git a/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c b/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c index fa740a8ce02a..ac138733cf3c 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c +++ b/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -26,7 +26,7 @@ #include "driver/twai.h" #include "esp_rom_gpio.h" #include "esp_rom_sys.h" -#include "soc/gpio_sig_map.h" // For GPIO matrix signal index +#include "soc/twai_periph.h" // For GPIO matrix signal index /* --------------------- Definitions and static variables ------------------ */ //Example Configuration @@ -38,12 +38,6 @@ #define ERR_PERIOD_US 80 //Approximate time for two bits at 25KBPS #define EXAMPLE_TAG "TWAI Alert and Recovery" -#if CONFIG_IDF_TARGET_ESP32C6 -#define TWAI_TX_SIGNAL_IDX TWAI0_TX_IDX -#else -#define TWAI_TX_SIGNAL_IDX TWAI_TX_IDX -#endif - static const twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_25KBITS(); static const twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TX_GPIO_NUM, RX_GPIO_NUM, TWAI_MODE_NO_ACK); @@ -54,15 +48,15 @@ static SemaphoreHandle_t ctrl_task_sem; static bool trigger_tx_error = false; /* --------------------------- Tasks and Functions -------------------------- */ - +extern const twai_controller_signal_conn_t twai_controller_periph_signals; static void invert_tx_bits(bool enable) { if (enable) { //Inverts output of TX to trigger errors - esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, TWAI_TX_SIGNAL_IDX, true, false); + esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, twai_controller_periph_signals.controllers[0].tx_sig, true, false); } else { //Returns TX to default settings - esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, TWAI_TX_SIGNAL_IDX, false, false); + esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, twai_controller_periph_signals.controllers[0].tx_sig, false, false); } } diff --git a/examples/peripherals/twai/twai_network/README.md b/examples/peripherals/twai/twai_network/README.md index dd0fd36ccf78..a10d4ca76ff0 100644 --- a/examples/peripherals/twai/twai_network/README.md +++ b/examples/peripherals/twai/twai_network/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # TWAI Network Example diff --git a/examples/peripherals/twai/twai_self_test/README.md b/examples/peripherals/twai/twai_self_test/README.md index 38902161dddf..ae75e8323177 100644 --- a/examples/peripherals/twai/twai_self_test/README.md +++ b/examples/peripherals/twai/twai_self_test/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # TWAI Self Test Example From 5ce93aa257343513eddba53da7f4c78a90b46a8f Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 5 Sep 2023 14:34:04 +0530 Subject: [PATCH 054/161] fix(esp_tls): Refactor esp-tls to remove ESP_TLS_SERVER config option --- components/esp-tls/Kconfig | 13 ++------ components/esp-tls/esp_tls.c | 10 ++----- components/esp-tls/esp_tls.h | 10 +++---- components/esp-tls/esp_tls_mbedtls.c | 30 ++++++++----------- components/esp-tls/esp_tls_wolfssl.c | 19 ++++-------- .../esp-tls/private_include/esp_tls_mbedtls.h | 12 ++------ .../esp-tls/private_include/esp_tls_private.h | 24 ++++++++++----- .../esp-tls/private_include/esp_tls_wolfssl.h | 5 +--- .../esp-tls/test_apps/main/test_esp_tls.c | 2 -- .../esp-tls/test_apps/sdkconfig.defaults | 2 -- 10 files changed, 47 insertions(+), 80 deletions(-) diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index ac28442ef3db..32e1e0db832f 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -38,16 +38,9 @@ menu "ESP-TLS" help Enable session ticket support as specified in RFC5077. - config ESP_TLS_SERVER - bool "Enable ESP-TLS Server" - depends on (ESP_TLS_USING_MBEDTLS && MBEDTLS_TLS_SERVER) || ESP_TLS_USING_WOLFSSL - help - Enable support for creating server side SSL/TLS session, available for mbedTLS - as well as wolfSSL TLS library. - config ESP_TLS_SERVER_SESSION_TICKETS bool "Enable server session tickets" - depends on ESP_TLS_SERVER && ESP_TLS_USING_MBEDTLS && MBEDTLS_SERVER_SSL_SESSION_TICKETS + depends on ESP_TLS_USING_MBEDTLS && MBEDTLS_SERVER_SSL_SESSION_TICKETS help Enable session ticket support as specified in RFC5077 @@ -60,7 +53,7 @@ menu "ESP-TLS" config ESP_TLS_SERVER_CERT_SELECT_HOOK bool "Certificate selection hook" - depends on ESP_TLS_USING_MBEDTLS && ESP_TLS_SERVER + depends on ESP_TLS_USING_MBEDTLS help Ability to configure and use a certificate selection callback during server handshake, to select a certificate to present to the client based on the TLS extensions supplied in @@ -68,7 +61,7 @@ menu "ESP-TLS" config ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL bool "ESP-TLS Server: Set minimum Certificate Verification mode to Optional" - depends on ESP_TLS_SERVER && ESP_TLS_USING_MBEDTLS + depends on ESP_TLS_USING_MBEDTLS help When this option is enabled, the peer (here, the client) certificate is checked by the server, however the handshake continues even if verification failed. By default, the diff --git a/components/esp-tls/esp_tls.c b/components/esp-tls/esp_tls.c index b80edd16793c..76265587e972 100644 --- a/components/esp-tls/esp_tls.c +++ b/components/esp-tls/esp_tls.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -64,12 +64,10 @@ static const char *TAG = "esp-tls"; #define _esp_tls_get_client_session esp_mbedtls_get_client_session #define _esp_tls_free_client_session esp_mbedtls_free_client_session #define _esp_tls_get_ssl_context esp_mbedtls_get_ssl_context -#ifdef CONFIG_ESP_TLS_SERVER #define _esp_tls_server_session_create esp_mbedtls_server_session_create #define _esp_tls_server_session_delete esp_mbedtls_server_session_delete #define _esp_tls_server_session_ticket_ctx_init esp_mbedtls_server_session_ticket_ctx_init #define _esp_tls_server_session_ticket_ctx_free esp_mbedtls_server_session_ticket_ctx_free -#endif /* CONFIG_ESP_TLS_SERVER */ #define _esp_tls_get_bytes_avail esp_mbedtls_get_bytes_avail #define _esp_tls_init_global_ca_store esp_mbedtls_init_global_ca_store #define _esp_tls_set_global_ca_store esp_mbedtls_set_global_ca_store /*!< Callback function for setting global CA store data for TLS/SSL */ @@ -83,10 +81,8 @@ static const char *TAG = "esp-tls"; #define _esp_tls_write esp_wolfssl_write #define _esp_tls_conn_delete esp_wolfssl_conn_delete #define _esp_tls_net_init esp_wolfssl_net_init -#ifdef CONFIG_ESP_TLS_SERVER #define _esp_tls_server_session_create esp_wolfssl_server_session_create #define _esp_tls_server_session_delete esp_wolfssl_server_session_delete -#endif /* CONFIG_ESP_TLS_SERVER */ #define _esp_tls_get_bytes_avail esp_wolfssl_get_bytes_avail #define _esp_tls_init_global_ca_store esp_wolfssl_init_global_ca_store #define _esp_tls_set_global_ca_store esp_wolfssl_set_global_ca_store /*!< Callback function for setting global CA store data for TLS/SSL */ @@ -108,7 +104,7 @@ static const char *TAG = "esp-tls"; static esp_err_t create_ssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls) { - return _esp_create_ssl_handle(hostname, hostlen, cfg, tls); + return _esp_create_ssl_handle(hostname, hostlen, cfg, tls, NULL); } static esp_err_t esp_tls_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg) @@ -638,7 +634,6 @@ void esp_tls_free_client_session(esp_tls_client_session_t *client_session) #endif /* CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS */ -#ifdef CONFIG_ESP_TLS_SERVER esp_err_t esp_tls_cfg_server_session_tickets_init(esp_tls_cfg_server_t *cfg) { #if defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS) @@ -682,7 +677,6 @@ void esp_tls_server_session_delete(esp_tls_t *tls) { return _esp_tls_server_session_delete(tls); } -#endif /* CONFIG_ESP_TLS_SERVER */ ssize_t esp_tls_get_bytes_avail(esp_tls_t *tls) { diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index 92e7dbfcf73b..32eccacb5d80 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -213,7 +213,6 @@ typedef struct esp_tls_cfg { esp_tls_proto_ver_t tls_version; /*!< TLS protocol version of the connection, e.g., TLS 1.2, TLS 1.3 (default - no preference) */ } esp_tls_cfg_t; -#ifdef CONFIG_ESP_TLS_SERVER #if defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS) /** * @brief Data structures necessary to support TLS session tickets according to RFC5077 @@ -228,7 +227,7 @@ typedef struct esp_tls_server_session_ticket_ctx { } esp_tls_server_session_ticket_ctx_t; #endif - +#if defined(CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK) /** * @brief tls handshake callback * Can be used to configure per-handshake attributes for the TLS connection. @@ -239,7 +238,11 @@ typedef struct esp_tls_server_session_ticket_ctx { * or a specific MBEDTLS_ERR_XXX code, which will cause the handhsake to abort */ typedef mbedtls_ssl_hs_cb_t esp_tls_handshake_callback; +#endif +/** + * @brief ESP-TLS Server configuration parameters + */ typedef struct esp_tls_cfg_server { const char **alpn_protos; /*!< Application protocols required for HTTP2. If HTTP2/ALPN support is required, a list @@ -341,7 +344,6 @@ esp_err_t esp_tls_cfg_server_session_tickets_init(esp_tls_cfg_server_t *cfg); * @param cfg server configuration as esp_tls_cfg_server_t */ void esp_tls_cfg_server_session_tickets_free(esp_tls_cfg_server_t *cfg); -#endif /* ! CONFIG_ESP_TLS_SERVER */ typedef struct esp_tls esp_tls_t; @@ -681,7 +683,6 @@ mbedtls_x509_crt *esp_tls_get_global_ca_store(void); */ const int *esp_tls_get_ciphersuites_list(void); #endif /* CONFIG_ESP_TLS_USING_MBEDTLS */ -#ifdef CONFIG_ESP_TLS_SERVER /** * @brief Create TLS/SSL server session * @@ -707,7 +708,6 @@ int esp_tls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls * @param[in] tls pointer to esp_tls_t */ void esp_tls_server_session_delete(esp_tls_t *tls); -#endif /* ! CONFIG_ESP_TLS_SERVER */ /** * @brief Creates a plain TCP connection, returning a valid socket fd on success or an error handle diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index c2730d2df5b4..5708dfcb952b 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -70,7 +70,9 @@ typedef struct esp_tls_pki_t { #endif } esp_tls_pki_t; -esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls) +static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls); + +esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params) { assert(cfg != NULL); assert(tls != NULL); @@ -116,16 +118,16 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const goto exit; } } else if (tls->role == ESP_TLS_SERVER) { -#ifdef CONFIG_ESP_TLS_SERVER - esp_ret = set_server_config((esp_tls_cfg_server_t *) cfg, tls); + if (server_params == NULL) { + /* Server params cannot be NULL when TLS role is server */ + return ESP_ERR_INVALID_ARG; + } + esp_tls_server_params_t *input_server_params = server_params; + esp_ret = input_server_params->set_server_cfg((esp_tls_cfg_server_t *) cfg, tls); if (esp_ret != 0) { ESP_LOGE(TAG, "Failed to set server configurations, returned [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); goto exit; } -#else - ESP_LOGE(TAG, "ESP_TLS_SERVER Not enabled in Kconfig"); - goto exit; -#endif } if ((ret = mbedtls_ctr_drbg_seed(&tls->ctr_drbg, @@ -353,10 +355,6 @@ void esp_mbedtls_cleanup(esp_tls_t *tls) mbedtls_x509_crt_free(tls->cacert_ptr); } tls->cacert_ptr = NULL; -#ifdef CONFIG_ESP_TLS_SERVER - mbedtls_x509_crt_free(&tls->servercert); - mbedtls_pk_free(&tls->serverkey); -#endif mbedtls_x509_crt_free(&tls->cacert); mbedtls_x509_crt_free(&tls->clientcert); mbedtls_pk_free(&tls->clientkey); @@ -478,7 +476,6 @@ static esp_err_t set_global_ca_store(esp_tls_t *tls) return ESP_OK; } -#ifdef CONFIG_ESP_TLS_SERVER #ifdef CONFIG_ESP_TLS_SERVER_SESSION_TICKETS int esp_mbedtls_server_session_ticket_write(void *p_ticket, const mbedtls_ssl_session *session, unsigned char *start, const unsigned char *end, size_t *tlen, uint32_t *lifetime) { @@ -547,7 +544,7 @@ void esp_mbedtls_server_session_ticket_ctx_free(esp_tls_server_session_ticket_ct } #endif -esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) +static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) { assert(cfg != NULL); assert(tls != NULL); @@ -679,7 +676,6 @@ esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) return ESP_OK; } -#endif /* ! CONFIG_ESP_TLS_SERVER */ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls) { @@ -903,7 +899,6 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t return ESP_OK; } -#ifdef CONFIG_ESP_TLS_SERVER /** * @brief Create TLS/SSL server session */ @@ -914,7 +909,9 @@ int esp_mbedtls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp } tls->role = ESP_TLS_SERVER; tls->sockfd = sockfd; - esp_err_t esp_ret = esp_create_mbedtls_handle(NULL, 0, cfg, tls); + esp_tls_server_params_t server_params = {}; + server_params.set_server_cfg = &set_server_config; + esp_err_t esp_ret = esp_create_mbedtls_handle(NULL, 0, cfg, tls, &server_params); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "create_ssl_handle failed, returned [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, esp_ret); @@ -946,7 +943,6 @@ void esp_mbedtls_server_session_delete(esp_tls_t *tls) free(tls); } }; -#endif /* ! CONFIG_ESP_TLS_SERVER */ esp_err_t esp_mbedtls_init_global_ca_store(void) { diff --git a/components/esp-tls/esp_tls_wolfssl.c b/components/esp-tls/esp_tls_wolfssl.c index 9c4f1771a943..733b097429da 100644 --- a/components/esp-tls/esp_tls_wolfssl.c +++ b/components/esp-tls/esp_tls_wolfssl.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -44,9 +44,7 @@ static uint8_t psk_key_array[PSK_MAX_KEY_LEN]; static uint8_t psk_key_max_len = 0; #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */ -#ifdef CONFIG_ESP_TLS_SERVER static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls); -#endif /* CONFIG_ESP_TLS_SERVER */ /* This function shall return the error message when appropriate log level has been set otherwise this function shall do nothing */ @@ -124,7 +122,7 @@ void *esp_wolfssl_get_ssl_context(esp_tls_t *tls) return (void*)tls->priv_ssl; } -esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls) +esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params) { #ifdef CONFIG_ESP_DEBUG_WOLFSSL wolfSSL_Debugging_ON(); @@ -152,16 +150,11 @@ esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const goto exit; } } else if (tls->role == ESP_TLS_SERVER) { -#ifdef CONFIG_ESP_TLS_SERVER esp_ret = set_server_config((esp_tls_cfg_server_t *) cfg, tls); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "Failed to set server configurations, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); goto exit; } -#else - ESP_LOGE(TAG, "ESP_TLS_SERVER Not enabled in menuconfig"); - goto exit; -#endif } else { ESP_LOGE(TAG, "tls->role is not valid"); @@ -321,7 +314,6 @@ static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls return ESP_OK; } -#ifdef CONFIG_ESP_TLS_SERVER static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) { int ret = WOLFSSL_FAILURE; @@ -378,7 +370,6 @@ static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls) wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd); return ESP_OK; } -#endif int esp_wolfssl_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg) { @@ -486,7 +477,6 @@ void esp_wolfssl_cleanup(esp_tls_t *tls) wolfSSL_Cleanup(); } -#ifdef CONFIG_ESP_TLS_SERVER /** * @brief Create TLS/SSL server session */ @@ -497,7 +487,9 @@ int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp } tls->role = ESP_TLS_SERVER; tls->sockfd = sockfd; - esp_err_t esp_ret = esp_create_wolfssl_handle(NULL, 0, cfg, tls); + esp_tls_server_params_t server_params = {}; + server_params.set_server_cfg = &set_server_config; + esp_err_t esp_ret = esp_create_wolfssl_handle(NULL, 0, cfg, tls, &server_params); if (esp_ret != ESP_OK) { ESP_LOGE(TAG, "create_ssl_handle failed, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret)); ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, esp_ret); @@ -531,7 +523,6 @@ void esp_wolfssl_server_session_delete(esp_tls_t *tls) free(tls); } } -#endif /* CONFIG_ESP_TLS_SERVER */ esp_err_t esp_wolfssl_init_global_ca_store(void) { diff --git a/components/esp-tls/private_include/esp_tls_mbedtls.h b/components/esp-tls/private_include/esp_tls_mbedtls.h index 5526bba98c20..6bb1071ab04b 100644 --- a/components/esp-tls/private_include/esp_tls_mbedtls.h +++ b/components/esp-tls/private_include/esp_tls_mbedtls.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,7 +46,7 @@ ssize_t esp_mbedtls_get_bytes_avail(esp_tls_t *tls); /** * Internal Callback for creating ssl handle for mbedtls */ -esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls); +esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void* server_params); /** * mbedTLS function for Initializing socket wrappers @@ -61,13 +61,6 @@ static inline void esp_mbedtls_net_init(esp_tls_t *tls) */ void *esp_mbedtls_get_ssl_context(esp_tls_t *tls); -#ifdef CONFIG_ESP_TLS_SERVER -/** - * Internal Callback for set_server_config - * - * /note :- can only be used with mbedtls ssl library - */ -esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls); /** * Internal Callback for mbedtls_server_session_create @@ -98,7 +91,6 @@ esp_err_t esp_mbedtls_server_session_ticket_ctx_init(esp_tls_server_session_tick */ void esp_mbedtls_server_session_ticket_ctx_free(esp_tls_server_session_ticket_ctx_t *cfg); #endif -#endif /** * Internal Callback for set_client_config_function diff --git a/components/esp-tls/private_include/esp_tls_private.h b/components/esp-tls/private_include/esp_tls_private.h index dcbb42070eab..4341557aaf9e 100644 --- a/components/esp-tls/private_include/esp_tls_private.h +++ b/components/esp-tls/private_include/esp_tls_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -53,21 +53,21 @@ struct esp_tls { mbedtls_x509_crt cacert; /*!< Container for the X.509 CA certificate */ mbedtls_x509_crt *cacert_ptr; /*!< Pointer to the cacert being used. */ - + union { mbedtls_x509_crt clientcert; /*!< Container for the X.509 client certificate */ + mbedtls_x509_crt servercert; /*!< Container for the X.509 server certificate */ + }; + union { mbedtls_pk_context clientkey; /*!< Container for the private key of the client certificate */ + mbedtls_pk_context serverkey; /*!< Container for the private key of the server + certificate */ + }; #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN bool use_ecdsa_peripheral; /*!< Use the ECDSA peripheral for the private key operations. */ uint8_t ecdsa_efuse_blk; /*!< The efuse block number where the ECDSA key is stored. */ #endif -#ifdef CONFIG_ESP_TLS_SERVER - mbedtls_x509_crt servercert; /*!< Container for the X.509 server certificate */ - - mbedtls_pk_context serverkey; /*!< Container for the private key of the server - certificate */ -#endif #elif CONFIG_ESP_TLS_USING_WOLFSSL void *priv_ctx; void *priv_ssl; @@ -95,3 +95,11 @@ struct esp_tls { esp_tls_error_handle_t error_handle; /*!< handle to error descriptor */ }; + +// Function pointer for the server configuration API +typedef esp_err_t (*set_server_config_func_ptr) (esp_tls_cfg_server_t *cfg, esp_tls_t *tls); + +// This struct contains any data that is only specific to the server session and not required by the client. +typedef struct esp_tls_server_params { + set_server_config_func_ptr set_server_cfg; +} esp_tls_server_params_t; diff --git a/components/esp-tls/private_include/esp_tls_wolfssl.h b/components/esp-tls/private_include/esp_tls_wolfssl.h index 32c9a42917c6..121c13477f2d 100644 --- a/components/esp-tls/private_include/esp_tls_wolfssl.h +++ b/components/esp-tls/private_include/esp_tls_wolfssl.h @@ -11,7 +11,7 @@ /** * Internal Callback for creating ssl handle for wolfssl */ -int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls); +int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params); /** * Internal Callback for wolfssl_handshake @@ -76,7 +76,6 @@ static inline void esp_wolfssl_net_init(esp_tls_t *tls) { } -#ifdef CONFIG_ESP_TLS_SERVER /** * Function to Create ESP-TLS Server session with wolfssl Stack @@ -87,5 +86,3 @@ int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp * Delete Server Session */ void esp_wolfssl_server_session_delete(esp_tls_t *tls); - -#endif diff --git a/components/esp-tls/test_apps/main/test_esp_tls.c b/components/esp-tls/test_apps/main/test_esp_tls.c index e245fc7e8bd1..f91c279a1184 100644 --- a/components/esp-tls/test_apps/main/test_esp_tls.c +++ b/components/esp-tls/test_apps/main/test_esp_tls.c @@ -76,7 +76,6 @@ TEST_CASE("esp-tls global_ca_store set free", "[esp-tls]") esp_tls_free_global_ca_store(); } -#ifdef CONFIG_ESP_TLS_SERVER TEST_CASE("esp_tls_server session create delete", "[esp-tls]") { struct esp_tls *tls = esp_tls_init(); @@ -95,4 +94,3 @@ TEST_CASE("esp_tls_server session create delete", "[esp-tls]") esp_tls_server_session_delete(tls); } -#endif diff --git a/components/esp-tls/test_apps/sdkconfig.defaults b/components/esp-tls/test_apps/sdkconfig.defaults index 60afb44a2eab..e8191f02df1c 100644 --- a/components/esp-tls/test_apps/sdkconfig.defaults +++ b/components/esp-tls/test_apps/sdkconfig.defaults @@ -5,6 +5,4 @@ CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y CONFIG_COMPILER_STACK_CHECK=y - CONFIG_ESP_TASK_WDT_EN=n -CONFIG_ESP_TLS_SERVER=y From d4544a0d5cee10f8b8c58e377934acefb15245f2 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 5 Sep 2023 14:52:39 +0530 Subject: [PATCH 055/161] fix(esp_https_server): Remove dependency on CONFIG_ESP_TLS_SERVER Closes https://github.com/espressif/esp-idf/issues/12023 --- components/esp_https_server/CMakeLists.txt | 6 ++---- components/esp_https_server/Kconfig | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/components/esp_https_server/CMakeLists.txt b/components/esp_https_server/CMakeLists.txt index 95c24291153d..916597b723c6 100644 --- a/components/esp_https_server/CMakeLists.txt +++ b/components/esp_https_server/CMakeLists.txt @@ -1,7 +1,5 @@ -if(CONFIG_ESP_HTTPS_SERVER_ENABLE OR CONFIG_IDF_DOC_BUILD) - set(src "src/https_server.c") - set(inc "include") -endif() +set(src "src/https_server.c") +set(inc "include") idf_component_register(SRCS ${src} INCLUDE_DIRS ${inc} diff --git a/components/esp_https_server/Kconfig b/components/esp_https_server/Kconfig index 4fae425f0f77..f4cd30282c36 100644 --- a/components/esp_https_server/Kconfig +++ b/components/esp_https_server/Kconfig @@ -3,7 +3,6 @@ menu "ESP HTTPS server" config ESP_HTTPS_SERVER_ENABLE bool "Enable ESP_HTTPS_SERVER component" depends on (ESP_TLS_USING_MBEDTLS && MBEDTLS_TLS_SERVER) - select ESP_TLS_SERVER help Enable ESP HTTPS server component From a0d73b5155c8a694f29630015c0d2178d71021e1 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 10 Oct 2023 16:27:59 +0530 Subject: [PATCH 056/161] fix(esp_https_server): Convert HTTPD_SSL_CONFIG_DEFAULT MACRO to function Previously with HTTPD_SSL_CONFIG_DEFAULT being a MACRO, the configuration options could not be applied to it. This was casuing error in multiple scenarios. For e.g., here user_cert_cb is a part of httpd_ssl_config_t which this macro defines. But the type of user_cert_cb (esp_tls_server_callback_t) is only available when it is enabled in esp-tls. The MACRO however cannot be modified to set the defaults based on configuration option. This fix solves the issue without breaking the compatibility --- .../include/esp_https_server.h | 58 +++---------------- .../esp_https_server/src/https_server.c | 54 +++++++++++++++++ .../https_server/simple/sdkconfig.ci | 1 + 3 files changed, 64 insertions(+), 49 deletions(-) diff --git a/components/esp_https_server/include/esp_https_server.h b/components/esp_https_server/include/esp_https_server.h index 1fd31b454398..0a598f602ecf 100644 --- a/components/esp_https_server/include/esp_https_server.h +++ b/components/esp_https_server/include/esp_https_server.h @@ -104,70 +104,30 @@ struct httpd_ssl_config { esp_https_server_user_cb *user_cb; void *ssl_userdata; /*!< user data to add to the ssl context */ +#if CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK esp_tls_handshake_callback cert_select_cb; /*!< Certificate selection callback to use */ +#endif const char** alpn_protos; /*!< Application protocols the server supports in order of prefernece. Used for negotiating during the TLS handshake, first one the client supports is selected. The data structure must live as long as the https server itself! */ }; typedef struct httpd_ssl_config httpd_ssl_config_t; +/* Macro kept for compatibility reasons */ +#define HTTPD_SSL_CONFIG_DEFAULT httpd_ssl_config_default /** - * Default config struct init - * - * (http_server default config had to be copied for customization) + * Returns the httpd config struct with default initialisation * + * @return + * httpd_ssl_config_t HTTPD ssl config struct + * with default initialisation * Notes: * - port is set when starting the server, according to 'transport_mode' * - one socket uses ~ 40kB RAM with SSL, we reduce the default socket count to 4 * - SSL sockets are usually long-lived, closing LRU prevents pool exhaustion DOS * - Stack size may need adjustments depending on the user application */ -#define HTTPD_SSL_CONFIG_DEFAULT() { \ - .httpd = { \ - .task_priority = tskIDLE_PRIORITY+5, \ - .stack_size = 10240, \ - .core_id = tskNO_AFFINITY, \ - .server_port = 0, \ - .ctrl_port = ESP_HTTPD_DEF_CTRL_PORT+1, \ - .max_open_sockets = 4, \ - .max_uri_handlers = 8, \ - .max_resp_headers = 8, \ - .backlog_conn = 5, \ - .lru_purge_enable = true, \ - .recv_wait_timeout = 5, \ - .send_wait_timeout = 5, \ - .global_user_ctx = NULL, \ - .global_user_ctx_free_fn = NULL, \ - .global_transport_ctx = NULL, \ - .global_transport_ctx_free_fn = NULL, \ - .enable_so_linger = false, \ - .linger_timeout = 0, \ - .keep_alive_enable = false, \ - .keep_alive_idle = 0, \ - .keep_alive_interval = 0, \ - .keep_alive_count = 0, \ - .open_fn = NULL, \ - .close_fn = NULL, \ - .uri_match_fn = NULL \ - }, \ - .servercert = NULL, \ - .servercert_len = 0, \ - .cacert_pem = NULL, \ - .cacert_len = 0, \ - .prvtkey_pem = NULL, \ - .prvtkey_len = 0, \ - .use_ecdsa_peripheral = false, \ - .ecdsa_key_efuse_blk = 0, \ - .transport_mode = HTTPD_SSL_TRANSPORT_SECURE, \ - .port_secure = 443, \ - .port_insecure = 80, \ - .session_tickets = false, \ - .use_secure_element = false, \ - .user_cb = NULL, \ - .ssl_userdata = NULL, \ - .cert_select_cb = NULL, \ - .alpn_protos = NULL, \ -} +httpd_ssl_config_t httpd_ssl_config_default(void); /** * Create a SSL capable HTTP server (secure mode may be disabled in config) diff --git a/components/esp_https_server/src/https_server.c b/components/esp_https_server/src/https_server.c index c224b7c0e1c1..42a29c3b746d 100644 --- a/components/esp_https_server/src/https_server.c +++ b/components/esp_https_server/src/https_server.c @@ -48,6 +48,60 @@ static void httpd_ssl_close(void *ctx) ESP_LOGD(TAG, "Secure socket closed"); } +httpd_ssl_config_t httpd_ssl_config_default(void) +{ + httpd_ssl_config_t config = { + .httpd = { + .task_priority = tskIDLE_PRIORITY + 5, + .stack_size = 10240, + .core_id = tskNO_AFFINITY, + .server_port = 0, + .ctrl_port = ESP_HTTPD_DEF_CTRL_PORT + 1, + .max_open_sockets = 4, + .max_uri_handlers = 8, + .max_resp_headers = 8, + .backlog_conn = 5, + .lru_purge_enable = true, + .recv_wait_timeout = 5, + .send_wait_timeout = 5, + .global_user_ctx = NULL, + .global_user_ctx_free_fn = NULL, + .global_transport_ctx = NULL, + .global_transport_ctx_free_fn = NULL, + .enable_so_linger = false, + .linger_timeout = 0, + .keep_alive_enable = false, + .keep_alive_idle = 0, + .keep_alive_interval = 0, + .keep_alive_count = 0, + .open_fn = NULL, + .close_fn = NULL, + .uri_match_fn = NULL, + }, + .servercert = NULL, + .servercert_len = 0, + .cacert_pem = NULL, + .cacert_len = 0, + .prvtkey_pem = NULL, + .prvtkey_len = 0, + .use_ecdsa_peripheral = false, + .ecdsa_key_efuse_blk = 0, + .transport_mode = HTTPD_SSL_TRANSPORT_SECURE, + .port_secure = 443, + .port_insecure = 80, + .session_tickets = false, + .use_secure_element = false, + .user_cb = NULL, + .ssl_userdata = NULL, +#if CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK + .cert_select_cb = NULL, +#endif + .alpn_protos = NULL, + }; + + return config; +} + /** * SSL socket pending-check function * diff --git a/examples/protocols/https_server/simple/sdkconfig.ci b/examples/protocols/https_server/simple/sdkconfig.ci index 84ffce91b891..5c2b28801375 100644 --- a/examples/protocols/https_server/simple/sdkconfig.ci +++ b/examples/protocols/https_server/simple/sdkconfig.ci @@ -1,3 +1,4 @@ CONFIG_ESP_HTTPS_SERVER_ENABLE=y +CONFIG_ESP_TLS_CERT_SELECT_HOOK=y CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK=y CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y From 804ed172ddebe0eb216c41c345976b6203c94683 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Wed, 11 Oct 2023 13:41:37 +0530 Subject: [PATCH 057/161] fix(mbedtls): allow to use built in entropy implementation for linux target --- components/mbedtls/CMakeLists.txt | 6 ++++-- components/mbedtls/port/include/mbedtls/esp_config.h | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 0726b0da97f3..3d2ad9d8553e 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -192,8 +192,10 @@ if(AES_PERIPHERAL_TYPE STREQUAL "dma") endif() -target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c" - "${COMPONENT_DIR}/port/esp_mem.c" +if(NOT ${IDF_TARGET} STREQUAL "linux") + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_hardware.c") +endif() +target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_mem.c" "${COMPONENT_DIR}/port/esp_timing.c" ) diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 9aebf99e299b..0bf4d3e60369 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -232,6 +232,7 @@ #undef MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK #endif +#ifndef CONFIG_IDF_TARGET_LINUX /** * \def MBEDTLS_ENTROPY_HARDWARE_ALT * @@ -244,6 +245,7 @@ * Uncomment to use your own hardware entropy collector. */ #define MBEDTLS_ENTROPY_HARDWARE_ALT +#endif // !CONFIG_IDF_TARGET_LINUX /** * \def MBEDTLS_AES_ROM_TABLES @@ -866,6 +868,7 @@ */ #define MBEDTLS_FS_IO +#ifndef CONFIG_IDF_TARGET_LINUX /** * \def MBEDTLS_NO_PLATFORM_ENTROPY * @@ -876,6 +879,7 @@ * Uncomment this macro to disable the built-in platform entropy functions. */ #define MBEDTLS_NO_PLATFORM_ENTROPY +#endif // !CONFIG_IDF_TARGET_LINUX /** * \def MBEDTLS_PK_RSA_ALT_SUPPORT From 030cac07df2553d861b8c5eed7295ab651608efe Mon Sep 17 00:00:00 2001 From: Xu Si Yu Date: Fri, 20 Oct 2023 18:52:38 +0800 Subject: [PATCH 058/161] fix(coex): fix esp32c6 wrong reg offset --- components/esp_coex/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_coex/lib b/components/esp_coex/lib index ad378ec993cd..68cbbdb45cdc 160000 --- a/components/esp_coex/lib +++ b/components/esp_coex/lib @@ -1 +1 @@ -Subproject commit ad378ec993cde453b0c93439aa4dbcd317970ccf +Subproject commit 68cbbdb45cdc8c88ffbfc2587a4e7af020695e56 From 7a1db4befbc2170b408299809ce020ade8ce6a14 Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Mon, 23 Oct 2023 15:03:38 +0800 Subject: [PATCH 059/161] feat(bt/bluedroid): support clear legacy advertising --- .../bt/host/bluedroid/api/esp_gap_ble_api.c | 13 +++++++++ .../api/include/api/esp_gap_ble_api.h | 18 ++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 9 ++++++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 23 +++++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 1 + .../bluedroid/bta/dm/include/bta_dm_int.h | 8 ++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 15 ++++++++++ .../btc/profile/std/gap/btc_gap_ble.c | 28 ++++++++++++++++++- .../btc/profile/std/include/btc_gap_ble.h | 3 ++ .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 22 +++++++++++++++ .../bt/host/bluedroid/stack/btm/btm_devctl.c | 8 ++++++ .../bluedroid/stack/btm/include/btm_ble_int.h | 1 + .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 21 ++++++++++++++ .../stack/include/stack/btm_ble_api.h | 12 ++++++++ .../bluedroid/stack/include/stack/hcidefs.h | 4 +++ .../bluedroid/stack/include/stack/hcimsgs.h | 7 +++-- 16 files changed, 190 insertions(+), 3 deletions(-) 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 65d24518c209..9a99c9c5f830 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -122,6 +122,19 @@ esp_err_t esp_ble_gap_stop_advertising(void) return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } + +esp_err_t esp_ble_gap_clear_advertising(void) +{ + btc_msg_t msg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_CLEAR_ADV; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params) 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 4ee8154affde..faee853fd9fa 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 @@ -222,6 +222,8 @@ typedef enum { ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT, /*!< when periodic advertising sync transfer received, the event comes */ // DTM ESP_GAP_BLE_DTM_TEST_UPDATE_EVT, /*!< when direct test mode state changes, the event comes */ + // BLE_INCLUDED + ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT, /*!< When clear advertising complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -1086,6 +1088,12 @@ typedef union { struct ble_adv_stop_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate adv stop operation success status */ } adv_stop_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT + */ + struct ble_adv_clear_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate adv clear operation success status */ + } adv_clear_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT */ #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) /** * @brief ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT @@ -2499,6 +2507,16 @@ esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params); */ esp_err_t esp_ble_dtm_stop(void); +/** +* @brief This function is used to clear legacy advertising +* +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_clear_advertising(void); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 82fa8ff0fe6d..02137ad43d27 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5702,6 +5702,15 @@ void bta_dm_ble_gap_dtm_stop(tBTA_DM_MSG *p_data) BTM_BleTestEnd(p_data->dtm_stop.p_dtm_cmpl_cback); } +void bta_dm_ble_gap_clear_adv(tBTA_DM_MSG *p_data) +{ + if (BTM_BleClearAdv(p_data->ble_clear_adv.p_clear_adv_cback) == FALSE) { + if (p_data->ble_clear_adv.p_clear_adv_cback) { + (*p_data->ble_clear_adv.p_clear_adv_cback)(BTA_FAILURE); + } + } +} + #if (BLE_50_FEATURE_SUPPORT == TRUE) void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data) { diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index ede373efde8a..95301cb40386 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -1813,6 +1813,29 @@ extern void BTA_DmBleBroadcast (BOOLEAN start, tBTA_START_STOP_ADV_CMPL_CBACK *p } } +/******************************************************************************* +** +** Function BTA_DmBleClearAdv +** +** Description This function is called to clear Advertising +** +** Parameters p_adv_data_cback : clear adv complete callback. +** +** Returns None +** +*******************************************************************************/ +void BTA_DmBleClearAdv (tBTA_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback) +{ + tBTA_DM_API_CLEAR_ADV *p_msg; + + if ((p_msg = (tBTA_DM_API_CLEAR_ADV *) + osi_malloc(sizeof(tBTA_DM_API_CLEAR_ADV))) != NULL) { + p_msg->hdr.event = BTA_DM_API_BLE_CLEAR_ADV_EVT; + p_msg->p_clear_adv_cback = p_clear_adv_cback; + + bta_sys_sendmsg(p_msg); + } +} #endif /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 83e8b12ca825..bff904532907 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -224,6 +224,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_dtm_tx_start, /* BTA_DM_API_DTM_TX_START_EVT */ bta_dm_ble_gap_dtm_rx_start, /* BTA_DM_API_DTM_RX_START_EVT */ bta_dm_ble_gap_dtm_stop, /* BTA_DM_API_DTM_STOP_EVT */ + bta_dm_ble_gap_clear_adv, /* BTA_DM_API_BLE_CLEAR_ADV_EVT */ #endif }; diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 6694c0dfc2b7..10823c9c96a9 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -217,6 +217,7 @@ enum { BTA_DM_API_DTM_TX_START_EVT, BTA_DM_API_DTM_RX_START_EVT, BTA_DM_API_DTM_STOP_EVT, + BTA_DM_API_BLE_CLEAR_ADV_EVT, #endif BTA_DM_MAX_EVT }; @@ -896,6 +897,11 @@ typedef struct { tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; } tBTA_DM_API_BLE_DTM_STOP; +typedef struct { + BT_HDR hdr; + tBTA_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback; +} tBTA_DM_API_CLEAR_ADV; + #endif /* BLE_INCLUDED */ /* data type for BTA_DM_API_REMOVE_ACL_EVT */ @@ -1293,6 +1299,7 @@ typedef union { tBTA_DM_API_BLE_DTM_TX_START dtm_tx_start; tBTA_DM_API_BLE_DTM_RX_START dtm_rx_start; tBTA_DM_API_BLE_DTM_STOP dtm_stop; + tBTA_DM_API_CLEAR_ADV ble_clear_adv; #endif tBTA_DM_API_REMOVE_ACL remove_acl; @@ -1732,6 +1739,7 @@ extern void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_dtm_tx_start(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_dtm_rx_start(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_dtm_stop(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_clear_adv(tBTA_DM_MSG *p_data); #if (BLE_50_FEATURE_SUPPORT == TRUE) extern void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index bddc51bc007c..e59bee7c08ef 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1243,6 +1243,8 @@ typedef void (tBTA_START_STOP_SCAN_CMPL_CBACK) (tBTA_STATUS status); typedef void (tBTA_START_STOP_ADV_CMPL_CBACK) (tBTA_STATUS status); +typedef void (tBTA_CLEAR_ADV_CMPL_CBACK) (tBTA_STATUS status); + typedef void (tBTA_BLE_TRACK_ADV_CMPL_CBACK)(int action, tBTA_STATUS status, tBTA_DM_BLE_PF_AVBL_SPACE avbl_space, tBTA_DM_BLE_REF_VALUE ref_value); @@ -2654,6 +2656,19 @@ extern void BTA_DmBleSetAdvConfigRaw (UINT8 *p_raw_adv, UINT32 raw_adv_len, void BTA_DmBleSetLongAdv (UINT8 *adv_data, UINT32 adv_data_len, tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback); +/******************************************************************************* +** +** Function BTA_DmBleClearAdv +** +** Description This function is called to clear Advertising +** +** Parameters p_adv_data_cback : clear adv complete callback. +** +** Returns None +** +*******************************************************************************/ +void BTA_DmBleClearAdv (tBTA_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback); + /******************************************************************************* ** ** Function BTA_DmBleSetScanRsp diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 4364f3802696..fdafb67c910e 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -470,6 +470,25 @@ static void btc_stop_adv_callback(uint8_t status) } } +static void btc_clear_adv_callback(uint8_t status) +{ + esp_ble_gap_cb_param_t param; + bt_status_t ret; + btc_msg_t msg = {0}; + + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BLE; + msg.act = ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT; + param.adv_clear_cmpl.status = btc_hci_to_esp_status(status); + + ret = btc_transfer_context(&msg, ¶m, + sizeof(esp_ble_gap_cb_param_t), NULL, NULL); + + if (ret != BT_STATUS_SUCCESS) { + BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); + } +} + void btc_update_duplicate_exceptional_list_callback(tBTA_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info) { esp_ble_gap_cb_param_t param; @@ -1257,13 +1276,17 @@ static void btc_ble_stop_scanning(tBTA_START_STOP_SCAN_CMPL_CBACK *stop_scan_cb) BTA_DmBleScan(false, duration, NULL, stop_scan_cb); } - static void btc_ble_stop_advertising(tBTA_START_STOP_ADV_CMPL_CBACK *stop_adv_cb) { bool stop_adv = false; BTA_DmBleBroadcast(stop_adv, stop_adv_cb); } + +static void btc_ble_clear_advertising(tBTA_CLEAR_ADV_CMPL_CBACK *clear_adv_cb) +{ + BTA_DmBleClearAdv(clear_adv_cb); +} #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) static void btc_ble_update_conn_params(BD_ADDR bd_addr, uint16_t min_int, uint16_t max_int, uint16_t latency, uint16_t timeout) @@ -1731,6 +1754,9 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) case BTC_GAP_BLE_ACT_STOP_ADV: btc_ble_stop_advertising(btc_stop_adv_callback); break; + case BTC_GAP_BLE_ACT_CLEAR_ADV: + btc_ble_clear_advertising(btc_clear_adv_callback); + break; #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) case BTC_GAP_BLE_ACT_UPDATE_CONN_PARAM: btc_ble_update_conn_params(arg->conn_update_params.conn_params.bda, diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index 89d72d05d566..3fb5f4b34eaa 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -99,6 +99,9 @@ typedef enum { BTC_GAP_BLE_DTM_RX_START, #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) BTC_GAP_BLE_DTM_STOP, +#if (BLE_42_FEATURE_SUPPORT == TRUE) + BTC_GAP_BLE_ACT_CLEAR_ADV, +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ 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 2ce4488e38e6..432173d5d262 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -4669,6 +4669,28 @@ BOOLEAN BTM_Ble_Authorization(BD_ADDR bd_addr, BOOLEAN authorize) return FALSE; } +/******************************************************************************* +** +** Function BTM_BleClearAdv +** +** Description This function is called to clear legacy advertising +** +** Parameter p_clear_adv_cback - Command complete callback +** +*******************************************************************************/ +BOOLEAN BTM_BleClearAdv(tBTM_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback) +{ + tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; + + if (btsnd_hcic_ble_clear_adv() == FALSE) { + BTM_TRACE_ERROR("%s: Unable to Clear Advertising", __FUNCTION__); + return FALSE; + } + + p_cb->inq_var.p_clear_adv_cb = p_clear_adv_cback; + return TRUE; +} + bool btm_ble_adv_pkt_ready(void) { tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index 0656f18f99aa..bffb5bbee0e8 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -731,6 +731,14 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len, } break; } + case HCI_VENDOR_BLE_CLEAR_ADV: { + uint8_t status; + STREAM_TO_UINT8(status, p); + if (ble_cb && ble_cb->inq_var.p_clear_adv_cb) { + ble_cb->inq_var.p_clear_adv_cb(status); + } + break; + } default: break; } diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 2f864b04ecd3..1f55289c75d1 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -159,6 +159,7 @@ typedef struct { tBTM_BLE_SFP sfp; /* scanning filter policy */ tBTM_START_ADV_CMPL_CBACK *p_adv_cb; tBTM_START_STOP_ADV_CMPL_CBACK *p_stop_adv_cb; + tBTM_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cb; tBLE_ADDR_TYPE adv_addr_type; UINT8 evt_type; UINT8 adv_mode; diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 1f12c344b302..0324002792c6 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1084,6 +1084,27 @@ BOOLEAN btsnd_hcic_ble_set_channels (BLE_CHANNELS channels) return (TRUE); } +BOOLEAN btsnd_hcic_ble_clear_adv (void) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_CLEAR_ADV)) == NULL) { + return (FALSE); + } + + pp = (UINT8 *)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CLEAR_ADV; + p->offset = 0; + + UINT16_TO_STREAM (pp, HCI_VENDOR_BLE_CLEAR_ADV); + UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_CLEAR_ADV); + + btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + #define HCIC_BLE_CMD_CREATED(p, pp, size) do{\ if ((p = HCI_GET_CMD_BUF(size)) == NULL) { \ return FALSE; \ 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 3df5120421a8..f64500656bef 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 @@ -1000,6 +1000,7 @@ typedef void (tBTM_START_ADV_CMPL_CBACK) (UINT8 status); typedef void (tBTM_START_STOP_ADV_CMPL_CBACK) (UINT8 status); typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS status, uint8_t subcode, uint32_t length, uint8_t *device_info); +typedef void (tBTM_CLEAR_ADV_CMPL_CBACK) (UINT8 status); #if (BLE_50_FEATURE_SUPPORT == TRUE) #define BTM_BLE_5_GAP_READ_PHY_COMPLETE_EVT 1 #define BTM_BLE_5_GAP_SET_PREFERED_DEFAULT_PHY_COMPLETE_EVT 2 @@ -2638,6 +2639,17 @@ BOOLEAN BTM_GetCurrentConnParams(BD_ADDR bda, uint16_t *interval, uint16_t *late ** *******************************************************************************/ BOOLEAN BTM_Ble_Authorization(BD_ADDR bd_addr, BOOLEAN authorize); + +/******************************************************************************* +** +** Function BTM_BleClearAdv +** +** Description This function is called to clear legacy advertising +** +** Parameter p_clear_adv_cback - Command complete callback +** +*******************************************************************************/ +BOOLEAN BTM_BleClearAdv(tBTM_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback); /* #ifdef __cplusplus } diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 22d5727133b7..8c5ba3f2f045 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -419,6 +419,8 @@ #define HCI_SUBCODE_BLE_DUPLICATE_EXCEPTIONAL_LIST 0x08 #define HCI_SUBCODE_BLE_SET_ADV_FLOW_CONTROL 0x09 #define HCI_SUBCODE_BLE_ADV_REPORT_FLOW_CONTROL 0x0A +#define HCI_SUBCODE_BLE_RD_STATIC_ADDR 0x0B +#define HCI_SUBCODE_BLE_CLEAR_ADV 0x0C #define HCI_SUBCODE_BLE_MAX 0x7F //ESP BT subcode define @@ -462,6 +464,8 @@ #define HCI_VENDOR_BLE_UPDATE_DUPLICATE_EXCEPTIONAL_LIST HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_DUPLICATE_EXCEPTIONAL_LIST) #define HCI_VENDOR_BLE_SET_ADV_FLOW_CONTROL HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_SET_ADV_FLOW_CONTROL) #define HCI_VENDOR_BLE_ADV_REPORT_FLOW_CONTROL HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_ADV_REPORT_FLOW_CONTROL) +/* BLE clear legacy advertising */ +#define HCI_VENDOR_BLE_CLEAR_ADV HCI_ESP_VENDOR_OPCODE_BUILD(HCI_VENDOR_OGF, HCI_ESP_GROUP_BLE, HCI_SUBCODE_BLE_CLEAR_ADV) //ESP BT HCI CMD /* subcode for multi adv feature */ diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index d8ef269e2089..bd328fab2389 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -751,8 +751,9 @@ void btsnd_hcic_vendor_spec_cmd (BT_HDR *buffer, UINT16 opcode, #define HCIC_PARAM_SIZE_BLE_SET_ADDR_RESOLUTION_ENABLE 1 #define HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT 2 #define HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH 6 -#define HCIC_PARAM_SIZE_BLE_WRITE_EXTENDED_SCAN_PARAM 11 -#define HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL 2 +#define HCIC_PARAM_SIZE_BLE_WRITE_EXTENDED_SCAN_PARAM 11 +#define HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL 2 +#define HCIC_PARAM_SIZE_BLE_CLEAR_ADV 0 #if (BLE_50_FEATURE_SUPPORT == TRUE) #define HCIC_PARAM_SIZE_BLE_READ_PHY 2 #define HCIC_PARAM_SIZE_BLE_SET_DEF_PHY 3 @@ -906,6 +907,8 @@ BOOLEAN btsnd_hcic_ble_set_addr_resolution_enable (UINT8 addr_resolution_enable) BOOLEAN btsnd_hcic_ble_set_rand_priv_addr_timeout (UINT16 rpa_timout); +BOOLEAN btsnd_hcic_ble_clear_adv(void); + #endif /* BLE_INCLUDED */ #if (BLE_50_FEATURE_SUPPORT == TRUE) typedef struct { From 2e762ae3f7e736aef7c38100b6e68f0bcfc47a12 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Thu, 26 Oct 2023 19:21:21 +0800 Subject: [PATCH 060/161] fix(bt/bluedroid): Fix key size check in BLE smp --- components/bt/host/bluedroid/bta/dm/bta_dm_co.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c index caf5e6872e28..c6b62f3a6f77 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c @@ -356,7 +356,7 @@ void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap, *p_resp_key = bte_appl_cfg.ble_resp_key; } - if (bte_appl_cfg.ble_max_key_size > 7 && bte_appl_cfg.ble_max_key_size <= 16) { + if (bte_appl_cfg.ble_max_key_size >= 7 && bte_appl_cfg.ble_max_key_size <= 16) { *p_max_key_size = bte_appl_cfg.ble_max_key_size; } #endif ///SMP_INCLUDED == TRUE From 58b6add55c6766ab18255c1c9059782435548f40 Mon Sep 17 00:00:00 2001 From: Ondrej Date: Thu, 26 Oct 2023 11:38:28 +0000 Subject: [PATCH 061/161] ci(esp_eth): make additional Ethernet chips test as nightly run --- components/esp_eth/test_apps/pytest_esp_eth.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/components/esp_eth/test_apps/pytest_esp_eth.py b/components/esp_eth/test_apps/pytest_esp_eth.py index e6b83c4980e8..921636f4419a 100644 --- a/components/esp_eth/test_apps/pytest_esp_eth.py +++ b/components/esp_eth/test_apps/pytest_esp_eth.py @@ -214,6 +214,7 @@ def test_esp_eth_ip101(dut: IdfDut) -> None: # ----------- LAN8720 ----------- @pytest.mark.esp32 @pytest.mark.eth_lan8720 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_lan8720', ], indirect=True) @@ -226,6 +227,7 @@ def test_esp_eth_lan8720(dut: IdfDut) -> None: # ----------- RTL8201 ----------- @pytest.mark.esp32 @pytest.mark.eth_rtl8201 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_rtl8201', ], indirect=True) @@ -238,6 +240,7 @@ def test_esp_eth_rtl8201(dut: IdfDut) -> None: # ----------- KSZ8041 ----------- @pytest.mark.esp32 @pytest.mark.eth_ksz8041 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_ksz8041', ], indirect=True) @@ -250,6 +253,7 @@ def test_esp_eth_ksz8041(dut: IdfDut) -> None: # ----------- DP83848 ----------- @pytest.mark.esp32 @pytest.mark.eth_dp83848 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_dp83848', ], indirect=True) @@ -262,6 +266,7 @@ def test_esp_eth_dp83848(dut: IdfDut) -> None: # ----------- W5500 ----------- @pytest.mark.esp32 @pytest.mark.eth_w5500 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_w5500', ], indirect=True) @@ -274,6 +279,7 @@ def test_esp_eth_w5500(dut: IdfDut) -> None: # ----------- KSZ8851SNL ----------- @pytest.mark.esp32 @pytest.mark.eth_ksz8851snl +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_ksz8851snl', ], indirect=True) @@ -286,6 +292,7 @@ def test_esp_eth_ksz8851snl(dut: IdfDut) -> None: # ----------- DM9051 ----------- @pytest.mark.esp32 @pytest.mark.eth_dm9051 +@pytest.mark.nightly_run @pytest.mark.parametrize('config', [ 'default_dm9051', ], indirect=True) From 420ac840ff785a370c0bde3845a9f86758b8ca06 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Tue, 24 Oct 2023 11:31:33 +0800 Subject: [PATCH 062/161] fix(flash_encryption): Fix the issue that XTS_AES Plain text memory size wrong --- components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h | 4 +++- components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h | 4 +++- components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h | 4 +++- components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h | 4 +++- components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h | 4 +++- components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h | 4 +++- components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h | 4 +++- components/soc/esp32c6/include/soc/Kconfig.soc_caps.in | 2 +- components/soc/esp32c6/include/soc/soc_caps.h | 2 +- components/soc/esp32h2/include/soc/Kconfig.soc_caps.in | 2 +- components/soc/esp32h2/include/soc/soc_caps.h | 2 +- components/soc/esp32p4/include/soc/Kconfig.soc_caps.in | 2 +- components/soc/esp32p4/include/soc/soc_caps.h | 2 +- 13 files changed, 27 insertions(+), 13 deletions(-) diff --git a/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h index 6717fc87c0da..8d59c99148ae 100644 --- a/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c2/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/system_reg.h" #include "soc/xts_aes_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -84,7 +85,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(XTS_AES_PLAIN_MEM + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h index 1196d16c12f1..8857e1f915ab 100644 --- a/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c3/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/system_reg.h" #include "soc/xts_aes_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -84,7 +85,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(XTS_AES_PLAIN_MEM + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h index 5e05cd6aba0f..20c303344a43 100644 --- a/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32c6/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/hp_system_reg.h" #include "soc/xts_aes_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -84,7 +85,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(XTS_AES_PLAIN_MEM(0) + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h index 5e05cd6aba0f..20c303344a43 100644 --- a/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32h2/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/hp_system_reg.h" #include "soc/xts_aes_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -84,7 +85,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(XTS_AES_PLAIN_MEM(0) + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h index 398839abaf81..de642b56d692 100644 --- a/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/hp_system_reg.h" #include "soc/spi_mem_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -88,7 +89,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(SPI_MEM_XTS_PLAIN_BASE_REG(0) + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h index 34d38742cfef..529fb990076d 100644 --- a/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32s2/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/system_reg.h" #include "soc/hwcrypto_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -93,7 +94,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(AES_XTS_PLAIN_BASE + plaintext_offs), buffer, size); } diff --git a/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h index cac478ee5146..dae3528dd9d0 100644 --- a/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32s3/include/hal/spi_flash_encrypted_ll.h @@ -17,6 +17,7 @@ #include "soc/system_reg.h" #include "soc/hwcrypto_reg.h" #include "soc/soc.h" +#include "soc/soc_caps.h" #include "hal/assert.h" #ifdef __cplusplus @@ -84,7 +85,8 @@ static inline void spi_flash_encrypt_ll_buffer_length(uint32_t size) */ static inline void spi_flash_encrypt_ll_plaintext_save(uint32_t address, const uint32_t* buffer, uint32_t size) { - uint32_t plaintext_offs = (address % 64); + uint32_t plaintext_offs = (address % SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); + HAL_ASSERT(plaintext_offs + size <= SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX); memcpy((void *)(AES_XTS_PLAIN_BASE + plaintext_offs), buffer, size); } diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index cb4f3353cd62..fbca618fb766 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1113,7 +1113,7 @@ config SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY config SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX int - default 32 + default 64 config SOC_FLASH_ENCRYPTION_XTS_AES bool diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 74f167076769..d82e4dba855d 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -455,7 +455,7 @@ #define SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY 1 /*-------------------------- Flash Encryption CAPS----------------------------*/ -#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (32) +#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (64) #define SOC_FLASH_ENCRYPTION_XTS_AES 1 #define SOC_FLASH_ENCRYPTION_XTS_AES_128 1 diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 82c436d287ad..110397316c1f 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1093,7 +1093,7 @@ config SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY config SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX int - default 32 + default 64 config SOC_FLASH_ENCRYPTION_XTS_AES bool diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 6df8be00681c..f267085e02df 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -448,7 +448,7 @@ #define SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY 1 /*-------------------------- Flash Encryption CAPS----------------------------*/ -#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (32) +#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (64) #define SOC_FLASH_ENCRYPTION_XTS_AES 1 #define SOC_FLASH_ENCRYPTION_XTS_AES_128 1 diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 37bf7397360c..04d59467bafa 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1069,7 +1069,7 @@ config SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY config SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX int - default 32 + default 64 config SOC_FLASH_ENCRYPTION_XTS_AES bool diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 35685464f654..82ffb8d8764d 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -479,7 +479,7 @@ #define SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY 1 /*-------------------------- Flash Encryption CAPS----------------------------*/ -#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (32) +#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (64) #define SOC_FLASH_ENCRYPTION_XTS_AES 1 #define SOC_FLASH_ENCRYPTION_XTS_AES_128 1 From ada56ca062c1b08ff2bf7f17b1237588ac7933dc Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Thu, 26 Oct 2023 17:24:14 +0800 Subject: [PATCH 063/161] Update bt lib for ESP32-C3 and ESP32-S3(f817304) - Support get the range of TX power level - Support clear legacy adv using vendor hci --- components/bt/controller/lib_esp32c3_family | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family index af6be404ea58..ec7ef197cb80 160000 --- a/components/bt/controller/lib_esp32c3_family +++ b/components/bt/controller/lib_esp32c3_family @@ -1 +1 @@ -Subproject commit af6be404ea583da57f9a4f0dfe7e02351ff5aa0d +Subproject commit ec7ef197cb8018c468cd59dca893dbe018f47a2a From 8171b22c40f39a75cd0db62165e7ef017f78c572 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Wed, 25 Oct 2023 10:47:02 +0200 Subject: [PATCH 064/161] change(version): Update version to 5.3.0 --- .gitlab/ci/common.yml | 8 ++++---- components/esp_common/include/esp_idf_version.h | 2 +- tools/cmake/version.cmake | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitlab/ci/common.yml b/.gitlab/ci/common.yml index 6ba8f3f33ab8..2109985f36ee 100644 --- a/.gitlab/ci/common.yml +++ b/.gitlab/ci/common.yml @@ -45,10 +45,10 @@ variables: PYTHON_VER: 3.8.17 # Docker images - ESP_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-env-v5.2:2" - ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env-v5.2:2-1" - QEMU_IMAGE: "${CI_DOCKER_REGISTRY}/qemu-v5.2:2-20230522" - TARGET_TEST_ENV_IMAGE: "$CI_DOCKER_REGISTRY/target-test-env-v5.2:2" + ESP_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-env-v5.3:1" + ESP_IDF_DOC_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env-v5.3:1-1" + QEMU_IMAGE: "${CI_DOCKER_REGISTRY}/qemu-v5.3:1-20230522" + TARGET_TEST_ENV_IMAGE: "$CI_DOCKER_REGISTRY/target-test-env-v5.3:1" SONARQUBE_SCANNER_IMAGE: "${CI_DOCKER_REGISTRY}/sonarqube-scanner:5" diff --git a/components/esp_common/include/esp_idf_version.h b/components/esp_common/include/esp_idf_version.h index cc68d2d1329b..4cb488257a4f 100644 --- a/components/esp_common/include/esp_idf_version.h +++ b/components/esp_common/include/esp_idf_version.h @@ -13,7 +13,7 @@ extern "C" { /** Major version number (X.x.x) */ #define ESP_IDF_VERSION_MAJOR 5 /** Minor version number (x.X.x) */ -#define ESP_IDF_VERSION_MINOR 2 +#define ESP_IDF_VERSION_MINOR 3 /** Patch version number (x.x.X) */ #define ESP_IDF_VERSION_PATCH 0 diff --git a/tools/cmake/version.cmake b/tools/cmake/version.cmake index 037b9c088fe0..4db536bdaa55 100644 --- a/tools/cmake/version.cmake +++ b/tools/cmake/version.cmake @@ -1,5 +1,5 @@ set(IDF_VERSION_MAJOR 5) -set(IDF_VERSION_MINOR 2) +set(IDF_VERSION_MINOR 3) set(IDF_VERSION_PATCH 0) set(ENV{IDF_VERSION} "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}.${IDF_VERSION_PATCH}") From 0bf1dce413266c636048b801b12258d9732c8230 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Thu, 26 Oct 2023 14:04:00 +0800 Subject: [PATCH 065/161] refactor(i2c): Add reset and clock control to i2c ll layer --- components/driver/i2c/i2c.c | 41 ++++++++++++++---- components/driver/i2c/i2c_common.c | 14 +++++-- components/driver/i2c/i2c_master.c | 10 ++++- components/driver/i2c/i2c_private.h | 13 ++++++ components/driver/i2c/i2c_slave.c | 4 +- components/hal/esp32/include/hal/i2c_ll.h | 46 +++++++++++++++++++++ components/hal/esp32c2/include/hal/i2c_ll.h | 33 +++++++++++++++ components/hal/esp32c3/include/hal/i2c_ll.h | 33 +++++++++++++++ components/hal/esp32c6/include/hal/i2c_ll.h | 24 +++++++++++ components/hal/esp32h2/include/hal/i2c_ll.h | 22 ++++++++++ components/hal/esp32p4/include/hal/i2c_ll.h | 45 +++++++++++++++++++- components/hal/esp32s2/include/hal/i2c_ll.h | 46 +++++++++++++++++++++ components/hal/esp32s3/include/hal/i2c_ll.h | 41 ++++++++++++++++++ components/hal/i2c_hal.c | 7 ++-- components/hal/include/hal/i2c_hal.h | 30 ++++++++++++-- 15 files changed, 386 insertions(+), 23 deletions(-) diff --git a/components/driver/i2c/i2c.c b/components/driver/i2c/i2c.c index 1d638babb792..e9397b175267 100644 --- a/components/driver/i2c/i2c.c +++ b/components/driver/i2c/i2c.c @@ -110,6 +110,18 @@ static const char *I2C_TAG = "i2c"; #endif #define I2C_MEM_ALLOC_CAPS_DEFAULT MALLOC_CAP_DEFAULT +#if SOC_PERIPH_CLK_CTRL_SHARED +#define I2C_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define I2C_CLOCK_SRC_ATOMIC() +#endif + +#if !SOC_RCC_IS_INDEPENDENT +#define I2C_RCC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define I2C_RCC_ATOMIC() +#endif + /** * I2C bus are defined in the header files, let's check that the values are correct */ @@ -240,7 +252,9 @@ static void i2c_hw_disable(i2c_port_t i2c_num) { I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); if (i2c_context[i2c_num].hw_enabled != false) { - periph_module_disable(i2c_periph_signal[i2c_num].module); + I2C_RCC_ATOMIC() { + i2c_ll_enable_bus_clock(i2c_num, false); + } i2c_context[i2c_num].hw_enabled = false; } I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); @@ -250,7 +264,10 @@ static void i2c_hw_enable(i2c_port_t i2c_num) { I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); if (i2c_context[i2c_num].hw_enabled != true) { - periph_module_enable(i2c_periph_signal[i2c_num].module); + I2C_RCC_ATOMIC() { + i2c_ll_enable_bus_clock(i2c_num, true); + i2c_ll_reset_register(i2c_num); + } i2c_context[i2c_num].hw_enabled = true; } I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); @@ -375,7 +392,9 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_ return ESP_FAIL; } i2c_hw_enable(i2c_num); - i2c_hal_init(&i2c_context[i2c_num].hal, i2c_num); + I2C_CLOCK_SRC_ATOMIC() { + i2c_hal_init(&i2c_context[i2c_num].hal, i2c_num); + } //Disable I2C interrupt. i2c_ll_disable_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK); i2c_ll_clear_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK); @@ -478,7 +497,9 @@ esp_err_t i2c_driver_delete(i2c_port_t i2c_num) } #endif - i2c_hal_deinit(&i2c_context[i2c_num].hal); + I2C_CLOCK_SRC_ATOMIC() { + i2c_hal_deinit(&i2c_context[i2c_num].hal); + } free(p_i2c_obj[i2c_num]); p_i2c_obj[i2c_num] = NULL; @@ -746,7 +767,9 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) return ret; } i2c_hw_enable(i2c_num); - i2c_hal_init(&i2c_context[i2c_num].hal, i2c_num); + I2C_CLOCK_SRC_ATOMIC() { + i2c_hal_init(&i2c_context[i2c_num].hal, i2c_num); + } I2C_ENTER_CRITICAL(&(i2c_context[i2c_num].spinlock)); i2c_ll_disable_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK); i2c_ll_clear_intr_mask(i2c_context[i2c_num].hal.dev, I2C_LL_INTR_MASK); @@ -754,7 +777,9 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) if (i2c_conf->mode == I2C_MODE_SLAVE) { //slave mode i2c_hal_slave_init(&(i2c_context[i2c_num].hal)); i2c_ll_slave_tx_auto_start_en(i2c_context[i2c_num].hal.dev, true); - i2c_ll_set_source_clk(i2c_context[i2c_num].hal.dev, src_clk); + I2C_CLOCK_SRC_ATOMIC() { + i2c_ll_set_source_clk(i2c_context[i2c_num].hal.dev, src_clk); + } i2c_ll_set_slave_addr(i2c_context[i2c_num].hal.dev, i2c_conf->slave.slave_addr, i2c_conf->slave.addr_10bit_en); i2c_ll_set_rxfifo_full_thr(i2c_context[i2c_num].hal.dev, I2C_FIFO_FULL_THRESH_VAL); i2c_ll_set_txfifo_empty_thr(i2c_context[i2c_num].hal.dev, I2C_FIFO_EMPTY_THRESH_VAL); @@ -768,7 +793,9 @@ esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t *i2c_conf) i2c_hal_master_init(&(i2c_context[i2c_num].hal)); //Default, we enable hardware filter i2c_ll_master_set_filter(i2c_context[i2c_num].hal.dev, I2C_FILTER_CYC_NUM_DEF); - i2c_hal_set_bus_timing(&(i2c_context[i2c_num].hal), i2c_conf->master.clk_speed, src_clk, s_get_src_clk_freq(src_clk)); + I2C_CLOCK_SRC_ATOMIC() { + i2c_hal_set_bus_timing(&(i2c_context[i2c_num].hal), i2c_conf->master.clk_speed, src_clk, s_get_src_clk_freq(src_clk)); + } } i2c_ll_update(i2c_context[i2c_num].hal.dev); I2C_EXIT_CRITICAL(&(i2c_context[i2c_num].spinlock)); diff --git a/components/driver/i2c/i2c_common.c b/components/driver/i2c/i2c_common.c index f9cb44da5944..831bef2bdc64 100644 --- a/components/driver/i2c/i2c_common.c +++ b/components/driver/i2c/i2c_common.c @@ -56,9 +56,13 @@ static esp_err_t s_i2c_bus_handle_aquire(i2c_port_num_t port_num, i2c_bus_handle bus->bus_mode = mode; // Enable the I2C module - periph_module_enable(i2c_periph_signal[port_num].module); - periph_module_reset(i2c_periph_signal[port_num].module); - i2c_hal_init(&bus->hal, port_num); + I2C_RCC_ATOMIC() { + i2c_ll_enable_bus_clock(bus->port_num, true); + i2c_ll_reset_register(bus->port_num); + } + I2C_CLOCK_SRC_ATOMIC() { + i2c_hal_init(&bus->hal, port_num); + } } } else { ESP_LOGE(TAG, "I2C bus id(%d) has already been acquired", port_num); @@ -131,7 +135,9 @@ esp_err_t i2c_release_bus_handle(i2c_bus_handle_t i2c_bus) ESP_RETURN_ON_ERROR(esp_pm_lock_delete(i2c_bus->pm_lock), TAG, "delete pm_lock failed"); } // Disable I2C module - periph_module_disable(i2c_periph_signal[port_num].module); + I2C_RCC_ATOMIC() { + i2c_ll_enable_bus_clock(port_num, false); + } free(i2c_bus); } } diff --git a/components/driver/i2c/i2c_master.c b/components/driver/i2c/i2c_master.c index 2fa24a020adb..0ea9be27b605 100644 --- a/components/driver/i2c/i2c_master.c +++ b/components/driver/i2c/i2c_master.c @@ -486,7 +486,10 @@ static esp_err_t s_i2c_transaction_start(i2c_master_dev_handle_t i2c_dev, int xf i2c_master->rx_cnt = 0; i2c_master->read_len_static = 0; - i2c_hal_set_bus_timing(hal, i2c_dev->scl_speed_hz, i2c_master->base->clk_src, i2c_master->base->clk_src_freq_hz); + I2C_CLOCK_SRC_ATOMIC() { + i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src); + i2c_hal_set_bus_timing(hal, i2c_dev->scl_speed_hz, i2c_master->base->clk_src, i2c_master->base->clk_src_freq_hz); + } i2c_ll_master_set_fractional_divider(hal->dev, 0, 0); i2c_ll_update(hal->dev); @@ -1044,7 +1047,10 @@ esp_err_t i2c_master_probe(i2c_master_bus_handle_t i2c_master, uint16_t address, // I2C probe does not have i2c device module. So set the clock parameter independently // This will not influence device transaction. - i2c_hal_set_bus_timing(hal, 100000, i2c_master->base->clk_src, i2c_master->base->clk_src_freq_hz); + I2C_CLOCK_SRC_ATOMIC() { + i2c_ll_set_source_clk(hal->dev, i2c_master->base->clk_src); + i2c_hal_set_bus_timing(hal, 100000, i2c_master->base->clk_src, i2c_master->base->clk_src_freq_hz); + } i2c_ll_master_set_fractional_divider(hal->dev, 0, 0); i2c_ll_update(hal->dev); diff --git a/components/driver/i2c/i2c_private.h b/components/driver/i2c/i2c_private.h index 8d4688562d81..546aae170a76 100644 --- a/components/driver/i2c/i2c_private.h +++ b/components/driver/i2c/i2c_private.h @@ -17,12 +17,25 @@ #include "freertos/task.h" #include "freertos/ringbuf.h" #include "driver/i2c_slave.h" +#include "esp_private/periph_ctrl.h" #include "esp_pm.h" #ifdef __cplusplus extern "C" { #endif +#if SOC_PERIPH_CLK_CTRL_SHARED +#define I2C_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define I2C_CLOCK_SRC_ATOMIC() +#endif + +#if !SOC_RCC_IS_INDEPENDENT +#define I2C_RCC_ATOMIC() PERIPH_RCC_ATOMIC() +#else +#define I2C_RCC_ATOMIC() +#endif + #if CONFIG_I2C_ISR_IRAM_SAFE #define I2C_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #else diff --git a/components/driver/i2c/i2c_slave.c b/components/driver/i2c/i2c_slave.c index e3bae30bc400..41e6d2fa3813 100644 --- a/components/driver/i2c/i2c_slave.c +++ b/components/driver/i2c/i2c_slave.c @@ -245,7 +245,9 @@ esp_err_t i2c_new_slave_device(const i2c_slave_config_t *slave_config, i2c_slave #endif //Default, we enable hardware filter - i2c_ll_set_source_clk(hal->dev, slave_config->clk_source); + I2C_CLOCK_SRC_ATOMIC() { + i2c_ll_set_source_clk(hal->dev, slave_config->clk_source); + } bool addr_10bit_en = slave_config->addr_bit_len != I2C_ADDR_BIT_LEN_7; i2c_ll_set_slave_addr(hal->dev, slave_config->slave_addr, addr_10bit_en); #if SOC_I2C_SLAVE_SUPPORT_BROADCAST diff --git a/components/hal/esp32/include/hal/i2c_ll.h b/components/hal/esp32/include/hal/i2c_ll.h index 9a2e89ebea95..9ca1b16b2f15 100644 --- a/components/hal/esp32/include/hal/i2c_ll.h +++ b/components/hal/esp32/include/hal/i2c_ll.h @@ -13,6 +13,7 @@ #include "soc/i2c_periph.h" #include "soc/i2c_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/dport_reg.h" #include "hal/i2c_types.h" #include "esp_attr.h" #include "hal/assert.h" @@ -670,6 +671,51 @@ static inline void i2c_ll_update(i2c_dev_t *hw) ;// ESP32 do not support } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + if (i2c_port == 0) { + uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG); + reg_val &= ~DPORT_I2C_EXT0_CLK_EN; + reg_val |= enable << 7; + DPORT_WRITE_PERI_REG(DPORT_PERIP_CLK_EN_REG, reg_val); + } else if (i2c_port == 1) { + uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG); + reg_val &= ~DPORT_I2C_EXT1_CLK_EN; + reg_val |= enable << 18; + DPORT_WRITE_PERI_REG(DPORT_PERIP_CLK_EN_REG, reg_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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + if (i2c_port == 0) { + DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, DPORT_I2C_EXT0_RST); + DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, 0); + } else if (i2c_port == 1) { + DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, DPORT_I2C_EXT1_RST); + DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, 0); + } +} + +/// 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 i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Set whether slave should auto start, or only start with start signal from master * diff --git a/components/hal/esp32c2/include/hal/i2c_ll.h b/components/hal/esp32c2/include/hal/i2c_ll.h index 8958be0d2edc..44e873aa2d33 100644 --- a/components/hal/esp32c2/include/hal/i2c_ll.h +++ b/components/hal/esp32c2/include/hal/i2c_ll.h @@ -17,6 +17,7 @@ #include "hal/i2c_types.h" #include "soc/rtc_cntl_reg.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "esp_attr.h" #ifdef __cplusplus @@ -111,6 +112,38 @@ static inline void i2c_ll_update(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + (void)i2c_port; + SYSTEM.perip_clk_en0.i2c_ext0_clk_en = enable; +} + +/// 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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + (void)i2c_port; + SYSTEM.perip_rst_en0.i2c_ext0_rst = 1; + SYSTEM.perip_rst_en0.i2c_ext0_rst = 0; +} + +/// 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 i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Configure the I2C bus timing related register. * diff --git a/components/hal/esp32c3/include/hal/i2c_ll.h b/components/hal/esp32c3/include/hal/i2c_ll.h index f199940382b3..c6a58cc55218 100644 --- a/components/hal/esp32c3/include/hal/i2c_ll.h +++ b/components/hal/esp32c3/include/hal/i2c_ll.h @@ -17,6 +17,7 @@ #include "hal/i2c_types.h" #include "soc/rtc_cntl_reg.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "esp_attr.h" #include "hal/misc.h" @@ -126,6 +127,38 @@ static inline void i2c_ll_update(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + (void)i2c_port; + SYSTEM.perip_clk_en0.reg_i2c_ext0_clk_en = enable; +} + +/// 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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + (void)i2c_port; + SYSTEM.perip_rst_en0.reg_i2c_ext0_rst = 1; + SYSTEM.perip_rst_en0.reg_i2c_ext0_rst = 0; +} + +/// 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 i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Configure the I2C bus timing related register. * diff --git a/components/hal/esp32c6/include/hal/i2c_ll.h b/components/hal/esp32c6/include/hal/i2c_ll.h index 80e7738b69ab..8a37a9819d3e 100644 --- a/components/hal/esp32c6/include/hal/i2c_ll.h +++ b/components/hal/esp32c6/include/hal/i2c_ll.h @@ -127,6 +127,30 @@ static inline void i2c_ll_update(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + (void)i2c_port; + PCR.i2c_conf.i2c_clk_en = enable; +} + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + (void)i2c_port; + PCR.i2c_conf.i2c_rst_en = 1; + PCR.i2c_conf.i2c_rst_en = 0; +} + /** * @brief Configure the I2C bus timing related register. * diff --git a/components/hal/esp32h2/include/hal/i2c_ll.h b/components/hal/esp32h2/include/hal/i2c_ll.h index 1ed9ecddc0ac..3d1e404b0278 100644 --- a/components/hal/esp32h2/include/hal/i2c_ll.h +++ b/components/hal/esp32h2/include/hal/i2c_ll.h @@ -126,6 +126,28 @@ static inline void i2c_ll_update(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + PCR.i2c[i2c_port].i2c_conf.i2c_clk_en = enable; +} + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + PCR.i2c[i2c_port].i2c_conf.i2c_rst_en = 1; + PCR.i2c[i2c_port].i2c_conf.i2c_rst_en = 0; +} + /** * @brief Configure the I2C bus timing related register. * diff --git a/components/hal/esp32p4/include/hal/i2c_ll.h b/components/hal/esp32p4/include/hal/i2c_ll.h index 5888db147ea1..ddeff8daf482 100644 --- a/components/hal/esp32p4/include/hal/i2c_ll.h +++ b/components/hal/esp32p4/include/hal/i2c_ll.h @@ -131,6 +131,45 @@ static inline void i2c_ll_update(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + if (i2c_port == 0) { + HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2c0_apb_clk_en = enable; + } else if (i2c_port == 1) { + HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2c1_apb_clk_en = enable; + } +} + +/// 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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + if (i2c_port == 0) { + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_i2c0 = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_i2c0 = 0; + } else if (i2c_port == 1) { + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_i2c1 = 1; + HP_SYS_CLKRST.hp_rst_en1.reg_rst_en_i2c1 = 0; + } +} + +/// 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 i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Configure the I2C bus timing related register. * @@ -760,6 +799,10 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c } +/// 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 i2c_ll_set_source_clk(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_set_source_clk(__VA_ARGS__);} while(0) + /** * @brief Enable I2C peripheral controller clock * @@ -769,10 +812,8 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en) { if (hw == &I2C0) { - HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2c0_apb_clk_en = en; HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c0_clk_en = en; } else if (hw == &I2C1) { - HP_SYS_CLKRST.soc_clk_ctrl2.reg_i2c1_apb_clk_en = en; HP_SYS_CLKRST.peri_clk_ctrl10.reg_i2c1_clk_en = en; } else if (hw == &LP_I2C) { // Do nothing diff --git a/components/hal/esp32s2/include/hal/i2c_ll.h b/components/hal/esp32s2/include/hal/i2c_ll.h index d45c4cfd05ed..f7942d940134 100644 --- a/components/hal/esp32s2/include/hal/i2c_ll.h +++ b/components/hal/esp32s2/include/hal/i2c_ll.h @@ -11,6 +11,7 @@ #include "soc/i2c_periph.h" #include "soc/i2c_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/system_reg.h" #include "hal/i2c_types.h" #include "esp_attr.h" #include "hal/misc.h" @@ -718,6 +719,51 @@ static inline void i2c_ll_update(i2c_dev_t *hw) ;// ESP32S2 do not support } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + if (i2c_port == 0) { + uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG); + reg_val &= ~DPORT_I2C_EXT0_CLK_EN_M; + reg_val |= enable << DPORT_I2C_EXT0_CLK_EN_S; + WRITE_PERI_REG(DPORT_PERIP_CLK_EN0_REG, reg_val); + } else if (i2c_port == 1) { + uint32_t reg_val = READ_PERI_REG(DPORT_PERIP_CLK_EN0_REG); + reg_val &= ~DPORT_I2C_EXT1_CLK_EN_M; + reg_val |= enable << DPORT_I2C_EXT1_CLK_EN_S; + WRITE_PERI_REG(DPORT_PERIP_CLK_EN0_REG, reg_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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + if (i2c_port == 0) { + WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, DPORT_I2C_EXT0_RST_M); + WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, 0); + } else if (i2c_port == 1) { + WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, DPORT_I2C_EXT1_RST_M); + WRITE_PERI_REG(DPORT_PERIP_RST_EN0_REG, 0); + } +} + +/// 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 i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Set whether slave should auto start, or only start with start signal from master * diff --git a/components/hal/esp32s3/include/hal/i2c_ll.h b/components/hal/esp32s3/include/hal/i2c_ll.h index 374c8c6e0458..70d5d0e78ebf 100644 --- a/components/hal/esp32s3/include/hal/i2c_ll.h +++ b/components/hal/esp32s3/include/hal/i2c_ll.h @@ -15,6 +15,7 @@ #include "soc/soc_caps.h" #include "soc/i2c_struct.h" #include "soc/clk_tree_defs.h" +#include "soc/system_struct.h" #include "hal/i2c_types.h" #include "esp_attr.h" #include "esp_assert.h" @@ -125,6 +126,46 @@ static inline void i2c_ll_update(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Enable the bus clock for I2C module + * + * @param i2c_port I2C port id + * @param enable true to enable, false to disable + */ +static inline void i2c_ll_enable_bus_clock(int i2c_port, bool enable) +{ + if (i2c_port == 0) { + SYSTEM.perip_clk_en0.i2c_ext0_clk_en = enable; + } else if (i2c_port == 1) { + SYSTEM.perip_clk_en0.i2c_ext1_clk_en = enable; + } +} + +/// 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 i2c_ll_enable_bus_clock(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_enable_bus_clock(__VA_ARGS__);} while(0) + +/** + * @brief Reset the I2C module + * + * @param i2c_port Group ID + */ +static inline void i2c_ll_reset_register(int i2c_port) +{ + if (i2c_port == 0) { + SYSTEM.perip_rst_en0.i2c_ext0_rst = 1; + SYSTEM.perip_rst_en0.i2c_ext0_rst = 0; + } else if (i2c_port == 1) { + SYSTEM.perip_rst_en0.i2c_ext1_rst = 1; + SYSTEM.perip_rst_en0.i2c_ext1_rst = 0; + } + +} + +/// 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 i2c_ll_reset_register(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; i2c_ll_reset_register(__VA_ARGS__);} while(0) + /** * @brief Configure the I2C bus timing related register. * diff --git a/components/hal/i2c_hal.c b/components/hal/i2c_hal.c index 6a44f13939e5..2b1248f622a8 100644 --- a/components/hal/i2c_hal.c +++ b/components/hal/i2c_hal.c @@ -22,9 +22,8 @@ void i2c_hal_slave_init(i2c_hal_context_t *hal) } #endif -void i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_clock_source_t src_clk, int source_freq) +void _i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_clock_source_t src_clk, int source_freq) { - i2c_ll_set_source_clk(hal->dev, src_clk); i2c_hal_clk_config_t clk_cal = {0}; i2c_ll_master_cal_bus_clk(source_freq, scl_freq, &clk_cal); i2c_ll_master_set_bus_timing(hal->dev, &clk_cal); @@ -45,7 +44,7 @@ void i2c_hal_master_init(i2c_hal_context_t *hal) i2c_ll_rxfifo_rst(hal->dev); } -void i2c_hal_init(i2c_hal_context_t *hal, int i2c_port) +void _i2c_hal_init(i2c_hal_context_t *hal, int i2c_port) { if (hal->dev == NULL) { hal->dev = I2C_LL_GET_HW(i2c_port); @@ -53,7 +52,7 @@ void i2c_hal_init(i2c_hal_context_t *hal, int i2c_port) i2c_ll_enable_controller_clock(hal->dev, true); } -void i2c_hal_deinit(i2c_hal_context_t *hal) +void _i2c_hal_deinit(i2c_hal_context_t *hal) { i2c_ll_enable_controller_clock(hal->dev, false); hal->dev = NULL; diff --git a/components/hal/include/hal/i2c_hal.h b/components/hal/include/hal/i2c_hal.h index 797bf6e8ab71..ed8a73f74855 100644 --- a/components/hal/include/hal/i2c_hal.h +++ b/components/hal/include/hal/i2c_hal.h @@ -83,7 +83,15 @@ void i2c_hal_master_init(i2c_hal_context_t *hal); * * @return None */ -void i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_clock_source_t src_clk, int source_freq); +void _i2c_hal_set_bus_timing(i2c_hal_context_t *hal, int scl_freq, i2c_clock_source_t src_clk, int source_freq); + +#if SOC_PERIPH_CLK_CTRL_SHARED +/// 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 i2c_hal_set_bus_timing(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; _i2c_hal_set_bus_timing(__VA_ARGS__);} while(0) +#else +#define i2c_hal_set_bus_timing(...) _i2c_hal_set_bus_timing(__VA_ARGS__) +#endif /** * @brief I2C hardware FSM reset @@ -120,14 +128,30 @@ void i2c_hal_master_handle_rx_event(i2c_hal_context_t *hal, i2c_intr_event_t *ev * @param hal Context of the HAL * @param i2c_port I2C port number. */ -void i2c_hal_init(i2c_hal_context_t *hal, int i2c_port); +void _i2c_hal_init(i2c_hal_context_t *hal, int i2c_port); + +#if SOC_PERIPH_CLK_CTRL_SHARED +/// 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 i2c_hal_init(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; _i2c_hal_init(__VA_ARGS__);} while(0) +#else +#define i2c_hal_init(...) _i2c_hal_init(__VA_ARGS__) +#endif /** * @brief Deinit I2C hal layer * * @param hal Context of the HAL */ -void i2c_hal_deinit(i2c_hal_context_t *hal); +void _i2c_hal_deinit(i2c_hal_context_t *hal); + +#if SOC_PERIPH_CLK_CTRL_SHARED +/// 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 i2c_hal_deinit(...) do {(void)__DECLARE_RCC_ATOMIC_ENV; _i2c_hal_deinit(__VA_ARGS__);} while(0) +#else +#define i2c_hal_deinit(...) _i2c_hal_deinit(__VA_ARGS__) +#endif /** * @brief Start I2C master transaction From 0a95914839eac30dbcc006d85eecaa47adea44e9 Mon Sep 17 00:00:00 2001 From: Sarvesh Bodakhe Date: Fri, 27 Oct 2023 09:29:58 +0530 Subject: [PATCH 066/161] fix(esp_wifi): Fix issue of station disconnecting immediately when AP RSSI is zero --- components/esp_wifi/include/esp_wifi.h | 3 ++- components/esp_wifi/include/esp_wifi_types.h | 2 +- components/esp_wifi/lib | 2 +- .../esp_supplicant/src/esp_common.c | 12 ++++++------ .../esp_supplicant/src/esp_common_i.h | 4 ++-- .../esp_supplicant/src/esp_scan.c | 4 ++-- .../esp_supplicant/src/esp_scan_i.h | 18 ++++-------------- .../esp_supplicant/src/esp_wifi_driver.h | 2 +- tools/ci/check_copyright_ignore.txt | 1 - 9 files changed, 19 insertions(+), 29 deletions(-) diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 4aef336ec25b..f5a8d9746815 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -1191,7 +1191,8 @@ esp_err_t esp_wifi_statis_dump(uint32_t modules); * @attention If the user wants to receive another WIFI_EVENT_STA_BSS_RSSI_LOW event after receiving one, this API needs to be * called again with an updated/same RSSI threshold. * - * @param rssi threshold value in dbm between -100 to 0 + * @param rssi threshold value in dbm between -100 to 10 + * Note that in some rare cases where signal strength is very strong, rssi values can be slightly positive. * * @return * - ESP_OK: succeed diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index ae525511ba20..8500fb3b7624 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -211,7 +211,7 @@ typedef struct { uint8_t ssid[33]; /**< SSID of AP */ uint8_t primary; /**< channel of AP */ wifi_second_chan_t second; /**< secondary channel of AP */ - int8_t rssi; /**< signal strength of AP */ + int8_t rssi; /**< signal strength of AP. Note that in some rare cases where signal strength is very strong, rssi values can be slightly positive */ wifi_auth_mode_t authmode; /**< authmode of AP */ wifi_cipher_type_t pairwise_cipher; /**< pairwise cipher of AP */ wifi_cipher_type_t group_cipher; /**< group cipher of AP */ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 71efb6cbce42..ee1f0c433287 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 71efb6cbce423e457daaaf54129c3da7bfe28704 +Subproject commit ee1f0c43328754e64f43803fc532faaba489d3f4 diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common.c b/components/wpa_supplicant/esp_supplicant/src/esp_common.c index 56399020c732..eeb5e006f887 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common.c @@ -47,7 +47,7 @@ static bool s_supplicant_task_init_done; #define SUPPLICANT_TASK_STACK_SIZE (6144 + TASK_STACK_SIZE_ADD) static int handle_action_frm(u8 *frame, size_t len, - u8 *sender, u32 rssi, u8 channel) + u8 *sender, int8_t rssi, u8 channel) { struct ieee_mgmt_frame *frm = os_malloc(sizeof(struct ieee_mgmt_frame) + len); @@ -73,7 +73,7 @@ static int handle_action_frm(u8 *frame, size_t len, #if defined(CONFIG_IEEE80211KV) static void handle_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender, - u8 *payload, size_t len, u32 rssi) + u8 *payload, size_t len, int8_t rssi) { if (payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) { /* neighbor report parsing */ @@ -89,7 +89,7 @@ static void handle_rrm_frame(struct wpa_supplicant *wpa_s, u8 *sender, } } -static int mgmt_rx_action(u8 *frame, size_t len, u8 *sender, u32 rssi, u8 channel) +static int mgmt_rx_action(u8 *frame, size_t len, u8 *sender, int8_t rssi, u8 channel) { u8 category; u8 bssid[ETH_ALEN]; @@ -215,7 +215,7 @@ static void register_mgmt_frames(struct wpa_supplicant *wpa_s) #ifdef CONFIG_IEEE80211R static int handle_auth_frame(u8 *frame, size_t len, - u8 *sender, u32 rssi, u8 channel) + u8 *sender, int8_t rssi, u8 channel) { if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK) { if (gWpaSm.ft_protocol) { @@ -230,7 +230,7 @@ static int handle_auth_frame(u8 *frame, size_t len, } static int handle_assoc_frame(u8 *frame, size_t len, - u8 *sender, u32 rssi, u8 channel) + u8 *sender, int8_t rssi, u8 channel) { if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK) { if (gWpaSm.ft_protocol) { @@ -255,7 +255,7 @@ void esp_supplicant_unset_all_appie(void) } static int ieee80211_handle_rx_frm(u8 type, u8 *frame, size_t len, u8 *sender, - u32 rssi, u8 channel, u64 current_tsf) + int8_t rssi, u8 channel, u64 current_tsf) { int ret = 0; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_common_i.h index d7d64f364320..e6c1d23290b7 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common_i.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,7 @@ extern struct wpa_supplicant g_wpa_supp; struct ieee_mgmt_frame { u8 sender[ETH_ALEN]; u8 channel; - u32 rssi; + int8_t rssi; size_t len; u8 payload[0]; }; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_scan.c b/components/wpa_supplicant/esp_supplicant/src/esp_scan.c index f4dc09655b9c..d0f5edcef65e 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_scan.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_scan.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -114,7 +114,7 @@ void esp_scan_deinit(struct wpa_supplicant *wpa_s) } int esp_handle_beacon_probe(u8 type, u8 *frame, size_t len, u8 *sender, - u32 rssi, u8 channel, u64 current_tsf) + int8_t rssi, u8 channel, u64 current_tsf) { struct wpa_supplicant *wpa_s = &g_wpa_supp; struct os_reltime now; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h index 25442a6ac0c6..bbea37986749 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h @@ -1,17 +1,7 @@ -/** - * Copyright 2020 Espressif Systems (Shanghai) PTE LTD +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * SPDX-License-Identifier: Apache-2.0 */ #ifndef ESP_SCAN_I_H @@ -19,7 +9,7 @@ void esp_scan_init(struct wpa_supplicant *wpa_s); void esp_scan_deinit(struct wpa_supplicant *wpa_s); int esp_handle_beacon_probe(u8 type, u8 *frame, size_t len, u8 *sender, - u32 rssi, u8 channel, u64 current_tsf); + int8_t rssi, u8 channel, u64 current_tsf); void esp_supplicant_handle_scan_done_evt(void); #endif diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h index 8979dfc69da6..0837ef1f0b5d 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -137,7 +137,7 @@ struct wpa_funcs { uint8_t *(*wpa3_build_sae_msg)(uint8_t *bssid, uint32_t type, size_t *len); int (*wpa3_parse_sae_msg)(uint8_t *buf, size_t len, uint32_t type, uint16_t status); int (*wpa3_hostap_handle_auth)(uint8_t *buf, size_t len, uint32_t type, uint16_t status, uint8_t *bssid); - int (*wpa_sta_rx_mgmt)(u8 type, u8 *frame, size_t len, u8 *sender, u32 rssi, u8 channel, u64 current_tsf); + int (*wpa_sta_rx_mgmt)(u8 type, u8 *frame, size_t len, u8 *sender, int8_t rssi, u8 channel, u64 current_tsf); void (*wpa_config_done)(void); uint8_t *(*owe_build_dhie)(uint16_t group); int (*owe_process_assoc_resp)(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_ie, size_t dh_len); diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index f7cb594c324a..511f6dae2965 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -833,7 +833,6 @@ components/wifi_provisioning/python/wifi_scan_pb2.py components/wifi_provisioning/src/scheme_console.c components/wifi_provisioning/src/wifi_config.c components/wifi_provisioning/src/wifi_scan.c -components/wpa_supplicant/esp_supplicant/src/esp_scan_i.h components/wpa_supplicant/esp_supplicant/src/esp_wpa_err.h components/wpa_supplicant/include/utils/wpa_debug.h components/wpa_supplicant/include/utils/wpabuf.h From d23e4d6f3e30a0d2509c2405d9ded456f423f4de Mon Sep 17 00:00:00 2001 From: luomanruo Date: Fri, 27 Oct 2023 14:17:35 +0800 Subject: [PATCH 067/161] ble: update c6 h2 lib to 5bd7cb83, c2 lib to 1d31e175 --- components/bt/controller/lib_esp32c2/esp32c2-bt-lib | 2 +- components/bt/controller/lib_esp32c6/esp32c6-bt-lib | 2 +- components/bt/controller/lib_esp32h2/esp32h2-bt-lib | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib index 4fb60aa91de6..30e5c4f95bff 160000 --- a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib +++ b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib @@ -1 +1 @@ -Subproject commit 4fb60aa91de64b0f1d0eb6292d38b6c22a3aa005 +Subproject commit 30e5c4f95bff1a17e06ce1042a165b0aa2bc4ca5 diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index 25d9661bc3d5..a763b33ce1f6 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit 25d9661bc3d5cc7bade40c03f501b935d3ad7642 +Subproject commit a763b33ce1f6bdc257947845b0520c3b44de87eb diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index 8450d3f50804..c8018101d5a7 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit 8450d3f50804bc2d685a6ef5c5a76e1f4f13d579 +Subproject commit c8018101d5a71162c220782e6c860e9ba33013c4 From a9846479ffa94d956383c866d513e37187e9ff80 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 27 Oct 2023 09:28:20 +0200 Subject: [PATCH 068/161] fix(examples): Fix usage of SNTP netif API in examples --- examples/protocols/https_request/main/time_sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/protocols/https_request/main/time_sync.c b/examples/protocols/https_request/main/time_sync.c index 63416e7b3fdb..268c819a9583 100644 --- a/examples/protocols/https_request/main/time_sync.c +++ b/examples/protocols/https_request/main/time_sync.c @@ -87,7 +87,7 @@ esp_err_t fetch_and_store_time_in_nvs(void *args) if (my_handle != 0) { nvs_close(my_handle); } - esp_netif_deinit(); + esp_netif_sntp_deinit(); if (err != ESP_OK) { ESP_LOGE(TAG, "Error updating time in nvs"); From 43b53a18850193d6ed76b360dc8994764e231932 Mon Sep 17 00:00:00 2001 From: cjin Date: Wed, 25 Oct 2023 16:08:16 +0800 Subject: [PATCH 069/161] change(ble): added option for msys buffer source --- components/bt/controller/esp32c6/Kconfig.in | 11 ++++++++++- components/bt/host/nimble/Kconfig.in | 9 +++++++++ components/bt/porting/nimble/src/os_msys_init.c | 16 ++++++++++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/components/bt/controller/esp32c6/Kconfig.in b/components/bt/controller/esp32c6/Kconfig.in index 1f56aab918b2..41619efd334c 100644 --- a/components/bt/controller/esp32c6/Kconfig.in +++ b/components/bt/controller/esp32c6/Kconfig.in @@ -212,6 +212,15 @@ menu "Memory Settings" help Dynamic memory size of block 2 + config BT_LE_MSYS_BUF_FROM_HEAP + bool "Get Msys Mbuf from heap" + default y + depends on BT_LE_MSYS_INIT_IN_CONTROLLER + help + This option sets the source of the shared msys mbuf memory between + the Host and the Controller. Allocate the memory from the heap if + this option is sets, from the mempool otherwise. + config BT_LE_ACL_BUF_COUNT int "ACL Buffer count" default 10 @@ -539,5 +548,5 @@ config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD again. config BT_LE_MSYS_INIT_IN_CONTROLLER - bool + bool "Msys Mbuf Init in Controller" default y diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index 9a87c6d6789f..38f956e5430b 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -276,6 +276,15 @@ menu "Memory Settings" help Dynamic memory size of block 2 + config BT_NIMBLE_MSYS_BUF_FROM_HEAP + bool "Get Msys Mbuf from heap" + default y + depends on BT_LE_MSYS_INIT_IN_CONTROLLER + help + This option sets the source of the shared msys mbuf memory between + the Host and the Controller. Allocate the memory from the heap if + this option is sets, from the mempool otherwise. + config BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT int "ACL Buffer count" depends on BT_NIMBLE_ENABLED diff --git a/components/bt/porting/nimble/src/os_msys_init.c b/components/bt/porting/nimble/src/os_msys_init.c index 53619197d078..bf4f4145166e 100644 --- a/components/bt/porting/nimble/src/os_msys_init.c +++ b/components/bt/porting/nimble/src/os_msys_init.c @@ -30,6 +30,11 @@ static STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = #define OS_MSYS_1_SANITY_MIN_COUNT MYNEWT_VAL(MSYS_1_SANITY_MIN_COUNT) #define OS_MSYS_2_SANITY_MIN_COUNT MYNEWT_VAL(MSYS_2_SANITY_MIN_COUNT) +#if CONFIG_BT_NIMBLE_MSYS_BUF_FROM_HEAP +#define OS_MSYS_BLOCK_FROM_HEAP (1) +#else +#define OS_MSYS_BLOCK_FROM_HEAP (0) +#endif // CONFIG_BT_NIMBLE_MSYS_BUF_FROM_HEAP #else #define OS_MSYS_1_BLOCK_COUNT CONFIG_BT_LE_MSYS_1_BLOCK_COUNT #define OS_MSYS_1_BLOCK_SIZE CONFIG_BT_LE_MSYS_1_BLOCK_SIZE @@ -38,6 +43,12 @@ static STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = #define OS_MSYS_1_SANITY_MIN_COUNT 0 #define OS_MSYS_2_SANITY_MIN_COUNT 0 + +#if CONFIG_BT_LE_MSYS_BUF_FROM_HEAP +#define OS_MSYS_BLOCK_FROM_HEAP (1) +#else +#define OS_MSYS_BLOCK_FROM_HEAP (0) +#endif // CONFIG_BT_LE_MSYS_BUF_FROM_HEAP #endif @@ -71,7 +82,7 @@ static struct os_mempool os_msys_init_2_mempool; #endif #if CONFIG_BT_LE_MSYS_INIT_IN_CONTROLLER -extern int esp_ble_msys_init(uint16_t msys_size1, uint16_t msys_size2, uint16_t msys_cnt1, uint16_t msys_cnt2); +extern int esp_ble_msys_init(uint16_t msys_size1, uint16_t msys_size2, uint16_t msys_cnt1, uint16_t msys_cnt2, uint8_t from_heap); extern void esp_ble_msys_deinit(void); int os_msys_init(void) @@ -79,7 +90,8 @@ int os_msys_init(void) return esp_ble_msys_init(SYSINIT_MSYS_1_MEMBLOCK_SIZE, SYSINIT_MSYS_2_MEMBLOCK_SIZE, OS_MSYS_1_BLOCK_COUNT, - OS_MSYS_2_BLOCK_COUNT); + OS_MSYS_2_BLOCK_COUNT, + OS_MSYS_BLOCK_FROM_HEAP); } void os_msys_deinit(void) From d42fbcf144dc9abcfb2645db4ca6a9b8a8b1579a Mon Sep 17 00:00:00 2001 From: luomanruo Date: Fri, 27 Oct 2023 15:17:09 +0800 Subject: [PATCH 070/161] ble: update c2 rom.ld --- components/bt/controller/esp32c2/bt.c | 2 +- components/bt/controller/esp32c6/bt.c | 2 +- components/bt/controller/esp32h2/bt.c | 2 +- components/esp_rom/esp32c2/ld/esp32c2.rom.ld | 4 ---- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index 9a37c1c7c1cd..0e1622ab8064 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -1003,7 +1003,7 @@ uint8_t esp_ble_get_chip_rev_version(void) static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) { for (int i = 0; i < len; i++) { - esp_rom_printf("%02x,", addr[i]); + esp_rom_printf("%02x ", addr[i]); } if (end) { esp_rom_printf("\n"); diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index 4691ba4a6deb..0643b525fec4 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -1173,7 +1173,7 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) { for (int i = 0; i < len; i++) { - esp_rom_printf("%02x,", addr[i]); + esp_rom_printf("%02x ", addr[i]); } if (end) { esp_rom_printf("\n"); diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 068387749f23..b3361bbb6943 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -1147,7 +1147,7 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) { for (int i = 0; i < len; i++) { - esp_rom_printf("%02x,", addr[i]); + esp_rom_printf("%02x ", addr[i]); } if (end) { esp_rom_printf("\n"); diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index 347425d8858d..d4b3ac80e126 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -1035,9 +1035,7 @@ r_ble_ll_utils_csa2_prng = 0x400013b8; r_ble_ll_utils_remapped_channel = 0x400013bc; r_ble_ll_whitelist_add = 0x400013c0; r_ble_ll_whitelist_chg_allowed = 0x400013c4; -r_ble_ll_whitelist_clear = 0x400013c8; r_ble_ll_whitelist_read_size = 0x400013cc; -r_ble_ll_whitelist_rmv = 0x400013d0; r_ble_ll_write_rf_path_compensation = 0x400013d8; r_ble_lll_adv_aux_schedule = 0x400013e0; r_ble_lll_adv_aux_schedule_first = 0x400013e4; @@ -1113,7 +1111,6 @@ r_ble_lll_conn_master_common_init = 0x40001530; r_ble_lll_conn_master_new = 0x40001534; r_ble_lll_conn_module_reset = 0x40001540; r_ble_lll_conn_pre_process = 0x40001548; -r_ble_lll_conn_process_acked_pdu = 0x4000154c; r_ble_lll_conn_recv_ack = 0x40001554; r_ble_lll_conn_recv_valid_packet = 0x40001558; r_ble_lll_conn_reset_pending_sched = 0x4000155c; @@ -1196,7 +1193,6 @@ r_ble_lll_scan_npl_store = 0x400016dc; r_ble_lll_scan_period_timer_cb = 0x400016e0; r_ble_lll_scan_process_adv_in_isr = 0x400016e4; r_ble_lll_scan_req_backoff = 0x400016ec; -r_ble_lll_scan_restart = 0x400016f0; r_ble_lll_scan_sched_next_aux = 0x40001700; r_ble_lll_scan_sched_remove = 0x40001704; r_ble_lll_scan_start = 0x40001708; From 53f4f19cc14dd8db0d0b1a9d5d4d5a13caf2b180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rohl=C3=ADnek?= Date: Fri, 6 Oct 2023 11:35:44 +0200 Subject: [PATCH 071/161] feat(storage): update config for app tests --- examples/storage/.build-test-rules.yml | 124 +++--------------- .../storage/custom_flash_driver/README.md | 4 +- examples/storage/ext_flash_fatfs/README.md | 4 +- .../ext_flash_fatfs/pytest_ext_flash_fatfs.py | 3 +- examples/storage/fatfsgen/README.md | 4 +- .../fatfsgen/pytest_fatfsgen_example.py | 2 +- examples/storage/nvs_rw_blob/README.md | 4 +- .../storage/nvs_rw_blob/pytest_nvs_rw_blob.py | 5 +- examples/storage/nvs_rw_value/README.md | 4 +- .../nvs_rw_value/pytest_nvs_rw_value.py | 5 +- examples/storage/nvs_rw_value_cxx/README.md | 4 +- .../pytest_nvs_rw_value_cxx.py | 5 +- examples/storage/nvsgen/README.md | 4 +- .../partition_api/partition_find/README.md | 4 +- .../pytest_partition_find_example.py | 2 +- .../partition_api/partition_mmap/README.md | 4 +- .../pytest_partition_mmap_example.py | 2 +- .../partition_api/partition_ops/README.md | 4 +- .../pytest_partition_ops_example.py | 2 +- examples/storage/parttool/README.md | 4 +- .../parttool/pytest_parttool_example.py | 3 +- .../pytest_perf_benchmark_example.py | 2 +- examples/storage/semihost_vfs/README.md | 4 +- .../main/semihost_vfs_example_main.c | 1 + .../semihost_vfs/pytest_semihost_vfs.py | 27 +++- examples/storage/spiffs/README.md | 4 +- .../storage/spiffs/pytest_spiffs_example.py | 3 +- examples/storage/spiffsgen/README.md | 4 +- .../spiffsgen/pytest_spiffsgen_example.py | 1 - examples/storage/wear_levelling/README.md | 4 +- .../pytest_wear_levelling_example.py | 3 +- 31 files changed, 92 insertions(+), 158 deletions(-) diff --git a/examples/storage/.build-test-rules.yml b/examples/storage/.build-test-rules.yml index 701a5601b1f9..5bc57c03f332 100644 --- a/examples/storage/.build-test-rules.yml +++ b/examples/storage/.build-test-rules.yml @@ -1,10 +1,6 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps examples/storage/custom_flash_driver: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet examples/storage/emmc: enable: @@ -13,103 +9,48 @@ examples/storage/emmc: examples/storage/ext_flash_fatfs: disable: - - if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2", "esp32p4"] - temporary: true - reason: target(s) not supported yet + - if: IDF_TARGET == "esp32p4" + reason: not supported yet disable_test: - - if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3"] + - if: IDF_TARGET not in ["esp32", "esp32s2"] temporary: true reason: lack of runners examples/storage/fatfsgen: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet disable_test: - - if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET != "esp32" + reason: only one target needed examples/storage/nvs_rw_blob: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet - disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners examples/storage/nvs_rw_value: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet - disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners examples/storage/nvs_rw_value_cxx: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet - disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners examples/storage/nvsgen: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners, should be same for every target + - if: IDF_TARGET != "esp32" + reason: only one target needed examples/storage/partition_api/partition_find: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/partition_api/partition_mmap: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/partition_api/partition_ops: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/parttool: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET != "esp32" + reason: only one target needed examples/storage/perf_benchmark: disable: @@ -125,7 +66,7 @@ examples/storage/sd_card/sdmmc: disable: - if: SOC_SDMMC_HOST_SUPPORTED != 1 disable_test: - - if: IDF_TARGET == "esp32s3" + - if: IDF_TARGET not in ["esp32"] temporary: true reason: lack of runners @@ -133,46 +74,21 @@ examples/storage/sd_card/sdspi: disable: - if: SOC_GPSPI_SUPPORTED != 1 disable_test: - - if: IDF_TARGET in ["esp32s3", "esp32c2", "esp32c6", "esp32h2", "esp32p4"] + - if: IDF_TARGET not in ["esp32", "esp32c3", "esp32s2"] temporary: true reason: lack of runners examples/storage/semihost_vfs: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet disable_test: - - if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3", "esp32c6", "esp32h2"] + - if: IDF_TARGET not in ["esp32"] temporary: true reason: lack of runners examples/storage/spiffs: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet - disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners examples/storage/spiffsgen: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners + - if: IDF_TARGET != "esp32" + reason: only one target needed examples/storage/wear_levelling: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet - disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2"] - temporary: true - reason: lack of runners diff --git a/examples/storage/custom_flash_driver/README.md b/examples/storage/custom_flash_driver/README.md index c124504499dc..9c251e68cc27 100644 --- a/examples/storage/custom_flash_driver/README.md +++ b/examples/storage/custom_flash_driver/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Custom Flash Driver Example diff --git a/examples/storage/ext_flash_fatfs/README.md b/examples/storage/ext_flash_fatfs/README.md index 6db77cb42083..55538e2e4d7c 100644 --- a/examples/storage/ext_flash_fatfs/README.md +++ b/examples/storage/ext_flash_fatfs/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # FAT FS on External Flash example diff --git a/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py b/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py index 8b85b85d2da2..b3dfd1e5b97b 100644 --- a/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py +++ b/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 @@ -7,6 +7,7 @@ @pytest.mark.esp32 +@pytest.mark.esp32s2 @pytest.mark.external_flash def test_ext_flash_fatfs(dut: Dut) -> None: message_list = ('Initialized external Flash', diff --git a/examples/storage/fatfsgen/README.md b/examples/storage/fatfsgen/README.md index 1beb6fd676c1..683d59534f8a 100644 --- a/examples/storage/fatfsgen/README.md +++ b/examples/storage/fatfsgen/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # FATFS partition generation example diff --git a/examples/storage/fatfsgen/pytest_fatfsgen_example.py b/examples/storage/fatfsgen/pytest_fatfsgen_example.py index c19201c5a3ae..74ed3d8051ba 100644 --- a/examples/storage/fatfsgen/pytest_fatfsgen_example.py +++ b/examples/storage/fatfsgen/pytest_fatfsgen_example.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import os diff --git a/examples/storage/nvs_rw_blob/README.md b/examples/storage/nvs_rw_blob/README.md index e9e2f52b8af1..7563617da8c0 100644 --- a/examples/storage/nvs_rw_blob/README.md +++ b/examples/storage/nvs_rw_blob/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Non-Volatile Storage (NVS) Read and Write Example diff --git a/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py b/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py index 23430e76d15b..422dee3bb067 100644 --- a/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py +++ b/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import logging @@ -11,8 +11,7 @@ from pytest_embedded import Dut -@pytest.mark.esp32 -@pytest.mark.esp32c3 +@pytest.mark.supported_targets def test_examples_nvs_rw_blob(dut: Dut) -> None: def expect_start_msg(index: int) -> None: dut.expect('Restart counter = {}'.format(index), timeout=10) diff --git a/examples/storage/nvs_rw_value/README.md b/examples/storage/nvs_rw_value/README.md index ca311bb26e14..dd67cc5f5eb9 100644 --- a/examples/storage/nvs_rw_value/README.md +++ b/examples/storage/nvs_rw_value/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Non-Volatile Storage (NVS) Read and Write Example diff --git a/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py b/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py index f42756d6f4fc..e7f2f30c2a9b 100644 --- a/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py +++ b/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import logging @@ -8,8 +8,7 @@ from pytest_embedded import Dut -@pytest.mark.esp32 -@pytest.mark.esp32c3 +@pytest.mark.supported_targets def test_examples_nvs_rw_value(dut: Dut) -> None: for i, counter_state in zip_longest(range(4), ('The value is not initialized yet!',), fillvalue='Done'): dut.expect('Opening Non-Volatile Storage \\(NVS\\) handle... Done', timeout=20) diff --git a/examples/storage/nvs_rw_value_cxx/README.md b/examples/storage/nvs_rw_value_cxx/README.md index 7108fef8bde9..5d9248d662d3 100644 --- a/examples/storage/nvs_rw_value_cxx/README.md +++ b/examples/storage/nvs_rw_value_cxx/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Non-Volatile Storage (NVS) C++ Read and Write Example diff --git a/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py b/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py index 86cf0105faa5..e2f990e8e8af 100644 --- a/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py +++ b/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import logging @@ -8,8 +8,7 @@ from pytest_embedded import Dut -@pytest.mark.esp32 -@pytest.mark.esp32c3 +@pytest.mark.supported_targets def test_examples_nvs_rw_value_cxx(dut: Dut) -> None: for i, counter_state in zip_longest(range(4), ('The value is not initialized yet!',), fillvalue='Done'): dut.expect('Opening Non-Volatile Storage \\(NVS\\) handle... Done', timeout=20) diff --git a/examples/storage/nvsgen/README.md b/examples/storage/nvsgen/README.md index 622573a4d0e6..e0f68366c0ea 100644 --- a/examples/storage/nvsgen/README.md +++ b/examples/storage/nvsgen/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # NVS Partition Image Generation on Build Example diff --git a/examples/storage/partition_api/partition_find/README.md b/examples/storage/partition_api/partition_find/README.md index 823f05a94425..50b471279fce 100644 --- a/examples/storage/partition_api/partition_find/README.md +++ b/examples/storage/partition_api/partition_find/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Finding Partitions Example diff --git a/examples/storage/partition_api/partition_find/pytest_partition_find_example.py b/examples/storage/partition_api/partition_find/pytest_partition_find_example.py index 1bd7d5a22ab3..6b03f8174c27 100644 --- a/examples/storage/partition_api/partition_find/pytest_partition_find_example.py +++ b/examples/storage/partition_api/partition_find/pytest_partition_find_example.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import re diff --git a/examples/storage/partition_api/partition_mmap/README.md b/examples/storage/partition_api/partition_mmap/README.md index 94ea4430d37c..d63e67af9c8b 100644 --- a/examples/storage/partition_api/partition_mmap/README.md +++ b/examples/storage/partition_api/partition_mmap/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Partition Memory Map Example diff --git a/examples/storage/partition_api/partition_mmap/pytest_partition_mmap_example.py b/examples/storage/partition_api/partition_mmap/pytest_partition_mmap_example.py index e77d29fe5bc7..46d306fc770e 100644 --- a/examples/storage/partition_api/partition_mmap/pytest_partition_mmap_example.py +++ b/examples/storage/partition_api/partition_mmap/pytest_partition_mmap_example.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import re diff --git a/examples/storage/partition_api/partition_ops/README.md b/examples/storage/partition_api/partition_ops/README.md index 8ff19ce942cf..0ca9e6dce529 100644 --- a/examples/storage/partition_api/partition_ops/README.md +++ b/examples/storage/partition_api/partition_ops/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Partition Read, Write, Erase Example diff --git a/examples/storage/partition_api/partition_ops/pytest_partition_ops_example.py b/examples/storage/partition_api/partition_ops/pytest_partition_ops_example.py index c5f031a7032a..74abd28608b3 100644 --- a/examples/storage/partition_api/partition_ops/pytest_partition_ops_example.py +++ b/examples/storage/partition_api/partition_ops/pytest_partition_ops_example.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import re diff --git a/examples/storage/parttool/README.md b/examples/storage/parttool/README.md index a26adf289de3..e369b66c210c 100644 --- a/examples/storage/parttool/README.md +++ b/examples/storage/parttool/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Partitions Tool Example diff --git a/examples/storage/parttool/pytest_parttool_example.py b/examples/storage/parttool/pytest_parttool_example.py index 9f984cfc1afe..8411418ab502 100644 --- a/examples/storage/parttool/pytest_parttool_example.py +++ b/examples/storage/parttool/pytest_parttool_example.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import os @@ -10,7 +10,6 @@ @pytest.mark.esp32 -@pytest.mark.esp32c3 def test_examples_parttool(dut: Dut) -> None: # Verify factory firmware dut.expect('Partitions Tool Example') diff --git a/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py b/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py index 34758fbe96a0..6275e231f68e 100644 --- a/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py +++ b/examples/storage/perf_benchmark/pytest_perf_benchmark_example.py @@ -52,8 +52,8 @@ def test_examples_perf_benchmark_sdcard_sdmmc(dut: Dut) -> None: @pytest.mark.esp32 -@pytest.mark.esp32s2 @pytest.mark.esp32c3 +@pytest.mark.esp32s2 @pytest.mark.sdcard_spimode @pytest.mark.parametrize( 'config', diff --git a/examples/storage/semihost_vfs/README.md b/examples/storage/semihost_vfs/README.md index ae14f9a1c2f7..5a744c2cdddc 100644 --- a/examples/storage/semihost_vfs/README.md +++ b/examples/storage/semihost_vfs/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Semihosting VFS driver example diff --git a/examples/storage/semihost_vfs/main/semihost_vfs_example_main.c b/examples/storage/semihost_vfs/main/semihost_vfs_example_main.c index 3db7d566b0b7..05a61e3f4bb2 100644 --- a/examples/storage/semihost_vfs/main/semihost_vfs_example_main.c +++ b/examples/storage/semihost_vfs/main/semihost_vfs_example_main.c @@ -14,6 +14,7 @@ #include #include "esp_err.h" #include "esp_log.h" +#include "esp_cpu.h" #include "esp_vfs_semihost.h" static const char *TAG = "example"; diff --git a/examples/storage/semihost_vfs/pytest_semihost_vfs.py b/examples/storage/semihost_vfs/pytest_semihost_vfs.py index ba5e5478d9cf..9345086b70b4 100644 --- a/examples/storage/semihost_vfs/pytest_semihost_vfs.py +++ b/examples/storage/semihost_vfs/pytest_semihost_vfs.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 import os @@ -24,7 +24,6 @@ def prepare() -> t.Generator[None, None, None]: shutil.rmtree(TEMP_DIR, ignore_errors=True) -@pytest.mark.esp32 @pytest.mark.jtag @pytest.mark.parametrize( 'embedded_services, no_gdb, openocd_cli_args', @@ -35,6 +34,30 @@ def prepare() -> t.Generator[None, None, None]: f'-c \'set ESP_SEMIHOST_BASEDIR "{TEMP_DIR}"\' -f board/esp32-wrover-kit-3.3v.cfg', marks=[pytest.mark.esp32], ), + # pytest.param( + # 'esp,idf,jtag', + # 'y', + # f'-c \'set ESP_SEMIHOST_BASEDIR "{TEMP_DIR}"\' -f board/esp32c2-ftdi.cfg', + # marks=[pytest.mark.esp32c2], + # ), + # pytest.param( + # 'esp,idf,jtag', + # 'y', + # f'-c \'set ESP_SEMIHOST_BASEDIR "{TEMP_DIR}"\' -f board/esp32s2-kaluga-1.cfg', + # marks=[pytest.mark.esp32c3], + # ), + # pytest.param( + # 'esp,idf,jtag', + # 'y', + # f'-c \'set ESP_SEMIHOST_BASEDIR "{TEMP_DIR}"\' -f board/esp32s2-kaluga-1.cfg', + # marks=[pytest.mark.esp32s2], + # ), + # pytest.param( + # 'esp,idf,jtag', + # 'y', + # f'-c \'set ESP_SEMIHOST_BASEDIR "{TEMP_DIR}"\' -f board/esp32s2-kaluga-1.cfg', + # marks=[pytest.mark.esp32s3], + # ), ], indirect=True, ) diff --git a/examples/storage/spiffs/README.md b/examples/storage/spiffs/README.md index eaa6959f4853..23508289c2e2 100644 --- a/examples/storage/spiffs/README.md +++ b/examples/storage/spiffs/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # SPIFFS example diff --git a/examples/storage/spiffs/pytest_spiffs_example.py b/examples/storage/spiffs/pytest_spiffs_example.py index 70e1540ecd67..0687ffe82f64 100644 --- a/examples/storage/spiffs/pytest_spiffs_example.py +++ b/examples/storage/spiffs/pytest_spiffs_example.py @@ -7,8 +7,7 @@ from pytest_embedded import Dut -@pytest.mark.esp32 -@pytest.mark.esp32c3 +@pytest.mark.supported_targets def test_examples_spiffs(dut: Dut) -> None: message_list = (rb'example: Initializing SPIFFS', rb'example: Partition size: total: \d+, used: \d+', diff --git a/examples/storage/spiffsgen/README.md b/examples/storage/spiffsgen/README.md index 8ec3c47be73b..eecc6230dca6 100644 --- a/examples/storage/spiffsgen/README.md +++ b/examples/storage/spiffsgen/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # SPIFFS Image Generation on Build Example diff --git a/examples/storage/spiffsgen/pytest_spiffsgen_example.py b/examples/storage/spiffsgen/pytest_spiffsgen_example.py index a4c9a7976f10..75f2a9ad3192 100644 --- a/examples/storage/spiffsgen/pytest_spiffsgen_example.py +++ b/examples/storage/spiffsgen/pytest_spiffsgen_example.py @@ -9,7 +9,6 @@ @pytest.mark.esp32 -@pytest.mark.esp32c3 def test_spiffsgen_example(dut: Dut) -> None: # Test with default build configurations base_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'spiffs_image') diff --git a/examples/storage/wear_levelling/README.md b/examples/storage/wear_levelling/README.md index 8f12b1a49315..3fbc2db4c6f7 100644 --- a/examples/storage/wear_levelling/README.md +++ b/examples/storage/wear_levelling/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # Wear levelling example diff --git a/examples/storage/wear_levelling/pytest_wear_levelling_example.py b/examples/storage/wear_levelling/pytest_wear_levelling_example.py index 51ef1670acdf..c55352e02ac8 100644 --- a/examples/storage/wear_levelling/pytest_wear_levelling_example.py +++ b/examples/storage/wear_levelling/pytest_wear_levelling_example.py @@ -8,8 +8,7 @@ from pytest_embedded import Dut -@pytest.mark.esp32 -@pytest.mark.esp32c3 +@pytest.mark.supported_targets def test_wear_levelling_example(dut: Dut) -> None: message_list = ('example: Mounting FAT filesystem', From 8f3abfb60ebc90774a22bd20c8eabfd15cdb8b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rohl=C3=ADnek?= Date: Mon, 9 Oct 2023 10:55:42 +0200 Subject: [PATCH 072/161] feat(storage): add dependencies for tests --- examples/storage/.build-test-rules.yml | 72 ++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/examples/storage/.build-test-rules.yml b/examples/storage/.build-test-rules.yml index 5bc57c03f332..30e10b7d3a08 100644 --- a/examples/storage/.build-test-rules.yml +++ b/examples/storage/.build-test-rules.yml @@ -1,13 +1,29 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps examples/storage/custom_flash_driver: + depends_components: + - fatfs + - vfs + - spi_flash + - driver examples/storage/emmc: + depends_components: + - sdmmc + - driver + - fatfs + - vfs enable: - if: IDF_TARGET == "esp32s3" reason: only support on esp32s3 examples/storage/ext_flash_fatfs: + depends_components: + - fatfs + - vfs + - spi_flash + - driver + - esp_system disable: - if: IDF_TARGET == "esp32p4" reason: not supported yet @@ -17,42 +33,77 @@ examples/storage/ext_flash_fatfs: reason: lack of runners examples/storage/fatfsgen: + depends_components: + - fatfs + - vfs + - esp_system disable_test: - if: IDF_TARGET != "esp32" reason: only one target needed examples/storage/nvs_rw_blob: + depends_components: + - nvs_flash + - driver + - esp_system examples/storage/nvs_rw_value: + depends_components: + - nvs_flash + - nvs_system examples/storage/nvs_rw_value_cxx: + depends_components: + - nvs_flash + - nvs_system examples/storage/nvsgen: + depends_components: + - nvs_flash disable_test: - if: IDF_TARGET != "esp32" reason: only one target needed examples/storage/partition_api/partition_find: + depends_components: + - esp_partition disable_test: - if: IDF_TARGET not in ["esp32", "esp32c3"] reason: only one target per arch needed examples/storage/partition_api/partition_mmap: + depends_components: + - esp_partition disable_test: - if: IDF_TARGET not in ["esp32", "esp32c3"] reason: only one target per arch needed examples/storage/partition_api/partition_ops: + depends_components: + - esp_partition + - spi_flash disable_test: - if: IDF_TARGET not in ["esp32", "esp32c3"] reason: only one target per arch needed examples/storage/parttool: + depends_components: + - partition_table disable_test: - if: IDF_TARGET != "esp32" reason: only one target needed examples/storage/perf_benchmark: + depends_components: + - fatfs + - spi_flash + - vfs + - sdmmc + - spiffs + - soc + - wear_levelling + - esp_partition + - driver disable: - if: IDF_TARGET == "esp32p4" and CONFIG_NAME in ["sdmmc_1line", "sdmmc_4line", "sdspi_1line"] temporary: true @@ -63,6 +114,10 @@ examples/storage/perf_benchmark: reason: SPIFLASH not supported on P4 yet, only build stage enabled # TODO: IDF-7499 examples/storage/sd_card/sdmmc: + depends_components: + - vfs + - sdmmc + - driver disable: - if: SOC_SDMMC_HOST_SUPPORTED != 1 disable_test: @@ -71,6 +126,10 @@ examples/storage/sd_card/sdmmc: reason: lack of runners examples/storage/sd_card/sdspi: + depends_components: + - vfs + - sdmmc + - driver disable: - if: SOC_GPSPI_SUPPORTED != 1 disable_test: @@ -79,16 +138,29 @@ examples/storage/sd_card/sdspi: reason: lack of runners examples/storage/semihost_vfs: + depends_components: + - vfs disable_test: - if: IDF_TARGET not in ["esp32"] temporary: true reason: lack of runners examples/storage/spiffs: + depends_components: + - spiffs + - vfs examples/storage/spiffsgen: + depends_components: + - spiffs + - vfs + - mbedtls disable_test: - if: IDF_TARGET != "esp32" reason: only one target needed examples/storage/wear_levelling: + depends_components: + - vfs + - wear_levelling + - fatfs From 1fa85abf46ca0e7656d0f90705abe714c052122f Mon Sep 17 00:00:00 2001 From: gaoxu Date: Fri, 27 Oct 2023 17:11:13 +0800 Subject: [PATCH 073/161] ci(adc): add a test that adc read zero after getting done signal --- .../esp_adc/test_apps/adc/main/test_adc.c | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/components/esp_adc/test_apps/adc/main/test_adc.c b/components/esp_adc/test_apps/adc/main/test_adc.c index 30230fa4c29a..ad65b3f82742 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc.c +++ b/components/esp_adc/test_apps/adc/main/test_adc.c @@ -15,6 +15,7 @@ #include "driver/gpio.h" #include "driver/rtc_io.h" #include "test_common_adc.h" +#include "esp_rom_sys.h" const __attribute__((unused)) static char *TAG = "TEST_ADC"; @@ -117,6 +118,44 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]") #endif //#if ADC_TEST_ONESHOT_HIGH_LOW_TEST_ADC2 } +TEST_CASE("ADC oneshot stress test that get zero even if convent done", "[adc_oneshot]") +{ + //There is a hardware limitation. After ADC get DONE signal, it still need a delay to synchronize ADC raw data or it may get zero even if getting DONE signal. + + int test_num = 100; + adc_channel_t channel = ADC1_TEST_CHAN1; + adc_atten_t atten = ADC_ATTEN_DB_11; + adc_unit_t unit_id = ADC_UNIT_1; + + adc_oneshot_unit_handle_t adc1_handle; + adc_oneshot_unit_init_cfg_t init_config1 = { + .unit_id = unit_id, + .ulp_mode = ADC_ULP_MODE_DISABLE, + }; + + adc_oneshot_chan_cfg_t config = { + .bitwidth = SOC_ADC_RTC_MAX_BITWIDTH, + .atten = atten, + }; + + int raw_data = 0; + srand(199); + + for (int i = 0; i < test_num; i++) { + test_adc_set_io_level(unit_id, ADC1_TEST_CHAN1, 1); + + TEST_ESP_OK(adc_oneshot_new_unit(&init_config1, &adc1_handle)); + TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, channel, &config)); + TEST_ESP_OK(adc_oneshot_read(adc1_handle, channel, &raw_data)); + + TEST_ASSERT_NOT_EQUAL(0, raw_data); + + TEST_ESP_OK(adc_oneshot_del_unit(adc1_handle)); + + esp_rom_delay_us(rand() % 512); + } +} + #if SOC_ADC_CALIBRATION_V1_SUPPORTED /*--------------------------------------------------------------- ADC Oneshot with Light Sleep From a4e712f61aed6afa64205364f9a5a004495979f9 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Fri, 27 Oct 2023 16:18:48 +0530 Subject: [PATCH 074/161] fix(nimble): remove IRAM_ATTR from npl_os_freertos.c file --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index b85d99de41d8..98b88eacee2d 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit b85d99de41d8c9085c6f3de50a29ebedd9681381 +Subproject commit 98b88eacee2daf00f19c4ff52855cc3327d12e81 From 6f400e1b5d3b6db54620cbea6efbd2e40e8f55d9 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Tue, 24 Oct 2023 11:44:32 +0800 Subject: [PATCH 075/161] feat(bt/bluedroid): Support BLE gattc notify registration number --- components/bt/host/bluedroid/Kconfig.in | 8 ++++++++ components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c | 2 +- .../bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h | 4 ---- .../common/include/common/bluedroid_user_config.h | 7 +++++++ .../bt/host/bluedroid/common/include/common/bt_target.h | 6 ++++++ 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 079080bf3af8..7add8fbf9a02 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -250,6 +250,14 @@ config BT_GATTC_MAX_CACHE_CHAR help Maximum GATTC cache characteristic count +config BT_GATTC_NOTIF_REG_MAX + int "Max gattc notify(indication) register number" + depends on BT_GATTC_ENABLE + range 1 64 + default 5 + help + Maximum GATTC notify(indication) register number + config BT_GATTC_CACHE_NVS_FLASH bool "Save gattc cache data to nvs flash" depends on BT_GATTC_ENABLE diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c index 3e42603aeb44..6e2586d69c0e 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c @@ -932,7 +932,7 @@ tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if, } if (i == BTA_GATTC_NOTIF_REG_MAX) { status = BTA_GATT_NO_RESOURCES; - APPL_TRACE_ERROR("Max Notification Reached, registration failed."); + APPL_TRACE_ERROR("Max Notification Reached, registration failed,see CONFIG_BT_GATTC_NOTIF_REG_MAX in menuconfig"); } } } else { diff --git a/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h b/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h index 9797c4793cda..108358ca63b8 100644 --- a/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h +++ b/components/bt/host/bluedroid/bta/gatt/include/bta_gattc_int.h @@ -319,10 +319,6 @@ typedef struct { bool update_incl_srvc; } tBTA_GATTC_SERV; -#ifndef BTA_GATTC_NOTIF_REG_MAX -#define BTA_GATTC_NOTIF_REG_MAX BTA_GATTC_CONN_MAX -#endif - typedef struct { BOOLEAN in_use; BD_ADDR remote_bda; 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 82b3bf5bd02e..7c017363e6cc 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 @@ -163,6 +163,13 @@ #define UC_BT_GATTC_MAX_CACHE_CHAR 40 #endif +//GATTC NOTIF +#ifdef CONFIG_BT_GATTC_NOTIF_REG_MAX +#define UC_BT_GATTC_NOTIF_REG_MAX CONFIG_BT_GATTC_NOTIF_REG_MAX +#else +#define UC_BT_GATTC_NOTIF_REG_MAX 5 +#endif + #ifdef CONFIG_BT_GATTC_CACHE_NVS_FLASH #define UC_BT_GATTC_CACHE_NVS_FLASH_ENABLED CONFIG_BT_GATTC_CACHE_NVS_FLASH #else 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 4c3c5ef37cb7..e97b4178ffb6 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -248,6 +248,12 @@ #define GATTC_CONNECT_RETRY_EN FALSE #endif +#ifdef UC_BT_GATTC_NOTIF_REG_MAX +#define BTA_GATTC_NOTIF_REG_MAX UC_BT_GATTC_NOTIF_REG_MAX +#else +#define BTA_GATTC_NOTIF_REG_MAX 5 +#endif + #if (UC_BT_SMP_ENABLE) #define SMP_INCLUDED TRUE #if (BLE_INCLUDED == TRUE) From a051438322fcb8cf12248f8801d2bf38f0326d48 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Tue, 24 Oct 2023 11:59:23 +0800 Subject: [PATCH 076/161] fix(bt/bluedroid): Fix max BLE gattc notify number to improve compatibility --- examples/bluetooth/esp_hid_host/sdkconfig.defaults | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/bluetooth/esp_hid_host/sdkconfig.defaults b/examples/bluetooth/esp_hid_host/sdkconfig.defaults index 2828e5ca2ac7..1c2104eacc6b 100644 --- a/examples/bluetooth/esp_hid_host/sdkconfig.defaults +++ b/examples/bluetooth/esp_hid_host/sdkconfig.defaults @@ -7,3 +7,4 @@ CONFIG_BT_BLE_ENABLED=y CONFIG_BT_HID_ENABLED=y CONFIG_BT_HID_HOST_ENABLED=y CONFIG_BT_BLE_42_FEATURES_SUPPORTED=y +CONFIG_BT_GATTC_NOTIF_REG_MAX=16 From f4305753c859f5fa2c589f82b96c782bc43ec6d2 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Tue, 24 Oct 2023 14:23:00 +0800 Subject: [PATCH 077/161] feat(bt/bluedroid): Display BLE permission check handle in error trace --- .../bt/host/bluedroid/stack/gatt/gatt_db.c | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_db.c b/components/bt/host/bluedroid/stack/gatt/gatt_db.c index cd2d2ddc4986..4aebc30f40ee 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_db.c @@ -1173,39 +1173,39 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, if ((op_code == GATT_SIGN_CMD_WRITE) && !(perm & GATT_WRITE_SIGNED_PERM)) { status = GATT_WRITE_NOT_PERMIT; - GATT_TRACE_DEBUG( "gatts_write_attr_perm_check - sign cmd write not allowed"); + GATT_TRACE_DEBUG( "gatts_write_attr_perm_check - sign cmd write not allowed,handle:0x%04x",handle); } if ((op_code == GATT_SIGN_CMD_WRITE) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED)) { status = GATT_INVALID_PDU; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encypted link"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - Error!! sign cmd write sent on a encypted link,handle:0x%04x",handle); } else if (!(perm & GATT_WRITE_ALLOWED)) { status = GATT_WRITE_NOT_PERMIT; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_WRITE_NOT_PERMIT,handle:0x%04x",handle); } /* require authentication, but not been authenticated */ else if ((perm & GATT_WRITE_AUTH_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_UNAUTHED)) { status = GATT_INSUF_AUTHENTICATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION,handle:0x%04x",handle); } else if ((perm & GATT_WRITE_MITM_REQUIRED ) && !(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED)) { status = GATT_INSUF_AUTHENTICATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: MITM required,handle:0x%04x",handle); } else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED)) { status = GATT_INSUF_ENCRYPTION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_ENCRYPTION,handle:0x%04x",handle); } else if ((perm & GATT_WRITE_ENCRYPTED_PERM ) && (sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (key_size < min_key_size)) { status = GATT_INSUF_KEY_SIZE; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_KEY_SIZE,handle:0x%04x",handle); } /* LE Authorization check*/ else if ((perm & GATT_WRITE_AUTHORIZATION) && (!(sec_flag & GATT_SEC_FLAG_LKEY_AUTHED) || !(sec_flag & GATT_SEC_FLAG_AUTHORIZATION))){ status = GATT_INSUF_AUTHORIZATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHORIZATION"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHORIZATION,handle:0x%04x",handle); } /* LE security mode 2 attribute */ else if (perm & GATT_WRITE_SIGNED_PERM && op_code != GATT_SIGN_CMD_WRITE && !(sec_flag & GATT_SEC_FLAG_ENCRYPTED) && (perm & GATT_WRITE_ALLOWED) == 0) { status = GATT_INSUF_AUTHENTICATION; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INSUF_AUTHENTICATION: LE security mode 2 required,handle:0x%04x",handle); } else { /* writable: must be char value declaration or char descritpors */ if (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) { switch (p_attr->uuid) { @@ -1246,10 +1246,10 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, { if (op_code == GATT_REQ_PREPARE_WRITE && offset != 0) { /* does not allow write blob */ status = GATT_NOT_LONG; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_NOT_LONG"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_NOT_LONG,handle:0x%04x",handle); } else if (len != max_size) { /* data does not match the required format */ status = GATT_INVALID_ATTR_LEN; - GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INVALID_PDU"); + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_INVALID_PDU,handle:0x%04x",handle); } else { status = GATT_SUCCESS; } From b281a72fa17c034796ea785e97814cd43a1881f1 Mon Sep 17 00:00:00 2001 From: luomanruo Date: Fri, 27 Oct 2023 20:11:47 +0800 Subject: [PATCH 078/161] ble: update c2 lib to 6ed444f2 --- components/bt/controller/lib_esp32c2/esp32c2-bt-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib index 30e5c4f95bff..ea33fbad1fa0 160000 --- a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib +++ b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib @@ -1 +1 @@ -Subproject commit 30e5c4f95bff1a17e06ce1042a165b0aa2bc4ca5 +Subproject commit ea33fbad1fa0879fe0e118359d20463b3e2f126b From 3a998bd0ce18e00551cc558b4bf0c0cd0aa2b452 Mon Sep 17 00:00:00 2001 From: Aleksei Apaseev Date: Fri, 27 Oct 2023 17:32:47 +0800 Subject: [PATCH 079/161] ci: Upload artifacts of target stage jobs to s3 bucket --- .gitlab/ci/target-test.yml | 4 ++++ tools/ci/artifacts_handler.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 803efd9dae0c..b2fec6d5400c 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -50,6 +50,7 @@ --parallel-index ${CI_NODE_INDEX:-1} ${PYTEST_EXTRA_FLAGS} --app-info-filepattern \"list_job_*.txt\" + - python tools/ci/artifacts_handler.py upload --type logs junit_reports .pytest_examples_dir_template: extends: .pytest_template @@ -1298,6 +1299,7 @@ pytest_examples_openthread_br: --parallel-index ${CI_NODE_INDEX:-1} ${PYTEST_EXTRA_FLAGS} --app-info-filepattern \"list_job_*.txt\" + - python tools/ci/artifacts_handler.py upload --type logs junit_reports pytest_examples_openthread_bbr: extends: @@ -1332,6 +1334,7 @@ pytest_examples_openthread_bbr: --parallel-index ${CI_NODE_INDEX:-1} ${PYTEST_EXTRA_FLAGS} --app-info-filepattern \"list_job_*.txt\" + - python tools/ci/artifacts_handler.py upload --type logs junit_reports pytest_examples_openthread_sleep: extends: @@ -1363,6 +1366,7 @@ pytest_examples_openthread_sleep: --parallel-index ${CI_NODE_INDEX:-1} ${PYTEST_EXTRA_FLAGS} --app-info-filepattern \"list_job_*.txt\" + - python tools/ci/artifacts_handler.py upload --type logs junit_reports pytest_examples_esp32h2_zigbee: extends: diff --git a/tools/ci/artifacts_handler.py b/tools/ci/artifacts_handler.py index 070a88e5ca33..496e88e6b89b 100644 --- a/tools/ci/artifacts_handler.py +++ b/tools/ci/artifacts_handler.py @@ -21,6 +21,7 @@ class ArtifactType(str, Enum): LOGS = 'logs' SIZE_REPORTS = 'size_reports' + JUNIT_REPORTS = 'junit_reports' TYPE_PATTERNS_DICT = { @@ -48,6 +49,9 @@ class ArtifactType(str, Enum): '**/build*/size.json', 'size_info.txt', ], + ArtifactType.JUNIT_REPORTS: [ + 'XUNIT_RESULT.xml', + ], } From 24446bfab1eeb37447388aa44efcf34e0b904954 Mon Sep 17 00:00:00 2001 From: Espressif BOT Date: Wed, 25 Oct 2023 19:19:40 +0800 Subject: [PATCH 080/161] change(esp_crt_bundle): Update esp_crt_bundle certificates --- .../mbedtls/esp_crt_bundle/cacrt_all.pem | 289 +++++++++++------- .../esp_crt_bundle/cacrt_deprecated.pem | 114 +++++++ .../protocols/esp_crt_bundle.rst | 2 +- 3 files changed, 299 insertions(+), 106 deletions(-) create mode 100644 components/mbedtls/esp_crt_bundle/cacrt_deprecated.pem diff --git a/components/mbedtls/esp_crt_bundle/cacrt_all.pem b/components/mbedtls/esp_crt_bundle/cacrt_all.pem index 2ae7b6cb21ba..9551dfd830b9 100644 --- a/components/mbedtls/esp_crt_bundle/cacrt_all.pem +++ b/components/mbedtls/esp_crt_bundle/cacrt_all.pem @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Tue Jan 10 04:12:06 2023 GMT +## Certificate data from Mozilla as of: Tue Aug 22 03:12:04 2023 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: 90c470e705b4b5f36f09684dc50e2b79c8b86989a848b62cd1a7bd6460ee65f6 +## SHA256: 0ff137babc6a5561a9cfbe9f29558972e5b528202681b7d3803d03a3e82922bd ## @@ -603,26 +603,6 @@ NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- -Hongkong Post Root CA 1 -======================= ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT -DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx -NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n -IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 -ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr -auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh -qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY -V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV -HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i -h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio -l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei -IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps -T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT -c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== ------END CERTIFICATE----- - SecureSign RootCA11 =================== -----BEGIN CERTIFICATE----- @@ -1261,40 +1241,6 @@ Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- -E-Tugra Certification Authority -=============================== ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w -DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls -ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw -NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx -QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl -cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD -DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd -hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K -CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g -ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ -BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 -E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz -rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq -jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 -dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB -/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG -MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK -kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO -XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 -VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo -a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc -dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV -KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT -Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 -8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G -C7TbO6Orb1wdtn7os4I07QZcJA== ------END CERTIFICATE----- - T-TeleSec GlobalRoot Class 2 ============================ -----BEGIN CERTIFICATE----- @@ -3276,55 +3222,6 @@ AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8 rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR -----END CERTIFICATE----- -E-Tugra Global Root CA RSA v3 -============================= ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -E-Tugra Global Root CA ECC v3 -============================= ------BEGIN CERTIFICATE----- -MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAbBgNV -BAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENB -IEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEP -MA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 -Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBFQ0MgdjMw -djAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQKczLWYHMjLiSF4mDKpL2 -w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YKfWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31 -Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQ -zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO -PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W -Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 ------END CERTIFICATE----- - Security Communication RootCA3 ============================== -----BEGIN CERTIFICATE----- @@ -3370,3 +3267,185 @@ BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e N9k= -----END CERTIFICATE----- + +BJCA Global Root CA1 +==================== +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQG +EwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJK +Q0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAzMTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkG +A1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQD +DBRCSkNBIEdsb2JhbCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFm +CL3ZxRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZspDyRhyS +sTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O558dnJCNPYwpj9mZ9S1Wn +P3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgRat7GGPZHOiJBhyL8xIkoVNiMpTAK+BcW +yqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRj +eulumijWML3mG90Vr4TqnMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNn +MoH1V6XKV0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/pj+b +OT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZOz2nxbkRs1CTqjSSh +GL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXnjSXWgXSHRtQpdaJCbPdzied9v3pK +H9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMB +AAGjQjBAMB0GA1UdDgQWBBTF7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3KliawLwQ8hOnThJ +dMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u+2D2/VnGKhs/I0qUJDAnyIm8 +60Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuh +TaRjAv04l5U/BXCga99igUOLtFkNSoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW +4AB+dAb/OMRyHdOoP2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmp +GQrI+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRzznfSxqxx +4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9eVzYH6Eze9mCUAyTF6ps +3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4S +SPfSKcOYKMryMguTjClPPGAyzQWWYezyr/6zcCwupvI= +-----END CERTIFICATE----- + +BJCA Global Root CA2 +==================== +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQswCQYDVQQGEwJD +TjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJKQ0Eg +R2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgyMVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UE +BhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRC +SkNBIEdsb2JhbCBSb290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jl +SR9BIgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK++kpRuDCK +/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJKsVF/BvDRgh9Obl+rg/xI +1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8 +W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8g +UXOQwKhbYdDFUDn9hf7B43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root E46 +============================================= +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQswCQYDVQQGEwJH +QjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBTZXJ2 +ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5 +WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0 +aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUr +gQQAIgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccCWvkEN/U0 +NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+6xnOQ6OjQjBAMB0GA1Ud +DgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAKBggqhkjOPQQDAwNnADBkAjAn7qRaqCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RH +lAFWovgzJQxC36oCMB3q4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21U +SAGKcw== +-----END CERTIFICATE----- + +Sectigo Public Server Authentication Root R46 +============================================= +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBfMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1 +OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3 +DQEBAQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDaef0rty2k +1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnzSDBh+oF8HqcIStw+Kxwf +GExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xfiOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMP +FF1bFOdLvt30yNoDN9HWOaEhUTCDsG3XME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vu +ZDCQOc2TZYEhMbUjUDM3IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5Qaz +Yw6A3OASVYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgESJ/A +wSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu+Zd4KKTIRJLpfSYF +plhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt8uaZFURww3y8nDnAtOFr94MlI1fZ +EoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+LHaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW +6aWWrL3DkJiy4Pmi1KZHQ3xtzwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWI +IUkwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQYKlJfp/imTYp +E0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52gDY9hAaLMyZlbcp+nv4fjFg4 +exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZAFv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M +0ejf5lG5Nkc/kLnHvALcWxxPDkjBJYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI +84HxZmduTILA7rpXDhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9m +pFuiTdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5dHn5Hrwd +Vw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65LvKRRFHQV80MNNVIIb/b +E/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmm +J1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAYQqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +SSL.com TLS RSA Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQG +EwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBSU0Eg +Um9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloXDTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMC +VVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u +9nTPL3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OYt6/wNr/y +7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0insS657Lb85/bRi3pZ7Qcac +oOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3PnxEX4MN8/HdIGkWCVDi1FW24IBydm5M +R7d1VVm0U3TZlMZBrViKMWYPHqIbKUBOL9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDG +D6C1vBdOSHtRwvzpXGk3R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEW +TO6Af77wdr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS+YCk +8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYSd66UNHsef8JmAOSq +g+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoGAtUjHBPW6dvbxrB6y3snm/vg1UYk +7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2fgTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsu +N+7jhHonLs0ZNbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsMQtfhWsSWTVTN +j8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvfR4iyrT7gJ4eLSYwfqUdYe5by +iB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJDPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjU +o3KUQyxi4U5cMj29TH0ZR6LDSeeWP4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqo +ENjwuSfr98t67wVylrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7Egkaib +MOlqbLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2wAgDHbICi +vRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3qr5nsLFR+jM4uElZI7xc7 +P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sjiMho6/4UIyYOf8kpIEFR3N+2ivEC+5BB0 +9+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +SSL.com TLS ECC Root CA 2022 +============================ +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV +UzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBFQ0MgUm9v +dCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMx +GDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWy +JGYmacCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFNSeR7T5v1 +5wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSJjy+j6CugFFR7 +81a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NWuCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGG +MAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w +7deedWo1dlJF4AIxAMeNb0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5 +Zn6g6g== +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA ECC TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4wLAYDVQQDDCVB +dG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQswCQYD +VQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3Mg +VHJ1c3RlZFJvb3QgUm9vdCBDQSBFQ0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYT +AkRFMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6K +DP/XtXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4AjJn8ZQS +b+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2KCXWfeBmmnoJsmo7jjPX +NtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIwW5kp85wxtolrbNa9d+F851F+ +uDrNozZffPc8dz7kUK2o59JZDCaOMDtuCCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGY +a3cpetskz2VAv9LcjBHo9H1/IISpQuQo +-----END CERTIFICATE----- + +Atos TrustedRoot Root CA RSA TLS 2021 +===================================== +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBMMS4wLAYDVQQD +DCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQsw +CQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0 +b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNV +BAYTAkRFMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BB +l01Z4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYvYe+W/CBG +vevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZkmGbzSoXfduP9LVq6hdK +ZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDsGY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt +0xU6kGpn8bRrZtkh68rZYnxGEFzedUlnnkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVK +PNe0OwANwI8f4UDErmwh3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMY +sluMWuPD0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzygeBY +Br3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8ANSbhqRAvNncTFd+ +rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezBc6eUWsuSZIKmAMFwoW4sKeFYV+xa +fJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lIpw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUdEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0G +CSqGSIb3DQEBDAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPso0UvFJ/1TCpl +Q3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJqM7F78PRreBrAwA0JrRUITWX +AdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuywxfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9G +slA9hGCZcbUztVdF5kJHdWoOsAgMrr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2Vkt +afcxBPTy+av5EzH4AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9q +TFsR0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuYo7Ey7Nmj +1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5dDTedk+SKlOxJTnbPP/l +PqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcEoji2jbDwN/zIIX8/syQbPYtuzE2wFg2W +HYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- diff --git a/components/mbedtls/esp_crt_bundle/cacrt_deprecated.pem b/components/mbedtls/esp_crt_bundle/cacrt_deprecated.pem new file mode 100644 index 000000000000..f5ec79d41edf --- /dev/null +++ b/components/mbedtls/esp_crt_bundle/cacrt_deprecated.pem @@ -0,0 +1,114 @@ +## +## Deprecated CA Root Certificates +## Deprecated CA Root Certificates that get appended to 'cacrt_all.pem' + +## These certificates have been removed from the newer Mozilla CA certificate store. +## Refer to https://wiki.mozilla.org/CA/Removed_Certificates for more information. + +## These certificates might be removed from ESP-IDF during every major release. + +## The current deprecated certificate bundle is up-to-date with the Mozilla cert bundle (cacrt_all.pem) dated Tue Aug 22 03:12:04 2023 GMT + + +Hongkong Post Root CA 1 +======================= +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT +DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx +NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n +IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 +ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr +auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh +qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY +V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV +HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i +h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio +l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei +IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps +T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT +c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== +-----END CERTIFICATE----- + +E-Tugra Certification Authority +=============================== +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w +DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls +ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw +NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx +QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl +cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD +DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd +hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K +CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g +ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ +BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 +E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz +rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq +jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 +dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG +MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK +kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO +XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 +VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo +a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc +dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV +KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT +Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 +8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G +C7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +E-Tugra Global Root CA RSA v3 +============================= +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +E-Tugra Global Root CA ECC v3 +============================= +-----BEGIN CERTIFICATE----- +MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMwgYAxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVncmEgRUJHIEEuUy4xHTAbBgNV +BAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENB +IEVDQyB2MzAeFw0yMDAzMTgwOTQ2NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEP +MA0GA1UEBxMGQW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 +Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBFQ0MgdjMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQKczLWYHMjLiSF4mDKpL2 +w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YKfWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31 +Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQ +zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO +PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W +Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 +-----END CERTIFICATE----- diff --git a/docs/en/api-reference/protocols/esp_crt_bundle.rst b/docs/en/api-reference/protocols/esp_crt_bundle.rst index 5a2f5fbe4b06..e4c92ee62294 100644 --- a/docs/en/api-reference/protocols/esp_crt_bundle.rst +++ b/docs/en/api-reference/protocols/esp_crt_bundle.rst @@ -16,7 +16,7 @@ The bundle comes with the complete list of root certificates from Mozilla's NSS When generating the bundle you may choose between: - * The full root certificate bundle from Mozilla, containing more than 130 certificates. The current bundle was updated Tue Jan 10 04:12:06 2023 GMT. + * The full root certificate bundle from Mozilla, containing more than 130 certificates. The current bundle was updated Tue Aug 22 03:12:04 2023 GMT. * A pre-selected filter list of the name of the most commonly used root certificates, reducing the amount of certificates to around 41 while still having around 90% absolute usage coverage and 99% market share coverage according to SSL certificate authorities statistics. In addition, it is possible to specify a path to a certificate file or a directory containing certificates which then will be added to the generated bundle. From 5b047057cacaa6c52a41ccbdf3fc35477e1e9b01 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Tue, 24 Oct 2023 18:55:24 +0530 Subject: [PATCH 081/161] feat(mbedtls): add new deprecated cert list and relevant config Cert bundle is periodically updated with the upstream Mozilla's NSS root cert store. Retracted certs are moved to deprecated list now and an additional config allows to include them in the default bundle. New config is kept default disabled but can be enabled if one would like to ensure 100% compatibility w.r.t. cert bundle across IDF minor or patch releases. In IDF major release the deprecated list shall be reset. --- components/mbedtls/CMakeLists.txt | 6 ++++++ components/mbedtls/Kconfig | 15 +++++++++++++++ examples/protocols/https_request/sdkconfig.ci | 1 + 3 files changed, 22 insertions(+) diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 3d2ad9d8553e..a162a0a3abd6 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -45,6 +45,12 @@ if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE) list(APPEND args --filter ${DEFAULT_CRT_DIR}/cmn_crt_authorities.csv) endif() + # Add deprecated root certs if enabled. This config is not visible if the default cert + # bundle is not selected + if(CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST) + list(APPEND crt_paths ${DEFAULT_CRT_DIR}/cacrt_deprecated.pem) + endif() + if(CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE) get_filename_component(custom_bundle_path ${CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH} ABSOLUTE BASE_DIR "${project_dir}") diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index e618261230f9..8fc0f0eb2b70 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -348,6 +348,21 @@ menu "mbedTLS" Name of the custom certificate directory or file. This path is evaluated relative to the project root directory. + config MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST + bool "Add deprecated root certificates" + depends on MBEDTLS_CERTIFICATE_BUNDLE && !MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE + help + Include the deprecated list of root certificates in the bundle. + This list gets updated when a certificate is removed from the Mozilla's + NSS root certificate store. This config can be enabled if you would like + to ensure that none of the certificates that were deployed in the product + are affected because of the update to bundle. In turn, enabling this + config keeps expired, retracted certificates in the bundle and it may + pose a security risk. + + - Deprecated cert list may grow based based on sync with upstream bundle + - Deprecated certs would be be removed in ESP-IDF (next) major release + config MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS int "Maximum no of certificates allowed in certificate bundle" default 200 diff --git a/examples/protocols/https_request/sdkconfig.ci b/examples/protocols/https_request/sdkconfig.ci index 5577f9549a77..9f61f58c61b8 100644 --- a/examples/protocols/https_request/sdkconfig.ci +++ b/examples/protocols/https_request/sdkconfig.ci @@ -10,3 +10,4 @@ CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 CONFIG_EXAMPLE_ETH_PHY_ADDR=1 CONFIG_EXAMPLE_CONNECT_IPV6=y CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST=y From ac97c61d1a633b412a36644482d9b5bbe738f2ac Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Tue, 24 Oct 2023 18:56:58 +0530 Subject: [PATCH 082/161] docs: add section about periodic sync of the certificate bundle --- docs/en/api-reference/protocols/esp_crt_bundle.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/en/api-reference/protocols/esp_crt_bundle.rst b/docs/en/api-reference/protocols/esp_crt_bundle.rst index e4c92ee62294..88e343ab4076 100644 --- a/docs/en/api-reference/protocols/esp_crt_bundle.rst +++ b/docs/en/api-reference/protocols/esp_crt_bundle.rst @@ -76,6 +76,11 @@ Updating the Certificate Bundle The bundle is embedded into the app and can be updated along with the app by an OTA update. If you want to include a more up-to-date bundle than the bundle currently included in ESP-IDF, then the certificate list can be downloaded from Mozilla as described in :ref:`updating_bundle`. +Periodic Sync +------------- + +The bundle is kept updated by periodic sync with the Mozilla's NSS root certificate store. The deprecated certs from the upstream bundle are added to deprecated list (for compatibility reasons) in ESP-IDF minor or patch release. If required, the deprecated certs can be added to the default bundle by enabling :ref:`CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST`. The deprecated certs shall be removed (reset) on the next major ESP-IDF release. + Application Examples -------------------- From 64cb35deef5996ada376715e81d341cbd136faf4 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Tue, 24 Oct 2023 18:57:28 +0530 Subject: [PATCH 083/161] docs(security): add section about managing the root certificates --- docs/en/security/security.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/en/security/security.rst b/docs/en/security/security.rst index 521f3189510e..8b173aaa0ea0 100644 --- a/docs/en/security/security.rst +++ b/docs/en/security/security.rst @@ -177,6 +177,23 @@ UART Download Mode It is highly recommended to verify the identity of the server based on X.509 certificates to avoid establishing communication with the **fake** server. + Managing Root Certificates + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Root Certificates embedded inside the application must be managed carefully. Any update to the root certificate list or the :doc:`../api-reference/protocols/esp_crt_bundle` can have an impact on the TLS connection with the remote endpoint. This includes a connection to the OTA update server. In some cases, the problem shall be visible on the next OTA update and it may leave device unable to perform OTA updates forever. + + Root certificates list update could have following reasons: + + - New firmware has different set of remote endpoint(s). + - Existing certificate has expired. + - The certificate has been added or retracted from the upstream certificate bundle. + - The certificate list changed due to market share statistics (``CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN`` case). + + Some guidelines to consider on this topic: + + - Please consider enabling :ref:`OTA rollback ` and then keep the successful connection to the OTA update server as the checkpoint to cancel the rollback process. This ensures that the newly updated firmware can successfully reach till the OTA update server, otherwise rollback process will go back to the previous firmware on the device. + - If you plan to enable the :ref:`CONFIG_MBEDTLS_HAVE_TIME_DATE` option then please consider to have sufficient number of trusted certificates and the time sync mechanism (SNTP) in place. + Product Security ---------------- From fc174f581170cedfd4572d6ba13864850cf68fec Mon Sep 17 00:00:00 2001 From: Jin Cheng Date: Fri, 1 Sep 2023 09:29:40 +0800 Subject: [PATCH 084/161] feat(bt/bluedroid): Added mode to use BlueDroid host only without Bluetooth Controller --- components/bt/CMakeLists.txt | 40 +++++---- components/bt/Kconfig | 6 +- components/bt/common/include/bt_user_config.h | 8 +- components/bt/host/bluedroid/Kconfig.in | 15 ++-- .../bt/host/bluedroid/api/esp_bluedroid_hci.c | 89 +++++++++++++++++++ .../bt/host/bluedroid/api/esp_bt_main.c | 5 ++ .../bt/host/bluedroid/api/esp_hf_ag_api.c | 2 + .../api/include/api/esp_bluedroid_hci.h | 84 +++++++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 13 ++- .../btc/profile/std/gap/btc_gap_ble.c | 7 ++ .../btc/profile/std/hf_ag/btc_hf_ag.c | 4 + .../btc/profile/std/hf_client/btc_hf_client.c | 9 +- .../include/common/bluedroid_user_config.h | 2 +- .../common/include/common/bt_target.h | 6 ++ components/bt/host/bluedroid/hci/hci_hal_h4.c | 16 ++-- components/bt/host/bluedroid/hci/hci_layer.c | 6 +- .../host/bluedroid/hci/include/hci/hci_hal.h | 5 +- .../bluedroid/hci/include/hci/hci_trans_int.h | 47 ++++++++++ components/bt/test_apps/main/test_smp.c | 1 - components/esp_hid/src/ble_hidd.c | 1 - components/esp_hid/src/ble_hidh.c | 1 - components/esp_hid/src/bt_hidd.c | 1 - .../protocomm/src/simple_ble/simple_ble.c | 9 +- components/soc/esp32p4/include/soc/soc.h | 1 + components/wifi_provisioning/src/scheme_ble.c | 18 +++- .../main/advanced_https_ota_example.c | 2 +- .../main/ble_helper/ble_api.c | 2 +- .../main/ble_helper/bluedroid_gatts.c | 2 +- .../main/ble_helper/include/ble_api.h | 2 +- .../main/ble_helper/include/bluedroid_gatts.h | 2 +- 30 files changed, 349 insertions(+), 57 deletions(-) create mode 100644 components/bt/host/bluedroid/api/esp_bluedroid_hci.c create mode 100644 components/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h create mode 100644 components/bt/host/bluedroid/hci/include/hci/hci_trans_int.h diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 67ca86cd1574..736709fc5435 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -70,30 +70,35 @@ if(CONFIG_BT_ENABLED) set(srcs "") set(include_dirs "") set(ldfragments "linker.lf") + if(CONFIG_BT_CONTROLLER_ENABLED) + if(CONFIG_IDF_TARGET_ESP32) + list(APPEND srcs "controller/esp32/bt.c" + "controller/esp32/hli_api.c" + "controller/esp32/hli_vectors.S") - if(CONFIG_IDF_TARGET_ESP32) - list(APPEND srcs "controller/esp32/bt.c" - "controller/esp32/hli_api.c" - "controller/esp32/hli_vectors.S") + elseif(CONFIG_IDF_TARGET_ESP32C3) + list(APPEND srcs "controller/esp32c3/bt.c") - elseif(CONFIG_IDF_TARGET_ESP32C3) - list(APPEND srcs "controller/esp32c3/bt.c") + elseif(CONFIG_IDF_TARGET_ESP32S3) + list(APPEND srcs "controller/esp32c3/bt.c") - elseif(CONFIG_IDF_TARGET_ESP32S3) - list(APPEND srcs "controller/esp32c3/bt.c") + elseif(CONFIG_IDF_TARGET_ESP32C2) + list(APPEND srcs "controller/esp32c2/bt.c") - elseif(CONFIG_IDF_TARGET_ESP32C2) - set(ldfragments "linker.lf.esp32c2") - list(APPEND srcs "controller/esp32c2/bt.c") + elseif(CONFIG_IDF_TARGET_ESP32C2) + set(ldfragments "linker.lf.esp32c2") + list(APPEND srcs "controller/esp32c2/bt.c") - elseif(CONFIG_IDF_TARGET_ESP32C6) - list(APPEND srcs "controller/esp32c6/bt.c") + elseif(CONFIG_IDF_TARGET_ESP32C6) + list(APPEND srcs "controller/esp32c6/bt.c") - elseif(CONFIG_IDF_TARGET_ESP32H2) - list(APPEND srcs "controller/esp32h2/bt.c") - endif() + elseif(CONFIG_IDF_TARGET_ESP32H2) + list(APPEND srcs "controller/esp32h2/bt.c") + endif() - list(APPEND include_dirs ${target_specific_include_dirs}) + list(APPEND include_dirs ${target_specific_include_dirs}) + + endif() # Common list(APPEND include_dirs common/osi/include) @@ -174,6 +179,7 @@ if(CONFIG_BT_ENABLED) list(APPEND srcs "host/bluedroid/api/esp_a2dp_api.c" "host/bluedroid/api/esp_avrc_api.c" + "host/bluedroid/api/esp_bluedroid_hci.c" "host/bluedroid/api/esp_bt_device.c" "host/bluedroid/api/esp_bt_main.c" "host/bluedroid/api/esp_gap_ble_api.c" diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 152ce7b38667..1781dc6f99f2 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -1,9 +1,8 @@ menu "Bluetooth" - visible if SOC_BT_SUPPORTED config BT_ENABLED bool "Bluetooth" - depends on SOC_BT_SUPPORTED && !APP_NO_BLOBS + depends on !APP_NO_BLOBS help Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices. @@ -22,10 +21,12 @@ menu "Bluetooth" config BT_NIMBLE_ENABLED bool "NimBLE - BLE only" + depends on BT_CONTROLLER_ENABLED help This option is recommended for BLE only usecases to save on memory config BT_CONTROLLER_ONLY + depends on SOC_BT_SUPPORTED bool "Disabled" help This option is recommended when you want to communicate directly with the @@ -42,6 +43,7 @@ menu "Bluetooth" This helps to choose Bluetooth controller stack config BT_CONTROLLER_ENABLED + depends on SOC_BT_SUPPORTED bool "Enabled" help This option is recommended for Bluetooth controller usecases diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index 9f6df2bdd4ba..738f4f2cd932 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,6 +29,12 @@ #define UC_BT_STACK_NO_LOG FALSE #endif +#ifdef CONFIG_BT_CONTROLLER_ENABLED +#define UC_BT_CONTROLLER_INCLUDED TRUE +#else +#define UC_BT_CONTROLLER_INCLUDED FALSE +#endif + /********************************************************** * Thread/Task reference **********************************************************/ diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 079080bf3af8..7005d52256c3 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -49,7 +49,7 @@ config BT_BLUEDROID_ESP_COEX_VSC config BT_CLASSIC_ENABLED bool "Classic Bluetooth" - depends on BT_BLUEDROID_ENABLED && IDF_TARGET_ESP32 + depends on BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BT_CLASSIC_SUPPORTED) || BT_CONTROLLER_DISABLED) default n help For now this option needs "SMP_ENABLE" to be set to yes @@ -1106,8 +1106,9 @@ config BT_MAX_DEVICE_NAME_LEN config BT_BLE_RPA_SUPPORTED bool "Update RPA to Controller" - depends on BT_BLUEDROID_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED - default n + depends on (BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) || BT_CONTROLLER_DISABLED)) + default n if (BT_CONTROLLER_ENABLED && !SOC_BLE_DEVICE_PRIVACY_SUPPORTED) + default y if BT_CONTROLLER_DISABLED help This enables controller RPA list function. For ESP32, ESP32 only support network privacy mode. If this option is enabled, ESP32 will only accept @@ -1131,28 +1132,28 @@ config BT_BLE_RPA_TIMEOUT config BT_BLE_50_FEATURES_SUPPORTED bool "Enable BLE 5.0 features" - depends on (BT_BLUEDROID_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER)) + depends on (BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BLE_50_SUPPORTED) || BT_CONTROLLER_DISABLED)) default y help This enables BLE 5.0 features, this option only support esp32c3/esp32s3 chip config BT_BLE_42_FEATURES_SUPPORTED bool "Enable BLE 4.2 features" - depends on (BT_BLUEDROID_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER)) + depends on (BT_BLUEDROID_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BLE_SUPPORTED) || BT_CONTROLLER_DISABLED)) default n help This enables BLE 4.2 features. config BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER bool "Enable BLE periodic advertising sync transfer feature" - depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && SOC_ESP_NIMBLE_CONTROLLER) + depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_ESP_NIMBLE_CONTROLLER) || BT_CONTROLLER_DISABLED)) default n help This enables BLE periodic advertising sync transfer feature config BT_BLE_FEAT_PERIODIC_ADV_ENH bool "Enable periodic adv enhancements(adi support)" - depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && SOC_ESP_NIMBLE_CONTROLLER) + depends on (BT_BLUEDROID_ENABLED && BT_BLE_50_FEATURES_SUPPORTED && ((BT_CONTROLLER_ENABLED && SOC_ESP_NIMBLE_CONTROLLER) || BT_CONTROLLER_DISABLED)) default n help Enable the periodic advertising enhancements diff --git a/components/bt/host/bluedroid/api/esp_bluedroid_hci.c b/components/bt/host/bluedroid/api/esp_bluedroid_hci.c new file mode 100644 index 000000000000..892f6790d602 --- /dev/null +++ b/components/bt/host/bluedroid/api/esp_bluedroid_hci.c @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "esp_log.h" +#include "esp_bluedroid_hci.h" +#include "common/bt_target.h" +#include "hci/hci_trans_int.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) +#include "esp_bt.h" +#endif + +#define LOG_TAG "HCI_API" + +static esp_bluedroid_hci_driver_operations_t s_hci_driver_ops = { 0 }; + +esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *p_ops) +{ + if (!p_ops) { + ESP_LOGE(LOG_TAG, "%s invalid function parameter", __func__); + return ESP_FAIL; + } + + s_hci_driver_ops.send = p_ops->send; + s_hci_driver_ops.check_send_available = p_ops->check_send_available; + s_hci_driver_ops.register_host_callback = p_ops->register_host_callback; + + return ESP_OK; +} + +esp_err_t esp_bluedroid_detach_hci_driver(void) +{ + s_hci_driver_ops.send = NULL; + s_hci_driver_ops.check_send_available = NULL; + s_hci_driver_ops.register_host_callback = NULL; + + return ESP_OK; +} + +/**************************************************************** + * INTERNAL USE * + ****************************************************************/ + +bool hci_host_check_send_available(void) +{ + bool can_send = false; +#if (BT_CONTROLLER_INCLUDED == TRUE) + can_send = esp_vhci_host_check_send_available(); +#else /* BT_CONTROLLER_INCLUDED == TRUE */ + if (s_hci_driver_ops.check_send_available) { + can_send = s_hci_driver_ops.check_send_available(); + } +#endif /* BT_CONTROLLER_INCLUDED == TRUE */ + return can_send; +} + +void hci_host_send_packet(uint8_t *data, uint16_t len) +{ +#if (BT_CONTROLLER_INCLUDED == TRUE) + esp_vhci_host_send_packet(data, len); +#else /* BT_CONTROLLER_INCLUDED == TRUE */ + if (s_hci_driver_ops.send) { + s_hci_driver_ops.send(data, len); + } +#endif /* BT_CONTROLLER_INCLUDED == TRUE */ +} + +esp_err_t hci_host_register_callback(const esp_bluedroid_hci_driver_callbacks_t *callback) +{ + esp_err_t ret = ESP_FAIL; + + if (!callback) { + ESP_LOGE(LOG_TAG, "%s invalid function parameter", __func__); + return ESP_FAIL; + } + +#if (BT_CONTROLLER_INCLUDED == TRUE) + ret = esp_vhci_host_register_callback((esp_vhci_host_callback_t *)callback); +#else /* BT_CONTROLLER_INCLUDED == TRUE */ + if (s_hci_driver_ops.register_host_callback) { + ret = s_hci_driver_ops.register_host_callback(callback); + } +#endif /* BT_CONTROLLER_INCLUDED == TRUE */ + + return ret; +} diff --git a/components/bt/host/bluedroid/api/esp_bt_main.c b/components/bt/host/bluedroid/api/esp_bt_main.c index d4b93fbb33c1..497ba769b65d 100644 --- a/components/bt/host/bluedroid/api/esp_bt_main.c +++ b/components/bt/host/bluedroid/api/esp_bt_main.c @@ -5,10 +5,13 @@ */ +#include "common/bt_target.h" #include "esp_bt_main.h" #include "btc/btc_task.h" #include "btc/btc_main.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #include "osi/future.h" #include "osi/allocator.h" #include "config/stack_config.h" @@ -123,10 +126,12 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg) return ESP_ERR_INVALID_ARG; } +#if (BT_CONTROLLER_INCLUDED == TRUE) if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { LOG_ERROR("Controller not initialised\n"); return ESP_ERR_INVALID_STATE; } +#endif if (bd_already_init) { LOG_ERROR("Bluedroid already initialised\n"); diff --git a/components/bt/host/bluedroid/api/esp_hf_ag_api.c b/components/bt/host/bluedroid/api/esp_hf_ag_api.c index 42878a4c7ab9..3098cd471619 100644 --- a/components/bt/host/bluedroid/api/esp_hf_ag_api.c +++ b/components/bt/host/bluedroid/api/esp_hf_ag_api.c @@ -21,7 +21,9 @@ #include "common/bt_target.h" #include "common/bt_defs.h" #include "device/bdaddr.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #include "esp_hf_ag_api.h" #include "esp_err.h" #include "esp_bt_main.h" diff --git a/components/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h b/components/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h new file mode 100644 index 000000000000..0004072c667d --- /dev/null +++ b/components/bt/host/bluedroid/api/include/api/esp_bluedroid_hci.h @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_BLUEDROID_HCI_H__ +#define __ESP_BLUEDROID_HCI_H__ + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* HCI driver callbacks */ +typedef struct esp_bluedroid_hci_driver_callbacks { + /** + * @brief callback used to notify that the host can send packet to controller + */ + void (*notify_host_send_available)(void); + + /** + * @brief callback used to notify that the controller has a packet to send to the host + * + * @param[in] data pointer to data buffer + * @param[in] len length of data + * + * @return 0 received successfully, failed otherwise + */ + int (*notify_host_recv)(uint8_t *data, uint16_t len); +} esp_bluedroid_hci_driver_callbacks_t; + +/* HCI driver operations */ +typedef struct esp_bluedroid_hci_driver_operations { + /** + * @brief send data from host to controller + * + * @param[in] data pointer to data buffer + * @param[in] len length of data + */ + void (*send)(uint8_t *data, uint16_t len); + + /** + * @brief host checks whether it can send data to controller + * + * @return true if host can send data, false otherwise + */ + bool (*check_send_available)(void); + + /** + * @brief register host callback + * + * @param[in] callback HCI driver callbacks + */ + esp_err_t (* register_host_callback)(const esp_bluedroid_hci_driver_callbacks_t *callback); +} esp_bluedroid_hci_driver_operations_t; + +/** + * @brief get the operations of HCI transport layer. This API should only be used in + * Bluedroid Host-only mode before Bluedroid initialization. + * + * @param[in] ops struct containing operations of HCI transport layer + * + * @return ESP_OK if get successfully, ESP_FAIL otherwise + */ +esp_err_t esp_bluedroid_attach_hci_driver(const esp_bluedroid_hci_driver_operations_t *ops); + +/** + * @brief remove the operations of HCI transport layer. This API should only be used in + * Bluedroid Host-only mode before Bluedroid initialization. + * + * @param[in] ops struct containing operations of HCI transport layer + * + * @return ESP_OK if get successfully, ESP_FAIL otherwise + */ +esp_err_t esp_bluedroid_detach_hci_driver(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_BLUEDROID_HCI_H__ */ diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 82fa8ff0fe6d..60865a1bc8c2 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -46,6 +46,9 @@ #if (GAP_INCLUDED == TRUE) #include "stack/gap_api.h" #endif +#if (BT_CONTROLLER_INCLUDED == TRUE) +#include "esp_bt.h" +#endif static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir); static void bta_dm_inq_cmpl_cb (void *p_result); @@ -136,7 +139,6 @@ static void bta_dm_observe_discard_cb (uint32_t num_dis); static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle); extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8 *p_uuid128); static void bta_dm_disable_timer_cback(TIMER_LIST_ENT *p_tle); -extern int bredr_txpwr_get(int *min_power_level, int *max_power_level); const UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID] = { UUID_SERVCLASS_PNP_INFORMATION, /* Reserved */ @@ -4313,7 +4315,14 @@ static void bta_dm_set_eir (char *local_name) if (p_bta_dm_eir_cfg->bta_dm_eir_included_tx_power) { if (free_eir_length >= 3) { int min_power_level, max_power_level; - if (bredr_txpwr_get(&min_power_level, &max_power_level) == 0) { +#if (BT_CONTROLLER_INCLUDED == TRUE) + if (esp_bredr_tx_power_get((esp_power_level_t *)&min_power_level, (esp_power_level_t *)&max_power_level) == ESP_OK) { +#else + { + min_power_level = 0; + max_power_level = 0; + UNUSED(min_power_level); +#endif INT8 btm_tx_power[BTM_TX_POWER_LEVEL_MAX + 1] = BTM_TX_POWER; p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power = btm_tx_power[max_power_level]; UINT8_TO_STREAM(p, 2); /* Length field */ diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 4364f3802696..a723ed06f686 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -9,6 +9,7 @@ #include "osi/allocator.h" #include "stack/bt_types.h" #include "common/bt_defs.h" +#include "common/bt_target.h" #include "bta/bta_api.h" #include "bta/bta_dm_co.h" #include "btc/btc_task.h" @@ -23,7 +24,9 @@ #include "osi/mutex.h" #include "osi/thread.h" #include "osi/pkt_queue.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #if (BLE_INCLUDED == TRUE) #if (BLE_42_FEATURE_SUPPORT == TRUE) @@ -187,7 +190,11 @@ static void btc_to_bta_adv_data(esp_ble_adv_data_t *p_adv_data, tBTA_BLE_ADV_DAT if (p_adv_data->include_txpower) { mask |= BTM_BLE_AD_BIT_TX_PWR; +#if (BT_CONTROLLER_INCLUDED == TRUE) bta_adv_data->tx_power = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_ADV); +#else + bta_adv_data->tx_power = 0; +#endif } if (p_adv_data->min_interval > 0 && p_adv_data->max_interval > 0 && diff --git a/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c b/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c index 8ababa1c6fc4..d04ec79f5c1a 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c +++ b/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c @@ -29,7 +29,9 @@ #include "common/bt_trace.h" #include "common/bt_defs.h" #include "device/bdaddr.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #include "esp_hf_ag_api.h" #include "osi/allocator.h" @@ -328,12 +330,14 @@ bt_status_t btc_hf_init(void) // custom initialization here hf_local_param[idx].btc_hf_cb.initialized = true; // set audio path +#if (BT_CONTROLLER_INCLUDED == TRUE) #if BTM_SCO_HCI_INCLUDED uint8_t data_path = ESP_SCO_DATA_PATH_HCI; #else uint8_t data_path = ESP_SCO_DATA_PATH_PCM; #endif esp_bredr_sco_datapath_set(data_path); +#endif return BT_STATUS_SUCCESS; } diff --git a/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c b/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c index 3909a4c6f6b1..67973bc267ae 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c +++ b/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c @@ -25,7 +25,9 @@ #include "btc/btc_util.h" #include "esp_hf_client_api.h" #include "bta/bta_hf_client_api.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #include #if BT_HF_CLIENT_BQB_INCLUDED @@ -167,19 +169,20 @@ bt_status_t btc_hf_client_init(void) { BTC_TRACE_EVENT("%s", __FUNCTION__); - uint8_t data_path; btc_dm_enable_service(BTA_HFP_HS_SERVICE_ID); clear_state(); hf_client_local_param.btc_hf_client_cb.initialized = true; +#if (BT_CONTROLLER_INCLUDED == TRUE) #if BTM_SCO_HCI_INCLUDED - data_path = ESP_SCO_DATA_PATH_HCI; + uint8_t data_path = ESP_SCO_DATA_PATH_HCI; #else - data_path = ESP_SCO_DATA_PATH_PCM; + uint8_t data_path = ESP_SCO_DATA_PATH_PCM; #endif esp_bredr_sco_datapath_set(data_path); +#endif return BT_STATUS_SUCCESS; } 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 82b3bf5bd02e..ba35cf8fdd55 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 @@ -105,7 +105,7 @@ #ifdef CONFIG_BT_BLE_RPA_SUPPORTED #define UC_BT_BLE_RPA_SUPPORTED CONFIG_BT_BLE_RPA_SUPPORTED #else -#if SOC_BLE_DEVICE_PRIVACY_SUPPORTED +#if (CONFIG_BT_CONTROLLER_ENABLED && SOC_BLE_DEVICE_PRIVACY_SUPPORTED) #define UC_BT_BLE_RPA_SUPPORTED TRUE #else #define UC_BT_BLE_RPA_SUPPORTED FALSE 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 4c3c5ef37cb7..7fecc9a78536 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -51,6 +51,12 @@ #define ESP_COEX_VSC_INCLUDED FALSE #endif +#if (UC_BT_CONTROLLER_INCLUDED == TRUE) +#define BT_CONTROLLER_INCLUDED TRUE +#else +#define BT_CONTROLLER_INCLUDED FALSE +#endif + /****************************************************************************** ** ** Classic BT features diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index 7a1377f6115f..121a4d510165 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -22,16 +22,20 @@ #include "hci/hci_hal.h" #include "hci/hci_internals.h" #include "hci/hci_layer.h" +#include "hci/hci_trans_int.h" #include "osi/thread.h" #include "osi/pkt_queue.h" #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) #include "osi/mutex.h" #include "osi/alarm.h" #endif +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif +#include "esp_bluedroid_hci.h" #include "stack/hcimsgs.h" -#if SOC_ESP_NIMBLE_CONTROLLER +#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) #include "nimble/ble_hci_trans.h" #endif @@ -87,7 +91,7 @@ typedef struct { static hci_hal_env_t hci_hal_env; static const hci_hal_t interface; -static const esp_vhci_host_callback_t vhci_host_cb; +static const esp_bluedroid_hci_driver_callbacks_t hci_host_cb; static void host_send_pkt_available_cb(void); static int host_recv_pkt_cb(uint8_t *data, uint16_t len); @@ -167,7 +171,7 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks, void *task_thre hci_hal_env_init(upper_callbacks, (osi_thread_t *)task_thread); //register vhci host cb - if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) { + if (hci_host_register_callback(&hci_host_cb) != ESP_OK) { return false; } @@ -207,7 +211,7 @@ static uint16_t transmit_data(serial_data_type_t type, BTTRC_DUMP_BUFFER("Transmit Pkt", data, length); // TX Data to target - esp_vhci_host_send_packet(data, length); + hci_host_send_packet(data, length); // Be nice and restore the old value of that byte *(data) = previous_byte; @@ -590,7 +594,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) return 0; } -#if SOC_ESP_NIMBLE_CONTROLLER +#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) int ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg) @@ -625,7 +629,7 @@ ble_hs_rx_data(struct os_mbuf *om, void *arg) } #endif -static const esp_vhci_host_callback_t vhci_host_cb = { +static const esp_bluedroid_hci_driver_callbacks_t hci_host_cb = { .notify_host_send_available = host_send_pkt_available_cb, .notify_host_recv = host_recv_pkt_cb, }; diff --git a/components/bt/host/bluedroid/hci/hci_layer.c b/components/bt/host/bluedroid/hci/hci_layer.c index b5c1bab66a94..56ab8877dc56 100644 --- a/components/bt/host/bluedroid/hci/hci_layer.c +++ b/components/bt/host/bluedroid/hci/hci_layer.c @@ -17,7 +17,10 @@ ******************************************************************************/ #include #include "sdkconfig.h" +#include "common/bt_target.h" +#if (BT_CONTROLLER_INCLUDED == TRUE) #include "esp_bt.h" +#endif #include "common/bt_defs.h" #include "common/bt_trace.h" @@ -28,6 +31,7 @@ #include "hci/hci_internals.h" #include "hci/hci_hal.h" #include "hci/hci_layer.h" +#include "hci/hci_trans_int.h" #include "osi/allocator.h" #include "hci/packet_fragmenter.h" #include "osi/list.h" @@ -226,7 +230,7 @@ static void hci_downstream_data_handler(void *arg) * All packets will be directly copied to single queue in driver layer with * H4 type header added (1 byte). */ - while (esp_vhci_host_check_send_available()) { + while (hci_host_check_send_available()) { /*Now Target only allowed one packet per TX*/ BT_HDR *pkt = packet_fragmenter->fragment_current_packet(); if (pkt != NULL) { diff --git a/components/bt/host/bluedroid/hci/include/hci/hci_hal.h b/components/bt/host/bluedroid/hci/include/hci/hci_hal.h index 9ed0692ef0f3..fe5796db3230 100644 --- a/components/bt/host/bluedroid/hci/include/hci/hci_hal.h +++ b/components/bt/host/bluedroid/hci/include/hci/hci_hal.h @@ -21,9 +21,10 @@ #include #include +#include "common/bt_target.h" #include "osi/pkt_queue.h" #include "stack/bt_types.h" -#if SOC_ESP_NIMBLE_CONTROLLER +#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) #include "os/os_mbuf.h" #endif typedef enum { @@ -85,7 +86,7 @@ typedef struct hci_hal_t { // Gets the correct hal implementation, as compiled for. const hci_hal_t *hci_hal_h4_get_interface(void); -#if SOC_ESP_NIMBLE_CONTROLLER +#if ((BT_CONTROLLER_INCLUDED == TRUE) && SOC_ESP_NIMBLE_CONTROLLER) int ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg); int ble_hs_rx_data(struct os_mbuf *om, void *arg); diff --git a/components/bt/host/bluedroid/hci/include/hci/hci_trans_int.h b/components/bt/host/bluedroid/hci/include/hci/hci_trans_int.h new file mode 100644 index 000000000000..86d74bd4bf16 --- /dev/null +++ b/components/bt/host/bluedroid/hci/include/hci/hci_trans_int.h @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __HCI_TRANS_INT_H__ +#define __HCI_TRANS_INT_H__ + +#include +#include +#include "esp_err.h" +#include "esp_bluedroid_hci.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief host checks whether it can send data to controller + * + * @return true if host can send data, false otherwise + */ +bool hci_host_check_send_available(void); + +/** + * @brief host sends packet to controller + * + * @param[in] data pointer to data buffer + * @param[in] len length of data in byte + */ +void hci_host_send_packet(uint8_t *data, uint16_t len); + +/** + * @brief register the HCI function interface + * + * @param[in] callback HCI function interface + * + * @return ESP_OK register successfully, ESP_FAIL otherwise + */ +esp_err_t hci_host_register_callback(const esp_bluedroid_hci_driver_callbacks_t *callback); + +#ifdef __cplusplus +} +#endif + +#endif /* __HCI_TRANS_INT_H__ */ diff --git a/components/bt/test_apps/main/test_smp.c b/components/bt/test_apps/main/test_smp.c index 4eefbe12f4bf..ea89ec261b42 100644 --- a/components/bt/test_apps/main/test_smp.c +++ b/components/bt/test_apps/main/test_smp.c @@ -15,7 +15,6 @@ #include "unity.h" #include "esp_random.h" -#include "esp_bt.h" #include "esp_bt_main.h" #include "esp_bt_device.h" #include "esp_gap_ble_api.h" diff --git a/components/esp_hid/src/ble_hidd.c b/components/esp_hid/src/ble_hidd.c index e0c22adb857d..a70e47a31789 100644 --- a/components/esp_hid/src/ble_hidd.c +++ b/components/esp_hid/src/ble_hidd.c @@ -12,7 +12,6 @@ #include "esp_hidd_private.h" #include "esp_log.h" -#include "esp_bt.h" #include "esp_bt_main.h" #include "esp_bt_defs.h" #include "esp_gatts_api.h" diff --git a/components/esp_hid/src/ble_hidh.c b/components/esp_hid/src/ble_hidh.c index 99b7f44b3b36..8df54c2fc99f 100644 --- a/components/esp_hid/src/ble_hidh.c +++ b/components/esp_hid/src/ble_hidh.c @@ -11,7 +11,6 @@ #include "esp_err.h" #include "esp_log.h" -#include "esp_bt.h" #include "esp_bt_defs.h" #include "esp_bt_main.h" #include "esp_gattc_api.h" diff --git a/components/esp_hid/src/bt_hidd.c b/components/esp_hid/src/bt_hidd.c index ab3d34605335..08e7209a3611 100644 --- a/components/esp_hid/src/bt_hidd.c +++ b/components/esp_hid/src/bt_hidd.c @@ -6,7 +6,6 @@ #include "bt_hidd.h" #if CONFIG_BT_HID_DEVICE_ENABLED -#include "esp_bt.h" #include "esp_bt_defs.h" #include "esp_bt_main.h" #include "esp_hidd.h" diff --git a/components/protocomm/src/simple_ble/simple_ble.c b/components/protocomm/src/simple_ble/simple_ble.c index 426fcc2dce50..a4184b52624d 100644 --- a/components/protocomm/src/simple_ble/simple_ble.c +++ b/components/protocomm/src/simple_ble/simple_ble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,7 +8,9 @@ #include #include #include +#ifdef CONFIG_BT_CONTROLLER_ENABLED #include "esp_bt.h" +#endif #include #include #include @@ -213,6 +215,7 @@ esp_err_t simple_ble_start(simple_ble_cfg_t *cfg) ESP_LOGD(TAG, "Free mem at start of simple_ble_init %" PRIu32, esp_get_free_heap_size()); esp_err_t ret; +#ifdef CONFIG_BT_CONTROLLER_ENABLED esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ret = esp_bt_controller_init(&bt_cfg); if (ret) { @@ -232,6 +235,7 @@ esp_err_t simple_ble_start(simple_ble_cfg_t *cfg) ESP_LOGE(TAG, "%s enable controller failed %d", __func__, ret); return ret; } +#endif esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); ret = esp_bluedroid_init_with_cfg(&bluedroid_cfg); @@ -307,6 +311,7 @@ esp_err_t simple_ble_stop(void) return err; } ESP_LOGD(TAG, "esp_bluedroid_deinit called successfully"); +#ifdef CONFIG_BT_CONTROLLER_ENABLED err = esp_bt_controller_disable(); if (err != ESP_OK) { return ESP_FAIL; @@ -321,7 +326,7 @@ esp_err_t simple_ble_stop(void) return ESP_FAIL; } ESP_LOGD(TAG, "esp_bt_controller_deinit called successfully"); - +#endif ESP_LOGD(TAG, "Free mem at end of simple_ble_stop %" PRIu32, esp_get_free_heap_size()); return ESP_OK; } diff --git a/components/soc/esp32p4/include/soc/soc.h b/components/soc/esp32p4/include/soc/soc.h index 735a0b7a59fb..7bbcd0618b25 100644 --- a/components/soc/esp32p4/include/soc/soc.h +++ b/components/soc/esp32p4/include/soc/soc.h @@ -142,6 +142,7 @@ #define CPU_CLK_FREQ_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration #define CPU_CLK_FREQ APB_CLK_FREQ #define APB_CLK_FREQ ( 40*1000000 ) +#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) #define XTAL_CLK_FREQ (40*1000000) #define GPIO_MATRIX_DELAY_NS 0 diff --git a/components/wifi_provisioning/src/scheme_ble.c b/components/wifi_provisioning/src/scheme_ble.c index 88e1724e08c8..6b594f22c46a 100644 --- a/components/wifi_provisioning/src/scheme_ble.c +++ b/components/wifi_provisioning/src/scheme_ble.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,7 +7,9 @@ #include #include #include +#ifdef CONFIG_BT_CONTROLLER_ENABLED #include "esp_bt.h" +#endif #include #include @@ -197,9 +199,10 @@ static esp_err_t set_config_endpoint(void *config, const char *endpoint_name, ui /* Used when both BT and BLE are not needed by application */ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event_t event, void *event_data) { - esp_err_t err; switch (event) { case WIFI_PROV_INIT: +#ifdef CONFIG_BT_CONTROLLER_ENABLED + esp_err_t err; /* Release BT memory, as we need only BLE */ err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT); if (err != ESP_OK) { @@ -207,10 +210,12 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event } else { ESP_LOGI(TAG, "BT memory released"); } +#endif break; case WIFI_PROV_DEINIT: #ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV +#ifdef CONFIG_BT_CONTROLLER_ENABLED /* Release memory used by BLE and Bluedroid host stack */ err = esp_bt_mem_release(ESP_BT_MODE_BTDM); if (err != ESP_OK) { @@ -218,6 +223,7 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event } else { ESP_LOGI(TAG, "BTDM memory released"); } +#endif #endif break; @@ -229,9 +235,10 @@ void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event /* Used when BT is not needed by application */ void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t event, void *event_data) { - esp_err_t err; switch (event) { case WIFI_PROV_INIT: +#ifdef CONFIG_BT_CONTROLLER_ENABLED + esp_err_t err; /* Release BT memory, as we need only BLE */ err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT); if (err != ESP_OK) { @@ -239,6 +246,7 @@ void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t } else { ESP_LOGI(TAG, "BT memory released"); } +#endif break; default: @@ -249,10 +257,11 @@ void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t /* Used when BLE is not needed by application */ void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_t event, void *event_data) { - esp_err_t err; switch (event) { case WIFI_PROV_DEINIT: #ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV +#ifdef CONFIG_BT_CONTROLLER_ENABLED + esp_err_t err; /* Release memory used by BLE stack */ err = esp_bt_mem_release(ESP_BT_MODE_BLE); if (err != ESP_OK) { @@ -260,6 +269,7 @@ void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_ } else { ESP_LOGI(TAG, "BLE memory released"); } +#endif #endif break; diff --git a/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c b/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c index 52b70bff0e9f..6cdb88455123 100644 --- a/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c +++ b/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c @@ -272,7 +272,7 @@ void app_main(void) #endif // CONFIG_BT_ENABLED #endif // CONFIG_EXAMPLE_CONNECT_WIFI -#if CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED +#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED) ESP_ERROR_CHECK(esp_ble_helper_init()); #endif diff --git a/examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c b/examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c index 02b0375f8461..701a6c7768aa 100644 --- a/examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c +++ b/examples/system/ota/advanced_https_ota/main/ble_helper/ble_api.c @@ -6,7 +6,7 @@ #include "sdkconfig.h" -#if CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED +#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED) #include "ble_api.h" #include "esp_log.h" 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 c6c6482bcc22..ac4bdfa91cf9 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 @@ -9,7 +9,7 @@ #include "esp_log.h" #include "string.h" -#if CONFIG_BT_BLE_ENABLED +#if CONFIG_BT_CONTROLLER_ENABLED && CONFIG_BT_BLE_ENABLED static const char *TAG = "bluedroid_gatts"; static prepare_type_env_t a_prepare_write_env; diff --git a/examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h b/examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h index 740355c1e268..2dc59f4c86fe 100644 --- a/examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h +++ b/examples/system/ota/advanced_https_ota/main/ble_helper/include/ble_api.h @@ -12,7 +12,7 @@ extern "C" { #endif -#if CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED +#if CONFIG_BT_CONTROLLER_ENABLED && (CONFIG_BT_BLE_ENABLED || CONFIG_BT_NIMBLE_ENABLED) esp_err_t esp_ble_helper_init(void); #endif diff --git a/examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h b/examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h index b685a3d03125..2ebbcc8b587c 100644 --- a/examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h +++ b/examples/system/ota/advanced_https_ota/main/ble_helper/include/bluedroid_gatts.h @@ -9,7 +9,7 @@ #include "sdkconfig.h" -#if CONFIG_BT_BLE_ENABLED +#if CONFIG_BT_CONTROLLER_ENABLED && CONFIG_BT_BLE_ENABLED #ifdef __cplusplus extern "C" { From b319143e3b0121263bb2452cd83b6d2894fd8db6 Mon Sep 17 00:00:00 2001 From: Jin Cheng Date: Wed, 6 Sep 2023 14:51:48 +0800 Subject: [PATCH 085/161] feat(bt/bluedroid): Added bt_discovery based host only example --- .../bluedroid_host_only_uart/CMakeLists.txt | 6 + .../bluedroid_host_only_uart/README.md | 85 +++++ .../main/CMakeLists.txt | 3 + .../main/Kconfig.projbuild | 8 + .../bluedroid_host_only_uart/main/main.c | 306 ++++++++++++++++++ .../main/uart_driver.c | 165 ++++++++++ .../main/uart_driver.h | 46 +++ .../sdkconfig.defaults | 4 + 8 files changed, 623 insertions(+) create mode 100644 examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/README.md create mode 100644 examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/CMakeLists.txt create mode 100644 examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/Kconfig.projbuild create mode 100644 examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/main.c create mode 100644 examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.c create mode 100644 examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.h create mode 100644 examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/sdkconfig.defaults diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/CMakeLists.txt b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/CMakeLists.txt new file mode 100644 index 000000000000..632ea6ca8e06 --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/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(host_hci_uart) diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/README.md b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/README.md new file mode 100644 index 000000000000..bbc884518dc3 --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/README.md @@ -0,0 +1,85 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +ESP-IDF UART HCI Host +===================== + +This is a Bluetooth Host use UART as HCI IO. This require the UART device support RTS/CTS mandatory. + +It can do the configuration of UART baudrate by menuconfig. + +## Example Layout + +This example is modified based on [bt_discovery](../../classic_bt/bt_discovery), and all modifications are listed below: + +- Removed all dependencies on controller from `main.c`. + +``` +#include "esp_bt.h" + +... + +ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_BLE)); + +esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); +if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s initialize controller failed: %s", __func__, esp_err_to_name(ret)); + return; +} + +if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s enable controller failed: %s", __func__, esp_err_to_name(ret)); + return; +} +``` + +- Add support for uart driver: `uart_driver.c` and `uart_driver.h`. + +- Initialize UART driver in `main.c`. + +``` +#include "esp_hci_api.h" +#include "uart_driver.h" + +... + +/* initialize HCI TRANSPORT first */ +hci_uart_open(); +/* get HCI driver operations */ +esp_bluedroid_hci_driver_operations_t operations = { + .send = hci_uart_send, + .check_send_available = hci_check_send_available, + .register_host_callback = hci_register_host_callback, +}; +esp_bluedroid_attach_hci_driver(&operations); +``` + +## How to use example + +### Hardware Required + +This example should be able to run on any commonly available ESP development board. To connect UART to another board running a Bluetooth controller. For example, [controller_hci_uart_esp32](../../../hci/controller_hci_uart_esp32). + +### Configure the project + +``` +idf.py menuconfig +``` + +- UART baudrate can be configured in `Example Configuration > UART Baudrate for HCI` + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(Replace PORT with the name of the serial port to use.) + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Troubleshooting diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/CMakeLists.txt b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/CMakeLists.txt new file mode 100644 index 000000000000..7661c7c45ebd --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "main.c" + "uart_driver.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/Kconfig.projbuild b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/Kconfig.projbuild new file mode 100644 index 000000000000..5089dc503ceb --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/Kconfig.projbuild @@ -0,0 +1,8 @@ +menu "Example Configuration" + config EXAMPLE_HCI_UART_BAUDRATE + int "UART Baudrate for HCI" + range 115200 921600 + default 921600 + help + UART Baudrate for HCI. Please use standard baudrate. +endmenu diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/main.c b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/main.c new file mode 100644 index 000000000000..7bab44ab66dd --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/main.c @@ -0,0 +1,306 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + + +/**************************************************************************** +* +* This file is for Classic Bluetooth device and service discovery Demo. +* +****************************************************************************/ + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_system.h" +#include "esp_log.h" +#include "esp_bt_main.h" +#include "esp_bt_device.h" +#include "esp_gap_bt_api.h" +#include "esp_bluedroid_hci.h" +#include "uart_driver.h" + +#define GAP_TAG "GAP" + +typedef enum { + APP_GAP_STATE_IDLE = 0, + APP_GAP_STATE_DEVICE_DISCOVERING, + APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE, + APP_GAP_STATE_SERVICE_DISCOVERING, + APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE, +} app_gap_state_t; + +typedef struct { + bool dev_found; + uint8_t bdname_len; + uint8_t eir_len; + uint8_t rssi; + uint32_t cod; + uint8_t eir[ESP_BT_GAP_EIR_DATA_LEN]; + uint8_t bdname[ESP_BT_GAP_MAX_BDNAME_LEN + 1]; + esp_bd_addr_t bda; + app_gap_state_t state; +} app_gap_cb_t; + +static app_gap_cb_t m_dev_info; + +static char *bda2str(esp_bd_addr_t bda, char *str, size_t size) +{ + if (bda == NULL || str == NULL || size < 18) { + return NULL; + } + + uint8_t *p = bda; + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + p[0], p[1], p[2], p[3], p[4], p[5]); + return str; +} + +static char *uuid2str(esp_bt_uuid_t *uuid, char *str, size_t size) +{ + if (uuid == NULL || str == NULL) { + return NULL; + } + + if (uuid->len == 2 && size >= 5) { + sprintf(str, "%04x", uuid->uuid.uuid16); + } else if (uuid->len == 4 && size >= 9) { + sprintf(str, "%08"PRIx32, uuid->uuid.uuid32); + } else if (uuid->len == 16 && size >= 37) { + uint8_t *p = uuid->uuid.uuid128; + sprintf(str, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + p[15], p[14], p[13], p[12], p[11], p[10], p[9], p[8], + p[7], p[6], p[5], p[4], p[3], p[2], p[1], p[0]); + } else { + return NULL; + } + + return str; +} + +static bool get_name_from_eir(uint8_t *eir, uint8_t *bdname, uint8_t *bdname_len) +{ + uint8_t *rmt_bdname = NULL; + uint8_t rmt_bdname_len = 0; + + if (!eir) { + return false; + } + + rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_CMPL_LOCAL_NAME, &rmt_bdname_len); + if (!rmt_bdname) { + rmt_bdname = esp_bt_gap_resolve_eir_data(eir, ESP_BT_EIR_TYPE_SHORT_LOCAL_NAME, &rmt_bdname_len); + } + + if (rmt_bdname) { + if (rmt_bdname_len > ESP_BT_GAP_MAX_BDNAME_LEN) { + rmt_bdname_len = ESP_BT_GAP_MAX_BDNAME_LEN; + } + + if (bdname) { + memcpy(bdname, rmt_bdname, rmt_bdname_len); + bdname[rmt_bdname_len] = '\0'; + } + if (bdname_len) { + *bdname_len = rmt_bdname_len; + } + return true; + } + + return false; +} + +static void update_device_info(esp_bt_gap_cb_param_t *param) +{ + char bda_str[18]; + uint32_t cod = 0; + int32_t rssi = -129; /* invalid value */ + uint8_t *bdname = NULL; + uint8_t bdname_len = 0; + uint8_t *eir = NULL; + uint8_t eir_len = 0; + esp_bt_gap_dev_prop_t *p; + + ESP_LOGI(GAP_TAG, "Device found: %s", bda2str(param->disc_res.bda, bda_str, 18)); + for (int i = 0; i < param->disc_res.num_prop; i++) { + p = param->disc_res.prop + i; + switch (p->type) { + case ESP_BT_GAP_DEV_PROP_COD: + cod = *(uint32_t *)(p->val); + ESP_LOGI(GAP_TAG, "--Class of Device: 0x%"PRIx32, cod); + break; + case ESP_BT_GAP_DEV_PROP_RSSI: + rssi = *(int8_t *)(p->val); + ESP_LOGI(GAP_TAG, "--RSSI: %"PRId32, rssi); + break; + case ESP_BT_GAP_DEV_PROP_BDNAME: + bdname_len = (p->len > ESP_BT_GAP_MAX_BDNAME_LEN) ? ESP_BT_GAP_MAX_BDNAME_LEN : + (uint8_t)p->len; + bdname = (uint8_t *)(p->val); + break; + case ESP_BT_GAP_DEV_PROP_EIR: { + eir_len = p->len; + eir = (uint8_t *)(p->val); + break; + } + default: + break; + } + } + + /* search for device with Major device type "PHONE" or "Audio/Video" in COD */ + app_gap_cb_t *p_dev = &m_dev_info; + if (p_dev->dev_found) { + return; + } + + if (!esp_bt_gap_is_valid_cod(cod) || + (!(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_PHONE) && + !(esp_bt_gap_get_cod_major_dev(cod) == ESP_BT_COD_MAJOR_DEV_AV))) { + return; + } + + memcpy(p_dev->bda, param->disc_res.bda, ESP_BD_ADDR_LEN); + p_dev->dev_found = true; + + p_dev->cod = cod; + p_dev->rssi = rssi; + if (bdname_len > 0) { + memcpy(p_dev->bdname, bdname, bdname_len); + p_dev->bdname[bdname_len] = '\0'; + p_dev->bdname_len = bdname_len; + } + if (eir_len > 0) { + memcpy(p_dev->eir, eir, eir_len); + p_dev->eir_len = eir_len; + } + + if (p_dev->bdname_len == 0) { + get_name_from_eir(p_dev->eir, p_dev->bdname, &p_dev->bdname_len); + } + + ESP_LOGI(GAP_TAG, "Found a target device, address %s, name %s", bda_str, p_dev->bdname); + p_dev->state = APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE; + ESP_LOGI(GAP_TAG, "Cancel device discovery ..."); + esp_bt_gap_cancel_discovery(); +} + +static void bt_app_gap_init(void) +{ + app_gap_cb_t *p_dev = &m_dev_info; + memset(p_dev, 0, sizeof(app_gap_cb_t)); + + p_dev->state = APP_GAP_STATE_IDLE; +} + +static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) +{ + app_gap_cb_t *p_dev = &m_dev_info; + char bda_str[18]; + char uuid_str[37]; + + switch (event) { + case ESP_BT_GAP_DISC_RES_EVT: { + update_device_info(param); + break; + } + case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: { + if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) { + ESP_LOGI(GAP_TAG, "Device discovery stopped."); + if ( (p_dev->state == APP_GAP_STATE_DEVICE_DISCOVER_COMPLETE || + p_dev->state == APP_GAP_STATE_DEVICE_DISCOVERING) + && p_dev->dev_found) { + p_dev->state = APP_GAP_STATE_SERVICE_DISCOVERING; + ESP_LOGI(GAP_TAG, "Discover services ..."); + esp_bt_gap_get_remote_services(p_dev->bda); + } + } else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) { + ESP_LOGI(GAP_TAG, "Discovery started."); + } + break; + } + case ESP_BT_GAP_RMT_SRVCS_EVT: { + if (memcmp(param->rmt_srvcs.bda, p_dev->bda, ESP_BD_ADDR_LEN) == 0 && + p_dev->state == APP_GAP_STATE_SERVICE_DISCOVERING) { + p_dev->state = APP_GAP_STATE_SERVICE_DISCOVER_COMPLETE; + if (param->rmt_srvcs.stat == ESP_BT_STATUS_SUCCESS) { + ESP_LOGI(GAP_TAG, "Services for device %s found", bda2str(p_dev->bda, bda_str, 18)); + for (int i = 0; i < param->rmt_srvcs.num_uuids; i++) { + esp_bt_uuid_t *u = param->rmt_srvcs.uuid_list + i; + ESP_LOGI(GAP_TAG, "--%s", uuid2str(u, uuid_str, 37)); + } + } else { + ESP_LOGI(GAP_TAG, "Services for device %s not found", bda2str(p_dev->bda, bda_str, 18)); + } + } + break; + } + case ESP_BT_GAP_RMT_SRVC_REC_EVT: + default: { + ESP_LOGI(GAP_TAG, "event: %d", event); + break; + } + } + return; +} + +static void bt_app_gap_start_up(void) +{ + /* register GAP callback function */ + esp_bt_gap_register_callback(bt_app_gap_cb); + + char *dev_name = "ESP_GAP_INQRUIY"; + esp_bt_dev_set_device_name(dev_name); + + /* set discoverable and connectable mode, wait to be connected */ + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); + + /* inititialize device information and status */ + bt_app_gap_init(); + + /* start to discover nearby Bluetooth devices */ + app_gap_cb_t *p_dev = &m_dev_info; + p_dev->state = APP_GAP_STATE_DEVICE_DISCOVERING; + esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); +} + +void app_main(void) +{ + /* Initialize NVS — it is used to store PHY calibration data and save key-value pairs in flash memory*/ + 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()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK( ret ); + + /* initialize HCI TRANSPORT first */ + hci_uart_open(); + /* get HCI driver operations */ + esp_bluedroid_hci_driver_operations_t operations = { + .send = hci_uart_send, + .check_send_available = hci_check_send_available, + .register_host_callback = hci_register_host_callback, + }; + esp_bluedroid_attach_hci_driver(&operations); + + esp_bluedroid_config_t bluedroid_cfg = BT_BLUEDROID_INIT_CONFIG_DEFAULT(); + if ((ret = esp_bluedroid_init_with_cfg(&bluedroid_cfg)) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s initialize bluedroid failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + if ((ret = esp_bluedroid_enable()) != ESP_OK) { + ESP_LOGE(GAP_TAG, "%s enable bluedroid failed: %s", __func__, esp_err_to_name(ret)); + return; + } + + bt_app_gap_start_up(); +} diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.c b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.c new file mode 100644 index 000000000000..4ac100ec00b2 --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.c @@ -0,0 +1,165 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "driver/uart.h" +#include "esp_log.h" +#include "esp_attr.h" +#include "esp_bluedroid_hci.h" +#include "uart_driver.h" + +#define TAG "UART_HCI" + +#define UART_NO (1) +#define UART_BUF_SZ (1024) + +#define UART_TX_PIN (5) +#define UART_RX_PIN (18) +#define UART_RTS_PIN (19) +#define UART_CTS_PIN (23) + +enum { + UART_RX_TYPE = 0, + UART_RX_LEN, + UART_RX_DATA, +}; + +enum { + DATA_TYPE_COMMAND = 1, + DATA_TYPE_ACL = 2, + DATA_TYPE_SCO = 3, + DATA_TYPE_EVENT = 4 +}; + +TaskHandle_t s_rx_task_hdl; +esp_bluedroid_hci_driver_callbacks_t s_callback = { 0 }; + +static void IRAM_ATTR hci_uart_rx_task(void *arg) +{ + uint8_t buf[1026]; + int len_now_read = -1; + uint32_t len_to_read = 1; + uint32_t len_total_read = 0; + uint8_t rx_st = UART_RX_TYPE; + + while (1) { + len_now_read = uart_read_bytes(UART_NO, &buf[len_total_read], len_to_read, portMAX_DELAY); + assert(len_now_read == len_to_read); + len_total_read += len_now_read; + + switch (rx_st) { + case UART_RX_TYPE: { + assert(buf[0] >= DATA_TYPE_ACL && buf[0] <= DATA_TYPE_EVENT); + if (buf[0] == DATA_TYPE_ACL) { + len_to_read = 4; + } else if (buf[0] == DATA_TYPE_SCO) { + len_to_read = 3; + } else if (buf[0] == DATA_TYPE_EVENT) { + len_to_read = 2; + } else { + assert(0); + } + rx_st = UART_RX_LEN; + } + break; + + case UART_RX_LEN: { + if (buf[0] == DATA_TYPE_ACL) { + len_to_read = buf[3] | (buf[4] << 8); + } else if (buf[0] == DATA_TYPE_SCO) { + len_to_read = buf[3]; + } else if (buf[0] == DATA_TYPE_EVENT) { + len_to_read = buf[2]; + } else { + assert(0); + } + rx_st = UART_RX_DATA; + } + break; + + case UART_RX_DATA: { + if (s_callback.notify_host_recv) { + s_callback.notify_host_recv(buf, len_total_read); + } + + rx_st = UART_RX_TYPE; + len_to_read = 1; + len_total_read = 0; + } + break; + + default: { + assert(0); + break; + } + } + } + + vTaskDelete(NULL); +} + +void hci_uart_send(uint8_t *buf, uint16_t len) +{ + uint8_t *p = buf; + int len_write = 0; + + while (len) { + len_write = uart_write_bytes(UART_NO, p, len); + assert(len_write > 0); + len -= len_write; + p += len_write; + } +} + +bool hci_check_send_available(void) +{ + return true; +} + +esp_err_t hci_register_host_callback(const esp_bluedroid_hci_driver_callbacks_t *callback) +{ + s_callback.notify_host_send_available = callback->notify_host_send_available; + s_callback.notify_host_recv = callback->notify_host_recv; + + return ESP_OK; +} + +void hci_uart_open(void) +{ + uart_config_t uart_config = { + .baud_rate = CONFIG_EXAMPLE_HCI_UART_BAUDRATE, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, + .source_clk = UART_SCLK_DEFAULT, + .rx_flow_ctrl_thresh = UART_HW_FIFO_LEN(UART_NO) - 1, + }; + + int intr_alloc_flags = 0; +#if CONFIG_UART_ISR_IN_IRAM + intr_alloc_flags = ESP_INTR_FLAG_IRAM; +#endif + + ESP_ERROR_CHECK(uart_driver_install(UART_NO, UART_BUF_SZ * 2, UART_BUF_SZ * 2, 0, NULL, intr_alloc_flags)); + ESP_ERROR_CHECK(uart_param_config(UART_NO, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(UART_NO, UART_TX_PIN, UART_RX_PIN, UART_RTS_PIN, UART_CTS_PIN)); + + xTaskCreate(hci_uart_rx_task, "hci_uart_rx_task", 2048, NULL, 12, &s_rx_task_hdl); +} + +void hci_uart_close(void) +{ + if (s_rx_task_hdl) { + vTaskDelete(s_rx_task_hdl); + } + uart_driver_delete(UART_NO); + memset(&s_callback, 0, sizeof(esp_bluedroid_hci_driver_callbacks_t)); +} diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.h b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.h new file mode 100644 index 000000000000..077d93813436 --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/main/uart_driver.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#ifndef __UART_DRIVER_H__ +#define __UART_DRIVER_H__ + +#include +#include +#include "esp_bluedroid_hci.h" + +/** + * @brief open HCI transport of uart + */ +void hci_uart_open(void); + +/** + * @brief close HCI transport of uart + */ +void hci_uart_close(void); + +/** + * @brief send data from host to HCI transport + * + * @param[in] data pointer to data buffer + * @param[in] len length of data + */ +void hci_uart_send(uint8_t *data, uint16_t len); + +/** + * @brief host checks whether it can send data to HCI transport + * + * @return true if host can send data, false otherwise + */ +bool hci_check_send_available(void); + +/** + * @brief register host callbacks + * + * @param[in] callback HCI driver callbacks + */ +esp_err_t hci_register_host_callback(const esp_bluedroid_hci_driver_callbacks_t *callback); + +#endif /* __UART_DRIVER_H__ */ diff --git a/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/sdkconfig.defaults b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/sdkconfig.defaults new file mode 100644 index 000000000000..f23507d897e4 --- /dev/null +++ b/examples/bluetooth/bluedroid/bluedroid_host_only/bluedroid_host_only_uart/sdkconfig.defaults @@ -0,0 +1,4 @@ +CONFIG_BT_CONTROLLER_DISABLED=y +CONFIG_BT_ENABLED=y +CONFIG_BT_BLUEDROID_ENABLED=y +CONFIG_BT_CLASSIC_ENABLED=y From 0349f471af27aea234544e2cf3152d8d31bef66d Mon Sep 17 00:00:00 2001 From: "radim.karnis" Date: Tue, 10 Oct 2023 14:53:16 +0200 Subject: [PATCH 086/161] docs(idf-clang-tidy): Mention the need for a clang based toolchain Closes https://github.com/espressif/clang-tidy-runner/issues/32 --- docs/en/api-guides/tools/idf-clang-tidy.rst | 2 ++ docs/zh_CN/api-guides/tools/idf-clang-tidy.rst | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/en/api-guides/tools/idf-clang-tidy.rst b/docs/en/api-guides/tools/idf-clang-tidy.rst index 7d3e7a802d6f..dab019a6e12a 100644 --- a/docs/en/api-guides/tools/idf-clang-tidy.rst +++ b/docs/en/api-guides/tools/idf-clang-tidy.rst @@ -10,6 +10,8 @@ The IDF Clang Tidy is a tool that uses `clang-tidy ` IDF clang-tidy 的功能及其依赖的工具链尚在开发中,最终版本发布前可能有重大变更。 + 目前仅支持基于 clang 的工具链。在配置项目前,必须在环境变量或 CMake 缓存中设置 ``IDF_TOOLCHAIN=clang`` 进行激活。 + .. only:: CONFIG_IDF_TARGET_ARCH_RISCV .. warning:: From 7cd75c1075ed639288f56a6bcb994fd0590e1f33 Mon Sep 17 00:00:00 2001 From: wanlei Date: Fri, 1 Sep 2023 17:51:54 +0800 Subject: [PATCH 087/161] feat(spi_slave): add p4 hp spi slave driver support --- .../include/esp_private/spi_common_internal.h | 10 +- components/driver/spi/gpspi/spi_master.c | 12 +- components/driver/spi/gpspi/spi_slave.c | 291 ++++++++++++------ .../driver/spi/include/driver/spi_slave.h | 10 +- .../driver/test_apps/.build-test-rules.yml | 5 +- .../spi/master/main/test_spi_master.c | 15 +- .../driver/test_apps/spi/slave/README.md | 4 +- .../test_apps/spi/slave/main/test_app_main.c | 12 +- .../test_apps/spi/slave/main/test_spi_slave.c | 38 +-- .../spi/slave/main/test_spi_slave_queue.c | 11 +- components/hal/cache_hal.c | 2 +- components/hal/esp32/cache_hal_esp32.c | 2 +- components/hal/include/hal/spi_hal.h | 1 + components/hal/include/hal/spi_slave_hal.h | 12 +- components/hal/spi_slave_hal.c | 1 - components/hal/spi_slave_hal_iram.c | 48 ++- docs/docs_not_updated/esp32p4.txt | 1 - .../api-reference/peripherals/spi_slave.rst | 12 +- .../api-reference/peripherals/spi_slave.rst | 12 +- examples/peripherals/.build-test-rules.yml | 3 - examples/peripherals/spi_slave/README.md | 21 +- .../spi_slave/receiver/main/app_main.c | 53 +--- .../spi_slave/sender/main/app_main.c | 2 +- 23 files changed, 341 insertions(+), 237 deletions(-) diff --git a/components/driver/include/esp_private/spi_common_internal.h b/components/driver/include/esp_private/spi_common_internal.h index 4789182b73a2..92f4a0e8992f 100644 --- a/components/driver/include/esp_private/spi_common_internal.h +++ b/components/driver/include/esp_private/spi_common_internal.h @@ -13,6 +13,7 @@ #include "freertos/FreeRTOS.h" #include "hal/spi_types.h" #include "hal/dma_types.h" +#include "soc/gdma_channel.h" #include "esp_pm.h" #if SOC_GDMA_SUPPORTED #include "esp_private/gdma.h" @@ -46,19 +47,14 @@ extern "C" #define BUS_LOCK_DEBUG_EXECUTE_CHECK(x) #endif -#if !defined(SOC_GDMA_TRIG_PERIPH_SPI2_BUS) +#if SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB #define DMA_DESC_MEM_ALIGN_SIZE 4 +#define SPI_GDMA_NEW_CHANNEL gdma_new_ahb_channel typedef dma_descriptor_align4_t spi_dma_desc_t; #else -#if defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) #define DMA_DESC_MEM_ALIGN_SIZE 8 #define SPI_GDMA_NEW_CHANNEL gdma_new_axi_channel typedef dma_descriptor_align8_t spi_dma_desc_t; -#elif defined(SOC_GDMA_BUS_AHB) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) -#define DMA_DESC_MEM_ALIGN_SIZE 4 -#define SPI_GDMA_NEW_CHANNEL gdma_new_ahb_channel -typedef dma_descriptor_align4_t spi_dma_desc_t; -#endif #endif struct spi_bus_lock_t; diff --git a/components/driver/spi/gpspi/spi_master.c b/components/driver/spi/gpspi/spi_master.c index 9daa87bd2658..a0692ddfb090 100644 --- a/components/driver/spi/gpspi/spi_master.c +++ b/components/driver/spi/gpspi/spi_master.c @@ -887,15 +887,15 @@ static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_host_t *host, spi_trans uint32_t tx_byte_len = (trans_desc->length + 7) / 8; uint32_t rx_byte_len = (trans_desc->rxlength + 7) / 8; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - bool tx_un_align = ((((uint32_t)send_ptr) | tx_byte_len) & (alignment - 1)); - bool rx_un_align = ((((uint32_t)rcv_ptr) | rx_byte_len) & (alignment - 1)); + bool tx_unaligned = ((((uint32_t)send_ptr) | tx_byte_len) & (alignment - 1)); + bool rx_unaligned = ((((uint32_t)rcv_ptr) | rx_byte_len) & (alignment - 1)); #else - bool tx_un_align = false; //tx don't need align on addr or length, for other chips - bool rx_un_align = (((uint32_t)rcv_ptr) & (alignment - 1)); + bool tx_unaligned = false; //tx don't need align on addr or length, for other chips + bool rx_unaligned = (((uint32_t)rcv_ptr) & (alignment - 1)); #endif if (send_ptr && bus_attr->dma_enabled) { - if ((!esp_ptr_dma_capable(send_ptr) || tx_un_align )) { + if ((!esp_ptr_dma_capable(send_ptr) || tx_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 TX buffer addr&len not align to %d, or not dma_capable", alignment); //if txbuf in the desc not DMA-capable, or not bytes aligned to alignment, malloc a new one ESP_EARLY_LOGD(SPI_TAG, "Allocate TX buffer for DMA" ); @@ -914,7 +914,7 @@ 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_un_align )) { + 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" ); diff --git a/components/driver/spi/gpspi/spi_slave.c b/components/driver/spi/gpspi/spi_slave.c index af9ca699d921..1ab5299cb54c 100644 --- a/components/driver/spi/gpspi/spi_slave.c +++ b/components/driver/spi/gpspi/spi_slave.c @@ -12,6 +12,7 @@ #include "esp_log.h" #include "esp_err.h" #include "esp_pm.h" +#include "esp_cache.h" #include "esp_heap_caps.h" #include "esp_rom_sys.h" #include "soc/lldesc.h" @@ -29,7 +30,7 @@ #include "hal/spi_slave_hal.h" #include "esp_private/spi_slave_internal.h" #include "esp_private/spi_common_internal.h" - +#include "esp_private/esp_cache_private.h" static const char *SPI_TAG = "spi_slave"; @@ -48,13 +49,20 @@ static const char *SPI_TAG = "spi_slave"; #define SPI_SLAVE_ATTR #endif +/// struct to hold private transaction data (like tx and rx buffer for DMA). +typedef struct { + spi_slave_transaction_t *trans; //original trans + void *tx_buffer; //actually tx buffer (re-malloced if needed) + void *rx_buffer; //actually rx buffer (re-malloced if needed) +} spi_slave_trans_priv_t; + typedef struct { int id; spi_bus_config_t bus_config; spi_slave_interface_config_t cfg; intr_handle_t intr; spi_slave_hal_context_t hal; - spi_slave_transaction_t *cur_trans; + spi_slave_trans_priv_t cur_trans; uint32_t flags; uint32_t intr_flags; int max_transfer_sz; @@ -63,6 +71,7 @@ typedef struct { bool dma_enabled; bool cs_iomux; uint8_t cs_in_signal; + uint16_t internal_mem_align_size; uint32_t tx_dma_chan; uint32_t rx_dma_chan; #ifdef CONFIG_PM_ENABLE @@ -159,17 +168,37 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b memcpy(&spihost[host]->cfg, slave_config, sizeof(spi_slave_interface_config_t)); memcpy(&spihost[host]->bus_config, bus_config, sizeof(spi_bus_config_t)); spihost[host]->id = host; + spi_slave_hal_context_t *hal = &spihost[host]->hal; - bool use_dma = (dma_chan != SPI_DMA_DISABLED); - spihost[host]->dma_enabled = use_dma; - if (use_dma) { -#if CONFIG_IDF_TARGET_ESP32P4 - abort(); //will supported in IDF-7503 -#endif + spihost[host]->dma_enabled = (dma_chan != SPI_DMA_DISABLED); + if (spihost[host]->dma_enabled) { ret = spicommon_dma_chan_alloc(host, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan); if (ret != ESP_OK) { goto cleanup; } + spihost[host]->tx_dma_chan = actual_tx_dma_chan; + spihost[host]->rx_dma_chan = actual_rx_dma_chan; + + //See how many dma descriptors we need and allocate them + int dma_desc_ct = (bus_config->max_transfer_sz + SPI_MAX_DMA_LEN - 1) / SPI_MAX_DMA_LEN; + if (dma_desc_ct == 0) dma_desc_ct = 1; //default to 4k when max is not given + spihost[host]->max_transfer_sz = dma_desc_ct * SPI_MAX_DMA_LEN; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_DMA, (size_t *)&spihost[host]->internal_mem_align_size); +#else + spihost[host]->internal_mem_align_size = 4; +#endif + + hal->dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); + hal->dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); + if (!hal->dmadesc_tx || !hal->dmadesc_rx) { + ret = ESP_ERR_NO_MEM; + goto cleanup; + } + hal->dmadesc_n = dma_desc_ct; + } else { + //We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most. + spihost[host]->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE; } err = spicommon_bus_initialize_io(host, bus_config, SPICOMMON_BUSFLAG_SLAVE|bus_config->flags, &spihost[host]->flags); @@ -185,20 +214,8 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b } // The slave DMA suffers from unexpected transactions. Forbid reading if DMA is enabled by disabling the CS line. - if (use_dma) freeze_cs(spihost[host]); + if (spihost[host]->dma_enabled) freeze_cs(spihost[host]); - int dma_desc_ct = 0; - spihost[host]->tx_dma_chan = actual_tx_dma_chan; - spihost[host]->rx_dma_chan = actual_rx_dma_chan; - if (use_dma) { - //See how many dma descriptors we need and allocate them - dma_desc_ct = (bus_config->max_transfer_sz + SPI_MAX_DMA_LEN - 1) / SPI_MAX_DMA_LEN; - if (dma_desc_ct == 0) dma_desc_ct = 1; //default to 4k when max is not given - spihost[host]->max_transfer_sz = dma_desc_ct * SPI_MAX_DMA_LEN; - } else { - //We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most. - spihost[host]->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE; - } #ifdef CONFIG_PM_ENABLE err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_slave", &spihost[host]->pm_lock); @@ -211,13 +228,13 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b #endif //CONFIG_PM_ENABLE //Create queues - spihost[host]->trans_queue = xQueueCreate(slave_config->queue_size, sizeof(spi_slave_transaction_t *)); + spihost[host]->trans_queue = xQueueCreate(slave_config->queue_size, sizeof(spi_slave_trans_priv_t)); if (!spihost[host]->trans_queue) { ret = ESP_ERR_NO_MEM; goto cleanup; } if(!(slave_config->flags & SPI_SLAVE_NO_RETURN_RESULT)) { - spihost[host]->ret_queue = xQueueCreate(slave_config->queue_size, sizeof(spi_slave_transaction_t *)); + spihost[host]->ret_queue = xQueueCreate(slave_config->queue_size, sizeof(spi_slave_trans_priv_t)); if (!spihost[host]->ret_queue) { ret = ESP_ERR_NO_MEM; goto cleanup; @@ -243,7 +260,6 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b goto cleanup; } - spi_slave_hal_context_t *hal = &spihost[host]->hal; //assign the SPI, RX DMA and TX DMA peripheral registers beginning address spi_slave_hal_config_t hal_config = { .host_id = host, @@ -252,32 +268,20 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b }; spi_slave_hal_init(hal, &hal_config); - if (dma_desc_ct) { - hal->dmadesc_tx = heap_caps_malloc(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA); - hal->dmadesc_rx = heap_caps_malloc(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA); - if (!hal->dmadesc_tx || !hal->dmadesc_rx) { - ret = ESP_ERR_NO_MEM; - goto cleanup; - } - } - hal->dmadesc_n = dma_desc_ct; hal->rx_lsbfirst = (slave_config->flags & SPI_SLAVE_RXBIT_LSBFIRST) ? 1 : 0; hal->tx_lsbfirst = (slave_config->flags & SPI_SLAVE_TXBIT_LSBFIRST) ? 1 : 0; hal->mode = slave_config->mode; - hal->use_dma = use_dma; + hal->use_dma = spihost[host]->dma_enabled; hal->tx_dma_chan = actual_tx_dma_chan; hal->rx_dma_chan = actual_rx_dma_chan; spi_slave_hal_setup_device(hal); - return ESP_OK; cleanup: if (spihost[host]) { if (spihost[host]->trans_queue) vQueueDelete(spihost[host]->trans_queue); if (spihost[host]->ret_queue) vQueueDelete(spihost[host]->ret_queue); - free(spihost[host]->hal.dmadesc_tx); - free(spihost[host]->hal.dmadesc_rx); #ifdef CONFIG_PM_ENABLE if (spihost[host]->pm_lock) { esp_pm_lock_release(spihost[host]->pm_lock); @@ -288,6 +292,8 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b spi_slave_hal_deinit(&spihost[host]->hal); if (spihost[host]->dma_enabled) { spicommon_dma_chan_free(host); + free(spihost[host]->hal.dmadesc_tx); + free(spihost[host]->hal.dmadesc_rx); } free(spihost[host]); @@ -305,10 +311,10 @@ esp_err_t spi_slave_free(spi_host_device_t host) if (spihost[host]->ret_queue) vQueueDelete(spihost[host]->ret_queue); if (spihost[host]->dma_enabled) { spicommon_dma_chan_free(host); + free(spihost[host]->hal.dmadesc_tx); + free(spihost[host]->hal.dmadesc_rx); } spicommon_bus_free_io_cfg(&spihost[host]->bus_config); - free(spihost[host]->hal.dmadesc_tx); - free(spihost[host]->hal.dmadesc_rx); esp_intr_free(spihost[host]->intr); #ifdef CONFIG_PM_ENABLE esp_pm_lock_release(spihost[host]->pm_lock); @@ -320,6 +326,89 @@ esp_err_t spi_slave_free(spi_host_device_t host) return ESP_OK; } +static void SPI_SLAVE_ISR_ATTR spi_slave_uninstall_priv_trans(spi_host_device_t host, spi_slave_trans_priv_t *priv_trans) +{ +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + spi_slave_transaction_t *trans = (spi_slave_transaction_t *)priv_trans->trans; + + if (spihost[host]->dma_enabled) { + if (trans->tx_buffer && (trans->tx_buffer != priv_trans->tx_buffer)) { + free(priv_trans->tx_buffer); + } + if (trans->rx_buffer && (trans->rx_buffer != priv_trans->rx_buffer)) { + memcpy(trans->rx_buffer, priv_trans->rx_buffer, (trans->length + 7) / 8); + free(priv_trans->rx_buffer); + } + } +#endif //SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +} + +static esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_setup_priv_trans(spi_host_device_t host, spi_slave_trans_priv_t *priv_trans) +{ + spi_slave_transaction_t *trans = (spi_slave_transaction_t *)priv_trans->trans; + + priv_trans->tx_buffer = (void *)trans->tx_buffer; + priv_trans->rx_buffer = trans->rx_buffer; + +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + uint16_t alignment = spihost[host]->internal_mem_align_size; + uint32_t buffer_byte_len = (trans->length + 7) / 8; + + if (spihost[host]->dma_enabled && trans->tx_buffer) { + if ((!esp_ptr_dma_capable( trans->tx_buffer ) || ((((uint32_t)trans->tx_buffer) | buffer_byte_len) & (alignment - 1)))) { + ESP_RETURN_ON_FALSE_ISR(trans->flags & SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, ESP_ERR_INVALID_ARG, SPI_TAG, "TX buffer addr&len not align to %d, or not dma_capable", alignment); + //if txbuf in the desc not DMA-capable, or not align to "alignment", malloc a new one + ESP_EARLY_LOGD(SPI_TAG, "Allocate TX buffer for DMA" ); + buffer_byte_len = (buffer_byte_len + alignment - 1) & (~(alignment - 1)); // up align to "alignment" + uint32_t *temp = heap_caps_aligned_alloc(alignment, buffer_byte_len, MALLOC_CAP_DMA); + if (temp == NULL) { + return ESP_ERR_NO_MEM; + } + + memcpy(temp, trans->tx_buffer, (trans->length + 7) / 8); + priv_trans->tx_buffer = temp; + } + 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; + } + } +#endif //SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + return ESP_OK; +} + +esp_err_t SPI_SLAVE_ATTR spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait) +{ + BaseType_t r; + SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG); + SPI_CHECK(spihost[host], "host not slave", ESP_ERR_INVALID_ARG); + SPI_CHECK(spihost[host]->dma_enabled == 0 || trans_desc->tx_buffer==NULL || esp_ptr_dma_capable(trans_desc->tx_buffer), + "txdata not in DMA-capable memory", ESP_ERR_INVALID_ARG); + SPI_CHECK(spihost[host]->dma_enabled == 0 || trans_desc->rx_buffer==NULL || + (esp_ptr_dma_capable(trans_desc->rx_buffer) && esp_ptr_word_aligned(trans_desc->rx_buffer) && + (trans_desc->length%4==0)), + "rxdata not in DMA-capable memory or not WORD aligned", ESP_ERR_INVALID_ARG); + + SPI_CHECK(trans_desc->length <= spihost[host]->max_transfer_sz * 8, "data transfer > host maximum", ESP_ERR_INVALID_ARG); + + spi_slave_trans_priv_t priv_trans = {.trans = (spi_slave_transaction_t *)trans_desc}; + SPI_CHECK(ESP_OK == spi_slave_setup_priv_trans(host, &priv_trans), "slave setup priv_trans failed", ESP_ERR_NO_MEM); + + r = xQueueSend(spihost[host]->trans_queue, (void *)&priv_trans, ticks_to_wait); + if (!r) return ESP_ERR_TIMEOUT; + esp_intr_enable(spihost[host]->intr); + return ESP_OK; +} + /** * @note * This API is used to reset SPI Slave transaction queue. After calling this function: @@ -342,70 +431,72 @@ esp_err_t SPI_SLAVE_ATTR spi_slave_queue_reset(spi_host_device_t host) esp_intr_disable(spihost[host]->intr); spi_ll_set_int_stat(spihost[host]->hal.hw); - spihost[host]->cur_trans = NULL; - xQueueReset(spihost[host]->trans_queue); + spi_slave_trans_priv_t trans; + while( uxQueueMessagesWaiting(spihost[host]->trans_queue)) { + xQueueReceive(spihost[host]->trans_queue, &trans, 0); + spi_slave_uninstall_priv_trans(host, &trans); + } + spihost[host]->cur_trans.trans = NULL; return ESP_OK; } -esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_queue_reset_isr(spi_host_device_t host) +esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_queue_trans_isr(spi_host_device_t host, const spi_slave_transaction_t *trans_desc) { + BaseType_t r; + BaseType_t do_yield = pdFALSE; ESP_RETURN_ON_FALSE_ISR(is_valid_host(host), ESP_ERR_INVALID_ARG, SPI_TAG, "invalid host"); ESP_RETURN_ON_FALSE_ISR(spihost[host], ESP_ERR_INVALID_ARG, SPI_TAG, "host not slave"); + ESP_RETURN_ON_FALSE_ISR(trans_desc->length <= spihost[host]->max_transfer_sz * 8, ESP_ERR_INVALID_ARG, SPI_TAG, "data transfer > host maximum"); + if (spihost[host]->dma_enabled) { + uint16_t alignment = spihost[host]->internal_mem_align_size; + uint32_t buffer_byte_len = (trans_desc->length + 7) / 8; + + ESP_RETURN_ON_FALSE_ISR(\ + (trans_desc->tx_buffer && \ + esp_ptr_dma_capable(trans_desc->tx_buffer) && \ + ((((uint32_t)trans_desc->tx_buffer) | buffer_byte_len) & (alignment - 1)) == 0), \ + ESP_ERR_INVALID_ARG, SPI_TAG, "txdata addr & len not align to %d bytes or not dma_capable", alignment\ + ); + ESP_RETURN_ON_FALSE_ISR(\ + (trans_desc->rx_buffer && \ + esp_ptr_dma_capable(trans_desc->rx_buffer) && \ + ((((uint32_t)trans_desc->rx_buffer) | buffer_byte_len) & (alignment - 1)) == 0), \ + ESP_ERR_INVALID_ARG, SPI_TAG, "rxdata addr & len not align to %d bytes or not dma_capable", alignment\ + ); + } - spi_slave_transaction_t *trans = NULL; - BaseType_t do_yield = pdFALSE; - while( pdFALSE == xQueueIsQueueEmptyFromISR(spihost[host]->trans_queue)) { - xQueueReceiveFromISR(spihost[host]->trans_queue, &trans, &do_yield); + spi_slave_trans_priv_t priv_trans = { + .trans = (spi_slave_transaction_t *)trans_desc, + .tx_buffer = (void *)trans_desc->tx_buffer, + .rx_buffer = trans_desc->rx_buffer, + }; + r = xQueueSendFromISR(spihost[host]->trans_queue, (void *)&priv_trans, &do_yield); + if (!r) { + return ESP_ERR_NO_MEM; } if (do_yield) { portYIELD_FROM_ISR(); } - - spihost[host]->cur_trans = NULL; return ESP_OK; } -esp_err_t SPI_SLAVE_ATTR spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait) -{ - BaseType_t r; - SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG); - SPI_CHECK(spihost[host], "host not slave", ESP_ERR_INVALID_ARG); - SPI_CHECK(spihost[host]->dma_enabled == 0 || trans_desc->tx_buffer==NULL || esp_ptr_dma_capable(trans_desc->tx_buffer), - "txdata not in DMA-capable memory", ESP_ERR_INVALID_ARG); - SPI_CHECK(spihost[host]->dma_enabled == 0 || trans_desc->rx_buffer==NULL || - (esp_ptr_dma_capable(trans_desc->rx_buffer) && esp_ptr_word_aligned(trans_desc->rx_buffer) && - (trans_desc->length%4==0)), - "rxdata not in DMA-capable memory or not WORD aligned", ESP_ERR_INVALID_ARG); - - SPI_CHECK(trans_desc->length <= spihost[host]->max_transfer_sz * 8, "data transfer > host maximum", ESP_ERR_INVALID_ARG); - r = xQueueSend(spihost[host]->trans_queue, (void *)&trans_desc, ticks_to_wait); - if (!r) return ESP_ERR_TIMEOUT; - esp_intr_enable(spihost[host]->intr); - return ESP_OK; -} - -esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_queue_trans_isr(spi_host_device_t host, const spi_slave_transaction_t *trans_desc) +esp_err_t SPI_SLAVE_ISR_ATTR spi_slave_queue_reset_isr(spi_host_device_t host) { - BaseType_t r; - BaseType_t do_yield = pdFALSE; ESP_RETURN_ON_FALSE_ISR(is_valid_host(host), ESP_ERR_INVALID_ARG, SPI_TAG, "invalid host"); ESP_RETURN_ON_FALSE_ISR(spihost[host], ESP_ERR_INVALID_ARG, SPI_TAG, "host not slave"); - ESP_RETURN_ON_FALSE_ISR(spihost[host]->dma_enabled == 0 || trans_desc->tx_buffer==NULL || esp_ptr_dma_capable(trans_desc->tx_buffer), - ESP_ERR_INVALID_ARG, SPI_TAG, "txdata not in DMA-capable memory"); - ESP_RETURN_ON_FALSE_ISR(spihost[host]->dma_enabled == 0 || trans_desc->rx_buffer==NULL || - (esp_ptr_dma_capable(trans_desc->rx_buffer) && esp_ptr_word_aligned(trans_desc->rx_buffer) && - (trans_desc->length%4==0)), - ESP_ERR_INVALID_ARG, SPI_TAG, "rxdata not in DMA-capable memory or not WORD aligned"); - ESP_RETURN_ON_FALSE_ISR(trans_desc->length <= spihost[host]->max_transfer_sz * 8, ESP_ERR_INVALID_ARG, SPI_TAG, "data transfer > host maximum"); - r = xQueueSendFromISR(spihost[host]->trans_queue, (void *)&trans_desc, &do_yield); - if (!r) { - return ESP_ERR_NO_MEM; + spi_slave_trans_priv_t trans; + BaseType_t do_yield = pdFALSE; + while( pdFALSE == xQueueIsQueueEmptyFromISR(spihost[host]->trans_queue)) { + xQueueReceiveFromISR(spihost[host]->trans_queue, &trans, &do_yield); + spi_slave_uninstall_priv_trans(host, &trans); } if (do_yield) { portYIELD_FROM_ISR(); } + + spihost[host]->cur_trans.trans = NULL; return ESP_OK; } @@ -417,8 +508,12 @@ esp_err_t SPI_SLAVE_ATTR spi_slave_get_trans_result(spi_host_device_t host, spi_ //if SPI_SLAVE_NO_RETURN_RESULT is set, ret_queue will always be empty SPI_CHECK(!(spihost[host]->cfg.flags & SPI_SLAVE_NO_RETURN_RESULT), "API not Supported!", ESP_ERR_NOT_SUPPORTED); - r = xQueueReceive(spihost[host]->ret_queue, (void *)trans_desc, ticks_to_wait); + spi_slave_trans_priv_t priv_trans; + r = xQueueReceive(spihost[host]->ret_queue, (void *)&priv_trans, ticks_to_wait); if (!r) return ESP_ERR_TIMEOUT; + + spi_slave_uninstall_priv_trans(host, &priv_trans); + *trans_desc = priv_trans.trans; return ESP_OK; } @@ -451,19 +546,18 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) { BaseType_t r; BaseType_t do_yield = pdFALSE; - spi_slave_transaction_t *trans = NULL; spi_slave_t *host = (spi_slave_t *)arg; spi_slave_hal_context_t *hal = &host->hal; assert(spi_slave_hal_usr_is_done(hal)); bool use_dma = host->dma_enabled; - if (host->cur_trans) { + if (host->cur_trans.trans) { // When DMA is enabled, the slave rx dma suffers from unexpected transactions. Forbid reading until transaction ready. if (use_dma) freeze_cs(host); spi_slave_hal_store_result(hal); - host->cur_trans->trans_len = spi_slave_hal_get_rcv_bitlen(hal); + host->cur_trans.trans->trans_len = spi_slave_hal_get_rcv_bitlen(hal); #if CONFIG_IDF_TARGET_ESP32 //This workaround is only for esp32 @@ -473,12 +567,22 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) } #endif //#if CONFIG_IDF_TARGET_ESP32 - if (host->cfg.post_trans_cb) host->cfg.post_trans_cb(host->cur_trans); +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //invalidate here to let user access rx data in post_cb if possible + if (use_dma && host->cur_trans.rx_buffer) { + uint16_t alignment = host->internal_mem_align_size; + uint32_t buffer_byte_len = (host->cur_trans.trans->length + 7) / 8; + buffer_byte_len = (buffer_byte_len + alignment - 1) & (~(alignment - 1)); + // invalidate priv_trans.buffer_to_rcv anyway, only user provide aligned buffer can rcv correct data in post_cb + esp_err_t ret = esp_cache_msync((void *)host->cur_trans.rx_buffer, buffer_byte_len, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + assert(ret == ESP_OK); + } +#endif + if (host->cfg.post_trans_cb) host->cfg.post_trans_cb(host->cur_trans.trans); if(!(host->cfg.flags & SPI_SLAVE_NO_RETURN_RESULT)) { xQueueSendFromISR(host->ret_queue, &host->cur_trans, &do_yield); } - host->cur_trans = NULL; + host->cur_trans.trans = NULL; } #if CONFIG_IDF_TARGET_ESP32 @@ -497,21 +601,22 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) //Disable interrupt before checking to avoid concurrency issue. esp_intr_disable(host->intr); + spi_slave_trans_priv_t priv_trans; //Grab next transaction - r = xQueueReceiveFromISR(host->trans_queue, &trans, &do_yield); + r = xQueueReceiveFromISR(host->trans_queue, &priv_trans, &do_yield); if (r) { // sanity check - assert(trans); + assert(priv_trans.trans); //enable the interrupt again if there is packet to send esp_intr_enable(host->intr); //We have a transaction. Send it. - host->cur_trans = trans; + host->cur_trans = priv_trans; - hal->bitlen = trans->length; - hal->rx_buffer = trans->rx_buffer; - hal->tx_buffer = trans->tx_buffer; + hal->bitlen = priv_trans.trans->length; + hal->rx_buffer = priv_trans.rx_buffer; + hal->tx_buffer = priv_trans.tx_buffer; #if CONFIG_IDF_TARGET_ESP32 if (use_dma) { @@ -530,7 +635,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) //Kick off transfer spi_slave_hal_user_start(hal); - if (host->cfg.post_setup_cb) host->cfg.post_setup_cb(trans); + if (host->cfg.post_setup_cb) host->cfg.post_setup_cb(priv_trans.trans); } if (do_yield) portYIELD_FROM_ISR(); } diff --git a/components/driver/spi/include/driver/spi_slave.h b/components/driver/spi/include/driver/spi_slave.h index dbbfc1fb20f0..cc07d094f71d 100644 --- a/components/driver/spi/include/driver/spi_slave.h +++ b/components/driver/spi/include/driver/spi_slave.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -65,15 +65,19 @@ typedef struct { */ } spi_slave_interface_config_t; + +#define SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO (1<<0) ///< Automatically re-malloc dma buffer if user buffer doesn't meet hardware alignment or dma_capable, this process may loss some memory and performance + /** * This structure describes one SPI transaction */ struct spi_slave_transaction_t { + uint32_t flags; ///< Bitwise OR of SPI_SLAVE_TRANS_* flags size_t length; ///< Total data length, in bits size_t trans_len; ///< Transaction data length, in bits const void *tx_buffer; ///< Pointer to transmit buffer, or NULL for no MOSI phase void *rx_buffer; /**< Pointer to receive buffer, or NULL for no MISO phase. - * When the DMA is anabled, must start at WORD boundary (``rx_buffer%4==0``), + * When the DMA is enabled, must start at WORD boundary (``rx_buffer%4==0``), * and has length of a multiple of 4 bytes. */ void *user; ///< User-defined variable. Can be used to store eg transaction ID. @@ -138,6 +142,8 @@ esp_err_t spi_slave_free(spi_host_device_t host); * never time out. * @return * - ESP_ERR_INVALID_ARG if parameter is invalid + * - ESP_ERR_NO_MEM if set flag `SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO` but there is no free memory + * - ESP_ERR_INVALID_STATE if sync data between Cache and memory failed * - ESP_OK on success */ esp_err_t spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait); diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index 98a33dbdf742..e14bb9b223d3 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -148,14 +148,11 @@ components/driver/test_apps/spi/param: - if: SOC_GPSPI_SUPPORTED != 1 - if: IDF_TARGET in ["esp32p4"] temporary: true - reason: target(s) is not supported yet # TODO: IDF-7503 + reason: target(s) is not supported yet # TODO: IDF-7505 components/driver/test_apps/spi/slave: disable: - if: SOC_GPSPI_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-7503 slave support components/driver/test_apps/spi/slave_hd: disable: diff --git a/components/driver/test_apps/spi/master/main/test_spi_master.c b/components/driver/test_apps/spi/master/main/test_spi_master.c index 4904d3a824f7..d017af51752b 100644 --- a/components/driver/test_apps/spi/master/main/test_spi_master.c +++ b/components/driver/test_apps/spi/master/main/test_spi_master.c @@ -1047,7 +1047,7 @@ TEST_CASE("SPI master variable dummy test", "[spi]") TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi)); spi_slave_interface_config_t slave_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG(); - TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slave_cfg, 0)); + TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slave_cfg, SPI_DMA_DISABLED)); spitest_gpio_output_sel(bus_cfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out); spitest_gpio_output_sel(bus_cfg.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out); @@ -1069,7 +1069,6 @@ TEST_CASE("SPI master variable dummy test", "[spi]") master_free_device_bus(spi); } -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support /** * This test is to check when the first transaction of the HD master is to send data without receiving data via DMA, * then if the master could receive data correctly. @@ -1113,6 +1112,7 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]") spi_slave_transaction_t slave_trans = { .rx_buffer = slv_recv_buf, .length = buf_size * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_trans, portMAX_DELAY)); @@ -1137,6 +1137,7 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]") slave_trans = (spi_slave_transaction_t) {}; slave_trans.tx_buffer = slv_send_buf; slave_trans.length = buf_size * 8; + slave_trans.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_trans, portMAX_DELAY)); vTaskDelay(50); @@ -1158,10 +1159,8 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]") spi_slave_free(TEST_SLAVE_HOST); master_free_device_bus(spi); } -#endif #endif //#if (TEST_SPI_PERIPH_NUM >= 2) -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32) //TODO: IDF-3494 #define FD_TEST_BUF_SIZE 32 #define TEST_NUM 4 @@ -1337,7 +1336,6 @@ static void fd_slave(void) TEST_CASE_MULTIPLE_DEVICES("SPI Master: FD, DMA, Master Single Direction Test", "[spi_ms][test_env=generic_multi_device]", fd_master, fd_slave); #endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32) //TODO: IDF-3494 -#endif //p4 slave support //NOTE: Explained in IDF-1445 | MR !14996 @@ -1491,7 +1489,6 @@ TEST_CASE("spi_speed", "[spi]") #endif // CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE #endif // !(CONFIG_SPIRAM) || (CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL >= 16384) -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support //****************************************spi master add device test************************************// //add dummy devices first #if CONFIG_IDF_TARGET_ESP32 @@ -1576,7 +1573,7 @@ void test_add_device_slave(void) .spics_io_num = CS_REAL_DEV, .queue_size = 3, }; - TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO)); + TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_DISABLED)); spi_slave_transaction_t slave_trans = {}; slave_trans.length = sizeof(slave_sendbuf) * 8; @@ -1602,7 +1599,7 @@ void test_add_device_slave(void) } TEST_CASE_MULTIPLE_DEVICES("SPI_Master:Test multiple devices", "[spi_ms]", test_add_device_master, test_add_device_slave); -#endif //p4 slave support + #if (SOC_CPU_CORES_NUM > 1) && (!CONFIG_FREERTOS_UNICORE) @@ -1662,7 +1659,6 @@ TEST_CASE("test_master_isr_pin_to_core","[spi]") } #endif -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //IDF-7503 slave support #if CONFIG_SPI_MASTER_IN_IRAM #define TEST_MASTER_IRAM_TRANS_LEN 120 static IRAM_ATTR void test_master_iram_post_trans_cbk(spi_transaction_t *trans) @@ -1768,4 +1764,3 @@ static void test_iram_slave_normal(void) TEST_CASE_MULTIPLE_DEVICES("SPI_Master:IRAM_safe", "[spi_ms]", test_master_iram, test_iram_slave_normal); #endif -#endif //p4 slave support diff --git a/components/driver/test_apps/spi/slave/README.md b/components/driver/test_apps/spi/slave/README.md index 07b81b7c84c7..5b39ff96532d 100644 --- a/components/driver/test_apps/spi/slave/README.md +++ b/components/driver/test_apps/spi/slave/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | \ No newline at end of file +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | \ No newline at end of file diff --git a/components/driver/test_apps/spi/slave/main/test_app_main.c b/components/driver/test_apps/spi/slave/main/test_app_main.c index e883caa740f2..e66cde4a0344 100644 --- a/components/driver/test_apps/spi/slave/main/test_app_main.c +++ b/components/driver/test_apps/spi/slave/main/test_app_main.c @@ -10,23 +10,15 @@ #define TEST_MEMORY_LEAK_THRESHOLD (200) -static size_t before_free_8bit; -static size_t before_free_32bit; - void setUp(void) { - before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); + unity_utils_record_free_mem(); } void tearDown(void) { esp_reent_cleanup(); //clean up some of the newlib's lazy allocations - size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); - size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); - printf("\n"); - unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD); - unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD); + unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD); } void app_main(void) diff --git a/components/driver/test_apps/spi/slave/main/test_spi_slave.c b/components/driver/test_apps/spi/slave/main/test_spi_slave.c index 69cd1d48aba3..5650233f392d 100644 --- a/components/driver/test_apps/spi/slave/main/test_spi_slave.c +++ b/components/driver/test_apps/spi/slave/main/test_spi_slave.c @@ -133,6 +133,7 @@ TEST_CASE("test fullduplex slave with only RX direction", "[spi]") slave_t.length = 8 * 32; slave_t.tx_buffer = NULL; slave_t.rx_buffer = slave_rxbuf; + slave_t.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; // Colorize RX buffer with known pattern memset( slave_rxbuf, 0x66, sizeof(slave_rxbuf)); @@ -179,6 +180,7 @@ TEST_CASE("test fullduplex slave with only TX direction", "[spi]") slave_t.length = 8 * 32; slave_t.tx_buffer = slave_txbuf; slave_t.rx_buffer = NULL; + slave_t.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; // Colorize RX buffer with known pattern memset( master_rxbuf, 0x66, sizeof(master_rxbuf)); @@ -226,6 +228,7 @@ TEST_CASE("test slave send unaligned", "[spi]") slave_t.length = 8 * 32; slave_t.tx_buffer = slave_txbuf + i; slave_t.rx_buffer = slave_rxbuf; + slave_t.flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; // Colorize RX buffers with known pattern memset( master_rxbuf, 0x66, sizeof(master_rxbuf)); @@ -391,7 +394,7 @@ TEST_CASE_MULTIPLE_DEVICES("SPI_Slave_Unaligned_Test", "[spi_ms][timeout=120]", #if CONFIG_SPI_SLAVE_ISR_IN_IRAM #define TEST_IRAM_TRANS_NUM 8 -#define TEST_TRANS_LEN 120 +#define TEST_TRANS_LEN 64 #define TEST_BUFFER_SZ (TEST_IRAM_TRANS_NUM*TEST_TRANS_LEN) static void test_slave_iram_master_normal(void) @@ -484,8 +487,8 @@ static IRAM_ATTR void test_slave_isr_iram(void) slvcfg.post_trans_cb = test_slave_iram_post_trans_cbk; TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO)); - uint8_t *slave_iram_send = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - uint8_t *slave_iram_recv = heap_caps_calloc(1, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_iram_send = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_iram_recv = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); uint8_t *slave_iram_exp = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); get_tx_buffer(1001, slave_iram_exp, slave_iram_send, TEST_BUFFER_SZ); spi_slave_transaction_t trans_cfg[TEST_IRAM_TRANS_NUM] = {0}; @@ -522,7 +525,6 @@ static IRAM_ATTR void test_slave_isr_iram(void) free(slave_iram_exp); spi_slave_free(TEST_SPI_HOST); } - TEST_CASE_MULTIPLE_DEVICES("SPI_Slave: Test_ISR_IRAM_disable_cache", "[spi_ms]", test_slave_iram_master_normal, test_slave_isr_iram); static uint32_t isr_trans_cnt, isr_trans_test_fail; @@ -565,8 +567,8 @@ static IRAM_ATTR void spi_slave_trans_in_isr(void) slvcfg.post_trans_cb = test_trans_in_isr_post_trans_cbk; TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO)); - uint8_t *slave_isr_send = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - uint8_t *slave_isr_recv = heap_caps_calloc(1, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_isr_send = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_isr_recv = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); uint8_t *slave_isr_exp = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); get_tx_buffer(1001, slave_isr_exp, slave_isr_send, TEST_BUFFER_SZ); spi_slave_transaction_t trans_cfg = { @@ -596,7 +598,6 @@ static IRAM_ATTR void spi_slave_trans_in_isr(void) } TEST_CASE_MULTIPLE_DEVICES("SPI_Slave: Test_Queue_Trans_in_ISR", "[spi_ms]", test_slave_iram_master_normal, spi_slave_trans_in_isr); -uint32_t dummy_data[2] = {0x38383838, 0x5b5b5b5b}; spi_slave_transaction_t dummy_trans[2]; static uint32_t queue_reset_isr_trans_cnt, test_queue_reset_isr_fail; static IRAM_ATTR void test_queue_reset_in_isr_post_trans_cbk(spi_slave_transaction_t *curr_trans) @@ -615,8 +616,6 @@ static IRAM_ATTR void test_queue_reset_in_isr_post_trans_cbk(spi_slave_transacti if (queue_reset_isr_trans_cnt > 4) { // add some confusing transactions - dummy_data[0] ++; - dummy_data[1] --; spi_slave_queue_trans_isr(TEST_SPI_HOST, &dummy_trans[0]); ESP_LOG_BUFFER_HEX_ISR(DRAM_STR("Queue Hacked hahhhhh..."), dummy_trans[0].tx_buffer, dummy_trans[0].length / 8); spi_slave_queue_trans_isr(TEST_SPI_HOST, &dummy_trans[1]); @@ -651,10 +650,12 @@ static IRAM_ATTR void spi_queue_reset_in_isr(void) slvcfg.post_trans_cb = test_queue_reset_in_isr_post_trans_cbk; TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO)); - uint8_t *slave_isr_send = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); - uint8_t *slave_isr_recv = heap_caps_calloc(1, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_isr_send = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *slave_isr_recv = heap_caps_aligned_alloc(64, TEST_BUFFER_SZ, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); + uint8_t *dummy_data = heap_caps_aligned_alloc(64, 64*2, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); uint8_t *slave_isr_exp = heap_caps_malloc(TEST_BUFFER_SZ, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); get_tx_buffer(1001, slave_isr_exp, slave_isr_send, TEST_BUFFER_SZ); + get_tx_buffer(1001, dummy_data, dummy_data + 64, 64); spi_slave_transaction_t trans_cfg = { .tx_buffer = slave_isr_send, .rx_buffer = slave_isr_recv, @@ -664,10 +665,10 @@ static IRAM_ATTR void spi_queue_reset_in_isr(void) unity_wait_for_signal("Master ready"); for (uint8_t i = 0; i < 2; i++) { - dummy_trans[i].tx_buffer = &dummy_data[i]; - dummy_trans[i].rx_buffer = &dummy_data[i]; - dummy_trans[i].user = &dummy_data[i]; - dummy_trans[i].length = sizeof(uint32_t) * 8; + dummy_trans[i].tx_buffer = dummy_data + i * 64; + dummy_trans[i].rx_buffer = dummy_data + i * 64; + dummy_trans[i].user = dummy_data + i * 64; + dummy_trans[i].length = 64 * 8; } // start a trans by normal API first to trigger spi isr spi_slave_queue_trans(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY); @@ -687,7 +688,7 @@ static IRAM_ATTR void spi_queue_reset_in_isr(void) spi_slave_free(TEST_SPI_HOST); } TEST_CASE_MULTIPLE_DEVICES("SPI_Slave: Test_Queue_Reset_in_ISR", "[spi_ms]", test_slave_iram_master_normal, spi_queue_reset_in_isr); -#endif // CONFIG_SPI_SLAVE_ISR_IN_IRAM +#endif // CONFIG_SPI_SLAVE_ISR_IN_IRAM #if (SOC_CPU_CORES_NUM > 1) && (!CONFIG_FREERTOS_UNICORE) @@ -716,7 +717,7 @@ TEST_CASE("test_slave_isr_pin_to_core", "[spi]") slave_expect = 0; for (int i = 0; i < TEST_ISR_CNT; i++) { - TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO)); + TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_DISABLED)); TEST_ESP_OK(spi_slave_queue_trans(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY)); TEST_ESP_OK(spi_slave_free(TEST_SPI_HOST)); } @@ -729,7 +730,7 @@ TEST_CASE("test_slave_isr_pin_to_core", "[spi]") slave_expect = 0; for (int i = 0; i < TEST_ISR_CNT; i++) { - TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO)); + TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_DISABLED)); TEST_ESP_OK(spi_slave_queue_trans(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY)); vTaskDelay(1); // Waiting ISR on core 1 to be done. TEST_ESP_OK(spi_slave_free(TEST_SPI_HOST)); @@ -737,5 +738,4 @@ TEST_CASE("test_slave_isr_pin_to_core", "[spi]") printf("Test Slave ISR Assign CPU1: %d : %ld\n", TEST_ISR_CNT, slave_expect); TEST_ASSERT_EQUAL_UINT32(TEST_ISR_CNT, slave_expect); } - #endif diff --git a/components/driver/test_apps/spi/slave/main/test_spi_slave_queue.c b/components/driver/test_apps/spi/slave/main/test_spi_slave_queue.c index 74103554003c..1550fca913ed 100644 --- a/components/driver/test_apps/spi/slave/main/test_spi_slave_queue.c +++ b/components/driver/test_apps/spi/slave/main/test_spi_slave_queue.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,6 @@ #define TEST_BUF_SIZE 32 #define TEST_TIMES 4 - static void test_master(void) { spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); @@ -144,6 +143,7 @@ static void test_slave(void) trans[0].tx_buffer = slv_tx_buf[0]; trans[0].rx_buffer = slv_rx_buf[0]; trans[0].length = TEST_BUF_SIZE * 8; + trans[0].flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &trans[0], portMAX_DELAY)); unity_send_signal("Slave ready"); TEST_ESP_OK(spi_slave_get_trans_result(SPI2_HOST, &ret_trans, portMAX_DELAY)); @@ -159,24 +159,28 @@ static void test_slave(void) spi_slave_transaction_t dummy_trans0 = { .tx_buffer = &dummy_data0, .length = sizeof(uint32_t) * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &dummy_trans0, portMAX_DELAY)); uint32_t dummy_data1 = 0xBB; spi_slave_transaction_t dummy_trans1 = { .tx_buffer = &dummy_data1, .length = sizeof(uint32_t) * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &dummy_trans1, portMAX_DELAY)); uint32_t dummy_data2 = 0xCC; spi_slave_transaction_t dummy_trans2 = { .tx_buffer = &dummy_data2, .length = sizeof(uint32_t) * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &dummy_trans2, portMAX_DELAY)); uint32_t dummy_data3 = 0xDD; spi_slave_transaction_t dummy_trans3 = { .tx_buffer = &dummy_data3, .length = sizeof(uint32_t) * 8, + .flags = SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO, }; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &dummy_trans3, portMAX_DELAY)); @@ -185,16 +189,19 @@ static void test_slave(void) trans[1].tx_buffer = slv_tx_buf[1]; trans[1].rx_buffer = slv_rx_buf[1]; trans[1].length = TEST_BUF_SIZE * 8; + trans[1].flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &trans[1], portMAX_DELAY)); trans[2].tx_buffer = slv_tx_buf[2]; trans[2].rx_buffer = slv_rx_buf[2]; trans[2].length = TEST_BUF_SIZE * 8; + trans[2].flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &trans[2], portMAX_DELAY)); trans[3].tx_buffer = slv_tx_buf[3]; trans[3].rx_buffer = slv_rx_buf[3]; trans[3].length = TEST_BUF_SIZE * 8; + trans[3].flags |= SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO; TEST_ESP_OK(spi_slave_queue_trans(SPI2_HOST, &trans[3], portMAX_DELAY)); unity_send_signal("Slave ready"); diff --git a/components/hal/cache_hal.c b/components/hal/cache_hal.c index ea6d3e485f0d..423589e7a0ad 100644 --- a/components/hal/cache_hal.c +++ b/components/hal/cache_hal.c @@ -286,7 +286,7 @@ void cache_hal_unfreeze(uint32_t cache_level, cache_type_t type) uint32_t cache_hal_get_cache_line_size(uint32_t cache_level, cache_type_t type) { - HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS)); + HAL_ASSERT(cache_level <= CACHE_LL_LEVEL_NUMS); uint32_t line_size = 0; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE diff --git a/components/hal/esp32/cache_hal_esp32.c b/components/hal/esp32/cache_hal_esp32.c index e8acd5283171..815923332775 100644 --- a/components/hal/esp32/cache_hal_esp32.c +++ b/components/hal/esp32/cache_hal_esp32.c @@ -55,7 +55,7 @@ bool cache_hal_vaddr_to_cache_level_id(uint32_t vaddr_start, uint32_t len, uint3 uint32_t cache_hal_get_cache_line_size(uint32_t cache_level, cache_type_t type) { - HAL_ASSERT(cache_level && (cache_level <= CACHE_LL_LEVEL_NUMS)); + HAL_ASSERT(cache_level <= CACHE_LL_LEVEL_NUMS); uint32_t line_size = 0; diff --git a/components/hal/include/hal/spi_hal.h b/components/hal/include/hal/spi_hal.h index 93a284f218e5..9fbff296eca8 100644 --- a/components/hal/include/hal/spi_hal.h +++ b/components/hal/include/hal/spi_hal.h @@ -30,6 +30,7 @@ #include "soc/soc_caps.h" #include "hal/spi_types.h" #include "hal/dma_types.h" +#include "soc/gdma_channel.h" #if SOC_GPSPI_SUPPORTED #include "hal/spi_ll.h" #endif diff --git a/components/hal/include/hal/spi_slave_hal.h b/components/hal/include/hal/spi_slave_hal.h index 4ef6e26db19a..30b8f2fbc27f 100644 --- a/components/hal/include/hal/spi_slave_hal.h +++ b/components/hal/include/hal/spi_slave_hal.h @@ -27,8 +27,9 @@ #include "sdkconfig.h" #include "esp_types.h" #include "soc/soc_caps.h" +#include "hal/dma_types.h" +#include "soc/gdma_channel.h" #if SOC_GPSPI_SUPPORTED -#include "soc/lldesc.h" #include "hal/spi_ll.h" #endif @@ -37,6 +38,11 @@ extern "C" { #endif #if SOC_GPSPI_SUPPORTED +#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) +typedef dma_descriptor_align4_t spi_dma_desc_t; +#else +typedef dma_descriptor_align8_t spi_dma_desc_t; +#endif /** * Context that should be maintained by both the driver and the HAL. @@ -47,11 +53,11 @@ typedef struct { spi_dma_dev_t *dma_in; ///< Address of the DMA peripheral registers which stores the data received from a peripheral into RAM. spi_dma_dev_t *dma_out; ///< Address of the DMA peripheral registers which transmits the data from RAM to a peripheral. /* should be configured by driver at initialization */ - lldesc_t *dmadesc_rx; /**< Array of DMA descriptor used by the TX DMA. + spi_dma_desc_t *dmadesc_rx; /**< Array of DMA descriptor used by the TX DMA. * The amount should be larger than dmadesc_n. The driver should ensure that * the data to be sent is shorter than the descriptors can hold. */ - lldesc_t *dmadesc_tx; /**< Array of DMA descriptor used by the RX DMA. + spi_dma_desc_t *dmadesc_tx; /**< Array of DMA descriptor used by the RX DMA. * The amount should be larger than dmadesc_n. The driver should ensure that * the data to be sent is shorter than the descriptors can hold. */ diff --git a/components/hal/spi_slave_hal.c b/components/hal/spi_slave_hal.c index 9d61e12042af..c53bd600cadf 100644 --- a/components/hal/spi_slave_hal.c +++ b/components/hal/spi_slave_hal.c @@ -35,7 +35,6 @@ static void s_spi_slave_hal_dma_init_config(const spi_slave_hal_context_t *hal) void spi_slave_hal_init(spi_slave_hal_context_t *hal, const spi_slave_hal_config_t *hal_config) { - memset(hal, 0, sizeof(spi_slave_hal_context_t)); spi_dev_t *hw = SPI_LL_GET_HW(hal_config->host_id); hal->hw = hw; hal->dma_in = hal_config->dma_in; diff --git a/components/hal/spi_slave_hal_iram.c b/components/hal/spi_slave_hal_iram.c index 07c58d4045ec..0d0dcef6df70 100644 --- a/components/hal/spi_slave_hal_iram.c +++ b/components/hal/spi_slave_hal_iram.c @@ -45,13 +45,49 @@ void spi_slave_hal_user_start(const spi_slave_hal_context_t *hal) spi_ll_user_start(hal->hw); } +#if SOC_NON_CACHEABLE_OFFSET +#define ADDR_DMA_2_CPU(addr) ((typeof(addr))((uint32_t)(addr) + SOC_NON_CACHEABLE_OFFSET)) +#define ADDR_CPU_2_DMA(addr) ((typeof(addr))((uint32_t)(addr) - SOC_NON_CACHEABLE_OFFSET)) +#else +#define ADDR_DMA_2_CPU(addr) (addr) +#define ADDR_CPU_2_DMA(addr) (addr) +#endif + +static void s_spi_slave_hal_dma_desc_setup_link(spi_dma_desc_t *dmadesc, const void *data, int len, bool is_rx) +{ + dmadesc = ADDR_DMA_2_CPU(dmadesc); + int n = 0; + while (len) { + int dmachunklen = len; + if (dmachunklen > DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED) { + dmachunklen = DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; + } + if (is_rx) { + //Receive needs DMA length rounded to next 32-bit boundary + dmadesc[n].dw0.size = (dmachunklen + 3) & (~3); + } else { + dmadesc[n].dw0.size = dmachunklen; + dmadesc[n].dw0.length = dmachunklen; + } + dmadesc[n].buffer = (uint8_t *)data; + dmadesc[n].dw0.suc_eof = 0; + dmadesc[n].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; + dmadesc[n].next = ADDR_CPU_2_DMA(&dmadesc[n + 1]); + len -= dmachunklen; + data += dmachunklen; + n++; + } + dmadesc[n - 1].dw0.suc_eof = 1; //Mark last DMA desc as end of stream. + dmadesc[n - 1].next = NULL; +} + void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal) { if (hal->use_dma) { //Fill DMA descriptors if (hal->rx_buffer) { - lldesc_setup_link(hal->dmadesc_rx, hal->rx_buffer, ((hal->bitlen + 7) / 8), true); + s_spi_slave_hal_dma_desc_setup_link(hal->dmadesc_rx, hal->rx_buffer, ((hal->bitlen + 7) / 8), true); //reset dma inlink, this should be reset before spi related reset spi_dma_ll_rx_reset(hal->dma_in, hal->rx_dma_chan); @@ -60,10 +96,10 @@ void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal) spi_ll_infifo_full_clr(hal->hw); spi_ll_dma_rx_enable(hal->hw, 1); - spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, hal->dmadesc_rx); + spi_dma_ll_rx_start(hal->dma_in, hal->rx_dma_chan, (lldesc_t *)hal->dmadesc_rx); } if (hal->tx_buffer) { - lldesc_setup_link(hal->dmadesc_tx, hal->tx_buffer, (hal->bitlen + 7) / 8, false); + s_spi_slave_hal_dma_desc_setup_link(hal->dmadesc_tx, hal->tx_buffer, (hal->bitlen + 7) / 8, false); //reset dma outlink, this should be reset before spi related reset spi_dma_ll_tx_reset(hal->dma_out, hal->tx_dma_chan); @@ -72,7 +108,7 @@ void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal) spi_ll_outfifo_empty_clr(hal->hw); spi_ll_dma_tx_enable(hal->hw, 1); - spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, hal->dmadesc_tx); + spi_dma_ll_tx_start(hal->dma_out, hal->tx_dma_chan, (lldesc_t *)hal->dmadesc_tx); } } else { //No DMA. Turn off SPI and copy data to transmit buffers. @@ -125,8 +161,8 @@ bool spi_slave_hal_dma_need_reset(const spi_slave_hal_context_t *hal) //In case CS goes high too soon, the transfer is aborted while the DMA channel still thinks it's going. This //leads to issues later on, so in that case we need to reset the channel. The state can be detected because //the DMA system doesn't give back the offending descriptor; the owner is still set to DMA. - for (i = 0; hal->dmadesc_rx[i].eof == 0 && hal->dmadesc_rx[i].owner == 0; i++) {} - if (hal->dmadesc_rx[i].owner) { + for (i = 0; hal->dmadesc_rx[i].dw0.suc_eof == 0 && hal->dmadesc_rx[i].dw0.owner == 0; i++) {} + if (hal->dmadesc_rx[i].dw0.owner) { ret = true; } } diff --git a/docs/docs_not_updated/esp32p4.txt b/docs/docs_not_updated/esp32p4.txt index 2f190dd54401..c5b6972d879a 100644 --- a/docs/docs_not_updated/esp32p4.txt +++ b/docs/docs_not_updated/esp32p4.txt @@ -90,7 +90,6 @@ api-reference/peripherals/usb_host/usb_host_notes_design.rst api-reference/peripherals/usb_device.rst api-reference/peripherals/gpio.rst api-reference/peripherals/dac.rst -api-reference/peripherals/spi_slave.rst api-reference/peripherals/touch_element.rst api-reference/peripherals/lcd.rst api-reference/peripherals/ana_cmpr.rst diff --git a/docs/en/api-reference/peripherals/spi_slave.rst b/docs/en/api-reference/peripherals/spi_slave.rst index bd36b3810431..9d119dec1a0a 100644 --- a/docs/en/api-reference/peripherals/spi_slave.rst +++ b/docs/en/api-reference/peripherals/spi_slave.rst @@ -141,12 +141,12 @@ GPIO Matrix and IO_MUX .. only:: not esp32 - {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1"} - {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4"} - {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5"} - {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0"} - {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3"} - {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2"} + {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7"} + {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9"} + {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8"} + {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10"} + {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6"} + {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11"} Most of chip's peripheral signals have direct connection to their dedicated IO_MUX pins. However, the signals can also be routed to any other available pins using the less direct GPIO matrix. If at least one signal is routed through the GPIO matrix, then all signals will be routed through it. diff --git a/docs/zh_CN/api-reference/peripherals/spi_slave.rst b/docs/zh_CN/api-reference/peripherals/spi_slave.rst index c80843dab4a3..6ab50cf464aa 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_slave.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_slave.rst @@ -141,12 +141,12 @@ GPIO 交换矩阵和 IO_MUX .. only:: not esp32 - {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1"} - {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4"} - {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5"} - {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0"} - {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3"} - {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2"} + {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7"} + {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9"} + {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8"} + {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10"} + {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6"} + {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11"} {IDF_TARGET_NAME} 的大多数外设信号都直接连接到其专用的 IO_MUX 管脚。不过,也可以使用 GPIO 交换矩阵,将信号路由到任何可用的其他管脚。如果通过 GPIO 交换矩阵路由了至少一个信号,则所有信号都将通过 GPIO 交换矩阵路由。 diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 5141971ac67d..9772054a6c25 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -258,9 +258,6 @@ examples/peripherals/spi_master/lcd: examples/peripherals/spi_slave: disable: - if: SOC_GPSPI_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-7503 slave support examples/peripherals/spi_slave_hd/append_mode/master: disable: diff --git a/examples/peripherals/spi_slave/README.md b/examples/peripherals/spi_slave/README.md index c094825d3298..dd8d85b8059f 100644 --- a/examples/peripherals/spi_slave/README.md +++ b/examples/peripherals/spi_slave/README.md @@ -1,22 +1,23 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | ## SPI slave example These two projects illustrate the SPI Slave driver. They're supposed to be flashed into two separate Espressif chips connected to eachother using the SPI pins defined in app_main.c. Once connected and flashed, they will use the spi master and spi slave driver to communicate with eachother. The example also includes a handshaking line to allow the master to only poll the slave when it is actually ready to parse a transaction. +### Connection For different chip and host used, the connections may be different. Here show a example diagram of hardware connection, you can freely change the GPIO settings by editing defines in the top of `main/app_main.c` in the master/slave source code. and change the hardware relatively. The default GPIOs used in the example are the following: -| Signal | ESP32 | -|-----------|--------| -| Handshake | GPIO2 | -| MOSI | GPIO12 | -| MISO | GPIO13 | -| SCLK | GPIO15 | -| CS | GPIO14 | - + + + + + + + +
Signal Handshake MOSI MISO SCLK CS
Pin GPIO2 GPIO12 GPIO13 GPIO15 GPIO14
Please run wires between the following GPIOs between the slave and master to make the example function: diff --git a/examples/peripherals/spi_slave/receiver/main/app_main.c b/examples/peripherals/spi_slave/receiver/main/app_main.c index 1dde14944789..8032f2b8307b 100644 --- a/examples/peripherals/spi_slave/receiver/main/app_main.c +++ b/examples/peripherals/spi_slave/receiver/main/app_main.c @@ -30,54 +30,21 @@ ready to send/receive data, this code uses a callback to set the handshake pin h sending a transaction. As soon as the transaction is done, the line gets set low again. */ -/* -Pins in use. The SPI Master can use the GPIO mux, so feel free to change these if needed. -*/ -#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 -#define GPIO_HANDSHAKE 2 -#define GPIO_MOSI 12 -#define GPIO_MISO 13 -#define GPIO_SCLK 15 -#define GPIO_CS 14 - -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 -#define GPIO_HANDSHAKE 3 -#define GPIO_MOSI 7 -#define GPIO_MISO 2 -#define GPIO_SCLK 6 -#define GPIO_CS 10 - -#elif CONFIG_IDF_TARGET_ESP32C6 -#define GPIO_HANDSHAKE 15 -#define GPIO_MOSI 19 -#define GPIO_MISO 20 -#define GPIO_SCLK 18 -#define GPIO_CS 9 - -#elif CONFIG_IDF_TARGET_ESP32H2 -#define GPIO_HANDSHAKE 2 -#define GPIO_MOSI 5 -#define GPIO_MISO 0 -#define GPIO_SCLK 4 -#define GPIO_CS 1 - -#elif CONFIG_IDF_TARGET_ESP32S3 -#define GPIO_HANDSHAKE 2 -#define GPIO_MOSI 11 -#define GPIO_MISO 13 -#define GPIO_SCLK 12 -#define GPIO_CS 10 - -#endif //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 - +////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////// Please update the following configuration according to your HardWare spec ///////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifdef CONFIG_IDF_TARGET_ESP32 #define RCV_HOST HSPI_HOST - #else #define RCV_HOST SPI2_HOST - #endif +#define GPIO_HANDSHAKE 2 +#define GPIO_MOSI 12 +#define GPIO_MISO 13 +#define GPIO_SCLK 15 +#define GPIO_CS 14 + //Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high. void my_post_setup_cb(spi_slave_transaction_t *trans) { @@ -119,7 +86,7 @@ void app_main(void) gpio_config_t io_conf = { .intr_type = GPIO_INTR_DISABLE, .mode = GPIO_MODE_OUTPUT, - .pin_bit_mask = (1 << GPIO_HANDSHAKE) + .pin_bit_mask = BIT64(GPIO_HANDSHAKE), }; //Configure handshake line as output diff --git a/examples/peripherals/spi_slave/sender/main/app_main.c b/examples/peripherals/spi_slave/sender/main/app_main.c index fc8421109dad..1154e3ba0ce0 100644 --- a/examples/peripherals/spi_slave/sender/main/app_main.c +++ b/examples/peripherals/spi_slave/sender/main/app_main.c @@ -105,7 +105,7 @@ void app_main(void) .intr_type = GPIO_INTR_POSEDGE, .mode = GPIO_MODE_INPUT, .pull_up_en = 1, - .pin_bit_mask = (1 << GPIO_HANDSHAKE) + .pin_bit_mask = BIT64(GPIO_HANDSHAKE), }; int n = 0; From 95b01526371f082252ad3b598646872cf6e622f4 Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 30 Oct 2023 12:17:25 +0800 Subject: [PATCH 088/161] doc(adc): added efuse related failure doc Closes https://github.com/espressif/esp-idf/issues/12372 --- docs/en/api-guides/flash_psram_config.rst | 2 +- docs/en/api-reference/peripherals/adc_calibration.rst | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/en/api-guides/flash_psram_config.rst b/docs/en/api-guides/flash_psram_config.rst index fc7e352b63c1..a272a91036d4 100644 --- a/docs/en/api-guides/flash_psram_config.rst +++ b/docs/en/api-guides/flash_psram_config.rst @@ -173,7 +173,7 @@ Error Handling this means: - either you're using a board with a Quad Flash - - or you're using a board with an Octal Flash, but the eFuse bit ``FLASH_TYPE`` isn't burnt. Espressif guarantees this bit during module manufacturing, but if the module is manufactured by others, this may happen. + - or you're using a board with an Octal Flash, but the eFuse bit ``FLASH_TYPE`` isn't burnt. Espressif guarantees this bit is burnt during module manufacturing, but if the module is manufactured by others, this may happen. Here is a method to burn the eFuse bit: diff --git a/docs/en/api-reference/peripherals/adc_calibration.rst b/docs/en/api-reference/peripherals/adc_calibration.rst index ce1d6119c111..53903e429180 100644 --- a/docs/en/api-reference/peripherals/adc_calibration.rst +++ b/docs/en/api-reference/peripherals/adc_calibration.rst @@ -104,7 +104,16 @@ If you use your custom ADC calibration schemes, you could either modify this fun - :cpp:member:`adc_cali_curve_fitting_config_t::atten`, ADC attenuation that your ADC raw results use. - :cpp:member:`adc_cali_curve_fitting_config_t::bitwidth`, bit width of ADC raw result. - After setting up the configuration structure, call :cpp:func:`adc_cali_create_scheme_curve_fitting` to create a Curve Fitting calibration scheme handle. This function may fail due to reasons such as :c:macro:`ESP_ERR_INVALID_ARG` or :c:macro:`ESP_ERR_NO_MEM`. Especially, when the function return :c:macro:`ESP_ERR_NOT_SUPPORTED`, this means the calibration scheme required eFuse bits are not burnt on your board. + After setting up the configuration structure, call :cpp:func:`adc_cali_create_scheme_curve_fitting` to create a Curve Fitting calibration scheme handle. This function may fail due to reasons such as :c:macro:`ESP_ERR_INVALID_ARG` or :c:macro:`ESP_ERR_NO_MEM`. + + ADC Calibration Efuse Related Failures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + When the function :cpp:func:`adc_cali_create_scheme_curve_fitting` returns :c:macro:`ESP_ERR_NOT_SUPPORTED`, this means the calibration scheme required eFuse bits are not correct on your board. + + ESP-IDF provided ADC calibration scheme is based on the values in certain ADC calibration related on-chip eFuse bits. Espressif guarantees that these bits are burnt during module manufacturing, so you don't have to burn these eFuses bits yourself. + + If you see such an error, please contact us at `Technical Inquiries `__ website. Create Curve Fitting Scheme ~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 2eb1a7f93388d140ed9a8bb39f610e08f1848036 Mon Sep 17 00:00:00 2001 From: alanmaxwell Date: Mon, 30 Oct 2023 11:54:27 +0800 Subject: [PATCH 089/161] fix(wifi): Fix bug using CONFIG_WIFI_ENABLED macro --- components/esp_phy/src/phy_common.c | 8 ++++---- components/esp_phy/test/test_phy_rtc.c | 2 +- .../classic_bt/bt_spp_acceptor/sdkconfig.defaults | 2 +- .../classic_bt/bt_spp_initiator/sdkconfig.defaults | 2 +- .../classic_bt/bt_spp_vfs_acceptor/sdkconfig.defaults | 2 +- .../classic_bt/bt_spp_vfs_initiator/sdkconfig.defaults | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/esp_phy/src/phy_common.c b/components/esp_phy/src/phy_common.c index d28745b8e8bd..ad4a3b388e3b 100644 --- a/components/esp_phy/src/phy_common.c +++ b/components/esp_phy/src/phy_common.c @@ -13,7 +13,7 @@ static volatile uint16_t s_phy_modem_flag = 0; extern void phy_param_track_tot(bool en_wifi, bool en_ble_154); static esp_timer_handle_t phy_track_pll_timer; -#if CONFIG_WIFI_ENABLED +#if CONFIG_ESP_WIFI_ENABLED static volatile int64_t s_wifi_prev_timestamp; #endif #if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED @@ -21,7 +21,7 @@ static volatile int64_t s_bt_154_prev_timestamp; #endif #define PHY_TRACK_PLL_PERIOD_IN_US 1000000 -#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED || CONFIG_WIFI_ENABLED +#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED || CONFIG_ESP_WIFI_ENABLED bool phy_enabled_modem_contains(esp_phy_modem_t modem) { return (s_phy_modem_flag & modem) != 0; @@ -32,7 +32,7 @@ static void phy_track_pll(void) { bool wifi_track_pll = false; bool ble_154_track_pll = false; -#if CONFIG_WIFI_ENABLED +#if CONFIG_ESP_WIFI_ENABLED if (phy_enabled_modem_contains(PHY_MODEM_WIFI)) { wifi_track_pll = true; s_wifi_prev_timestamp = esp_timer_get_time(); @@ -64,7 +64,7 @@ void phy_track_pll_init(void) // Using a variable to record the previously tracked time when PLL was last called. // If the duration is larger than PHY_TRACK_PLL_PERIOD_IN_US, then track PLL. bool need_track_pll = false; -#if CONFIG_WIFI_ENABLED +#if CONFIG_ESP_WIFI_ENABLED need_track_pll = need_track_pll || ((esp_timer_get_time() - s_wifi_prev_timestamp) > PHY_TRACK_PLL_PERIOD_IN_US); #endif #if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED diff --git a/components/esp_phy/test/test_phy_rtc.c b/components/esp_phy/test/test_phy_rtc.c index 7cfe722722cb..1d653ce15cc6 100644 --- a/components/esp_phy/test/test_phy_rtc.c +++ b/components/esp_phy/test/test_phy_rtc.c @@ -46,7 +46,7 @@ static void test_phy_rtc_init(void) ret = nvs_flash_init(); } TEST_ESP_OK(ret); -#if CONFIG_WIFI_ENABLED +#if CONFIG_ESP_WIFI_ENABLED esp_phy_enable(PHY_MODEM_WIFI); #endif #if CONFIG_BT_ENABLED diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.defaults index a30359952112..1974e0e8cb5f 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_acceptor/sdkconfig.defaults @@ -5,6 +5,6 @@ CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_CLASSIC_ENABLED=y -CONFIG_WIFI_ENABLED=n +CONFIG_ESP_WIFI_ENABLED=n CONFIG_BT_SPP_ENABLED=y CONFIG_BT_BLE_ENABLED=n diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.defaults index a30359952112..1974e0e8cb5f 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_initiator/sdkconfig.defaults @@ -5,6 +5,6 @@ CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_CLASSIC_ENABLED=y -CONFIG_WIFI_ENABLED=n +CONFIG_ESP_WIFI_ENABLED=n CONFIG_BT_SPP_ENABLED=y CONFIG_BT_BLE_ENABLED=n diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.defaults index a30359952112..1974e0e8cb5f 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/sdkconfig.defaults @@ -5,6 +5,6 @@ CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_CLASSIC_ENABLED=y -CONFIG_WIFI_ENABLED=n +CONFIG_ESP_WIFI_ENABLED=n CONFIG_BT_SPP_ENABLED=y CONFIG_BT_BLE_ENABLED=n diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.defaults b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.defaults index a30359952112..1974e0e8cb5f 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.defaults +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/sdkconfig.defaults @@ -5,6 +5,6 @@ CONFIG_BTDM_CTRL_MODE_BLE_ONLY=n CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=y CONFIG_BTDM_CTRL_MODE_BTDM=n CONFIG_BT_CLASSIC_ENABLED=y -CONFIG_WIFI_ENABLED=n +CONFIG_ESP_WIFI_ENABLED=n CONFIG_BT_SPP_ENABLED=y CONFIG_BT_BLE_ENABLED=n From 120e53b34d7ef03b757169b3a259527def680087 Mon Sep 17 00:00:00 2001 From: alanmaxwell Date: Mon, 30 Oct 2023 14:26:25 +0800 Subject: [PATCH 090/161] fix(phy): Fix ESP32C6 rx pkts fail in light sleep mode --- components/esp_phy/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_phy/lib b/components/esp_phy/lib index 8673ea44a5ae..9af837d5a581 160000 --- a/components/esp_phy/lib +++ b/components/esp_phy/lib @@ -1 +1 @@ -Subproject commit 8673ea44a5aebaf46b7c95251ed3392bce549433 +Subproject commit 9af837d5a581f502d7d5b1b5829a5c008c048be4 From 6fc878f857d61a785758eba6782826ee03730c65 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Mon, 30 Oct 2023 13:43:10 +0530 Subject: [PATCH 091/161] fix(ci): Use latest stable actions/checkout@v3 instead of v2 for GitHub Actions --- .github/workflows/issue_comment.yml | 2 +- .github/workflows/new_issues.yml | 2 +- .github/workflows/new_prs.yml | 2 +- .github/workflows/pr_approved.yml | 2 +- .github/workflows/pre_commit_check.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/issue_comment.yml b/.github/workflows/issue_comment.yml index b542f792f906..f78a699082bb 100644 --- a/.github/workflows/issue_comment.yml +++ b/.github/workflows/issue_comment.yml @@ -12,7 +12,7 @@ jobs: name: Sync Issue Comments to Jira runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Sync issue comments to JIRA uses: espressif/github-actions/sync_issues_to_jira@master env: diff --git a/.github/workflows/new_issues.yml b/.github/workflows/new_issues.yml index 4d355c07767b..7a8879a42a16 100644 --- a/.github/workflows/new_issues.yml +++ b/.github/workflows/new_issues.yml @@ -12,7 +12,7 @@ jobs: name: Sync issues to Jira runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Sync GitHub issues to Jira project uses: espressif/github-actions/sync_issues_to_jira@master env: diff --git a/.github/workflows/new_prs.yml b/.github/workflows/new_prs.yml index 4c750bba1529..3000aff80a75 100644 --- a/.github/workflows/new_prs.yml +++ b/.github/workflows/new_prs.yml @@ -15,7 +15,7 @@ jobs: name: Sync PRs to Jira runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Sync PRs to Jira project uses: espressif/github-actions/sync_issues_to_jira@master with: diff --git a/.github/workflows/pr_approved.yml b/.github/workflows/pr_approved.yml index 963d6cba87dd..a641a7e50198 100644 --- a/.github/workflows/pr_approved.yml +++ b/.github/workflows/pr_approved.yml @@ -11,7 +11,7 @@ jobs: (github.event.label.name == 'PR-Sync-Rebase') || (github.event.label.name == 'PR-Sync-Update') steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Sync approved PRs to internal codebase uses: espressif/github-actions/github_pr_to_internal_pr@master env: diff --git a/.github/workflows/pre_commit_check.yml b/.github/workflows/pre_commit_check.yml index af77668695ae..859f56780710 100644 --- a/.github/workflows/pre_commit_check.yml +++ b/.github/workflows/pre_commit_check.yml @@ -14,7 +14,7 @@ jobs: SKIP: "cleanup-ignore-lists" # Comma-separated string of ignored pre-commit check IDs steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Fetch head and base refs # This is necessary for pre-commit to check the changes in the PR branch run: | From 3f4698ac47b85a2a519f6432d22a7f2c05bb359d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rohl=C3=ADnek?= Date: Mon, 30 Oct 2023 10:22:08 +0100 Subject: [PATCH 092/161] fix(storage/fatfs): add missing lock release introduced by IMMEDIATE_FSYNC --- components/fatfs/vfs/vfs_fat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/fatfs/vfs/vfs_fat.c b/components/fatfs/vfs/vfs_fat.c index 169133a08a8b..4ae04c3d6171 100644 --- a/components/fatfs/vfs/vfs_fat.c +++ b/components/fatfs/vfs/vfs_fat.c @@ -424,6 +424,7 @@ static ssize_t vfs_fat_write(void* ctx, int fd, const void * data, size_t size) if (res != FR_OK) { ESP_LOGD(TAG, "%s: fresult=%d", __func__, res); errno = fresult_to_errno(res); + _lock_release(&fat_ctx->lock); return -1; } } From ddb82f7ac95351d4670afbbac64c7d45f9d31b25 Mon Sep 17 00:00:00 2001 From: Linda Date: Tue, 24 Oct 2023 17:34:20 +0800 Subject: [PATCH 093/161] docs: add Ethernet driver update to migration from 4.4 to 5.0 --- docs/en/migration-guides/release-5.x/5.0/networking.rst | 9 +++++++++ .../migration-guides/release-5.x/5.0/networking.rst | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/docs/en/migration-guides/release-5.x/5.0/networking.rst b/docs/en/migration-guides/release-5.x/5.0/networking.rst index 08cb46d778ca..ba52226cac47 100644 --- a/docs/en/migration-guides/release-5.x/5.0/networking.rst +++ b/docs/en/migration-guides/release-5.x/5.0/networking.rst @@ -83,6 +83,15 @@ The SPI-Ethernet Module initialization is now simplified. Previously, you had to Now, you no longer need to call :cpp:func:`spi_bus_add_device` as SPI devices are allocated internally. As a result, the :cpp:class:`eth_dm9051_config_t`, :cpp:class:`eth_w5500_config_t`, and :cpp:class:`eth_ksz8851snl_config_t` configuration structures are updated to include members for SPI device configuration (e.g., to allow fine tuning of SPI timing which may be dependent on PCB design). Likewise, the ``ETH_DM9051_DEFAULT_CONFIG``, ``ETH_W5500_DEFAULT_CONFIG``, and ``ETH_KSZ8851SNL_DEFAULT_CONFIG`` configuration initialization macros are updated to accept new input parameters. Refer to :doc:`Ethernet API Reference Guide <../../../api-reference/network/esp_eth>` for an example of SPI-Ethernet Module initialization. +Ethernet Driver +--------------- + +APIs for creating MAC instances (`esp_eth_mac_new_*()`) have been reworked to accept two parameters, instead of one common configuration. Now, the configuration includes + +* Vendor specific MAC configuration +* Ethernet driver MAC configuration + +This is applicable to internal Ethernet MAC :cpp:func:`esp_eth_mac_new_esp32()` as well as to external MAC devices, such as :cpp:func:`esp_eth_mac_new_ksz8851snl()`, :cpp:func:`esp_eth_mac_new_dm9051()`, and :cpp:func:`esp_eth_mac_new_w5500()` .. _tcpip-adapter: diff --git a/docs/zh_CN/migration-guides/release-5.x/5.0/networking.rst b/docs/zh_CN/migration-guides/release-5.x/5.0/networking.rst index 412abc3dc26e..4293fd438c2c 100644 --- a/docs/zh_CN/migration-guides/release-5.x/5.0/networking.rst +++ b/docs/zh_CN/migration-guides/release-5.x/5.0/networking.rst @@ -83,6 +83,15 @@ SPI 以太网模块的初始化过程已经简化。此前,你需要在实例 现在,SPI 设备已在内部分配,因此无需再调用 :cpp:func:`spi_bus_add_device`。:cpp:class:`eth_dm9051_config_t`、:cpp:class:`eth_w5500_config_t` 和 :cpp:class:`eth_ksz8851snl_config_t` 配置结构体现已包含 SPI 设备配置成员(例如,可以微调可能依赖 PCB 设计的 SPI 时序)。``ETH_DM9051_DEFAULT_CONFIG``、``ETH_W5500_DEFAULT_CONFIG`` 和 ``ETH_KSZ8851SNL_DEFAULT_CONFIG`` 配置初始化宏也已接受新的参数输入。了解 SPI 以太网模块初始化示例,请查看 :doc:`以太网 API 参考指南<../../../api-reference/network/esp_eth>`。 +Ethernet 驱动 +---------------- + +用于创建 MAC 实例的 API (`esp_eth_mac_new_*()`) 的输入参数由一个配置参数改为两个,这两个参数用于 + +* 供应商特定的 MAC 配置 +* Ethernet 驱动 MAC 配置 + +该更新不仅适用于内部 Ethernet MAC :cpp:func:`esp_eth_mac_new_esp32()` 也适用于外部 MAC 设备,如 :cpp:func:`esp_eth_mac_new_ksz8851snl()`、 :cpp:func:`esp_eth_mac_new_dm9051()` 和 :cpp:func:`esp_eth_mac_new_w5500()`。 .. _tcpip-adapter: From 97526e92887527b5d7516d334eacba7d162ed35c Mon Sep 17 00:00:00 2001 From: Armando Date: Tue, 17 Oct 2023 18:54:13 +0800 Subject: [PATCH 094/161] feat(isp): isp af submodule low level driver --- components/hal/CMakeLists.txt | 4 + components/hal/esp32p4/include/hal/isp_ll.h | 724 ++++++++++++++++++ .../hal/include/hal/color_space_types.h | 31 + components/hal/include/hal/isp_hal.h | 75 ++ components/hal/include/hal/isp_types.h | 62 ++ components/hal/isp_hal.c | 62 ++ .../esp32p4/include/soc/Kconfig.soc_caps.in | 16 + .../soc/esp32p4/include/soc/clk_tree_defs.h | 17 + .../soc/esp32p4/include/soc/isp_struct.h | 5 +- components/soc/esp32p4/include/soc/soc_caps.h | 6 + 10 files changed, 1000 insertions(+), 2 deletions(-) create mode 100644 components/hal/esp32p4/include/hal/isp_ll.h create mode 100644 components/hal/include/hal/color_space_types.h create mode 100644 components/hal/include/hal/isp_hal.h create mode 100644 components/hal/include/hal/isp_types.h create mode 100644 components/hal/isp_hal.c diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index eb41bb2dcd54..58698a72195e 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -83,6 +83,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "i2c_hal.c" "i2c_hal_iram.c") endif() + if(CONFIG_SOC_ISP_SUPPORTED) + list(APPEND srcs "isp_hal.c") + endif() + if(CONFIG_SOC_RMT_SUPPORTED) list(APPEND srcs "rmt_hal.c") endif() diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h new file mode 100644 index 000000000000..33499ec5c44c --- /dev/null +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -0,0 +1,724 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "esp_attr.h" +#include "hal/misc.h" +#include "hal/assert.h" +#include "hal/isp_types.h" +#include "hal/color_space_types.h" +#include "soc/isp_struct.h" +#include "soc/hp_sys_clkrst_struct.h" +#include "soc/clk_tree_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ISP_LL_GET_HW(num) (((num) == 0) ? (&ISP) : NULL) + + +/*--------------------------------------------------------------- + INTR +---------------------------------------------------------------*/ +#define ISP_LL_EVENT_DATA_TYPE_ERR (1<<0) +#define ISP_LL_EVENT_ASYNC_FIFO_OVF (1<<1) +#define ISP_LL_EVENT_BUF_FULL (1<<2) +#define ISP_LL_EVENT_HVNUM_SETTING_ERR (1<<3) +#define ISP_LL_EVENT_DATA_TYPE_SETTING_ERR (1<<4) +#define ISP_LL_EVENT_MIPI_HNUM_UNMATCH (1<<5) +#define ISP_LL_EVENT_DPC_CHECK_DONE (1<<6) +#define ISP_LL_EVENT_GAMMA_XCOORD_ERR (1<<7) +#define ISP_LL_EVENT_AE_MONITOR (1<<8) +#define ISP_LL_EVENT_AE_FRAME_DONE (1<<9) +#define ISP_LL_EVENT_AF_FDONE (1<<10) +#define ISP_LL_EVENT_AF_ENV (1<<11) +#define ISP_LL_EVENT_AWB_FDONE (1<<12) +#define ISP_LL_EVENT_HIST_FDONE (1<<13) +#define ISP_LL_EVENT_FRAME (1<<14) +#define ISP_LL_EVENT_BLC_FRAME (1<<15) +#define ISP_LL_EVENT_LSC_FRAME (1<<16) +#define ISP_LL_EVENT_DPC_FRAME (1<<17) +#define ISP_LL_EVENT_BF_FRAME (1<<18) +#define ISP_LL_EVENT_DEMOSAIC_FRAME (1<<19) +#define ISP_LL_EVENT_MEDIAN_FRAME (1<<20) +#define ISP_LL_EVENT_CCM_FRAME (1<<21) +#define ISP_LL_EVENT_GAMMA_FRAME (1<<22) +#define ISP_LL_EVENT_RGB2YUV_FRAME (1<<23) +#define ISP_LL_EVENT_SHARP_FRAME (1<<24) +#define ISP_LL_EVENT_COLOR_FRAME (1<<25) +#define ISP_LL_EVENT_YUV2RGB_FRAME (1<<26) +#define ISP_LL_EVENT_TAIL_IDI_FRAME (1<<27) +#define ISP_LL_EVENT_HEADER_IDI_FRAME (1<<28) + +#define ISP_LL_EVENT_ALL_MASK (0x1FFFFFFF) +#define ISP_LL_EVENT_AF_MASK (ISP_LL_EVENT_AF_FDONE | ISP_LL_EVENT_AF_ENV) + +/*--------------------------------------------------------------- + AF +---------------------------------------------------------------*/ +#define ISP_LL_AF_WINDOW_MAX_RANGE ((1<<12) - 1) + + +/** + * @brief Env monitor mode + */ +typedef enum { + ISP_LL_AF_ENV_MONITOR_MODE_ABS, ///< Use absolute val for threshold + ISP_LL_AF_ENV_MONITOR_MODE_RATIO, ///< Use ratio val for threshold +} isp_ll_af_env_monitor_mode_t; + +/** + * @brief Edge monitor mode + */ +typedef enum { + ISP_LL_AF_EDGE_MONITOR_MODE_AUTO, ///< Auto set threshold + ISP_LL_AF_EDGE_MONITOR_MODE_MANUAL, ///< Manual set threshold +} isp_ll_af_edge_monitor_mode_t; + + +/*--------------------------------------------------------------- + Clock +---------------------------------------------------------------*/ +/** + * @brief Enable the bus clock for ISP module + * + * @param hw hardware instance address + * @param en enable / disable + */ +static inline void isp_ll_enable_module_clock(isp_dev_t *hw, bool en) +{ + HP_SYS_CLKRST.peri_clk_ctrl25.reg_isp_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 isp_ll_enable_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_enable_module_clock(__VA_ARGS__) + +/** + * @brief Reset the ISP module + * + * @param hw hardware instance address + */ +static inline void isp_ll_reset_module_clock(isp_dev_t *hw) +{ + HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_isp = 1; + HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_isp = 0; +} + +/// 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 isp_ll_reset_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_reset_module_clock(__VA_ARGS__) + +/** + * @brief Select ISP clock source + * + * @param hw hardware instance address + * @param clk_src clock source, see valid sources in type `soc_periph_isp_clk_src_t` + */ +static inline void isp_ll_select_clk_source(isp_dev_t *hw, soc_periph_isp_clk_src_t clk_src) +{ + uint32_t clk_val = 0; + switch (clk_src) { + case ISP_CLK_SRC_XTAL: + clk_val = 0; + break; + case ISP_CLK_SRC_PLL160: + clk_val = 1; + break; + case ISP_CLK_SRC_PLL240: + clk_val = 2; + break; + default: + HAL_ASSERT(false); + break; + } + + HP_SYS_CLKRST.peri_clk_ctrl25.reg_isp_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 isp_ll_select_clk_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_select_clk_source(__VA_ARGS__) + +/** + * @brief Set ISP clock div + * + * @param hw hardware instance address + * @param div divider value + */ +static inline void isp_ll_set_clock_div(isp_dev_t *hw, uint32_t div) +{ + HP_SYS_CLKRST.peri_clk_ctrl26.reg_isp_clk_div_num = div; +} + +/// 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 isp_ll_set_clock_div(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_set_clock_div(__VA_ARGS__) + +/*--------------------------------------------------------------- + Misc +---------------------------------------------------------------*/ +/** + * @brief Init ISP + * + * @param[in] hw + */ +static inline void isp_ll_init(isp_dev_t *hw) +{ + hw->cntl.val = 0; + hw->int_clr.val = ISP_LL_EVENT_ALL_MASK; + hw->int_ena.val = ~ISP_LL_EVENT_ALL_MASK; +} + +/** + * @brief Enable / Disable ISP clock + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_en = enable; +} + +/** + * @brief Enable / Disable ISP + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.isp_en = enable; +} + +/** + * @brief Set input data source + * + * @param[in] hw + * @param[in] source input data source, see `isp_input_data_source_t` + */ +static inline void isp_ll_set_input_data_source(isp_dev_t *hw, isp_input_data_source_t source) +{ + switch (source) { + case ISP_INPUT_DATA_SOURCE_CSI: + hw->cntl.isp_in_src = 0; + hw->cntl.mipi_data_en = 1; + break; + case ISP_INPUT_DATA_SOURCE_CAM: + hw->cntl.isp_in_src = 1; + hw->cntl.mipi_data_en = 0; + break; + case ISP_INPUT_DATA_SOURCE_DMA: + hw->cntl.isp_in_src = 2; + hw->cntl.mipi_data_en = 0; + break; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Set input data format + * + * @param[in] hw + * @param[in] format data format, see `color_space_pixel_format_t` + */ +static inline void isp_ll_set_input_data_format(isp_dev_t *hw, color_space_pixel_format_t format) +{ + switch (format) { + case COLOR_SPACE_RAW8: + hw->cntl.isp_data_type = 0; + break; + case COLOR_SPACE_RAW10: + hw->cntl.isp_data_type = 1; + break; + case COLOR_SPACE_RAW12: + hw->cntl.isp_data_type = 2; + break; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Set input data horizontal pixel number + * + * @param[in] hw + * @param[in] pixel_num number of pixels + */ +static inline void isp_ll_set_intput_data_h_pixel_num(isp_dev_t *hw, uint32_t pixel_num) +{ + hw->frame_cfg.hadr_num = pixel_num - 1; +} + +/** + * @brief Set input data vertical row number + * + * @param[in] hw + * @param[in] row_num number of rows + */ +static inline void isp_ll_set_intput_data_v_row_num(isp_dev_t *hw, uint32_t row_num) +{ + hw->frame_cfg.vadr_num = row_num - 1; +} + +/** + * @brief Set output data format + * + * @param[in] hw + * @param[in] format data format, see `color_space_pixel_format_t` + */ +static inline void isp_ll_set_output_data_format(isp_dev_t *hw, color_space_pixel_format_t format) +{ + switch (format) { + case COLOR_SPACE_RAW8: + hw->cntl.isp_out_type = 0; + hw->cntl.demosaic_en = 0; + hw->cntl.rgb2yuv_en = 0; + hw->cntl.yuv2rgb_en = 0; + break; + case COLOR_SPACE_YUV422: + hw->cntl.isp_out_type = 1; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 0; + break; + case COLOR_SPACE_RGB888: + hw->cntl.isp_out_type = 2; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 1; + break; + case COLOR_SPACE_YUV420: + hw->cntl.isp_out_type = 3; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 0; + break; + case COLOR_SPACE_RGB565: + hw->cntl.isp_out_type = 4; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 1; + break; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Set if line start packet exists + * + * @param[in] hw + * @param[in] en Enable / Disable + */ +static inline void isp_ll_enable_line_start_packet_exist(isp_dev_t *hw, bool en) +{ + hw->frame_cfg.hsync_start_exist = en; +} + +/** + * @brief Set if line end packet exists + * + * @param[in] hw + * @param[in] en Enable / Disable + */ +static inline void isp_ll_enable_line_end_packet_exist(isp_dev_t *hw, bool en) +{ + hw->frame_cfg.hsync_end_exist = en; +} + +/** + * @brief Get if demosaic is enabled + * + * @return True: enabled + */ +static inline bool isp_ll_get_demosaic_en(isp_dev_t *hw) +{ + return hw->cntl.demosaic_en; +} + +/** + * @brief Get if rgb2yuv is enabled + * + * @return True: enabled + */ +static inline bool isp_ll_get_rgb2yuv_en(isp_dev_t *hw) +{ + return hw->cntl.rgb2yuv_en; +} + +/*--------------------------------------------------------------- + AF +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable AF clock + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_af_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_af_force_on = enable; +} + +/** + * @brief Enable / Disable AF + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_af_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.af_en = enable; +} + +/** + * @brief Enable / Disable auto aupdate AF + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_af_enable_auto_update(isp_dev_t *hw, bool enable) +{ + hw->af_ctrl0.af_auto_update = enable; +} + +/** + * @brief Manual aupdate AF once + * + * @param[in] hw + */ +static inline void isp_ll_af_manual_update(isp_dev_t *hw) +{ + //self clear + hw->af_ctrl0.af_manual_update = 1; +} + +/** + * @brief Set edge thresh mode + * + * @param[in] hw + * @param[in] mode See `isp_ll_af_edge_monitor_mode_t` + */ +static inline void isp_ll_af_set_edge_thresh_mode(isp_dev_t *hw, isp_ll_af_edge_monitor_mode_t mode) +{ + if (mode == ISP_LL_AF_EDGE_MONITOR_MODE_AUTO) { + hw->af_threshold.af_threshold = 0; + } +} + +/** + * @brief Set edge threshold + * + * @param[in] hw + * @param[in] thresh Edge threshold + */ +static inline void isp_ll_af_set_edge_thresh(isp_dev_t *hw, uint32_t thresh) +{ + HAL_ASSERT(thresh != 0); + + hw->af_threshold.af_threshold = thresh; +} + +/** + * @brief Set auto edge thresh pixel num + * + * @param[in] hw + * @param[in] pixel_num Pixel numbers + */ +static inline void isp_ll_af_set_auto_edge_thresh_pixel_num(isp_dev_t *hw, uint32_t pixel_num) +{ + HAL_ASSERT(hw->af_threshold.af_threshold == 0); + + hw->af_ctrl1.af_thpixnum = pixel_num; +} + +/** + * @brief Set window range + * + * @param[in] hw + * @param[in] window_id Window ID + * @param[in] top_left_x Top left pixel x axis value + * @param[in] top_left_y Top left pixel y axis value + * @param[in] bottom_right_x Bottom right pixel x axis value + * @param[in] bottom_right_y Bottom right pixel y axis value + */ +static inline void isp_ll_af_set_window_range(isp_dev_t *hw, uint32_t window_id, uint32_t top_left_x, uint32_t top_left_y, uint32_t bottom_right_x, uint32_t bottom_right_y) +{ + HAL_ASSERT(top_left_x < ISP_LL_AF_WINDOW_MAX_RANGE && + top_left_y < ISP_LL_AF_WINDOW_MAX_RANGE && + bottom_right_x < ISP_LL_AF_WINDOW_MAX_RANGE && + bottom_right_y < ISP_LL_AF_WINDOW_MAX_RANGE); + + switch (window_id) { + case 0: + hw->af_hscale_a.af_lpoint_a = top_left_x; + hw->af_vscale_a.af_tpoint_a = top_left_y; + hw->af_hscale_a.af_rpoint_a = bottom_right_x; + hw->af_vscale_a.af_bpoint_a = bottom_right_y; + break; + case 1: + hw->af_hscale_b.af_lpoint_b = top_left_x; + hw->af_vscale_b.af_tpoint_b = top_left_y; + hw->af_hscale_b.af_rpoint_b = bottom_right_x; + hw->af_vscale_b.af_bpoint_b = bottom_right_y; + break; + case 2: + hw->af_hscale_c.af_lpoint_c = top_left_x; + hw->af_vscale_c.af_tpoint_c = top_left_y; + hw->af_hscale_c.af_rpoint_c = bottom_right_x; + hw->af_vscale_c.af_bpoint_c = bottom_right_y; + break; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Get window sum + * + * @param[in] hw + * @param[in] window_id Window ID + * + * @return Window sum + */ +static inline uint32_t isp_ll_af_get_window_sum(isp_dev_t *hw, uint32_t window_id) +{ + switch (window_id) { + case 0: + return hw->af_sum_a.af_suma; + case 1: + return hw->af_sum_b.af_sumb; + case 2: + return hw->af_sum_c.af_sumc; + default: + HAL_ASSERT(false); + } +} + +/** + * @brief Get window lum + * + * @param[in] hw + * @param[in] window_id Window ID + * + * @return Window lum + */ +static inline uint32_t isp_ll_af_get_window_lum(isp_dev_t *hw, uint32_t window_id) +{ + switch (window_id) { + case 0: + return hw->af_lum_a.af_luma; + case 1: + return hw->af_lum_b.af_lumb; + case 2: + return hw->af_lum_c.af_lumc; + default: + HAL_ASSERT(false); + } +} + +/*--------------------------------------------- + AF Env Monitor +----------------------------------------------*/ +/** + * @brief Set env monitor period + * + * @param[in] hw + * @param[in] period period of the env monitor, in frames + */ +static inline void isp_ll_af_env_monitor_set_period(isp_dev_t *hw, uint32_t period) +{ + hw->af_ctrl0.af_env_period = period; +} + +/** + * @brief Set env monitor mode + * + * @param[in] hw + * @param[in] mode See `isp_ll_af_env_monitor_mode_t` + */ +static inline void isp_ll_af_env_monitor_set_mode(isp_dev_t *hw, isp_ll_af_env_monitor_mode_t mode) +{ + if (mode == ISP_LL_AF_ENV_MONITOR_MODE_RATIO) { + hw->af_env_user_th_sum.af_env_user_threshold_sum = 0x0; + hw->af_env_user_th_lum.af_env_user_threshold_lum = 0x0; + } + + //nothing to do to if using abs mode, it'll be enabled after `isp_ll_af_env_monitor_set_thresh()` +} + +/** + * @brief Set env monitor threshold + * + * @param[in] hw + * @param[in] sum_thresh Threshold for definition + * @param[in] lum_thresh Threshold for luminance + */ +static inline void isp_ll_af_env_monitor_set_thresh(isp_dev_t *hw, uint32_t sum_thresh, uint32_t lum_thresh) +{ + HAL_ASSERT(sum_thresh != 0 || lum_thresh != 0); + + hw->af_env_user_th_sum.af_env_user_threshold_sum = sum_thresh; + hw->af_env_user_th_lum.af_env_user_threshold_lum = lum_thresh; +} + +/** + * @brief Set env monitor ratio + * + * @param[in] hw + * @param[in] ratio_val Threshold for ratio + */ +static inline void isp_ll_af_env_monitor_set_ratio(isp_dev_t *hw, uint32_t ratio_val) +{ + HAL_ASSERT(hw->af_env_user_th_sum.af_env_user_threshold_sum == 0 && + hw->af_env_user_th_lum.af_env_user_threshold_lum == 0); + + hw->af_ctrl0.af_env_threshold = ratio_val; +} + +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable BF clock + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_bf_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_bf_force_on = enable; +} + +/** + * @brief Enable / Disable BF + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_bf_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.bf_en = enable; +} + +/*--------------------------------------------------------------- + CCM +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable CCM clock + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_ccm_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_ccm_force_on = enable; +} + +/** + * @brief Enable / Disable CCM + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_ccm_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.ccm_en = enable; +} + +/*--------------------------------------------------------------- + Color +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable Color clock + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_color_clk_enable(isp_dev_t *hw, bool enable) +{ + hw->clk_en.clk_color_force_on = enable; +} + +/** + * @brief Enable / Disable Color + * + * @param[in] hw + * @param[in] enable Enable / Disable + */ +static inline void isp_ll_color_enable(isp_dev_t *hw, bool enable) +{ + hw->cntl.color_en = enable; +} + +/*--------------------------------------------------------------- + INTR +---------------------------------------------------------------*/ +/** + * @brief Enable / Disable interrupt + * + * @param[in] hw + * @param[in] mask INTR mask + * @param[in] enable Enable / disable + */ +__attribute__((always_inline)) +static inline void isp_ll_enable_intr(isp_dev_t *hw, uint32_t mask, bool enable) +{ + if (enable) { + hw->int_ena.val |= mask; + } else { + hw->int_ena.val &= ~mask; + } +} + +/** + * @brief Get interrupt status + * + * @param[in] hw + * + * @return Interrupt status + */ +__attribute__((always_inline)) +static inline uint32_t isp_ll_get_intr_status(isp_dev_t *hw) +{ + return hw->int_st.val; +} + +/** + * @brief Get interrupt raw + * + * @param[in] hw + * + * @return Interrupt raw + */ +__attribute__((always_inline)) +static inline uint32_t isp_ll_get_intr_raw(isp_dev_t *hw) +{ + return hw->int_raw.val; +} + +/** + * @brief Clear interrupt + * + * @param[in] hw + * @param[in] mask INTR mask + */ +__attribute__((always_inline)) +static inline void isp_ll_clear_intr(isp_dev_t *hw, uint32_t mask) +{ + hw->int_clr.val = mask; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/color_space_types.h b/components/hal/include/hal/color_space_types.h new file mode 100644 index 000000000000..9ed088c7063a --- /dev/null +++ b/components/hal/include/hal/color_space_types.h @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumeration of pixel color space format + */ +typedef enum { + COLOR_SPACE_RAW8, /*!< 8 bits per pixel */ + COLOR_SPACE_RAW10, /*!< 10 bits per pixel */ + COLOR_SPACE_RAW12, /*!< 12 bits per pixel */ + COLOR_SPACE_RGB888, /*!< 24 bits, 8 bits per R/G/B value */ + COLOR_SPACE_RGB565, /*!< 16 bits, 5 bits per R/B value, 6 bits for G value */ + COLOR_SPACE_YUV422, /*!< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels */ + COLOR_SPACE_YUV420, /*!< 12 bits, 8-bit Y per pixel, 8-bit U and V per four pixels */ +} color_space_pixel_format_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/isp_hal.h b/components/hal/include/hal/isp_hal.h new file mode 100644 index 000000000000..80ea6db9de58 --- /dev/null +++ b/components/hal/include/hal/isp_hal.h @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The hal is not public api, don't use in application code. + * See readme.md in hal/include/hal/readme.md + ******************************************************************************/ + +#pragma once + +#include +#include "hal/isp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Context that should be maintained by both the driver and the HAL + */ +typedef struct { + void *hw; ///< Beginning address of the ISP registers +} isp_hal_context_t; + +/** + * @brief Init the ISP hal and set the ISP to the default configuration. + * + * @note This function should be called first before other hal layer function is called. + * + * @param[in] hal Context of the HAL layer + * @param[in] isp_id ISP ID + */ +void isp_hal_init(isp_hal_context_t *hal, int isp_id); + + +/*--------------------------------------------------------------- + AF +---------------------------------------------------------------*/ +/** + * @brief Configure AF window + * + * @param[in] hal Context of the HAL layer + * @param[in] window_id Window ID + * @param[in] window Window info, see `isp_af_window_t` + */ +void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_af_window_t *window); + +/** + * @brief Get AF oneshot result + * + * @param[in] hal Context of the HAL layer + * @param[out] out_res AF result + */ +void isp_hal_af_get_oneshot_result(const isp_hal_context_t *hal, isp_af_result_t *out_res); + +/*--------------------------------------------------------------- + INTR +---------------------------------------------------------------*/ +/** + * @brief Clear ISP HW intr event + * + * @param[in] hal Context of the HAL layer + * @param[in] mask HW event mask + */ +uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t mask); + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/isp_types.h b/components/hal/include/hal/isp_types.h new file mode 100644 index 000000000000..65c7cb483e23 --- /dev/null +++ b/components/hal/include/hal/isp_types.h @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" +#include "soc/clk_tree_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------- + Misc +---------------------------------------------------------------*/ +#if SOC_ISP_SUPPORTED +typedef soc_periph_isp_clk_src_t isp_clk_src_t; ///< Clock source type of ISP +#else +typedef int isp_clk_src_t; ///< Default type +#endif + +/** + * @brief ISP Input Source + */ +typedef enum { + ISP_INPUT_DATA_SOURCE_CSI, ///< Input data from CSI + ISP_INPUT_DATA_SOURCE_CAM, ///< Input data from CAM + ISP_INPUT_DATA_SOURCE_DWDMA, ///< Input data from DW-DMA +} isp_input_data_source_t; + +/*--------------------------------------------------------------- + AF +---------------------------------------------------------------*/ +/** + * @brief ISP AF window + */ +typedef struct { + uint32_t top_left_x; ///< Top left x axis value + uint32_t top_left_y; ///< Top left y axis value + uint32_t bottom_right_x; ///< Bottom right x axis value + uint32_t bottom_right_y; ///< Bottom right y axis value +} isp_af_window_t; + + +/** + * @brief ISP AF result + */ +typedef struct { +#if SOC_ISP_SUPPORTED + uint32_t definition[SOC_ISP_AF_WINDOW_NUMS]; ///< Definition + uint32_t luminance[SOC_ISP_AF_WINDOW_NUMS]; ///< Luminance +#endif +} isp_af_result_t; + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/isp_hal.c b/components/hal/isp_hal.c new file mode 100644 index 000000000000..6fb72413a999 --- /dev/null +++ b/components/hal/isp_hal.c @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "sdkconfig.h" +#include "soc/soc_caps.h" +#include "hal/assert.h" +#include "hal/log.h" +#include "hal/isp_hal.h" +#include "hal/isp_ll.h" + +/** + * ISP HAL layer + */ +void isp_hal_init(isp_hal_context_t *hal, int isp_id) +{ + //ISP hardware instance + hal->hw = ISP_LL_GET_HW(isp_id); + isp_ll_init(hal->hw); +} + + +/*--------------------------------------------------------------- + AF +---------------------------------------------------------------*/ +void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_af_window_t *window) +{ + isp_ll_af_set_window_range(hal->hw, window_id, window->top_left_x, window->top_left_y, window->bottom_right_x, window->bottom_right_y); +} + +void isp_hal_af_get_oneshot_result(const isp_hal_context_t *hal, isp_af_result_t *out_res) +{ + isp_ll_clear_intr(hal->hw, ISP_LL_EVENT_AF_FDONE); + isp_ll_af_manual_update(hal->hw); + + while (!(isp_ll_get_intr_raw(hal->hw) & ISP_LL_EVENT_AF_FDONE)) { + ; + } + + for (int i = 0; i < SOC_ISP_AF_WINDOW_NUMS; i++) { + out_res->definition[i] = isp_ll_af_get_window_sum(hal->hw, i); + out_res->luminance[i] = isp_ll_af_get_window_lum(hal->hw, i); + } +} + + +/*--------------------------------------------------------------- + INTR, put in iram +---------------------------------------------------------------*/ +uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t mask) +{ + uint32_t triggered_events = isp_ll_get_intr_status(hal->hw) & mask; + + if (triggered_events) { + isp_ll_clear_intr(hal->hw, triggered_events); + } + + return triggered_events; +} diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index e980bda57a20..a46faeba1208 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -555,6 +555,22 @@ config SOC_I2S_TDM_FULL_DATA_WIDTH bool default y +config SOC_ISP_NUMS + int + default 1 + +config SOC_ISP_AF_CTRLR_NUMS + int + default 1 + +config SOC_ISP_AF_ENV_DETECTOR_NUMS + int + default 1 + +config SOC_ISP_AF_WINDOW_NUMS + int + default 3 + config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK bool default y diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index c218ff496e3e..90f56146d0b3 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32p4/include/soc/clk_tree_defs.h @@ -443,6 +443,23 @@ typedef enum { FLASH_CLK_SRC_SPLL = SOC_MOD_CLK_SPLL, /*!< Select SOC_MOD_CLK_SPLL as FLASH source clock */ } soc_periph_flash_clk_src_t; +/////////////////////////////////////////////////ISP//////////////////////////////////////////////////////////////////// + +/** + * @brief Array initializer for all supported clock sources of ISP + */ +#define SOC_ISP_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_PLL_F240M} + +/** + * @brief Type of ISP clock source. + */ +typedef enum { + ISP_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select SOC_MOD_CLK_PLL_F160M as ISP source clock */ + ISP_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select SOC_MOD_CLK_XTAL as ISP source clock */ + ISP_CLK_SRC_PLL160 = SOC_MOD_CLK_PLL_F160M, /*!< Select SOC_MOD_CLK_PLL_F160M as ISP source clock */ + ISP_CLK_SRC_PLL240 = SOC_MOD_CLK_PLL_F240M, /*!< Select SOC_MOD_CLK_PLL_F240M as ISP source clock */ +} soc_periph_isp_clk_src_t; + //////////////////////////////////////////////////SDM////////////////////////////////////////////////////////////// //////////////////////////////////////////////////GPIO Glitch Filter//////////////////////////////////////////////////// diff --git a/components/soc/esp32p4/include/soc/isp_struct.h b/components/soc/esp32p4/include/soc/isp_struct.h index acb3c4a465fb..980103687bfc 100644 --- a/components/soc/esp32p4/include/soc/isp_struct.h +++ b/components/soc/esp32p4/include/soc/isp_struct.h @@ -247,11 +247,11 @@ typedef union { */ uint32_t bayer_mode:2; /** hsync_start_exist : R/W; bitpos: [29]; default: 1; - * this bit configures the line end packet exist or not. 0: not exist, 1: exist + * this bit configures the line end start exist or not. 0: not exist, 1: exist */ uint32_t hsync_start_exist:1; /** hsync_end_exist : R/W; bitpos: [30]; default: 1; - * this bit configures the line start packet exist or not. 0: not exist, 1: exist + * this bit configures the line end packet exist or not. 0: not exist, 1: exist */ uint32_t hsync_end_exist:1; uint32_t reserved_31:1; @@ -3857,6 +3857,7 @@ typedef struct { volatile isp_rdn_eco_high_reg_t rdn_eco_high; } isp_dev_t; +extern isp_dev_t ISP; #ifndef __cplusplus _Static_assert(sizeof(isp_dev_t) == 0x244, "Invalid size of isp_dev_t structure"); diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 7e03ccbbb848..4a1615b5f470 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -267,6 +267,12 @@ #define SOC_I2S_PDM_MAX_RX_LINES (4) // On I2S0 #define SOC_I2S_TDM_FULL_DATA_WIDTH (1) /*!< No limitation to data bit width when using multiple slots */ +/*-------------------------- ISP CAPS ----------------------------------------*/ +#define SOC_ISP_NUMS 1U +#define SOC_ISP_AF_CTRLR_NUMS 1U +#define SOC_ISP_AF_ENV_DETECTOR_NUMS 1U +#define SOC_ISP_AF_WINDOW_NUMS 3 + /*-------------------------- LEDC CAPS ---------------------------------------*/ #define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1) #define SOC_LEDC_SUPPORT_XTAL_CLOCK (1) From 7efcf06c5d4f1d568260e9b27467c209281862f8 Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 26 Oct 2023 11:17:13 +0800 Subject: [PATCH 095/161] change(ll): update color space types, ll changes --- components/hal/esp32p4/include/hal/isp_ll.h | 228 ++++++++++-------- .../hal/include/hal/color_space_types.h | 31 --- components/hal/include/hal/color_types.h | 92 +++++++ components/hal/include/hal/isp_types.h | 26 +- .../esp32p4/include/soc/Kconfig.soc_caps.in | 2 +- components/soc/esp32p4/include/soc/soc_caps.h | 2 +- 6 files changed, 246 insertions(+), 135 deletions(-) delete mode 100644 components/hal/include/hal/color_space_types.h create mode 100644 components/hal/include/hal/color_types.h diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index 33499ec5c44c..96633369b2db 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -11,7 +11,7 @@ #include "hal/misc.h" #include "hal/assert.h" #include "hal/isp_types.h" -#include "hal/color_space_types.h" +#include "hal/color_types.h" #include "soc/isp_struct.h" #include "soc/hp_sys_clkrst_struct.h" #include "soc/clk_tree_defs.h" @@ -89,7 +89,7 @@ typedef enum { /** * @brief Enable the bus clock for ISP module * - * @param hw hardware instance address + * @param hw Hardware instance address * @param en enable / disable */ static inline void isp_ll_enable_module_clock(isp_dev_t *hw, bool en) @@ -104,7 +104,7 @@ static inline void isp_ll_enable_module_clock(isp_dev_t *hw, bool en) /** * @brief Reset the ISP module * - * @param hw hardware instance address + * @param hw Hardware instance address */ static inline void isp_ll_reset_module_clock(isp_dev_t *hw) { @@ -119,7 +119,7 @@ static inline void isp_ll_reset_module_clock(isp_dev_t *hw) /** * @brief Select ISP clock source * - * @param hw hardware instance address + * @param hw Hardware instance address * @param clk_src clock source, see valid sources in type `soc_periph_isp_clk_src_t` */ static inline void isp_ll_select_clk_source(isp_dev_t *hw, soc_periph_isp_clk_src_t clk_src) @@ -150,7 +150,7 @@ static inline void isp_ll_select_clk_source(isp_dev_t *hw, soc_periph_isp_clk_sr /** * @brief Set ISP clock div * - * @param hw hardware instance address + * @param hw Hardware instance address * @param div divider value */ static inline void isp_ll_set_clock_div(isp_dev_t *hw, uint32_t div) @@ -168,7 +168,7 @@ static inline void isp_ll_set_clock_div(isp_dev_t *hw, uint32_t div) /** * @brief Init ISP * - * @param[in] hw + * @param[in] hw Hardware instance address */ static inline void isp_ll_init(isp_dev_t *hw) { @@ -180,7 +180,7 @@ static inline void isp_ll_init(isp_dev_t *hw) /** * @brief Enable / Disable ISP clock * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_clk_enable(isp_dev_t *hw, bool enable) @@ -191,7 +191,7 @@ static inline void isp_ll_clk_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable ISP * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_enable(isp_dev_t *hw, bool enable) @@ -202,7 +202,7 @@ static inline void isp_ll_enable(isp_dev_t *hw, bool enable) /** * @brief Set input data source * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] source input data source, see `isp_input_data_source_t` */ static inline void isp_ll_set_input_data_source(isp_dev_t *hw, isp_input_data_source_t source) @@ -212,11 +212,11 @@ static inline void isp_ll_set_input_data_source(isp_dev_t *hw, isp_input_data_so hw->cntl.isp_in_src = 0; hw->cntl.mipi_data_en = 1; break; - case ISP_INPUT_DATA_SOURCE_CAM: + case ISP_INPUT_DATA_SOURCE_DVP: hw->cntl.isp_in_src = 1; hw->cntl.mipi_data_en = 0; break; - case ISP_INPUT_DATA_SOURCE_DMA: + case ISP_INPUT_DATA_SOURCE_DWGDMA: hw->cntl.isp_in_src = 2; hw->cntl.mipi_data_en = 0; break; @@ -226,32 +226,43 @@ static inline void isp_ll_set_input_data_source(isp_dev_t *hw, isp_input_data_so } /** - * @brief Set input data format + * @brief Set input data color format * - * @param[in] hw - * @param[in] format data format, see `color_space_pixel_format_t` + * @param[in] hw Hardware instance address + * @param[in] format color format, see `color_space_pixel_format_t` + * + * @return true for valid format, false for invalid format */ -static inline void isp_ll_set_input_data_format(isp_dev_t *hw, color_space_pixel_format_t format) +static inline bool isp_ll_set_input_data_color_format(isp_dev_t *hw, color_space_pixel_format_t format) { - switch (format) { - case COLOR_SPACE_RAW8: - hw->cntl.isp_data_type = 0; - break; - case COLOR_SPACE_RAW10: - hw->cntl.isp_data_type = 1; - break; - case COLOR_SPACE_RAW12: - hw->cntl.isp_data_type = 2; - break; - default: - HAL_ASSERT(false); + bool valid = false; + + if (format.color_space == COLOR_SPACE_RAW) { + switch(format.pixel_format) { + case COLOR_PIXEL_RAW8: + hw->cntl.isp_data_type = 0; + valid = true; + break; + case COLOR_PIXEL_RAW10: + hw->cntl.isp_data_type = 1; + valid = true; + break; + case COLOR_PIXEL_RAW12: + hw->cntl.isp_data_type = 2; + valid = true; + break; + default: + break; + } } + + return valid; } /** * @brief Set input data horizontal pixel number * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] pixel_num number of pixels */ static inline void isp_ll_set_intput_data_h_pixel_num(isp_dev_t *hw, uint32_t pixel_num) @@ -262,7 +273,7 @@ static inline void isp_ll_set_intput_data_h_pixel_num(isp_dev_t *hw, uint32_t pi /** * @brief Set input data vertical row number * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] row_num number of rows */ static inline void isp_ll_set_intput_data_v_row_num(isp_dev_t *hw, uint32_t row_num) @@ -271,53 +282,76 @@ static inline void isp_ll_set_intput_data_v_row_num(isp_dev_t *hw, uint32_t row_ } /** - * @brief Set output data format - * - * @param[in] hw - * @param[in] format data format, see `color_space_pixel_format_t` - */ -static inline void isp_ll_set_output_data_format(isp_dev_t *hw, color_space_pixel_format_t format) -{ - switch (format) { - case COLOR_SPACE_RAW8: - hw->cntl.isp_out_type = 0; - hw->cntl.demosaic_en = 0; - hw->cntl.rgb2yuv_en = 0; - hw->cntl.yuv2rgb_en = 0; - break; - case COLOR_SPACE_YUV422: - hw->cntl.isp_out_type = 1; - hw->cntl.demosaic_en = 1; - hw->cntl.rgb2yuv_en = 1; - hw->cntl.yuv2rgb_en = 0; - break; - case COLOR_SPACE_RGB888: - hw->cntl.isp_out_type = 2; - hw->cntl.demosaic_en = 1; - hw->cntl.rgb2yuv_en = 1; - hw->cntl.yuv2rgb_en = 1; - break; - case COLOR_SPACE_YUV420: - hw->cntl.isp_out_type = 3; - hw->cntl.demosaic_en = 1; - hw->cntl.rgb2yuv_en = 1; - hw->cntl.yuv2rgb_en = 0; - break; - case COLOR_SPACE_RGB565: - hw->cntl.isp_out_type = 4; - hw->cntl.demosaic_en = 1; - hw->cntl.rgb2yuv_en = 1; - hw->cntl.yuv2rgb_en = 1; - break; - default: - HAL_ASSERT(false); + * @brief Set output data color format + * + * @param[in] hw Hardware instance address + * @param[in] format color format, see `color_space_pixel_format_t` + * + * @return true for valid format, false for invalid format + */ +static inline bool isp_ll_set_output_data_color_format(isp_dev_t *hw, color_space_pixel_format_t format) +{ + bool valid = false; + + if (format.color_space == COLOR_SPACE_RAW) { + switch(format.pixel_format) { + case COLOR_PIXEL_RAW8: + hw->cntl.isp_out_type = 0; + hw->cntl.demosaic_en = 0; + hw->cntl.rgb2yuv_en = 0; + hw->cntl.yuv2rgb_en = 0; + valid = true; + break; + default: + break; + } + } else if (format.color_space == COLOR_SPACE_RGB) { + switch(format.pixel_format) { + case COLOR_PIXEL_RGB888: + hw->cntl.isp_out_type = 2; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 1; + valid = true; + break; + case COLOR_PIXEL_RGB565: + hw->cntl.isp_out_type = 4; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 1; + valid = true; + break; + default: + break; + } + } else if (format.color_space == COLOR_SPACE_YUV) { + switch(format.pixel_format) { + case COLOR_PIXEL_YUV422: + hw->cntl.isp_out_type = 1; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 0; + valid = true; + break; + case COLOR_PIXEL_YUV420: + hw->cntl.isp_out_type = 3; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 0; + valid = true; + break; + default: + break; + } } + + return valid; } /** * @brief Set if line start packet exists * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] en Enable / Disable */ static inline void isp_ll_enable_line_start_packet_exist(isp_dev_t *hw, bool en) @@ -328,7 +362,7 @@ static inline void isp_ll_enable_line_start_packet_exist(isp_dev_t *hw, bool en) /** * @brief Set if line end packet exists * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] en Enable / Disable */ static inline void isp_ll_enable_line_end_packet_exist(isp_dev_t *hw, bool en) @@ -339,9 +373,11 @@ static inline void isp_ll_enable_line_end_packet_exist(isp_dev_t *hw, bool en) /** * @brief Get if demosaic is enabled * + * @param[in] hw Hardware instance address + * * @return True: enabled */ -static inline bool isp_ll_get_demosaic_en(isp_dev_t *hw) +static inline bool isp_ll_is_demosaic_enabled(isp_dev_t *hw) { return hw->cntl.demosaic_en; } @@ -349,9 +385,11 @@ static inline bool isp_ll_get_demosaic_en(isp_dev_t *hw) /** * @brief Get if rgb2yuv is enabled * + * @param[in] hw Hardware instance address + * * @return True: enabled */ -static inline bool isp_ll_get_rgb2yuv_en(isp_dev_t *hw) +static inline bool isp_ll_is_rgb2yuv_enabled(isp_dev_t *hw) { return hw->cntl.rgb2yuv_en; } @@ -373,7 +411,7 @@ static inline void isp_ll_af_clk_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable AF * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_af_enable(isp_dev_t *hw, bool enable) @@ -395,7 +433,7 @@ static inline void isp_ll_af_enable_auto_update(isp_dev_t *hw, bool enable) /** * @brief Manual aupdate AF once * - * @param[in] hw + * @param[in] hw Hardware instance address */ static inline void isp_ll_af_manual_update(isp_dev_t *hw) { @@ -406,7 +444,7 @@ static inline void isp_ll_af_manual_update(isp_dev_t *hw) /** * @brief Set edge thresh mode * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] mode See `isp_ll_af_edge_monitor_mode_t` */ static inline void isp_ll_af_set_edge_thresh_mode(isp_dev_t *hw, isp_ll_af_edge_monitor_mode_t mode) @@ -419,7 +457,7 @@ static inline void isp_ll_af_set_edge_thresh_mode(isp_dev_t *hw, isp_ll_af_edge_ /** * @brief Set edge threshold * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] thresh Edge threshold */ static inline void isp_ll_af_set_edge_thresh(isp_dev_t *hw, uint32_t thresh) @@ -432,7 +470,7 @@ static inline void isp_ll_af_set_edge_thresh(isp_dev_t *hw, uint32_t thresh) /** * @brief Set auto edge thresh pixel num * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] pixel_num Pixel numbers */ static inline void isp_ll_af_set_auto_edge_thresh_pixel_num(isp_dev_t *hw, uint32_t pixel_num) @@ -445,7 +483,7 @@ static inline void isp_ll_af_set_auto_edge_thresh_pixel_num(isp_dev_t *hw, uint3 /** * @brief Set window range * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] window_id Window ID * @param[in] top_left_x Top left pixel x axis value * @param[in] top_left_y Top left pixel y axis value @@ -486,7 +524,7 @@ static inline void isp_ll_af_set_window_range(isp_dev_t *hw, uint32_t window_id, /** * @brief Get window sum * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] window_id Window ID * * @return Window sum @@ -508,7 +546,7 @@ static inline uint32_t isp_ll_af_get_window_sum(isp_dev_t *hw, uint32_t window_i /** * @brief Get window lum * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] window_id Window ID * * @return Window lum @@ -533,7 +571,7 @@ static inline uint32_t isp_ll_af_get_window_lum(isp_dev_t *hw, uint32_t window_i /** * @brief Set env monitor period * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] period period of the env monitor, in frames */ static inline void isp_ll_af_env_monitor_set_period(isp_dev_t *hw, uint32_t period) @@ -544,7 +582,7 @@ static inline void isp_ll_af_env_monitor_set_period(isp_dev_t *hw, uint32_t peri /** * @brief Set env monitor mode * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] mode See `isp_ll_af_env_monitor_mode_t` */ static inline void isp_ll_af_env_monitor_set_mode(isp_dev_t *hw, isp_ll_af_env_monitor_mode_t mode) @@ -560,7 +598,7 @@ static inline void isp_ll_af_env_monitor_set_mode(isp_dev_t *hw, isp_ll_af_env_m /** * @brief Set env monitor threshold * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] sum_thresh Threshold for definition * @param[in] lum_thresh Threshold for luminance */ @@ -575,7 +613,7 @@ static inline void isp_ll_af_env_monitor_set_thresh(isp_dev_t *hw, uint32_t sum_ /** * @brief Set env monitor ratio * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] ratio_val Threshold for ratio */ static inline void isp_ll_af_env_monitor_set_ratio(isp_dev_t *hw, uint32_t ratio_val) @@ -592,7 +630,7 @@ static inline void isp_ll_af_env_monitor_set_ratio(isp_dev_t *hw, uint32_t ratio /** * @brief Enable / Disable BF clock * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_bf_clk_enable(isp_dev_t *hw, bool enable) @@ -603,7 +641,7 @@ static inline void isp_ll_bf_clk_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable BF * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_bf_enable(isp_dev_t *hw, bool enable) @@ -617,7 +655,7 @@ static inline void isp_ll_bf_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable CCM clock * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_ccm_clk_enable(isp_dev_t *hw, bool enable) @@ -628,7 +666,7 @@ static inline void isp_ll_ccm_clk_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable CCM * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_ccm_enable(isp_dev_t *hw, bool enable) @@ -642,7 +680,7 @@ static inline void isp_ll_ccm_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable Color clock * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_color_clk_enable(isp_dev_t *hw, bool enable) @@ -653,7 +691,7 @@ static inline void isp_ll_color_clk_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable Color * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_color_enable(isp_dev_t *hw, bool enable) @@ -667,7 +705,7 @@ static inline void isp_ll_color_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable interrupt * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] mask INTR mask * @param[in] enable Enable / disable */ @@ -684,7 +722,7 @@ static inline void isp_ll_enable_intr(isp_dev_t *hw, uint32_t mask, bool enable) /** * @brief Get interrupt status * - * @param[in] hw + * @param[in] hw Hardware instance address * * @return Interrupt status */ @@ -697,7 +735,7 @@ static inline uint32_t isp_ll_get_intr_status(isp_dev_t *hw) /** * @brief Get interrupt raw * - * @param[in] hw + * @param[in] hw Hardware instance address * * @return Interrupt raw */ @@ -710,7 +748,7 @@ static inline uint32_t isp_ll_get_intr_raw(isp_dev_t *hw) /** * @brief Clear interrupt * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] mask INTR mask */ __attribute__((always_inline)) diff --git a/components/hal/include/hal/color_space_types.h b/components/hal/include/hal/color_space_types.h deleted file mode 100644 index 9ed088c7063a..000000000000 --- a/components/hal/include/hal/color_space_types.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include "hal/assert.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Enumeration of pixel color space format - */ -typedef enum { - COLOR_SPACE_RAW8, /*!< 8 bits per pixel */ - COLOR_SPACE_RAW10, /*!< 10 bits per pixel */ - COLOR_SPACE_RAW12, /*!< 12 bits per pixel */ - COLOR_SPACE_RGB888, /*!< 24 bits, 8 bits per R/G/B value */ - COLOR_SPACE_RGB565, /*!< 16 bits, 5 bits per R/B value, 6 bits for G value */ - COLOR_SPACE_YUV422, /*!< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels */ - COLOR_SPACE_YUV420, /*!< 12 bits, 8-bit Y per pixel, 8-bit U and V per four pixels */ -} color_space_pixel_format_t; - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/include/hal/color_types.h b/components/hal/include/hal/color_types.h new file mode 100644 index 000000000000..e213216fb5e7 --- /dev/null +++ b/components/hal/include/hal/color_types.h @@ -0,0 +1,92 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @background + * + * Color Space: a specific representation of colors, e.g. RGB, YUV, etc. + * Color Pixel Format: a specific pixel format of a certain color space, e.g. RGB565, YUV422, etc. + */ + +/*--------------------------------------------------------------- + Color Space +---------------------------------------------------------------*/ +/** + * @brief Color Space + */ +typedef enum { + COLOR_SPACE_RAW, ///< Color space raw + COLOR_SPACE_RGB, ///< Color space rgb + COLOR_SPACE_YUV, ///< Color space yuv + COLOR_SPACE_GRAY, ///< Color space gray +} color_space_t; + +/*--------------------------------------------------------------- + Color Space Format +---------------------------------------------------------------*/ +/** + * @brief Raw Format + */ +typedef enum { + COLOR_PIXEL_RAW8, ///< 8 bits per pixel + COLOR_PIXEL_RAW10, ///< 10 bits per pixel + COLOR_PIXEL_RAW12, ///< 12 bits per pixel +} color_pixel_raw_format_t; + +/** + * @brief RGB Format + */ +typedef enum { + COLOR_PIXEL_RGB888, ///< 24 bits, 8 bits per R/G/B value + COLOR_PIXEL_RGB565, ///< 16 bits, 5 bits per R/B value, 6 bits for G value +} color_pixel_rgb_format_t; + +/** + * @brief YUV Format + */ +typedef enum { + COLOR_PIXEL_YUV444, ///< 24 bits, 8 bits per Y/U/V value + COLOR_PIXEL_YUV422, ///< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels + COLOR_PIXEL_YUV420, ///< 12 bits, 8-bit Y per pixel, 8-bit U and V per four pixels +} color_pixel_yuv_format_t; + +/** + * @brief Gray Format + */ +typedef enum { + COLOR_PIXEL_GRAY4, ///< 4 bits, grayscale + COLOR_PIXEL_GRAY8, ///< 8 bits, grayscale +} color_pixel_gray_format_t; + +/*--------------------------------------------------------------- + Color Space Struct Type +---------------------------------------------------------------*/ +#define COLOR_PIXEL_FORMAT_BITWIDTH 24 ///< Bitwidth of the `color_space_format_t:pixel_format` field +#define COLOR_SPACE_BITWIDTH 8 ///< Bitwidth of the `color_space_format_t:color_space` field + +/** + * @brief Color Space Info Structure + */ +typedef union { + struct { + uint32_t pixel_format: COLOR_PIXEL_FORMAT_BITWIDTH; ///< Format of a certain color space type + uint32_t color_space: COLOR_SPACE_BITWIDTH; ///< Color space type + }; + uint32_t color_type_id; ///< Unique type of a certain color pixel format +} color_space_pixel_format_t; + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/isp_types.h b/components/hal/include/hal/isp_types.h index 65c7cb483e23..27d7e0bc129b 100644 --- a/components/hal/include/hal/isp_types.h +++ b/components/hal/include/hal/isp_types.h @@ -6,9 +6,9 @@ #pragma once -#include #include "soc/soc_caps.h" #include "soc/clk_tree_defs.h" +#include "hal/color_types.h" #ifdef __cplusplus extern "C" { @@ -27,11 +27,24 @@ typedef int isp_clk_src_t; ///< Default type * @brief ISP Input Source */ typedef enum { - ISP_INPUT_DATA_SOURCE_CSI, ///< Input data from CSI - ISP_INPUT_DATA_SOURCE_CAM, ///< Input data from CAM - ISP_INPUT_DATA_SOURCE_DWDMA, ///< Input data from DW-DMA + ISP_INPUT_DATA_SOURCE_CSI, ///< Input data from CSI + ISP_INPUT_DATA_SOURCE_DVP, ///< Input data from DVP + ISP_INPUT_DATA_SOURCE_DWGDMA, ///< Input data from DW-GDMA } isp_input_data_source_t; +/** + * @brief ISP Color Type + */ +typedef enum { + ISP_COLOR_RAW8 = (COLOR_SPACE_RAW << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RAW8, ///< RAW8 + ISP_COLOR_RAW10 = (COLOR_SPACE_RAW << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RAW10, ///< RAW10 + ISP_COLOR_RAW12 = (COLOR_SPACE_RAW << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RAW12, ///< RAW12 + ISP_COLOR_RGB888 = (COLOR_SPACE_RGB << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RGB888, ///< RGB888 + ISP_COLOR_RGB565 = (COLOR_SPACE_RGB << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RGB565, ///< RGB565 + ISP_COLOR_YUV422 = (COLOR_SPACE_YUV << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_YUV422, ///< YUV422 + ISP_COLOR_YUV420 = (COLOR_SPACE_YUV << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_YUV420, ///< YUV420 +} isp_color_t; + /*--------------------------------------------------------------- AF ---------------------------------------------------------------*/ @@ -45,14 +58,13 @@ typedef struct { uint32_t bottom_right_y; ///< Bottom right y axis value } isp_af_window_t; - /** * @brief ISP AF result */ typedef struct { #if SOC_ISP_SUPPORTED - uint32_t definition[SOC_ISP_AF_WINDOW_NUMS]; ///< Definition - uint32_t luminance[SOC_ISP_AF_WINDOW_NUMS]; ///< Luminance + int definition[SOC_ISP_AF_WINDOW_NUMS]; ///< Definition, it refers how clear and sharp an image is + int luminance[SOC_ISP_AF_WINDOW_NUMS]; ///< Luminance, it refers how luminant an image is #endif } isp_af_result_t; diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index a46faeba1208..ded76ad0fb9c 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -559,7 +559,7 @@ config SOC_ISP_NUMS int default 1 -config SOC_ISP_AF_CTRLR_NUMS +config SOC_ISP_AF_CTLR_NUMS int default 1 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 4a1615b5f470..f351f934b848 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -269,7 +269,7 @@ /*-------------------------- ISP CAPS ----------------------------------------*/ #define SOC_ISP_NUMS 1U -#define SOC_ISP_AF_CTRLR_NUMS 1U +#define SOC_ISP_AF_CTLR_NUMS 1U #define SOC_ISP_AF_ENV_DETECTOR_NUMS 1U #define SOC_ISP_AF_WINDOW_NUMS 3 From 16d8b7df41b4255cb7728d829d327334d628431a Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 30 Oct 2023 15:29:17 +0800 Subject: [PATCH 096/161] feat(color): added helper to get color space and color pixel format --- components/hal/include/hal/color_types.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/components/hal/include/hal/color_types.h b/components/hal/include/hal/color_types.h index e213216fb5e7..5890da3f42a3 100644 --- a/components/hal/include/hal/color_types.h +++ b/components/hal/include/hal/color_types.h @@ -72,8 +72,14 @@ typedef enum { /*--------------------------------------------------------------- Color Space Struct Type ---------------------------------------------------------------*/ -#define COLOR_PIXEL_FORMAT_BITWIDTH 24 ///< Bitwidth of the `color_space_format_t:pixel_format` field -#define COLOR_SPACE_BITWIDTH 8 ///< Bitwidth of the `color_space_format_t:color_space` field +///< Bitwidth of the `color_space_format_t:color_space` field +#define COLOR_SPACE_BITWIDTH 8 +///< Bitwidth of the `color_space_format_t:pixel_format` field +#define COLOR_PIXEL_FORMAT_BITWIDTH 24 +///< Helper to get `color_space_format_t:color_space` from its `color_space_pixel_format_t:color_type_id` +#define COLOR_SPACE_TYPE(color_type_id) (((color_type_id) >> COLOR_PIXEL_FORMAT_BITWIDTH) & ((1 << COLOR_SPACE_BITWIDTH) - 1)) +///< Helper to get `color_space_format_t:pixel_format` from its `color_space_pixel_format_t:color_type_id` +#define COLOR_PIXEL_FORMAT(color_type_id) ((color_type_id) & ((1 << COLOR_PIXEL_FORMAT_BITWIDTH) - 1)) /** * @brief Color Space Info Structure From c1b39f7aa525482e482094a33fc12697b60b5f69 Mon Sep 17 00:00:00 2001 From: zhanghaipeng Date: Mon, 30 Oct 2023 17:45:38 +0800 Subject: [PATCH 097/161] fix(bt/bluedroid): Fix BLE remove bond list status --- components/bt/host/bluedroid/btc/core/btc_ble_storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 d21eda34cf74..be2bd3ab913b 100644 --- a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c @@ -380,7 +380,7 @@ static bt_status_t _btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_a BTIF_TRACE_DEBUG(" %s in bd addr:%s",__FUNCTION__, bdstr); - _btc_storage_remove_all_ble_keys(bdstr); + ret = _btc_storage_remove_all_ble_keys(bdstr); //here don't remove section, because config_save will check it _btc_storage_save(); From f63c05357b6e96048cc4211e713d874896a2f2cf Mon Sep 17 00:00:00 2001 From: zwx Date: Mon, 23 Oct 2023 17:27:16 +0800 Subject: [PATCH 098/161] feat(openthread): Add deep sleep support for SED --- .../{ => deep_sleep}/CMakeLists.txt | 0 .../ot_sleepy_device/deep_sleep/README.md | 64 +++++ .../image/H2-deep-sleep-power-consumption.png | Bin 0 -> 92589 bytes .../{ => deep_sleep}/main/CMakeLists.txt | 0 .../deep_sleep/main/esp_ot_sleepy_device.c | 220 ++++++++++++++++++ .../main/esp_ot_sleepy_device_config.h | 53 +++++ .../{ => deep_sleep}/partitions.csv | 0 .../deep_sleep/sdkconfig.defaults | 54 +++++ .../light_sleep/CMakeLists.txt | 6 + .../{ => light_sleep}/README.md | 4 +- .../light_sleep/main/CMakeLists.txt | 2 + .../main/esp_ot_sleepy_device.c | 0 .../main/esp_ot_sleepy_device_config.h | 0 .../light_sleep/partitions.csv | 5 + .../light_sleep/sdkconfig.ci.sleepy_c6 | 6 + .../{ => light_sleep}/sdkconfig.ci.sleepy_h2 | 0 .../{ => light_sleep}/sdkconfig.defaults | 0 17 files changed, 412 insertions(+), 2 deletions(-) rename examples/openthread/ot_sleepy_device/{ => deep_sleep}/CMakeLists.txt (100%) create mode 100644 examples/openthread/ot_sleepy_device/deep_sleep/README.md create mode 100644 examples/openthread/ot_sleepy_device/deep_sleep/image/H2-deep-sleep-power-consumption.png rename examples/openthread/ot_sleepy_device/{ => deep_sleep}/main/CMakeLists.txt (100%) create mode 100644 examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device.c create mode 100644 examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device_config.h rename examples/openthread/ot_sleepy_device/{ => deep_sleep}/partitions.csv (100%) create mode 100644 examples/openthread/ot_sleepy_device/deep_sleep/sdkconfig.defaults create mode 100644 examples/openthread/ot_sleepy_device/light_sleep/CMakeLists.txt rename examples/openthread/ot_sleepy_device/{ => light_sleep}/README.md (89%) create mode 100644 examples/openthread/ot_sleepy_device/light_sleep/main/CMakeLists.txt rename examples/openthread/ot_sleepy_device/{ => light_sleep}/main/esp_ot_sleepy_device.c (100%) rename examples/openthread/ot_sleepy_device/{ => light_sleep}/main/esp_ot_sleepy_device_config.h (100%) create mode 100644 examples/openthread/ot_sleepy_device/light_sleep/partitions.csv create mode 100644 examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_c6 rename examples/openthread/ot_sleepy_device/{ => light_sleep}/sdkconfig.ci.sleepy_h2 (100%) rename examples/openthread/ot_sleepy_device/{ => light_sleep}/sdkconfig.defaults (100%) diff --git a/examples/openthread/ot_sleepy_device/CMakeLists.txt b/examples/openthread/ot_sleepy_device/deep_sleep/CMakeLists.txt similarity index 100% rename from examples/openthread/ot_sleepy_device/CMakeLists.txt rename to examples/openthread/ot_sleepy_device/deep_sleep/CMakeLists.txt diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/README.md b/examples/openthread/ot_sleepy_device/deep_sleep/README.md new file mode 100644 index 000000000000..5ee3f7d9b2d3 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/deep_sleep/README.md @@ -0,0 +1,64 @@ +| Supported Targets | ESP32-H2 | +| ----------------- | -------- | + +# OpenThread Sleepy Device Example + +The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Deep Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/system/sleep_modes.html#sleep-modes) during idle state. + +This example is designed to address a specific deep sleep application scenario. First, it connects to the Thread network, and after 5 seconds when the state changes to CHILD, it enters deep sleep mode. There are two ways to wake up in this example: one is by using a 20-second periodic RTC timer, and the other is through GPIO input. Deep sleep is part of the upper-layer logic, and it's the user's responsibility to manage it in their own applications. If you need more wake-up methods, you can refer to the [Exapmle deep sleep](../../../system/deep_sleep/). Additionally, Espressif provides a stub for handling wake-ups, which allows for a quick check, and the user can decide whether to wake up or continue deep sleep in this stub, as explained in the [Example deep sleep stub](../../../system/deep_sleep_wake_stub). + +Note: Implementing a standard Thread Sleepy Device is recommended using the [Light Sleep example](../light_sleep). Deep sleep triggers a reboot, and the device needs to undergo a re-attach process to rejoin the network. This means additional packet interactions are necessary after each wake-up from deep sleep. It can be advantageous in reducing power consumption, especially when the device remains in a sleep state for extended periods, such as more than 30 minutes. +## How to use example + +### Hardware Required + +* Prepare two 802.15.4 SoC development boards, one for an OpenThread Leader and the other one for an OpenThread Sleepy End Device (SED). +* Connect the board using a USB cable for power supply and programming. + +## Configure the Openthread Dataset + +* Run [ot_cli](../../ot_cli/) on another 802.15.4 SoC device to create openthread dataset configuration and start an openthread network as the Leader. +* Configure the Openthread dataset using `idf.py menuconfig` in `Component config ---> Openthread ---> Thread Operation Dataset`, ensuring that the openthread sleepy device's dataset matches the dataset of the Leader device. + +### Build and Flash + +Build the project and flash it to the board. Use the following command: `idf.py -p erase-flash flash monitor`. + +### Example Output + +As the example runs, you will see the log output indicating the initialization and operation of OpenThread, including the device joining the OpenThread network as a Sleepy End Device (SED). + +``` +I(281) OPENTHREAD:[I] Settings------: Read NetworkInfo {rloc:0x4001, extaddr:623954c9725869e6, role:child, mode:0x04, version:4, keyseq:0x0, ... +I(291) OPENTHREAD:[I] Settings------: ... pid:0x3b33d767, mlecntr:0x3ba17, maccntr:0x3baa8, mliid:868f19ce8c3f6207} +I(301) OPENTHREAD:[I] Settings------: Read ParentInfo {extaddr:3afe8db4802dc1aa, version:4} +I (311) ot_esp_power_save: Wake up from timer. Time spent in deep sleep and boot: 20321ms +I (331) ot_esp_power_save: Enabling timer wakeup, 20s +I (331) OPENTHREAD: OpenThread attached to netif +I(341) OPENTHREAD:[N] Mle-----------: Role disabled -> detached +I (291) main_task: Returned from app_main() +I (371) OT_STATE: netif up +I(511) OPENTHREAD:[N] Mle-----------: Role detached -> child +I (531) ot_esp_power_save: Start one-shot timer for 5s to enter the deep sleep +I (5531) ot_esp_power_save: Enter deep sleep +``` + +When the device enter deep sleep, GPIO9 also can wake up the device, you can push down the BOOT button then you can see the device wakes up: + +``` +I(281) OPENTHREAD:[I] Settings------: Read NetworkInfo {rloc:0x4001, extaddr:623954c9725869e6, role:child, mode:0x04, version:4, keyseq:0x0, ... +I(291) OPENTHREAD:[I] Settings------: ... pid:0x3b33d767, mlecntr:0x3d576, maccntr:0x3d609, mliid:868f19ce8c3f6207} +I(301) OPENTHREAD:[I] Settings------: Read ParentInfo {extaddr:3afe8db4802dc1aa, version:4} +I (321) ot_esp_power_save: Wake up from GPIO. Time spent in deep sleep and boot: 8470ms +I (331) ot_esp_power_save: Enabling timer wakeup, 20s +I (331) OPENTHREAD: OpenThread attached to netif +I(341) OPENTHREAD:[N] Mle-----------: Role disabled -> detached +I (291) main_task: Returned from app_main() +I (371) OT_STATE: netif up +I(511) OPENTHREAD:[N] Mle-----------: Role detached -> child +I (531) ot_esp_power_save: Start one-shot timer for 5s to enter the deep sleep +I (5531) ot_esp_power_save: Enter deep sleep +``` + +During the deep sleep, a typical power consumption is shown below: +![H2-deep-sleep-power-consumption](image/H2-deep-sleep-power-consumption.png) \ No newline at end of file diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/image/H2-deep-sleep-power-consumption.png b/examples/openthread/ot_sleepy_device/deep_sleep/image/H2-deep-sleep-power-consumption.png new file mode 100644 index 0000000000000000000000000000000000000000..26df54501537fff4471feb405301f85736cd3e43 GIT binary patch literal 92589 zcmb@ubyQT}7dAeCf+(RPf}{wDAf3`E0@4lAO4krl5(B6RN=i$2$52C;A|fCSGcdGB z4h=KJ5bs4lqTlzg-&*hQuH_o;%)RICv*X#%KKoqXtEtElU#7YY0)dF-pFGw8fe8FT zAiTXx_`o+kU7E!p&~1?X|o7!+mtL-?PkoF27+<%94T0WfGT{m@@&%mRmpi=$Vn+$~a=SPs#yV?t_(q1gq$b1GIw~8&b zx4nY=7fbRnNbbJ=s!2tdhs!J3xAm0gH_YIgQ3jf<=_~6@lu!m{L`7Yfi*0dwnt%oL^(_lgS`=6IDf?HFBv7cc6fkS z728eKYBzn7Wc<{4scH>L|8wP)w_onJZ{NZTJ}ZOl_-wyFkZ(YvC2R^&4w8o_MLLd= z)k=I-6FuwB-ptBP#zKqi!=G&e;}+RRj63|R=lAPKRoz@%scrji6%9-wJ0rZtU(o+~ zDhT9yslz6X`K{}XGDVP~`)aKO$H`}#aY=<{E$9@X{$_X58?Wu;@{+9na6XTwWwA$y z&U@tcg4$({2`}WhhONyqhD9!|n@^!Go)6hiUTd&}5Ttdz_vl$XYdVYSQR&HCx%aAM zo!*>9`A6h26z`$fn(^A$4{lrcVal-RDy$viAZ!oPWH9(ZFDV>8N@LTV+H{iEr8r#* zzEU;DZ&8|dAFP)zX}>x5vc=A^+#*6>x8?cd3)V$TBT2T_ze@CXxMv6#cBeQ|=(WS$ z7%k7zv;*9p#n3(SCg=X?s^lCe;mN&8NOzod-2z*m#Amlc-zI)JgPY-Sv5t!_Lf?m$ z-Wu?G9N(`Hq|M=(`&njO3hUwbaA6+zT=Jggokt3;8svI*>l2g;SCFV-43p5X7T7pD zg1;k>1KkH16-18yV^Mzxb{e<{=Eey!fbD{N0&YDcN4G$gQwY<%^|JBeGgqxomI-DH zolg2#K{>^}L^dbNhob1%CjENvs@z)~B@3m9!@6z(aLwXQINNA(Q`d-fN3%ANm&(WLtn+ARJXckZ%}Ztsxzzuvx-`Psr1%5|c& zwMvQWp)<243KCTAG%Y`=eA~`%(dBAws=Ne=H7py`dR2q3X%cCps4Y%4pG&{!q6%q; z#i?IRvhWf<7}izt6o)~PM}?ENRT273)9AmTWu)vuKSF)U4=TXNSE;!X(g)iA1bFVa z`>H0T1;o#DSu2Liorq z&;1ZY^ydTwdj1;p|5>Dzt02;$zPJ*N0oy%EQe|iRo%=>(FNWWZsfsqOD-^@VZ1=Ky zVoVCG(QHi*yr1Tcj7ByZ`*p*-#;ux2qtX2<+HCrQij0lPs4fDXf~8lTpI9dxKKf$( z_jUqRx*=PKWW|yc9DeJsef{3F9VUyHq~$bB`_1Dur=>lkIahRl%40WVLf7;Nrow)(D%A&<@pOG?HVdCKH6)lCZB0heXd>Q}C$$4JOaGc7M&Bkg-kkjSff zP+)=l*JQ7lnHbup-0*&#^wab>=Ndk*p%3k`!M;m(Hd2FHhV#>c~BCh zjbB()hE30EQb#|(!I5+IXz<*&{@idG+-Ioa;)?}SvV`3tZ#Q2nVY@48{E8ZM-&$*} zeKjTL`UpKrx{C@sMNt|9_Oi58nBQ1Y9)G7?ll6cFl`*mt3-(^-euSKCqU6Eai1SIa zd2RYOsjrkw_c||G*To1tl^$XqTSy*8SA&>2ouM?zgk+{O)ceqHF$%%x z_kuQd^4QcRJ zGMce^(HNe&4yb`Ri0koa8fnj7(^qG>54n-Leak}T_KkVT5dj1}!5>9z=Ir3k#4LMR zqS?rWkM`-O^yNn4nvNUW^2Jd6-``k$C(=_hBYw!|7TxA%=sDz?_Hgmtm}eKKpKjlS z&|y)Yy90N!KPy$dhTh=P#|jAnr}gz7}Pl;iR_(?=_Lut)`k+Q|;dE z;}|mbs{jYZ#3HWKA#?pW-9KKhkKNU)XH{hLogLc&D_nu)ekqT1E3qCI&W1nt6itn; z`b1Uyf>wOh$?ze9=AwwHyK(mu)Xv^)Yatf)oyRo|2qe~dHvN@NnSijq6^T5n{8&y; zQjM6?m>oYMd&!G>y&TX+n|l13;s)?eXQGF;r5}m-JwM&Ov5onMP35~rv8J zsz8;PIC%Y?s>hfvySzxga{GLj?Hj*m_OH zQCU?Lze$Gk9#?Ys*d^TYHtpqZ%770^Hbe?OeFKxWYYexPD9)PKI5~q8cylphNVjXg zmMy}i!nq{aQX=ChPlvT7L={Jjf8;rb1wl}FoFZSb9T&Xo-ALZjpS$Q5wWHD;}Pki%e;0VY}?{t4#Q?= zH7(myZlf9{*5M=@&n}(1;3Gl{NU^flGsX8^mgY7u4s}>X+o@9HNQN-mEc`aXuJFuP+Pr*oP1|4tuGE+wYM(pzSHTu#JSg6 z=}=?I^G9r{4{p%{{w0i(w1}8BUcpjr^|}~HdvTmiIO2dtz;h`-3HHX|zIZ01g1T+E z+o2UIW)QAkQ|N|QTTe~PC|KO6T$@sLaFYZ-#4^zLStFVW z)@g<_vbM#V+-?sBS-;C>3?hvB1G!RrL&^Z+ij;OGLW5}9@>yFn2JkXS-hyGuy1v17 zmsWaTX`{4?mB=5ANa&H4oWx4!*T@?vX0P5F5*U5HHgN_paRNpM3@ImLxy+$T^3E;m zTL4VomwBW4Q?z)hR!3%@waer|H{DFw$79zbH{&3Awi=bK)hfExAr8An{LSR-r+I@q zhuo-xGkmciS?ulHu8VWYul4q|-z$6x?&e21tmow(DfE4RvLzhwG>N( zxasJo>>zw`9!S5MLjtu&MonYNrPP0n(W<_efa^6^*(E6kq%@d<%oTfT59_fjgRvUc zdHIu1i+@~9=)#EdBePi?C5qEHyg%DC4gR1oj>~;wyF3>S7S;L?yG+9t?=XVdUhdMh z&hx7-SH@eT)JU^R!50zjPAfY++U>1|MRre}l&pJW>BP-U76p`}E3z{QtVBZ(X>)-w zA01q=veA5)L9)MyNVgh0faa#u{fQ*5w( zrDcs>(~CcI_wVQBt#Ij4qrllW`?8vcR&sx@_+ZgSbf!C&v{>UI+pF{P@Dlx``DN>L ziz??X*U29bnp_UqCxx=E6bJp~QLZ?XR=_1yY95mLIzyt~Y4E?Ss`dl-MgBie1%Uzx zbN$Z&4D|m%$NrZg{{O@O9&6=aS-OPqIW1I+_b1VCTm2|8-o!F&@mG8!jZM5~(zf9a zI%bdFB$_4N(4)^;a^VTK4~_Yrp4L+mou^W0-eHyE!t0t?{C#8PXF+rZ=Q();Emgd} z4iah?SRQ{qB9dZU;y9$zd3|zq@NOoLMic3tcG}=$w8Y2!{Q7WepNY}_^mmuC+79Kc z`33p&%QG1MM-ZI`jnReCyV~Y->LdFv5+ZLx!5jlUA_6}GRKgxGWC=f#H_5%{*>P0{ z?xA$mo|4`1ueoME4=(JY_eU?s&iiC7P$CAJn?FY0)b`!WS26TaDliBtI!%2D=4fMV zdv@V3NB0lEMn+rm(YntWHI|4}DPCyw$9u;2c{s9@z}3f4ra^UzW;|P3cU@EY)P<@- z*eHW(D#f(`=;cNmDACdTxnUSHD;C%Jq9k4I# z)O|^wwv$5}DJgqFBT7yQhgN?;U43Qf{zH})@vH^QJ(RSZtZcr?hOr1_A-TKluQFZT zU~Xu(qWl-gn-mm9!#|l?!X=F%3J~nBmc3G_EQzYyEv_|A>f^ zOV-FmJB`wT*4kITHSxuaue_6=THLz)MQv$NT&_Pc+)SjxnELBBO+P;E?7fZ?SQgn$G6k?drs{_)Jk=GQSysOy| z^(fVGb3^+g;KLKe$I~=0f~M-LPop&V8%~q5==>jk>l)Vo9cxxC0_?;&E>`&yTus~uiC?-mH&;Az@xkb^Ch zWy|lN57(w)4$WqDCs-1B%*mkZ(5dHBA*QqqkHw;$D*K|fSoD#X+xsquG8k3~dbDi; zPT)6zPIESGH(c)7pLA1*E1Bk9l$ab|Cmk|X_q2d%;NN8vVN;NfBKXFyEF-7aHoe_t zn{ZRnzvcd4&2U$zBb=F>ygyF^zBn*OwHVpV7(`qij*oFXFsV@*syb~L_)64c_4#nE z%oaey7Ezihm)g=>KFUeK(hO7kKYzA1DMg%a5;7NJ~6xnmk;A`+91n(3M#DFXf~-9sCGHBY~0 zc2rr8)4QPrQNs9+Pcx^B#Rp%6+0@%~w$&SxbQtlNKqpUvQx#ya%Bdj28p&0)G^Vx> z4AO%Zi5`nsuU(9&+Y>UkjiQ!*)G4dB{nJbX1YJ3NYm`fiyWnYcLLT1p@~2wrZW^q3 zWaQ+xSUV4i1A_~rE1t50eVzU=I*`BAgTU4(5%Zsp04TT(_Q3*ZW#nXFN;qKJ13St< z)6A?@J6r;{%S%JcBRJ%HL%V5g91I-kW)rC%kDo1qq0;RQS{VD*0irbix>I}-?wl#w2UvGi`u0y4Z+cP-HDPt%4 zNAoKMV4PWRnuO_3zE%|~>88VfzB>gGKj}ac<=hgF}hz_gzUMPsphiia*)e21f}zK}cfcjHc^L z`^4hK_yzO|M|0MKQflZ$^cj?4aId8@teLp5hOd$WX0q2LGBQ#@MM29|E1N1Q(VQ|c zQ@>hUOS`CU>=c&s*Rq()vYXTt6sQUg-oeFD0}A!X$db>~J6RBLRxFrdvw4uwcAL>) zhYBPlC)9m?%}>fhxl5pn>Vt(}%8j&a6Qk|>d4en}s`+JAYUm!cG1fM`JXJK4XK-Vu zCcb4cwx4x=r!qjS#c-OJ@#D2`Eib9|}aOw+jU9H{Fi)q4d4I?D>rJx|YmX#K9 z=-FLgp`(efG7$4hGZ}fjcXA3xVU72S`o0F>x2Fd0H3VWR-c}{-}(%5H=1vsSXP6bVfjZTiEZ`RsRTiy;Ybh8)zrTM~AZ^Ida1-CiE#sm{1dl7j4i44eHeN^Q~h(evAGaP;jq6%FvZl z-%lG7Nk5Jx{nV<8J(7~eo*dfeDSm9o`RT&y`60?pNi?`GVoKb#>XAl;23V0kZ+^M7 zpft+`@J&w0o(QVG$x$?vQ=(C2!{@GYEu`74XXd8xm6LpL=%&U-wFepz{IK5Fct5{bEpyCZ&si1Pgt{joCdXL| zNI_qWiGJz(sEOf0jg7>h_$P{V@E^L+O2^5Al@u>d|Hv=2v-Zj*N<+g5E-(kVJwYL% zqQ>n2FXk^OL$J{$whQO-e~yTZOtJGqj?oMib2;p#FnyK%Y75`gQwUXdMWza|_eor= zV%4ni@d|C1;tfG~1Xc`qY6(!DJGWv4HC2~?C z=lvRqKWU0+_9^Rent%AR%k2RVMxpE1z4BK^c~V3?E0jC3P`38gY8LZ6VU!OWNzcWm zd9WGQEtrPmwDIOWZz7|)tUl7`2Whv&u#lCJ>iYWunhXg7JW_w+HZ_ewP!5T_=E{dE z{|Grm#|HWN7-cUgKyv#c_X;@`fD)wYAbT;f*QR}n9EUb~*CO~13Sv3L`NPzV{MzhJ z)cH-I+w2Fi6?Zo%Gs(>E57P|MY!XV8>}!dtuI@HK%poyR9z=xuVo_QKx_Nj6&CW@# ze`_kK+MWBL@Zt!Kl{i=0`WGfrDIId{C^Q6GG%&cd#{-lzH8#7@tWyDDIRO}KZRPKs zp!&@GZ%^7gI#AK7r?d5a(<+A>x3Uv)tlWGI-%hiX7MBc9cbzVHU~x=x^MR7cw`T7P zzj8{U#K^kuU&+&p-iJhJZWuRBtY5LtU;CiUINaZ$GEIW!GHg1lE%qj{YLdib$#hSI z=|J-k%`q_iB9Y+ACMnr$k{-C3Wzcl?WBo1?3ww&ng{Wc3Cy--;Cye zMZPs;jq0Yf%_(ID9m{oB*FhoMaIo!8CnG8=rrzzPS}x?D0{e8?P9ghGKq z;C-O7Org^$8DcC%gORLynMp=SS$^5Vz1ij!m)q(PlDqDdVnGGu@bQpqO%e;&U? z>4U)s(MJ5=jU<1Ej`5lc2lxzs#H;-PNb%7T3934ZMjJ0;L;{4^^7TEDE~9x3uy zi1eZzN)TdKd?>-~rPk1*eZC^-Diins-z2{o-BCk)?hqb7c|Z=K;HB>(Vz!}0q;7zG%8OkYRixQM{&C&`!tFBvsC$)6-=lKlwSqdj zN6)jR6pC6n4hfY)EhExOvICgp2U`kHa$u+WMRyf7y;c80FUWde9kky;ar*SF&`l9A zbrQdh2ef7U-AZgFN&;Lpr5RVz0IG`Ck9BzLH=21s(&$hGOLm(hLFQ&c4 zX?^?Z%>U+>iS4|nzHQ(AkCe^0@Pd|lfweYQ(T&Fa$SKdQERr?)-%s)9d-NQ%M0fV% z6(A1r=ZSM$AQwb0EcEd7yMH>|`8`u)FXnWiguv?M;VGtc_jKE+;3jB^2yp9qn(?Hs zon&lAQ)Ty!j`f;*G?S!y=awGr6EPa%E4j|wEv@g>R!W-5A!I>B>6$OGiY!luc(GW^ zDzwD-!9mD?=#nA;gr+uEy4E%l-OM8_~4d(n${^4N<@OFe@V)cTgS-^N_*Vts0JtTomO zC6r$>UguqTnAHHS-WxE&YjnCLGp;^sX0?*P~ErYWLk0mo^LqXc#~VoF@mg;(+wl#KeYXkvP?*Ah zCS1Ssp}zxRJq45 zQ$O5lmxPaIm;Vl~gLZ|KQc1Am5KDE$f}x0wHys5`Lf z>egX*nr^+l5NADSx-aNL#GKF-JYul;)?QBv)Wy>)3rYK0Z|2b!pk;V&3ZAslZ_t^H zTidC_gx612xuh$atcRl)#Y)CE$7uT9m{k(VSFZPeKH9@#{L+BjEpdeH-~=PZacesV zvqwxyFvtbhW1FV^K8kT~Hqi6dEo!ZB$D4SB?)DuIPTtN@a*JY6>s&eTMf=IGCwsIZh3K~zUscwAl;t{$=Tr?-43c-r7II{nSx2vTz(g=(X$-*+9 zNavnN+mu9&UAO-=kbmVRRnbh8nMfr`L?+5q+6dSG_VSV=;Q`qR?vgKM*srLSLj2%3 zLRU?vL8^~^stH_at0f~w46aBU65`JCfYzN0bvypK6!t({~AO zI|1+&SbqUDISROgp7gJlqrdyijxcB~@_~&`zM|BXUurL3v{AB_JoS^%kcYTN2PrQXlAPMfip0CHh+;DL#)_qE+*A`}739j&z4w zpXNVnGrd>OsUxnkr_~aCvZ6U4d2dMKTwgo;F9bk_lt-8SnNd~WA>9P|jtBnX#RO6x z0akT;==*=q0QL85&PT4Z{Ie6sKU~Hi4@5zN`|Qs(fK+GOYedMW`OgcXU(7;;_-`2^ z)$tEI`hRKD0JxUUmvHJUIn4Z50I8to|1=hWo=}S%NbX~_P~L4-#0t8^(MzFwr`B30&EIB zAWdEfgq@gLCM0C1+&nw=ZS~D%M!%GF7=vy|BODF z&~dHxT5ds+;+}`sKI-L3QS%s7dyW?gyIUs7`rxl70`MXj{pC`{1{my4@b8pY>oBUO zUb6WoarYYm#79ooBWwm%H2inkAfuEH(98Zhz7)M6IlR6UVt}ojAN?Ev+Sgi1OP_@$ zH1JR@9{6cyq~AN}%&mcAi9aY+^ag+#Ab$$FGu2y40V~^d4YryM)$o5FLcs<|hv(c0 z*(>nViMx}T1*wMd3$E--o)(DrNl=Gs{&7%XO#LcRQ1j1bYz%sL2q^U=?Ba;zO|Ieo zy+W%0f*`%iec8tWhgKG_<@4s`uVOhoG$djPx`Mn8)K@ zuJZA4sz)e$DFr@%0EQM94D&JfEp1J7kdxh-!#vf@H6BI3#-vW%m#=^Rh4^rGlODNe zpcFzkjj2@`PAzi`i3s*s-U%t>+FglC%|(U0QBNuxSB^-_jm1)2s**2vaB3CDILX z!&re>6^8YSly38HYA5+V@*2G}G@T!ek5*-{`7=hb0QLH597fHpay*B{8vU|iy4{~< zAkH_1UJYR2n_#1CKxVq}9E?&dL))5!bf7GncHTW;V^gAS#M;I+F?TF!KmVmsf_u(N z5^8No4Jgd-i`+rZ@pKY)Vq82;DFd(1T~ArD78i##u>M}g%xJ&#>`bd5+|ASG13&#L zx5z$sgRW|zHDDyZYm2S^Qv2A5ZK`#eJ@D?5)fBm#|LhjDJpMZqN?mrwy zp4s#_(N7k6OV;aRRn~@%x)-pGzo?>rZ`*$|iAVv{HpZ?9Op2`Qh9l?icX*t33YC%LvA_>l7O#kQRPT_pBlh zzoJLBx#AkYCgWPD8z&0z4{m_ZV-p+0Gm62xj;Kup9C4gB<>&`#dq=(7HY+(CuWcgo zwr_*>rRv$gD1o04u{~!Qna9iXeJ1WJ(E3t+Z`HLCAc}S;M*0dWay1mIIS6MQe%V4q zx&ikYM=v3?(7z=(pnoEw8o(4{Km&-fX!q z04#fX+>%*c5*lkMC+J#-qhVqDJ(M4x(~lj=j8GV3f8mj9se1{Iy*|5$vEf9nSp=}0 zd-5yNIWJYaxj`f#qcts* zbNZw_b>}&cE$1AE`zO*jn0#6Mi+%x`Yn8hyPSfI;mBo`4zk~VUcj1_^slnmwx$zpi zKEES5Z`EH&Bo!Y|8J};!Ri~Y6v$EITQsYk5=PNAh0`vB;kRB#P#>K?#KX`&|S!dSO2R<@((AE5%6#E z!sxZ+xmY5t&QvSqQFCU^c64P+YNCX;=1^XJaYzy%LdRY4yKUUNz!Oy%Uut^ic74c@ zD2J?$2kug3wpo#kW22cuYz8t*LXyKdKC0brJ%ShFTpRc7Bq$&(5y; zeQXAGfJRLz5AQ*;l^FT$M4l2!)05J(D!%Ler|6yx>i|8C3g2DHYRQRM*}ZypgZJS* z+U1eF|2v@z_=7P-l=+TkW^QiFzUZQ&wawRsb93me&B%wOev97|vZx&!2Ttni>hwG& z-QvS(MJ=b{S#qSu%c_1FhK9)ygXhmPE?>EVx2_naQ~Wd|JDUlMs;JDGylg-wT_WIpH#Wn22B&kOWUWdel%_J0xDo2HYn@{N&<#HaOgw-(HJP*#gi7t-X&X?zJw+%1D(~J)$|_ERYZ`}T9eO!NIK7K zu1d(+A0BZSt`pY1RJQ4X#jJI8cMqxh9clvG2v&09jR(^ozG2d9gKHP*u!@N2?=19a z8XKoJ@Bg^clPI8AY1wl*pR1Fqmza`Uid6EbY)W z|J?G@(9qD*(OGbvIy&-+c#f&C=uUp5rh4Rg_a>L|>aN&?a|dm3NXSsy>5*01am~WU zMwMIy9UD8lt5>tnB#U3##xvu;E+vv?f>UNrYzt;svx~P_Ip}t&Vi&EMlmr4T3&Gi4 z71aI7c&7#!pnf)xTFbz|j+D{P)^>NwdxMpiS3}pxEtY9H)q6dXNgOk3hVkDSkfYbu z){b?kU%pFB#s6)i`Gt#%z_V5mIR(YI^tYZQA=LiX92LLyhdzJ!&Cjv1u?2;NT_}Mu z*?#!&@DebR`s2p|bl$5x(Bo+@R0+@v)~~XTgpAuko9@adNr(wrJV!=GF7kVg zMXvb*E;T8EbOkJ@-{4+?PfBM`dfV@4j{ZI;r-~iCxcro4$_vE-TwfQu=~fKYg&K?a z?3bCqz9;a>;o%eY!%GYx)o8R*D6Oc@Tt|eio?gPSXMSPf;E<|hNp0w@Eseni7^KSQ;6+|!W7IAhVWJo{I5?P$znR5O{H%`ABIK2AOX3*XtfJ zuHwxkCQ=>mq@B8s`Jzf{6eaJNUJ67?z-LzoE6+<=i<@@oTUTiDQ?szzBe&<{iFvlD)62gFOf8~aXT0=Eh4wT zUsFTFy!@%5EMJ%WHHVw4Yl|9$`fgERX83{0=m z(q^*Wjm}OzL;80Bv_sR5%I=HK= z%Me%1fVQMfecZJ*JOjPZlN6hpS_-5SbpS9|`njqd z?@dEZj($*hZFjPulctYk%gf8Xen!fP6dRiW31;^Cmr{col_+56TX$9WImSyF7^>lv znLR^M-mOjz9*xW^@DxYSzvmE35q8P_8b-ay8zpeH1VQ8e^TA{V$7A#to+Ge$rpNb> zJPwEiw7Y{U0QhJ4!_3Sqd~u?>;C**@w>Vt`Fh#&Pvhjv5-s2Nf-Efjh1+=y`*U`;Q z#GzO5#p3inv@sKj)Q?B)Ehap8@$=o+aM~j0xv#=uC+CwM8Qkrs$;s>9=p+Iv_Tb z<>j}47YOZ&3kx-TeVc(?mh5}79p91}&VG)4LRQweO?x-!>7nt)Uh+|^s0n@cn;iO8-%wjF3*QHze#dqZvrwicG~A#N3iYU`KeGVf z5JUQ(PDUF&E6-BzdomUzA{RUv-(XiUauyW8%doVf?n(eY0B}}8(0*U1*y(Z@_!tg{ z*>{KYbL!p3VHJ*Y1r*Hdf~>7?hS;7snteOt-Z$2UV{BE+`emDaDY9nTO*ZjMex3%e}b zla!qHZK3ho3vY2T=?f@<{-S=!$(X^D%RfCC>kUBDs} zGvoN(8g>I2izILBf%k+tU%D)E^#}Q#j#_w+60`#TOdIyAmDu|B?A77VRDa>Ny;7=Jf~2O@RSTn3V3FFtEYi*MreCiA?YX`iR}GI6 za9;=Y-38rtJ!>5TTWf#q78c7$d}THKvHvz-=5aRx^-bx4MbqJ|iul9z4QMmLVRsqj z+J8NhU(v?N?|ZS;N)zZE#vB)-bg6f7zhBZMZdw`XFEY-PrPH10e3=8LDM*#WUN}B$ zo$a5FHJr}muJf53ZJ3oYcW){?GgUpv2-%S?qaH6{8Fsx7HyljKX?P=qD;oBMU)0{x zP~Y*M&5zYU{I(g94>rD4F~b}>bG)Js+!xATL^pU(W?L`}Ov2g%zkX;aQQYi_=+gc6 zYCPvjMS*Lx-^ad(a)XiPiWQL6J-fhLKCZ64S!OAHuXd6b53XMO?-;O;tG>9KLr&p* z;yBf(xGj{hnR&JMvUFbDQTxLQV;~Sqhx+L4JB)AuC@*eX?*BNpG`*Q9{20dc1M^>?}Vf76R z)U~y94kSX_Ux$a2JQ>_?WA212-TJc^pn^RsC+Ff~Z%X&`-N$^2&AoZ%<2Uz7^%8q% zsA=|5Er)jVi%t(h9ew7gZ?&}4)>2L%^m=gno%mE$RXsB|zW`Fx*AH&;-YYCs=W5)< z^*u(JEMoAk_S`-YNs9s-yj+7JHj#Ev3yKE=M1l!BY$sGq`^Ub(&DNzIcH}+o(M>8A zFI2WfWLy$zr#~z=;nj>2hqPxNO&}0KXT!p0#U&G$0s4{WBWY)67wx+T5IC8mB{|8& z-95NDZ$@P$nQWH2-c9dj>&Xr>9|`)z#Kf4ixxS*8kxwotD=TkekLBm?v9l|^6qg9x zcX0#u+rK~(&WuYoZAo96i)}ejIJvxyK0acNaqo}cc!vAYn)CYUr5hA1&Kbh4OKM%& z+DDRfbJHxT6_%_sjSOquKkbuXBysHu5GL<;Q}6Rc7{nMH_yrAGZ8$>Dwr z_%or!ou;H!Pq%S!4G!pxo%h(0K(+Z1<}N8+Ka+pB1utZpcNQqYg(!(e%gqRSQ$+Ka zf~o-u!~}cU7hx$9-FYFYClJ_W{H=nhXykIyNTEU~a?O3>MK_1unlzJ9jr|yI%XFGk zv#Xn1Mp4oI*(TE_%{-NYI09T8`_VFn=Md+#{*65rCO@2K)6EcWsxZP+)sPldLZ;Lr zvarag`~6-FwGVRpc07OPt-0{(f_$!$1t&P{@LDF7&v0c41vpQA@44I#w-wH6DYhkimOIZ*6b)!3;D`04xwRTvm2);8!p&~?=1b#Mg{7Rtp;H4Rh~0hkNH@# zZVhJ>`GEC}G~dI51(8Ob0mG;@H@0Y(U<7NT9WWhVAfbGI#ytb*`osJ#xfQjLL%@Lb zm)W+USSANuT?%}Bd^JtYtckRlGcN_I&*$8fzdYd0n>QbY9O>YtMoB}EcRTa3y2k2J z6&(@uat~;9-1bAPcoWKekG%pOWrQ{yfG6w8K{0mb?D5?fE5}0pur+>)FTtHr%$MFi zD!hCGR2sOTm6eqjRC9)TdN@8M=Br;x)0AZH@krn}9XD^oE@tV06~wljmIs+{+`P#K zz5^f!4-lf-w><3|2)DlUZ*G=tlh*GGe*8iBc0Vs}RR8ro(M)pLqi8X!-sDe9OZhM8 zf?0gO)YSqs%xBHcMDg&8IzN>RKh@hY`>(*wwkglJ-+lV@5U7;_0`_{5vxf}`Z`@ZP z|1H$&=eJk3fEpIC+|?cs%+8iU{`w&ntKB{AcM1Uv@EoXlKn_(qWFvPz1B`e}*W~1W z6X5Xi*oKF8F$?;!-c?$_1=U~aG7?;ag>d( z$s^vkNS0gnP(8kLE%|}-Bbc$HBNyPO>bklFEz^D8zWj3~1~nwDFOyD_9O?;yI=WD> zzZ~2*4es(1J ze9M$e_J_~O{#*nZoSKH_v9>n(DbJHimF8ZSE&8+n+Juq_zgQo3nJ$9BA2UJ!xbhQt zzUE<^1rZ5JVH}W444b^jg(h9ezFYD++^2Uus4?%nZjmxLsKGBN_ydS3Ye&Z*v$n9) znD;kdwY9YoVjH<#aR5^2-(xwa?3Sp#?IuA8(DHk1Y@Zh;_JmzsT|tyBvh96jO8iOY zF2)?jjg$b03!8w@V%cX=7`=SJ&&$hO@Y|k1?HrsX7m;hof;kCzx#VMS&pu1{=7CT= zr%_>J(B6@C?)9~_wpnff4GE$<0|4~Xre6B`RkqfUa~OeOxj|_Qdmg?AH*jQTCws41 zQr%fsd;)vQuJC+*s>yryMcwtO@sW|YQ&Yx(T&>HlxRfo`xraUpUp}%03F-DhdM<1R z+`!pa1Q~<)s_@M1-uu>rE?>y^bHKTKDrny9m~ zvaD@v5_0q3?b=iDj>Q;| zL;~yUMc9q%`EBeZ@6 zW@e1Gwzf_{?d-F_mzJaua};?T^@vqwotqXu^zsX>;3_X`zj_p%kVaOMb06yrHFDk`p9R(dAhVI0g; z>SZ;~d-rZ3+?*ra+uNI=o7dLPZm4qaO~B z+kMq+sBFL?el00Mt3F%M#AI82r9?SOq|0WGRl_Et%!;G?LR!D9$dt_zrP4=xRtFp4m&JH2T z%F52lCVOY^^*b(_zt{JVPcJWz`~#?;iz~KQnkACjhh*yq zUz8xKK?l-8mM;>&(c_%{MM)+9Pl)b?1^_KL8E@A?sBf#eQq+p8Byh z5lX}sTb~c3V9)gWH7$8QXC~lxRhZfF?#ye-ntcNv1-WGY`fAf>&`a^V1x#w*AGT#y zS66@6W%>aG4gA%B)G5s@HGc}d-67?pr$_~8&dTmapBu>7nQBiZx_D6`(b6Z#$S2v_ z!NxA^W3N1_`rfJUBq%bhSDa&08gOTkt?9Tlb|1)ft@Xm;|8THt(c;1cNh`|%hCyfc z&Zd9u?had?Bx6ci1O0`Gnc3gc%~<`3r~YG?Na^JGFlP_ZIjKmV!z!<3;2c$T>rj6X z^Y-nrlFjx^{C*oa&`i6s4}-g}q=4Do(A*^kOgFIkE&rX}w4z$E3$cEVih`bknwk$( zN}m@mvQJ)W;D#$JONo(dxG%;^A~E)<1wVS^qwOR{M?7Q5bbUtoyuGJQ5M7o8(bcv_F{ z05ZW*As2ZM7SS<}axv#)fD&F-$E98E=7ExNZ=+gc`}WZHvd1(uG^K0BYrJ|G(B{Q^ zq8^E6E;{mI4SNoCDza$z0LqDsjFj6{@l5=jARatFt+{tWF;!u5RTcm|6ic{#*Y@mf zO)cNV#pwuMypP=3M~|@EBa}d!)SfmB%iaHOHrIFOJ^1DE752a5ofo7vv&ex=<*bpe zR)CKzA$9f0>~z?$Wq_M}Ir{IuMviCn@8dakWN1#Bl;4eX(2@v`XWo7B)yKL~K{${A zGz3-LnA>QU2uj<@d6i}<*|G3>jJGTWy{TFBZWre>2K+;C~!g5 zH2$2|YyLp+{_{R_k1kWGx4V(gb=PPgE>vVwpgHZP0*!a%nX1Ht%EMEwJFr#j_Ks>@ zbQeQeV6SVUK06MWd=q{eK*Los`ud(0>xIDu2Nddn5y9nxVyv8N9JHuPb5?uHAeJ5} z=b@+hR(ri%WkuzQy{Ml70wQyoxNK{0KUDhgP_0we+>%of5hjVcB zStiyv4;a5GU{i$Uwhj?b8LzJKY-SB4gbV|=GvFZ9V=O4*c%|hw~PIzY|GofY- z&*l$A{a}2q{}ldm2-TEK`+kNzxNMDJz}DlIWA@?_oz-S!YwN`$&1vu8FIev5XJt+S zpA5Xmlhi`DRmdzXB;&HY^D^<~*|0%}l9$hE_KG)G?#x#;5zs|0AxpvK_l zCoHwbt^PlX1@h5Y+BT(oCe}Ko``)SV!=GlK{`=1vb<)@&OWXK=>kelm3wkNtDSeuj zwy3J^@p;(f>HTvpuG9*c@){7#l@DjG8#-cP{Os;R>OpHdflru@L@m?%+B&t*VCZ#7DHr5mk z7T{&(zWecPm|Y&!*V}1;*@gUEs%<^|UPry4ElDa!3fB2(+Qp3eTFG^IV*CU4rl$gf z)&BbqS^@rQ`JaD*PjMwBE`=Pi*d=Ni8hk8*iKAUz@BB zFB7C9s{r0-$ho_{NdEa3_>_&5np~vozbm_ix&i0idf-xrqEz>wOVq4&h_ zXo$oNFN*Be?zM;KH3oKhInEI?oF7iSOy&OPrz}t4Vb;rSJzkyJ-xc4=%8*s}+^{h$ zbLG+5pm)n{vz&Vzb3(627M`x5*5y#-sC66x&ZB3DnE1x$X74KOdhLiey98e(_-Cy* zoCHKS4@RSh7B5C$G2GzI zxK8v`?UKPo_p?EF*PRbZJUpyyyQ|;JYRl5Y_wTPMDJX)grNtw&6^d8CUVn7VrAp}U zD=91-AkWx`^;_87|LHR3x@uSwf4+>h=R=>lGX1%Rj>5viW`H!-BsYTpJ9+ZtbKxt7 z#>S5Z=9DyYdS(sH&7V>9g={j~hYuC09!O{?6jcB&l1I>DBns@<+T48iV6H!Y;aJU3 zEoD~8U79D7;q0S&- z=x3{|tDh)1B&Z0!WoqJ~4)iC{&{vnQxPpOuhxI~a8>jy)CvjmUqL2FHsJw3d!J_h+ z+df*3O^PZ9d>epfm%gLmD%B) zW6-2MS{w9EH9cj`^NA%RQN?s-$%~&5o7i>N^KC}Pvofu_{>3#f4xMRmnXE#C;0OL6 zF7+K7HYw2hMlXj%@5~q&trZ$Hkv%EDkAwa2i9@1OgoHliFyO{>LZy98uky&t%PYb> zny~cG>j}*5w117dRL2aG<s!0Py)AUPuI$_ka@|^udH3!v%Vbwik9TdY7|-^6xmfId@O)oUpp$1LMdY7Vk}&}MDR8@W3ky`W z47Gwsli%Ze_`h=$?;Xxn8}IGz7@C+oZa03~ZY+5( z@($~HN)qaOs;curnJ#)&F9X04ErZw$^>(qEZ@_~ASB@KMAKW1$LV6>ZZj|rdy?a6D znn73;ci`=@lHDd_Q2+Sk^JhW53lD$%Ft3m1*KAkiR&h31cqM}Yxh0bO>DZWlTYLNH z@>=!rzf}BMv6%)-k8&)J@`o@UW2QUzKLF7H!*K~Sv(SouZA4^b&wx%o#^ZYqDmiS6 zlO*gCMvEM+QgSN#R^E2~cHt1BP7s`uaWA z9#^W=-NRJ@6sY;!Ojk)l6Foi3*k&3)n2*Y|1Z9Ox8Awl!Z*zio7t){)3Oc-z@;ID6 zeE6`#`k;r+NAlP%0h5Sckj#C^sU@ih&fQRZ4iO_g`sv9@^u64$I;-rWqKgnHaOhT6 zzi}RHHOuw+!T4&5;9*@A6=Jw}D0q#aCjcA-(FDP7mYk%=aIin@?QY%ARaKZHxOfq) zN;Zcg4IdvLnn+UXr?~%IC`O_ut&{Q!4v{>L_~3z-pD&(2jOa(IYF-sFqS;tiq%i9rbxd)wRa6okB#l;y?`z}V)FZB4w?XI-6EHiaaPal+sw>6nwpv-HdFdHrK^3pIY2D6Q`{m{3(&2^DS^Ky*Z%|T6a-Nw*MZA;F%*nfivuK@r&R#fX zR#r?AQq)kR^340f80SXw%z93r@~|3kU86KrO5IeNn3@uVd`QYBgWC^@%cqZNl|MV_ zFkg05MpZRTCbwTWM1ralhQX$lX`Ke?ndZg~MYj&&_{3@}W|el+l&lk91~`)`?eAsH zPRrGda?-l-Pd*>U-+J{@luUYLDY2aEuVa^nE^A5ED}3ihusGTr2OBG)aujk=S~*>e zJUnUg{D-lzc-DGtkTaut7|T*es!rasQ~r|%1H8E}c%>dXdg}WZzpJ#VpP3;!sGoEB zfZ(Q#3JD3l(j!L5OZGY!%j2?3NEralLpfcseO#PyPl z;rFB0_{3@8c_Ow;i`^$63tW9TbKzn~EU&ou1SJ1D>)>Fl$~EZ-JU*=UB7i_aUH#6$h)7x+ON+!XmdJ^W zTKz__F+WuR+DPSkRemxNwaw+=;Spi8{!hfEzIpvwu;4^QMC5fW*qJj>H(u%Wx^2ky zI!?+dXKIu^%3?bE#rhkTFePpY!?i~xx|iMLoLKmjZCPTi2;T-qf?9KykT5waQM5`w zC&495P(orBe5-g%)4GQM9-5vfN&QB@kV*1t)aRbUZd+PnQpv56%&$lYUhl8Opb=!(99x5 z*;+|qZE|I}yY2I6cwc7+w228J)jvPgm^{goSjKisxH^_`*ZT|nAg{a%nk06lfL$~?srwKb({&o zoLD;*VNIL^ZdLnSS}*H#%BWIVul(UHZ2|nbTyqGc;|I|TJ*MnmvLjvz zOR*8J-63}kT)1Sw2)($VNd;`Zk^7>>I6);PKwf?J%g$jY@;{{W7Q=WT*$bnObCb+l z%V|Lv9VXchm(9jWCYw3%l(G-#eizdea!?YdLF3{$FD5FZ@M1BLl#HYh|p_7 zggbj4Flgj5C;t2ke5#3yEwcLkOvZu0vU-O&o!_FLNBD~0`{|vb^Cbd8LWh17t!X5z zSBzT6fPo8j3Go*dt;Vl4hF%)Ts_n4Bf|sL0zE<;zf1qSqci9#rh<8Bkt*|*#gd(Mq zj3dt41QS$>g`$dAYUl9%OD?0vv0Sh(olkm#Rho|afx7GB8cI>O-tyIPJGktX0wtsG z)_ghMpe1Ku^zGa8F+v{l(ocBywwD|r6AGW&a8ALk`NJ@?+uPato0|{xusTNz|L2CJ z)#$Ke4LFt$>4*Dc@Z@U-_E46mOM`fDvQL-lqt+^BFtd9bDE{=fV-ck)kgCm>=XWmB z2n-HRjXH~ary7uKkQS+7&!8DJ4tRaJiVZHzyb03mzIW7OQK_Wo1}ml_Vx9F=cn`< z@+JVY?mIXrqfv!wHvs9-v=_m@BmNL-wCJG#%AhIgHULb>C;-b*rU%?0!bw^M##_>2 z+&`~DhO~jp{k)GaEoM(wOt4^(02Ny^|2eCfwts6TTf6f3^2$m~Ufwyfmv>ai_-WTA zIr^ReB!8cqOIs%xbN90v9%Ai)lq@9lIJ@X4LEQ-Wef^Q2CBq$t`yG2jqcarIOHa8|YUduDk4 ziKlcBM4LG{5Fy9-n(@MhOYO%jh?xMg7@N+T4sFnfvuLA4?@i`XQ7n_LJXqJuzy~=9^9i{EvR$s1~Dz$Vw)QDY#&-tyc;lkB1!EdtjpKbiJ6GYFmTlD*wbYwu8zy%oU2C;9Q-R+IeY`y=s-Aeqw_7=N3 zcT>Ep)V>A#xLf!+e6Sx>lD*zB^?^nkly>=+4*GNA-SM|fOz42*jquoavxZ72m$>nw zN)1^dH=tdMPa~YuAVEfb^X5$mO1y)IazxyGa0*EN#fukVIZ1P^dg7!~pn;^ObUZ4% z6wz2gAJ-X8Ux%m(wL9e8wlqfg$|m)`15FSJ0?#sOdoakCgyWj$Tz7YO1hqR0ZFf7x z{ZESzn9U1!-Tp|Ju`UpP=XBe4Xb~=lpeqv6sHMxKQ7}3PWQf2qUOO8mK{Yc_LJqaV zjIbBHH^AR#j^VUa(fOyu+@-lpJ73A*b_QV81i-&gMhF(XO-ri)A{TCt>H1B|L*)=B=aFgPzn;0eu(a_R9 zEYlLeU`mYlV9O|w@puN;gcMo~@IjLHwwm7GrUiMoT5;C%?Cd{r4lH2Sv zm~pMAS(&Pn4PV)xb*asim8N(sce}F)xu6erV*yb#$gM? zx{i(o`jqJu=&+!@=&j!Id1wU~syweL3<)ohEwNRU1jL8Fd^x6=p_c4Z1LcH0{3P6$ z`vajq1zFREz6;6PGcz+4U}N1?R(|_F0Sx%6?Tsacl40G*3$OVB;Q^F=~pZi zy-GID0o#YHsk8$oQK6;_7G%n>?fmy!XV0GfKIlQ-IPK=SENT*A%N@z$7BREWM3ECD zP%n0;$gnj+0(P5*%R(jYEM4)YlA)=ou(b3`=KkXC#X1Mb_u`X@)#%m}Uc?7^>E1mO z9x^;Yq(@TQxnq>;YHKYAKOg2KJ$2&535Yku78jG^&gzupN;?fIJF8@W>SSQ=HAAPmi5KfXZS$P{mz|5DSd}RR( z1(x7LxUM-(eE$LF6~nHka$$}fkfGbSjNb^Rn&wt_N8pq46opiI^!H>_qmSU^iu%Xb z%eg@KA3VrJvq(wS^G3b_lU2_`8KsUKuuY(0wdK^HF8WhYrk6&h$>WtmJyoz?=`x7E zEh*XXq*@J3KK~~V`W=tLeFHfW+)x2$=dCCH??7am47}t&l4X`69mV7M%dK`kNUJGS zU+;42(#8(?4fmgCUm2^n3@*1l)fzk|%@K$p z$5!Opj7uT(+FF9bQ)ir|@qDuz8~e9|pcRCek!72?McqPD^fKTeNpUyj6$DIlRjMFA z9+~6N!iyrf*M75$NvYld(vnGO)cCz!wv50_>kWCWcAoF})Lcu;32G<(OW_j+lz#f8hSo(5FF95%L7Bn9dBeMAVTwNik)V{0XC5B+*~7DJCuP$>>qLFG zvm4ikEQmuw(rn3R_nwsob&V>XQ=U~P@~~^$O{|?8dY3eOq;xW_|^ON zW!pei+&VaF>?6 z@>**A$w7)x%1}c)r6Gzb6gBuwIE`+{tgGuT7HB7kKYH#pqKgX&FkgtTjnn(xV(qDT z5dc6hY`jL|0`*}gjJfI7u$lw(X$0`0u8R5xGA2ss*XQ=kqF%kb9^P;SCH9Du++TtG zzoD(KZEb-88$DgvVSg<}?ff3AkuPWTepDQ6QOu5AyVDiVg>lU8_^~689d=eaWYpBs z>hD9D{@UAn0_~qjZx7cGvzdeu3*9C(lf8Yj4T!gnt?gL|)hqJlggCd1FX{0NSkN<3 z>$yzJ4MKDPwigK2CD{`4gQIbyIqk*@eBqrhweox5{;~D6kb%&M>O2xg^XwZZv8E?C zK{fi;%*_kFRP`)m{8Cc3g;$azOt;U@=8!vl$3iUox#Y}D>2BZ4giuhS&*6y~8wZE< zTfIG9Q{e6bLvuXr8J$@iBx!$D_yOy zf*CYLAan_Wx?;L&0zGE%>G}Bv3pbXe1rVi7dp|Hunn1mk!KXzQSqD@?adB^1Jt};b z*r3#&Sw+_|T?O^f=jm@-#mE4&gH9J47bj$7aSa6TnNGj_Yxfqq1Y=G^rqdGG!nGw+ z?5`5b(3EgQM@Q#va`Jsb#%4R!;doAd{Y6e(A8It5e3#I&Egn)s)ivvD$A*@w8)I%% z-A_NNrCr_IX~li^`2E&INrK%pC`X27W(sC?<4dFQi;CVM)o?r;z3_wqCc?myKy44Q zqnEYwRhL@*oadIg_y7#@nr&Y9CTZ>JIn?^YDw7w}m?y4mtGH%cQO+q=%XhUyIV6jy zqh0Wuc$OqYroH%9VU2H`pr!upNJ4X-Z~lOrGx&_+($#?jt-Y;vOzK5WY^aH`pGK_u z>dU(CTb>rzgj(RHJpm5^_;@<7MZ|}t<1fKa8sPeuZ)a?8i~X-g?CTwM;@B7(zRle~ z%#i0!5HEOnBm9bf?7>J<;5YtGLR}vjo|3q1C;XHTr2X}r0w$V`9D%UITQ$Ti1ECNC(*kLa2~uJ zi|#eRzXx36^v~41CdUO|VzZuE`*KtEpG^Yd&vRhQc*?!jYj-+u62r1KUHDkp*b;Um z2q;%cjz4{8)S4J!5&c~M6w|4v<%99#&fA=U#%iMMd{tr`RkyGB#SdpdWkCei!NL3O zok_U^$)x4lIuk#Bh&*`kKq@~o6!k(3-%ZBtCj0J`t7!HKEgr6|BorTN9@pLS6gH!_ zOXEOKOvbja7`_yJ;YAtR0lVry3xie36X%vGvk(QsIHQHF!>_*eWyKTl`X3?BG{ zCgwNU3+OaUsH1O4LFKl<4*RJMZBF(>u`kjqp3Q zvuK8GJ{`!7qm&C_$p~M;oj~|Xbxarb1r(o(13^E1$sz0dGTI||vA)-#NV(RRMyGqc zrFVBfZJ%<XIwR(FIlXm6SKb3l{ae-Rg3#HB=2*gcjzbceq!}%GG_@D@Eq6yfek^dxWz|~ z!cZvYt_J=^=&%J~Am&d+PFN)zh)J$OYw=+9K)yM;$wT1MtK}UyM&~zN#2&E&(TD0oi`zbt5YM{izF<|apOc(-5`_f!?%uuY?m_Oxd7lI-^({a}7g8JaA48kn z=DS*GWjpODY`MGbhyZ5Ls<`@!^$)+BFKO^z&^&VJ$Hh$nqoa}1!Cu~0+Fi2}yMH1q zlTY4$Lo$BQV-I7nQ78{Q@+wg7yunQT&QY@A>%R<|eL1uS%eSj6nEBn#4Sr=LKIS5-XiUHS(5y;KI9EmTk>Ng{J!A$`7P&yd_spQ0hz!G z@H7vkslf!ooj$PSPT=7U1L~<={GF6HR_yl@7E7$rl*#G%@m|`6+H#y^~xf4|px%$W^G+-R!NYLM2x>&c+ z>SauY`BSBAf&HF<{QcwdL0}T4epg|>8zj6L!yCXhJ3c+js1ft+>sNQMXu&ImH-xw)Bv9&INhl~F zW+-0Qt~D!x7De1TVL^6wbW4B#3uGRE%}rp2sCmfCQh#FSqfXBHikTU*HWSae$=G77wLj9xhlp z>FQF%$l5o-2muN-8@t!A_4@q%h9@Zv`sJS-m-g{VZ?x#s?7NDJ&mgKtQ$n89>It#o zna-?3z&=3qf($?A^SB1E0o3>04voiP`ySBQ(B_32`R?Odm#?AMC6kFuXxYY1$N#Ec z&d?DOf8G7+eqi9_cah3jXut56n1Ge4rBEc zUT4G>`L-=Uj~KXJi2t`Zg7n?Uw}>BlZI?=Q672IytB8ne$z-Zs&~3wg^Cl8pR=rWj zjIch`a8T|~WrOQS(LxnTXMs)9Vopepay@lKG9<3mu2#$?A(8jU2yk}+kSW7}0Q{GR zK^Gx7o)MhxbL}q!@wxTjL3&uSpmEZN6RXkG%Qd%IRYx@2{8ukVjS%5Gkmafji^k#i^Leh={D7^VgHTp(jL1 zDR{{hzk!g&3|?AI3g+p4Ax@T;BIk8Fiwb;_3hDL(rKpwf1HnKfbUghBwuwqZ7=cJiSd zc%q(kK=1p$xv4iG%(^nH%MA_%j7<;=dD*MWe1GusQ*?EgGJ&JvZTZbA#qWtE0X$^V z{bQnyf$Kg9s{)3pkV)bz(y-A>?e%w_gH;Dca|}&1$Ng$W3U;Lk54VQKBB%|pi~_n7 zYjlxL!&4Wz1LwP;GYWeQu65>HW#Ep@nZhvE)ZI7;fZ>5JThJ{m}6 z-%kEQfPr`dOv;D|E)eykX_og1n0$Wi8?<`2FHTJvLrVz=4)HE~0n&WQDmx_N@|)PD z$Rr5*xv42JBJT=^k)@6AmYlLwn4F7CESF#025D3DUa2VaO0ZYPvyjUU@OXaFLtp5Vn1fG)Gepjh)xW_D2F>Ra$(9C$D2X{Qr zd|;}Qv{j3G3zIqyxicGB(Pws~@=OGHCm-#^c6tGc@09;o-Jd8TK`XEe#5{RWP!*{o zOtqO!FCTCRN1v$QU~kMHx}*;S;WZkjtz%YIRi$#(;e#Lmj8Q;qLhN`Q`o`zW$#?Iz zv$N(Y7&eGRks zV7n`NCv>WFwlnK$rcRK;Daa0qC9~x^SUI?G8^CL=x-R~TLVbNawXtScd?s6)W8VO%jiEk~#X)Bq&z zG!1oMHk8$6Kh%YbWbV>odH^EW#lmTB5&iJ@Iz>Kc873{YaSw?WtS81o@kL8dl4~3o zP=kYmPu5PIJPEC3V3{EeL)rAy6rTTtK@>0>O>V0>VstIGfakDK05Zbo4I+$T^1?^3 z9jlqr)6yb-oMw*wZ39n@x?nHcAor`fUPoCm#}pVX>%A9~64@@5)@RYT|IH#V64qe} zoF6~?CVKeze%5+Fajlkw+W8Z|#+?|C2y4{2zwP0U@=#~-iDI`#ES@t?VfXAL z$XXkCEZzBjC8N2iURJ;L_#a}z)1;*j)T0lro56QdUp_mnJBEsS;rMvvFUu8Q^6Wi< zCM=7hmDf`SAlyI%ECz0nRFX|t?7w_iO$R%~a%D;Z?mm@S&E@VpcqdQZhtlCs5fd9L znEL`wU1$nrVrNe@-ussU%X#B|=c?7up;q!yC?A^x$-OG!6TwV5zH z1R_Rwxw*L@L)9)KQsILKbo|gU&9nSfXabA~2y(D?^c2`o!!H8QFAJP~y5D|pbe!+x zZ{F5GWnZXH%NUyB>~mmvp>GH5 zd;t__6iVeaTXjk2%EJmP<^Up=zHjngzBl>K2mdF5YO)4z;Ra%Rx~vrrNEVtSp%ikB zF|%J;fJuo$4ba*knqqy1?9Yq155xlcZa|5Pdc9LkeZ#+q3Lke!-xWIUM9^A=eb7C( z88{8Lq-ozrHa%@>z5)^mN0b8##>MgLJ#94>4vS-RWg1H$RNwL={x#v8W?SC??Rq+T z`U*%Y0kR6RvV#64ByP&g=V>L&bJu3#>*WTf>#GmXF^LrPnY(QD3`m8&l4O(8$Ja^h z2{VSCYaM*}+MRAE+I67X{uUC(v<_4PeFHRZ+o>Zc6eA0BqUB zyGH6G62}~5_z7Ub)eFAbzg(65mT&xT(ri+R-d0!ObwXb376pFU#?p8ebl-v^F=D&* zuY&sgS{l+6`R?6mSYas0ciyiL=a5#=Bk7rvmG|}(d)GOOL^nC+sk@!H0vyDFU@9X< zFLm0|_EOVum(O0Jfg1yVL`gU)lV0014ESKSZMq-;u-AAK$Mf?;9Y?vfXp92 zGPjM5jZf?VWgkT$!ye@8U@1U9G=Fjm^TJIK`IHoz;I7dtzq=G;EJa}hd-G*p9y^5o z;O$E`Ps|Q}gT3moE}&582H_vBs`*(dbLj!eLBlxB_3M@3*+N%2q;wNhVcH%G1kfbI z+}T1UCMG6CiS8XedK3$VFyQOb98y%?GS4$Zr1H}}LuTe=PvgxkudNNYCCeeX1Hj@^ zh1Bo<_Ij*ifySP{p@wi+06AnJVEjNB z5=n^OMGe?B@L`laEu^UD|ay%+CocqdP*ciPb0qY ze$3b1cmwbVOos4+c5kC%j`LtofsF|z3*JtV@jQoKJS14{*vH@(RrxXi%Cg9d04Uaq zpPBtWEN|_6fEKn(b=IGWDE%t{2H-~DGJ!p4XClbV6#ywvpV(^-u{~ivHM=)-$om(d zO^uki3@&fZ3+i(Oe>p^f1Xbf zYkxoAq?x2hVo4p?GPnFGK5b5=)-wC?6hl?D#{citAZclSzwEOTl|7{oMJ~k0k1r~* zl7i?~_I0legW1uXud#4-?7{oluZZ| z_ri2aXhTpjqwDz9J7LKk32!MKz9KrG7b4OEalgZ=+#c0TtJHKex=w+vbuySl{Oraa zi*k;9w~H3rLz)XY9MS-q##~GO0-6iVlDpW$?FI|NLn9#6$z5v#*B(XDJCfgJigHIx zw&8WiDaoj)ctSs8dmdbk8PX7fpc}N=2Lu!pXG#i3P!SONnInAUj3i$A2m>SEF6>?e zJ+!X~$oC?Go;ioY;&~Lzlt9IkQQtNNxM`{b1el=vn>_!$em2H?F>GIltJ-Vo-??+!v43L^bMn~Z z$6C2Q!uGin>=b7_((Ym6E89QpxO_{jsv=)M8I?^Eu=Bxwqb)ZnCW(n8_po#CPAO zYA&ujKej$*ZncMlzQti_2jds+PDF zIZ8Gaq>b~a$jisixs2bG2`G^@U5f9RZigfno71vkPH#?gN$X@AJRT%&Y;5d9W5Jdb(H8c;@lkU>?!f_ z!bV0$FbQKvWAdZZiZRSzgaM)S@l8>l`Z|ZRFVoS9Gn8ywf2q9}m-*c~HY-i}1ysqW z6v;(J>L8|fr04fv^C*u2)+8n?+CmA3TXkDkS8`X5LC$facL;|MU(%UZqeMe`4+NpF za3nQ2)`n2`^z<}TWXPQA4xtVY56^|cCFmA-UFBonzMJTTQm3Y**sji~1O)~@S#Gy^ zYL;g6LyH-|6&yjC@e0UJq`Y|}5YBFP!O}F3IA`gQA2=Fw8as}==NqE)&HGY1G@Q)@ zIJ_%iBxBs1+gjmRlSTV(lE%hDzuU^fQ-=DlKhzZ#PMz!+^t(gW3}>*8u}OXpB^o&V zV`5n~Xg#Q_pjFY4fZ~-3B^vJmk!yBK$Rf8df2z+UwCqyWFwfD_`50+tw$9Ayr!I6= z#hjo`85z;Fv$sD5Uo0ji^_oJwg4^bsM3K#MhI+kEa0zTd@!}L=cSu{_ctSW7m`0GQFoYAk(NnUOsDT+4 z=v;V9`NpEIpnZES6Nd3#M(>KX0AXZ-Aps>`L@+w|*PlxtHN*rkRq$n)o#|ILFhS%S z3=TpTD>97HuX@<8t>``s?c3Ii^dtf}r!D3&+v-0sCX#F#uzVz5RHY^_Fwxpy-0XhE55S^ms z=hyUK9%aC&ApP!q@N=d#cSkkrnT?2viJgFlFDqeIl$@ZOgAxs0P0fe!c-{=`?XGp_ znS}$eq(H+&zD*Cz`q3OrW(UdHJ3|7|KOb@d56ghY62r-sgz}3=P+F+i*X}vHoQV^dSsm*k)^JAM9jo#DSYo~qcJpz|@+ z3BXKM?h!Q@{R)YRE3l)Yw@0Wy+QZM@oVW^O0TeL{=P@yW@$MoQoC1xEGz7ZCYSco3 zq=vu352ipvj3%;pH8&H&C@G1FRPh*(@-t`eD7i$z*t}nVL_WO5{q7xn!{iZ*kiRW- z-+DxtSXh8qQ203m=JfeM6A*!Q{oI-f;Q0GyyksvC9Q%B&cs8%+(a?uB@%3Nd2>vV7 zhX1vMYYEeU8E_nr+=M6?GX+*3%&+^rLaVQ+D?!PHV|HmAj%AntkP53|z?Hby zJRb(+yuV+5gpHMT`NFsWQC2=IPiP%{Y)_6VZ<@4CfzBnqXojIJ-q!{7gO-K>J(-#c zc!_Od;x)!O;?(8j0wA7rwW>o-M<=e!p7HR@Tl5(5&D3E0uffYx(weP{l->_$K zzn;od!falkeDmv7JgyqFoEX@h9bh$Xqe)lE5dlq9|B=?t=E`MUPf@gYKhX{j^;vMR z6qJ=|&|^n;MFhDxv4-pmb6vOWS*-9)G+UBzFMtChaEY<>%v5Cg;8%bFbZEFN&C8Rm zN7=egXss^?@vt?L*n~0}9BI<4%8HMV=Ns=8h4~vWbBBZt%M75%ea#TRcpzpF;Jod- z^EF1u)kn~U{$5`F_C02c{!bsM-Q!-nzmCs;*=Dkb*%ovw;m_ch^&Xh(Fv%>5fzRSi zy8e1eS6{;E1*1x}sl*?HPb>j!oqx0WWj&!WGXK^EAnW3y;HCp)PIU8oRu=0Rssoi9 zYHAPBrB>3-|`I@*Q8ktXk>$~ zfVepg5lTfF8JWE!LeVd*Ak!c!2(7RtFuV3X-4C!LDN6=2p-T(AYFZW+xzNzi$Hj|8 z@4^h1bnWbNMSL&V2{i?PJO?g1$1rTqGd;ZEs>7x>{E`J7xiGrU5E=UXalDsO{PmOf zo~+{{FgC^bb?)43!J{5<*)p2OS^QhFs4zzt3j;r5qM@?GG}R8I0YO$a78Km-TqnUy zT&;2oOvl?=LOnXx{O-q49~r!r8fZ>&VZGeWDoP3sNCgrrNJv zzuu0_{1v$L265`ae}msq6{ee?BISGojjJrl3q#%vDIY&}OQ;cz3i^(SK&K5%qsxV` z;|D4>ib+5>vfA3(Uzmo=H=v*{@j({s8}x8(wLgGy=}228jB|aPm?$E<<`yE-C5K*g z;4wBbVp4J^#&rkmQ>ULZS&qklVsaV+m%iP>6lMd(JKQ3Jo6v0c$_ml@p=%9RINl^o zH6+gFMA1!hNuN7+u77?XBZ3Ftz}K@Zu`AZ6iSHM$r0J?4yB5(S7th5ZOA=g{0Iv)D z6|~>l`5S1$#&ExCFWK2qzW{x#G|A2qpsKwGIN1=vmD4fu0JCDkm6>0pUb3Se z*YCV%+Pk+kJ9hzn@aPD5w9V7Q!MnW>XoLL-4QdT|gLq^-M6$<0!%zgBfQ{dl!#}3# zS_|B_TJRf?q1-oayl$O5K}*6-bU697y;OB3J&KNkEK?Q6rw zd(%Wd^AM*(#EJ{9+xRr?YpxDMot!S)l`Nd9l&L5v_z03K8TIuN=)R?q#nC!w z(l~F!+@ZX)HB7$uVW0`Z1PN_BmBavkqnkQR3LjqhU|jED7adw4(BjbK0pPa(O$!UqeI0*_ z-FeltR^X78<<*9Otm9I!|tW2a>bQ!|3x^(UjFa3W0F44JE#q=q=%-ZjS>Y!fA-MaMCqMU(&K_?4I6CD~Ek>S31;cc` za!B;xB7O=e@kclW`gpjUPsJLfQNSBUPQ0h;aGUL5^42@$2&tqEz3><@)E(6tQ%3w9 zNMguTr}NYN9v)0|4(vKHQBlUa&i2*UjY*m0&2Z zATu+q(7PY|%xAlD?!XA_;NL`V;uUiWG8P%0oM5}XzVL23->fGwFz{><#APm9;jAfW zXpqTi9@3j(xQ0$hNVr@Q3}8l2R~IH@b7>120~7HVCN{iu%KV8Vvm$(fD-{O%yfolk z)fiWcW6foH05hah5)y7hgra0a4Y(*=?44^Hr1hP0>rSh?MH+CW{m&Nrt86Y4KOXOY zsCD=kiq%pE!Ak+4DG02g`@{~Zasc^r!KQ(gqXE@a|Iv5ku?mo-h;kV6bfYu@UtTSD0tE>Lo~I~Nlr%Qa`M)i_4c||A9RXcP7REk#eszGp^iC`5b6YJrMDNB657-iyF#b|q|qU)7AC_VrzlOz#(CA{IB?26XG zQE;*#F<;om0?tdAi1o~NCDZSNg{i5}=1ne#`8SZNcn=9YtW4~@hLA{dqPut;Zx~$e zKeL}Zt~ur#v-aicOGB^}m~w#+_{YC^@uKVm?Ts1xLOmc_Oo?Ehv_sp9$4wtT6(b49 z$f{_CD%&5u1^&9BYk`DS?=w4$Rv+ZFubU3veRfvC+BzGI2jq(>sj0>NDYX$!*w3}u zXz9^RP3KFS*}9%n8`2oTCg)GT5apl7lHqTsohufByssUgt>M=B#TtP-eoA^~BauT^ z?_biFxwPlPm$(W~Zh)y%7e?M5X#^(um^>B63&4$oihfjH&>l9)N6SG$(yJsqikmK< zkN;$x*v;Fs1FmwJC03VaIR8`;6iVyK8=Pgyx9{J}J32bvPq=mE`atmKx<^DL4kX<@ zJus-hwhV9ofq(m@R3K9nHJ}R(A7E3SU+4{_l>=@FgXYpe+jwr~Gm_T+**Y0mH!2ITyWmRa z@WKQH?qtQpyr5$6zg;-=3v8h#F4DPM-~%cF&jk=2LI*)^`rIuM!6^f!&8xfm03X?c zpZIDRQI?@&z9Og+p{_vgb-b8pY0>_+P#{9O@seP{9*6x4 z_17YA(+c{v!0p}gE=-enFvq|34+v=Q>f-9Xzf8+juqDJsSJ6#8(RTCB0PzpTP2B{h zQM(HmMdH>*fd@W{4$^P|lxn!MR4Jv9_oH)gg_wRWcI5T;%awB_suZX!=5N{U&ToWt zQ&Uj^L^F96cYzbRVszg?j6G4qc1SOwi8}3cl5V7OIzIJR%|Q2JT$t#3?dnw_5Q@B1 z`&Im-+%}DnM=NY+LY>sp(}U-mkbXA&MPyJYH3t0Bt7`CE0<{~+a}LTCe;h$h=zTN` zdUehC(q!@050V+iKmSVw7Ui2eA3(6I(a$jg>a1^MAOsllN6FsqE9Rymgir(jVTBXo z)vCzG1b99gN<=@G>W6~S@$pm;;Ml_@W!Kql%WFV)nzRk$2VG92PgZ&=<5Ng*a1um< z0Lt7kgK^^Tq4N*2iy_spzu)WCz1HXvm34M5gmy3DmLGsH+48S>wJBMeHg9_716U$F zd-lYpt9y8vFORgC|3MXS;nR$sTLb(~zobo3rKSS|GWHiqZy?hPIO>WTN6qu^0SXu5 zt18p^+A-iaU3UEY8FQ$hm-Qlp=~ZIEZK<1EgXVixfP}uAkEA3egZj)npr?!i4c)6s zATdJNPq4cogh>dvAZUc-%i}*Un3iN2dDT%1p|uJEX~WIs$?^;LKuZKZj>tVmATMw3 zu9alMQxl8<44mmXPe}NbLOG6!@4NKD6B`gHISaEJkq0n<8QNeE{07tnML15r7!;J% z5P~FzAkR1vU*@g-?*%%f$1-7rB@-W>6mVovIgT(27V!`NV$H;>1C&~N9E&`(c1^D4 z`8^U+YwheUJjBzVI_2Q88E`51&4l_d{EqK0?*R3{1}8tL!_g;5!TBzS1EL|LudlDH zT{dZJ3?sjh9X&8Nw^Cenbo(C)uKEAid(W^a(`{R{Fk=?lgea|om=Q^W1VbB2k`g5& z2uN0fNG!AsZ9ufhu?z%}q##K`q0%5(2_jj^Ip>1nj1SOu?Y*CS_P%$YbMBABvzBW? zrLW%aePt?;&=j;ih3xUyTGGsh2@%8I-TinBoGoB&*E4u#sgkfN~KiASwYrinm-%#a9nUe<4+1DSDLg@o~V)oZl2H5=GK2QcKV6&TENl1e~hgTAll#URf>;}!RmVo<&k8 zy5yHKdg-x9H~%oBpvyw7w)n@|HB#}2vYXdiZ!os18_-at*ztHQWK?sMX$=Qk&dZd2}b4M zM2iT0W2t0eAF;Xt`X*o>un6PEW)#WI`-33l5O# zWm<8G4~}L!S~jW2UA#+-Zh@eBpH4hX6?qbR zO;mb#2wBt^3HE!-xNREUh+p+zE?zmefUja8(T!j53h@mw%O@-AkA0x?qoNqdDW5!fTiCqnH~yoaebDmer61tKGo3u!z?R{hA3}4ZT6~W!N@3YMzw#KV5=SNj4P=A#H~pVFXNpfYo>8 z)FKNNiPl^+eyUU$yl5F?6l`;d6C=ya&$o95g9VvO%>AsNoE!gEuBzi!v3*Dy{$<=w z5AYJQ^sUvbXr6VT%g)rZV|3gpJ#o_u7BAPUhdA?s#mSYlfT*rw*)RM2*aaPI?wxd7 z+B*Vh`Xf;GgsB*u>cRoQC3Y}qo~>8VjugnIluTOTxGe3nI4 z`hNWcRI4C{cmaM`kLz7-{Wq_Iem&1P@85)XPz90Qvt?%5#=RG>RHU@#2Itl@xvvn| z2k6E}Ym-%UJ)3-vv3KA0^z`%{F>yap!1_%p&;P|ZB{){9Fdzm{^Q%D@x(>2ckDSJH zrlyf7lz#@@+N z&~)g@M?$++*g|2{SI+mqR*SpK zb-4o$8sx2zlFxo7HQ027NFd|8&q?ceE8@Jv zwX`Jr(q~nsLc9@E?W<%4Y7&*uXpC_3I+(-A?`4f+@pfvY8o4I1tj#SgX8`|F1v{4s z2o4rAm26KAysl(RJ|ox&aeN^4Z4NKuX2gSQC|udTz*v13 z9Qbs+*uLbNRQ<=ni{cxtgF{~A>TKUw1wSfWyiir@Rn=r1!CT);Ho5|66w%DugQF|| zC|l6?;@n;T>DKWHF3Oc8g|4fE*RU;!;t5=vJeO17QMzT@u){F0vW{B2`f`v*;ay#3 z&cl&9<*FG2YeU1s2@o}=QeZgT?(Gm4{hH$9dIt@f(?IU9#OAqG)BT7}NwTQjx|!np z@w6UV@xgX$QUx7`+FlJjc}(35o%q)7MbuA2*TfO4sbyK?G)(}lv7ACv?&T>ul#vY2 zx9g>Vt00c|%MF6<2$FDA0fcgn)*O@CQ-V63A@s5MY{tH10THa;;t>IkFx+iP(NJje zvOH;}rjT_oYHITbI5cuCod!U>6N3|0s5vKrvHz=rnEHi_@Rx8Dj&!}gCF+p;na88c zFcA-wd|SotI)W#6_JrvQ6qq=ua>9L+$o{6Z{)Il5%2$QRk1i6vXkb8KY9V^pU(c)D zsn5lkuj^H~DyC+&c@#uWFTisV5M*YgtGR$->*8%e$#mU_9)F3_$x2WM$PAQ``N04R zKM6QV#T+uA@on!Gb9rL;gF9CQ$WzC5yd`LkU`0qcT>im z9X)j_NB8z`>#wHP9t2>pp)|$1wFATDK5RZoixLb=lWQ#AtuKadBjmUO$GoNbRTZ6r zjMPdKr^G8ekKfxZDyoJrPdpi^Ax|#bYXaNo<#aYm{?O*(mF-z!JgH_NV^q|^oc8_C zW`wH@bL)F5#wn6qR^sX@jc~5W0){)coTP5OcA`r+HTck-eBB%l;}ZkJz6UPcfZ}d- z&c{XWUXrv|#|R{4bKW7xJo3u`w6dK(lBZC$p^REx$ zcc1nFCx^j8kpy&ICBQiJ1OEAQ#7yrDNxFonE+DF>(BJ??d!JB9 zVUx4j&bO7FjZF}}Ze)YR5_DJsC7soYHG}>a^K~&)Rovc+KJoLdNTi|dEM}<9Duo$K zuqJU~ zsAY9^TiEWb(dlb#c|5Uy_ilxwM~{|mXxybBLmk5WEd^qJYJ-cEF88Yj@r}m8cwH$# z-ff9|v#}CwP)BFbLU0x!sCsqbPq0hR60e8_LEL~@tyi*yk>>5*wd-++HshX%zSE7r z2NPCf=V``_qgjH#h-I*ua6n0EX#%=Z5!)Ui$_U}8u zwh@sC#J}f|EBs*8&w2bl3mNnXq1^$QEy8kp#A?p)>h3QnMQRMbc(A8j;GFq`Pz3i+ zZ?xualIY*#>_55UVdXVitPWlBqTGX#Ti%zZFeGx+kslLhA_C=%VnwrNi7D+?EmFT^QFoKx3jh3W;$c!{0h&GHLp14l`Y@^MtJSs47S-KwsNpqM+p}AvzxsdEx%ic_*pCgH3MF zlI*Q2;|vH;5<7I`Adw)!c8FYD8~M1#GXyz`8YCW_!@&e;g1Cv`;oIGrZSH#a1fUCo zU=@BQXBa~M+E@`Z#@nM24#>9o+@Z^{`bx24C#SbUO}%?Tt4 zql26=hHX@#;s9q_$h=Art<7bzqw|W2RA5VS)85Bm28ut-sclbKpa6=PG+kCz z#o+_-`Rq^41_uou$LDZk6Abz^LsD8<9%&77bwIQ&ufLVYo*YO(@kUqGKZ=4ij3ST% zkaGaoFVL5emL+POFH|h#W#>j?+ZTX$iCN{yiV7Eem?fwhye}_x`LfA);dWgf6@TC@ zQm|DQ_V}SYdo;!%k5=jwuYF7KYTEiy!N@|vY(MnZt-~N!ZbJS6@#N#*BxxLxf6c${ zDjKd+%uEG1LKsNsG771a*Ng+)97i$&_FNmSmwkJ$q{AfwQTmghAPAL{RT^5h zqS4c5c%A}%d_yFZ?d|PWhd2iu(oN9n1Vn@kWBlPJ5xG?oLuaM9emMC9H4hfF>c*OJ ztdvmAoI{PVv>bhPkFz_pkMDJC6Pt~B5xj4`>jtpe7`(>TyC&o-vSJ(dY+xCxKkduw zmTnD-o*qfcdV4G>{Cu9!CI)j6uQlo!gp7(ftz-4JUkxZUR1rI{n`_7}cIex<-K?qv ziVP7-l0>8w(l7p&*3B>AObO=>?sK@ty4V=nJ}A}H%My{uqiRhOw(>eRX2?Qc=kV?N zVo!hns#wz>cl!e$FK>9ULiX{$Pk*X16COMdxI86CFC^X6vDA8@CUS=`8NX+UQIPU? zU=B`l&w0lYEwG1yft)FtF^{~`7HwDiKFWY-$9YeaX0bE3+eNF(3VKfn;hK+&Yry03 zR`T;nRP57Z268c&y2q~J>*=mVy+=87k@|g58Q@^NDh?DS#4Hn&tx|lcwOitL|Dcn| z>cKo+WXu@oB3|+Pen>pZj-?cYrr0%1?na z7JHeT^eYdJytz2<+7}?Q*1hti*RKb}D+R`@>-oGk7(6!@);OK(NF-+GODexwYc7?Q z+XTuJxJD@W?ek!HOe`!`26#Nk0_i8HsyiC>moE2Z{mMO44g@9&22VZhT7O^n{|cWR z9Ung!Mqa|f5ETY-hqMC~Cu>x@IU-94=+3$xCvv$4&sSPg?70>tYA_Nw7by)(@@j}J zh=HX~o_u?&n$IF40K+z4mU-qWYpX8K<69i;?cSxmYUP=_QQ9jXHsidlq2FW|r*Y_H zK`gT=w7W4u)q$J9$ceV8) zwLPf?reJak7F@rgwKrEM!jWEp*bY`+NA=l`Yqqg#Q>S^B4jVFw^zG3c!VFbOzNm8SXTUjB!>SoV?u#s{O5`b%KefGUqb#8^Vi84s2} zefkrMfrQZE#bqHeNs0(pF|_KehDHFl@jz4VRL75nIgqBHsEE#9i*1L?h9QR{^6j!g zbm#CHLbiPPqV#(dS)lKf`PWxRb8~YE6AHda2`F+RE3>aIxwwMPv?c1AL(+^dAAZjH z=JlEGUo-Ho!>gCH0S*^nCuN&xBZtb$%6e52Au*a}lUfUO81W6~*<8~`Nti-0m&s%c zOz3_z2!)U^yU@EvHl*)ErSf;W&6n47MTyA+6|M~ALaV=HMH{i2IvWSw-|eifq4C`$ zR#aI-BN9U97Z6!>IPJDA*20F|T6|DR=RCj4(bU?WSJW^454N@}c=Z&a0tAMHsGpca z4-LVbL0*$YW zyU#j8n#+(;0pXZBkwclxk!0Lci77h^LkMtUuoYS`Av38BkQJvE3jKYK;P& zA;h)QQ)gWt9nuL+_#)2v2TIP{26q()T1gBR6QPGokEr}fHuIi-+?%&H#`NAwuE#Co zr$@WHMH~3#M|XrRKqp|SC^++W1Xf#f&;Z>QS<+@vt1NND_)4fa@fG*q`LGoS7llZ+ zHa1yrXuXJI5LTA_lPE0@Cs@&5l# z5>)$(&1hLT?j$+xl;N_FfGCi@b`UMk5vFAQOru3s>RZ-eE#sG8(s3-Emsxnzp6$a{ zlX+v!{;JK!_1a#*=%!xwhbaV6603&B~J|MDj>n>^%)?u)EyZ=<9~#_pe_ z`3rO|1Kx{wslf2!H%MrR@aB~JmU1AEHaH-Fxg{;zE*~PYUtrM2P&Q*btPtf|vOvjh zh(1(Wp+2_M*Y{4qod^I=fr~%q{|G@Q(#FVAKCzW-(DSf2^b2 zeYl}VLTqwmO<@3oXUe$FW=2r*U$%1cMn>T-_Gw4&tfWWR3km-{&VK2%f4wqW zWiUSFGACDtrc#LRrN@2Ut?3Fz)+L%%>S-sTW}cckw}nZh%mbYQEM{X``W{!)hvG&i zFVYNa+Do+JjZ6Uc3jdpUd-}VjZ3uJoW=8p4m)=bem`EqpGn`V8S_%TvdSs2VGB0lY zzuYJZI(R_TL=veZY!A3jpIJ2su3=k5D(6RH<|nLLv<|&a{70?`0ZZH8h*mM0a>}Uo z9PwYIhz9b(A;q%6A#;31)8z+WUYz@0>jKDkz@d8h+~C3>#)fe4&gZiro|uBfzNxH5W*kvJv&H-*iC)hPzB{3Yr+UoCy-ipOZ5oUC9VaKgW>~(`qU6C^l33<@&)|6OnsTjA<{$J2M%hV}ha$J_} z;|QH^mN2-*-`#2JA4H4Jp7?ilJUz^_g-c&wT_iSK^x5wAukx-p0-rWNUt33%?I_2| zMXB6XB>o*gjJh6~Xtr4y3jQ4}yZq2t#lm~C+a*YfP-m%3OgpRmr5L9Yr7~uAEUw6R zPWZwj_k_-N`!H!angu$6h(}$|o#>i{KM&P`xGd*|2Q2myGQL8?QbYsrne0|E=wVGr z{t!=*VTvyiTFHvJ{0aS#%U_&(jwmF&y)^s|w+E_3OG-*mpS4keiAnZzKbfDlv53Eq z)=n4e@&&;#ix}`A43VZHrrz$8zt+13l|FoPK2 z`nY~LF%s#B5<%ui04tylVR$k`MT!ceb?=aP62gSCnwq@;C=n21LZ>u(#rc#4$?OMi zgkTGJ)9rmOKQ4_#iXvrmq1M%Ts#B)|M5fZYa~HP6#>A{t>rRC=AUM+}PcrxJs;#Sw zL883UzTlsi9(()`$=#J)(W!jl!UbA|s%&caBe+mg}_p zwFXzjQjW9za!E0&GOXVKqEGb-QJ(Lrq;8ds<)0Y1VZSxUL7K_&fV;0dsg|SkXB7mV{S*nYkyy}F zhoFG|RQjS{{08ar6dpfSJt)EvVAeucjXA$gaiBt%`#Nu(l{CGF^`CD&gXdNd zB}^2D@W}cKHx67_GNX9$)@}bhX+z2)RFr`O>ZA+v@H~9{&m);1MNk99$<_$?^a;jKH1^Q)Be0= z*~HPm>3;_JAtBb$BBOoXX^Yp4%x!5;}wa}3U_%GP;e1YBG7=xxg)hIQ6R!94Qyq_QYMUQ=Yse7WM z9T=z6nT)CUHN~6A-x_ci-|*`fG~PM=L*0+h%5?pk0K#xTO-F-i%g1gL#Qf-Vz17rs z4c~5weX=Wfb)=kzV+=W$h3 z+&uB6%5tZ9fv;qBQF3W0my$R;bpg{OqH?0%l<8xZ`0=j(ht_bp$EFj4Q?&4;2<&p{ zOTS!#)L#(`Z0d$;e5rKm#rVph&{V@aoQx7J>j@bqM@jaBbHrm+ziG)i9#MJyzhz2zXhW%PSqWyEZM|7Z;60{HN1$Tp9jQ>3L6n*x4?BKmdh};Kf;hb-sx(t6%Q5ZNKtx>&EZ$))z3$~U9YN1~m;YLq zY;5%8@X0-CM0gcBqk)|XK?dv)fBh3;K?1=d2+r6Hs!m~ligPO8GFI+BYLC9?8n%<3teU{4&uP`8bxt;4-EiE#E6 z;d-pgrVy#lsZ?J;z6YvpmFP5)aL>TmfU0J*oQ|g}*Z({ON2KsMJslk-t9Azy$GZ05 zg=1yZqUdN<+qCZ?RaI$QbNI9}qNWFjgqvlHl^q<^vrNt7+Mh35Z}aTCC!&&x@eO~W zry%_M(~zDf3sBvDHEwSduAz-b)ocAbpjsr^GJk%Y>q3GJcyc_y6nIWsJ2*_9wnbr4)lRP3e-|>H+0a8ekPHm~Q5J*)B-wNg z2vQ2|g5b#jFn?q!8nzI1XQ(8*^(J6OLXrwy*_QfmKY&oMoXc3hts%5MkaqYB7(G;D zs!>s&x0hU%;SAw5vR8sz1d7dL8{4suk8hQ6WB)Z9uw?+o{a6if(nmhLRf*M(hGvYAPLaROS|;DnK;XiW-rnoL;rLY$h1mdUw>q2GB%ecB|L&bT z&tml|El>`7eCQX4_-reSlLw}9>BqKG`u^m~szDUxg$kHO9Blur>!IfhetF6Nhq&oq zW2Gg(+&j{NV~_sD0RMM|YX6%*l1Ulqkvdew$XGSGXc zQTm^+)g@U!IyfasIuf+{N90<@$}$)I{x|;du2;f-*S}vw)YMg%ei&dRnTodQL@VI- z&d$g;#^&aQ$e^JxRjB-eal4pH!pgwWJ%uuvJxSOKJAh*Q66iE&hcbwVqzkvq|+gEi?DBce2RDu(SfQR?K6Rt8R!5L0^(tW zbix}CHKPPp4jc$Uld7kS&+g}Mv8=8>*CA!ziSmcaBugEG>Rx6~?+!9i)5o2Q`EuUe z_6>J=t(cSJ+_`}LO6%)si?>|+9jK$Rsi|~?QXX<}>u;IYxyhJ-h{}U@Oe4Ao&v}15 zZuTQw$$MF}T0xEt0t#yak62nqfhHcsmWGfWqySgG$@A2s32d(nE*9+$f}=E34r1-> zF+FR?8&UN0M0=Jv7?_2Qb3&-hngyA*7MM#_)t4l`XAJDgM_|C{Fc}EUQP$WFZ;y#) z1}HaAL9G$#vYNHXh_ti=sbcD+LP!IQ{ zZI@jko3LMB?nH-TZ|S(Ir(}9#(P3)HYFb3dp(+30!oNH#^CSLslIQswZ#DZ1{%sXd z&X?SLUgFW`@1LW(&ub_%o=q~=hZcn#O5mXRQcgq&?2?OKre-8BUwor${mZQ+?UPtb z>%MRAh=sm<`2cNtveiQ~h1q)yRTwhmlqLvOTD8+lC`X+b8#&p{;b+ig>-`KlQb=2JZ@O+{{_%7c8Khz*llbXHAF9J!R81 z**ma~#^>;hqUpJgn~}{NnfV_v?g&1P*u<0NI#bHTXc6cg)P3eoLjgNW-$6u!F`8-D z_(5+MLVI*jP|y>sh5eb-;m(S1M59m?6+vKB`svdnf~37vT2qKO8$)?n7^{E8{rn1bb!_5&B8q7J*63PHaeh9eGSZ?bFxmtBk|NZ<>^ zo)&7^)q0`Ei#TV?7;|Wss~W3oXAKk{gQzrb?VU=ei(E))4G(tMO&$Pm$V0{eTT~7L zo<)^@Fn1-LLP5Xc0ce?95ip?#n!Kf@C4f^!R?q6HsyG1b#CHVrcfP=9?wV!d;=Z5} z_ZFA2?-)WQ1#zU;>TBpGOi(UpsYm6;2xfb92qE?b+V9jyh$p6|9>x?luWGzqAxuCC zW-)I+^^lvqXx7Y}a5^!2J~M3=Waek#Xt$aPVAjh8?>-r#-!H=4!c%HmlI*D(h+d2@UHYhDnJ#pJ0rG%2ySPkw`vR1TV?O&i=RXiHO1^5rRfp*>-^l=g{F^tbq!1`M_Y3hSNyUV&((C2(H*Vfi zSoJUg)+&!qnK4k2{dZx_#XK6y-afJ&85-LA(d8+}yl-M6I4eApvQ)x%k_W0xV|h{z zDvpH(SRjFwCX5&N#!Z{@8{MUXF{_AM)o_Wso13zQJLMttLpzgdtfWy@%3JWe8eZMTcE_^U{r?a|>XR*?n37eSF_P6^wtwy@z3HO6`;|ImX zHSwLx%4`hIMlVTN>As>hsIj-~?E}%Z5%THstvcr>Y_4^kaXT?41J_dl$Fgq5y{v0? z+>Mo-`-S)uEkb>y-CsT`x9!`dqM^Wum(GtLGVYx>S%s zTKrpGf~hK@xF(wU-q+eOyPGbrfHC?w)@KKepz72ZN>#&P)=}8#|0+GrX{fKS?`AV? zHnVX3n}?*mBZg;EE5Sq=K5r25%?`3QWonr4{itDPuc}3hI(Wb$#4?9_ZRhZua&{8m ze1t|cfyr8gUK!Ih?uCX+cdG6FTK5W*XIY6uPjPG=Fy<9PS( zS}}XAdoze=?-r`Zy*?-9)bz<@910;bwHLsZd-u`>a=_y+2C! z&+;zFoc$xo_84idkl_FRab`*W;|0+(h+d|91?3srA=37$-oAZ%Ws0>Ch9&A$qA5LL zOvAu?$3@RN&iEcv1Xmcyr<2(+x8Y2DS!RqccD(@@sd4n9@`br-hS5a%kmJlQ!8i*! zm_Ia7csvuYLy>`~rlh=Fxv~OvU%XvJCz}5-4DZy$bVH&$6cNKnu)VX(>Q8FmDwq!h+pA;J^kjLJwkV)SsDix|>vV)w4l z-a5Nc&Kk0|8GP&1nRY;iE_tCEWC>zpZz6VrM?jxkqLp}QMTN-IT0~WTfYK1XNT{V) z8Gxl6fXrX^k~Pq<osJ`wU3wC3T?HH}U81}%=+9HKbL z0VNhrXPp||L=4T$%+8z^hr{{R2x_Wc12Nv-*7oA%7c@%X&IKj@(#1KU1VNXtn1|kw zafH%KTUO;=3N!~=5&an=M@f0|l^ILe*YQ1yQTF!ly~ZbpOTwjdH`~=c4!a%pF9B=a zmDbHq(Gb8-hAXMhwpx;Xa+RCUcAKUsaeYqMH{nGgyb86P!xycvM zXCwAoQSss7Mn^}Mm9Hl89VZMLWCKKk1tSkjxbLeq^haSGQdW>Glc`UiK3y1Tlz~|# z>%)pdHaPqL*0}8TY3B}SvFUpy;RYwhW!65GZ*`!>RLAW%s+UY9JQ);#h*pVALRMCF zQTe^Ioqb;~*NHOaqVs(fe+KY(a$?HP-~3N~rI_(7{|74{w#XFwy{uZ_o*cUb$<51z zCHm}G!#6weOGLs>+xO*GE4~>R0ySyx>I%HPS!ed%K9OAF>hrk&doM&_d#d>~lON$b z)i@0nDsG8)nVJw36l?-+BZ{~gTO7v-gm*`{Z#Yjy}Ev>E9N=g4Wmixptp}Fs7_K)Sh zq-?%;(IT97A*0kEwp(NFQx6pXU)zlp`+w`AG;cvbgvRQvA0KZA!tv5pbawekrRs>P z?-3IWzB%>$j)zM4YBB6|7Tk>-)v z%t$Ro0s~(l_Tn@9K6h6G7i20YBg+#wc#w(?H?6&sL39r!m7%e*v0n_dyl^$B5q-sW zQQinR!^X{<3vooO0h1V4d(LmN+FA1-Mc+|9^S@d3jn^})Dbnx~$O5U{NYY?pn{WC> z2^8ML1U}n3%#2Ti9I!Io(T;#&jxEe=ek4pLw6-;r>8aAhY5z4m~{FdzyO8DGWy4bS6Zd2~-Cp zyncyV@uy;?eGD7j;Ug#SoQhA>H&^byKhUc)6W*IR=>ZxcaF_iTgCry*mc{A3$c|%m z1uVBGUQq{eC8E4ER62V3rCDZ-8v?U~cN|qRWbrXdgOL2nm#Zirk4>YhYTFxp5ysG% zl=iRy=n$wgX*aRhkO-)1GaybQASr{9K|mg8d-=S^Du18ijeaQbl%`I_z-N+?94QT( zMiNNF?BaOnIc;6{Bbt8`wUZXHZ3c+4)%eofRc*9BK4c@RVPSKVzZeumM6~BUQD0-S zdCR7v!#VX4wi~T?|L~pdeP6ve?)Uwt@*yGGd5_QUJ_ojoDk?L!Z600wv?%0!!nzA) z+kQzK$NB=J8}d*1GWD;7mP(M`42_{@AXYE9tI#aT7gY;Hg; z72&wT7SuO4KfiP5&N6GQIWqgjsd?Wv67w6#RHDglo-;IWg+xF{Bx|f3EVR~*Zq3NqwkXZ_Aa|&nO3gSFWsh6#80oYjpJ>3BM zgY31kU50>i^Eg_9==jwVX}uB6S$GaPLXY**>goU?(=P<3I)nHU$TC{a6`-ihL~#zr zeZ;K>Bevf#?QIX+Q4Fm~RlmKtzftgMg z6i>=vp6V2lym<)&bx@ojiXJLwv1x0hHD^)@^H_v|D>FZaN~0_XREduB@paRXs7H1< zuiZB}dk0;c-?M$1v(EopX~OkYer|1h9OYSmHW&Uplh# z)Yp?T-*>bn2PznIr>E~JDQzs4B%Vqt6A*A^@lL^aL^wV3mrU_B_(Hy>4a9H5Axa#6 zR~;>T@12NQK)NSAd%;Jve0wh1^M0EDswR0u)4_PkG!s*LMd7vJWrHv4AZa0jC2w!< zyu|h@LeM;uUCjYk@7K)<6bo{fe=~T7Gy^Y$Pab?TngrkgrM1RpW(9;FAs7l2M$6)~ zBVpRzO~6>lK!BF*C5|nmx*(ywiLUkchZSZnp5(d_!Rd9Y+{GqiyoJQnhaGCMf_?FJTv+ps$ zY&D2J?V%JONGW#SkBT0DD+<1>utkk8>`Yi}tmS)W!Vmn&&VF@#Kk}r)L#Z2Hq~nGq z?4P|q=NH5vhfKq`P5WjqRl_vOoDBiR6ISzI<}Lo89BH0HTj`2Ta^cVQov9&86Tfc~ zp5)Gzmp8FBZFW}Q?R?+@!;BGmEA&%%`R+U;`c7JS$RTI33Wm+K;mco~O=|VL1)n># zmxeYGepT_f;=g1cy>P(XyRwV`AJJ#ihnaut6@SercKkgqQywS3SY_2kn`?rmhrg(l zGfhluUwyZUd0<^5)_%3J?6sSFwSj+*T#c}f?H7e}CPI?@)Awc&ruA_}!NI``EBOF; z7TiGd$bTU=)JoDYuj3zLqXFMl!FZ>H1ZBJ;X+Q5qzk?r=!i}1fN86iOtBvaG8#IrLd(f*IGjMS@iM#bTG*=sxx|w@c^Y{&X&8=>UEK=XC5Pf1pz-dG}vsBNC z2=*9nG^Se`0-ICgHnSgH4Wvmj5YPThzIrqOuflOzf$75JErKnpL|ea`KcWsmg5np( zjffY!nl}G&jg%}rPxm15ZURsX4K+BE>=vs0d3;}`tHT&okL5523f^~IuQEKr!K<1OFc*p?JHt0P)l*OEl zpSYglb!PkQG0?5^+qIm;Ug*;7*pYpoFT)q7GOrsU07k4g;}{aK3>@DeCf2o}pcai{ zG8By~X8F>*Zr~nsX=(w=%c$IQmZl+n4&v5TpZCq60VqpweBrD=Y%#M#3p`FSn@f^; z^J31O%4r@N(i~^6t4@8ET|Rr@rEksk0(>DY7r0ng6n1|0fuA(-EfJSQOT3grWgaPk zhqUN?Hs|u0GkwGvHuU!;Gp^57Y|iMDNH5su>AH$3?shACyMVY2k-`;A4YI{aPsHZw z&c5}(dGarRd|@5qPJI4v$}q<2J|xnu?X$k*$)^Q>llu7o#Ubpy0M7xUl6d{PKX8S_ z3vA&-<7effUPu%!5WJ`SF*t?houquQXX_ zoymE&n~9Jr;swOd-nR>Q@)u;EiT}2LB)}fAulO=wvLSbtHJNZA@(6a19Hhf0ANYjEC6_4ea~-dh!28;O{WJ_ zFMPNp7i7hp^=1dWNWR>vH);uL5usZ?La{J&0)Zpw7SJ#R8&5Fib5tF9+k%7~gfGcy^g zCIoF9+V2`rL$r5>9e$&k*fed3!H?6?HNk1I+~ZwFygjk&?hQ%q``_eJt!YX5+n9O@h~bkriX`qK8iUyIIO!!Kf8kE0GT>RC8PE3MT6?O_?X~tL_|bd(SAX3i{npuL4*`k zD58qPTq#J@xN|>!`jn7%^91^qYtG`93J>_QI(tj=$tO!n2Yr+i)1NsNeuFPqzhAJa zEMikhY5c*^l23xtTeZ}-w2$>Grr5L}YaVHGmQA9o?<`@w*-4v(>DKA~&q$hiF z@hR)D)`B;qK4*@zXG<7L_M{#>Nxi7a$WOU^K`>IqEi}B9FMQ)@^1*C=`{nw2SkZhh zXP$^IOW_lulCu91vCl)=K^|C-kq#IttkFCI(L2Fz6G0qUO~(~`X6%M{YKr&mx>pwj z!{t&MwvxDGSPFC)pWR&qzmE`{dPihz3ut&51cq)e=dHVM+DzDk`{n~L4YPR>#xHS= z$ooYLkmrn4PM#*I^=F>$cw1YtxZQT*@Nfv+W+Cjh;YkAL2C@v+{2zzNLoiIAdVsbR zft0Pg*67BeymZ(!tl2Ga4WTzXAfV4n+G{jVm#`C1?GPl9mpS0ykEpt~o=xliCp75ds#B@B=Pe+*b&JtF*SVQc*wT=I8hd@&|9`eGi( zBgZA*rB}5^hgQBfA)SVckv=Ipw$JP2?!`xo#Rbl?TIx7<$F@v~@@Zc39d+J+Gt}mh z5DaMkt%$Yw4(qDNUc38=4;CDOt;suoI)OK%xID(6y-~z`clO;(x$}mS*SL;O!8`3` zY5cQ3Wu@hSmE`XZ)+hz}Fms z;^j(0ok<+l-QmI6`|h!+2u!>5ufOBwK~jdNEjvGcs#@k<@7R1_tyJ~ccF{b>hH1{m zRZhVUCVl=RsT*1tr@EiJuPp3jh6!*9t#5yux2!gN(Du=O891TyoF49tc}Yfx+nvL_ ziiOQK1hM^Aj5b@Ej6D@}&xgB=UWSV2JM1bWGK5CwX0i49fnglhTJs$u05^S~R_IWC zl1Qvprp@9b6{$^wdRnUtC*A9BO>C{HPSw*smTBd@Ou5yGCY$!ih}Y-L_Q7>Z?$f=; z)VltRau5?h|Kum$F$PWzuXDn5c1-vgEed<^^ns;FtwM46q8w-EJw_7iqOOW|+!C(n z?--N5UtV>4g_K`HalY*rvGd(H%cig1DuMTL;h>mztB>wFOSpQDjr7US3I3fN!lhG( zg4)NurN1S7lKR?eI=#&P>J@w1;IL)JBWE$%Vl~xNrE#lq8Qj2v@cx|3&AR52F`o}t zzr57!(ZQmpH}%J@NMuEQ z>aMqhrbHH!mc{sU8KhoKKqI|HVG^rxhR#(o3k2q?CWsG>am6;b`ld~p$Ves!6gF}B z?oriFac;=^>dD9xpyV^S=r;>xri3+g&u8?iQB;Kr5 ze_fxZvzV%@#(hcKb$dz3?f1}z>MAOzO$y5HDZLrAmwU%G3z@Me6LM}=I8N*N$9NBP zcHu$>)#ZaG+PPJwRFsyf9vhaH&VcUgQ}_{c#CIlb>cv)09TD$p?CRxZzp9uo5oez2 zbSkq-*dZmauRk8yR`N!uK*=(JK@WD;iVnT}rK8-}-J!LkwA1;a`f$6`zQZd?XZiL| zH%%-~J7u|{u&u2oe$vD|;!Dav_=?7Jdz;yBY}yn~r%Z;%hAnf7wdK?uxY9AkULSi^ zM^z(V&o^4$=b6dGn=ezToQ$&M#br{`N9ON+)-M$m(~@I8ex$i9B7%~b!<8jtcSOKt zq;DAQgmK?=B@3?}bWDi99$xLvzuLE2!SD0(nE;keWSnI9cK&l5i9OYw-EWC#_sDA^ zR_w?cjZ6t#OFAn-7zx2zAxgM_Xjf2oX6{kqD8Kqm>2S|EVHcT36T=aXWr$|2`d7Ph z?B?q8^tl>rY)rgk_}*zvmoCl40s@6gGOGUEhnKlVCb&$UmJ6O78?n*n8r)cB@%4aM zH_sc_yB4YDZ(1sJ7Oi_o+VJGI;Zmdg#gdJGemCI?&=lP?!em$m52oC=+7b1q2;OFA z@Setvst;Rvi)(^RW%SLHn6QWG7CODMXA@-_y$Gz)$=BG_ug6wCseWK8zE-4K-)OL3 zU%K+ucV1D{-+MAzUYdq6a_U92QvJ3Zt{8mSTiPCM9iwhkZI>{eQJP?n-OEjerx+R< zOIbj=oS;3{vP>=AVfeu)Wz?&;B{kN`?u)bd*I`{rdiNk&J?Hu`$9)Dq>o|MX+cWJ- zN@@<8GYEBVe>rc-C~ac5dr)qrwb5WGg&7KQs$6Ajb#Gcw{j~`Z!>I5m&5H5SqT&g$ z7KOTAs5!PwdM%DM)p@1l`JtZJb2-k9^XvWI*JDX45y=!wRzr#!ro$Q~ew)7z&SF5{ zGS%GXOAa@?`zBs4T9K`|M&WCU(5SqHVqtP7u^g}q%I=2?t_Dg}SnK3>*1o!MoC);& znH57lTg*_g`}`@PMoEDwMzLVgm4xY-@*15&{oc2c7qYK-R?5UMBElC98c__#jb0d? z6l7VaW^eo~SHPup;;32%kuiAw`9v|?;zif!NcAbJjDX&jnmw&Zs1pflX$d1D+_L$vBWrt)m1}0uK~w;X zSMJr93?8hi@vp1XC`FVz$gHtWKNT|~RQx5}y1UmQ*e+3c^JdkRA)3n;lfG3=b@;g0 z<|S^jNZyM1P?oJN0hUEv^x>R%$qaK_jh^YQDX%AqUH9pefA2ES-`exF?fe8&QHR=e zdGtGHkED30xv1IH=g(ZBcyh*6SCW93nE$Ei_UEG0b>n8^xAu)EP$o>r2k2u~E`yzP zHT#;3oYBysy9y6COQ}>c-;3yc6ruMQb}qdRT6j=;y3dEoO{gS>1_O4-vfMKpFbL14 zebp{x&1$YL)nbcun&&uvC_f?2-@oMW>7818_BseA5zvV3@jPa0* z=FAyd<)6o!F@HFJ;aV1x5T_>sOcJ_z1nimaZddceC$L-i43ET|1`bf;!Z>X~ckbAD zy*aUw3&29t9VxTGPccrZN*rn>@ti(Z<}hcP3DFk$d#1m8IXxX*rkpVS_jLbyYY3@Z zg1G1crn+Du{Eaf0G7w%J+BzAO+sX_t4h>D=p^TlP95PL{`YHw9ar-k?C`{{{#W@pXi4=e23C@zn6PP}t|{ZNxKk0#}baLvfuFqS{<@9KTW*)ns`0T1+ zN`@%nh&{Y?pZWBD-nZ_nSn{X$x!ZZ>?8$57NUE1)uyzR)I!M^{EXr{p?cFmI$51X? zOR$*P8$a()3KuA~?y7Zs{^#$$+4}BU4C)yYN#;%S`a~rm#^}44#qkcq9fbH|yxv8! zzLTlFa+(n#E$XAy*;UUy{(ZXt12?--tpyGQv9%B4kT6FX9^6yCqpg3glKf~+8B8>r z7?<@*q%$ok5&#g!W2cKLL8QVboYnoH|=eJ(Sd!TV+tRF+&*y%a&lecC&p zEmH~v`TYF3)ER2vm^)Oa;!v3i>y$EeBa-V3407%yG+%kt)TowO+TN}v+B~4roCCi7 zW0d=?=8xnxXQxBvk!-VARus6$IyGmD50~ji=Ob#i%DZj`TW3(cUW|TLt!Jz&C0;S6 zS|fPMadKKr5{oWB{ii%3K(BXhPW5_n)#)_jRuP}flFQ-CY{LaK&N?MCF0ZuXih08b zYNhbH?b$R~K3^y36G|9<*O_eQQ?Zbmb5r(=prkz&z3CjyolD(gjq&(&b1_r;3~i^Z zee~JiN(#25w0fp6iZ3jMvM&T2XU^-v}z1k^+b21C&=aQy2a?VpLy&s&a5>S za7W5P{ZZ_ajDs3>JIV`~vN4(-cEEiplV7;xzcO1X{jG#f^({R;Ca&ATXj-l{iCJq& zm<0NCM{hBQk|j1#%5?lF<}@9kj}O;Fa%)}gc`>i6k$aq>!OS4}9!m{wHsE!))GWSs z=QSJ2dr!S9LL1WFzXpVy-8V~lk51GFBy{IaTOAB=aZ$txlU<@)G1YBL$bo6of74VG zoyT>YQeK`-N{brOJbERiD899*WmIQsYGXBeUbfIC8!1$7(Y}QF@sgusnGSKOhkJ-L zJ!7btF34l%@;!i0DMrL;U;KTRC+e~3BdRImEp*Uht_yXe&$^ztNLJgqsNy{fDcPl2 z?JeX+rA5rzfn^#49n!Ha0rg{s)FuXHY-;(6Rn2!PQ-4%Z64Ogsn8kH8T!qTKn#6K* z;taj?pVG)E>fvI3<|_JXIQgJ1H(ym=*u}d~^Ly8r>9{wSs!Im6&9-^AxAR?k`+9lE zF6~^*k|@SvlB=ID%ko#J#l-gWk`bpxUm>v1irDEXrj5&M>ug4TybZBTgS|n;D@0@h z@0<;;bR4Wt7R}A6sC34cBMx~+Nzd1QeRgkk<}iiPX?^=`uGbUWm?z0jvW*veHm37A z4c^Mz``yIb2>p;^_VzlB)KsQTGZ`sQzu(SV-e5@|>o(@HYmf^5_^I!#d`R5GWa@PtSQ` z14gV%yQ-0MjpnG28(q79_)SVx>%M@_s*eJ@7Jonchl=F&J@M55_Xf9hYhRCNxAZe@l9?T~hwQ zbj!5$@Vmw9d25*OTQdSND8s3ab|-SM#u|6&f?uDOkPlv$gfVte`bhmmwS4I!xf3WwSQBiJ7*kBtGMKK|WD53}oNDz?> zDk>rfO3olb1SIE-0T2UGl0=UL$vKBcC4(RtNlg%t*yN^3{nZA~x%bX|-@5Z>);F_e zSnHf6&~(4=e)q0=s_Lnyqyl0S5)!I{G9t*`RUSb1XYF@h(z~SYYrMS763}IJA}iLR z`JeP9sPr+E9ZpY>5forgkf)WfWZ5bwXJ@!Q-=>vs5mDlPCMb!d6Z!~p$fAy|S@(sg z&A)Ra0X==-Kj`Ug?-@NlF9o_00v*Oy1plK~YU3AfLoeX?5I3-Ow18@_x=px0jFXdD zuMZ~AC%Bksv6Eu;Jv-Wq2R%=LLv!p~Q+Xnp+o(ipivEz5dJ(_XQZ<>cmAY#EJv~Ry z+Wab(*dtfHe#XTbYHtYvu~%j?t$o*+SRm({X>|E(*DdG(h)jpnZ<@0vc0TCT!urDZ zg$F<7>r-WzS*q5eRv-I_mY+LGzrt?40y#kQ)MdB`^xp_+7iK9DpbFZWuV8C}B+@?> zxamK0VhUbj%X15|R!?FcNbb~5TK+etW5&iGrXy;U6fSCmGNU%sc*_<_+XRL?P9|9(Ba->$%uEm2n^4MSs} zoqXKA>)n-#D%Sh)&syA%^-_=@-pO={=?kyUa7`Cu-UWvPDr1y(_`AV+^=DN|!kY{( zceJ?T46t}J(e6{1CzEjth(H!7e-a}_(YFexLpLG(Fs7eoT``br64)Z#O+ta7J~9ej z4t3M{xG3Pl^g^x_@h#z7k)IcKmKWGBHYaWxoyH8_-Nr>2d`l7)_@n6TR&;B-YnE zIo3O`^7xeG&mqDT5ic5+D%vYB;j#ub!a29Kxv90V_8*vwOl~WOa_bYqTY*lMuLq<& z6`;JqP>J`yRz#!Hu$!wAX%v{M5Ue^G#@^)whiU}SZWP2?K(_Q35Ol<<` z5hY6MjUMYKx#B-Fm{%8`PN486(<(kn5p6$>+l<7WS&l##mCv!B59EZW6|?!W1{bcE z4a?vU@7#r%_0%PQBHaT6xdW5aijr2NXQ`{CW1s@q_If#Q*?AHqq%W_U!g&oe50zQYzRy)i(-_}B z(~S#)+y4MBNU>jgeI(j$$xJ;G*k#U3lUk`~jDe6uMPG0Z2yE>Fz+GKf!V(=}$kRep zeZN(UDrVr_?*m#-BBqYIlg9$PMSFMfjh(O@(o}6__|E*kSG#3gkxNwBcEq zR=NR$YZJB+JzP5O-B9fP=5+}92CK#}ZpMnp4x!8M;;Kp(qD!+K`}~)OHU@oN`E>3p zIS;%>Bo2Qw;VV^+pgcjz_fTI&xmtXHKOaM+RrzH1rl*V?CXd>dK5R% zJCCG0J185>4(Lb8P`G>blIRIX(vp+wqe`9T(N27%D@~DCylgk}Vp3#9Rg)cqDPda1 z?B)A5wF?sS$J>)674^S`T+`DXt8$+6;dl(%7lo$ZZGLtYa-9<79rY0{Jzra+k&PvI zVMF>ql@i~vx(@T;NM53=gMPE9qYt~bh7D&VD$x^_K8d7fF)rxhoL~zUwrmL6<8l7h z)A+jFPOb1I(%33$u!YZ}=#g3R;h>9t(PLU@Qn3Il-)xORbr()1wX*CB=)c-I(=Lwn zpVXGPsx?hHar~3DImKXK_K^B-0ybK2z6|2;uFW2r+1!{{DvP)zC*8;KkUWaCZsium zDq>#gx5~<3F<+lH<{zB67vt{z*A{2Wom}ZBmN39d7RX2`vZxI#z4<1kjRl5bcKhl* zhHN~e(Y#AkNu?0?Dg>pa+=LqpUle%Wt*S)nOovDSU6>Cuq;-Z_)PrGs$ zmX?+rn)LDfBlZ^soJc#%Prbm<3{cEdGGH(R-?ib7#DYZu{xrI+x{>4pel_7&7Z|Gr z_47B)jYpfpqeWLXMDJRbB(D%QzvJUz7&dKJze9CoyK$f6LTVwtf9=Xx1ix4n%r0jm z4U^XB#f*UEA}DimGcP~apt46vzSvFNlB9%}!8iA>cjRJuel4v}x-F%Pm*9(XCoS=A z*!)%drMP6ogb*)Vs_9}rjKOGO{rsj`NNT>?-5+w9N2YBwACguqxz#J zT571G*9p-L=xwGIIv>OC7#?AU~*^LXNbxNNkmEzU=tkg#{%VwIE^DtPgpimeY!lk z9!xZofL`CFC@2XLe_=_nsHKWe7xMZBq3qg_qwjFpY;2+wyw=@cM6m4-cM`;(o>RZz zEZm+eGxp(y%i=J-@JMLu>9y+UjbSb=IL1uR{~4ud^b)g8nzNYm;J7MnOOBb1XWnKn z04d_gPI!OxfO8Kh|IBTDp|CXtF za2~FA`-|sabi)75Ka7{Q-BDtJ;23Yey)I~;deXT~Wma2)#-$QH>d^$9_C%4H@$p)q z#JW{YZ0!vU<_;4k-U!CR0Zmoev|!M43fhh;xbpjK)nM+A%0UlMMufDh-KeD2>OY;F zOko#d5VE%}`bg_l24-4Q~qNTIbj#fd& z2QVTcB4SM=z%&C!~VS^aSWPt`2V9XGmt-_&!mrEQ6$(S zgq^N+a$&L_F8*oQ~B?ufkbMad_mLMOJEOcT9lhrw_JNe4k zo=lLB<%fnk^m)MmQ%f9H56E9o(g=xANx>a59T4P9ET zShv3k*n@V^x-4-%Av@3%FRzSkej^GFVTdo8KYfRMrv=<` zdZ0gv=>8?~W2PWQ0h+>y!|chnOG8DZNS&Qhb_uG|4$2HaVFU z1`9}yHbqAx-i-vJbAqlr7hG&1u=1G`?6>dotoMZ&qBxN08=zNcAyLL9$uT7%ff)#* zOMVup@fLjuB2Pt~F43pA`} zuEJCnUl_a+pPg+rv>(wE;H&Bu*=%?PjKj2o{T&DT{1pqxLc(7M!q9s*B@G(|k$HdL zSYT8k73L&e=!&%Z6a3S!byZuoD=3Ws*|!n;%~2}~_dhh^hx^=dyIBTjK%y75ZcRC( zNFVGQw`K#uig)lc-#-v#wr@m4x>e|9}`t)fyTQn!8Y@s^}x`mO- z3}|$>LiPc;l82l&m#2FW0*7Hp6oUEYgJ0D_0Y*0|_m5rYjh_olgswiMc@o+RgLB-n zBxwTAeFwRZ71p|l6C(@nj~htKEQwss56WIqqK-zkj@4@QPS#Y3{-yRHCS>tiA{?WA zuzxj-gRQ?H!5{)m;87kBF8RZ0CGrQsd;Hxzj@oeA^coHA)a-nMeDw$84pd()yNDzG zg+x&lvC%YtR8NknjC}$|2ScYv=3xx?M|fsDqoi7x+{q;2b4FOe|H8XBf4YZsr2}== zue1Gq6^6GTipbp#ZIvsPp-xwg5XSXcA!n2*f3HwI3b`S9flbNWb8V_;E{@INg++eq zN67k*f;P%JmA-WSu4>~g)>LE3zj2#IpKN9Qg>a#>wpC)ei&d}L^ zvrp+I^sBb3zQo;UtPJ}{N~!86w+4 zDlWP<>(A931O5>3t)d)8!(e`?C~u#&TtFh=Yb?JVq622x6M8G1QAjwQqdy9zQW7O zD1&*VT7Ks**xMtz^lQpsuR?lEi!TEryML5{bNiu7U6H(wCGWNEF+ph^=++2?eR8B) zD*PIfC;`Asza$X7Qo$U+7`^_BIr;P#;^1 zvwRZw^)X!6`*ZEFz8+!jIys~ABL`* zVXQps&D4=+mS;%)!+{!Am#7S-OJ%CH9**V+nU_?ZL%o{~|K7W4#d4`J;y>g`Y9m^S z^2FDW=|D>4Svszd{G|B7`TAyv|k{&K~+~kQUfN9EZy# zg!vd1|Dd|JL70L&@;iHAt87V_q4;Y;vov8IrZ_m&45O}Lh|JKQgW*x(*tKHpDZ+<8 zJ8AC1zl=81)G9DGYaxJwlEjrMb$#M*G(4hfxW$sc!pI zAG$~6Y!F`@j%~6p#E)5~eMP7N3W;3sP4N9Oyp{+lRb`3JqMl9BjaE_NkzDAmMsRA5 z<>2;RFc?`&XNG#)=uuw_m=Qnm#B;6Sj@ z6Kli~nnmML+qpmwuMpbTywoTE4IkIqJ8VDD^0RS2@s# z>WG0FUqg@oV~4id;H(^z2!@5J5tZ1Y6{+B>NvdJ3yaD=Smn9R^uKov742jHV+t!x) z@3DMwPmxuMGur_U4Zirf+r-Ung}>E}ik0mqgvc5JdY8p!@O8|=$;DnoTF+ZNWMMl>;XPKWLdMoSdsrDlbARTJ{L7}p{Ia4 zDS_EB`4VRa-5|P~tRZ0X8Ii$a&Wg2Y{v)>1U?}?*`|2M&|9=5V_bWVnsan5lL};_L zdMo?!4+?h}u-_J)`tK>8g^;GE%qZQTOTW{&-f^^G|5lxvE%yHR#K@pExw~-%Xgykj zOhG*OF^Lw)wt@@$SfpfTDYRY+f()e*_|8R(6;3=)jOYP>-$uJSIcoM#e!X zfp$|AZ$YAg#r)16R=;NlElQyf zv$g2qUkvw@wCEeYPjSfAh7kds5Z32+sJqj<<&jxQ|7&M&)1Dkab!AM89#-jTqtvM87DD%cvT}k1tu6=OB&1 zgse-|+2eLv^Nm8JKC z8Ec1bA7J|R&+8vcNnURX6)9b{0R_>Q9$2au>7vG?4dkVNa$eU{Y2+}y{nv_Dm!LC_ z?@{IUQekGh-(A9(hHunkRuV)v#$QtX!SUtBc6Atgm?Ig+GZ|9PIr(>L-(FWhAJcoS zmr%i{GZQvx3F!w5Q93) z0bVN7`{t4Uya^@{AG^c6XQ~6Ddj>n?<-2LQQ|6Ve8!Y+d_H98_|iJVb-- z9;S1-ZLSCQ>jFY9gnP_}<}Rd}0dqkILXA$*(JGaRj73;o(XD#h5W$c1|7woO2yw+5 zN0OuLF+A~bkbpD*nI411ergTthiEk+2r&R*V30)>{Y3CmwP?ZEo0H9=u1zqu3}dKU zG9Tpeh85w6$XWI~jE(G~U%9^2i_T zAV3`+D!=8gyC94qfAG=T>MGLgW0U{|0DvTcW6^G|Z9nFMlr(DrIiRPl2kPp??#{Ac z7;PR4^=LF+7U|1wD+#nFxxlFfDtdx6t*xeY^X3@^|1Q}aq(B2=Y4>5_F4`mX zLAwn)OC`Z~q1D=0)k9mF@lw#eFcFtkiCqKGQ998HgqKfy%VBecap^+4AW*x24|3m9 zh=wER9ua2AGpu_&r{%$jY>HNgwO79&kYE9E;cf){rUpPnrknzC(x%&3HOJe{kUv4s zR&P0EOCK*yv=bqG_iIm9Lb6Z5tQSKnND~DxTXhtIav9KLSW<@n)s0w!r}La%fEmgk zjShDMC;%joUL-#Ut+`3ncVx$_T*l)<=3!=U>1byjNO_@WU=V4e2=MXFL7Q-h!9a+5 zVi+j#KHVDX)cmZyJ3o=*9w&J@gxsCp1;5f=wbYOsIfUoP~Clwe``tn43 zE@@;voow@(s6BwJ{_SM#=hL9I)CBY}PdY*874zI;9{zr!fU=8=OE9~}2PkeDrxiZ# z;$fA%N4X5U^cMhS31o>ZQe3SeN&XWwG9e)t47z*?iHU|a#z}n8gb&;AflDtixuF_& zWY@sGPAfnzfS$b~j&0t|jAX<_3ICe=DCRYf=IIr#47~w5hf3$B^TsL4__e!)N%qHQ zcM*R!Esy;e{Fc6kdJzGSg!h1efF&qqj(`ZIm`_u*s9V=277}dg+gfYrup*F;a+C)+ zN;rpdo8(v2=1`L%U@J*r$2N+rO~K{B;5kIp^PtwO0jP2XMw&IibkYi+!8+My1Y|(~ zow>wypy4DB#?N+<^zaalBWwUir80KbZszy&g9JfB2aW-3> zJpoejBbE+bRxB{v*bf#kMAPvS(%}neh!PeYvE+wHL&g#yG14Z0*3m{dJYLhsgy1q5 zH1b~@ggFl_EiVpgK6bo{q#6rB0!F?Lrnh@e?@}MvlMVpugLu5~$WK|+{{FH?I@CXz z54HnuUoD85Kj}#;)$K%@X>~9d>}4xM4V%^RUm@P$M@q~^#o}hP5!Xyq;h8BOi~-|< z6n-cQJ8NOmvB8(;dmPq!aGEX$;qm_jyzUAk1}MU-;S{mKU^EaUp_y}rx9y+vv163j z`lS;kjK><&z&k263QVS;u2WF=B4qGGZbo9sX#WF3Hqn3HjoAq96Etv~DdCG;ZLGOI>@gNk7edcM$N(oodY&$X79RC~5IBVKt1pPKpIr9Jgq5|f?tb(`&ypq zbEVRZ zr8Ga_U}9{XT-IR_<-mkn>n9`)hp=m?PQUW3y<&tZ(VP4FsCx5J&qCo?`lf+TM63<{ z*4hn7!FXsjV z1_Rqai->^KU+Q zkWE7AOsG0}wV|3JI;vn@LCkyh6`>d061-Mehk8~y3I{tENXkO6b8DXOIgkY}MsVlu z*rIp+qb8Ugjh-?@jUkZohj-DwYpxNN{H5NA`CG_7FWwKAK1F`sT@G*UMpV*j)FP#m zy~J+qm+K5d^EF#OA4x%hR_z#6v1(vC?*cr$U&&e|czX!mEEzdNX!N@a0IRlp=Y|F}WWBM+OMgg;v>wG=NaaK4`%T`(`_*>d%=MAtf8IJfb zP00=I10&^uT8)!%^OmqHC<>WMj=b&O5z&R;4zVtRZdGu}@M%0vR;L-%Ai?3lp(%st zR5baF+fuvI0*ZRP4xPSd>5T2HTk(J15Euq!hYZ~ypP}YP!qSq$uKG-Lc!D{!MD)yX zbpaKKe&aXtM!cJ3JG+T}A@;qMOO;RL!@cUMCtv22BPWPK7)P)lVnxz<-=XtYa83) z>upqureal$1v4zj3lpyzA_enT3)I<>6KVpsMYb8P%qYPS#+Q43Wi~Q2tnI;VE<+QI zT>ETZRww=mTz?d}4N5_g7T3H4*>THA@RcxpCcLP0PfwusVv+s-buNOC9$I)kJ2+&vjoNL$irQHjzrkg^#I zkYulg3Vt@Y3unN?bqLR6iQ!m&!-OkRIS+RYaBOyxESM&@k%s;EU^bNi*0h3iNdDD^ zW8e*Y(M3qyG$K3L*ST~HN+9j-vvB0@Th7OMLMkQ5u52L^iRNz(act_`eYFbLa&VmU z%zb#iXgF~Z2UqP6_D=BbNP`Sc=6UvUA$w8}Kujdse=1LD_SPx7vaOCFob1E|S{A|pRnD|9Y>A{H zI+>M+SwlRz9W1_%fqAS@7z3yw<^%I%(XbF0m{K$M&5M$foSb#XqX46eeBCYq{(?`U zL0npBuHsliN-kVxcdk>>Uaun1IBQJPC`Kj}yscBkkD{#iHUPB&Pbu}0>~ao`dCQY) ziSNGy5vF)#U>zY5OcbP6Ke;0L&m^ansDhVvaaKiHomSxMP`#eXs4^WCi>}!P_gRf~cp&G4AmS7aJL>yOf8D#Sic>%l=7mLK*%VY&`naA6{D{ zP9S?^*gqefuLr3Ygl7=$f^>vYg)vGMAXtcyJP4;=0VlvwGJ7*X4@^P(>-JI!gvRnTu;lw2!KA!a2DXV z*SkKfo7+smu#cP%5)*|=pk4QvG#yH=qdKs1wbn+vmI9$>8n~<~leZ}=r3ap|=sAno`l4=0W$$&R5gvqQz;LT#wAJNFHcDVr6TUiox7P~)b8 zhOS1Pcs(i&xASxWjmRi+e&Nz3($qUGgMa8b3G3@C=j69$S^W31f?2E^>H2N`#Ibwg z24ID@^P|uK8w%z95*Yl@1e4#Bo6xRAr7XxD0`m-I;S=}zLVp<%V#G#v1=fJCYCUpwfwmcnf1<5~C4o2dr83*on_3m@zNDwohEAQU z>bXs=;l~`cvZ)uc?S-VCXMgz6!hJ7f#(UT&xE{&yPL^p&);GXn@_8MKE;?@w>9a7w z1mTVJWdp6wL_yCT(rqnQSgEz_Z)`5(&z!N9Cga4ElkfF8ElEmtfvpjn9Nq0#bV-h> z7)c%Rndp+c$r$u1r?qC=O?3*uB`;6)@v;;4^7#V~ePFkZTs#1Mdr6FqHCw&Uw5T+} zf2Pybzo^+;x%E%w^*;zj$n|PJzieN>-Vn*l%nenBng00#_3XmL_tEqM5h2Sn^)t~k zCoN4;o}Z8^Y1udx3^6y)NLiUhp@E#P?xB+Tg(>H`1b%bv-?GDTvSN*bgjB=uzJRha zC8P?~>4Jr3rPz;;jFz#^oTS-x8CiBpm(!`K*;&7%OD?2lKaMB-UYY9AFnUr0k;{kZ zQfJO4lHOWIXXe1=1#UBGr^gL^g2KY3!Yw1RJ7e$1DNK2R0r@!h%v6 z2XL7}PLAR8t(&WKDaJG*#(8v;^(kT8mV^8zL?Xwb5o#~jLNl9cwGh3Zg_3Ay9dJAr z7Z=~w3qwm`7>Zp%1Y&-PjQ)(}j0UxqUl@110i=G=R2Vlm66^p#B?$K2K0y7rqv0g6 z1LtN}LxgNp5R#aT2ZKlFpP0HSI+}OoDKj_8*tqk0alYG1|R_XhBT=$hBdhW&#{O6O|9Sk;?!^7p+eVgci zE6%LRghYm?i_ZQi&?LP3UE*WKZ8f?mv|P&U6&WsSX4>yC=OH%w2qkx$^poc)n}mT| zua)EjQB>j31~$0*jGLuYb>Oc^($rVRlXLydA9$?pxK5WQ%Ng-);%B3x`gtn}WJk9a zv|vVQGV2kp7fK0uo5_g)To_i6q_^3-K3k}@_x^OY+WgQPj>m9Phn>FBQMLmispwI) z!S@J%q+$yL5l$1F*wymb@Q$6uo~NUsWP&CDj#2{_F2GrVuQH783vjb{{XGY{e5jV- zYRdWCxS?Oqayqwjb^GDEbL);akg%mrzON@l2zxh2&h7AgR5HY=e!T6-sld;@6bvtE zWOQ{>j&gkbqTCbM`P=(a;^V}*ly;l`G=)!Tp;aC7lM<)2STAu&G}C@Ee0%O_%08pF ziZ@1PI0p{W6uzvV-Q>#Vbu#5Fr+D#=upslj;W24B>g40!&V&Ua%O_V=!y})**RB4m zFm4Zou_p-RUp_@go8=onF*f^25xS=(rbQ@c>eAudyt3Tc7NLQucT;i>L)~AClwPNO zj7?ErC$tY4EAG<3>^pGq#=|+Aw)P$Zud{}Ra6q(FdEo)vuu z4(hR!Ow7X1{Lgz1cg+Q!7-JKn3{v2=7@gw3mB{?4Do0$ZvHhX^mwSw&VcJW4-mx^8 zV@KeNU&YER;oCPY%eZ_nqO-Fzr(@g2<5XJt zh3{@Mi0kTpYJZTCn@gqQRd$@fL-_gg$CF&e()17TKn?%-P#e8n|hGh((?ZDrI#5UIk|b>A7c;88(mekh#uXM zX09pwN&MZ*kbLSK9v+>Qq}0SrB8}$dvb`QReNML0Pjc-e!<1_JT2Zs#RFiwN5_)oW z?xbg;=p}C588X|T-Esp?D_i?A>IAauYQpGDGh8CRUuqmrY`!1C7Exp=U&Q9QQ5zC z3=9tLSgIfoUG6&n>MaeW$GO9p2UF{VwXlQlIbv$wLt^LaO$Bu0>BYXU zlUUxIw4Ny{OKx)cJTxqQ3p4wozcq1fbC9fcSs~TLg}=6Fk06*Rt8=`HA*I z%7v4UEz2-56tueY_L%a&_HcCdipQw?6cZ+X#1vD)-70=lvKqq{zbtHO^mH8BU7W1W z)2^y_diChT35gR5Z8s-P2kqbA(5=v>!I-`e4%Pf-aw3Y+@Xs~)j6;lH^6@U7>52J<(* zkej8rfrND5QN=i{C zht-*?t({j{9=m@kGH7yqoIL0r`MavaPY;l05-sy!nGNzA0}zGrEIA`!i;F zdHza+`L#U06VC^;J*c1NeX@NCg<|))a_8mwMGq$hC&JNz4`|#aX01z$%SW}o(Fwp zeD=e2)qeTX+_iD6(_e`l-3mue$3^Xi?J=+1m4ped-}RQ^sS@kskNWu`3Ct5V0&J?Y zJ7ISXJ{{aMXOUf{+MexjA@h2Ar`V_Fn0Ix*$Xb-x@kd76|$CE57w2A!^2bEj21J1x{LuXLRR^Uf8f z`_#BBGxx;r(V*oBF`!$f zht~vGl6X$O9iNR$Vt2Qiv>GnRm{Pyv3?W2I^=0jZH=o_+xkIjV7wGMf2|!31`^)1P zF26EW>-$gV*dljL;qka+BK9VyGq^4;=lh{2jk(_kl`&E5FwLkGiL;6n6`b7z{-@Gq zU2i6PsLX@Ex@DNUvB{u|GjKp{U!F&`=00DK;km`diZ=TDo_Xj z96gEj=Z7<%t}(^#CaibwJzK`4(C(FSP59V_QsK~8o*LEDCd0}RW?xFiEJ|bB7%@Th zyUtSXbH91ym66FoAhKFatw=~k9QLM%ag`jtuG4Kx-}#MQ7IMYk(Rw=(CSp1#2dAeG z77AeqGwuA-yBNP5+%ph$k*=a1hLdR0Ed;!nkI@`10*B;t{%5)B_E+xJ6R$&_BJRa3${6~dG=t*Q48@pjK{zA(j^(N$96)pq5^ z69qa#u>@o}{Ea<4l46>lH1|Jp{J3F$`|RT;$2vy&97QTtc~4J|Buq@tL^mL&nAF7a zR*U`9NgjT(j%r%_2BTANG8&IfG}PS(b8sX}NwM$N{prgMF1FY1_|h8A)7-ir#i+Q` z$jc@#fKBoCE!9k~E?mGpT24veR1tniG1-2M`BnQs%YmJZ z5yD`{^om_@DW3zqsz`r8%@MQOta?{Y>geb^c<|t?XZcr?uh(wwqdUoUX2Sc}1M5^X z?6C_c%^qFuugoKwX{$sT`W*{f_S_icaQ{`g5VO;LfQIpo-e0jHA0Oz24pPP^)jcC+ z37@_0+4XyT1sk5XT#yPk{>+W8>J%w=CrQY*mw_rQO&#YvEl%%1{|?N?wqYU z#Fprx`gEUhd%4uTn64!6fl~Hg9-6qn|=C zj2W;!{|!gh9&x{>-_M<8PWa}#pfy`vf(Re~?rSN5wEHm%(rUK{8VIRhGDe%<)&8!t zedlXZ`IwP=?gCh0+V`HUJ3mtFzv&1M!J!6b{`o>{R)3~9B zN%H5hiF>TKBX8_`>f!KJwj(JtmnZkt2O;vh%o{)CPmLam7O_&K@N}Vf+_%4wPRYjQ zK($jczy{jX6OTSJ4AE(O++=Sgv`;R9YWndp;92FL+G&*idTb_CY5#$b+1EpBQ&LO! znA}foj}9r5PVva@i}byd%oC=|*1(&VSh#1Y;_jU7xPz0^slRS55UZ~uUnXKZ#K^97 ziB^@{{lI>IdTvUN3;L?5vG+9d_gn1osPW|@os0C$GV~SJna3%msb|tI?$0OhxhuT< zyG?|w9P=Pxj!du8x-~Ve@1ZGCrFOUW z_cwCB@|9WhwzmG8VlNKq-tm2YjuRZ>J6l1DBcXI3EtAyYx=F^{7AhS=yYufv}nnmN>F`by340)1T zPW*U=+v|cX)Oa=r_oPxX)%%xDtjlPne?8kNryDm&t$OtC3Ej??@B5ni-L=w%W@62) z4_(tYyS{Ti!{PRx;2CM_ue3*{U2(KmjgNvUZr=3`hoip|CK?s;GQ2K^E0k;cNapt} z%PHmJQPMqf6YIEzmmZ|kX&Diu*SX1ftYFi!3AW~>M-Lz!TULp|0<*X2jy{ekJ zQlO-0c=!bEPB-1krJ5t(EXL>CUGs08Nb=bZy6$&O`8Xs$wpv;ecL!oW%nbUauuP@Ak z?j{{9iRWZ9`Qm9+CKrzA9KnR=id;304o85Y%R85sT01=RIiH(2ZGU2p(C&|s%oWR_ zF1>a>Klb=ajwZ*xPlCu%8x+xkhlMw|-k31UeArj2iT`26%j>Gn=ek)}zmMWQp=1t2Lw&|GcRYRg z6V~-@i)+JEE@qd;9WkH2IVz;jR;w8pBv_pxXb&u|iYb>=sxGB|w7R|NBRVj8(-6bv z-2bE^uf*RFucM~Eqoa&6rSF{lMECErhv)c)UL2T9tX+GvpI5Zcd;N0qtgUR?PY-#| za%C&?^U_|*d&`FmqW!x>y6&hs1}?Xo_ZxKAx%{k}D3YIQl;$bTZn~`LJIq@fEUF~? za1Z0l^GAOxeSWB^>GRJ5xebbWW-`*Wb{B$vBQ@tQ=KUk$v7!Bt~dpB~Io+|?8EYuKU|cl|_aqes()Pf@CVJuUt-Fw4u=rO42`|Cgw*o^FFW0lclbrmulsp>$|>0onuRBucZ?>BaU55 zzg{W(@n(mFagqT8*YTPjgR-$tHMKnhB{7zb_Ad=g@64xt@{DO~UdtcoC8YMJkYhey z)LoIhb?esE3d5w_At80+kC(Nd+)rt?rce55l)(0~b|*uuH6!fS#;iK`>TQ7q68@^FJvuEMj!ECiKJGW{4N>=9i zy|^6J=Be><@6q5BLaQ~tDW1#EEcx&F(D+<;a4%4_`>1EuSe%$h4pB8g@sIE?fGJE0 z#V!2h2L(<8ju(5;=(r+4LvH1>Ys3;t3^yQfQjVp<@j>20hC+eQOZ`LBoK`!F)rEeB#YD-FA$vdBw z_wr1n(3jdC(TSuNszPX!}ApP zV6U@NmQSW{FmJlfzHv=w_7fSyRH!hFmXwtIXl@>y?Tqklk#bh$q#S?Tp6}U6CFmcp zi%soGwd?b-M?K+Q8MYF%_p~Wy@=|Vi{KVVO>wGi#YXtAYF2Y}c={XU9?n=U>Row#* z=Y7W9bw|n?7nv&t9K0=@0++vp*}DkOKC`!wEX)j0J}Sk`kLNb&Y|*3Rjm96)Rco0Q znaSx=rMXI0FDLe_#AV~qXDEWtLZ{VG2zLE~j;^kMNC;VsvCtP7B-n*dmXEtPzdt5S zl=70=6+fNMb$i_vCo5*zx6uzz?69E0+&b?fn&Bcr+y89N=3E)OwsR!S47I3M-qWu= zLDxnfF{ftE^9Ij7$G&>-t?~%N$5*=@`8LVgn%{LrK+GXw<^Cz)PCjc0ZPMLHzG|MU zHoUHpg*$6&D-VDDd2mhfuZmi3%VXE3_FiK?|1<2g^Z9Q_UbFmCb!g_}p%X4L#@y5* zXU3ZSER9#DYRGGV(|1cx!+DD0rHAK0MXh>`-W91=G-eN7_FLyFUNe(>$||*&PHP7R zjp{jEsSNJ_`dj`1%5vG>e&gyD1IVPFs(b4H$Eh=^3Eg^Jx zVq`jQaj;aA^4%TQsQg8z10Qc^{fO#ne#wu8*n)wDN}yX%ip9@kO@ZaYom>ih`#P@Q zuaP163du)hpJ|+xOWg7O{P3EJY7NJAO-)T5?exycgVP`1<%dV-&lWS3-qo4-_V5HX z>yLrvNerKIBAx1GDB+BBtvN8rDoU~>2ArV1nfBI_1{?IA)67KKr+3|`exi0lOu6U2 zf`rmakAfjpSYA0NBz(Th>QIbIb<3;$w6nj<`9R|bk6HTFW9bQ}NG2^G{Ci)|?eu&P z5N($7+UPS?|D3~@zFglN`#O1%I^lpKgYb;St;g@}Tuw$UoXKlyxV}2Ub2qI`dv0C( z7v8>pQ~=HtTk_}ft{5)xGQ*9L#RajSK&EoPN|c*VgQeJmQ2Y|KC+N{ zt72nt?u>6@RhUewSL)ZX_cUFv6>2;;K8(emNFBDC_s2R?4IQg`WM;_!;DfgbneJPw zM#{5#xgP_RQ|{TmXv*Oaf19d)`l_*Pdgpm=?qi7CV@^mLEd31?*e_a}^VD9RSPTVz zQZk8xD(A~Wh6zasqnKoK+cT_OBbxWCai{aLGf!5Bore9{lC+y&we2r|5XHwOSj0P? zk$udxlRwza?BwG%NdryEO;^_M6_b)z)@(N^{XX$KbY(ocq?qLU)sK+G#maSDAq;Dw z!^7UteV)Fu>bnHQB(GE^G%nie>{Jgb+)0O<5b|-wO+4b#GrNm<;L$);Yd*BJAMO4{ zcmKv_g}v`?EGG(CMB(SAwyHrz+3-^S{!3A7xSIum>!aq)~Uaa|? z`Ph)f%vXZ2BH_@jJsCN#JB1d*H@oB^1^Kzu=0L3slQNiQ6uKK#9#;G4CkE-Y#5X5i z_4Ho6d@MR0a)jV!bShKNJ~*S@Vyi-vJ9_cviqO*F#TAi7ze;DVM-W~=*$0J>`;E0n zQoc`9?HkNboqqE=UG3%k%>%}RG#(%b?Qpcar~7{Q>(0)}m@7W_b8Iwk9%jp#Uk1hk zM(FPUD&vOZxLK3Scf=`wr`aj&(;0RtZZp<>PoA0@vzyxN9ZJdhNkK_|OfsQ@4V@n2Q2r>CX;Fs63Nm%Kp5$r|9v{aHSocg1_&}rPTE8h)us{MrPb0 zO{Wo5Sj+wC*@W22t$BUNW$b?cvTjQz+vSdT`*3CC<7yOG>JIDxuc@GW`nNU0DT};W zp;2K`vXf!aw#BK?({^HAk6qfuiFSIrqi0#lRp>wL@7}WtB}K zr4$$xxU95#Iqm&rLH2{{J-gIx5HVq-?J4i!-PP;rZ+PIak~!wmHA46sJKG8dl?L;ayg8{m!DGBUSADX@VvHYdbLcuG5+b(yPt24?yt^EXgA8` zv!6Yy=`_uQDTfNE!IMbaxyVHwzG16NsU18Iy~Eo%$&C(Ly^I@7DNV@$C!SDjr=bJmfMz->X?sd=Z&wnaV z)cl|}Rnyz0INSe2{>fS?0xCCoUS(MME)wJgiSdg4D94_p2-BY=6-ro z&RqeDIxoD|2zH;rTJt3+?sEWUg~d5$>TCmH57^w(`)zlODPhDDnROO_KjgFi6@B87 z12~D#@9)uVPS8NsvAMsQK~Yr;ib~+}Ey}olP)Xg}g@ZiL5S-LkooLMp>-ucGHMx1a;UV82x?)AV|_P97ZAC8N9^(JKVa)11T zn)^x7aY0|c_L_+A9d2_f-S6H$;oT^3$b$6Z8s?7Dg?6%@V6cZM z=~jHnj>>wIf!`PQKc zDpiW18&L58!7gxAx&@SW2m}aHRg};J(xn6erAkK*0xFX{Rj8Moew+v*?FGXnYCxnto6R{T5;>J08<{0({OcL2oEyw*ZB;0n zUzZ;FR$3jiJiav`*Xz-$Aiw;1DBgH@WTU7Duny5_O0u;%{DN`-HCj9g08a)>z#xk* zV}1?#+Mlv-$U5S|a`&u$QOsAaZbI!reRr_r(rPxei6MHjaTia;sh>hAU;4OVsO;23 z6MmuSt#^e6G@c$4%>qo+xBD0kgOyM?yjaZli4!&DZ94ai8PaEQ_17M-*hY%FoyD!; zqrH@Zs&YZhvZjB1W`US`-O^yOQ)4TEq)`HG!W1PutCGMxaA8k86jI$@oKKH;ZJ;+V z8Rf|L&Rg4bfR)*7SxND$L>!$*Hy!(uO;C-Ae}2yKVq)J%D@+Ca8BV7UNyQ5)glA@= zmg31a{lb6kKWoUL_0RMV1W)9n!jIz#5qGri+`(WD7CO1fZnm(Ks2DR2_Z%x;b#)t1 zNYesgd}CeiGUw=feyMkfZ#_>;cv?|J<-=r~;<0IjG?i->Tv2m#-uCWqK0A5*Al*pc zraQk5OX)(ONiKWNKO`7U^A~+UVP#g(UC~O=Bh~s4OxQF)%$RS)l-fm9wFV>vNQ~&op~VE zEE?cnFhH~Bt6!iTB^HGC7D0%_jX#g;M|n}pbNcGFdn653XVjVG z-xR>wK{gibgKN_bKhhdcHavPVNXK1V-uPjfy7IamDqmV$8^KfG#;O?IEL=oPeB@NK z9*ReqjbbbG95QT+QO};dZgJWfkCr7Ok&*hSVKxXmM{Iq=<_bT6 zl#oqvnJm~F2H8hPj7%k4l-<2CBJ+j2Nfs?$nk z&qAqhui8YOt44Qg3YQN>k>WZvrRM%5UX~y){O0bvlu*^{dXU01@g&oyD;g2C5f*b9 z=5`kpEHA4`Op7UL{dApE>}u}wsQvS2_~;Xjw&x6?ot;3qmVEB9iZ8K%XssT88{`%2 z>+k;phr8vRL?0i=Ci``YhfympBo*F<-PXTVQFl}^wUV^YAIYNVOfxA{Y-8X>ln!d* zE1n?r{Att1vMkVsM$kEvTmm|VPngxUwFoVxCVc*(qjHylPzL48;{QR4$&%XLRg9BV z|0AMCES5T!-i|WJ%)aIp=C)$dH8ndczGOj#Wv-(O@f(1>(sw0U2DZ;G_gfZ`98L`@ z+xo_$&=}WPT#yfe5B*ICiz;OuagZ|@`=0Uwrou*y{$!NGLKe=)*2}zoO4G)Mjd7TTCPv^)8Mlq zCIvky9oEpjFDer&U8mI*Fxe`cBtHzOBq1Ro^YB__Jw4;V-K({6Fu$zw179bi-C znyvhYZNOlbs-Uvp-E-$QvuViBcYCc&wJ(mS=qj_2w=*V8zHGdgZxipl5Ns1LqSo`p z{Jk3?m$3i|KOre;;H1i%Q^fIZRpy0<`P$T_*8q#pr1XxeKqyA-!{Lfau79MyJmsu# z?UQ~w0xPa`D5PDa>$)YjIAhb^Rxw7c8P4(1RZ07WNvrY1giBq-7etP{V6AA>j=`K?O zOOOcMS96fsFPusZ)5;Yt2h+`wvu1iNFmJx{kwsM!MbOy7ThOuN`Puv806m{!Ij{je4)2Wf z^YR?o^~7)SQxDiUMZ5td&GUiv#9P2OTyAl+@Wn9X0h!DiqFbkMEW9o(f9fuMZ_o(d zhisWUlOV-5u~_D5tieQNps~pmQD5=1(h{R9iL{xOs{9}?K9(K?Ytz( zBtpjyuO1T()-W49{>s_!usI+~pY0USSx3UvcS3fvrR&srrLO=o41}}m-s{H3-X=S; zlY4h=kKvJN4pzQUvt3XCv^P@vG47Pq1mjlFf;J_=cTkpztnz2OdQU7C8T~Ox;bkJJ zm9lKnEamN`E!7^Q7^JTa8OzAXx86j*ieS|^@t2RIEM>y_Fy3@Na&TRl)y?%x2lf2y zh3h=z@zWaAt#i74XzoP)MiDPVx~HAQtsGUN0Gh8R)CEQ*8174umUX$v^m$^?SHi_C z<4DE<%L@|iE#!!BcElvFk++jnLUL9t&sZ?2e~0=~{HfJjCP{R)a_Qi$I~MO}??pHb zmh6cP85W*FLb3OnJX*Gy8@9d@IiJqc+#zCf*+5mDImP_T`ceD)O@s?BO9(U!6mol0 z{dXyudM2T(5_wH-@N``9+v-HxP*bE;By4+R{Pg98$2A2vu?VkKFCmfVJ`6h}zJ~+` z0TN<^+jdLC&CnfyN+=$gRx1-xclo}PYh(60U0e5lhDltc{{;ZtS_gQm1_JI!S+BLs zp?8lrgCY5$QsH6Kc56!0>};>quqazq<^l@lS4uUTnI6GU6x{F_%PjRMqMlxHyvp8x z-B9ublk|>OC`zZ3g*>3MYHP1P0Tb!nCLzlWkn44ey(cr;Es z`{+2KGv=WXNXhbOeFlFU5xmS(PeHXIyw{AWv_ByYm1rL*vb?XS!YzS zG9is_c+O-0m#-?g7Z>{;r-|f6&F7G4Ye}7NjRNM@Ad-?6CT7;5>On+Kg@?;$Z$?SP zkCKI77Zph#nj>uuMiz3ednmUp57Aa4biT^BD1_Yoaj7~vx!;uH;=F=W^&NmW*f5_Q zv%LuYQUvi`>oK%jz^Ff#=TRzoU2)b1b0jWzjp{=0W5B)$%8is? zE3ntP%`Wsr0|NYgHrM3jF;aAz5pxM2P)iz5PCjzowe(RU&$F?zI+x4xU|EQXst!AT6x?JpajEo7am}jBa@Sl zKoDX+h_v<)oP8_+l3p>>&l;*e_1=KHG9zYCjNl1y8qImmY`^^QL2}Ym8Sd)lf+mCi zj~MU5v$w7Ggf7fdTNop9eU}(?>;=a&3@VDcR%m<6N({gD~wO!QCvvreZQ|WPo9!D zw>Af=JK=1$e0+S|(yD{MhV$<&C)|gut%3NI;Gf;JN|gJPbHn$4hV$#QdA|x<`hQ$% z);|UL&w+Uga)&Tu_J7+TJDctA-~97LxgPTW-TXAr|1sNq+~b7r-LOo8PNXt34|J~> K=#*&LhW!^r$4-*~ literal 0 HcmV?d00001 diff --git a/examples/openthread/ot_sleepy_device/main/CMakeLists.txt b/examples/openthread/ot_sleepy_device/deep_sleep/main/CMakeLists.txt similarity index 100% rename from examples/openthread/ot_sleepy_device/main/CMakeLists.txt rename to examples/openthread/ot_sleepy_device/deep_sleep/main/CMakeLists.txt diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device.c b/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device.c new file mode 100644 index 000000000000..4c2e59248546 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device.c @@ -0,0 +1,220 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + * + * OpenThread Command Line Example + * + * This example code is in the Public Domain (or CC0 licensed, at your option.) + * + * Unless required by applicable law or agreed to in writing, this + * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. +*/ + +#include +#include +#include +#include +#include "esp_err.h" +#include "esp_event.h" +#include "esp_log.h" +#include "esp_sleep.h" +#include "esp_timer.h" +#include "esp_openthread.h" +#include "esp_openthread_netif_glue.h" +#include "esp_ot_sleepy_device_config.h" +#include "esp_vfs_eventfd.h" +#include "nvs_flash.h" +#include "driver/rtc_io.h" +#include "driver/uart.h" +#include "openthread/logging.h" +#include "openthread/thread.h" + +#if !SOC_IEEE802154_SUPPORTED +#error "Openthread sleepy device is only supported for the SoCs which have IEEE 802.15.4 module" +#endif + +#define TAG "ot_esp_power_save" + +static RTC_DATA_ATTR struct timeval s_sleep_enter_time; +static esp_timer_handle_t s_oneshot_timer; + +static void create_config_network(otInstance *instance) +{ + otLinkModeConfig linkMode = { 0 }; + + linkMode.mRxOnWhenIdle = false; + linkMode.mDeviceType = false; + linkMode.mNetworkData = false; + + if (otLinkSetPollPeriod(instance, CONFIG_OPENTHREAD_NETWORK_POLLPERIOD_TIME) != OT_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to set OpenThread pollperiod."); + abort(); + } + + if (otThreadSetLinkMode(instance, linkMode) != OT_ERROR_NONE) { + ESP_LOGE(TAG, "Failed to set OpenThread linkmode."); + abort(); + } + ESP_ERROR_CHECK(esp_openthread_auto_start(NULL)); +} + +static esp_netif_t *init_openthread_netif(const esp_openthread_platform_config_t *config) +{ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_OPENTHREAD(); + esp_netif_t *netif = esp_netif_new(&cfg); + assert(netif != NULL); + ESP_ERROR_CHECK(esp_netif_attach(netif, esp_openthread_netif_glue_init(config))); + + return netif; +} + +static void ot_state_change_callback(otChangedFlags changed_flags, void* ctx) +{ + OT_UNUSED_VARIABLE(ctx); + static otDeviceRole s_previous_role = OT_DEVICE_ROLE_DISABLED; + otInstance* instance = esp_openthread_get_instance(); + if (!instance) { + return; + } + otDeviceRole role = otThreadGetDeviceRole(instance); + if (role == OT_DEVICE_ROLE_CHILD && s_previous_role != OT_DEVICE_ROLE_CHILD) { + // Start the one-shot timer + const int before_deep_sleep_time_sec = 5; + ESP_LOGI(TAG, "Start one-shot timer for %ds to enter the deep sleep", before_deep_sleep_time_sec); + ESP_ERROR_CHECK(esp_timer_start_once(s_oneshot_timer, before_deep_sleep_time_sec * 1000000)); + } + s_previous_role = role; +} + +static void s_oneshot_timer_callback(void* arg) +{ + // Enter deep sleep + ESP_LOGI(TAG, "Enter deep sleep"); + gettimeofday(&s_sleep_enter_time, NULL); + esp_deep_sleep_start(); +} + +static void ot_deep_sleep_init(void) +{ + // Within this function, we print the reason for the wake-up and configure the method of waking up from deep sleep. + // This example provides support for two wake-up sources from deep sleep: RTC timer and GPIO. + + // The one-shot timer will start when the device transitions to the CHILD state for the first time. + // After a 5-second delay, the device will enter deep sleep. + + const esp_timer_create_args_t s_oneshot_timer_args = { + .callback = &s_oneshot_timer_callback, + .name = "one-shot" + }; + + ESP_ERROR_CHECK(esp_timer_create(&s_oneshot_timer_args, &s_oneshot_timer)); + + // Print the wake-up reason: + struct timeval now; + gettimeofday(&now, NULL); + int sleep_time_ms = (now.tv_sec - s_sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - s_sleep_enter_time.tv_usec) / 1000; + esp_sleep_wakeup_cause_t wake_up_cause = esp_sleep_get_wakeup_cause(); + switch (wake_up_cause) { + case ESP_SLEEP_WAKEUP_TIMER: { + ESP_LOGI(TAG, "Wake up from timer. Time spent in deep sleep and boot: %dms", sleep_time_ms); + break; + } + case ESP_SLEEP_WAKEUP_EXT1: { + ESP_LOGI(TAG, "Wake up from GPIO. Time spent in deep sleep and boot: %dms", sleep_time_ms); + break; + } + case ESP_SLEEP_WAKEUP_UNDEFINED: + default: + ESP_LOGI(TAG, "Not a deep sleep reset"); + break; + } + + // Set the methods of how to wake up: + // 1. RTC timer waking-up + const int wakeup_time_sec = 20; + ESP_LOGI(TAG, "Enabling timer wakeup, %ds\n", wakeup_time_sec); + ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000)); + + // 2. GPIO waking-up +#if CONFIG_IDF_TARGET_ESP32C6 + // For ESP32C6 boards, RTCIO only supports GPIO0~GPIO7 + // GPIO7 pull down to wake up + const int gpio_wakeup_pin = 7; +#elif CONFIG_IDF_TARGET_ESP32H2 + // You can wake up by pulling down GPIO9. On ESP32H2 development boards, the BOOT button is connected to GPIO9. + // You can use the BOOT button to wake up the boards directly. + const int gpio_wakeup_pin = 9; +#endif + const uint64_t gpio_wakeup_pin_mask = 1ULL << gpio_wakeup_pin; + // The configuration mode depends on your hardware design. + // Since the BOOT button is connected to a pull-up resistor, the wake-up mode is configured as LOW. + const uint64_t ext_wakeup_mode = 0 << gpio_wakeup_pin; + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_with_level_mask(gpio_wakeup_pin_mask, ext_wakeup_mode)); + + // Also these two GPIO configurations are also depended on the hardware design. + // The BOOT button is connected to the pull-up resistor, so enable the pull-up mode and disable the pull-down mode. + + // Notice: if these GPIO configurations do not match the hardware design, the deep sleep module will enable the GPIO hold + // feature to hold the GPIO voltage when enter the sleep, which will ensure the board be waked up by GPIO. But it will cause + // 3~4 times power consumption increasing during sleep. + ESP_ERROR_CHECK(gpio_pullup_en(gpio_wakeup_pin)); + ESP_ERROR_CHECK(gpio_pulldown_dis(gpio_wakeup_pin)); +} + + +static void ot_task_worker(void *aContext) +{ + esp_openthread_platform_config_t config = { + .radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(), + .host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(), + .port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(), + }; + + // Initialize the OpenThread stack + ESP_ERROR_CHECK(esp_openthread_init(&config)); + + ot_deep_sleep_init(); + +#if CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC + // The OpenThread log level directly matches ESP log level + (void)otLoggingSetLevel(CONFIG_LOG_DEFAULT_LEVEL); +#endif + esp_netif_t *openthread_netif; + // Initialize the esp_netif bindings + openthread_netif = init_openthread_netif(&config); + esp_netif_set_default_netif(openthread_netif); + otSetStateChangedCallback(esp_openthread_get_instance(), ot_state_change_callback, NULL); + + create_config_network(esp_openthread_get_instance()); + + // Run the main loop + esp_openthread_launch_mainloop(); + + // Clean up + esp_netif_destroy(openthread_netif); + esp_openthread_netif_glue_deinit(); + + esp_vfs_eventfd_unregister(); + vTaskDelete(NULL); +} + + +void app_main(void) +{ + // Used eventfds: + // * netif + // * ot task queue + // * radio driver + esp_vfs_eventfd_config_t eventfd_config = { + .max_fds = 3, + }; + + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_vfs_eventfd_register(&eventfd_config)); + + xTaskCreate(ot_task_worker, "ot_power_save_main", 4096, NULL, 5, NULL); +} diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device_config.h b/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device_config.h new file mode 100644 index 000000000000..145bb245ccc2 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/deep_sleep/main/esp_ot_sleepy_device_config.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + * + * OpenThread Command Line Example + * + * This example code is in the Public Domain (or CC0 licensed, at your option.) + * + * Unless required by applicable law or agreed to in writing, this + * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. + */ + +#pragma once + +#include "esp_openthread_types.h" + +# define CONFIG_OPENTHREAD_NETWORK_POLLPERIOD_TIME 30000 + +#if SOC_IEEE802154_SUPPORTED +#define ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG() \ + { \ + .radio_mode = RADIO_MODE_NATIVE, \ + } +#endif + +#define ESP_OPENTHREAD_DEFAULT_HOST_CONFIG() \ + { \ + .host_connection_mode = HOST_CONNECTION_MODE_CLI_UART, \ + .host_uart_config = { \ + .port = 0, \ + .uart_config = \ + { \ + .baud_rate = 115200, \ + .data_bits = UART_DATA_8_BITS, \ + .parity = UART_PARITY_DISABLE, \ + .stop_bits = UART_STOP_BITS_1, \ + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, \ + .rx_flow_ctrl_thresh = 0, \ + .source_clk = UART_SCLK_DEFAULT, \ + }, \ + .rx_pin = UART_PIN_NO_CHANGE, \ + .tx_pin = UART_PIN_NO_CHANGE, \ + }, \ + } + +#define ESP_OPENTHREAD_DEFAULT_PORT_CONFIG() \ + { \ + .storage_partition_name = "nvs", \ + .netif_queue_size = 10, \ + .task_queue_size = 10, \ + } diff --git a/examples/openthread/ot_sleepy_device/partitions.csv b/examples/openthread/ot_sleepy_device/deep_sleep/partitions.csv similarity index 100% rename from examples/openthread/ot_sleepy_device/partitions.csv rename to examples/openthread/ot_sleepy_device/deep_sleep/partitions.csv diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/sdkconfig.defaults b/examples/openthread/ot_sleepy_device/deep_sleep/sdkconfig.defaults new file mode 100644 index 000000000000..00774aa81dea --- /dev/null +++ b/examples/openthread/ot_sleepy_device/deep_sleep/sdkconfig.defaults @@ -0,0 +1,54 @@ +# +# Partition Table +# +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +# end of Partition Table + +# +# mbedTLS +# +# TODO: Re-enable HW acceleration when HW AES support pm_lock (IDF-7704) +CONFIG_MBEDTLS_HARDWARE_AES=n +CONFIG_MBEDTLS_HARDWARE_MPI=n +CONFIG_MBEDTLS_HARDWARE_SHA=n +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y +CONFIG_MBEDTLS_ECJPAKE_C=y +# end of mbedTLS + +# +# OpenThread +# +CONFIG_OPENTHREAD_ENABLED=y +CONFIG_OPENTHREAD_BORDER_ROUTER=n +CONFIG_OPENTHREAD_DNS64_CLIENT=y +# end of OpenThread + +# +# lwIP +# +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096 +CONFIG_LWIP_IPV6_NUM_ADDRESSES=8 +CONFIG_LWIP_IPV4=n +CONFIG_LWIP_ND6=n +# end of lwIP + +# +# IEEE 802.15.4 +# +CONFIG_IEEE802154_ENABLED=y +# end of IEEE 802.15.4 + +# +# deep sleep +# +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=80 +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_RESERVE_MEM=512 +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_RTC_CLK_SRC_INT_RC=y +CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y diff --git a/examples/openthread/ot_sleepy_device/light_sleep/CMakeLists.txt b/examples/openthread/ot_sleepy_device/light_sleep/CMakeLists.txt new file mode 100644 index 000000000000..876f5798c561 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/light_sleep/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(ot_sleepy_device) diff --git a/examples/openthread/ot_sleepy_device/README.md b/examples/openthread/ot_sleepy_device/light_sleep/README.md similarity index 89% rename from examples/openthread/ot_sleepy_device/README.md rename to examples/openthread/ot_sleepy_device/light_sleep/README.md index 5c832db28dee..ebcf8eae273d 100644 --- a/examples/openthread/ot_sleepy_device/README.md +++ b/examples/openthread/ot_sleepy_device/light_sleep/README.md @@ -3,7 +3,7 @@ # OpenThread Sleepy Device Example -The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Light Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-reference/system/sleep_modes.html#sleep-modes) during idle state. +The example demonstrates the Thread Sleepy End Device (SED), the device will enter [Light Sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/esp32h2/api-reference/system/sleep_modes.html#sleep-modes) during idle state. ## How to use example ### Hardware Required @@ -14,7 +14,7 @@ The example demonstrates the Thread Sleepy End Device (SED), the device will ent ## Configure the Openthread Dataset -* Run [ot_cli](../ot_cli/) on another 802.15.4 SoC device to create openthread dataset configuration and start an openthread network as the leader. +* Run [ot_cli](../../ot_cli/) on another 802.15.4 SoC device to create openthread dataset configuration and start an openthread network as the leader. * Configure the Openthread dataset using `idf.py menuconfig` in `Component config ---> Openthread ---> Thread Operation Dataset`, ensuring that the openthread sleepy device's dataset matches the dataset of the leader. ### Build and Flash diff --git a/examples/openthread/ot_sleepy_device/light_sleep/main/CMakeLists.txt b/examples/openthread/ot_sleepy_device/light_sleep/main/CMakeLists.txt new file mode 100644 index 000000000000..a7cde9d16a01 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/light_sleep/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "esp_ot_sleepy_device.c" + INCLUDE_DIRS ".") diff --git a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c b/examples/openthread/ot_sleepy_device/light_sleep/main/esp_ot_sleepy_device.c similarity index 100% rename from examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device.c rename to examples/openthread/ot_sleepy_device/light_sleep/main/esp_ot_sleepy_device.c diff --git a/examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h b/examples/openthread/ot_sleepy_device/light_sleep/main/esp_ot_sleepy_device_config.h similarity index 100% rename from examples/openthread/ot_sleepy_device/main/esp_ot_sleepy_device_config.h rename to examples/openthread/ot_sleepy_device/light_sleep/main/esp_ot_sleepy_device_config.h diff --git a/examples/openthread/ot_sleepy_device/light_sleep/partitions.csv b/examples/openthread/ot_sleepy_device/light_sleep/partitions.csv new file mode 100644 index 000000000000..6c0e048dba5c --- /dev/null +++ b/examples/openthread/ot_sleepy_device/light_sleep/partitions.csv @@ -0,0 +1,5 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 0x120000, diff --git a/examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_c6 b/examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_c6 new file mode 100644 index 000000000000..80eea9080103 --- /dev/null +++ b/examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_c6 @@ -0,0 +1,6 @@ +CONFIG_IDF_TARGET="esp32c6" +CONFIG_IDF_TARGET_ESP32C6=y +CONFIG_OPENTHREAD_NETWORK_CHANNEL=12 +CONFIG_OPENTHREAD_NETWORK_MASTERKEY="aabbccddeeff00112233445566778899" +CONFIG_ESP_SLEEP_DEBUG=y +CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y diff --git a/examples/openthread/ot_sleepy_device/sdkconfig.ci.sleepy_h2 b/examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_h2 similarity index 100% rename from examples/openthread/ot_sleepy_device/sdkconfig.ci.sleepy_h2 rename to examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.ci.sleepy_h2 diff --git a/examples/openthread/ot_sleepy_device/sdkconfig.defaults b/examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.defaults similarity index 100% rename from examples/openthread/ot_sleepy_device/sdkconfig.defaults rename to examples/openthread/ot_sleepy_device/light_sleep/sdkconfig.defaults From bd34fc41bb6d9b1e7e754574060704cb8252dce2 Mon Sep 17 00:00:00 2001 From: Jakob Hasse Date: Thu, 26 Oct 2023 18:37:59 +0800 Subject: [PATCH 099/161] fix(freertos): Fixed prvTaskCreateDynamicPinnedToCoreWithCaps * The function was based on an outdated IDF/FreeRTOS combination which didn't always require zero-ing the TCB. This has been changed in the current IDF/FreeRTOS combination, leading to crashes. Unconditionally zero-ing the TCB fixes this problem. --- .../freertos_tasks_c_additions.h | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/components/freertos/esp_additions/freertos_tasks_c_additions.h b/components/freertos/esp_additions/freertos_tasks_c_additions.h index f08eb86264c3..c7a9fe6ab8aa 100644 --- a/components/freertos/esp_additions/freertos_tasks_c_additions.h +++ b/components/freertos/esp_additions/freertos_tasks_c_additions.h @@ -1173,7 +1173,7 @@ void * pvTaskGetCurrentTCBForCore( BaseType_t xCoreID ) UBaseType_t uxCoreAffinityMask, UBaseType_t uxStackMemoryCaps, TaskHandle_t * const pxCreatedTask ) - #else + #else /* CONFIG_FREERTOS_SMP */ BaseType_t prvTaskCreateDynamicPinnedToCoreWithCaps( TaskFunction_t pxTaskCode, const char * const pcName, const configSTACK_DEPTH_TYPE usStackDepth, @@ -1182,7 +1182,7 @@ void * pvTaskGetCurrentTCBForCore( BaseType_t xCoreID ) const BaseType_t xCoreID, UBaseType_t uxStackMemoryCaps, TaskHandle_t * const pxCreatedTask ) - #endif /* if CONFIG_FREERTOS_SMP */ + #endif /* CONFIG_FREERTOS_SMP */ { TCB_t * pxNewTCB; BaseType_t xReturn; @@ -1203,11 +1203,7 @@ void * pvTaskGetCurrentTCBForCore( BaseType_t xCoreID ) if( pxNewTCB != NULL ) { - #if CONFIG_FREERTOS_USE_KERNEL_10_5_1 - { - memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); - } - #endif /* CONFIG_FREERTOS_USE_KERNEL_10_5_1 */ + memset( ( void * ) pxNewTCB, 0x00, sizeof( TCB_t ) ); /* Store the stack location in the TCB. */ pxNewTCB->pxStack = pxStack; @@ -1234,16 +1230,20 @@ void * pvTaskGetCurrentTCBForCore( BaseType_t xCoreID ) #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ #if CONFIG_FREERTOS_SMP + { prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); - #if ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) + #if ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) { /* Set the task's affinity before scheduling it */ pxNewTCB->uxCoreAffinityMask = uxCoreAffinityMask; } - #endif - #else + #endif /* ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) */ + } + #else /* CONFIG_FREERTOS_SMP */ + { prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL, xCoreID ); - #endif + } + #endif /* CONFIG_FREERTOS_SMP */ prvAddNewTaskToReadyList( pxNewTCB ); xReturn = pdPASS; @@ -1256,5 +1256,5 @@ void * pvTaskGetCurrentTCBForCore( BaseType_t xCoreID ) return xReturn; } -#endif // SPIRAM +#endif /* CONFIG_SPIRAM */ /*----------------------------------------------------------*/ From 14d8fc82fe25a8da38a04c6d62cc2f2aa53344ec Mon Sep 17 00:00:00 2001 From: Fu Hanxi Date: Mon, 30 Oct 2023 12:00:29 +0100 Subject: [PATCH 100/161] ci: update constraint file to 5.3 --- .gitlab/ci/common.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/ci/common.yml b/.gitlab/ci/common.yml index 2109985f36ee..3956df42edb9 100644 --- a/.gitlab/ci/common.yml +++ b/.gitlab/ci/common.yml @@ -66,7 +66,7 @@ variables: CI_PYTHON_CONSTRAINT_BRANCH: "" # Update the filename for a specific ESP-IDF release. It is used only with CI_PYTHON_CONSTRAINT_BRANCH. - CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v5.2.txt" + CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v5.3.txt" # Set this variable to repository name of a Python tool you wish to install and test in the context of ESP-IDF CI. # Keep the variable empty when not used. From 546b76befa7f0dbf00b052528bcaa9ce2b5a2868 Mon Sep 17 00:00:00 2001 From: Peter Marcisovsky Date: Thu, 19 Oct 2023 14:05:49 +0200 Subject: [PATCH 101/161] feat(usb/host): Modifiy usb_host_lib example The example keeps handling connections/disconnections indefinitely. Added kconfig.projbuild for GPIO selection. GPIO0 press does terdown/uninstall. --- .../usb/host/usb_host_lib/README.md | 46 +++-- .../usb/host/usb_host_lib/main/CMakeLists.txt | 2 +- .../host/usb_host_lib/main/Kconfig.projbuild | 12 ++ .../usb/host/usb_host_lib/main/class_driver.c | 48 +++-- .../usb_host_lib/main/usb_host_lib_main.c | 169 ++++++++++++++---- 5 files changed, 207 insertions(+), 70 deletions(-) create mode 100644 examples/peripherals/usb/host/usb_host_lib/main/Kconfig.projbuild diff --git a/examples/peripherals/usb/host/usb_host_lib/README.md b/examples/peripherals/usb/host/usb_host_lib/README.md index f6b746c7a71a..bb60eab1114b 100644 --- a/examples/peripherals/usb/host/usb_host_lib/README.md +++ b/examples/peripherals/usb/host/usb_host_lib/README.md @@ -5,19 +5,21 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) -This example demonstrates the basic usage of the [USB Host Library API](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/usb_host.html) by implementing a pseudo class driver and a Host Library daemon task. The example does the following: +This example demonstrates the basic usage of the [USB Host Library API](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/peripherals/usb_host.html) by implementing a pseudo class driver and a Host Library task. The example does the following: 1. Install Host Library and register a client 2. Waits for a device connection 3. Prints the device's information (such as device/configuration/string descriptors) 4. Waits for the device to disconnect -5. Deregister the client and uninstall the Host Library +5. Repeats steps 2 to 4 until a user pressess a button, which quits the `app` +6. If the button has been pressed, while a USB device is still connected, the user will be prompted to remove the device and push the button again to quit the `app` +7. Deregister the client, uninstall the Host Library and quit the `app` The example demonstrates the following aspects of the USB Host Library API: - How to use the Library API to: - Install and uninstall the USB Host Library - - Run the library event handler function a daemon task + - Run the library event handler function and usb host library task - How to handle library events - How to use the Client API from a client task to: - Register and deregister a client of the USB Host Library @@ -30,7 +32,7 @@ The example demonstrates the following aspects of the USB Host Library API: ### Hardware Required -An ESP board that supports USB-OTG. The example uses the ESP's internal USB PHY, however the internal USB PHY's pins will need to be connected to a USB port (i.e., a USB breakout board) as follows: +An ESP board that has a push button and supports USB-OTG. The example uses the ESP's internal USB PHY, however the internal USB PHY's pins will need to be connected to a USB port (i.e., a USB breakout board) as follows: - GND and 5V signals of the ESP board to the GND and 5V lines of the USB port - GPIO 19 to D- @@ -43,6 +45,7 @@ idf.py menuconfig ``` * The USB Host Stack has a maximum supported transfer size for control transfer during device enumeration. This size is specified via the USB_HOST_CONTROL_TRANSFER_MAX_SIZE configuration option and has a default value of 256 bytes. Therefore, if devices with length config/string descriptors are used, users may want to increase the size of this configuration. +* Push button GPIO selection ### Build and Flash @@ -61,14 +64,17 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ## Example Output ``` -I (261) cpu_start: Starting scheduler on PRO CPU. -I (267) DAEMON: Installing USB Host Library -I (297) CLASS: Registering Client -I (5067) CLASS: Opening device at address 1 -I (5067) CLASS: Getting device information -I (5067) CLASS: Full speed -I (5067) CLASS: bConfigurationValue 1 -I (5067) CLASS: Getting device descriptor +I (305) main_task: Started on CPU0 +I (315) main_task: Calling app_main() +I (315) USB host lib: USB host library example +I (315) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2 +I (325) USB host lib: Installing USB Host Library +I (365) CLASS: Registering Client +I (745) CLASS: Opening device at address 1 +I (745) CLASS: Getting device information +I (745) CLASS: Full speed +I (745) CLASS: bConfigurationValue 1 +I (745) CLASS: Getting device descriptor *** Device descriptor *** bLength 18 bDescriptorType 1 @@ -84,7 +90,7 @@ iManufacturer 1 iProduct 2 iSerialNumber 3 bNumConfigurations 1 -I (5097) CLASS: Getting config descriptor +I (775) CLASS: Getting config descriptor *** Configuration descriptor *** bLength 9 bDescriptorType 2 @@ -153,12 +159,20 @@ bMaxPower 500mA bmAttributes 0x2 BULK wMaxPacketSize 64 bInterval 1 -I (5227) CLASS: Getting Manufacturer string descriptor +I (855) CLASS: Getting Manufacturer string descriptor Espressif -I (5237) CLASS: Getting Product string descriptor +I (855) CLASS: Getting Product string descriptor USB JTAG/serial debug unit -I (5247) CLASS: Getting Serial Number string descriptor +I (865) CLASS: Getting Serial Number string descriptor 7C:DF:A1:E0:10:50 +W (2855) USB host lib: To shutdown example, remove all USB devices and press button again. +E (6135) USBH: Device 1 gone +I (9545) CLASS: Deregistering Client +I (9545) USB host lib: No more clients +I (9545) USB host lib: All devices marked as free +I (9545) USB host lib: No more clients and devices +I (9645) USB host lib: End of the example +I (9645) main_task: Returned from app_main() ``` ## Troubleshooting diff --git a/examples/peripherals/usb/host/usb_host_lib/main/CMakeLists.txt b/examples/peripherals/usb/host/usb_host_lib/main/CMakeLists.txt index 260f313feae2..5d0a296fb9c3 100644 --- a/examples/peripherals/usb/host/usb_host_lib/main/CMakeLists.txt +++ b/examples/peripherals/usb/host/usb_host_lib/main/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "usb_host_lib_main.c" "class_driver.c" INCLUDE_DIRS "." - PRIV_REQUIRES usb + PRIV_REQUIRES usb driver ) diff --git a/examples/peripherals/usb/host/usb_host_lib/main/Kconfig.projbuild b/examples/peripherals/usb/host/usb_host_lib/main/Kconfig.projbuild new file mode 100644 index 000000000000..680b0cc3c835 --- /dev/null +++ b/examples/peripherals/usb/host/usb_host_lib/main/Kconfig.projbuild @@ -0,0 +1,12 @@ +menu "Example Configuration" + + orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps" + + config APP_QUIT_PIN + int "APP Quit button GPIO pin" + range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + default 0 + help + GPIO pin number to be used as APP_QUIT button. + +endmenu diff --git a/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c b/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c index ce7ee4448700..e7a06ea59fe4 100644 --- a/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c +++ b/examples/peripherals/usb/host/usb_host_lib/main/class_driver.c @@ -12,13 +12,16 @@ #define CLIENT_NUM_EVENT_MSG 5 -#define ACTION_OPEN_DEV 0x01 -#define ACTION_GET_DEV_INFO 0x02 -#define ACTION_GET_DEV_DESC 0x04 -#define ACTION_GET_CONFIG_DESC 0x08 -#define ACTION_GET_STR_DESC 0x10 -#define ACTION_CLOSE_DEV 0x20 -#define ACTION_EXIT 0x40 +typedef enum { + ACTION_OPEN_DEV = 0x01, + ACTION_GET_DEV_INFO = 0x02, + ACTION_GET_DEV_DESC = 0x04, + ACTION_GET_CONFIG_DESC = 0x08, + ACTION_GET_STR_DESC = 0x10, + ACTION_CLOSE_DEV = 0x20, + ACTION_EXIT = 0x40, + ACTION_RECONNECT = 0x80, +} action_t; typedef struct { usb_host_client_handle_t client_hdl; @@ -28,6 +31,7 @@ typedef struct { } class_driver_t; static const char *TAG = "CLASS"; +static class_driver_t *s_driver_obj; static void client_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg) { @@ -122,24 +126,20 @@ static void action_get_str_desc(class_driver_t *driver_obj) driver_obj->actions &= ~ACTION_GET_STR_DESC; } -static void aciton_close_dev(class_driver_t *driver_obj) +static void action_close_dev(class_driver_t *driver_obj) { ESP_ERROR_CHECK(usb_host_device_close(driver_obj->client_hdl, driver_obj->dev_hdl)); driver_obj->dev_hdl = NULL; driver_obj->dev_addr = 0; - //We need to exit the event handler loop + //We need to connect a new device driver_obj->actions &= ~ACTION_CLOSE_DEV; - driver_obj->actions |= ACTION_EXIT; + driver_obj->actions |= ACTION_RECONNECT; } void class_driver_task(void *arg) { - SemaphoreHandle_t signaling_sem = (SemaphoreHandle_t)arg; class_driver_t driver_obj = {0}; - //Wait until daemon task has installed USB Host Library - xSemaphoreTake(signaling_sem, portMAX_DELAY); - ESP_LOGI(TAG, "Registering Client"); usb_host_client_config_t client_config = { .is_synchronous = false, //Synchronous clients currently not supported. Set this to false @@ -150,6 +150,7 @@ void class_driver_task(void *arg) }, }; ESP_ERROR_CHECK(usb_host_client_register(&client_config, &driver_obj.client_hdl)); + s_driver_obj = &driver_obj; while (1) { if (driver_obj.actions == 0) { @@ -171,18 +172,29 @@ void class_driver_task(void *arg) action_get_str_desc(&driver_obj); } if (driver_obj.actions & ACTION_CLOSE_DEV) { - aciton_close_dev(&driver_obj); + action_close_dev(&driver_obj); } if (driver_obj.actions & ACTION_EXIT) { break; } + if (driver_obj.actions & ACTION_RECONNECT) { + driver_obj.actions = 0; + } } } ESP_LOGI(TAG, "Deregistering Client"); ESP_ERROR_CHECK(usb_host_client_deregister(driver_obj.client_hdl)); - - //Wait to be deleted - xSemaphoreGive(signaling_sem); vTaskSuspend(NULL); } + +void class_driver_client_deregister(void) +{ + if (s_driver_obj->dev_hdl != NULL) { + s_driver_obj->actions = ACTION_CLOSE_DEV; + } + s_driver_obj->actions |= ACTION_EXIT; + + // Unblock, exit the loop and proceed to deregister client + ESP_ERROR_CHECK(usb_host_client_unblock(s_driver_obj->client_hdl)); +} diff --git a/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c b/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c index f73880cabcb3..db41bd326578 100644 --- a/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c +++ b/examples/peripherals/usb/host/usb_host_lib/main/usb_host_lib_main.c @@ -1,27 +1,78 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/semphr.h" +#include "freertos/queue.h" +#include "freertos/event_groups.h" #include "esp_log.h" #include "esp_intr_alloc.h" #include "usb/usb_host.h" +#include "driver/gpio.h" -#define DAEMON_TASK_PRIORITY 2 +#define HOST_LIB_TASK_PRIORITY 2 #define CLASS_TASK_PRIORITY 3 +#define APP_QUIT_PIN CONFIG_APP_QUIT_PIN extern void class_driver_task(void *arg); +extern void class_driver_client_deregister(void); -static const char *TAG = "DAEMON"; +static const char *TAG = "USB host lib"; -static void host_lib_daemon_task(void *arg) +QueueHandle_t app_event_queue = NULL; + +/** + * @brief APP event group + * + * APP_EVENT - General event, which is APP_QUIT_PIN press event in this example. + */ +typedef enum { + APP_EVENT = 0, +} app_event_group_t; + +/** + * @brief APP event queue + * + * This event is used for delivering events from callback to a task. + */ +typedef struct { + app_event_group_t event_group; +} app_event_queue_t; + +/** + * @brief BOOT button pressed callback + * + * Signal application to exit the Host lib task + * + * @param[in] arg Unused + */ +static void gpio_cb(void *arg) { - SemaphoreHandle_t signaling_sem = (SemaphoreHandle_t)arg; + const app_event_queue_t evt_queue = { + .event_group = APP_EVENT, + }; + + BaseType_t xTaskWoken = pdFALSE; + + if (app_event_queue) { + xQueueSendFromISR(app_event_queue, &evt_queue, &xTaskWoken); + } + + if (xTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} +/** + * @brief Start USB Host install and handle common USB host library events while app pin not low + * + * @param[in] arg Not used + */ +static void usb_host_lib_task(void *arg) +{ ESP_LOGI(TAG, "Installing USB Host Library"); usb_host_config_t host_config = { .skip_phy_setup = false, @@ -29,9 +80,8 @@ static void host_lib_daemon_task(void *arg) }; ESP_ERROR_CHECK(usb_host_install(&host_config)); - //Signal to the class driver task that the host library is installed - xSemaphoreGive(signaling_sem); - vTaskDelay(10); //Short delay to let client task spin up + //Signalize the app_main, the USB host library has been installed + xTaskNotifyGive(arg); bool has_clients = true; bool has_devices = true; @@ -39,52 +89,101 @@ static void host_lib_daemon_task(void *arg) uint32_t event_flags; ESP_ERROR_CHECK(usb_host_lib_handle_events(portMAX_DELAY, &event_flags)); if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + ESP_LOGI(TAG, "No more clients"); has_clients = false; + if (ESP_OK == usb_host_device_free_all()) { + ESP_LOGI(TAG, "All devices marked as free"); + } else { + ESP_LOGI(TAG, "Wait for the ALL FREE EVENT"); + } } if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + ESP_LOGI(TAG, "No more devices"); has_devices = false; } + } ESP_LOGI(TAG, "No more clients and devices"); //Uninstall the USB Host Library ESP_ERROR_CHECK(usb_host_uninstall()); - //Wait to be deleted - xSemaphoreGive(signaling_sem); vTaskSuspend(NULL); } void app_main(void) { - SemaphoreHandle_t signaling_sem = xSemaphoreCreateBinary(); - - TaskHandle_t daemon_task_hdl; - TaskHandle_t class_driver_task_hdl; - //Create daemon task - xTaskCreatePinnedToCore(host_lib_daemon_task, - "daemon", - 4096, - (void *)signaling_sem, - DAEMON_TASK_PRIORITY, - &daemon_task_hdl, - 0); - //Create the class driver task - xTaskCreatePinnedToCore(class_driver_task, - "class", - 4096, - (void *)signaling_sem, - CLASS_TASK_PRIORITY, - &class_driver_task_hdl, - 0); + ESP_LOGI(TAG, "USB host library example"); + + // Init BOOT button: Pressing the button simulates app request to exit + // It will uninstall the class driver and USB Host Lib + const gpio_config_t input_pin = { + .pin_bit_mask = BIT64(APP_QUIT_PIN), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .intr_type = GPIO_INTR_NEGEDGE, + }; + ESP_ERROR_CHECK(gpio_config(&input_pin)); + ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1)); + ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_cb, NULL)); + app_event_queue = xQueueCreate(10, sizeof(app_event_queue_t)); + app_event_queue_t evt_queue; + + TaskHandle_t host_lib_task_hdl, class_driver_task_hdl; + + //Create usb host lib task + BaseType_t task_created; + task_created = xTaskCreatePinnedToCore(usb_host_lib_task, + "usb_host", + 4096, + xTaskGetCurrentTaskHandle(), + HOST_LIB_TASK_PRIORITY, + &host_lib_task_hdl, + 0); + assert(task_created == pdTRUE); + + //Wait unit the USB host library is installed + ulTaskNotifyTake(false, 1000); + + //Create class driver task + task_created = xTaskCreatePinnedToCore(class_driver_task, + "class", + 4096, + NULL, + CLASS_TASK_PRIORITY, + &class_driver_task_hdl, + 0); + assert(task_created == pdTRUE); vTaskDelay(10); //Add a short delay to let the tasks run - //Wait for the tasks to complete - for (int i = 0; i < 2; i++) { - xSemaphoreTake(signaling_sem, portMAX_DELAY); + while (1) { + if (xQueueReceive(app_event_queue, &evt_queue, portMAX_DELAY)) { + if (APP_EVENT == evt_queue.event_group) { + // User pressed button + usb_host_lib_info_t lib_info; + ESP_ERROR_CHECK(usb_host_lib_info(&lib_info)); + if (lib_info.num_devices == 0) { + // End while cycle + break; + } else { + ESP_LOGW(TAG, "To shutdown example, remove all USB devices and press button again."); + // Keep polling + } + } + } } + //Deregister client + class_driver_client_deregister(); + vTaskDelay(10); + //Delete the tasks vTaskDelete(class_driver_task_hdl); - vTaskDelete(daemon_task_hdl); + vTaskDelete(host_lib_task_hdl); + + // Delete interrupt and queue + gpio_isr_handler_remove(APP_QUIT_PIN); + xQueueReset(app_event_queue); + vQueueDelete(app_event_queue); + ESP_LOGI(TAG, "End of the example"); } From 1780bababd69ec914c031192cb55f672c6bbc4cf Mon Sep 17 00:00:00 2001 From: David Cermak Date: Wed, 4 Oct 2023 17:35:57 +0200 Subject: [PATCH 102/161] feat(examples): Add PPP to common connection component --- .../protocol_examples_common/CMakeLists.txt | 8 + .../Kconfig.projbuild | 66 ++++- .../protocol_examples_common/README.md | 58 ++++ .../protocol_examples_common/connect.c | 10 + .../include/example_common_private.h | 3 + .../include/protocol_examples_common.h | 7 + .../protocol_examples_common/ppp_connect.c | 260 ++++++++++++++++++ 7 files changed, 411 insertions(+), 1 deletion(-) create mode 100644 examples/common_components/protocol_examples_common/README.md create mode 100644 examples/common_components/protocol_examples_common/ppp_connect.c diff --git a/examples/common_components/protocol_examples_common/CMakeLists.txt b/examples/common_components/protocol_examples_common/CMakeLists.txt index 4f9ea953cf46..a8f9b81c0579 100644 --- a/examples/common_components/protocol_examples_common/CMakeLists.txt +++ b/examples/common_components/protocol_examples_common/CMakeLists.txt @@ -22,6 +22,10 @@ if(CONFIG_EXAMPLE_CONNECT_ETHERNET) list(APPEND srcs "eth_connect.c") endif() +if(CONFIG_EXAMPLE_CONNECT_PPP) + list(APPEND srcs "ppp_connect.c") +endif() + idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "include" @@ -34,3 +38,7 @@ endif() if(CONFIG_EXAMPLE_CONNECT_ETHERNET) idf_component_optional_requires(PRIVATE esp_eth) endif() + +if(CONFIG_EXAMPLE_CONNECT_PPP) + idf_component_optional_requires(PRIVATE esp_tinyusb espressif__esp_tinyusb) +endif() diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild index 7eb2a8fd6f8c..6329d3a4751a 100644 --- a/examples/common_components/protocol_examples_common/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -306,16 +306,80 @@ menu "Example Connection Configuration" Set PHY address according your board schematic. endif # EXAMPLE_CONNECT_ETHERNET + config EXAMPLE_CONNECT_PPP + bool "connect using Point to Point interface" + select LWIP_PPP_SUPPORT + help + Protocol examples can use PPP connection over serial line. + Choose this option to connect to the ppp server running + on your laptop over a serial line (either UART or USB ACM) + + if EXAMPLE_CONNECT_PPP + choice EXAMPLE_CONNECT_PPP_DEVICE + prompt "Choose PPP device" + default EXAMPLE_CONNECT_PPP_DEVICE_USB + help + Select which peripheral to use to connect to the PPP server. + + config EXAMPLE_CONNECT_PPP_DEVICE_USB + bool "USB" + depends on SOC_USB_OTG_SUPPORTED + select TINYUSB_CDC_ENABLED + help + Use USB ACM device. + + config EXAMPLE_CONNECT_PPP_DEVICE_UART + bool "UART" + help + Use UART. + + endchoice + + menu "UART Configuration" + depends on EXAMPLE_CONNECT_PPP_DEVICE_UART + config EXAMPLE_CONNECT_UART_TX_PIN + int "TXD Pin Number" + default 4 + range 0 31 + help + Pin number of UART TX. + + config EXAMPLE_CONNECT_UART_RX_PIN + int "RXD Pin Number" + default 5 + range 0 31 + help + Pin number of UART RX. + + config EXAMPLE_CONNECT_UART_BAUDRATE + int "UART Baudrate" + default 115200 + range 9600 3000000 + help + Baudrate of the UART device + + endmenu + + config EXAMPLE_PPP_CONN_MAX_RETRY + int "Maximum retry" + default 6 + help + Set the Maximum retry to avoid station reconnecting if the pppd + is not available + + endif # EXAMPLE_CONNECT_PPP + config EXAMPLE_CONNECT_IPV4 bool depends on LWIP_IPV4 default y config EXAMPLE_CONNECT_IPV6 - depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET + depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET || EXAMPLE_CONNECT_PPP bool "Obtain IPv6 address" default y select LWIP_IPV6 + select LWIP_PPP_ENABLE_IPV6 if EXAMPLE_CONNECT_PPP help By default, examples will wait until IPv4 and IPv6 local link addresses are obtained. Disable this option if the network does not support IPv6. diff --git a/examples/common_components/protocol_examples_common/README.md b/examples/common_components/protocol_examples_common/README.md new file mode 100644 index 000000000000..f80d6b2fa8ee --- /dev/null +++ b/examples/common_components/protocol_examples_common/README.md @@ -0,0 +1,58 @@ +# protocol_example_connect + +This component implements the most common connection methods for ESP32 boards. It should be used mainly in examples of ESP-IDF to demonstrate functionality of network protocols and other libraries, that need the connection step as a prerequisite. + +## How to use this component + +Choose the preferred interface (WiFi, Ethernet, PPPoS) to connect to the network and configure the interface. + +It is possible to enable multiple interfaces simultaneously making the connection phase to block until all the chosen interfaces acquire IP addresses. +It is also possible to disable all interfaces, skipping the connection phase altogether. + +### WiFi + +Choose WiFi connection method (for chipsets that support it) and configure basic WiFi connection properties: +* WiFi SSID +* WiFI password +* Maximum connection retry (connection would be aborted if it doesn't succeed after specified number of retries) +* WiFi scan method (including RSSI and authorization mode threshold) + + + +### Ethernet + +Choose Ethernet connection if your board supports it. The most common settings is using Espressif Ethernet Kit, which is also the recommended HW for this selection. You can also select an SPI ethernet device (if your chipset doesn't support internal EMAC or if you prefer). It is also possible to use OpenCores Ethernet MAC if you're running the example under QEMU. + +### PPP + +Point to point connection method creates a simple IP tunnel to the counterpart device (running PPP server), typically a Linux machine with pppd service. We currently support only PPP over Serial (using UART or USB CDC). This is useful for simple testing of networking layers, but with some additional configuration on the server side, we could simulate standard model of internet connectivity. The PPP server could be also represented by a cellular modem device with pre-configured connectivity and already switched to PPP mode (this setup is not very flexible though, so we suggest using a standard modem library implementing commands and modes, e.g. [esp_modem](https://components.espressif.com/component/espressif/esp_modem) ). + +> [!Note] +> Note that if you choose USB device, you have to manually add a dependency on `esp_tinyusb` component. This step is necessary to keep the `protocol_example_connect` component simple and dependency free. Please run this command from your project location to add the dependency: +> ```bash +> idf.py add-dependency espressif/esp_tinyusb^1 +> ``` + +#### Setup a PPP server + +Connect the board using UART or USB and note the device name, which would be typically: +* `/dev/ttyACMx` for USB devices +* `/dev/ttyUSBx` for UART devices + +Run the pppd server: + +```bash +sudo pppd /dev/ttyACM0 115200 192.168.11.1:192.168.11.2 ms-dns 8.8.8.8 modem local noauth debug nocrtscts nodetach +ipv6 +``` + +Please update the parameters with the correct serial device, baud rate, IP addresses, DNS server, use `+ipv6` if `EXAMPLE_CONNECT_IPV6=y`. + +#### Connection to outside + +In order to access other network endpoints, we have to configure some IP/translation rules. The easiest method is to setup a masquerade of the PPPD created interface (`ppp0`) to your default networking interface (`${ETH0}`). Here is an example of such rule: + +```bash +sudo iptables -t nat -A POSTROUTING -o ${ETH0} -j MASQUERADE +sudo iptables -A FORWARD -i ${ETH0} -o ppp0 -m state --state RELATED,ESTABLISHED -j ACCEPT +sudo iptables -A FORWARD -i ppp0 -o ${ETH0} -j ACCEPT +``` diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c index 6abc2a3d24c5..f6aa9bbee8e1 100644 --- a/examples/common_components/protocol_examples_common/connect.c +++ b/examples/common_components/protocol_examples_common/connect.c @@ -101,6 +101,12 @@ esp_err_t example_connect(void) } ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_wifi_shutdown)); #endif +#if CONFIG_EXAMPLE_CONNECT_PPP + if (example_ppp_connect() != ESP_OK) { + return ESP_FAIL; + } + ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_ppp_shutdown)); +#endif #if CONFIG_EXAMPLE_CONNECT_ETHERNET example_print_all_netif_ips(EXAMPLE_NETIF_DESC_ETH); @@ -110,6 +116,10 @@ esp_err_t example_connect(void) example_print_all_netif_ips(EXAMPLE_NETIF_DESC_STA); #endif +#if CONFIG_EXAMPLE_CONNECT_PPP + example_print_all_netif_ips(EXAMPLE_NETIF_DESC_PPP); +#endif + return ESP_OK; } diff --git a/examples/common_components/protocol_examples_common/include/example_common_private.h b/examples/common_components/protocol_examples_common/include/example_common_private.h index b85d26d6360c..8a0b880ecbd7 100644 --- a/examples/common_components/protocol_examples_common/include/example_common_private.h +++ b/examples/common_components/protocol_examples_common/include/example_common_private.h @@ -45,6 +45,9 @@ void example_wifi_shutdown(void); esp_err_t example_wifi_connect(void); void example_ethernet_shutdown(void); esp_err_t example_ethernet_connect(void); +esp_err_t example_ppp_connect(void); +void example_ppp_start(void); +void example_ppp_shutdown(void); diff --git a/examples/common_components/protocol_examples_common/include/protocol_examples_common.h b/examples/common_components/protocol_examples_common/include/protocol_examples_common.h index 430cdae7f913..fc2e54cd3529 100644 --- a/examples/common_components/protocol_examples_common/include/protocol_examples_common.h +++ b/examples/common_components/protocol_examples_common/include/protocol_examples_common.h @@ -31,6 +31,10 @@ extern "C" { #define EXAMPLE_NETIF_DESC_ETH "example_netif_eth" #endif +#if CONFIG_EXAMPLE_CONNECT_PPP +#define EXAMPLE_NETIF_DESC_PPP "example_netif_ppp" +#endif + /* Example default interface, prefer the ethernet one if running in example-test (CI) configuration */ #if CONFIG_EXAMPLE_CONNECT_ETHERNET #define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH) @@ -38,6 +42,9 @@ extern "C" { #elif CONFIG_EXAMPLE_CONNECT_WIFI #define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_STA) #define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_STA) +#elif CONFIG_EXAMPLE_CONNECT_PPP +#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_PPP) +#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_PPP) #endif /** diff --git a/examples/common_components/protocol_examples_common/ppp_connect.c b/examples/common_components/protocol_examples_common/ppp_connect.c new file mode 100644 index 000000000000..090a3ed69cb4 --- /dev/null +++ b/examples/common_components/protocol_examples_common/ppp_connect.c @@ -0,0 +1,260 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "protocol_examples_common.h" +#include "example_common_private.h" + +#if CONFIG_EXAMPLE_CONNECT_PPP +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_netif_ppp.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB +#include "tinyusb.h" +#include "tusb_cdc_acm.h" + +static int s_itf; +static uint8_t buf[CONFIG_TINYUSB_CDC_RX_BUFSIZE]; + +#else // DEVICE is UART + +#include "driver/uart.h" +#define BUF_SIZE (1024) +static bool s_stop_task = false; + +#endif // CONNECT_PPP_DEVICE + + +static const char *TAG = "example_connect_ppp"; +static int s_retry_num = 0; +static EventGroupHandle_t s_event_group = NULL; +static esp_netif_t *s_netif; +static const int GOT_IPV4 = BIT0; +static const int CONNECTION_FAILED = BIT1; +#if CONFIG_EXAMPLE_CONNECT_IPV6 +static const int GOT_IPV6 = BIT2; +#define CONNECT_BITS (GOT_IPV4|GOT_IPV6|CONNECTION_FAILED) +#else +#define CONNECT_BITS (GOT_IPV4|CONNECTION_FAILED) +#endif + +static esp_err_t transmit(void *h, void *buffer, size_t len) +{ + ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + tinyusb_cdcacm_write_queue(s_itf, buffer, len); + tinyusb_cdcacm_write_flush(s_itf, 0); +#else // DEVICE_UART + uart_write_bytes(UART_NUM_1, buffer, len); +#endif // CONNECT_PPP_DEVICE + return ESP_OK; +} + +static esp_netif_driver_ifconfig_t driver_cfg = { + .handle = (void *)1, // singleton driver, just to != NULL + .transmit = transmit, +}; +const esp_netif_driver_ifconfig_t *ppp_driver_cfg = &driver_cfg; + +static void on_ip_event(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + + if (event_id == IP_EVENT_PPP_GOT_IP) { + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_netif_t *netif = event->esp_netif; + esp_netif_dns_info_t dns_info; + ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); + esp_netif_get_dns_info(netif, ESP_NETIF_DNS_MAIN, &dns_info); + ESP_LOGI(TAG, "Main DNS server : " IPSTR, IP2STR(&dns_info.ip.u_addr.ip4)); + xEventGroupSetBits(s_event_group, GOT_IPV4); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + } else if (event_id == IP_EVENT_GOT_IP6) { + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_PPP, event->esp_netif)) { + return; + } + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), + IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { + xEventGroupSetBits(s_event_group, GOT_IPV6); + } +#endif + } else if (event_id == IP_EVENT_PPP_LOST_IP) { + ESP_LOGI(TAG, "Disconnect from PPP Server"); + s_retry_num++; + if (s_retry_num > CONFIG_EXAMPLE_PPP_CONN_MAX_RETRY) { + ESP_LOGE(TAG, "PPP Connection failed %d times, stop reconnecting.", s_retry_num); + xEventGroupSetBits(s_event_group, CONNECTION_FAILED); + } else { + ESP_LOGI(TAG, "PPP Connection failed %d times, try to reconnect.", s_retry_num); + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + } + + } +} + +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB +static void cdc_rx_callback(int itf, cdcacm_event_t *event) +{ + size_t rx_size = 0; + if (itf != s_itf) { + // Not our channel + return; + } + esp_err_t ret = tinyusb_cdcacm_read(itf, buf, CONFIG_TINYUSB_CDC_RX_BUFSIZE, &rx_size); + if (ret == ESP_OK) { + ESP_LOG_BUFFER_HEXDUMP(TAG, buf, rx_size, ESP_LOG_VERBOSE); + // pass the received data to the network interface + esp_netif_receive(s_netif, buf, rx_size, NULL); + } else { + ESP_LOGE(TAG, "Read error"); + } +} + +static void line_state_changed(int itf, cdcacm_event_t *event) +{ + s_itf = itf; // use this channel for the netif communication + ESP_LOGI(TAG, "Line state changed on channel %d", itf); +} +#else // DEVICE is UART + +static void ppp_task(void *args) +{ + uart_config_t uart_config = {}; + uart_config.baud_rate = CONFIG_EXAMPLE_CONNECT_UART_BAUDRATE; + uart_config.data_bits = UART_DATA_8_BITS; + uart_config.parity = UART_PARITY_DISABLE; + uart_config.stop_bits = UART_STOP_BITS_1; + uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE; + uart_config.source_clk = UART_SCLK_DEFAULT; + + QueueHandle_t event_queue; + ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, BUF_SIZE, 0, 16, &event_queue, 0)); + ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config)); + ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, CONFIG_EXAMPLE_CONNECT_UART_TX_PIN, CONFIG_EXAMPLE_CONNECT_UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + ESP_ERROR_CHECK(uart_set_rx_timeout(UART_NUM_1, 1)); + + char *buffer = (char*)malloc(BUF_SIZE); + uart_event_t event; + esp_event_handler_register(IP_EVENT, IP_EVENT_PPP_GOT_IP, esp_netif_action_connected, s_netif); + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); + while (!s_stop_task) { + xQueueReceive(event_queue, &event, pdMS_TO_TICKS(1000)); + if (event.type == UART_DATA) { + size_t len; + uart_get_buffered_data_len(UART_NUM_1, &len); + if (len) { + len = uart_read_bytes(UART_NUM_1, buffer, BUF_SIZE, 0); + ESP_LOG_BUFFER_HEXDUMP(TAG, buffer, len, ESP_LOG_VERBOSE); + esp_netif_receive(s_netif, buffer, len, NULL); + } + } else { + ESP_LOGW(TAG, "Received UART event: %d", event.type); + } + } + free(buffer); + vTaskDelete(NULL); +} + +#endif // CONNECT_PPP_DEVICE + +esp_err_t example_ppp_connect(void) +{ + ESP_LOGI(TAG, "Start example_connect."); + +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + ESP_LOGI(TAG, "USB initialization"); + const tinyusb_config_t tusb_cfg = { + .device_descriptor = NULL, + .string_descriptor = NULL, + .external_phy = false, + .configuration_descriptor = NULL, + }; + + ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg)); + + tinyusb_config_cdcacm_t acm_cfg = { + .usb_dev = TINYUSB_USBDEV_0, + .cdc_port = TINYUSB_CDC_ACM_0, + .callback_rx = &cdc_rx_callback, + .callback_rx_wanted_char = NULL, + .callback_line_state_changed = NULL, + .callback_line_coding_changed = NULL + }; + + ESP_ERROR_CHECK(tusb_cdc_acm_init(&acm_cfg)); + /* the second way to register a callback */ + ESP_ERROR_CHECK(tinyusb_cdcacm_register_callback( + TINYUSB_CDC_ACM_0, + CDC_EVENT_LINE_STATE_CHANGED, + &line_state_changed)); +#endif // CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + + s_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event, NULL)); + + esp_netif_inherent_config_t base_netif_cfg = ESP_NETIF_INHERENT_DEFAULT_PPP(); + base_netif_cfg.if_desc = EXAMPLE_NETIF_DESC_PPP; + esp_netif_config_t netif_ppp_config = { .base = &base_netif_cfg, + .driver = ppp_driver_cfg, + .stack = ESP_NETIF_NETSTACK_DEFAULT_PPP + }; + + s_netif = esp_netif_new(&netif_ppp_config); + assert(s_netif); +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_USB + esp_netif_action_start(s_netif, 0, 0, 0); + esp_netif_action_connected(s_netif, 0, 0, 0); +#else // DEVICE is UART + s_stop_task = false; + if (xTaskCreate(ppp_task, "ppp connect", 4096, NULL, 5, NULL) != pdTRUE) { + ESP_LOGE(TAG, "Failed to create a ppp connection task"); + return ESP_FAIL; + } +#endif // CONNECT_PPP_DEVICE + + ESP_LOGI(TAG, "Waiting for IP address"); + EventBits_t bits = xEventGroupWaitBits(s_event_group, CONNECT_BITS, pdFALSE, pdFALSE, portMAX_DELAY); + if (bits & CONNECTION_FAILED) { + ESP_LOGE(TAG, "Connection failed!"); + return ESP_FAIL; + } + ESP_LOGI(TAG, "Connected!"); + + return ESP_OK; +} + +void example_ppp_shutdown(void) +{ + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, on_ip_event)); +#if CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_UART + s_stop_task = true; + vTaskDelay(pdMS_TO_TICKS(1000)); // wait for the ppp task to stop +#endif + + esp_netif_action_disconnected(s_netif, 0, 0, 0); + + vEventGroupDelete(s_event_group); + esp_netif_action_stop(s_netif, 0, 0, 0); + esp_netif_destroy(s_netif); + s_netif = NULL; + s_event_group = NULL; +} + +#endif // CONFIG_EXAMPLE_CONNECT_PPP From 327629c527e316f3c179637d510db5d9cac89cec Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 12 Oct 2023 17:16:26 +0200 Subject: [PATCH 103/161] feat(example): Use PPP config in one MQTT example to be build in CI, but only running PPP on UART to avoid adding tinyusb dependency. --- examples/protocols/mqtt/tcp/sdkconfig.ci.ppp_connect | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 examples/protocols/mqtt/tcp/sdkconfig.ci.ppp_connect diff --git a/examples/protocols/mqtt/tcp/sdkconfig.ci.ppp_connect b/examples/protocols/mqtt/tcp/sdkconfig.ci.ppp_connect new file mode 100644 index 000000000000..7366a909ec9e --- /dev/null +++ b/examples/protocols/mqtt/tcp/sdkconfig.ci.ppp_connect @@ -0,0 +1,3 @@ +CONFIG_EXAMPLE_CONNECT_WIFI=n +CONFIG_EXAMPLE_CONNECT_PPP=y +CONFIG_EXAMPLE_CONNECT_PPP_DEVICE_UART=y From 0ea0b39725b45d39eca390190463b10d414a8586 Mon Sep 17 00:00:00 2001 From: gaoxu Date: Mon, 30 Oct 2023 12:11:17 +0800 Subject: [PATCH 104/161] feat(adc_cali): Add ADC calibration support for ESP32H2 --- .../legacy_adc_driver/main/test_legacy_adc.c | 8 +- .../efuse/esp32h2/esp_efuse_rtc_calib.c | 114 ++++++++++++++++++ .../esp32h2/include/esp_efuse_rtc_calib.h | 23 +++- .../esp32h2/curve_fitting_coefficients.c | 61 ++++++++++ .../esp32h2/include/adc_cali_schemes.h | 2 +- .../test_apps/adc/main/test_common_adc.h | 10 +- components/hal/esp32h2/include/hal/adc_ll.h | 31 +++++ .../include/esp32h2/idf_performance_target.h | 2 +- .../esp32h2/include/soc/Kconfig.soc_caps.in | 10 +- .../soc/esp32h2/include/soc/regi2c_saradc.h | 4 + components/soc/esp32h2/include/soc/soc_caps.h | 4 +- 11 files changed, 251 insertions(+), 18 deletions(-) create mode 100644 components/esp_adc/esp32h2/curve_fitting_coefficients.c diff --git a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c index 455ec7c5d04d..2a6a7176103f 100644 --- a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c +++ b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c @@ -60,11 +60,11 @@ #define ADC_TEST_HIGH_VAL 3350 #define ADC_TEST_HIGH_THRESH 200 -#elif CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6216 -#define ADC_TEST_LOW_VAL 2144 -#define ADC_TEST_LOW_THRESH 200 +#elif CONFIG_IDF_TARGET_ESP32H2 +#define ADC_TEST_LOW_VAL 0 +#define ADC_TEST_LOW_THRESH 17 -#define ADC_TEST_HIGH_VAL 4081 +#define ADC_TEST_HIGH_VAL 3390 #define ADC_TEST_HIGH_THRESH 200 #endif diff --git a/components/efuse/esp32h2/esp_efuse_rtc_calib.c b/components/efuse/esp32h2/esp_efuse_rtc_calib.c index 5c41630475da..2ff20ea3a3cc 100644 --- a/components/efuse/esp32h2/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32h2/esp_efuse_rtc_calib.c @@ -7,6 +7,120 @@ #include #include "esp_efuse.h" #include "esp_efuse_table.h" +#include "esp_efuse_rtc_calib.h" +#include "hal/efuse_hal.h" + +/** + * @brief Get the signed value by the raw data that read from eFuse + * @param data The raw data that read from eFuse + * @param sign_bit The index of the sign bit, start from 0 + */ +#define RTC_CALIB_GET_SIGNED_VAL(data, sign_bit) ((data & BIT##sign_bit) ? -(int)(data & ~BIT##sign_bit) : (int)data) + +int esp_efuse_rtc_calib_get_ver(void) +{ + uint32_t cali_version = 0; + uint32_t blk_ver = efuse_hal_blk_version(); + if (blk_ver >= 2) { + cali_version = ESP_EFUSE_ADC_CALIB_VER1; + } else { + ESP_LOGW("eFuse", "calibration efuse version does not match, set default version to 0"); + } + + return cali_version; +} + +uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten) +{ + /* Version validation should be guaranteed in the caller */ + assert(atten >=0 && atten < 4); + (void) adc_unit; + + const esp_efuse_desc_t** init_code_efuse; + if (atten == 0) { + init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN0; + } else if (atten == 1) { + init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN1; + } else if (atten == 2) { + init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN2; + } else { + init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN3; + } + + int init_code_size = esp_efuse_get_field_size(init_code_efuse); + assert(init_code_size == 10); + + uint32_t init_code = 0; + ESP_ERROR_CHECK(esp_efuse_read_field_blob(init_code_efuse, &init_code, init_code_size)); + return init_code + 1600; // version 1 logic +} + +int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten) +{ + /* Version validation should be guaranteed in the caller */ + assert(atten < 4); + assert(adc_channel < SOC_ADC_CHANNEL_NUM(adc_unit)); + + const esp_efuse_desc_t** chan_diff_efuse = NULL; + switch (adc_channel) { + case 0: + chan_diff_efuse = ESP_EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF; + break; + case 1: + chan_diff_efuse = ESP_EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF; + break; + case 2: + chan_diff_efuse = ESP_EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF; + break; + case 3: + chan_diff_efuse = ESP_EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF; + break; + default: + chan_diff_efuse = ESP_EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF; + break; + } + + int chan_diff_size = esp_efuse_get_field_size(chan_diff_efuse); + assert(chan_diff_size == 4); + uint32_t chan_diff = 0; + ESP_ERROR_CHECK(esp_efuse_read_field_blob(chan_diff_efuse, &chan_diff, chan_diff_size)); + + return RTC_CALIB_GET_SIGNED_VAL(chan_diff, 3) * (4 - atten); +} + +esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t* out_digi, uint32_t* out_vol_mv) +{ + (void) adc_unit; + const esp_efuse_desc_t** cal_vol_efuse[4] = { + ESP_EFUSE_ADC1_HI_DOUT_ATTEN0, + ESP_EFUSE_ADC1_HI_DOUT_ATTEN1, + ESP_EFUSE_ADC1_HI_DOUT_ATTEN2, + ESP_EFUSE_ADC1_HI_DOUT_ATTEN3, + }; + const uint32_t input_vout_mv[1][4] = { + {750, 1000, 1500, 2800}, // Calibration V1 coefficients + }; + + if ((version < ESP_EFUSE_ADC_CALIB_VER_MIN) || + (version > ESP_EFUSE_ADC_CALIB_VER_MAX)) { + return ESP_ERR_INVALID_ARG; + } + if (atten >= 4 || atten < 0) { + return ESP_ERR_INVALID_ARG; + } + + assert(cal_vol_efuse[atten][0]->bit_count == 10); + + uint32_t cal_vol = 0; + esp_err_t ret = esp_efuse_read_field_blob(cal_vol_efuse[atten], &cal_vol, cal_vol_efuse[atten][0]->bit_count); + if (ret != ESP_OK) { + return ret; + } + uint32_t chk_offset = (atten == 2) ? 2970 : 2900; + *out_digi = chk_offset + RTC_CALIB_GET_SIGNED_VAL(cal_vol, 9); + *out_vol_mv = input_vout_mv[VER2IDX(version)][atten]; + return ESP_OK; +} esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal) { diff --git a/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h index 6929d1e7a9ed..d66708bb1c65 100644 --- a/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,9 +12,10 @@ extern "C" { #endif //This is the ADC calibration value version burnt in efuse -#define ESP_EFUSE_ADC_CALIB_VER 1 -#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER -#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER +#define ESP_EFUSE_ADC_CALIB_VER1 1 +#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER1 +#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER1 +#define VER2IDX(ver) (ver - 1) // Version number to index number of the array /** * @brief Get the RTC calibration efuse version @@ -33,10 +34,22 @@ int esp_efuse_rtc_calib_get_ver(void); */ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten); +/** + * @brief Get the channel specific calibration compensation + * + * @param version Version of the stored efuse + * @param adc_unit ADC unit. Not used, for compatibility. On ESP32H2, for calibration v1, both ADC units use the same init code (calibrated by ADC1) + * @param adc_channel ADC channel number + * @param atten Attenuation of the init code + * @return The channel calibration compensation value + */ +int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten); + /** * @brief Get the calibration digits stored in the efuse, and the corresponding voltage. * * @param version Version of the stored efuse + * @param adc_unit ADC unit (not used on ESP32H2, for compatibility) * @param atten Attenuation to use * @param out_digi Output buffer of the digits * @param out_vol_mv Output of the voltage, in mV @@ -44,7 +57,7 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a * - ESP_ERR_INVALID_ARG: If efuse version or attenuation is invalid * - ESP_OK: if success */ -esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t* out_digi, uint32_t* out_vol_mv); +esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t* out_digi, uint32_t* out_vol_mv); /** * @brief Get the temperature sensor calibration number delta_T stored in the efuse. diff --git a/components/esp_adc/esp32h2/curve_fitting_coefficients.c b/components/esp_adc/esp32h2/curve_fitting_coefficients.c new file mode 100644 index 000000000000..8ba3f37afc37 --- /dev/null +++ b/components/esp_adc/esp32h2/curve_fitting_coefficients.c @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_efuse_rtc_calib.h" +#include "../curve_fitting_coefficients.h" + +#define COEFF_VERSION_NUM 1 // Currently H2 has one versions of curve calibration schemes +#define COEFF_GROUP_NUM 4 +#define TERM_MAX 3 + +/** + * @note Error Calculation + * Coefficients for calculating the reading voltage error. + * Four sets of coefficients for atten0 ~ atten3 respectively. + * + * For each item, first element is the Coefficient, second element is the Multiple. (Coefficient / Multiple) is the real coefficient. + * + * @note {0,0} stands for unused item + * @note In case of the overflow, these coefficients are recorded as Absolute Value + * @note For atten0 ~ 2, error = (K0 * X^0) + (K1 * X^1) + * @note For atten3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + * @note Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered. + */ +const static uint64_t adc1_error_coef_atten[COEFF_VERSION_NUM][COEFF_GROUP_NUM][TERM_MAX][2] = { + /* Coefficients of calibration version 1 */ + { + {{5081991760658888, 1e16}, {7858995318513, 1e19}, {0, 1}}, //atten0 + {{8359230818901277, 1e16}, {9025419089179, 1e19}, {0, 1}}, //atten1 + {{1165668771581976, 1e15}, {8294679249061, 1e19}, {0, 1}}, //atten2 + {{3637329628677273, 1e16}, {19607259738935, 1e18}, {7871689227, 1e16}}, //atten3 + }, +}; + +/** + * Term sign + */ +const static int32_t adc1_error_sign[COEFF_VERSION_NUM][COEFF_GROUP_NUM][TERM_MAX] = { + /* Coefficient sign of calibration version 1 */ + { + {-1, 1, 1}, //atten0 + {-1, 1, 1}, //atten1 + {-1, 1, 1}, //atten2 + {-1, -1, 1}, //atten3 + }, +}; + +void curve_fitting_get_second_step_coeff(const adc_cali_curve_fitting_config_t *config, cali_chars_second_step_t *ctx) +{ + uint32_t adc_calib_ver = esp_efuse_rtc_calib_get_ver(); + assert((adc_calib_ver >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (adc_calib_ver <= ESP_EFUSE_ADC_CALIB_VER_MAX)); + + ctx->term_num = 3; + ctx->coeff = adc1_error_coef_atten[VER2IDX(adc_calib_ver)][config->atten]; + ctx->sign = adc1_error_sign[VER2IDX(adc_calib_ver)][config->atten]; +} diff --git a/components/esp_adc/esp32h2/include/adc_cali_schemes.h b/components/esp_adc/esp32h2/include/adc_cali_schemes.h index 16dc6be4f1fa..96067994e068 100644 --- a/components/esp_adc/esp32h2/include/adc_cali_schemes.h +++ b/components/esp_adc/esp32h2/include/adc_cali_schemes.h @@ -12,4 +12,4 @@ * @brief Supported calibration schemes */ -//Now no scheme supported +#define ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED 1 diff --git a/components/esp_adc/test_apps/adc/main/test_common_adc.h b/components/esp_adc/test_apps/adc/main/test_common_adc.h index 742b536aa958..5228713af93e 100644 --- a/components/esp_adc/test_apps/adc/main/test_common_adc.h +++ b/components/esp_adc/test_apps/adc/main/test_common_adc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -79,11 +79,11 @@ extern "C" { #define ADC_TEST_HIGH_VAL_DMA 4081 #define ADC_TEST_HIGH_THRESH 200 -#elif CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6216 -#define ADC_TEST_LOW_VAL 2144 -#define ADC_TEST_LOW_THRESH 200 +#elif CONFIG_IDF_TARGET_ESP32H2 +#define ADC_TEST_LOW_VAL 0 +#define ADC_TEST_LOW_THRESH 17 -#define ADC_TEST_HIGH_VAL 4081 +#define ADC_TEST_HIGH_VAL 3390 #define ADC_TEST_HIGH_VAL_DMA 4081 #define ADC_TEST_HIGH_THRESH 200 #endif diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index 31b8976c4090..5e4fbce2b26f 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -593,6 +593,37 @@ static inline void adc_ll_calibration_init(adc_unit_t adc_n) REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1); } +/** + * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration. + * + * @note Different ADC units and different attenuation options use different calibration data (initial data). + * + * @param adc_n ADC index number. + * @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage. + * false: Use IO external voltage as calibration voltage. + */ +static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gnd) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + /* Enable/disable internal connect GND (for calibration). */ + if (internal_gnd) { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 1); + } else { + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0); + } +} + +/** + * Resume register status after calibration. + * + * @param adc_n ADC index number. + */ +static inline void adc_ll_calibration_finish(adc_unit_t adc_n) +{ + HAL_ASSERT(adc_n == ADC_UNIT_1); + REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0); +} + /** * Set the calibration result to ADC. * diff --git a/components/idf_test/include/esp32h2/idf_performance_target.h b/components/idf_test/include/esp32h2/idf_performance_target.h index 33f100aa5462..9bc935c895f1 100644 --- a/components/idf_test/include/esp32h2/idf_performance_target.h +++ b/components/idf_test/include/esp32h2/idf_performance_target.h @@ -36,10 +36,10 @@ #define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV 70 #define IDF_PERFORMANCE_MAX_CYCLES_PER_SQRT 140 -//TODO: IDF-6216 #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER 10 #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2 10 #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4 10 #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8 10 #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16 10 #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64 10 +#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3 10 diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 110397316c1f..3185323be1df 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -301,7 +301,15 @@ config SOC_ADC_RTC_MAX_BITWIDTH config SOC_ADC_CALIBRATION_V1_SUPPORTED bool - default n + default y + +config SOC_ADC_SELF_HW_CALI_SUPPORTED + bool + default y + +config SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED + bool + default y config SOC_ADC_TEMPERATURE_SHARE_INTR bool diff --git a/components/soc/esp32h2/include/soc/regi2c_saradc.h b/components/soc/esp32h2/include/soc/regi2c_saradc.h index 7d211bf6aabf..aaa5fcfa7bcf 100644 --- a/components/soc/esp32h2/include/soc/regi2c_saradc.h +++ b/components/soc/esp32h2/include/soc/regi2c_saradc.h @@ -69,3 +69,7 @@ #define I2C_SARADC_SAR2_INIT_CODE_MSB 4 #define I2C_SARADC_SAR2_INIT_CODE_MSB_MSB 3 #define I2C_SARADC_SAR2_INIT_CODE_MSB_LSB 0 + +#define ADC_SAR1_ENCAL_GND_ADDR 0x8 +#define ADC_SAR1_ENCAL_GND_ADDR_MSB 0x1 +#define ADC_SAR1_ENCAL_GND_ADDR_LSB 0x1 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index f267085e02df..f9315797088b 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -119,7 +119,9 @@ #define SOC_ADC_RTC_MAX_BITWIDTH (12) /*!< Calibration */ -#define SOC_ADC_CALIBRATION_V1_SUPPORTED (0) /*!< support HW offset calibration version 1*/ +#define SOC_ADC_CALIBRATION_V1_SUPPORTED (1) /*!< support HW offset calibration version 1*/ +#define SOC_ADC_SELF_HW_CALI_SUPPORTED (1) /*!< support HW offset self calibration */ +#define SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED (1) /*!< support channel compensation to the HW offset calibration */ /*!< Interrupt */ #define SOC_ADC_TEMPERATURE_SHARE_INTR (1) From 8b8d4a0ffce15d44a87e26605c0c450ec7492220 Mon Sep 17 00:00:00 2001 From: Shreyas Sheth Date: Thu, 24 Aug 2023 18:56:09 +0530 Subject: [PATCH 105/161] fix(wifi): wpa3 softap fix deauth when assoc req recv before sae is finished --- components/esp_wifi/lib | 2 +- .../wpa_supplicant/esp_supplicant/src/esp_wpa_main.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index ee1f0c433287..fbe999ab6886 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit ee1f0c43328754e64f43803fc532faaba489d3f4 +Subproject commit fbe999ab688618498ee98b1569c23ed11c8889ce 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 8d807836548d..6f3c69110f2a 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -321,12 +321,15 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len,u8 sta_info = ap_sta_add(hapd, bssid); if (!sta_info) { wpa_printf(MSG_ERROR, "failed to add station " MACSTR, MAC2STR(bssid)); - return false; + goto fail; } #ifdef CONFIG_SAE if (sta_info->lock && os_semphr_take(sta_info->lock, 0) != TRUE) { wpa_printf(MSG_INFO, "Ignore assoc request as softap is busy with sae calculation for station "MACSTR, MAC2STR(bssid)); + if (esp_send_assoc_resp(hapd, sta_info, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) { + goto fail; + } return false; } #endif /* CONFIG_SAE */ @@ -357,10 +360,7 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len,u8 } fail: - if (sta_info) { - ap_free_sta(hapd, sta_info); - } - + esp_wifi_ap_deauth_internal(bssid, WLAN_REASON_PREV_AUTH_NOT_VALID); return false; } #endif From d78750306de2135f032da3976ae3078587dd2c90 Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 26 Oct 2023 18:01:30 +0800 Subject: [PATCH 106/161] refactor(emac): use clock_output driver for configuring RMII reference clock --- components/esp_eth/src/esp_eth_mac_esp.c | 18 +++++++++++++----- .../{include/esp_private => }/clkout_channel.h | 2 ++ components/esp_hw_support/esp_clock_output.c | 9 ++++----- .../esp_hw_support/include/esp_clock_output.h | 8 ++------ 4 files changed, 21 insertions(+), 16 deletions(-) rename components/esp_hw_support/{include/esp_private => }/clkout_channel.h (99%) diff --git a/components/esp_eth/src/esp_eth_mac_esp.c b/components/esp_eth/src/esp_eth_mac_esp.c index d59e1e33b4ab..25472c1e8cb6 100644 --- a/components/esp_eth/src/esp_eth_mac_esp.c +++ b/components/esp_eth/src/esp_eth_mac_esp.c @@ -18,6 +18,7 @@ #include "esp_cpu.h" #include "esp_heap_caps.h" #include "esp_intr_alloc.h" +#include "esp_clock_output.h" #include "esp_private/esp_clk.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -51,6 +52,7 @@ typedef struct { int smi_mdc_gpio_num; int smi_mdio_gpio_num; eth_mac_clock_config_t clock_config; + esp_clock_output_mapping_handle_t rmii_clk_hdl; // we use the esp_clock_output driver to output a pre-configured APLL clock as the RMII reference clock uint8_t addr[6]; uint8_t *rx_buf[CONFIG_ETH_DMA_RX_BUFFER_NUM]; uint8_t *tx_buf[CONFIG_ETH_DMA_TX_BUFFER_NUM]; @@ -472,6 +474,9 @@ static void esp_emac_free_driver_obj(emac_esp32_t *emac, void *descriptors) for (int i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) { free(emac->rx_buf[i]); } + if (emac->rmii_clk_hdl) { + esp_clock_output_stop(emac->rmii_clk_hdl); + } #ifdef CONFIG_PM_ENABLE if (emac->pm_lock) { esp_pm_lock_delete(emac->pm_lock); @@ -519,7 +524,7 @@ static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_ core_num = esp_cpu_get_core_id(); } BaseType_t xReturned = xTaskCreatePinnedToCore(emac_esp32_rx_task, "emac_rx", config->rx_task_stack_size, emac, - config->rx_task_prio, &emac->rx_task_hdl, core_num); + config->rx_task_prio, &emac->rx_task_hdl, core_num); ESP_GOTO_ON_FALSE(xReturned == pdPASS, ESP_FAIL, err, TAG, "create emac_rx task failed"); *out_descriptors = descriptors; @@ -578,15 +583,18 @@ static esp_err_t esp_emac_config_data_interface(const eth_esp32_emac_config_t *e emac->clock_config.rmii.clock_gpio == EMAC_CLK_OUT_180_GPIO, ESP_ERR_INVALID_ARG, err, TAG, "invalid EMAC clock output GPIO"); emac_hal_iomux_rmii_clk_ouput(emac->clock_config.rmii.clock_gpio); - if (emac->clock_config.rmii.clock_gpio == EMAC_APPL_CLK_OUT_GPIO) { - REG_SET_FIELD(PIN_CTRL, CLK_OUT1, 6); - } /* Enable RMII clock */ emac_hal_clock_enable_rmii_output(&emac->hal); - // Power up APLL clock + // the RMII reference comes from the APLL periph_rtc_apll_acquire(); ESP_GOTO_ON_ERROR(emac_config_apll_clock(), err, TAG, "Configure APLL for RMII failed"); emac->use_apll = true; + + // we can also use the IOMUX to route the APLL clock to specific GPIO + if (emac->clock_config.rmii.clock_gpio == EMAC_APPL_CLK_OUT_GPIO) { + ESP_GOTO_ON_ERROR(esp_clock_output_start(CLKOUT_SIG_APLL, EMAC_APPL_CLK_OUT_GPIO, &emac->rmii_clk_hdl), + err, TAG, "start APLL clock output failed"); + } } else { ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid EMAC clock mode"); } diff --git a/components/esp_hw_support/include/esp_private/clkout_channel.h b/components/esp_hw_support/clkout_channel.h similarity index 99% rename from components/esp_hw_support/include/esp_private/clkout_channel.h rename to components/esp_hw_support/clkout_channel.h index 2daa0d447f24..57169f0cc209 100644 --- a/components/esp_hw_support/include/esp_private/clkout_channel.h +++ b/components/esp_hw_support/clkout_channel.h @@ -5,7 +5,9 @@ */ #pragma once + #include "sdkconfig.h" +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_hw_support/esp_clock_output.c b/components/esp_hw_support/esp_clock_output.c index 0ccf01232301..1f2248aa40aa 100644 --- a/components/esp_hw_support/esp_clock_output.c +++ b/components/esp_hw_support/esp_clock_output.c @@ -6,13 +6,12 @@ #include #include "sdkconfig.h" - +#include "freertos/FreeRTOS.h" #include "driver/gpio.h" #include "esp_clock_output.h" #include "esp_check.h" #include "esp_rom_gpio.h" -#include "esp_private/clkout_channel.h" -#include "esp_private/startup_internal.h" +#include "clkout_channel.h" #include "hal/gpio_hal.h" #include "soc/soc_caps.h" #include "soc/io_mux_reg.h" @@ -59,13 +58,13 @@ static clkout_channel_handle_t* clkout_channel_alloc(soc_clkout_sig_id_t clk_sig s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].is_mapped = true; allocated_channel = &s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)]; } else if ((s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_io_bmap & BIT(gpio_num)) && - (s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_clock == clk_sig)) { + (s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_clock == clk_sig)) { allocated_channel = &s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)]; } allocated_channel->channel_id = (clock_out_channel_t)IONUM_TO_CLKOUT_CHANNEL(gpio_num); portEXIT_CRITICAL(&s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].clkout_channel_lock); #elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX - for(uint32_t channel = 0; channel < CLKOUT_CHANNEL_MAX; channel++) { + for (uint32_t channel = 0; channel < CLKOUT_CHANNEL_MAX; channel++) { portENTER_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock); if (!s_clkout_handle[channel].is_mapped) { s_clkout_handle[channel].is_mapped = true; diff --git a/components/esp_hw_support/include/esp_clock_output.h b/components/esp_hw_support/include/esp_clock_output.h index 33c87f9cec51..2acbb1377d80 100644 --- a/components/esp_hw_support/include/esp_clock_output.h +++ b/components/esp_hw_support/include/esp_clock_output.h @@ -6,15 +6,11 @@ #pragma once -#include #include -#include "sdkconfig.h" +#include "esp_err.h" #include "soc/soc_caps.h" #include "soc/clk_tree_defs.h" - -#include "esp_err.h" #include "driver/gpio.h" -#include "freertos/FreeRTOS.h" #ifdef __cplusplus extern "C" { @@ -46,7 +42,7 @@ esp_err_t esp_clock_output_start(soc_clkout_sig_id_t clk_sig, gpio_num_t gpio_nu * - ESP_ERR_INVALID_STATE The clock in handle is already in the disabled state */ esp_err_t esp_clock_output_stop(esp_clock_output_mapping_handle_t clkout_mapping_hdl); -#endif +#endif // SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX || SOC_GPIO_CLOCKOUT_BY_IO_MUX #ifdef __cplusplus } From b301f175c93dde97b7d7c32bb67db73ca965786d Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Thu, 26 Oct 2023 22:41:36 +0800 Subject: [PATCH 107/161] feat(freertos/idf): Add configRUN_TIME_COUNTER_TYPE option This commit adds a Kconfig option for configRUN_TIME_COUNTER_TYPE Closes https://github.com/espressif/esp-idf/issues/11973 --- components/freertos/Kconfig | 19 +++++++++++++++++++ .../config/include/freertos/FreeRTOSConfig.h | 8 ++++++++ .../freertos/sdkconfig.ci.freertos_options | 1 + 3 files changed, 28 insertions(+) diff --git a/components/freertos/Kconfig b/components/freertos/Kconfig index eccb221ff27a..d8ca79b487c2 100644 --- a/components/freertos/Kconfig +++ b/components/freertos/Kconfig @@ -244,6 +244,25 @@ menu "FreeRTOS" Note: The clock used for run time statistics can be configured in FREERTOS_RUN_TIME_STATS_CLK. + choice FREERTOS_RUN_TIME_COUNTER_TYPE + prompt "configRUN_TIME_COUNTER_TYPE" + depends on FREERTOS_GENERATE_RUN_TIME_STATS && !FREERTOS_SMP + default FREERTOS_RUN_TIME_COUNTER_TYPE_U32 + help + Sets the data type used for the FreeRTOS run time stats. A larger data type can be used to reduce the + frequency of the counter overflowing. + + config FREERTOS_RUN_TIME_COUNTER_TYPE_U32 + bool "uint32_t" + help + configRUN_TIME_COUNTER_TYPE is set to uint32_t + + config FREERTOS_RUN_TIME_COUNTER_TYPE_U64 + bool "uint64_t" + help + configRUN_TIME_COUNTER_TYPE is set to uint64_t + endchoice # FREERTOS_RUN_TIME_COUNTER_TYPE + config FREERTOS_USE_TICKLESS_IDLE # Todo: Currently not supported in SMP FreeRTOS yet (IDF-4986) # Todo: Consider whether this option should still be exposed (IDF-4986) diff --git a/components/freertos/config/include/freertos/FreeRTOSConfig.h b/components/freertos/config/include/freertos/FreeRTOSConfig.h index 623272fbc37d..c8e7922615dc 100644 --- a/components/freertos/config/include/freertos/FreeRTOSConfig.h +++ b/components/freertos/config/include/freertos/FreeRTOSConfig.h @@ -165,6 +165,14 @@ #define configUSE_STATS_FORMATTING_FUNCTIONS 1 /* Used by vTaskList() */ #endif /* CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS */ +#if !CONFIG_FREERTOS_SMP + #if CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U32 + #define configRUN_TIME_COUNTER_TYPE uint32_t + #elif CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U64 + #define configRUN_TIME_COUNTER_TYPE uint64_t + #endif /* CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U64 */ +#endif /* !CONFIG_FREERTOS_SMP */ + /* -------------------- Co-routines ----------------------- */ #define configUSE_CO_ROUTINES 0 /* CO_ROUTINES are not supported in ESP-IDF */ diff --git a/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options b/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options index 541b767a2a45..38ae8ab7df49 100644 --- a/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options +++ b/components/freertos/test_apps/freertos/sdkconfig.ci.freertos_options @@ -13,6 +13,7 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U64=y CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_FREERTOS_FPU_IN_ISR=y CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2 From 4a7a27c189d878f46aa101d5da589959b384326e Mon Sep 17 00:00:00 2001 From: liuning Date: Tue, 31 Oct 2023 14:44:31 +0800 Subject: [PATCH 108/161] fix(rom): fix wifi rom ld --- components/esp_rom/esp32c2/ld/esp32c2.rom.ld | 4 ++-- components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld | 1 + components/esp_rom/esp32c3/ld/esp32c3.rom.ld | 2 +- components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld | 2 +- components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld | 2 +- components/esp_rom/esp32s3/ld/esp32s3.rom.ld | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index 347425d8858d..5fc6c91d2525 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -1520,7 +1520,7 @@ mac_tx_set_htsig = 0x40001b5c; mac_tx_set_plcp0 = 0x40001b60; mac_tx_set_plcp1 = 0x40001b64; mac_tx_set_plcp2 = 0x40001b68; -pm_check_state = 0x40001b6c; +/* pm_check_state = 0x40001b6c; */ pm_disable_dream_timer = 0x40001b70; pm_disable_sleep_delay_timer = 0x40001b74; pm_dream = 0x40001b78; @@ -1880,7 +1880,7 @@ ieee80211_recycle_cache_eb = 0x40001fe8; ieee80211_search_node = 0x40001fec; roundup2 = 0x40001ff0; ieee80211_crypto_encap = 0x40001ff4; -ieee80211_crypto_decap = 0x40001ff8; +/* ieee80211_crypto_decap = 0x40001ff8; */ ieee80211_decap = 0x40001ffc; ieee80211_set_tx_pti = 0x40002000; wifi_is_started = 0x40002004; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld index 3aacbb3819fa..cec8398b4a9b 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld @@ -14,6 +14,7 @@ lmacTxDone = 0x4000162c; lmacTxFrame = 0x40001630; mac_tx_set_htsig = 0x40001638; mac_tx_set_plcp1 = 0x40001640; +pm_check_state = 0x40001648; pm_on_beacon_rx = 0x4000167c; /*pm_parse_beacon = 0x40001688;*/ pm_process_tim = 0x4000168c; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index 742786df59b0..2cadae443849 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -1535,7 +1535,7 @@ mac_tx_set_duration = 0x40001634; mac_tx_set_plcp0 = 0x4000163c; /* mac_tx_set_plcp1 = 0x40001640;*/ mac_tx_set_plcp2 = 0x40001644; -pm_check_state = 0x40001648; +/* pm_check_state = 0x40001648; */ pm_disable_dream_timer = 0x4000164c; pm_disable_sleep_delay_timer = 0x40001650; pm_dream = 0x40001654; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld index e5bd02bd9841..c096f9623991 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld @@ -48,7 +48,7 @@ ieee80211_copy_eb_header = 0x40000bb4; ieee80211_recycle_cache_eb = 0x40000bb8; ieee80211_search_node = 0x40000bbc; ieee80211_crypto_encap = 0x40000bc0; -ieee80211_crypto_decap = 0x40000bc4; +/* ieee80211_crypto_decap = 0x40000bc4; */ ieee80211_decap = 0x40000bc8; wifi_is_started = 0x40000bcc; ieee80211_gettid = 0x40000bd0; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld index 8a75b13a0654..6b9acfb45e3e 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -56,7 +56,7 @@ mac_tx_set_duration = 0x40000c60; //mac_tx_set_plcp0 = 0x40000c64; //mac_tx_set_plcp1 = 0x40000c68; mac_tx_set_plcp2 = 0x40000c6c; -pm_check_state = 0x40000c70; +/* pm_check_state = 0x40000c70; */ /* pm_disable_dream_timer = 0x40000c74; */ pm_disable_sleep_delay_timer = 0x40000c78; pm_dream = 0x40000c7c; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index 6ca2ab5010c1..abe6d427605d 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -1837,7 +1837,7 @@ mac_tx_set_duration = 0x400053dc; mac_tx_set_plcp0 = 0x400053f4; /* mac_tx_set_plcp1 = 0x40005400;*/ mac_tx_set_plcp2 = 0x4000540c; -pm_check_state = 0x40005418; +/* pm_check_state = 0x40005418; */ pm_disable_dream_timer = 0x40005424; pm_disable_sleep_delay_timer = 0x40005430; pm_dream = 0x4000543c; From b878125bae19b1e972cc1b46aaeaf7d1d861eddf Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Tue, 31 Oct 2023 15:44:37 +0800 Subject: [PATCH 109/161] change(freertos): Update real_time_stats example to use configRUN_TIME_COUNTER_TYPE This commit updates the real_time_stats example to use the configurable configRUN_TIME_COUNTER_TYPE. The CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U64 is enabled by the example by default to demonstrate its usage. Note: Also cleaned up redundant configs in sdkconfig.ci --- .../real_time_stats/main/real_time_stats_example_main.c | 2 +- examples/system/freertos/real_time_stats/sdkconfig.ci | 2 -- examples/system/freertos/real_time_stats/sdkconfig.defaults | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/system/freertos/real_time_stats/main/real_time_stats_example_main.c b/examples/system/freertos/real_time_stats/main/real_time_stats_example_main.c index 03639c1b209e..517177a64f5d 100644 --- a/examples/system/freertos/real_time_stats/main/real_time_stats_example_main.c +++ b/examples/system/freertos/real_time_stats/main/real_time_stats_example_main.c @@ -53,7 +53,7 @@ static esp_err_t print_real_time_stats(TickType_t xTicksToWait) { TaskStatus_t *start_array = NULL, *end_array = NULL; UBaseType_t start_array_size, end_array_size; - uint32_t start_run_time, end_run_time; + configRUN_TIME_COUNTER_TYPE start_run_time, end_run_time; esp_err_t ret; //Allocate array to store current task states diff --git a/examples/system/freertos/real_time_stats/sdkconfig.ci b/examples/system/freertos/real_time_stats/sdkconfig.ci index c87713d246d7..e69de29bb2d1 100644 --- a/examples/system/freertos/real_time_stats/sdkconfig.ci +++ b/examples/system/freertos/real_time_stats/sdkconfig.ci @@ -1,2 +0,0 @@ -CONFIG_FREERTOS_USE_TRACE_FACILITY=y -CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y diff --git a/examples/system/freertos/real_time_stats/sdkconfig.defaults b/examples/system/freertos/real_time_stats/sdkconfig.defaults index c87713d246d7..81c4a2635c7e 100644 --- a/examples/system/freertos/real_time_stats/sdkconfig.defaults +++ b/examples/system/freertos/real_time_stats/sdkconfig.defaults @@ -1,2 +1,3 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_RUN_TIME_COUNTER_TYPE_U64=y From ff1016c55fdd8e2d767dc6697e9c0f3b1e6eeb6c Mon Sep 17 00:00:00 2001 From: xueyunfei Date: Mon, 14 Aug 2023 17:54:13 +0800 Subject: [PATCH 110/161] Fix(lwip):bugfix for add config for tcp ooseq bufs --- components/lwip/Kconfig | 37 +++++++++++++++++++++++-- components/lwip/lwip | 2 +- components/lwip/port/include/lwipopts.h | 15 ++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index dc8e3cf6212f..6fadf80b25b4 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -582,7 +582,7 @@ menu "LWIP" Can be set lower to save RAM, the default value 1460(ipv4)/1440(ipv6) will give best throughput. IPv4 TCP_MSS Range: 576 <= TCP_MSS <= 1460 - IPv6 TCP_MSS Range: 1220<= TCP_mSS <= 1440 + IPv6 TCP_MSS Range: 1220<= TCP_MSS <= 1440 config LWIP_TCP_TMR_INTERVAL int "TCP timer interval(ms)" @@ -607,7 +607,7 @@ menu "LWIP" config LWIP_TCP_SND_BUF_DEFAULT int "Default send buffer size" - default 5744 # 4 * default MSS + default 5760 # 4 * default MSS range 2440 65535 if !LWIP_WND_SCALE range 2440 1024000 if LWIP_WND_SCALE help @@ -624,7 +624,7 @@ menu "LWIP" config LWIP_TCP_WND_DEFAULT int "Default receive window size" - default 5744 # 4 * default MSS + default 5760 # 4 * default MSS range 2440 65535 if !LWIP_WND_SCALE range 2440 1024000 if LWIP_WND_SCALE help @@ -666,6 +666,37 @@ menu "LWIP" Disable this option to save some RAM during TCP sessions, at the expense of increased retransmissions if segments arrive out of order. + config LWIP_TCP_OOSEQ_TIMEOUT + int "Timeout for each pbuf queued in TCP OOSEQ, in RTOs." + depends on LWIP_TCP_QUEUE_OOSEQ + range 1 30 + default 6 + help + The timeout value is TCP_OOSEQ_TIMEOUT * RTO. + + config LWIP_TCP_OOSEQ_MAX_PBUFS + int "The maximum number of pbufs queued on OOSEQ per pcb" + depends on LWIP_TCP_QUEUE_OOSEQ + range 0 12 + default 4 + help + If LWIP_TCP_OOSEQ_MAX_PBUFS = 0, TCP will not control the number of OOSEQ pbufs. + + In a poor network environment, many out-of-order tcp pbufs will be received. + These out-of-order pbufs will be cached in the TCP out-of-order queue which will + cause Wi-Fi/Ethernet fail to release RX buffer in time. + It is possible that all RX buffers for MAC layer are used by OOSEQ. + + Control the number of out-of-order pbufs to ensure that the MAC layer has enough RX buffer to receive packets. + + In the Wi-Fi scenario, recommended OOSEQ PBUFS Range: 0 <= TCP_OOSEQ_MAX_PBUFS <= CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM/(MAX_TCP_NUMBER + 1) + + In the Ethernet scenario,recommended Ethernet OOSEQ PBUFS Range: 0 <= TCP_OOSEQ_MAX_PBUFS <= CONFIG_ETH_DMA_RX_BUFFER_NUM/(MAX_TCP_NUMBER + 1) + + Within the recommended value range, the larger the value, the better the performance. + + MAX_TCP_NUMBER represent Maximum number of TCP connections in Wi-Fi(STA+SoftAP) and Ethernet scenario. + config LWIP_TCP_SACK_OUT bool "Support sending selective acknowledgements" default n diff --git a/components/lwip/lwip b/components/lwip/lwip index 6bf7044c0368..4a8286ab8bcf 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit 6bf7044c0368d587f70f7083e39e0a619b4d5788 +Subproject commit 4a8286ab8bcf983f22421e3d4be650837b5eb277 diff --git a/components/lwip/port/include/lwipopts.h b/components/lwip/port/include/lwipopts.h index afe2678d3ad2..1c981f8fc43f 100644 --- a/components/lwip/port/include/lwipopts.h +++ b/components/lwip/port/include/lwipopts.h @@ -545,6 +545,21 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #define TCP_QUEUE_OOSEQ 0 #endif +/** + * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs + * queued on ooseq per pcb + */ +#if TCP_QUEUE_OOSEQ +#define TCP_OOSEQ_MAX_PBUFS CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS +#endif + +/** + * TCP_OOSEQ_TIMEOUT: Timeout for each pbuf queued in TCP OOSEQ, in RTOs. + */ +#if TCP_QUEUE_OOSEQ +#define TCP_OOSEQ_TIMEOUT CONFIG_LWIP_TCP_OOSEQ_TIMEOUT +#endif + /** * LWIP_TCP_SACK_OUT==1: TCP will support sending selective acknowledgements (SACKs). */ From 7c8663ffa99a34c53c5a587d9bfa8ccfac825843 Mon Sep 17 00:00:00 2001 From: kohait00 Date: Tue, 24 Oct 2023 00:33:52 +0200 Subject: [PATCH 111/161] manager: fixing unwinding protocom endpoints, on prov_stop. This enables starting and stopping provisioning on a pre started http server --- components/wifi_provisioning/src/manager.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/wifi_provisioning/src/manager.c b/components/wifi_provisioning/src/manager.c index 69ed01e0fcc3..07022ecbfd3f 100644 --- a/components/wifi_provisioning/src/manager.c +++ b/components/wifi_provisioning/src/manager.c @@ -558,6 +558,16 @@ static void prov_stop_and_notify(bool is_async) vTaskDelay(cleanup_delay / portTICK_PERIOD_MS); } + protocomm_remove_endpoint(prov_ctx->pc, "prov-ctrl"); + + protocomm_remove_endpoint(prov_ctx->pc, "prov-scan"); + + protocomm_remove_endpoint(prov_ctx->pc, "prov-config"); + + protocomm_unset_security(prov_ctx->pc, "prov-session"); + + protocomm_unset_version(prov_ctx->pc, "proto-ver"); + /* All the extra application added endpoints are also * removed automatically when prov_stop is called */ prov_ctx->mgr_config.scheme.prov_stop(prov_ctx->pc); From c6c03d39f8a048ecdcc5d87893e0b98401c95b3c Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Tue, 31 Oct 2023 10:04:08 +0100 Subject: [PATCH 112/161] docs(ulp_riscv): Updated ulp_riscv example README files to update GPIO configuration This commit updates the README files for the ULP RISC-V I2C and Touch sensor examples to mention the GPIO configuration needed to run the examples. --- examples/system/ulp/ulp_riscv/i2c/README.md | 17 ++++++++++++- examples/system/ulp/ulp_riscv/touch/README.md | 24 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/examples/system/ulp/ulp_riscv/i2c/README.md b/examples/system/ulp/ulp_riscv/i2c/README.md index 11ba448c066f..a1496bd3ecaf 100644 --- a/examples/system/ulp/ulp_riscv/i2c/README.md +++ b/examples/system/ulp/ulp_riscv/i2c/README.md @@ -7,13 +7,28 @@ This example demonstrates how to use the RTC I2C peripheral from the ULP RISC-V The ULP program is based on the BMP180 Temperature and Pressure sensor (https://cz.mouser.com/datasheet/2/783/BST-BMP180-DS000-1509579.pdf) which has an I2C interface. The main CPU initializes the RTC I2C peripheral, the BMP180 sensor and loads the ULP program. It then goes into deep sleep. -The ULP program periodically measures the temperature and pressure values from the BMP180 sensor and wakesup the main CPU when the values are above a certain thershold. +The ULP program periodically measures the temperature and pressure values from the BMP180 sensor and wakes up the main CPU when the values are above a certain threshold. + +## How to use example + ### Hardware Required * A development board with a SOC which has a RISC-V ULP coprocessor (e.g., ESP32-S2 Saola) * A BMP180 sensor module * A USB cable for power supply and programming +#### Pin Assignment: + +**Note:** The following pin assignments are used by default. + +| | SDA | SCL | +| --------------------------- | ------| ------| +| ESP32-S2/S3 RTC I2C Master | GPIO3 | GPIO2 | +| BMP180 Sensor | SDA | SCL | + +**Note:** The SDA line can only be configured to use either GPIO1 or GPIO3 and the SCL line can only be configured to use either GPIO0 or GPIO2. +**Note:** This example enables the internal pull-up resistors for the SDA/SCL lines by default. + ## Example output Below is the output from this example. diff --git a/examples/system/ulp/ulp_riscv/touch/README.md b/examples/system/ulp/ulp_riscv/touch/README.md index d8d9afb923f6..7c3694b90655 100644 --- a/examples/system/ulp/ulp_riscv/touch/README.md +++ b/examples/system/ulp/ulp_riscv/touch/README.md @@ -17,6 +17,30 @@ The ULP Program scans all touch pad sensors periodically. When the ULP program f * A development board with ESP32-S2 or ESP32-S3 +The following capacitive touch pads are supported on ESP32-S2/S3: + +``` + ---------------------------------------------------------- + | Touch Pad | GPIO Pin | + |------------|-------------------------------------------| + | T0 | Internal channel, not connected to a GPIO | + | T1 | GPIO1 | + | T2 | GPIO2 | + | T3 | GPIO3 | + | T4 | GPIO4 | + | T5 | GPIO5 | + | T6 | GPIO6 | + | T7 | GPIO7 | + | T8 | GPIO8 | + | T9 | GPIO9 | + | T10 | GPIO10 | + | T11 | GPIO11 | + | T12 | GPIO12 | + | T13 | GPIO13 | + | T14 | GPIO14 | + ---------------------------------------------------------- +``` + ### Build and Flash Build the project and flash it to the board, then run monitor tool to view serial output: From 1ec09cf7b621fd2bdbae2e93e96310cbd8c40963 Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Thu, 19 Oct 2023 12:44:54 +0200 Subject: [PATCH 113/161] fix(tools/docker): set esp-idf repo as safe directory In our docker docs[1] we recommend to start docker as a non-root user. This has a side effect, because the esp-idf repo in docker image is owned by root. Git by default refuses even to parse a config file if the repo is owned by other than current user. As a result the version detection in cmake fails[2] and the app version is set to "HEAD-HASH-NOTFOUND". This adds esp-idf repo to the system git config as a safe one. [1] https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/ tools/idf-docker-image.html#building-a-project-with-cmake [2] https://github.com/espressif/esp-idf/issues/12389#issuecomment-1764268773 Closes https://github.com/espressif/esp-idf/issues/12389 Signed-off-by: Frantisek Hrbata --- tools/docker/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 8ce979b8cdb0..f81ede106753 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -68,6 +68,7 @@ RUN echo IDF_CHECKOUT_REF=$IDF_CHECKOUT_REF IDF_CLONE_BRANCH_OR_TAG=$IDF_CLONE_B ${IDF_CLONE_SHALLOW:+--depth=1 --shallow-submodules} \ ${IDF_CLONE_BRANCH_OR_TAG:+-b $IDF_CLONE_BRANCH_OR_TAG} \ $IDF_CLONE_URL $IDF_PATH && \ + git config --system --add safe.directory $IDF_PATH && \ if [ -n "$IDF_CHECKOUT_REF" ]; then \ cd $IDF_PATH && \ if [ -n "$IDF_CLONE_SHALLOW" ]; then \ From 9e1e2454770bd3014addf2fc5db141856feadc00 Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Fri, 6 Oct 2023 16:51:26 -0400 Subject: [PATCH 114/161] fix(heap): memalign respect malloc_alwaysinternal_limit This changes `memalign` (and `posix_memalign`) so that it uses an allocation method with the same selection criteria (checking `malloc_alwaysinternal_limit` and picking one of: - always MALLOC_CAP_INTERNAL - MALLOC_CAP_INTERNAL first with fallback - MALLOC_CAP_SPIRAM first with fallback `malloc_alwaysinternal_limit` is in turn set by the options `CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL` and `CONFIG_SPRIAM_USE_CAPS_ALLOC`. This notably affects folks using esp-rs to build rust code for the esp-idf, as all allocations from rust use `memalign`. Merges https://github.com/espressif/esp-idf/pull/12375 --- components/heap/heap_caps.c | 102 +++++++++++++----- components/heap/heap_private.h | 1 + components/newlib/heap.c | 7 +- .../newlib/test_apps/newlib/main/test_misc.c | 21 ++++ 4 files changed, 101 insertions(+), 30 deletions(-) diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 501ebe6392ed..73ac52d85c41 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -660,31 +660,8 @@ size_t heap_caps_get_allocated_size( void *ptr ) return MULTI_HEAP_REMOVE_BLOCK_OWNER_SIZE(size); } -HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps) +static HEAP_IRAM_ATTR void *heap_caps_aligned_alloc_base(size_t alignment, size_t size, uint32_t caps) { - void *ret = NULL; - - if(!alignment) { - return NULL; - } - - //Alignment must be a power of two: - if((alignment & (alignment - 1)) != 0) { - return NULL; - } - - if (size == 0) { - return NULL; - } - - if (MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size) > HEAP_SIZE_MAX) { - // Avoids int overflow when adding small numbers to size, or - // calculating 'end' from start+size, by limiting 'size' to the possible range - heap_caps_alloc_failed(size, caps, __func__); - - return NULL; - } - for (int prio = 0; prio < SOC_MEMORY_TYPE_NO_PRIOS; prio++) { //Iterate over heaps and check capabilities at this priority heap_t *heap; @@ -697,7 +674,7 @@ HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint //doesn't cover, see if they're available in other prios. if ((get_all_caps(heap) & caps) == caps) { //Just try to alloc, nothing special. - ret = multi_heap_aligned_alloc(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size), alignment); + void *ret = multi_heap_aligned_alloc(heap->heap, MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size), alignment); if (ret != NULL) { MULTI_HEAP_SET_BLOCK_OWNER(ret); ret = MULTI_HEAP_ADD_BLOCK_OWNER_OFFSET(ret); @@ -709,12 +686,83 @@ HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint } } - heap_caps_alloc_failed(size, caps, __func__); - //Nothing usable found. return NULL; } +static HEAP_IRAM_ATTR esp_err_t heap_caps_aligned_check_args(size_t alignment, size_t size, uint32_t caps, const char *funcname) +{ + if (!alignment) { + return ESP_FAIL; + } + + // Alignment must be a power of two: + if ((alignment & (alignment - 1)) != 0) { + return ESP_FAIL; + } + + if (size == 0) { + return ESP_FAIL; + } + + if (MULTI_HEAP_ADD_BLOCK_OWNER_SIZE(size) > HEAP_SIZE_MAX) { + // Avoids int overflow when adding small numbers to size, or + // calculating 'end' from start+size, by limiting 'size' to the possible range + heap_caps_alloc_failed(size, caps, funcname); + return ESP_FAIL; + } + + return ESP_OK; +} + +HEAP_IRAM_ATTR void *heap_caps_aligned_alloc_default(size_t alignment, size_t size) +{ + void *ret = NULL; + + if (malloc_alwaysinternal_limit == MALLOC_DISABLE_EXTERNAL_ALLOCS) { + return heap_caps_aligned_alloc(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + } + + if (heap_caps_aligned_check_args(alignment, size, MALLOC_CAP_DEFAULT, __func__) != ESP_OK) { + return NULL; + } + + if (size <= (size_t)malloc_alwaysinternal_limit) { + ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL); + } else { + ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM); + } + + if (ret != NULL) { + return ret; + } + + ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT); + + if (ret == NULL) { + heap_caps_alloc_failed(size, MALLOC_CAP_DEFAULT, __func__); + } + + return ret; +} + +HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps) +{ + void *ret = NULL; + + if (heap_caps_aligned_check_args(alignment, size, caps, __func__) != ESP_OK) { + return NULL; + } + + ret = heap_caps_aligned_alloc_base(alignment, size, caps); + + if (ret == NULL) { + heap_caps_alloc_failed(size, caps, __func__); + } + + return ret; +} + HEAP_IRAM_ATTR void heap_caps_aligned_free(void *ptr) { heap_caps_free(ptr); diff --git a/components/heap/heap_private.h b/components/heap/heap_private.h index 51b6773ffad2..fde7a78bcfd1 100644 --- a/components/heap/heap_private.h +++ b/components/heap/heap_private.h @@ -62,6 +62,7 @@ inline static uint32_t get_all_caps(const heap_t *heap) */ void *heap_caps_realloc_default(void *p, size_t size); void *heap_caps_malloc_default(size_t size); +void *heap_caps_aligned_alloc_default(size_t alignment, size_t size); #ifdef __cplusplus diff --git a/components/newlib/heap.c b/components/newlib/heap.c index fca44906a2d1..685e1e3c721c 100644 --- a/components/newlib/heap.c +++ b/components/newlib/heap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ */ extern void *heap_caps_malloc_default( size_t size ); extern void *heap_caps_realloc_default( void *ptr, size_t size ); +extern void *heap_caps_aligned_alloc_default( size_t alignment, size_t size ); void* malloc(size_t size) { @@ -71,7 +72,7 @@ void* _calloc_r(struct _reent *r, size_t nmemb, size_t size) void* memalign(size_t alignment, size_t n) { - return heap_caps_aligned_alloc(alignment, n, MALLOC_CAP_DEFAULT); + return heap_caps_aligned_alloc_default(alignment, n); } int posix_memalign(void **out_ptr, size_t alignment, size_t size) @@ -81,7 +82,7 @@ int posix_memalign(void **out_ptr, size_t alignment, size_t size) *out_ptr = NULL; return 0; } - void *result = heap_caps_aligned_alloc(alignment, size, MALLOC_CAP_DEFAULT); + void *result = heap_caps_aligned_alloc_default(alignment, size); if (result != NULL) { /* Modify output pointer only on success */ *out_ptr = result; diff --git a/components/newlib/test_apps/newlib/main/test_misc.c b/components/newlib/test_apps/newlib/main/test_misc.c index 98fe6dcae3bb..ec8a69b3f9f7 100644 --- a/components/newlib/test_apps/newlib/main/test_misc.c +++ b/components/newlib/test_apps/newlib/main/test_misc.c @@ -13,6 +13,7 @@ #include #include #include "unity.h" +#include "esp_heap_caps.h" TEST_CASE("misc - posix_memalign", "[newlib_misc]") @@ -41,6 +42,26 @@ TEST_CASE("misc - posix_memalign", "[newlib_misc]") TEST_ASSERT_NOT_NULL(outptr); TEST_ASSERT_EQUAL_INT(ret, 0); free(outptr); + + outptr = magic; + heap_caps_malloc_extmem_enable(128); + ret = posix_memalign(&outptr, 16, 64); + TEST_ASSERT_TRUE(outptr != magic); + TEST_ASSERT_NOT_NULL(outptr); + TEST_ASSERT_EQUAL_INT(ret, 0); + free(outptr); + + outptr = magic; + heap_caps_malloc_extmem_enable(64); + ret = posix_memalign(&outptr, 16, 128); + TEST_ASSERT_TRUE(outptr != magic); + TEST_ASSERT_NOT_NULL(outptr); + TEST_ASSERT_EQUAL_INT(ret, 0); + free(outptr); + +#if CONFIG_SPIRAM_USE_MALLOC + heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL); +#endif } TEST_CASE("misc - sysconf", "[newlib_misc]") From 28f19cf0e6354ab33ca1d37e85e29aa7f0253cd5 Mon Sep 17 00:00:00 2001 From: Xiao Xufeng Date: Sat, 26 Aug 2023 22:08:23 +0800 Subject: [PATCH 115/161] fix(ram_app): Fixed issue ram_app can't use the SPI Flash 1st bootloader won't help to initialize the MSPI & cache properly as it usually do when loading from flash. And the ram app doesn't have valid headers. Since there is no enough space in 2nd bootloader, we replace the `bootloader_init_spi_flash` in the ram_app (!pure_ram_app), with an customized alternative of it for the ram_app. This alternative helps to initialize the MSPI & cache properly, without the help of 1st bootloader or image headers. --- .../include/bootloader_flash_config.h | 5 ++ .../esp_private/bootloader_flash_internal.h | 9 ++ .../src/bootloader_flash_config_esp32.c | 88 ++++++++++++++++++- .../src/bootloader_flash_config_esp32c2.c | 68 +++++++++++++- .../src/bootloader_flash_config_esp32c3.c | 70 ++++++++++++++- .../src/bootloader_flash_config_esp32c6.c | 66 ++++++++++++++ .../src/bootloader_flash_config_esp32h2.c | 67 ++++++++++++++ .../src/bootloader_flash_config_esp32p4.c | 65 ++++++++++++++ .../src/bootloader_flash_config_esp32s2.c | 70 ++++++++++++++- .../src/bootloader_flash_config_esp32s3.c | 79 ++++++++++++++++- .../bootloader_support/src/bootloader_init.c | 2 + .../src/esp32/bootloader_esp32.c | 8 +- .../src/esp32c2/bootloader_esp32c2.c | 6 +- .../src/esp32c3/bootloader_esp32c3.c | 6 +- .../src/esp32c6/bootloader_esp32c6.c | 6 +- .../src/esp32h2/bootloader_esp32h2.c | 6 +- .../src/esp32p4/bootloader_esp32p4.c | 6 +- .../src/esp32s2/bootloader_esp32s2.c | 6 +- .../src/esp32s3/bootloader_esp32s3.c | 6 +- components/esp_system/port/cpu_start.c | 28 +++--- 20 files changed, 614 insertions(+), 53 deletions(-) diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash_config.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash_config.h index 6fbb6d4fc8e4..2709a3da30e2 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash_config.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash_config.h @@ -58,6 +58,7 @@ void bootloader_flash_clock_config(const esp_image_header_t* pfhdr); */ void bootloader_flash_gpio_config(const esp_image_header_t* pfhdr); +#ifdef CONFIG_IDF_TARGET_ESP32 /** * @brief Configure SPI flash read dummy based on different mode and frequency. * @@ -66,6 +67,10 @@ void bootloader_flash_gpio_config(const esp_image_header_t* pfhdr); * @return None */ void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr); +#else +// The meaning has changed on this chip. Deprecated, Call `bootloader_configure_spi_pins()` and `bootloader_flash_set_dummy_out()` directly. +void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr) __attribute__((deprecated)); +#endif #ifdef CONFIG_IDF_TARGET_ESP32 /** diff --git a/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h b/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h index 4bff3f9dea34..92c9d3988dc9 100644 --- a/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h +++ b/components/bootloader_support/bootloader_flash/include/esp_private/bootloader_flash_internal.h @@ -18,6 +18,15 @@ extern "C" { */ esp_err_t bootloader_init_spi_flash(void); +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +/** + * @brief Config all flash related stuff according to the header. The consistency of all flash configs is ensured. + * + * @return None + */ +void bootloader_flash_hardware_init(void); +#endif + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c index 99f6421c853a..140969b69281 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,7 @@ #include "soc/gpio_periph.h" #include "soc/efuse_reg.h" #include "soc/spi_reg.h" +#include "soc/dport_reg.h" #include "soc/soc_caps.h" #include "soc/soc_pins.h" #include "soc/chip_revision.h" @@ -354,6 +355,7 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr) ESP_EARLY_LOGI(TAG, "SPI Flash Size : %s", str); } + static void IRAM_ATTR bootloader_init_flash_configure(void) { bootloader_flash_gpio_config(&bootloader_image_hdr); @@ -384,3 +386,87 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_enable_wp(); return ESP_OK; } + + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); + + // reset MMU + /* completely reset MMU in case serial bootloader was running */ + Cache_Read_Disable(0); +#if !CONFIG_FREERTOS_UNICORE + Cache_Read_Disable(1); +#endif + Cache_Flush(0); +#if !CONFIG_FREERTOS_UNICORE + Cache_Flush(1); +#endif + mmu_init(0); +#if !CONFIG_FREERTOS_UNICORE + /* The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are + necessary to work around a hardware bug. */ + 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); +#endif + + /* normal ROM boot exits with DROM0 cache unmasked, + but serial bootloader exits with it masked. */ + DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0); +#if !CONFIG_FREERTOS_UNICORE + DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0); +#endif + + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_gpio_config(&hdr); + bootloader_flash_dummy_config(&hdr); + bootloader_flash_cs_timing_config(); + + /* Remaining parts in bootloader_init_spi_flash */ + bootloader_flash_unlock(); + update_flash_config(&hdr); + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c index 85f7c16654af..626b9bc1f808 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c @@ -71,6 +71,7 @@ void IRAM_ATTR bootloader_flash_set_dummy_out(void) REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL); } +//deprecated void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) { bootloader_configure_spi_pins(1); @@ -220,7 +221,8 @@ static void bootloader_print_mmu_page_size(void) static void IRAM_ATTR bootloader_init_flash_configure(void) { - bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_configure_spi_pins(1); + bootloader_flash_set_dummy_out(); bootloader_flash_cs_timing_config(); } @@ -248,3 +250,67 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(0, false); + + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_set_dummy_out(); + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + + bootloader_print_mmu_page_size(); + + cache_hal_disable(CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c index fb1f2329d1a6..f5a3d130765a 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c @@ -75,6 +75,7 @@ void IRAM_ATTR bootloader_flash_set_dummy_out(void) REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL); } +//deprecated void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) { bootloader_configure_spi_pins(1); @@ -222,7 +223,8 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr) static void IRAM_ATTR bootloader_init_flash_configure(void) { - bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_configure_spi_pins(1); + bootloader_flash_set_dummy_out(); bootloader_flash_cs_timing_config(); } @@ -256,3 +258,69 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); + + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_set_dummy_out(); + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + + cache_hal_disable(CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c index 6a1e62459c74..2d000ab1f543 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c @@ -219,3 +219,69 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(0, false); + + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + // TODO: set proper dummy output + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + + cache_hal_disable(CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c index b4b1bb94c3b4..951f053502b9 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c @@ -221,3 +221,70 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(0, false); + + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_clock_init(); + // TODO: set proper dummy output + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + + cache_hal_disable(CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c index 14887abe949b..9f5eccc159b3 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c @@ -207,3 +207,68 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(0, false); + + //init cache hal + cache_hal_init(); + //reset mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_cs_timing_config(); + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + + cache_hal_disable(CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c index a1855bb4c4a3..33cbb44c0c65 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c @@ -81,6 +81,7 @@ void IRAM_ATTR bootloader_flash_set_dummy_out(void) REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL); } +//deprecated void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t* pfhdr) { bootloader_configure_spi_pins(1); @@ -247,7 +248,8 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr) static void IRAM_ATTR bootloader_init_flash_configure(void) { - bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_configure_spi_pins(1); + bootloader_flash_set_dummy_out(); bootloader_flash_cs_timing_config(); } @@ -274,3 +276,69 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); + + // init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // Workaround: normal ROM bootloader exits with DROM0 cache unmasked, but 2nd bootloader exits with it masked. + REG_CLR_BIT(EXTMEM_PRO_ICACHE_CTRL1_REG, EXTMEM_PRO_ICACHE_MASK_DROM0); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_set_dummy_out(); + bootloader_flash_cs_timing_config(); + + bootloader_flash_unlock(); + + cache_hal_disable(CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c index 7ab25e7fc85a..730b6a1e515a 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c @@ -87,6 +87,7 @@ void IRAM_ATTR bootloader_flash_set_dummy_out(void) REG_SET_BIT(SPI_MEM_CTRL_REG(1), SPI_MEM_FDUMMY_OUT | SPI_MEM_D_POL | SPI_MEM_Q_POL); } +//deprecated void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t *pfhdr) { bootloader_configure_spi_pins(1); @@ -254,7 +255,8 @@ static void print_flash_info(const esp_image_header_t *bootloader_hdr) static void IRAM_ATTR bootloader_init_flash_configure(void) { - bootloader_flash_dummy_config(&bootloader_image_hdr); + bootloader_configure_spi_pins(1); + bootloader_flash_set_dummy_out(); bootloader_flash_cs_timing_config(); } @@ -297,3 +299,78 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_enable_wp(); return ESP_OK; } + +#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +static void bootloader_flash_set_spi_mode(const esp_image_header_t* pfhdr) +{ + esp_rom_spiflash_read_mode_t mode; + switch(pfhdr->spi_mode) { + case ESP_IMAGE_SPI_MODE_QIO: + mode = ESP_ROM_SPIFLASH_QIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_QOUT: + mode = ESP_ROM_SPIFLASH_QOUT_MODE; + break; + case ESP_IMAGE_SPI_MODE_DIO: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + break; + case ESP_IMAGE_SPI_MODE_FAST_READ: + mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + break; + case ESP_IMAGE_SPI_MODE_SLOW_READ: + mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + break; + default: + mode = ESP_ROM_SPIFLASH_DIO_MODE; + } + esp_rom_spiflash_config_readmode(mode); +} + +void bootloader_flash_hardware_init(void) +{ + esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); + + //init cache hal + cache_hal_init(); + //init mmu + mmu_hal_init(); + // update flash ID + bootloader_flash_update_id(); + // Check and run XMC startup flow + esp_err_t ret = bootloader_flash_xmc_startup(); + assert(ret == ESP_OK); + + /* Alternative of bootloader_init_spi_flash */ + // RAM app doesn't have headers in the flash. Make a default one for it. + esp_image_header_t WORD_ALIGNED_ATTR hdr = { + .spi_mode = ESP_IMAGE_SPI_MODE_DIO, + .spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2, + .spi_size = ESP_IMAGE_FLASH_SIZE_2MB, + }; + bootloader_configure_spi_pins(1); + bootloader_flash_set_spi_mode(&hdr); + bootloader_flash_clock_config(&hdr); + bootloader_flash_set_dummy_out(); + bootloader_flash_cs_timing_config(); + +#if CONFIG_BOOTLOADER_FLASH_DC_AWARE + // Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot. + bootloader_spi_flash_reset(); +#endif + + bootloader_spi_flash_resume(); + bootloader_flash_unlock(); + +#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH || CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH + bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); +#endif + + cache_hal_disable(CACHE_TYPE_ALL); + update_flash_config(&hdr); + cache_hal_enable(CACHE_TYPE_ALL); + + //ensure the flash is write-protected + bootloader_enable_wp(); + +} +#endif //CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP diff --git a/components/bootloader_support/src/bootloader_init.c b/components/bootloader_support/src/bootloader_init.c index 1dd9b3958de9..a68e57543bd3 100644 --- a/components/bootloader_support/src/bootloader_init.c +++ b/components/bootloader_support/src/bootloader_init.c @@ -23,7 +23,9 @@ static const char *TAG = "boot"; +#if !CONFIG_APP_BUILD_TYPE_RAM esp_image_header_t WORD_ALIGNED_ATTR bootloader_image_hdr; +#endif void bootloader_clear_bss_section(void) { diff --git a/components/bootloader_support/src/esp32/bootloader_esp32.c b/components/bootloader_support/src/esp32/bootloader_esp32.c index ddea3ee159dc..fd6441023b78 100644 --- a/components/bootloader_support/src/esp32/bootloader_esp32.c +++ b/components/bootloader_support/src/esp32/bootloader_esp32.c @@ -39,7 +39,7 @@ static const char *TAG = "boot.esp32"; -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM static void bootloader_reset_mmu(void) { /* completely reset MMU in case serial bootloader was running */ @@ -208,7 +208,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM // reset MMU bootloader_reset_mmu(); // update flash ID @@ -218,7 +218,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -227,12 +226,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // #if !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // #if !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c b/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c index a19fa85443c2..3d9e1af1f4ee 100644 --- a/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c +++ b/components/bootloader_support/src/esp32c2/bootloader_esp32c2.c @@ -120,14 +120,13 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //init mmu mmu_hal_init(); // update flash ID bootloader_flash_update_id(); -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -136,12 +135,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c b/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c index 0160b921f1e1..199ff6562415 100644 --- a/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c +++ b/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c @@ -159,7 +159,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //init mmu @@ -171,7 +171,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -180,12 +179,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif //#if !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif //#if !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c index 76fd0b90b300..d26965799262 100644 --- a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c +++ b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c @@ -143,7 +143,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //init mmu @@ -155,7 +155,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -164,12 +163,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c index e5b23acfe3ba..5cf7869c17f7 100644 --- a/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c +++ b/components/bootloader_support/src/esp32h2/bootloader_esp32h2.c @@ -132,7 +132,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //init mmu @@ -144,7 +144,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -153,12 +152,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c b/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c index 085ab34559f2..aa515759ec94 100644 --- a/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c +++ b/components/bootloader_support/src/esp32p4/bootloader_esp32p4.c @@ -136,7 +136,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //reset mmu @@ -148,7 +148,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -157,12 +156,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c b/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c index cf2a27fe6571..4624e29f27c0 100644 --- a/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c +++ b/components/bootloader_support/src/esp32s2/bootloader_esp32s2.c @@ -139,7 +139,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM // init cache hal cache_hal_init(); //init mmu @@ -153,7 +153,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -162,12 +161,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c b/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c index 06b4825a3a73..368aa648b4d1 100644 --- a/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c +++ b/components/bootloader_support/src/esp32s3/bootloader_esp32s3.c @@ -178,7 +178,7 @@ esp_err_t bootloader_init(void) /* print 2nd bootloader banner */ bootloader_print_banner(); -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#if !CONFIG_APP_BUILD_TYPE_RAM //init cache hal cache_hal_init(); //init mmu @@ -190,7 +190,6 @@ esp_err_t bootloader_init(void) ESP_LOGE(TAG, "failed when running XMC startup flow, reboot!"); return ret; } -#if !CONFIG_APP_BUILD_TYPE_RAM // read bootloader header if ((ret = bootloader_read_bootloader_header()) != ESP_OK) { return ret; @@ -199,12 +198,11 @@ esp_err_t bootloader_init(void) if ((ret = bootloader_check_bootloader_validity()) != ESP_OK) { return ret; } -#endif // !CONFIG_APP_BUILD_TYPE_RAM // initialize spi flash if ((ret = bootloader_init_spi_flash()) != ESP_OK) { return ret; } -#endif // #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +#endif // !CONFIG_APP_BUILD_TYPE_RAM // check whether a WDT reset happend bootloader_check_wdt_reset(); diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 53d9f3e67f31..99d6e8b42d89 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -101,6 +101,7 @@ #if CONFIG_APP_BUILD_TYPE_RAM #include "esp_rom_spiflash.h" #include "bootloader_init.h" +#include "esp_private/bootloader_flash_internal.h" #endif // CONFIG_APP_BUILD_TYPE_RAM //This dependency will be removed in the future @@ -429,14 +430,10 @@ void IRAM_ATTR call_start_cpu0(void) // When the APP is loaded into ram for execution, some hardware initialization behaviors // in the bootloader are still necessary #if CONFIG_APP_BUILD_TYPE_RAM + bootloader_init(); #if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP -#if SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE - esp_rom_spiflash_attach(esp_rom_efuse_get_flash_gpio_info(), false); -#else - esp_rom_spiflash_attach(0, false); -#endif + bootloader_flash_hardware_init(); #endif //#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP - bootloader_init(); #endif //#if CONFIG_APP_BUILD_TYPE_RAM #ifndef CONFIG_BOOTLOADER_WDT_ENABLE @@ -722,22 +719,19 @@ void IRAM_ATTR call_start_cpu0(void) } #endif //CONFIG_ESP_SYSTEM_MEMPROT_FEATURE && !CONFIG_ESP_SYSTEM_MEMPROT_TEST +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + // External devices (including SPI0/1, cache) should be initialized + +#if !CONFIG_APP_BUILD_TYPE_RAM + // Normal startup flow. We arrive here with the help of 1st, 2nd bootloader. There are valid headers (app/bootloader) + // Read the application binary image header. This will also decrypt the header if the image is encrypted. __attribute__((unused)) esp_image_header_t fhdr = {0}; -#if CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP - fhdr.spi_mode = ESP_IMAGE_SPI_MODE_DIO; - fhdr.spi_speed = ESP_IMAGE_SPI_SPEED_DIV_2; - fhdr.spi_size = ESP_IMAGE_FLASH_SIZE_4MB; - bootloader_flash_unlock(); -#else // This assumes that DROM is the first segment in the application binary, i.e. that we can read // the binary header through cache by accessing SOC_DROM_LOW address. hal_memcpy(&fhdr, (void *) SOC_DROM_LOW, sizeof(fhdr)); -#endif // CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP - -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if CONFIG_IDF_TARGET_ESP32 #if !CONFIG_SPIRAM_BOOT_INIT // If psram is uninitialized, we need to improve some flash configuration. @@ -756,6 +750,10 @@ void IRAM_ATTR call_start_cpu0(void) } bootloader_flash_update_size(app_flash_size); #endif //CONFIG_SPI_FLASH_SIZE_OVERRIDE +#else + // CONFIG_APP_BUILD_TYPE_RAM && !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + bootloader_flash_unlock(); +#endif #endif //!CONFIG_APP_BUILD_TYPE_PURE_RAM_APP #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE From cc2867468622ed7b45dd454b605b0211b39e7fcf Mon Sep 17 00:00:00 2001 From: Xiao Xufeng Date: Sun, 27 Aug 2023 01:12:21 +0800 Subject: [PATCH 116/161] refactor(bootloader_flash): make cache enable more obvious --- .../src/bootloader_flash_config_esp32.c | 13 ++++++++++--- .../src/bootloader_flash_config_esp32c2.c | 10 ++++++---- .../src/bootloader_flash_config_esp32c3.c | 10 ++++++---- .../src/bootloader_flash_config_esp32c6.c | 10 ++++++---- .../src/bootloader_flash_config_esp32h2.c | 10 ++++++---- .../src/bootloader_flash_config_esp32p4.c | 10 ++++++---- .../src/bootloader_flash_config_esp32s2.c | 10 ++++++---- .../src/bootloader_flash_config_esp32s3.c | 10 ++++++---- 8 files changed, 52 insertions(+), 31 deletions(-) diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c index 140969b69281..3c23ec5abcb6 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32.c @@ -270,13 +270,10 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - Cache_Read_Disable(0); // Set flash chip size esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode // TODO: set frequency - Cache_Flush(0); - Cache_Read_Enable(0); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -381,7 +378,12 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + Cache_Read_Disable(0); update_flash_config(&bootloader_image_hdr); + Cache_Flush(0); + Cache_Read_Enable(0); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; @@ -465,7 +467,12 @@ void bootloader_flash_hardware_init(void) /* Remaining parts in bootloader_init_spi_flash */ bootloader_flash_unlock(); + + Cache_Read_Disable(0); update_flash_config(&hdr); + Cache_Flush(0); + Cache_Read_Enable(0); + //ensure the flash is write-protected bootloader_enable_wp(); } diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c index 626b9bc1f808..cf5a56809f42 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c2.c @@ -128,10 +128,8 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -245,7 +243,11 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_print_mmu_page_size(); print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; @@ -306,9 +308,9 @@ void bootloader_flash_hardware_init(void) bootloader_print_mmu_page_size(); - cache_hal_disable(CACHE_TYPE_ALL); + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&hdr); - cache_hal_enable(CACHE_TYPE_ALL); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); //ensure the flash is write-protected bootloader_enable_wp(); diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c index f5a3d130765a..7b0eecefc483 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c3.c @@ -139,10 +139,8 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -253,7 +251,11 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; @@ -316,9 +318,9 @@ void bootloader_flash_hardware_init(void) bootloader_spi_flash_resume(); bootloader_flash_unlock(); - cache_hal_disable(CACHE_TYPE_ALL); + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&hdr); - cache_hal_enable(CACHE_TYPE_ALL); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); //ensure the flash is write-protected bootloader_enable_wp(); diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c index 2d000ab1f543..2e9ed60a12fd 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32c6.c @@ -103,10 +103,8 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -214,7 +212,11 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; @@ -277,9 +279,9 @@ void bootloader_flash_hardware_init(void) bootloader_spi_flash_resume(); bootloader_flash_unlock(); - cache_hal_disable(CACHE_TYPE_ALL); + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&hdr); - cache_hal_enable(CACHE_TYPE_ALL); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); //ensure the flash is write-protected bootloader_enable_wp(); diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c index 951f053502b9..e9888da6f916 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32h2.c @@ -110,10 +110,8 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -216,7 +214,11 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; @@ -280,9 +282,9 @@ void bootloader_flash_hardware_init(void) bootloader_spi_flash_resume(); bootloader_flash_unlock(); - cache_hal_disable(CACHE_TYPE_ALL); + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&hdr); - cache_hal_enable(CACHE_TYPE_ALL); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); //ensure the flash is write-protected bootloader_enable_wp(); diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c index 9f5eccc159b3..89894d5edd08 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32p4.c @@ -97,10 +97,8 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(rom_spiflash_legacy_data->chip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -202,7 +200,11 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; @@ -264,9 +266,9 @@ void bootloader_flash_hardware_init(void) bootloader_spi_flash_resume(); bootloader_flash_unlock(); - cache_hal_disable(CACHE_TYPE_ALL); + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&hdr); - cache_hal_enable(CACHE_TYPE_ALL); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); //ensure the flash is write-protected bootloader_enable_wp(); diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c index 33cbb44c0c65..40587e4960fc 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s2.c @@ -153,12 +153,10 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) default: size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode // TODO: set frequency - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -271,7 +269,11 @@ esp_err_t bootloader_init_spi_flash(void) #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; @@ -334,9 +336,9 @@ void bootloader_flash_hardware_init(void) bootloader_flash_unlock(); - cache_hal_disable(CACHE_TYPE_ALL); + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&hdr); - cache_hal_enable(CACHE_TYPE_ALL); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); //ensure the flash is write-protected bootloader_enable_wp(); diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c index 730b6a1e515a..c02aad5bbf7c 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_esp32s3.c @@ -160,12 +160,10 @@ static void update_flash_config(const esp_image_header_t *bootloader_hdr) size = 2; } - cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); // Set flash chip size esp_rom_spiflash_config_param(g_rom_flashchip.device_id, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff); // TODO: set mode // TODO: set frequency - cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); } static void print_flash_info(const esp_image_header_t *bootloader_hdr) @@ -294,7 +292,11 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); #endif print_flash_info(&bootloader_image_hdr); + + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&bootloader_image_hdr); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); + //ensure the flash is write-protected bootloader_enable_wp(); return ESP_OK; @@ -365,9 +367,9 @@ void bootloader_flash_hardware_init(void) bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); #endif - cache_hal_disable(CACHE_TYPE_ALL); + cache_hal_disable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); update_flash_config(&hdr); - cache_hal_enable(CACHE_TYPE_ALL); + cache_hal_enable(CACHE_LL_LEVEL_EXT_MEM, CACHE_TYPE_ALL); //ensure the flash is write-protected bootloader_enable_wp(); From 24ef7f6034bbcc0d27625c3931433f528b218b48 Mon Sep 17 00:00:00 2001 From: Xiao Xufeng Date: Fri, 7 Jul 2023 01:48:54 +0800 Subject: [PATCH 117/161] ci(ram_load_app): enable target tests for all targets --- tools/test_apps/.build-test-rules.yml | 6 ------ tools/test_apps/system/ram_loadable_app/README.md | 4 ++-- .../ram_loadable_app/pytest_ram_loadable_app.py | 13 ++----------- .../ram_loadable_app/sdkconfig.defaults.esp32 | 6 ------ 4 files changed, 4 insertions(+), 25 deletions(-) delete mode 100644 tools/test_apps/system/ram_loadable_app/sdkconfig.defaults.esp32 diff --git a/tools/test_apps/.build-test-rules.yml b/tools/test_apps/.build-test-rules.yml index 5cf3291d28ff..faef23a9e218 100644 --- a/tools/test_apps/.build-test-rules.yml +++ b/tools/test_apps/.build-test-rules.yml @@ -173,12 +173,6 @@ tools/test_apps/system/panic: temporary: true reason: target(s) not supported yet # TODO: IDF-7511 -tools/test_apps/system/ram_loadable_app: - disable: - - if: IDF_TARGET == "esp32h2" - temporary: true - reason: lack of runners - tools/test_apps/system/startup: disable: - if: CONFIG_NAME == "main_task_cpu1" and IDF_TARGET not in ["esp32", "esp32s3"] diff --git a/tools/test_apps/system/ram_loadable_app/README.md b/tools/test_apps/system/ram_loadable_app/README.md index f53505715493..0283938f981c 100644 --- a/tools/test_apps/system/ram_loadable_app/README.md +++ b/tools/test_apps/system/ram_loadable_app/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | # RAM loadable app Example diff --git a/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py b/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py index 71953f16f266..22b6011a38e6 100644 --- a/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py +++ b/tools/test_apps/system/ram_loadable_app/pytest_ram_loadable_app.py @@ -5,12 +5,7 @@ from pytest_embedded_idf.dut import IdfDut -@pytest.mark.esp32 -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 +@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['pure_ram',], indirect=True,) def test_pure_ram_loadable_app(dut: IdfDut) -> None: @@ -18,11 +13,7 @@ def test_pure_ram_loadable_app(dut: IdfDut) -> None: dut.expect('Time since boot: 3 seconds...', timeout=10) -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 +@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['defaults',], indirect=True,) def test_ram_loadable_app(dut: IdfDut) -> None: diff --git a/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults.esp32 b/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults.esp32 deleted file mode 100644 index d2816a3ebd6e..000000000000 --- a/tools/test_apps/system/ram_loadable_app/sdkconfig.defaults.esp32 +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG_APP_BUILD_TYPE_RAM=y - -# Reset is meaningless to ram_app -CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y - -CONFIG_APP_BUILD_TYPE_PURE_RAM_APP=y From 77bb19c49e5b467047e7d33c30bfb345d3a9cbcc Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Tue, 18 Apr 2023 15:04:14 +0800 Subject: [PATCH 118/161] ci(build): fixed/ignored warnings from unknown symbols in sdkconfig.defaults --- .../mspi/sdkconfig.ci.f8r8_80ddr_80ddr_ecc | 2 +- .../sdkconfig.ci.f8r8_80ddr_80ddr_ecc | 2 +- components/mbedtls/.build-test-rules.yml | 7 ++ .../mbedtls/test_apps/.build-test-rules.yml | 7 ++ .../mbedtls/test_apps/pytest_mbedtls_ut.py | 1 - .../test_apps/sdkconfig.ci.psram_esp32 | 3 - .../esp_http_client/sdkconfig.ci.ssldyn | 1 - .../restful_server/sdkconfig.defaults | 1 - .../https_request/sdkconfig.ci.mbedtls_config | 7 -- .../https_request/sdkconfig.ci.ssldyn | 1 - .../https_x509_bundle/sdkconfig.ci.ssldyn | 1 - .../storage/semihost_vfs/sdkconfig.defaults | 2 +- examples/system/.build-test-rules.yml | 1 + .../sdkconfig.ci.virt_sb_v2_and_fe.esp32c3 | 1 - .../sdkconfig.ci.virt_secure_boot_v2.esp32c3 | 1 - .../ulp/lp_core/gpio/sdkconfig.defaults | 2 +- .../ulp_riscv/uart_print/sdkconfig.defaults | 2 +- tools/ci/ignore_build_warnings.txt | 84 +++++++++++++++++++ tools/unit-test-app/sdkconfig.defaults | 2 - 19 files changed, 104 insertions(+), 24 deletions(-) create mode 100644 components/mbedtls/.build-test-rules.yml create mode 100644 components/mbedtls/test_apps/.build-test-rules.yml delete mode 100644 components/mbedtls/test_apps/sdkconfig.ci.psram_esp32 diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_80ddr_80ddr_ecc b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_80ddr_80ddr_ecc index f9dd19e0c883..7ab1d4bcfe01 100644 --- a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_80ddr_80ddr_ecc +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f8r8_80ddr_80ddr_ecc @@ -10,4 +10,4 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_SPIRAM=y CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_SPEED_80M=y -CONFIG_SPIRAM_ECC_ENABLE = y +CONFIG_SPIRAM_ECC_ENABLE=y diff --git a/components/esp_hw_support/test_apps/mspi_psram_with_dfs/sdkconfig.ci.f8r8_80ddr_80ddr_ecc b/components/esp_hw_support/test_apps/mspi_psram_with_dfs/sdkconfig.ci.f8r8_80ddr_80ddr_ecc index 200726d60d81..d9441e88687f 100644 --- a/components/esp_hw_support/test_apps/mspi_psram_with_dfs/sdkconfig.ci.f8r8_80ddr_80ddr_ecc +++ b/components/esp_hw_support/test_apps/mspi_psram_with_dfs/sdkconfig.ci.f8r8_80ddr_80ddr_ecc @@ -7,4 +7,4 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_SPIRAM=y CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_SPEED_80M=y -CONFIG_SPIRAM_ECC_ENABLE = y +CONFIG_SPIRAM_ECC_ENABLE=y diff --git a/components/mbedtls/.build-test-rules.yml b/components/mbedtls/.build-test-rules.yml new file mode 100644 index 000000000000..705dd4b66b6e --- /dev/null +++ b/components/mbedtls/.build-test-rules.yml @@ -0,0 +1,7 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/mbedtls/test_apps: + disable: + - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "psram_all_ext" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "ecdsa_sign" and SOC_ECDSA_SUPPORTED != 1 diff --git a/components/mbedtls/test_apps/.build-test-rules.yml b/components/mbedtls/test_apps/.build-test-rules.yml new file mode 100644 index 000000000000..705dd4b66b6e --- /dev/null +++ b/components/mbedtls/test_apps/.build-test-rules.yml @@ -0,0 +1,7 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/mbedtls/test_apps: + disable: + - if: CONFIG_NAME == "psram" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "psram_all_ext" and SOC_SPIRAM_SUPPORTED != 1 + - if: CONFIG_NAME == "ecdsa_sign" and SOC_ECDSA_SUPPORTED != 1 diff --git a/components/mbedtls/test_apps/pytest_mbedtls_ut.py b/components/mbedtls/test_apps/pytest_mbedtls_ut.py index 1445e9a5a4b2..7167a54fdf7a 100644 --- a/components/mbedtls/test_apps/pytest_mbedtls_ut.py +++ b/components/mbedtls/test_apps/pytest_mbedtls_ut.py @@ -60,7 +60,6 @@ def test_mbedtls_psram(dut: Dut) -> None: @pytest.mark.parametrize( 'config', [ - 'psram_esp32', 'psram_all_ext', ], indirect=True, diff --git a/components/mbedtls/test_apps/sdkconfig.ci.psram_esp32 b/components/mbedtls/test_apps/sdkconfig.ci.psram_esp32 deleted file mode 100644 index 5acbcfd7fc68..000000000000 --- a/components/mbedtls/test_apps/sdkconfig.ci.psram_esp32 +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_SPIRAM=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 -CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y diff --git a/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn b/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn index 22c15d6572c6..a682b25bbc98 100644 --- a/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn +++ b/examples/protocols/esp_http_client/sdkconfig.ci.ssldyn @@ -9,7 +9,6 @@ CONFIG_EXAMPLE_ETH_PHY_ADDR=1 CONFIG_EXAMPLE_CONNECT_IPV6=y CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH=y CONFIG_MBEDTLS_DYNAMIC_BUFFER=y -CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y CONFIG_MBEDTLS_DHM_C=y CONFIG_EXAMPLE_HTTP_ENDPOINT="httpbin.espressif.cn" diff --git a/examples/protocols/http_server/restful_server/sdkconfig.defaults b/examples/protocols/http_server/restful_server/sdkconfig.defaults index 87b6ea1e5727..648ade5093aa 100644 --- a/examples/protocols/http_server/restful_server/sdkconfig.defaults +++ b/examples/protocols/http_server/restful_server/sdkconfig.defaults @@ -1,6 +1,5 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 CONFIG_SPIFFS_OBJ_NAME_LEN=64 -CONFIG_FATFS_LONG_FILENAME=y CONFIG_FATFS_LFN_HEAP=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/examples/protocols/https_request/sdkconfig.ci.mbedtls_config b/examples/protocols/https_request/sdkconfig.ci.mbedtls_config index 2a24a07e03ec..113bcf6336a7 100644 --- a/examples/protocols/https_request/sdkconfig.ci.mbedtls_config +++ b/examples/protocols/https_request/sdkconfig.ci.mbedtls_config @@ -37,10 +37,7 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=n # end of TLS Key Exchange Methods CONFIG_MBEDTLS_SSL_RENEGOTIATION=n -CONFIG_MBEDTLS_SSL_PROTO_SSL3=n CONFIG_MBEDTLS_SSL_PROTO_DTLS=n -CONFIG_MBEDTLS_SSL_PROTO_TLS1=n -CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=n CONFIG_MBEDTLS_SSL_ALPN=n CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=n @@ -52,9 +49,6 @@ CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=n CONFIG_MBEDTLS_AES_C=n CONFIG_MBEDTLS_CAMELLIA_C=n CONFIG_MBEDTLS_DES_C=n -CONFIG_MBEDTLS_RC4_DISABLED=n -CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT=n -CONFIG_MBEDTLS_RC4_ENABLED=n CONFIG_MBEDTLS_BLOWFISH_C=n CONFIG_MBEDTLS_XTEA_C=n CONFIG_MBEDTLS_CCM_C=n @@ -94,5 +88,4 @@ CONFIG_MBEDTLS_CHACHA20_C=n CONFIG_MBEDTLS_HKDF_C=n CONFIG_MBEDTLS_THREADING_C=n CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI=n -CONFIG_MBEDTLS_SECURITY_RISKS=n # end of mbedTLS diff --git a/examples/protocols/https_request/sdkconfig.ci.ssldyn b/examples/protocols/https_request/sdkconfig.ci.ssldyn index 7840b5864973..a6c2b2db42cd 100644 --- a/examples/protocols/https_request/sdkconfig.ci.ssldyn +++ b/examples/protocols/https_request/sdkconfig.ci.ssldyn @@ -10,5 +10,4 @@ CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 CONFIG_EXAMPLE_ETH_PHY_ADDR=1 CONFIG_EXAMPLE_CONNECT_IPV6=y CONFIG_MBEDTLS_DYNAMIC_BUFFER=y -CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y diff --git a/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn b/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn index a8773f6a04c1..9fd5735ca20d 100644 --- a/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn +++ b/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn @@ -2,7 +2,6 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="certs" CONFIG_MBEDTLS_DYNAMIC_BUFFER=y -CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y CONFIG_EXAMPLE_CONNECT_ETHERNET=y diff --git a/examples/storage/semihost_vfs/sdkconfig.defaults b/examples/storage/semihost_vfs/sdkconfig.defaults index 989d01c23a1d..c24918731c09 100644 --- a/examples/storage/semihost_vfs/sdkconfig.defaults +++ b/examples/storage/semihost_vfs/sdkconfig.defaults @@ -1,2 +1,2 @@ # need this to detect that OpenOCD is connected -CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_ESP_DEBUG_OCDAWARE=y diff --git a/examples/system/.build-test-rules.yml b/examples/system/.build-test-rules.yml index 10fc5a153783..7dac32024a94 100644 --- a/examples/system/.build-test-rules.yml +++ b/examples/system/.build-test-rules.yml @@ -185,6 +185,7 @@ examples/system/ota/simple_ota_example: - if: IDF_TARGET in ["esp32h2", "esp32p4"] temporary: true reason: target esp32h2, esp32p4 is not supported yet + - if: CONFIG_NAME == "spiram" and SOC_SPIRAM_SUPPORTED != 1 disable_test: - if: IDF_TARGET == "esp32c2" or IDF_TARGET == "esp32c6" temporary: true diff --git a/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c3 b/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c3 index 9ba5277387d0..93a21dd5abdc 100644 --- a/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c3 +++ b/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32c3 @@ -4,7 +4,6 @@ CONFIG_IDF_TARGET="esp32c3" # ESP32C3 supports SECURE_BOOT_V2 only in ECO3 CONFIG_ESP32C3_REV_MIN_3=y -CONFIG_ESP32C3_REV_MIN=3 CONFIG_PARTITION_TABLE_OFFSET=0xD000 CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c3 b/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c3 index 35dc608a6123..c209bc98b605 100644 --- a/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c3 +++ b/examples/system/efuse/sdkconfig.ci.virt_secure_boot_v2.esp32c3 @@ -4,7 +4,6 @@ CONFIG_IDF_TARGET="esp32c3" # ESP32C3 supports SECURE_BOOT_V2 only in ECO3 CONFIG_ESP32C3_REV_MIN_3=y -CONFIG_ESP32C3_REV_MIN=3 CONFIG_PARTITION_TABLE_OFFSET=0xC000 CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/examples/system/ulp/lp_core/gpio/sdkconfig.defaults b/examples/system/ulp/lp_core/gpio/sdkconfig.defaults index b51373abf712..42aa360e61d4 100644 --- a/examples/system/ulp/lp_core/gpio/sdkconfig.defaults +++ b/examples/system/ulp/lp_core/gpio/sdkconfig.defaults @@ -1,6 +1,6 @@ # Enable ULP CONFIG_ULP_COPROC_ENABLED=y -CONFIG_ULP_COPROC_LP_CORE=y +CONFIG_ULP_COPROC_TYPE_LP_CORE=y CONFIG_ULP_COPROC_RESERVE_MEM=4096 # Set log level to Warning to produce clean output CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y diff --git a/examples/system/ulp/ulp_riscv/uart_print/sdkconfig.defaults b/examples/system/ulp/ulp_riscv/uart_print/sdkconfig.defaults index a28f71162ea0..e3745e505767 100644 --- a/examples/system/ulp/ulp_riscv/uart_print/sdkconfig.defaults +++ b/examples/system/ulp/ulp_riscv/uart_print/sdkconfig.defaults @@ -1,6 +1,6 @@ # Enable ULP CONFIG_ULP_COPROC_ENABLED=y -CONFIG_ULP_COPROC_RISCV=y +CONFIG_ULP_COPROC_TYPE_RISCV=y CONFIG_ULP_COPROC_RESERVE_MEM=4096 # Set log level to Warning to produce clean output CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y diff --git a/tools/ci/ignore_build_warnings.txt b/tools/ci/ignore_build_warnings.txt index 0f2daf214b83..dd9523ca8839 100644 --- a/tools/ci/ignore_build_warnings.txt +++ b/tools/ci/ignore_build_warnings.txt @@ -15,3 +15,87 @@ CryptographyDeprecationWarning Warning: \d+/\d+ app partitions are too small for binary CMake Deprecation Warning at main/lib/tinyxml2/CMakeLists\.txt:11 \(cmake_policy\) The smallest .+ partition is nearly full \(\d+% free space left\)! +warning: unknown kconfig symbol 'A2DP_SINK_ENABLE' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults +warning: unknown kconfig symbol 'A2DP_SRC_ENABLE' assigned to 'n' in /builds/espressif/esp-idf/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults +warning: unknown kconfig symbol 'APP_OFFSET' assigned to '0x10000' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'BLE_ENABLE_SRVCHG_REG' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/bluedroid/coex/a2dp_gatts_coex/sdkconfig.defaults +warning: unknown kconfig symbol 'BT_CTRL_BLE_MESH_SCAN_DUPL_EN' assigned to* +warning: unknown kconfig symbol 'BT_CTRL_COEX_PARAMETERS_ENABLE' assigned to* +warning: unknown kconfig symbol 'BT_CTRL_COEX_USE_HOOKS' assigned to* +warning: unknown kconfig symbol 'BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE' assigned to* +warning: unknown kconfig symbol 'BT_LE_50_FEATURE_SUPPORT' assigned to* +warning: unknown kconfig symbol 'BT_LE_MAX_EXT_ADV_INSTANCES' assigned to* +warning: unknown kconfig symbol 'BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER' assigned to 'n' in /builds/espressif/esp-idf/examples/bluetooth/nimble/power_save/sdkconfig.defaults.* +warning: unknown kconfig symbol 'BTDM_BLE_MESH_SCAN_DUPL_EN' assigned to* +warning: unknown kconfig symbol 'BTDM_CTRL_HCI_MODE_VHCI' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_hid_device/sdkconfig.defaults +warning: unknown kconfig symbol 'BTDM_CTRL_HCI_MODE_VHCI' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_hid_host/sdkconfig.defaults +warning: unknown kconfig symbol 'BTDM_CTRL_MODE_BLE_ONLY' assigned to* +warning: unknown kconfig symbol 'BTDM_CTRL_MODE_BR_EDR_ONLY' assigned to* +warning: unknown kconfig symbol 'BTDM_CTRL_MODE_BTDM' assigned to* +warning: unknown kconfig symbol 'BTDM_MODEM_SLEEP' assigned to* +warning: unknown kconfig symbol 'BTDM_SCAN_DUPL_TYPE_DATA_DEVICE' assigned to* +warning: unknown kconfig symbol 'CTRL_BTDM_MODEM_SLEEP' assigned to* +warning: unknown kconfig symbol 'ESP_DEFAULT_CPU_FREQ_MHZ_240' assigned to 'y' in /builds/espressif/esp-idf/components/vfs/test_apps/* +warning: unknown kconfig symbol 'ESP_DEFAULT_CPU_FREQ_MHZ_240' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/wifi_coexist/ +warning: unknown kconfig symbol 'ESP_DEFAULT_CPU_FREQ_MHZ_80' assigned to 'y' in /builds/espressif/esp-idf/examples/system/deep_sleep/* +warning: unknown kconfig symbol 'ESP_DEFAULT_CPU_FREQ_MHZ_80' assigned to 'y' in /builds/espressif/esp-idf/examples/system/light_sleep/* +warning: unknown kconfig symbol 'ESP_WIFI_SW_COEXIST_PREFERENCE_BALANCE' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESP_WIFI_SW_COEXIST_PREFERENCE_VALUE' assigned to '2' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/fast_provisioning/fast_prov_server/sdkconfig.ci.iram +warning: unknown kconfig symbol 'ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/fast_provisioninging/fast_prov_server/sdkconfig.ci.iram +warning: unknown kconfig symbol 'ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/nimble/ble_htp/htp_prph/sdkconfig.ci +warning: unknown kconfig symbol 'ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/nimble/ble_proximity_sensor/proximity_sensor_prph/sdkconfig.ci +warning: unknown kconfig symbol 'ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/nimble/blehr/sdkconfig.ci +warning: unknown kconfig symbol 'ESP32_REV_MIN_3' assigned to 'y' in /builds/espressif/esp-idf/examples/system/ota/simple_ota_example/sdkconfig.ci.on_update_no_sb_rsa +warning: unknown kconfig symbol 'ESP32_REV_MIN' assigned to '3' in /builds/espressif/esp-idf/examples/system/ota/simple_ota_example/sdkconfig.ci.on_update_no_sb_rsa +warning: unknown kconfig symbol 'ESP32H4_RTC_CLK_CAL_CYCLES' assigned to '576' in /builds/espressif/esp-idf/examples/bluetooth/nimble/blecent/sdkconfig.defaults.esp32h4 +warning: unknown kconfig symbol 'ESP32H4_RTC_CLK_SRC_EXT_CRYS' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/nimble/blecent/sdkconfig.defaults.esp32h4 +warning: unknown kconfig symbol 'ESPTOOLPY_BAUD_921600B' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_FLASHSIZE_4MB' assigned to 'y' in /builds/espressif/esp-idf/components/esp_partition/host_test/partition_api_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_FLASHSIZE_4MB' assigned to 'y' in /builds/espressif/esp-idf/components/spiffs/host_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_FLASHSIZE' assigned to '"4MB"' in /builds/espressif/esp-idf/components/esp_partition/host_test/partition_api_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_FLASHSIZE' assigned to '"4MB"' in /builds/espressif/esp-idf/components/spiffs/host_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_FLASHSIZE' assigned to '"8MB"' in /builds/espressif/esp-idf/components/wear_levelling/host_test/sdkconfig.defaults +warning: unknown kconfig symbol 'ESPTOOLPY_MONITOR_BAUD_921600B' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/vendor_models/* +warning: unknown kconfig symbol 'FMB_TIMER_GROUP' assigned to '0' in /builds/espressif/esp-idf/examples/protocols/modbus/tcp/* +warning: unknown kconfig symbol 'FMB_TIMER_INDEX' assigned to '0' in /builds/espressif/esp-idf/examples/protocols/modbus/tcp/* +warning: unknown kconfig symbol 'FMB_TIMER_ISR_IN_IRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/modbus/* +warning: unknown kconfig symbol 'LIBSODIUM_USE_MBEDTLS_SHA' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_br/* +warning: unknown kconfig symbol 'LIBSODIUM_USE_MBEDTLS_SHA' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_cli/* +warning: unknown kconfig symbol 'LIBSODIUM_USE_MBEDTLS_SHA' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_rcp/* +warning: unknown kconfig symbol 'LWIP_ETHARP_TRUST_IP_MAC' assigned to 'n' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/* +warning: unknown kconfig symbol 'LWIP_ETHARP_TRUST_IP_MAC' assigned to 'n' in /builds/espressif/esp-idf/examples/wifi/iperf/* +warning: unknown kconfig symbol 'LWIP_ETHARP_TRUST_IP_MAC' assigned to 'n' in /builds/espressif/esp-idf/idf-app-test/apps/iperf/* +warning: unknown kconfig symbol 'LWIP_IP_FRAG' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'LWIP_IP_REASSEMBLY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'MB_SLAVE_IP_FROM_STDIN' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/modbus/* +warning: unknown kconfig symbol 'MDNS_STRICT_MODE' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_br/* +warning: unknown kconfig symbol 'OPENTHREAD_TREL' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_br/* +warning: unknown kconfig symbol 'PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET' assigned to '0x10000' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'SDK_MAKE_WARN_UNDEFINED_VARIABLES' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/coex_test/sdkconfig.defaults +warning: unknown kconfig symbol 'SPI_FLASH_USE_LEGACY_IMPL' assigned to '1' in /builds/espressif/esp-idf/components/wear_levelling/host_test/sdkconfig.defaults +warning: unknown kconfig symbol 'SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/fast_provisioning/fast_prov_server/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_FETCH_INSTRUCTIONS' assigned to 'y' in /builds/espressif/esp-idf/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_IGNORE_NOTFOUND' assigned to 'y' in /builds/espressif/esp-idf/examples/network/simple_sniffer/sdkconfig.ci.mem +warning: unknown kconfig symbol 'SPIRAM_MALLOC_ALWAYSINTERNAL' assigned to '0' in /builds/espressif/esp-idf/components/fatfs/test_apps/flash_wl/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_MALLOC_ALWAYSINTERNAL' assigned to '0' in /builds/espressif/esp-idf/components/fatfs/test_apps/sdcard/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_MALLOC_ALWAYSINTERNAL' assigned to '0' in /builds/espressif/esp-idf/components/spiffs/test_apps/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_MALLOC_ALWAYSINTERNAL' assigned to '0' in /builds/espressif/esp-idf/components/vfs/test_apps/* +warning: unknown kconfig symbol 'SPIRAM_MALLOC_RESERVE_INTERNAL' assigned to '150000' in /builds/espressif/esp-idf/examples/peripherals/usb/host/uvc/sdkconfig.defaults +warning: unknown kconfig symbol 'SPIRAM_RODATA' assigned to 'y' in /builds/espressif/esp-idf/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM_TRY_ALLOCATE_WIFI_LWIP' assigned to 'y' in /builds/espressif/esp-idf/examples/peripherals/usb/host/uvc/sdkconfig.defaults +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/components/fatfs/test_apps/flash_wl/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/components/fatfs/test_apps/sdcard/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/components/spiffs/test_apps/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/components/vfs/test_apps/* +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/bluetooth/esp_ble_mesh/fast_provisioning/fast_prov_server/sdkconfig.ci.psram +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/network/simple_sniffer/sdkconfig.ci.mem +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/peripherals/usb/host/uvc/sdkconfig.defaults +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/http2_request/sdkconfig.ci +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/https_mbedtls/sdkconfig.ci +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/https_request/sdkconfig.ci +warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in /builds/espressif/esp-idf/examples/protocols/https_request/sdkconfig.ci.ssldyn +warning: unknown kconfig symbol 'TINYUSB' assigned to 'y' in /builds/espressif/esp-idf/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/sdkconfig.defaults +warning: unknown kconfig symbol 'UNITY_FREERTOS_STACK_SIZE' assigned to '12288' in /builds/espressif/esp-idf/components/bt/test_apps/sdkconfig.defaults +warning: unknown kconfig symbol 'WIFI_ENABLED' assigned to 'n' in /builds/espressif/esp-idf/examples/bluetooth/bluedroid/classic_bt/* +warning: unknown kconfig symbol 'WPA3_SAE' assigned to 'y' in /builds/espressif/esp-idf/components/wpa_supplicant/test_apps/sdkconfig.defaults diff --git a/tools/unit-test-app/sdkconfig.defaults b/tools/unit-test-app/sdkconfig.defaults index 59e5fa46bfbc..fc6ce0a1c6e3 100644 --- a/tools/unit-test-app/sdkconfig.defaults +++ b/tools/unit-test-app/sdkconfig.defaults @@ -1,6 +1,5 @@ CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y -CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=n CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partition_table_unit_test_app.csv" CONFIG_PARTITION_TABLE_FILENAME="partition_table_unit_test_app.csv" @@ -18,4 +17,3 @@ CONFIG_COMPILER_WARN_WRITE_STRINGS=y CONFIG_SPI_MASTER_IN_IRAM=y CONFIG_EFUSE_VIRTUAL=y CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y -CONFIG_MQTT_TEST_BROKER_URI="mqtt://${EXAMPLE_MQTT_BROKER_TCP}" From fe007196f2592c21b8ba9436f1a57aa5ead29b6b Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Wed, 1 Nov 2023 12:42:22 +0800 Subject: [PATCH 119/161] bugfix(spi_flash): Fix wrong naming on 32bit address --- components/bootloader/Kconfig.projbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 810bc7fb1360..ccccee451b7f 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -139,7 +139,7 @@ menu "Bootloader config" config BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH bool - default y if ESPTOOLPY_OCT_FLASH && SPI_FLASH_32BIT_ADDRESS + default y if ESPTOOLPY_OCT_FLASH && BOOTLOADER_FLASH_32BIT_ADDR default n endmenu From c14d7fbb17b00a28b21ee8e19e451e6ab7f6801e Mon Sep 17 00:00:00 2001 From: gaoxu Date: Wed, 1 Nov 2023 15:06:20 +0800 Subject: [PATCH 120/161] feat(adc): added adc enable debug log config --- components/esp_adc/Kconfig | 9 +++++++++ components/esp_adc/adc_continuous.c | 8 ++++++++ components/esp_adc/adc_oneshot.c | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/components/esp_adc/Kconfig b/components/esp_adc/Kconfig index 16ca09703739..24faca9919ac 100644 --- a/components/esp_adc/Kconfig +++ b/components/esp_adc/Kconfig @@ -76,4 +76,13 @@ menu "ADC and ADC Calibration" If you stick to this, you can enable this option to force use ADC2 under above conditions. For more details, you can search for errata on espressif website. + + config ADC_ENABLE_DEBUG_LOG + bool "Enable ADC debug log" + default n + help + Wether to enable the debug log message for ADC driver. + Note that this option only controls the ADC driver log, will not affect other drivers. + + note: This cannot be used in the ADC legacy driver. endmenu diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index a52799210d25..d954e880eaf7 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -9,6 +9,11 @@ #include #include #include "sdkconfig.h" +#if CONFIG_ADC_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif #include "esp_intr_alloc.h" #include "esp_log.h" #include "esp_pm.h" @@ -102,6 +107,9 @@ static esp_err_t adc_digi_gpio_init(adc_unit_t adc_unit, uint16_t channel_mask) esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_config, adc_continuous_handle_t *ret_handle) { +#if CONFIG_ADC_ENABLE_DEBUG_LOG + esp_log_level_set(ADC_TAG, ESP_LOG_DEBUG); +#endif esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE((hdl_config->conv_frame_size % SOC_ADC_DIGI_DATA_BYTES_PER_CONV == 0), ESP_ERR_INVALID_ARG, ADC_TAG, "conv_frame_size should be in multiples of `SOC_ADC_DIGI_DATA_BYTES_PER_CONV`"); diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c index dba3fd6b1ca5..80f2711489f2 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/components/esp_adc/adc_oneshot.c @@ -7,6 +7,11 @@ #include #include #include "sdkconfig.h" +#if CONFIG_ADC_ENABLE_DEBUG_LOG +// The local log level must be defined before including esp_log.h +// Set the maximum log level for this source file +#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG +#endif #include "stdatomic.h" #include "esp_log.h" #include "esp_check.h" @@ -69,6 +74,9 @@ esp_err_t adc_oneshot_channel_to_io(adc_unit_t unit_id, adc_channel_t channel, i esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, adc_oneshot_unit_handle_t *ret_unit) { +#if CONFIG_ADC_ENABLE_DEBUG_LOG + esp_log_level_set(TAG, ESP_LOG_DEBUG); +#endif esp_err_t ret = ESP_OK; adc_oneshot_unit_ctx_t *unit = NULL; ESP_GOTO_ON_FALSE(init_config && ret_unit, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument: null pointer"); From 77aee65708c82e4ca02a47c2e770767b7f34019f Mon Sep 17 00:00:00 2001 From: Shyamal Khachane Date: Wed, 1 Nov 2023 11:02:12 +0530 Subject: [PATCH 121/161] docs(esp_wifi): Fix inconsistency in NAN documentation --- docs/conf_common.py | 4 +++- docs/en/api-reference/network/index.rst | 2 +- docs/zh_CN/api-reference/network/index.rst | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/conf_common.py b/docs/conf_common.py index 05d2bb9748c6..6d286875c9a8 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -63,12 +63,13 @@ WIFI_DOCS = ['api-guides/wifi.rst', 'api-guides/wifi-security.rst', 'api-guides/wireshark-user-guide.rst', - 'api-reference/network/esp_nan.rst', 'api-reference/network/esp_now.rst', 'api-reference/network/esp_smartconfig.rst', 'api-reference/network/esp_wifi.rst', 'api-reference/network/esp_dpp.rst'] +NAN_DOCS = ['api-reference/network/esp_nan.rst'] + WIFI_MESH_DOCS = ['api-guides/esp-wifi-mesh.rst', 'api-reference/network/esp-wifi-mesh.rst'] @@ -223,6 +224,7 @@ 'SOC_SDM_SUPPORTED':SDM_DOCS, 'SOC_WIFI_MESH_SUPPORT':WIFI_MESH_DOCS, 'SOC_SPI_SUPPORT_SLAVE_HD_VER2':SPI_SLAVE_HD_DOCS, + 'SOC_WIFI_NAN_SUPPORT':NAN_DOCS, 'esp32':ESP32_DOCS, 'esp32s2':ESP32S2_DOCS, 'esp32s3':ESP32S3_DOCS, diff --git a/docs/en/api-reference/network/index.rst b/docs/en/api-reference/network/index.rst index 17cc3a5090ed..0c874ead99ae 100644 --- a/docs/en/api-reference/network/index.rst +++ b/docs/en/api-reference/network/index.rst @@ -16,7 +16,7 @@ Networking APIs esp_smartconfig esp_wifi esp_dpp - esp_nan + :SOC_WIFI_NAN_SUPPORT: esp_nan Code examples for the Wi-Fi API are provided in the :example:`wifi` directory of ESP-IDF examples. diff --git a/docs/zh_CN/api-reference/network/index.rst b/docs/zh_CN/api-reference/network/index.rst index dbd53d701d52..7acaac9aeca6 100644 --- a/docs/zh_CN/api-reference/network/index.rst +++ b/docs/zh_CN/api-reference/network/index.rst @@ -16,7 +16,7 @@ esp_smartconfig esp_wifi esp_dpp - esp_nan + :SOC_WIFI_NAN_SUPPORT: esp_nan 本部分的 Wi-Fi API 示例代码存放在 ESP-IDF 示例项目的 :example:`wifi` 目录下。 From 4dd480ce83a789588ec4dae05a6ac93dbf0b6317 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Tue, 31 Oct 2023 13:15:44 +0530 Subject: [PATCH 122/161] fix(esp_wifi): Fix key install issue in PTK renew --- components/esp_wifi/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index fbe999ab6886..a0a9c8b7838a 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit fbe999ab688618498ee98b1569c23ed11c8889ce +Subproject commit a0a9c8b7838adc81975f09bc7b4e1296dfcd27d8 From 5b759934f39a69b366ac8770a33453b482b66d3b Mon Sep 17 00:00:00 2001 From: zwl Date: Wed, 1 Nov 2023 16:25:11 +0800 Subject: [PATCH 123/161] fix(ble): fixed ble disconnection issue under temperature change --- components/esp_phy/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_phy/lib b/components/esp_phy/lib index 9af837d5a581..a8e8b9532e28 160000 --- a/components/esp_phy/lib +++ b/components/esp_phy/lib @@ -1 +1 @@ -Subproject commit 9af837d5a581f502d7d5b1b5829a5c008c048be4 +Subproject commit a8e8b9532e2874ac167d4ade7808fda70fe05820 From 93d4b0b38c819bd5ae5c1c131367c9844e87829a Mon Sep 17 00:00:00 2001 From: Guillaume Souchere Date: Fri, 20 Oct 2023 15:23:10 +0200 Subject: [PATCH 124/161] fix(heap): Patch tlsf_check_pool in ROM heap The integrity_walker now calls the integrity check hook to control free AND used blocks of memory in the TLSF pool. This integrity walker function is called from tlsf_check_pool. This commit creates a patch of integrity_walker function to update the outdated implementation in the ROM. --- components/esp_rom/CMakeLists.txt | 4 +- .../esp_rom/esp32c2/Kconfig.soc_caps.in | 4 - components/esp_rom/esp32c2/esp_rom_caps.h | 1 - .../esp_rom/esp32c6/Kconfig.soc_caps.in | 4 + components/esp_rom/esp32c6/esp_rom_caps.h | 1 + .../esp_rom/esp32c6/ld/esp32c6.rom.heap.ld | 1 - .../esp_rom/esp32h2/Kconfig.soc_caps.in | 4 + components/esp_rom/esp32h2/esp_rom_caps.h | 1 + .../esp_rom/esp32h2/ld/esp32h2.rom.heap.ld | 1 - components/esp_rom/linker.lf | 2 +- components/esp_rom/patches/esp_rom_tlsf.c | 211 +++++------------- components/heap/Kconfig | 10 + .../heap_tests/main/test_corruption_check.c | 4 - 13 files changed, 75 insertions(+), 173 deletions(-) diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 02ec89d331f8..0701edc6c82f 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -30,7 +30,7 @@ else() endif() endif() - if(CONFIG_HEAP_TLSF_USE_ROM_IMPL AND CONFIG_ESP_ROM_TLSF_CHECK_PATCH) + if(CONFIG_HEAP_TLSF_USE_ROM_IMPL AND (CONFIG_ESP_ROM_TLSF_CHECK_PATCH OR CONFIG_HEAP_TLSF_CHECK_PATCH)) # This file shall be included in the build if TLSF in ROM is activated list(APPEND sources "patches/esp_rom_tlsf.c") endif() @@ -301,7 +301,7 @@ else() # Regular app build # to force the linker to integrate the whole `esp_rom_tlsf.c` object file inside the # final binary. This is necessary because tlsf_set_rom_patches is a constructor, thus, # there as no explicit reference/call to it in IDF. - if(CONFIG_ESP_ROM_TLSF_CHECK_PATCH) + if((CONFIG_ESP_ROM_TLSF_CHECK_PATCH OR CONFIG_HEAP_TLSF_CHECK_PATCH)) target_link_libraries(${COMPONENT_LIB} PRIVATE "-u tlsf_set_rom_patches") endif() diff --git a/components/esp_rom/esp32c2/Kconfig.soc_caps.in b/components/esp_rom/esp32c2/Kconfig.soc_caps.in index 752cf25be62f..b2d3381e8c5c 100644 --- a/components/esp_rom/esp32c2/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32c2/Kconfig.soc_caps.in @@ -39,10 +39,6 @@ config ESP_ROM_HAS_HEAP_TLSF bool default y -config ESP_ROM_TLSF_CHECK_PATCH - bool - default y - config ESP_ROM_HAS_LAYOUT_TABLE bool default y diff --git a/components/esp_rom/esp32c2/esp_rom_caps.h b/components/esp_rom/esp32c2/esp_rom_caps.h index 8eacb1616c07..cc3fdc51804a 100644 --- a/components/esp_rom/esp32c2/esp_rom_caps.h +++ b/components/esp_rom/esp32c2/esp_rom_caps.h @@ -15,7 +15,6 @@ #define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver #define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver #define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library -#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check() #define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table #define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver #define ESP_ROM_HAS_NEWLIB_NANO_FORMAT (1) // ROM has the newlib nano version of formatting functions diff --git a/components/esp_rom/esp32c6/Kconfig.soc_caps.in b/components/esp_rom/esp32c6/Kconfig.soc_caps.in index 9e23f349b7e7..df5e153a0d22 100644 --- a/components/esp_rom/esp32c6/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32c6/Kconfig.soc_caps.in @@ -47,6 +47,10 @@ config ESP_ROM_HAS_HEAP_TLSF bool default y +config ESP_ROM_TLSF_CHECK_PATCH + bool + default y + config ESP_ROM_HAS_LAYOUT_TABLE bool default y diff --git a/components/esp_rom/esp32c6/esp_rom_caps.h b/components/esp_rom/esp32c6/esp_rom_caps.h index 1ec2d8723906..1eeab3bd3e8b 100644 --- a/components/esp_rom/esp32c6/esp_rom_caps.h +++ b/components/esp_rom/esp32c6/esp_rom_caps.h @@ -17,6 +17,7 @@ #define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver #define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver #define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library +#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool() #define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table #define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver #define ESP_ROM_HAS_REGI2C_BUG (1) // ROM has the regi2c bug diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld index 1e9538838326..f09bb74f08af 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld @@ -37,7 +37,6 @@ tlsf_pool_overhead = 0x40000438; tlsf_alloc_overhead = 0x4000043c; tlsf_walk_pool = 0x40000440; tlsf_check = 0x40000444; -tlsf_check_pool = 0x40000448; tlsf_poison_fill_pfunc_set = 0x4000044c; tlsf_poison_check_pfunc_set = 0x40000450; multi_heap_get_block_address_impl = 0x40000454; diff --git a/components/esp_rom/esp32h2/Kconfig.soc_caps.in b/components/esp_rom/esp32h2/Kconfig.soc_caps.in index a5b8f8797144..9e95fbf265f4 100644 --- a/components/esp_rom/esp32h2/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32h2/Kconfig.soc_caps.in @@ -39,6 +39,10 @@ config ESP_ROM_HAS_HEAP_TLSF bool default y +config ESP_ROM_TLSF_CHECK_PATCH + bool + default y + config ESP_ROM_HAS_LAYOUT_TABLE bool default y diff --git a/components/esp_rom/esp32h2/esp_rom_caps.h b/components/esp_rom/esp32h2/esp_rom_caps.h index 321ab91b8e46..375f91137d55 100644 --- a/components/esp_rom/esp32h2/esp_rom_caps.h +++ b/components/esp_rom/esp32h2/esp_rom_caps.h @@ -15,6 +15,7 @@ #define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver #define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver #define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library +#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool() #define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table #define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver #define ESP_ROM_WITHOUT_REGI2C (1) // ROM has no regi2c APIs diff --git a/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld b/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld index 3e17e87eba2d..0c176cbbb4e7 100644 --- a/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld +++ b/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld @@ -37,7 +37,6 @@ tlsf_pool_overhead = 0x40000430; tlsf_alloc_overhead = 0x40000434; tlsf_walk_pool = 0x40000438; tlsf_check = 0x4000043c; -tlsf_check_pool = 0x40000440; tlsf_poison_fill_pfunc_set = 0x40000444; tlsf_poison_check_pfunc_set = 0x40000448; multi_heap_get_block_address_impl = 0x4000044c; diff --git a/components/esp_rom/linker.lf b/components/esp_rom/linker.lf index 99ddf6bdd422..bc708c5697bf 100644 --- a/components/esp_rom/linker.lf +++ b/components/esp_rom/linker.lf @@ -6,7 +6,7 @@ entries: esp_rom_cache_esp32s2_esp32s3 (noflash) if ESP_ROM_HAS_CACHE_WRITEBACK_BUG = y: esp_rom_cache_writeback_esp32s3 (noflash) - if HEAP_TLSF_USE_ROM_IMPL = y && ESP_ROM_TLSF_CHECK_PATCH = y: + if HEAP_TLSF_USE_ROM_IMPL = y && (ESP_ROM_TLSF_CHECK_PATCH = y || HEAP_TLSF_CHECK_PATCH = y): esp_rom_tlsf (noflash) if SOC_SYSTIMER_SUPPORTED = y: esp_rom_systimer (noflash) diff --git a/components/esp_rom/patches/esp_rom_tlsf.c b/components/esp_rom/patches/esp_rom_tlsf.c index 088248acce73..06da0583289e 100644 --- a/components/esp_rom/patches/esp_rom_tlsf.c +++ b/components/esp_rom/patches/esp_rom_tlsf.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,46 +33,10 @@ typedef void* tlsf_walker; #define tlsf_cast(t, exp) ((t) (exp)) -enum tlsf_config { - /* log2 of number of linear subdivisions of block sizes. Larger - ** values require more memory in the control structure. Values of - ** 4 or 5 are typical. - */ - SL_INDEX_COUNT_LOG2 = 5, - - /* All allocation sizes and addresses are aligned to 4 bytes. */ - ALIGN_SIZE_LOG2 = 2, - ALIGN_SIZE = (1 << ALIGN_SIZE_LOG2), - -/* - ** We support allocations of sizes up to (1 << FL_INDEX_MAX) bits. - ** However, because we linearly subdivide the second-level lists, and - ** our minimum size granularity is 4 bytes, it doesn't make sense to - ** create first-level lists for sizes smaller than SL_INDEX_COUNT * 4, - ** or (1 << (SL_INDEX_COUNT_LOG2 + 2)) bytes, as there we will be - ** trying to split size ranges into more slots than we have available. - ** Instead, we calculate the minimum threshold size, and place all - ** blocks below that size into the 0th first-level list. - */ - - /* Fix the value of FL_INDEX_MAX to match the value that is defined - * in the ROM implementation. */ - FL_INDEX_MAX = 18, //Each pool can have up 256KB - - SL_INDEX_COUNT = (1 << SL_INDEX_COUNT_LOG2), - FL_INDEX_SHIFT = (SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2), - FL_INDEX_COUNT = (FL_INDEX_MAX - FL_INDEX_SHIFT + 1), - - SMALL_BLOCK_SIZE = (1 << FL_INDEX_SHIFT), -}; - #define block_header_free_bit (1 << 0) #define block_header_prev_free_bit (1 << 1) #define block_header_overhead (sizeof(size_t)) #define block_start_offset (offsetof(block_header_t, size) + sizeof(size_t)) -#define block_size_min (sizeof(block_header_t) - sizeof(block_header_t*)) - -typedef ptrdiff_t tlsfptr_t; typedef struct block_header_t { @@ -87,26 +51,6 @@ typedef struct block_header_t struct block_header_t* prev_free; } block_header_t; -/* The TLSF control structure. */ -typedef struct control_t -{ - /* Empty lists point at this block to indicate they are free. */ - block_header_t block_null; - - /* Bitmaps for free lists. */ - unsigned int fl_bitmap; - unsigned int sl_bitmap[FL_INDEX_COUNT]; - - /* Head of free lists. */ - block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT]; -} control_t; - -static inline __attribute__((__always_inline__)) int tlsf_fls(unsigned int word) -{ - const int bit = word ? 32 - __builtin_clz(word) : 0; - return bit - 1; -} - static inline __attribute__((__always_inline__)) size_t block_size(const block_header_t* block) { return block->size & ~(block_header_free_bit | block_header_prev_free_bit); @@ -122,41 +66,10 @@ static inline __attribute__((__always_inline__)) int block_is_prev_free(const bl return tlsf_cast(int, block->size & block_header_prev_free_bit); } -static inline __attribute__((__always_inline__)) block_header_t* offset_to_block(const void* ptr, size_t size) -{ - return tlsf_cast(block_header_t*, tlsf_cast(tlsfptr_t, ptr) + size); -} - -static inline __attribute__((__always_inline__)) void* block_to_ptr(const block_header_t* block) -{ - return tlsf_cast(void*, - tlsf_cast(unsigned char*, block) + block_start_offset); -} - -static inline __attribute__((__always_inline__)) block_header_t* block_next(const block_header_t* block) -{ - block_header_t* next = offset_to_block(block_to_ptr(block), - block_size(block) - block_header_overhead); - return next; -} - -static inline __attribute__((__always_inline__)) void mapping_insert(size_t size, int* fli, int* sli) +static inline __attribute__((always_inline)) block_header_t* block_from_ptr(const void* ptr) { - int fl, sl; - if (size < SMALL_BLOCK_SIZE) - { - /* Store small blocks in first list. */ - fl = 0; - sl = tlsf_cast(int, size) >> 2; - } - else - { - fl = tlsf_fls(size); - sl = tlsf_cast(int, size >> (fl - SL_INDEX_COUNT_LOG2)) ^ (1 << SL_INDEX_COUNT_LOG2); - fl -= (FL_INDEX_SHIFT - 1); - } - *fli = fl; - *sli = sl; + return tlsf_cast(block_header_t*, + tlsf_cast(unsigned char*, ptr) - block_start_offset); } /* ---------------------------------------------------------------- @@ -173,74 +86,54 @@ void tlsf_poison_check_pfunc_set(poison_check_pfunc_t pfunc) #define tlsf_insist_no_assert(x) { if (!(x)) { status--; } } -int tlsf_check(tlsf_t tlsf) +typedef struct integrity_t +{ + int prev_status; + int status; +} integrity_t; + +static void integrity_walker(void* ptr, size_t size, int used, void* user) { - int i, j; - - control_t* control = tlsf_cast(control_t*, tlsf); - int status = 0; - - /* Check that the free lists and bitmaps are accurate. */ - for (i = 0; i < FL_INDEX_COUNT; ++i) - { - for (j = 0; j < SL_INDEX_COUNT; ++j) - { - const int fl_map = control->fl_bitmap & (1 << i); - const int sl_list = control->sl_bitmap[i]; - const int sl_map = sl_list & (1 << j); - const block_header_t* block = control->blocks[i][j]; - - /* Check that first- and second-level lists agree. */ - if (!fl_map) - { - tlsf_insist_no_assert(!sl_map && "second-level map must be null"); - } - - if (!sl_map) - { - tlsf_insist_no_assert(block == &control->block_null && "block list must be null"); - continue; - } - - /* Check that there is at least one free block. */ - tlsf_insist_no_assert(sl_list && "no free blocks in second-level map"); - tlsf_insist_no_assert(block != &control->block_null && "block should not be null"); - - while (block != &control->block_null) - { - int fli, sli; - const bool is_block_free = block_is_free(block); - tlsf_insist_no_assert(is_block_free && "block should be free"); - tlsf_insist_no_assert(!block_is_prev_free(block) && "blocks should have coalesced"); - tlsf_insist_no_assert(!block_is_free(block_next(block)) && "blocks should have coalesced"); - tlsf_insist_no_assert(block_is_prev_free(block_next(block)) && "block should be free"); - tlsf_insist_no_assert(block_size(block) >= block_size_min && "block not minimum size"); - - mapping_insert(block_size(block), &fli, &sli); - tlsf_insist_no_assert(fli == i && sli == j && "block size indexed in wrong list"); - - /* block_size(block) returns the size of the usable memory when the block is allocated. - * As the block under test is free, we need to subtract to the block size the next_free - * and prev_free fields of the block header as they are not a part of the usable memory - * when the block is free. In addition, we also need to subtract the size of prev_phys_block - * as this field is in fact part of the current free block and not part of the next (allocated) - * block. Check the comments in block_split function for more details. - */ - const size_t actual_free_block_size = block_size(block) - - offsetof(block_header_t, next_free) - - block_header_overhead; - - if (s_poison_check_region != NULL) { - tlsf_insist_no_assert(s_poison_check_region((char *)block + sizeof(block_header_t), - actual_free_block_size, is_block_free, true /* print errors */)); - } - - block = block->next_free; - } - } - } - - return status; + block_header_t* block = block_from_ptr(ptr); + integrity_t* integ = tlsf_cast(integrity_t*, user); + const int this_prev_status = block_is_prev_free(block) ? 1 : 0; + const int this_status = block_is_free(block) ? 1 : 0; + const size_t this_block_size = block_size(block); + + int status = 0; + tlsf_insist_no_assert(integ->prev_status == this_prev_status && "prev status incorrect"); + tlsf_insist_no_assert(size == this_block_size && "block size incorrect"); + + if (s_poison_check_region != NULL) + { + /* block_size(block) returns the size of the usable memory when the block is allocated. + * As the block under test is free, we need to subtract to the block size the next_free + * and prev_free fields of the block header as they are not a part of the usable memory + * when the block is free. In addition, we also need to subtract the size of prev_phys_block + * as this field is in fact part of the current free block and not part of the next (allocated) + * block. Check the comments in block_split function for more details. + */ + const size_t actual_free_block_size = used ? this_block_size : + this_block_size - offsetof(block_header_t, next_free)- block_header_overhead; + + void* ptr_block = used ? (void*)block + block_start_offset : + (void*)block + sizeof(block_header_t); + + tlsf_insist_no_assert(s_poison_check_region(ptr_block, actual_free_block_size, !used, true)); + } + + integ->prev_status = this_status; + integ->status += status; +} + +extern void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user); +int tlsf_check_pool(pool_t pool) +{ + /* Check that the blocks are physically correct. */ + integrity_t integ = { 0, 0 }; + tlsf_walk_pool(pool, integrity_walker, &integ); + + return integ.status; } #undef tlsf_insist_no_assert @@ -299,7 +192,7 @@ void __attribute__((constructor)) tlsf_set_rom_patches(void) memcpy(&heap_tlsf_patch_table_ptr, heap_tlsf_table_ptr, sizeof(struct heap_tlsf_stub_table_t)); /* Set the patched function here */ - heap_tlsf_patch_table_ptr.tlsf_check = tlsf_check; + heap_tlsf_patch_table_ptr.tlsf_check_pool = tlsf_check_pool; /* Set our table as the one to use in the ROM code */ heap_tlsf_table_ptr = &heap_tlsf_patch_table_ptr; diff --git a/components/heap/Kconfig b/components/heap/Kconfig index 8de0f77519f3..48382f12060a 100644 --- a/components/heap/Kconfig +++ b/components/heap/Kconfig @@ -128,4 +128,14 @@ menu "Heap memory debugging" Note that it is only safe to enable this configuration if no functions from esp_heap_caps.h or esp_heap_trace.h are called from ISR. + + config HEAP_TLSF_CHECK_PATCH + bool "Patch the tlsf_check_pool() for ROM HEAP TLSF implementation" + depends on IDF_TARGET_ESP32C2 && ESP32C2_REV_MIN_FULL < 200 + default y + help + ROM does not contain the patch of tlsf_check_pool() allowing perform + the integrity checking on used blocks. The patch to allow such check + needs to be applied. + endmenu diff --git a/components/heap/test_apps/heap_tests/main/test_corruption_check.c b/components/heap/test_apps/heap_tests/main/test_corruption_check.c index ec88930c7a9e..2ee7aa21e305 100644 --- a/components/heap/test_apps/heap_tests/main/test_corruption_check.c +++ b/components/heap/test_apps/heap_tests/main/test_corruption_check.c @@ -70,8 +70,6 @@ TEST_CASE("multi_heap poisoning detection", "[heap]") } } -#if !defined(CONFIG_HEAP_TLSF_USE_ROM_IMPL) - #ifdef CONFIG_HEAP_TASK_TRACKING #define HEAD_CANARY_OFFSET 3 // head canary | task tracking | allocated size #else @@ -117,6 +115,4 @@ TEST_CASE("canary corruption in light or comprehensive poisoning mode", "[heap]" ptr[TAIL_CANARY_OFFSET] = canary; heap_caps_free(ptr); } - -#endif // !CONFIG_HEAP_TLSF_USE_ROM_IMPL #endif // CONFIG_HEAP_POISONING_LIGHT && CONFIG_HEAP_LIGHT_POISONING From 3ac6eeb7b64a6e2ee471d8b7f6a2793a7ccab1a2 Mon Sep 17 00:00:00 2001 From: Guillaume Souchere Date: Fri, 20 Oct 2023 15:47:05 +0200 Subject: [PATCH 125/161] change(docs): Remove heap_caps_check_integrity wrong behavior warning in ROM heap A patch will fix the behavior of heap_caps_check_integrity in the ROM implementation of the heap component so the warning is not longer needed. --- docs/en/api-reference/system/heap_debug.rst | 12 ------------ docs/zh_CN/api-reference/system/heap_debug.rst | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/docs/en/api-reference/system/heap_debug.rst b/docs/en/api-reference/system/heap_debug.rst index b9ce083c4892..599f4f16d1b5 100644 --- a/docs/en/api-reference/system/heap_debug.rst +++ b/docs/en/api-reference/system/heap_debug.rst @@ -154,12 +154,6 @@ In both cases, the functions involve checking that the first 4 bytes of an alloc Different values usually indicate buffer underrun or overrun. Overrun indicates that when writing to memory, the data written exceeds the size of the allocated memory, resulting in writing to an unallocated memory area; underrun indicates that when reading memory, the data read exceeds the allocated memory and reads data from an unallocated memory area. -.. only:: CONFIG_ESP_ROM_HAS_HEAP_TLSF - - .. warning:: - - When the ROM implementation of the heap TLSF is used, note that :cpp:func:`heap_caps_check_integrity` will not perform the check of the canary bytes. - Comprehensive +++++++++++++ @@ -184,12 +178,6 @@ Calls to :cpp:func:`heap_caps_check_integrity` may print errors relating to ``0x - For free heap blocks, the checker expects to find all bytes set to ``0xFE``. Any other values indicate a use-after-free bug where free memory has been incorrectly overwritten. - For allocated heap blocks, the behavior is the same as for the Light Impact mode. The canary bytes ``0xABBA1234`` and ``0xBAAD5678`` are checked at the head and tail of each allocated buffer, and any variation indicates a buffer overrun or underrun. -.. only:: CONFIG_ESP_ROM_HAS_HEAP_TLSF - - .. warning:: - - When the ROM implementation of the heap TLSF is used, note that :cpp:func:`heap_caps_check_integrity` will not perform the check of the canary bytes. - .. _heap-task-tracking: Heap Task Tracking diff --git a/docs/zh_CN/api-reference/system/heap_debug.rst b/docs/zh_CN/api-reference/system/heap_debug.rst index 9a01d6328ab3..e437eed71b17 100644 --- a/docs/zh_CN/api-reference/system/heap_debug.rst +++ b/docs/zh_CN/api-reference/system/heap_debug.rst @@ -154,12 +154,6 @@ ESP-IDF 集成了用于请求 :ref:`堆内存信息 `、:ref:` 如果检查到字节与上述值不同,通常表示缓冲区越界或下溢。其中越界表示在写入内存时,写入的数据超过了所分配内存的大小,导致写入到了未分配的内存区域;下溢表示在读取内存时,读取的数据超出了所分配内存的范围,读取了未分配的内存区域的数据。 -.. only:: CONFIG_ESP_ROM_HAS_HEAP_TLSF - - .. warning:: - - 需注意,使用 TLSF 堆的 ROM 实现时,:cpp:func:`heap_caps_check_integrity` 不会对 canary 字节执行检查。 - 全面检测模式 +++++++++++++++++++ @@ -184,12 +178,6 @@ ESP-IDF 集成了用于请求 :ref:`堆内存信息 `、:ref:` - 对于已释放的堆内存块,检测器会检查是否所有字节都设置为 ``0xFE``,检测到任何其他值都表示错误写入了已释放内存。 - 对于已分配的堆内存块,检测器的检查模式与轻微影响模式相同,即在每个分配的缓冲区头部和尾部检查 canary 字节 ``0xABBA1234`` 和 ``0xBAAD5678``,检测到任何其他字节都表示缓冲区越界或下溢。 -.. only:: CONFIG_ESP_ROM_HAS_HEAP_TLSF - - .. warning:: - - 需注意,使用 TLSF 堆的 ROM 实现时,:cpp:func:`heap_caps_check_integrity` 不会对 canary 字节执行检查。 - .. _heap-task-tracking: 堆任务跟踪 From 638d3af14afc9d0ecc25209f3e998c66d3c647dd Mon Sep 17 00:00:00 2001 From: Wang Mengyang Date: Wed, 27 Sep 2023 16:12:52 +0800 Subject: [PATCH 126/161] feat(bt/bluedroid): Support to build HFP Audio Gateway and Hands Free Unit in single binary --- components/bt/host/bluedroid/Kconfig.in | 21 ++++---- .../btc/profile/std/include/btc_hf_ag.h | 4 +- .../btc/profile/std/include/btc_hf_client.h | 4 +- .../common/include/common/bt_target.h | 49 ++++++++++--------- 4 files changed, 41 insertions(+), 37 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index 079080bf3af8..b33bfb9ff77e 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -83,21 +83,23 @@ config BT_L2CAP_ENABLED This enables the Logical Link Control and Adaptation Layer Protocol. Only supported classic bluetooth. -config BT_HFP_ENABLE +menuconfig BT_HFP_ENABLE bool "Hands Free/Handset Profile" depends on BT_CLASSIC_ENABLED default n + help + Hands Free Unit and Audio Gateway can be included simultaneously + but they cannot run simultaneously due to internal limitations. -choice BT_HFP_ROLE - prompt "Hands-free Profile Role configuration" +config BT_HFP_CLIENT_ENABLE + bool "Hands Free Unit" depends on BT_HFP_ENABLE + default y - config BT_HFP_CLIENT_ENABLE - bool "Hands Free Unit" - - config BT_HFP_AG_ENABLE - bool "Audio Gateway" -endchoice +config BT_HFP_AG_ENABLE + bool "Audio Gateway" + depends on BT_HFP_ENABLE + default y choice BT_HFP_AUDIO_DATA_PATH prompt "audio(SCO) data path" @@ -121,6 +123,7 @@ config BT_HFP_WBS_ENABLE This enables Wide Band Speech. Should disable it when SCO data path is PCM. Otherwise there will be no data transmited via GPIOs. + config BT_HID_ENABLED bool "Classic BT HID" depends on BT_CLASSIC_ENABLED diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h index d42c69124375..f936d1816d18 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h @@ -184,13 +184,13 @@ typedef union } phone; // BTC_HF_REGISTER_DATA_CALLBACK_EVT - struct reg_data_callback { + struct ag_reg_data_callback { esp_hf_incoming_data_cb_t recv; esp_hf_outgoing_data_cb_t send; } reg_data_cb; // BTC_HF_REQUEST_PKT_STAT_EVT - struct req_pkt_stat_sync_handle { + struct ag_req_pkt_stat_sync_handle { UINT16 sync_conn_handle; } pkt_sync_hd; diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h index 0af84506858f..4f10371bd016 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h @@ -102,7 +102,7 @@ typedef union { } send_dtmf; // BTC_HF_CLIENT_REGISTER_DATA_CALLBACK_EVT - struct reg_data_callback { + struct hf_client_reg_data_callback { esp_hf_client_incoming_data_cb_t recv; esp_hf_client_outgoing_data_cb_t send; } reg_data_cb; @@ -120,7 +120,7 @@ typedef union { } send_iphoneaccev; // BTC_HF_CLIENT_REQUEST_PKT_STAT_EVT - struct req_pkt_stat_sync_handle { + struct hf_client_req_pkt_stat_sync_handle { UINT16 sync_conn_handle; } pkt_sync_hd; 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 4c3c5ef37cb7..f97180d50c54 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -96,49 +96,50 @@ #define VND_BT_JV_BTA_L2CAP TRUE #endif /* UC_BT_L2CAP_ENABLED */ -#if (UC_BT_HFP_AG_ENABLED == TRUE) -#define BTC_HF_INCLUDED TRUE -#define BTA_AG_INCLUDED TRUE -#define PLC_INCLUDED TRUE -#define BTA_JV_RFCOMM_INCLUDED TRUE +#if (UC_BT_HFP_AG_ENABLED == TRUE) || (UC_BT_HFP_CLIENT_ENABLED == TRUE) #ifndef RFCOMM_INCLUDED #define RFCOMM_INCLUDED TRUE #endif #ifndef BTM_SCO_INCLUDED #define BTM_SCO_INCLUDED TRUE #endif -#ifndef BTM_MAX_SCO_LINKS -#define BTM_MAX_SCO_LINKS (1) -#endif #ifndef SBC_DEC_INCLUDED #define SBC_DEC_INCLUDED TRUE #endif #ifndef SBC_ENC_INCLUDED #define SBC_ENC_INCLUDED TRUE #endif -#endif /* UC_BT_HFP_AG_ENABLED */ +#ifndef PLC_INCLUDED +#define PLC_INCLUDED TRUE +#endif +#if (UC_BT_HFP_AG_ENABLED == TRUE) +#ifndef BTM_MAX_SCO_LINKS_AG +#define BTM_MAX_SCO_LINKS_AG (1) +#endif +#define BTC_HF_INCLUDED TRUE +#define BTA_AG_INCLUDED TRUE +#else +#ifndef BTM_MAX_SCO_LINKS_AG +#define BTM_MAX_SCO_LINKS_AG (0) +#endif +#endif /* (UC_BT_HFP_AG_ENABLED == TRUE) */ #if (UC_BT_HFP_CLIENT_ENABLED == TRUE) +#ifndef BTM_MAX_SCO_LINKS_CLIENT +#define BTM_MAX_SCO_LINKS_CLIENT (1) +#endif #define BTC_HF_CLIENT_INCLUDED TRUE #define BTA_HF_INCLUDED TRUE -#define PLC_INCLUDED TRUE -#ifndef RFCOMM_INCLUDED -#define RFCOMM_INCLUDED TRUE -#endif -#ifndef BTM_SCO_INCLUDED -#define BTM_SCO_INCLUDED TRUE -#endif -#ifndef BTM_MAX_SCO_LINKS -#define BTM_MAX_SCO_LINKS (1) +#else +#ifndef BTM_MAX_SCO_LINKS_CLIENT +#define BTM_MAX_SCO_LINKS_CLIENT (0) #endif +#endif /* (UC_BT_HFP_CLIENT_ENABLED == TRUE) */ -#ifndef SBC_DEC_INCLUDED -#define SBC_DEC_INCLUDED TRUE -#endif -#ifndef SBC_ENC_INCLUDED -#define SBC_ENC_INCLUDED TRUE +#ifndef BTM_MAX_SCO_LINKS +#define BTM_MAX_SCO_LINKS (BTM_MAX_SCO_LINKS_AG + BTM_MAX_SCO_LINKS_CLIENT) #endif -#endif /* UC_BT_HFP_CLIENT_ENABLED */ +#endif /* (UC_BT_HFP_AG_ENABLED == TRUE) || (UC_BT_HFP_CLIENT_ENABLED == TRUE) */ #if UC_BT_HID_ENABLED #define BT_HID_INCLUDED TRUE From 1f2a1564a2b3bb4c0cccf73cec5d50756a3f3261 Mon Sep 17 00:00:00 2001 From: Jin Cheng Date: Mon, 9 Oct 2023 10:12:19 +0800 Subject: [PATCH 127/161] feat(bt/bluedroid): Support to build HID Host and HID Device in single binary --- components/bt/host/bluedroid/Kconfig.in | 23 +++++++++---------- .../btc/profile/std/include/btc_hd.h | 2 +- .../btc/profile/std/include/btc_hh.h | 2 +- .../include/common/bluedroid_user_config.h | 6 +++-- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index b33bfb9ff77e..1c71a11a2d44 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -124,26 +124,25 @@ config BT_HFP_WBS_ENABLE Otherwise there will be no data transmited via GPIOs. -config BT_HID_ENABLED +menuconfig BT_HID_ENABLED bool "Classic BT HID" depends on BT_CLASSIC_ENABLED default n help This enables the BT HID Host -choice BT_HID_ROLE - prompt "Profile Role configuration" +config BT_HID_HOST_ENABLED + bool "Classic BT HID Host" depends on BT_HID_ENABLED - config BT_HID_HOST_ENABLED - bool "Classic BT HID Host" - help - This enables the BT HID Host + default n + help + This enables the BT HID Host - config BT_HID_DEVICE_ENABLED - bool "Classic BT HID Device" - help - This enables the BT HID Device -endchoice +config BT_HID_DEVICE_ENABLED + bool "Classic BT HID Device" + depends on BT_HID_ENABLED + help + This enables the BT HID Device config BT_BLE_ENABLED bool "Bluetooth Low Energy" diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h index c290dd7c0a9a..313930a4d02f 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h @@ -63,7 +63,7 @@ typedef struct { /* btc_hidd_args_t */ typedef union { // BTC_HD_CONNECT_EVT - struct connect_arg { + struct hd_connect_arg { BD_ADDR bd_addr; } connect; diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h index 0e0cea8a06db..ae6faefc1ef9 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hh.h @@ -103,7 +103,7 @@ typedef struct { /* btc_spp_args_t */ typedef union { // BTC_HH_CONNECT_EVT - struct connect_arg { + struct hh_connect_arg { BD_ADDR bd_addr; } connect; 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 82b3bf5bd02e..d8b406536cb5 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 @@ -454,13 +454,15 @@ #ifdef CONFIG_BT_LOG_HID_TRACE_LEVEL #if UC_BT_HID_HOST_ENABLED #define UC_BT_LOG_HIDH_TRACE_LEVEL CONFIG_BT_LOG_HID_TRACE_LEVEL -#elif UC_BT_HID_DEVICE_ENABLED +#endif +#if UC_BT_HID_DEVICE_ENABLED #define UC_BT_LOG_HIDD_TRACE_LEVEL CONFIG_BT_LOG_HID_TRACE_LEVEL #endif #else #if UC_BT_HID_HOST_ENABLED #define UC_BT_LOG_HIDH_TRACE_LEVEL UC_TRACE_LEVEL_WARNING -#elif UC_BT_HID_DEVICE_ENABLED +#endif +#if UC_BT_HID_DEVICE_ENABLED #define UC_BT_LOG_HIDD_TRACE_LEVEL UC_TRACE_LEVEL_WARNING #endif #endif From 37d6913e2faa0a92573ad9d87502d783abdad217 Mon Sep 17 00:00:00 2001 From: Ondrej Buchta Date: Wed, 1 Nov 2023 17:11:55 +0800 Subject: [PATCH 128/161] added spaces to lines 156-167 as the asterisk at 161 was apparently causing an issue --- .gitlab/CODEOWNERS | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index bd0687aaa1c7..17ea10947286 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -153,18 +153,18 @@ /components/wpa_supplicant/ @esp-idf-codeowners/wifi @esp-idf-codeowners/app-utilities/mbedtls /components/xtensa/ @esp-idf-codeowners/system -/docs/ @esp-idf-codeowners/docs -/docs/en/api-guides/jtag-debugging/ @esp-idf-codeowners/debugging -/docs/**/api-reference/bluetooth/ @esp-idf-codeowners/bluetooth -/docs/**/api-reference/network/ @esp-idf-codeowners/network @esp-idf-codeowners/wifi -/docs/**/api-reference/peripherals/ @esp-idf-codeowners/peripherals -/docs/**/api-reference/peripherals/usb* @esp-idf-codeowners/peripherals @esp-idf-codeowners/peripherals/usb -/docs/**/api-reference/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities -/docs/**/api-reference/provisioning/ @esp-idf-codeowners/app-utilities/provisioning -/docs/**/api-reference/storage/ @esp-idf-codeowners/storage -/docs/**/api-reference/system/ @esp-idf-codeowners/system -/docs/**/security/ @esp-idf-codeowners/security -/docs/**/migration-guides/ @esp-idf-codeowners/docs @esp-idf-codeowners/all-maintainers +/docs/ @esp-idf-codeowners/docs +/docs/en/api-guides/jtag-debugging/ @esp-idf-codeowners/debugging +/docs/**/api-reference/bluetooth/ @esp-idf-codeowners/bluetooth +/docs/**/api-reference/network/ @esp-idf-codeowners/network @esp-idf-codeowners/wifi +/docs/**/api-reference/peripherals/ @esp-idf-codeowners/peripherals +/docs/**/api-reference/peripherals/usb* @esp-idf-codeowners/peripherals @esp-idf-codeowners/peripherals/usb +/docs/**/api-reference/protocols/ @esp-idf-codeowners/network @esp-idf-codeowners/app-utilities +/docs/**/api-reference/provisioning/ @esp-idf-codeowners/app-utilities/provisioning +/docs/**/api-reference/storage/ @esp-idf-codeowners/storage +/docs/**/api-reference/system/ @esp-idf-codeowners/system +/docs/**/security/ @esp-idf-codeowners/security +/docs/**/migration-guides/ @esp-idf-codeowners/docs @esp-idf-codeowners/all-maintainers /examples/README.md @esp-idf-codeowners/docs @esp-idf-codeowners/ci /examples/**/*.py @esp-idf-codeowners/ci @esp-idf-codeowners/tools From 448d168dfd63221b78f03f6984eaab5191e901d3 Mon Sep 17 00:00:00 2001 From: chenjianhua Date: Thu, 26 Oct 2023 20:05:44 +0800 Subject: [PATCH 129/161] update esp32 bt-lib (6458728) - Modify mesh proxy solic uuid to 0x18590303 - Support get the range of TX power level - Support clear legacy adv using vendor hci --- components/bt/controller/lib_esp32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index 943b0f24eb6e..cddb921d2041 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit 943b0f24eb6ed390213599e4a9556c66844ef0db +Subproject commit cddb921d20418cef04de83ddfe3543463dfbc2bc From 46cbbdd48c0c6f91e2f80c3e3ddc1c54676eab29 Mon Sep 17 00:00:00 2001 From: Roman Leonov Date: Thu, 19 Oct 2023 09:58:52 +0200 Subject: [PATCH 130/161] feat(docs): added USB Host Stack Configuration description --- docs/_static/usb_host/poweron-timings.png | Bin 0 -> 39711 bytes .../en/api-reference/peripherals/usb_host.rst | 41 ++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 docs/_static/usb_host/poweron-timings.png diff --git a/docs/_static/usb_host/poweron-timings.png b/docs/_static/usb_host/poweron-timings.png new file mode 100644 index 0000000000000000000000000000000000000000..867253da18d734fef4d86af9f0628431169986df GIT binary patch literal 39711 zcmeFZ`6HC?`!;^tB70IPTPkT}-*=%!_J*;qN!j;p>=fE8F_!GI3}cslFGa>04VuA_ zh7iMyCHwc*>+^nn-p}`^=MQ-Lt+=o2ytd;!&*MDKUKr@zW1_!A4*&quea+iY0HA>Y z0A(rNDezwmI7;sTKm>6Awwh6(_3vrzFG4Gwyqn6CRC98JZxly7s&z`DwL0EiGG?E2H|Uw_jr9&MFmT-?~jF$9i5p%9CAmRzke*^4+uQ z#v&Q4K4Mg~*v{p!z0hTNSo+)t|wOom+tn6>h>AzqDTJrz?{NL}uE!x)U zG>-t@FyWX#tz60``go<|7r7nbN5?rcs>i1BD=V^LHOCrGoP~VWH<9x#ll~j+pA6!u zz!@U$>JxYHNP{J(#^Xw^-2LS;kMJUTNo`~vIfri%!ROF+4||HhI{)K6b9bh9hxirh z_F&eaSmJ%n)8N;)RKbb$TNj5#`3U4i?<7llss4%1qlIptwiyoFnJ>cX=cg0po!{e}IfZq4t|!mTF4&b2~n(2Be?c7?lQaLDGXSxB6|oi(FP z=+@R7&aK7J?0sUH zo2Oki$}P+7y^>~}^PWj3QZ#`!SX=WV zw0?W6ZgHnly(`8+Q==n?(6roMYb(d1(a)z+aNw>k*k{fRnHtoV9iI`c@OT!7bQ_V9 zs)w0JC*Se=!$Bg5E>fJFcZSco)qr8uwl;tIl}qZS+L*v$3YbRehxvWwaJ~5-__U;F zThL6{i$TNnbCH$@oy%}V-EfYyD72DX1!Z5iM6MQN$NfmVa{Hqrx0V>hnT2fC_vb%# zP=}O$vd8p|I5pclGMJ9J@Ugrk8*JC<^{zq($fRsozAM80Fa>q{CtR^3ByFi3*MY1% zfU%m_o9sacm08SJinMaWb=nKk)Set&1nmS2OjvM3{FLuy1a18CB(D{|P85kMt8MYO zC><=GtxNJ-PyYBp$@Hf7qaKC&ihIdJe1r=a2_D>7t9ckMF=9#-VUP`{aRuc{l46ig2(8Ay|k?yBlQa-`9u5adp#meaxuRGgZ;%s<-<;=U`)q_ld&BQW2`t3FV?bN|P_$i&}CoJrLi*hCXP9yaKLo5bCw3HFd|ZJNhKn-2Zt zf5t}=nlC{gV}2UmA8Y$LThG_7i>pl=Yh+qXln@Tk;C!b$dax_A^!`8`Uk^p4ZJ#|c zy`*l7dRpq|+(glODWpzNA#yj1HmBZ;i62rRWgS$ZYcY~0C2W{k$>(6LCD!g?om89N z2E)}NcihX?tTNtRbEx=fui;0$?zC4-gb*p(xoA&DjpL`t%)*rqL^XEsIq(>#sM%G# z^g7RI?VKz@SrgbU^kMS+NPVb(vIw7pFVv^fJv;PqhX|ZyCaq3*zlhl>Ln>6iuM|mE zeN$yPCeznBQ9M#}U*@oEHD!m+`X7V~D(z$_T5yI1>F3+>JWlywBk$(8ELQCOXUbf9 zU8yj{tRta*2F0nc>BO*?)ZpOeEnfI~I6h)?bC(d@kV3DE%3EJQ+HHWFZ3o55E+)Ov z#SeRNhP+OycEYjeS}|~BV$bW2jcYkCC?lUJCkoU|VHO{+Y>(RS&b7ZMlt+Cv%*+-q zoR~oMchG?Ay)`$rq^-dLL(x1CSWJqKow)K#!33^C`*2@>apFBRQ(VRR6{`qkjkD&5 zS-TvmP_sKqQ8j|s`iqrC`%mDs6IK#a1j14{Mt(M0&L0<$(dJ zZf8#JMhklS%yHSO4x3Q_hV1^W@KT*<=@6!1l_6QIY6-Rw(|(F=SFOyvdlx24U{HL|ROGv0p1}?uYheGiKcjvJNF_)>WvKCq-vm z`m2MFCQU!qI_%m+e>I~E;>x8N5yoRSd~5;+3`N2(kwOczp6EV90KiHry%?g33bfnf2?LB=x{;9nqQIfQ}M(+5mjh~SbLQy&hY(8qBa?UiAgA;Ex0{<)LQH* zR-tbQaE#VYpyC=!R92)y#oL_re#?lvHB|Pl8ppg8aN-_b$<>Ap*k9Ds_pB1Whvm`5 z$)|O6u`KyX5Yi2%oGs~gd9Y>YD(MrW<^N5Zu4(ljq>4&ZnXUq#=}%@ z!2J&BJ*(Z{;HDH-A~L^dpuaiYR^d`S7w9Be?ridV=m)KFsDFY0McfJkbtiSTbh;Yh zxLlY&Tuaq8n57USXak07fh9_XuRHrU`V2MhvFoDzKl})7ITaqe^l(p`cu~zBpGU+h zd|u2(HXESD>lIBp!Z1#U!^)%ErvC2sBRh1}>fnL^TYnJ3`L?iosK#%pGj;_6;|;+2 zmF{msgX#pt>Ni#LAB$kG7+rHvr0r#T}ef{0l`=%Lcd=6*o?wniqp}X+m(V6x3jHC7A zkPw|*+EjQ7N$@~1?$xmBQ77GfPG2*m52UwyKgXt=a>CV2FW0Pmc(*r<8N$+^)iCUp z!O}Th_uDOBxDj-!fpdX$V%guspX@4h6&MXpK`wu0^J9YGP{Fx4%PHmX$}nmqG!a%$ zG&H?9KU8$}J*!wxF8-!<0x$GZTJ|qP&B?`k<4)O^v|@^ZdLf!iL?7#Tp>G3?Hs@~h zG#GY-#t12norO}ic`8w-52aiC(qwHqy3)w24d%_x_s|OBd#tuWd4@)(Vx za{Gk#xfPwUKYVI<_}en)$yh45bemDHN`mN&Wc$pvFN!PIqthGrjIV!av*A3{-7WNO z8q(%~)F{GzkHS{B=haD@qo!v${Lu`5aslumXm$2;G%$*Q5HRaudBn zu^k1{Y)}bW%+soA@?yh01aO^Bk4Sc_9R|w$g$oCswif4AFs^Dj_^lhY6xX)|Xe8h? zqB^u!eEZ-X#iOcboSC|q_WnN5nnjua8SDaPEKH3b1lY2ETHaO#Vfofl`Y0ORz72r6+-X<-dmM(+} zMJ|7bStOkKlu#Ia%9sP<=BmlF`UGa4sJNszi$Dc4ccX~kz(}HE5$F`Bw6at~& zpG3e`EpNeAZA_aQLfLruwB~q+S$el$P}mCh zJVX5F8i3D6L+~p{cQf^)OO3ejG}<`GtV{4P-5yD-IzuI;$2Cz)&YGUu$7-VVt9Xf0 z)k^=K((xZu%YI6t#7`oI-!>Xzi4~YT1Lf?E(gMaG={QO~wr=QCp&HSE4YocJGu2fc z6O5=)aS%JLeYx;aJoGG|!|C9)G9vs^guhp(!TH%=TC=xpwl4yChV8SPXIu9QX*SZX*1s7s7L>Jk~e2XWFX;ccVkFg-wmyFtM4$x!z0z&Sn}fXWX-KHU26X&ZZ}eV+8*K7lknr zQs{aK#mxAaRb;v!Vzh6HJJp-G>QiH-B2DueyqQXQQ|K2CdhOdi{-QP(?<*=qR}7Uo z6u49y4n`Owb~(>Ne|Oytn5o`-Eie&;b6i}pY86*`onR}T zd%XeE&uPgFF;sN1pudsayoqhCA8~hC>8IyT=;vL8Ug88YUZ0NZ8R(Y*FFdB19eN#7 zQtr;oX=Jys1YFd(IC-b*LX|WO!zm$hWE1^tcTsw(&UlQwrzk@FXpODz@k($_kX@Sx z>Xfy6W<#QPKZS!tY+mhw^|+p9pI{cx<kMyT>QAgaZ_v_QNyoW{#OB)Zk9uKi>@UT$0Am-= zUW)sBG$YZ6&+aU-K|7v>4i-`Ndy2E{UAg^wqV}?=sGDiZh^u9cP}l2Davm8Iw^UkD zOHw9v)wy7neVUqrk1XR|lB4q%31|&13I|0sLa0&aRns@Vma9Ro$m|ox^drZ?QNSaL zdari)?>v1}4MvQAl#KYV+Gs%*R^?@A(wb|1?NG(s$2rLRnC9W4ht@MIT(&u==g8y6 zX`SpcM6Q-cj8frmOF;?YC;dUvP8k9$ienN+D?vrq7SEp+^r#v>V$^;UzaNG6!VZ-I zQxpHVfRX6Lq&t02+Zyue6KmNLcSGR6(r;=ENcfgpE2e}EAj2;P&>um+z(w9R9V5aX z)$^6nhlM4?u*FY2n)^|BqSPp~clmx@e44PR3x>US zH2dB?Qky~k*>{)>=T-E!82%3NbXgJJ=Qj#Dz2?mKqf{Z_{6ph0Bx)Ygr6Zf;@GHPc zGdIAxkw^85k%T~au1kiB0E6N%_ukKyyr07^QChaoQE@+FhQ@x~z3=i*=y*ey!s3Fi z+pUERtqa8yP#7uX2x&Abag<9rP;T`_X)_om+|DsXW;AUy+ENmJB7c-(ADj+LSu^+h z6O-5wq%8Wt453E|Q*&@VCP~}o>#eex42DW68BqZd6<}m~LnEqf9ZLDWnYu^*(*Wve zE-vmhZy%&wkv7t-5A9?7mIekt-CMcp&S>5!1e={!z$Hz<}h|x zUy8)oXn2Ht;B-geX`M0eo;yR$TDvt9CTjDa6G^YqGMC2oz#W)PRdc8h|8N^M zKNB&plZlG^d>Zee?GB#;Y~@i$?-lR-BR3sdKzC97kbJx zTU^ch+<10WgLjG6dnu#XFHgUaB(J&-EQC+D`WwSqoNjn%^_Jr{-Y@4njTtDrxzKS` zMI-p?`@h%y=9(7teC}r5(eT*90w1ikI@z;P#wB}OfmzRN+R+6qlRz<RRdYX3=GbfM2r1$6IiR(DJ1RemY45ppV%G`K z{$p25<4v1RntetpvRpiF=ny_6z1>J#mF~$gv>><0XHQ# zs5)=l9uZjQ`U_-s#msev?*YShyfoi2M`kI$>L$4Efrz|XUcOJh#g%AD zKjN&EVz@_u$Xqow&qKgPY&+7%(xRh6p&NJnxjXn!G?q-p%OC7dbR6x9hRf2ZHS%;E zeLm9vY|zmWF{f)eJP`V45NUJt1|PIDXLCI0(Q#<6PuxD9UB`y+ZLM_=v+NIa8mzHQ zWGN&Zwj-xwRrmcHkB3=^JNnGW$HcYf&QD^op~dtIoDDk}w1adM>o4<28}a(Dcf!}E zG!C_5yP5jKy-bHy!`oOxk8;CXaL1S`{OYk$vvSOH=er(w<>M!W&k1&Wb1S*w`^nt_ zJ1i`+XO6w(MVMk=t;!NU?_gsMHIJ74y4zyx>pxBO3Ot>w={_>#(pZq-8k#t++uO-J z%oQ4LocJVvxqW!7_0UEo>*f)jbjY;AG1IZXzO>GLth#gzGx%=k7XE$p7;E=uk+8_Y z=)!58OEs=aR~Ttcox*8(bxn&_fDiA;Fd|;K>6aCBmIGE6| zRIvQzbM&-OEa^w^YWMjG_}lKI{fXY|;4W+UUNe!&^cv20?wR*w+^^_{D?}Abg=}FO zJI!+fT1&=PJeB2Py@3P$W2Muhr5*UqFb$lVLvy^_WQWT2LBBss`z)PjHFkrl<_?dZ z5aewcG+I<|>`+9MQKvMfDe%h2%C|0dsutF46u~o^dV737j`j4}!}5pi!e{n&W&RWKab=@il)Cf9c`!%!iA}<=2nq)d)s&ie1V@v|(c@FEd5fAB7bkg%ymIK=3T?V5wpK zmQ|D%f9&2XfnoS9d6=VYKxy5y5e$xU&WvRsko^BZaaDf}(qPVHQDqmi|?Xx8~1N@>w~ zru8s@Ajc!hE!qH8=ddj;4x0^FPG2_MRag;o$m1TW7X^SlX9mH>^U!#BP!{S-mi7bp zYmYKpXuqIVyWFCNTJQ)PgdIOjFk2=%fA#nVhz#PwXzc#B8r#AWnwLf|eJD zb(T&(0c`V0dEO|7sUi+GXixH@IRqVN349LHyZFUeR;_g@h;~ushnzTJa6OAjUIm!K zd}29(&R#rDo$tBy7tSvj(qauwICGOiPXXu4g&s7Y3)Oh;>lMI!11SiT^I4QREzmNl z-Tu_0==Kculh>8_3x+h~KA4?9fTzb&pc00vQ%)6+GE4aDVC3J*jpVdo|9k_{z1q`) zQ7|}~75S>w=T>uOB{{u0vn6&ou&RQ(t<3j8__k(h^4uz7aezb_PzA1d} zW+8Pttr{hm*8ln#Mp?~jK`&T!Uron)FxW-EAb&6;;oN^R*8$70L~EZvBli$&{n`&y zrt^BWO>6(?a#0QHpIfYUW%oTtxdZ}ptB59hG zs&UzmDLec6aLrOF4n|K#K~)Ap3Oajrv^e>1ifK#Klv_)cWH9^dc0*qw(pDZ+^zR=I53LkXGYXHh-ulT$u)~KNmMt6}?e>P4 z=XJ{IafR#mE9(JbGyloWPMNmXX16r(pYcUDQ=~!qFZO45AIZB09ZH->T25 z^bgGoE0??uZQGkSl9t93dAB%Y>R-^>Y_yu2_dQy?8nN_W$!os`n(onPBvI-2HlE=2 zUHKjRc=IQ%1S%52FX$*eR))}K7^IN$aOM5)f$pTIXm)51QF?U+dAP1CFDzzBjo84w z?5gFGHCg%tbOru>eka>uyF~)4O-nC*ub%I2*M3+uDj3TAWn#RvVMeyC`L)AZ>+gYH z=u`A$CmHWrpW6xYvsug>qV>Bih@lb??8YvRNu_qZ==d$!wR}SFpk%PVw&l#}W~V

hoK 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 literal 0 HcmV?d00001 diff --git a/docs/en/api-reference/peripherals/usb_host.rst b/docs/en/api-reference/peripherals/usb_host.rst index 2f0756b43ff4..5007bea0e310 100644 --- a/docs/en/api-reference/peripherals/usb_host.rst +++ b/docs/en/api-reference/peripherals/usb_host.rst @@ -390,6 +390,47 @@ UVC * A host class driver for the USB Video Device Class is distributed as a managed component via the `ESP-IDF Component Registry `__. * The :example:`peripherals/usb/host/uvc` example demonstrates the usage of the UVC host driver to receive a video stream from a USB camera and optionally forward that stream over Wi-Fi. +.. ---------------------------------------------- USB Host Menuconfig -------------------------------------------------- + +Host Stack Configuration +------------------------ + +Non-Compliant Device Support +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To support USB devices that are non-compliant in various scenarios or exhibit specific behaviors it is possible to configure the USB Host stack. + +As a USB device may be hot-plugged, it is essential to have the configurable delays between power switching and device attachment, and when the device's internal power has stabilized. + +Enumeration Configuration +""""""""""""""""""""""""" + +During the process of enumerating connected USB devices, several timeout values ensure the proper functioning of the device. + +.. figure:: ../../../_static/usb_host/poweron-timings.png + :align: center + :alt: USB Root Hub Power-on and Connection Events Timing + :figclass: align-center + + USB Root Hub Power-on and Connection Events Timing + +The figure above shows all the timeouts associated with both turning on port power with a device connected and hot-plugging a device. + +* After a port is reset or resumed, the USB System Software is expected to provide a “recovery” interval of 10 ms before the device attached to the port is expected to respond to data transfers. +* After the reset/resume recovery interval, if a device receives a SetAddress() request, the device must be able to complete processing of the request and be able to successfully complete the Status stage of the request within 50 ms. +* After successful completion of the Status stage, the device is allowed a SetAddress() recovery interval of 2 ms. + +.. note:: + + For more details regarding connection event timings, please refer to the Universal Serial Bus 2.0 specification, chapter 7.1.7.3 "Connect and Disconnect Signaling". + +Configurable parameters of the USB host stack can be configured with multiple options via Menuconfig. + +* For Debounce delay refer to :ref:`CONFIG_USB_HOST_DEBOUNCE_DELAY_MS` +* For Reset hold interval refer to :ref:`CONFIG_USB_HOST_RESET_HOLD_MS` +* For Reset recovery interval refer to :ref:`CONFIG_USB_HOST_RESET_RECOVERY_MS` +* Fer SetAddress() recovery interval refer to: :ref:`CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS` + .. -------------------------------------------------- API Reference ---------------------------------------------------- API Reference From 442f8021026ccc5f7d7433a357b55af1e05e3875 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Wed, 1 Nov 2023 17:31:02 +0530 Subject: [PATCH 131/161] fix(wpa_supplicant): Correct iv lenght passed in mbedtls_cipher_set_iv() --- .../esp_supplicant/src/crypto/crypto_mbedtls.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c index 9790a0b3dd84..97b0df675fb0 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c @@ -506,16 +506,19 @@ static int crypto_init_cipher_ctx(mbedtls_cipher_context_t *ctx, return -1; } - if (mbedtls_cipher_setkey(ctx, key, key_len * 8, operation) != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_setkey returned error"); + ret = mbedtls_cipher_setkey(ctx, key, key_len * 8, operation); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_cipher_setkey returned error=%d", ret); return -1; } - if (mbedtls_cipher_set_iv(ctx, iv, cipher_info->MBEDTLS_PRIVATE(iv_size)) != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_set_iv returned error"); + ret = mbedtls_cipher_set_iv(ctx, iv, cipher_info->MBEDTLS_PRIVATE(iv_size) << MBEDTLS_IV_SIZE_SHIFT); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_cipher_set_iv returned error=%d", ret); return -1; } - if (mbedtls_cipher_reset(ctx) != 0) { - wpa_printf(MSG_ERROR, "mbedtls_cipher_reset() returned error"); + ret = mbedtls_cipher_reset(ctx); + if (ret != 0) { + wpa_printf(MSG_ERROR, "mbedtls_cipher_reset() returned error=%d", ret); return -1; } From ab55cd05c25ec8b1454ed42db12d05d76ccabb9f Mon Sep 17 00:00:00 2001 From: gongyantao Date: Wed, 1 Nov 2023 20:17:48 +0800 Subject: [PATCH 132/161] fix(bt/bluedroid): fix loadprohibited error in spp vfs acceptor example --- .../bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c | 2 +- .../bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c index 47cbbd0ce502..f944aa729e66 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_acceptor/main/spp_task.c @@ -112,7 +112,7 @@ void spp_task_task_shut_down(void) void spp_wr_task_start_up(spp_wr_task_cb_t p_cback, int fd) { - xTaskCreate(p_cback, "write_read", 2048, (void *)fd, 5, NULL); + xTaskCreate(p_cback, "write_read", 4096, (void *)fd, 5, NULL); } void spp_wr_task_shut_down(void) { diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.c b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.c index 47cbbd0ce502..f944aa729e66 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.c +++ b/examples/bluetooth/bluedroid/classic_bt/bt_spp_vfs_initiator/main/spp_task.c @@ -112,7 +112,7 @@ void spp_task_task_shut_down(void) void spp_wr_task_start_up(spp_wr_task_cb_t p_cback, int fd) { - xTaskCreate(p_cback, "write_read", 2048, (void *)fd, 5, NULL); + xTaskCreate(p_cback, "write_read", 4096, (void *)fd, 5, NULL); } void spp_wr_task_shut_down(void) { From 3fb23c85b6dd03d19b45004211c44965204b5e48 Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Fri, 27 Oct 2023 17:35:58 +0200 Subject: [PATCH 133/161] Revert "fix(freertos/idf): Add workaround for same priority preemption in xTaskIncrementTick()" This reverts commit 6c6a6ad44a52cd0b706cb23aee4c1c31fb76bf1f. --- components/freertos/FreeRTOS-Kernel/tasks.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index cbd9eb48aa7a..6075f88f1e51 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -3267,9 +3267,7 @@ BaseType_t xTaskIncrementTick( void ) * 0, we only need to context switch if the unblocked * task can run on core 0 and has a higher priority * than the current task. */ - - /* ">" changed to ">="" due to IDF incompatibility (IDF-8428) */ - if( ( taskIS_AFFINITY_COMPATIBLE( 0, pxTCB->xCoreID ) == pdTRUE ) && ( pxTCB->uxPriority >= pxCurrentTCBs[ 0 ]->uxPriority ) ) + if( ( taskIS_AFFINITY_COMPATIBLE( 0, pxTCB->xCoreID ) == pdTRUE ) && ( pxTCB->uxPriority > pxCurrentTCBs[ 0 ]->uxPriority ) ) { xSwitchRequired = pdTRUE; } From 0a0c7ef40f894399de3b9019d4cdf76af4c1876f Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Fri, 8 Sep 2023 16:13:06 +0200 Subject: [PATCH 134/161] fix(freertos/idf): Updated IDLE task names for each core to have the coreID as a suffix This commit updates the IDLE task names for each core by concatenating the respective coreIDs to the task names. Closes https://github.com/espressif/esp-idf/issues/12204 --- .../freertos/FreeRTOS-Kernel/idf_changes.md | 6 + components/freertos/FreeRTOS-Kernel/tasks.c | 124 +++++++++++++++--- 2 files changed, 109 insertions(+), 21 deletions(-) diff --git a/components/freertos/FreeRTOS-Kernel/idf_changes.md b/components/freertos/FreeRTOS-Kernel/idf_changes.md index 752d8fbbcde5..28385a40c555 100644 --- a/components/freertos/FreeRTOS-Kernel/idf_changes.md +++ b/components/freertos/FreeRTOS-Kernel/idf_changes.md @@ -193,3 +193,9 @@ List of changes made to Vanilla FreeRTOS V10.5.1 header files to allow for build - In functions/macros that are not meant to be directly called by users (i.e., internal), such as the various `Generic` variants of functions - Some types/functions/macros are manually documented, thus are documented with regular comment blocks (i.e., `/* */`) instead of doxygen comment blocks (i.e., `/** */`). Some of these blocks are changed into doxygen blocks. + +## Changes backported to IDF-FreeRTOS Kernel from upstream kernel beyond v10.5.1 LTS release + +### tasks.c + +- Backported a change where the IDLE tasks are created with the core ID as a suffix in the task name. diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c index cbd9eb48aa7a..8cda33056be7 100644 --- a/components/freertos/FreeRTOS-Kernel/tasks.c +++ b/components/freertos/FreeRTOS-Kernel/tasks.c @@ -596,6 +596,11 @@ PRIVILEGED_DATA static portMUX_TYPE xKernelLock = portMUX_INITIALIZER_UNLOCKED; /* File private functions. --------------------------------*/ +/* + * Creates the idle tasks during scheduler start. + */ +static BaseType_t prvCreateIdleTasks( void ); + /** * Utility function to check whether a yield (on either core) is required after * unblocking (or changing the priority of) a particular task. @@ -2278,14 +2283,73 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) #endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ /*-----------------------------------------------------------*/ -void vTaskStartScheduler( void ) +static BaseType_t prvCreateIdleTasks( void ) { - BaseType_t xReturn; - UBaseType_t x; + BaseType_t xReturn = pdPASS; + BaseType_t xCoreID; - /* Create idle tasks that are pinned to each core */ - for( x = 0; x < configNUMBER_OF_CORES; x++ ) +#if ( configNUMBER_OF_CORES > 1 ) + char cIdleName[ configMAX_TASK_NAME_LEN ]; +#endif /* #if ( configNUMBER_OF_CORES > 1 ) */ + + /* Add each idle task at the lowest priority. */ + for( xCoreID = ( BaseType_t ) 0; xCoreID < ( BaseType_t ) configNUMBER_OF_CORES; xCoreID++ ) { + #if ( configNUMBER_OF_CORES > 1 ) + { + BaseType_t x; + + if( xReturn == pdFAIL ) + { + /* TODO: IDF-8240 - Memory leaks occur if IDLE task creation fails on some core + * as we do not free memory for the successfully created IDLE tasks. */ + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + for( x = ( BaseType_t ) 0; x < ( BaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + cIdleName[ x ] = configIDLE_TASK_NAME[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + * configMAX_TASK_NAME_LEN characters just in case the memory after the + * string is not accessible (extremely unlikely). */ + if( cIdleName[ x ] == ( char ) 0x00 ) + { + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Append the idle task number to the end of the name if there is space. */ + if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN ) + { + cIdleName[ x ] = ( char ) ( xCoreID + '0' ); + x++; + + /* And append a null character if there is space. */ + if( x < ( BaseType_t ) configMAX_TASK_NAME_LEN ) + { + cIdleName[ x ] = '\0'; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ + /* Add the idle task at the lowest priority. */ #if ( configSUPPORT_STATIC_ALLOCATION == 1 ) { @@ -2296,43 +2360,61 @@ void vTaskStartScheduler( void ) /* The Idle task is created using user provided RAM - obtain the * address of the RAM then create the idle task. */ vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); - xIdleTaskHandle[ x ] = xTaskCreateStaticPinnedToCore( prvIdleTask, - configIDLE_TASK_NAME, - ulIdleTaskStackSize, - ( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */ - portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ - pxIdleTaskStackBuffer, - pxIdleTaskTCBBuffer, /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ - x ); - - if( xIdleTaskHandle[ x ] != NULL ) + xIdleTaskHandle[ xCoreID ] = xTaskCreateStaticPinnedToCore( prvIdleTask, + #if ( configNUMBER_OF_CORES > 1 ) + cIdleName, + #else /* #if ( configNUMBER_OF_CORES > 1 ) */ + configIDLE_TASK_NAME, + #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ + ulIdleTaskStackSize, + ( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */ + portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ + pxIdleTaskStackBuffer, + pxIdleTaskTCBBuffer, /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + xCoreID ); + + if( xIdleTaskHandle[ xCoreID ] != NULL ) { xReturn = pdPASS; } else { xReturn = pdFAIL; - break; } } #else /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ { /* The Idle task is being created using dynamically allocated RAM. */ xReturn = xTaskCreatePinnedToCore( prvIdleTask, - configIDLE_TASK_NAME, + #if ( configNUMBER_OF_CORES > 1 ) + cIdleName, + #else /* #if ( configNUMBER_OF_CORES > 1 ) */ + configIDLE_TASK_NAME, + #endif /* #if ( configNUMBER_OF_CORES > 1 ) */ configMINIMAL_STACK_SIZE, ( void * ) NULL, portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ &xIdleTaskHandle[ xCoreID ], /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ xCoreID ); - if( xReturn == pdFAIL ) - { - break; - } + } #endif /* configSUPPORT_STATIC_ALLOCATION */ } + return xReturn; +} + +/*-----------------------------------------------------------*/ + +void vTaskStartScheduler( void ) +{ + BaseType_t xReturn; + + /* The code for prvCreateIdleTasks() has been backported from the upstream + * FreeRTOS-Kernel source. The reference for the same is on the mainline + * at the commit id# 2f94b181a2f049ec342deba0927bed51f7174ab0. */ + xReturn = prvCreateIdleTasks(); + #if ( configUSE_TIMERS == 1 ) { if( xReturn == pdPASS ) From 659748748f8245a88be041d0ffb7c2c58d1fcfe3 Mon Sep 17 00:00:00 2001 From: Erhan Kurubas Date: Wed, 1 Nov 2023 19:41:56 +0100 Subject: [PATCH 135/161] fix(coredump-info): set default gdb timeout as 3 seconds --- tools/idf_py_actions/debug_ext.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/idf_py_actions/debug_ext.py b/tools/idf_py_actions/debug_ext.py index 65619bef0ee5..db7083c46961 100644 --- a/tools/idf_py_actions/debug_ext.py +++ b/tools/idf_py_actions/debug_ext.py @@ -584,7 +584,7 @@ def coredump_debug(action: str, gdb_timeout_sec_opt = { 'names': ['--gdb-timeout-sec'], 'type': INT, - 'default': 1, + 'default': 3, 'help': 'Overwrite the default internal delay for gdb responses', } fail_if_openocd_failed = { From 4f5773181df8b0de79b190c535bfd009ce8cf873 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Wed, 1 Nov 2023 19:14:12 +0800 Subject: [PATCH 136/161] fix(i2s): fix pdm rx high pass filter cut off coeff --- components/driver/i2s/i2s_pdm.c | 25 +++++++++++++++---------- components/hal/i2s_hal.c | 2 +- components/hal/include/hal/i2s_hal.h | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/components/driver/i2s/i2s_pdm.c b/components/driver/i2s/i2s_pdm.c index 3ec435621343..856cf43a1fc2 100644 --- a/components/driver/i2s/i2s_pdm.c +++ b/components/driver/i2s/i2s_pdm.c @@ -103,10 +103,14 @@ static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_ /* Share bck and ws signal in full-duplex mode */ i2s_ll_share_bck_ws(handle->controller->hal.dev, handle->controller->full_duplex); + /* Update the mode info: slot configuration */ + i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info; + memcpy(&(pdm_tx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_tx_slot_config_t)); + portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply PDM format */ bool is_slave = handle->role == I2S_ROLE_SLAVE; - i2s_hal_slot_config_t *slot_hal_cfg = (i2s_hal_slot_config_t *)slot_cfg; + i2s_hal_slot_config_t *slot_hal_cfg = (i2s_hal_slot_config_t *)(&(pdm_tx_cfg->slot_cfg)); #if SOC_I2S_HW_VERSION_2 /* Times 10 to transform the float type to integer because we should avoid float type in hal */ slot_hal_cfg->pdm_tx.hp_cut_off_freq_hzx10 = (uint32_t)(slot_cfg->hp_cut_off_freq_hz * 10); @@ -114,10 +118,6 @@ static esp_err_t i2s_pdm_tx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_ i2s_hal_pdm_set_tx_slot(&(handle->controller->hal), is_slave, slot_hal_cfg); portEXIT_CRITICAL(&g_i2s.spinlock); - /* Update the mode info: slot configuration */ - i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info; - memcpy(&(pdm_tx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_tx_slot_config_t)); - return ESP_OK; } @@ -389,16 +389,21 @@ static esp_err_t i2s_pdm_rx_set_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_ /* Share bck and ws signal in full-duplex mode */ i2s_ll_share_bck_ws(handle->controller->hal.dev, handle->controller->full_duplex); + /* Update the mode info: slot configuration */ + i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info; + memcpy(&(pdm_rx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_rx_slot_config_t)); + portENTER_CRITICAL(&g_i2s.spinlock); /* Configure the hardware to apply PDM format */ bool is_slave = (handle->role == I2S_ROLE_SLAVE) | handle->controller->full_duplex; - i2s_hal_pdm_set_rx_slot(&(handle->controller->hal), is_slave, (i2s_hal_slot_config_t *)slot_cfg); + i2s_hal_slot_config_t *slot_hal_cfg = (i2s_hal_slot_config_t *)(&(pdm_rx_cfg->slot_cfg)); +#if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER + /* Times 10 to transform the float type to integer because we should avoid float type in hal */ + slot_hal_cfg->pdm_rx.hp_cut_off_freq_hzx10 = (uint32_t)(slot_cfg->hp_cut_off_freq_hz * 10); +#endif + i2s_hal_pdm_set_rx_slot(&(handle->controller->hal), is_slave, slot_hal_cfg); portEXIT_CRITICAL(&g_i2s.spinlock); - /* Update the mode info: slot configuration */ - i2s_pdm_rx_config_t *pdm_rx_cfg = (i2s_pdm_rx_config_t *)handle->mode_info; - memcpy(&(pdm_rx_cfg->slot_cfg), slot_cfg, sizeof(i2s_pdm_rx_slot_config_t)); - return ESP_OK; } diff --git a/components/hal/i2s_hal.c b/components/hal/i2s_hal.c index ae00f259ee9e..56e7e225d5bc 100644 --- a/components/hal/i2s_hal.c +++ b/components/hal/i2s_hal.c @@ -255,7 +255,7 @@ void i2s_hal_pdm_set_rx_slot(i2s_hal_context_t *hal, bool is_slave, const i2s_ha #if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER uint32_t param0; uint32_t param5; - s_i2s_hal_get_cut_off_coef(slot_cfg->pdm_rx.hp_cut_off_freq_hz, ¶m0, ¶m5); + s_i2s_hal_get_cut_off_coef(slot_cfg->pdm_rx.hp_cut_off_freq_hzx10, ¶m0, ¶m5); i2s_ll_rx_enable_pdm_hp_filter(hal->dev, slot_cfg->pdm_rx.hp_en); i2s_ll_rx_set_pdm_hp_filter_param0(hal->dev, param0); i2s_ll_rx_set_pdm_hp_filter_param5(hal->dev, param5); diff --git a/components/hal/include/hal/i2s_hal.h b/components/hal/include/hal/i2s_hal.h index 02e325694937..2be2180b9d03 100644 --- a/components/hal/include/hal/i2s_hal.h +++ b/components/hal/include/hal/i2s_hal.h @@ -94,7 +94,7 @@ typedef struct { i2s_pdm_slot_mask_t slot_mask; /*!< Choose the slots to activate */ #if SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER bool hp_en; /*!< High pass filter enable */ - float hp_cut_off_freq_hz; /*!< High pass filter cut-off frequency, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */ + uint32_t hp_cut_off_freq_hzx10; /*!< High pass filter cut-off frequency times 10, range 23.3Hz ~ 185Hz, see cut-off frequency sheet above */ uint32_t amplify_num; /*!< The amplification number of the final conversion result */ #endif // SOC_I2S_SUPPORTS_PDM_RX_HP_FILTER From 843e07b2d583ef32fd9ea4cd8747ec0fb36f5c5b Mon Sep 17 00:00:00 2001 From: gaoxu Date: Thu, 2 Nov 2023 11:33:06 +0800 Subject: [PATCH 137/161] docs(adc): added adc calibration doc on h2 --- .../esp32c6/include/esp_efuse_rtc_calib.h | 2 +- .../esp32h2/include/esp_efuse_rtc_calib.h | 7 +++---- docs/docs_not_updated/esp32h2.txt | 1 - .../peripherals/adc_calibration.rst | 18 +++++++----------- .../peripherals/adc_calibration.rst | 10 +++------- 5 files changed, 14 insertions(+), 24 deletions(-) diff --git a/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h index e2cb7610fd15..9e65f777b5c8 100644 --- a/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h @@ -16,7 +16,7 @@ extern "C" { #define ESP_EFUSE_ADC_CALIB_VER2 2 #define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER1 #define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER2 -#define VER2IDX(ver) (ver - 1) // Version number to index number of the array +#define VER2IDX(ver) ((ver) - 1) // Version number to index number of the array /** * @brief Get the RTC calibration efuse version * diff --git a/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h index d66708bb1c65..2101902a7be8 100644 --- a/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h @@ -15,7 +15,7 @@ extern "C" { #define ESP_EFUSE_ADC_CALIB_VER1 1 #define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER1 #define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER1 -#define VER2IDX(ver) (ver - 1) // Version number to index number of the array +#define VER2IDX(ver) ((ver) - 1) // Version number to index number of the array /** * @brief Get the RTC calibration efuse version @@ -38,10 +38,9 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a * @brief Get the channel specific calibration compensation * * @param version Version of the stored efuse - * @param adc_unit ADC unit. Not used, for compatibility. On ESP32H2, for calibration v1, both ADC units use the same init code (calibrated by ADC1) - * @param adc_channel ADC channel number + * @param adc_unit ADC unit. Not used, for compatibility. ESP32H2 only supports one ADC unit * @param atten Attenuation of the init code - * @return The channel calibration compensation value + * @return The channel calibration compensation value */ int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten); diff --git a/docs/docs_not_updated/esp32h2.txt b/docs/docs_not_updated/esp32h2.txt index fb3d48388c9d..eab138e1bbd0 100644 --- a/docs/docs_not_updated/esp32h2.txt +++ b/docs/docs_not_updated/esp32h2.txt @@ -5,7 +5,6 @@ api-guides/dfu api-guides/index api-reference/peripherals/spi_features api-reference/peripherals/sdio_slave -api-reference/peripherals/adc_calibration api-reference/peripherals/dedic_gpio api-reference/peripherals/sd_pullup_requirements api-reference/peripherals/index diff --git a/docs/en/api-reference/peripherals/adc_calibration.rst b/docs/en/api-reference/peripherals/adc_calibration.rst index 53903e429180..64ee23ca1479 100644 --- a/docs/en/api-reference/peripherals/adc_calibration.rst +++ b/docs/en/api-reference/peripherals/adc_calibration.rst @@ -47,9 +47,9 @@ If you use your custom ADC calibration schemes, you could either modify this fun .. only:: esp32 - There is also a configuration :cpp:member:`adc_cali_line_fitting_config_t::default_vref`. Normally this can be simply set to 0. Line Fitting scheme does not rely on this value. However, if the Line Fitting scheme required eFuse bits are not burnt on your board, the driver will rely on this value to do the calibration. + There is also a configuration :cpp:member:`adc_cali_line_fitting_config_t::default_vref`. Normally this can be simply set to 0. Line Fitting scheme does not rely on this value. However, if the Line Fitting scheme required eFuse bits are not burned on your board, the driver will rely on this value to do the calibration. - You can use :cpp:func:`adc_cali_scheme_line_fitting_check_efuse` to check the eFuse bits. Normally the Line Fitting scheme eFuse value is :c:macro:`ADC_CALI_LINE_FITTING_EFUSE_VAL_EFUSE_TP` or :c:macro:`ADC_CALI_LINE_FITTING_EFUSE_VAL_EFUSE_VREF`. This means the Line Fitting scheme uses calibration parameters burnt in the eFuse to do the calibration. + You can use :cpp:func:`adc_cali_scheme_line_fitting_check_efuse` to check the eFuse bits. Normally the Line Fitting scheme eFuse value is :c:macro:`ADC_CALI_LINE_FITTING_EFUSE_VAL_EFUSE_TP` or :c:macro:`ADC_CALI_LINE_FITTING_EFUSE_VAL_EFUSE_VREF`. This means the Line Fitting scheme uses calibration parameters burned in the eFuse to do the calibration. When the Line Fitting scheme eFuse value is :c:macro:`ADC_CALI_LINE_FITTING_EFUSE_VAL_DEFAULT_VREF`, you need to set the :cpp:member:`esp_adc_cali_line_fitting_init::default_vref`. Default vref is an estimate of the ADC reference voltage provided as a parameter during calibration. @@ -57,7 +57,7 @@ If you use your custom ADC calibration schemes, you could either modify this fun .. only:: esp32s2 - This function may fail due to reasons such as :c:macro:`ESP_ERR_INVALID_ARG` or :c:macro:`ESP_ERR_NO_MEM`. Especially, when the function returns :c:macro:`ESP_ERR_NOT_SUPPORTED`, this means the calibration scheme required eFuse bits are not burnt on your board. + This function may fail due to reasons such as :c:macro:`ESP_ERR_INVALID_ARG` or :c:macro:`ESP_ERR_NO_MEM`. Especially, when the function returns :c:macro:`ESP_ERR_NOT_SUPPORTED`, this means the calibration scheme required eFuse bits are not burned on your board. .. code:: c @@ -82,7 +82,7 @@ If you use your custom ADC calibration schemes, you could either modify this fun ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle)); -.. only:: esp32c3 or esp32s3 or esp32c6 +.. only:: esp32c3 or esp32s3 or esp32c6 or esp32h2 ADC Calibration Curve Fitting Scheme ```````````````````````````````````` @@ -90,14 +90,14 @@ If you use your custom ADC calibration schemes, you could either modify this fun {IDF_TARGET_NAME} supports :c:macro:`ADC_CALI_SCHEME_VER_CURVE_FITTING` scheme. To create this scheme, set up :cpp:type:`adc_cali_curve_fitting_config_t` first. - .. only:: not esp32c6 + .. only:: esp32c3 or esp32s3 - :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`, the ADC that your ADC raw results are from. - :cpp:member:`adc_cali_curve_fitting_config_t::chan`, this member is kept here for extensibility. The calibration scheme only differs by attenuation, there is no difference among different channels. - :cpp:member:`adc_cali_curve_fitting_config_t::atten`, ADC attenuation that your ADC raw results use. - :cpp:member:`adc_cali_curve_fitting_config_t::bitwidth`, bit width of ADC raw result. - .. only:: esp32c6 + .. only:: esp32c6 or esp32h2 - :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`, the ADC that your ADC raw results are from. - :cpp:member:`adc_cali_curve_fitting_config_t::chan`, the ADC channel that your ADC raw results are from. The calibration scheme not only differs by attenuation but is also related to the channels. @@ -111,7 +111,7 @@ If you use your custom ADC calibration schemes, you could either modify this fun When the function :cpp:func:`adc_cali_create_scheme_curve_fitting` returns :c:macro:`ESP_ERR_NOT_SUPPORTED`, this means the calibration scheme required eFuse bits are not correct on your board. - ESP-IDF provided ADC calibration scheme is based on the values in certain ADC calibration related on-chip eFuse bits. Espressif guarantees that these bits are burnt during module manufacturing, so you don't have to burn these eFuses bits yourself. + ESP-IDF provided ADC calibration scheme is based on the values in certain ADC calibration related on-chip eFuse bits. Espressif guarantees that these bits are burned during module manufacturing, so you don't have to burn these eFuses bits yourself. If you see such an error, please contact us at `Technical Inquiries `__ website. @@ -141,10 +141,6 @@ If you use your custom ADC calibration schemes, you could either modify this fun ESP_ERROR_CHECK(adc_cali_delete_scheme_curve_fitting(handle)); -.. only:: esp32h2 - - There is no supported calibration scheme yet. - .. note:: If you want to use your custom calibration schemes, you could provide a creation function to create your calibration scheme handle. Check the function table ``adc_cali_scheme_t`` in ``components/esp_adc/interface/adc_cali_interface.h`` to know the ESP ADC calibration interface. diff --git a/docs/zh_CN/api-reference/peripherals/adc_calibration.rst b/docs/zh_CN/api-reference/peripherals/adc_calibration.rst index df7b345c3916..b2bbc3550fe2 100644 --- a/docs/zh_CN/api-reference/peripherals/adc_calibration.rst +++ b/docs/zh_CN/api-reference/peripherals/adc_calibration.rst @@ -82,7 +82,7 @@ ADC 校准驱动程序会提供 ADC 校准方案。对于驱动程序来说, ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle)); -.. only:: esp32c3 or esp32s3 or esp32c6 +.. only:: esp32c3 or esp32s3 or esp32c6 or esp32h2 ADC 校准曲线拟合方案 ```````````````````````````````````` @@ -90,14 +90,14 @@ ADC 校准驱动程序会提供 ADC 校准方案。对于驱动程序来说, {IDF_TARGET_NAME} 支持 :c:macro:`ADC_CALI_SCHEME_VER_CURVE_FITTING` 方案。要创建此方案,请先根据以下配置选项,设置 :cpp:type:`adc_cali_curve_fitting_config_t`。 - .. only:: not esp32c6 + .. only:: esp32c3 or esp32s3 - :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`,表示 ADC 原始结果来自哪个 ADC 单元。 - :cpp:member:`adc_cali_curve_fitting_config_t::chan`,此选项保留以供扩展。校准方案仅因衰减程度而异,与通道选择无关。 - :cpp:member:`adc_cali_curve_fitting_config_t::atten`,表示 ADC 原始结果的衰减程度。 - :cpp:member:`adc_cali_curve_fitting_config_t::bitwidth`,表示 ADC 原始结果的位宽。 - .. only:: esp32c6 + .. only:: esp32c6 or esp32h2 - :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`,表示 ADC 原始结果来自哪个 ADC 单元。 - :cpp:member:`adc_cali_curve_fitting_config_t::chan`,表示获取 ADC 原始结果的 ADC 通道。校准方案不仅因衰减程度而异,还与通道选择有关。 @@ -132,10 +132,6 @@ ADC 校准驱动程序会提供 ADC 校准方案。对于驱动程序来说, ESP_ERROR_CHECK(adc_cali_delete_scheme_curve_fitting(handle)); -.. only:: esp32h2 - - 目前尚不支持任何校准方案。 - .. note:: 要使用自定义校准方案,可以通过提供创建函数,创建自己的校准方案句柄。请参阅 ``components/esp_adc/interface/adc_cali_interface.h`` 中的函数表 ``adc_cali_scheme_t``,了解 ESP ADC 校准接口。 From 9aab41cde148459e43c096f43001cdab92913c0d Mon Sep 17 00:00:00 2001 From: Jakob Hasse Date: Tue, 31 Oct 2023 15:44:00 +0800 Subject: [PATCH 138/161] fix(esp_event): dedicated task test now waits for semaphore correctly --- .../test_apps/main/test_event_common.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/components/esp_event/test_apps/main/test_event_common.cpp b/components/esp_event/test_apps/main/test_event_common.cpp index 9b327cd59973..0daa3844eff8 100644 --- a/components/esp_event/test_apps/main/test_event_common.cpp +++ b/components/esp_event/test_apps/main/test_event_common.cpp @@ -1225,6 +1225,15 @@ static void test_handler_give_sem(void* handler_arg, esp_event_base_t base, int3 TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreGive(sem)); } +const TickType_t ONE_TICK = 1; + +static void wait_taken(SemaphoreHandle_t sem, TickType_t delay_ticks_if_not_taken) { + while (xSemaphoreTake(sem, ONE_TICK) == pdTRUE) { + xSemaphoreGive(sem); + vTaskDelay(delay_ticks_if_not_taken); + } +} + TEST_CASE("can post while handler is executing - dedicated task", "[event][linux]") { EV_LoopFix loop_fix(1, "loop_task"); @@ -1248,6 +1257,9 @@ TEST_CASE("can post while handler is executing - dedicated task", "[event][linux // Trigger waiting by sending first event TEST_ESP_OK(esp_event_post_to(loop_fix.loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY)); + // Wait until semaphore is actually taken, which means handler is running and blocked + wait_taken(ev1_sem, 2); + // Check that event can be posted while handler is running (waiting on the semaphore) TEST_ESP_OK(esp_event_post_to(loop_fix.loop, s_test_base1, TEST_EVENT_BASE1_EV2, NULL, 0, portMAX_DELAY)); @@ -1317,10 +1329,7 @@ TEST_CASE("can not post while handler is executing - no dedicated task", "[event TEST_ESP_OK(esp_event_post_to(loop_fix.loop, s_test_base1, TEST_EVENT_BASE1_EV1, NULL, 0, portMAX_DELAY)); // Wait until semaphore is actually taken, which means handler is running and blocked - while (xSemaphoreTake(sem, 1) == pdTRUE) { - xSemaphoreGive(sem); - vTaskDelay(2); - } + wait_taken(sem, 2); // For loop without tasks, posting is more restrictive. Posting should wait until execution of handler finishes TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, esp_event_post_to(loop_fix.loop, From 8a47c4875b814f1c7d9ef9f7b8de1d162ed4b945 Mon Sep 17 00:00:00 2001 From: alanmaxwell Date: Fri, 25 Aug 2023 15:30:33 +0800 Subject: [PATCH 139/161] fix(wifi): optimize wifi bin size and fix some issue 1.Optimize bin size for STA only mode 2.Change fragment threshold to 256 3.Support fragment for LR mode 4.Fix ampdu duration issue 5.Fix rx fragment fail in Open mode. --- components/esp_rom/esp32c2/ld/esp32c2.rom.ld | 12 ++-- .../esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld | 2 +- components/esp_rom/esp32c3/ld/esp32c3.rom.ld | 6 +- .../esp_rom/esp32c6/ld/esp32c6.rom.pp.ld | 4 +- components/esp_rom/esp32s3/ld/esp32s3.rom.ld | 6 +- components/esp_wifi/lib | 2 +- components/esp_wifi/src/wifi_init.c | 70 +++++++++++++++++++ 7 files changed, 86 insertions(+), 16 deletions(-) diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index d4b3ac80e126..ca52f9758212 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -1540,10 +1540,10 @@ pm_on_tbtt = 0x40001ba8; pm_sleep_for = 0x40001bc0; /* pm_tbtt_process = 0x40001bc4; */ ppAMPDU2Normal = 0x40001bc8; -ppAssembleAMPDU = 0x40001bcc; +/*ppAssembleAMPDU = 0x40001bcc;*/ ppCalFrameTimes = 0x40001bd0; ppCalSubFrameLength = 0x40001bd4; -ppCalTxAMPDULength = 0x40001bd8; +/*ppCalTxAMPDULength = 0x40001bd8;*/ ppCheckTxAMPDUlength = 0x40001bdc; ppDequeueRxq_Locked = 0x40001be0; ppDequeueTxQ = 0x40001be4; @@ -1563,8 +1563,8 @@ ppRecycleAmpdu = 0x40001c18; ppRecycleRxPkt = 0x40001c1c; ppResortTxAMPDU = 0x40001c20; ppResumeTxAMPDU = 0x40001c24; -ppRxFragmentProc = 0x40001c28; -ppRxPkt = 0x40001c2c; +/*ppRxFragmentProc = 0x40001c28;*/ +/* ppRxPkt = 0x40001c2c; */ ppRxProtoProc = 0x40001c30; ppSearchTxQueue = 0x40001c34; ppSearchTxframe = 0x40001c38; @@ -1592,7 +1592,7 @@ rcLowerSched = 0x40001c8c; rcSetTxAmpduLimit = 0x40001c90; /* rcTxUpdatePer = 0x40001c94;*/ rcUpdateAckSnr = 0x40001c98; -rcUpdateRate = 0x40001c9c; +/*rcUpdateRate = 0x40001c9c;*/ rcUpdateTxDone = 0x40001ca0; rcUpdateTxDoneAmpdu2 = 0x40001ca4; rcUpSched = 0x40001ca8; @@ -1667,7 +1667,7 @@ lmacRetryTxFrame = 0x40001db8; lmacProcessCollisions_task = 0x40001dbc; /*lmacProcessTxopQComplete = 0x40001dc0;*/ lmacInitAc = 0x40001dc4; -lmacInit = 0x40001dc8; +/*lmacInit = 0x40001dc8;*/ mac_tx_set_txop_q = 0x40001dcc; /*hal_init = 0x40001dd0;*/ hal_mac_rx_set_policy = 0x40001dd4; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld index 3aacbb3819fa..84490150e89e 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld @@ -23,7 +23,7 @@ pm_rx_data_process = 0x40001694; /* pm_tbtt_process = 0x400016a0;*/ ppMapTxQueue = 0x400016d8; ppProcTxSecFrame = 0x400016dc; -ppRxFragmentProc = 0x40001704; +/*ppRxFragmentProc = 0x40001704;*/ /* rcGetSched = 0x40001764;*/ rcTxUpdatePer = 0x40001770; rcUpdateTxDone = 0x4000177c; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index 742786df59b0..c7a7a94bebfc 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -1559,10 +1559,10 @@ pm_on_tbtt = 0x40001684; pm_sleep_for = 0x4000169c; /* pm_tbtt_process = 0x400016a0; */ ppAMPDU2Normal = 0x400016a4; -ppAssembleAMPDU = 0x400016a8; +/*ppAssembleAMPDU = 0x400016a8;*/ ppCalFrameTimes = 0x400016ac; ppCalSubFrameLength = 0x400016b0; -ppCalTxAMPDULength = 0x400016b4; +/*ppCalTxAMPDULength = 0x400016b4;*/ ppCheckTxAMPDUlength = 0x400016b8; ppDequeueRxq_Locked = 0x400016bc; ppDequeueTxQ = 0x400016c0; @@ -1608,7 +1608,7 @@ rcLowerSched = 0x40001768; rcSetTxAmpduLimit = 0x4000176c; /* rcTxUpdatePer = 0x40001770;*/ rcUpdateAckSnr = 0x40001774; -rcUpdateRate = 0x40001778; +/*rcUpdateRate = 0x40001778;*/ /* rcUpdateTxDone = 0x4000177c; */ rcUpdateTxDoneAmpdu2 = 0x40001780; rcUpSched = 0x40001784; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld index 8a75b13a0654..e9256ac1fd80 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -100,7 +100,7 @@ ppRecycleAmpdu = 0x40000d10; ppRecycleRxPkt = 0x40000d14; //ppResortTxAMPDU = 0x40000d18; ppResumeTxAMPDU = 0x40000d1c; -ppRxFragmentProc = 0x40000d20; +/*ppRxFragmentProc = 0x40000d20;*/ //ppRxPkt = 0x40000d24; ppRxProtoProc = 0x40000d28; ppSearchTxQueue = 0x40000d2c; @@ -129,7 +129,7 @@ rcLowerSched = 0x40000d84; rcSetTxAmpduLimit = 0x40000d88; rcTxUpdatePer = 0x40000d8c; rcUpdateAckSnr = 0x40000d90; -rcUpdateRate = 0x40000d94; +/*rcUpdateRate = 0x40000d94;*/ rcUpdateTxDone = 0x40000d98; rcUpdateTxDoneAmpdu2 = 0x40000d9c; rcUpSched = 0x40000da0; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index 6ca2ab5010c1..d5c010fa2f6e 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -1861,10 +1861,10 @@ pm_on_tbtt = 0x400054cc; pm_sleep_for = 0x40005514; /* pm_tbtt_process = 0x40005520; */ ppAMPDU2Normal = 0x4000552c; -ppAssembleAMPDU = 0x40005538; +/*ppAssembleAMPDU = 0x40005538;*/ ppCalFrameTimes = 0x40005544; ppCalSubFrameLength = 0x40005550; -ppCalTxAMPDULength = 0x4000555c; +/*ppCalTxAMPDULength = 0x4000555c;*/ ppCheckTxAMPDUlength = 0x40005568; ppDequeueRxq_Locked = 0x40005574; ppDequeueTxQ = 0x40005580; @@ -1912,7 +1912,7 @@ rcLowerSched = 0x40005778; rcSetTxAmpduLimit = 0x40005784; /* rcTxUpdatePer = 0x40005790;*/ rcUpdateAckSnr = 0x4000579c; -rcUpdateRate = 0x400057a8; +/*rcUpdateRate = 0x400057a8;*/ /* rcUpdateTxDone = 0x400057b4; */ rcUpdateTxDoneAmpdu2 = 0x400057c0; rcUpSched = 0x400057cc; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index a0a9c8b7838a..6c2a80c3abb0 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit a0a9c8b7838adc81975f09bc7b4e1296dfcd27d8 +Subproject commit 6c2a80c3abb091e9c4434b5bebaf7df76c97daae diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 4473cfc4386a..ac2dd2f2cca7 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -355,7 +355,77 @@ void ieee80211_ftm_attach(void) #ifndef CONFIG_ESP_WIFI_SOFTAP_SUPPORT void net80211_softap_funcs_init(void) { + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} + +bool ieee80211_ap_try_sa_query(void *p) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return false; +} + +bool ieee80211_ap_sa_query_timeout(void *p) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return false; +} + +int add_mic_ie_bip(void *p) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return 0; +} + +void ieee80211_free_beacon_eb(void) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} + +int ieee80211_pwrsave(void *p1, void *p2) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return 0; +} + +void cnx_node_remove(void *p) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ } + +int ieee80211_set_tim(void *p, int arg) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return 0; +} + +bool ieee80211_is_bufferable_mmpdu(void *p) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return false; +} + +void cnx_node_leave(void *p, uint8_t arg) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} + +void ieee80211_beacon_construct(void *p1, void *p2, void *p3, void *p4) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ +} + +void * ieee80211_assoc_resp_construct(void *p, int arg) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return NULL; +} + +void * ieee80211_alloc_proberesp(void *p, int arg) +{ + /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return NULL; +} + #endif #ifndef CONFIG_ESP_WIFI_NAN_ENABLE From c84b2cbaed7907289b2809a2154c093974db4d4c Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Wed, 18 Oct 2023 18:20:48 +0530 Subject: [PATCH 140/161] fix(esp_wifi): Drop fragmented AMPDU(fixCVE-2020-26142) --- components/esp_rom/esp32c3/ld/esp32c3.rom.ld | 2 +- components/esp_rom/esp32s3/ld/esp32s3.rom.ld | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index c7a7a94bebfc..b9661d078554 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -1581,7 +1581,7 @@ ppRecycleRxPkt = 0x400016f8; ppResortTxAMPDU = 0x400016fc; ppResumeTxAMPDU = 0x40001700; /* ppRxFragmentProc = 0x40001704; */ -ppRxPkt = 0x40001708; +/* ppRxPkt = 0x40001708; */ ppRxProtoProc = 0x4000170c; ppSearchTxQueue = 0x40001710; ppSearchTxframe = 0x40001714; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index d5c010fa2f6e..3967479a8224 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -1884,7 +1884,7 @@ ppRecycleRxPkt = 0x40005628; ppResortTxAMPDU = 0x40005634; ppResumeTxAMPDU = 0x40005640; /* ppRxFragmentProc = 0x4000564c; */ -ppRxPkt = 0x40005658; +/* ppRxPkt = 0x40005658; */ ppRxProtoProc = 0x40005664; ppSearchTxQueue = 0x40005670; ppSearchTxframe = 0x4000567c; From 8b1a494cd30143e8047fab9dfd1fbbcfaf65b4a7 Mon Sep 17 00:00:00 2001 From: Shang Zhou Date: Thu, 2 Nov 2023 14:10:34 +0800 Subject: [PATCH 141/161] docs: Fix typo in get-started/index.rst and thread-local-storage.rst based on customer feedback --- docs/en/api-guides/thread-local-storage.rst | 6 +++--- docs/en/get-started/index.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/api-guides/thread-local-storage.rst b/docs/en/api-guides/thread-local-storage.rst index 79e229fbd3a5..8065199430f9 100644 --- a/docs/en/api-guides/thread-local-storage.rst +++ b/docs/en/api-guides/thread-local-storage.rst @@ -27,7 +27,7 @@ In this case, the maximum number of variables that can be allocated is limited b Using the APIs above, you can allocate thread local variables of an arbitrary size, and assign them to any number of tasks. Different tasks can have different sets of TLS variables. -If size of the variable is more then 4 bytes, then you need to allocate/deallocate memory for it. Variable's deallocation is initiated by FreeRTOS when task is deleted, but user must provide callback function to do proper cleanup. +If size of the variable is more than 4 bytes, then you need to allocate/deallocate memory for it. Variable's deallocation is initiated by FreeRTOS when task is deleted, but user must provide callback function to do proper cleanup. .. _pthread-api: @@ -41,7 +41,7 @@ The ESP-IDF provides the following :doc:`/api-reference/system/pthread` to manag - :cpp:func:`pthread_getspecific` - :cpp:func:`pthread_setspecific` -These APIs have all benefits of the ones above, but eliminates some their limits. The number of variables is limited only by size of available memory on the heap. Due to the dynamic nature, this APIs introduce additional performance overhead compared to the native one. +These APIs have all benefits of the ones above, but eliminates some their limits. The number of variables is limited only by size of available memory on the heap. Due to the dynamic nature, this API introduces additional performance overhead compared to the native one. .. _c11-std: @@ -52,4 +52,4 @@ The ESP-IDF FreeRTOS supports thread local variables according to C11 standard, Storage for that kind of variables is allocated on the task stack. Note that area for all such variables in the program is allocated on the stack of every task in the system even if that task does not use such variables at all. For example, ESP-IDF system tasks (e.g., ``ipc``, ``timer`` tasks etc.) will also have that extra stack space allocated. Thus feature should be used with care. -Using C11 thread local variables comes at a trade-off. One one hand, they are quite handy to use in programming and can be accessed using minimal CPU instructions. However, this benefit comes at the cost of additional stack usage for all tasks in the system. Due to static nature of variables allocation, all tasks in the system have the same sets of C11 thread local variables. +Using C11 thread local variables comes at a trade-off. On one hand, they are quite handy to use in programming and can be accessed using minimal CPU instructions. However, this benefit comes at the cost of additional stack usage for all tasks in the system. Due to static nature of variables allocation, all tasks in the system have the same sets of C11 thread local variables. diff --git a/docs/en/get-started/index.rst b/docs/en/get-started/index.rst index efa8b3349e15..e8869448e52c 100644 --- a/docs/en/get-started/index.rst +++ b/docs/en/get-started/index.rst @@ -196,7 +196,7 @@ For the manual procedure, please select according to your operating system. Build Your First Project ======================== -If you already have the ESP-IDF installed and not using IDE, you can build your first project from the command line following the :ref:`Start a Project on Windows ` or :ref:`Start a Project on Linux and macOS `. +If you already have the ESP-IDF installed and are not using an IDE, you can build your first project from the command line following the :ref:`Start a Project on Windows ` or :ref:`Start a Project on Linux and macOS `. .. _Stable version: https://docs.espressif.com/projects/esp-idf/en/stable/ From 1feb3c9f9b4a9f193b5df7f8abdb19a772817018 Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Sun, 20 Aug 2023 14:05:47 +0100 Subject: [PATCH 142/161] espcoredump: Support for not overwriting existing core dump in flash If there's an unattended boot loop or a crash that causes another crash on the next boot, it needs to be possible to avoid overwriting a saved core dump with another core dump. Add an option to do this and skip writing core dumps if the partition isn't empty. Fixes #12027. Mergeshttps://github.com/espressif/esp-idf/pull/12105 --- components/espcoredump/Kconfig | 10 +++++++ components/espcoredump/src/core_dump_flash.c | 30 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/components/espcoredump/Kconfig b/components/espcoredump/Kconfig index 7f18ccef03bb..175e5347a326 100644 --- a/components/espcoredump/Kconfig +++ b/components/espcoredump/Kconfig @@ -84,6 +84,16 @@ menu "Core dump" Config delay (in ms) before printing core dump to UART. Delay can be interrupted by pressing Enter key. + config ESP_COREDUMP_FLASH_NO_OVERWRITE + bool "Don't overwrite existing core dump" + depends on ESP_COREDUMP_ENABLE_TO_FLASH + default n + help + Don't overwrite an existing core dump already present in flash. + Enable this option to only keep the first of multiple core dumps. + + If enabled, the core dump partition must be erased before the first + core dump can be written. config ESP_COREDUMP_USE_STACK_SIZE bool diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index 0b39a3f6dde7..c53530a69d22 100644 --- a/components/espcoredump/src/core_dump_flash.c +++ b/components/espcoredump/src/core_dump_flash.c @@ -27,6 +27,10 @@ typedef struct _core_dump_partition_t uint32_t size; /* Flag set to true if the partition is encrypted. */ bool encrypted; +#if CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE + /* Flag set to true if the partition is empty. */ + bool empty; +#endif } core_dump_partition_t; typedef uint32_t core_dump_crc_t; @@ -82,6 +86,18 @@ void esp_core_dump_flash_init(void) s_core_flash_config.partition.start = core_part->address; s_core_flash_config.partition.size = core_part->size; s_core_flash_config.partition.encrypted = core_part->encrypted; + +#if CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE + uint32_t core_size = 0; + esp_err_t err = esp_partition_read(core_part, 0, &core_size, sizeof(core_size)); + if (err == ESP_OK) { + s_core_flash_config.partition.empty = (core_size == BLANK_COREDUMP_SIZE); + } else { + ESP_COREDUMP_LOGE("Failed to read core dump data size (%d)!", err); + s_core_flash_config.partition.empty = false; + } +#endif + s_core_flash_config.partition_config_crc = esp_core_dump_calc_flash_config_crc(); if (esp_flash_encryption_enabled() && !core_part->encrypted) { @@ -318,6 +334,13 @@ void esp_core_dump_to_flash(panic_info_t *info) return; } +#if CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE + if (!s_core_flash_config.partition.empty) { + ESP_COREDUMP_LOGW("Core dump already exists in flash, will not overwrite it with a new core dump"); + return; + } +#endif + /* Initialize non-OS flash access critical section. */ spi_flash_guard_set(&g_flash_guard_no_os_ops); esp_flash_app_disable_protect(true); @@ -457,6 +480,13 @@ esp_err_t esp_core_dump_image_erase(void) ESP_LOGE(TAG, "Failed to write core dump partition size (%d)!", err); } +#if CONFIG_ESP_COREDUMP_FLASH_NO_OVERWRITE + if (!s_core_flash_config.partition.empty) { + s_core_flash_config.partition.empty = true; + s_core_flash_config.partition_config_crc = esp_core_dump_calc_flash_config_crc(); + } +#endif + return err; } From e1ec13548f8eeaac692abdd0efd3eded714165ea Mon Sep 17 00:00:00 2001 From: darshan Date: Fri, 27 Oct 2023 11:08:00 +0530 Subject: [PATCH 143/161] fix(protocomm): added Protocomm BLE Event Structure and Event Handling --- .../include/transports/protocomm_ble.h | 29 +++++++++++++++++++ .../protocomm/src/transports/protocomm_ble.c | 16 ++++++++-- .../src/transports/protocomm_nimble.c | 18 ++++++++++-- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/components/protocomm/include/transports/protocomm_ble.h b/components/protocomm/include/transports/protocomm_ble.h index 085767625eae..51aec06e99f9 100644 --- a/components/protocomm/include/transports/protocomm_ble.h +++ b/components/protocomm/include/transports/protocomm_ble.h @@ -59,6 +59,35 @@ typedef struct name_uuid { uint16_t uuid; } protocomm_ble_name_uuid_t; +/** + * @brief Structure for BLE events in Protocomm. + */ +typedef struct { + /** + * This field indicates the type of BLE event that occurred. + */ + uint16_t evt_type; + /** + * The handle of the relevant connection. + */ + uint16_t conn_handle; + + union { + /** + * The status of the connection attempt; + * o 0: the connection was successfully established. + * o BLE host error code: the connection attempt failed for + * the specified reason. + */ + uint16_t conn_status; + + /** + * Return code indicating the reason for the disconnect. + */ + uint16_t disconnect_reason; + }; +} protocomm_ble_event_t; + /** * @brief Config parameters for protocomm BLE service */ diff --git a/components/protocomm/src/transports/protocomm_ble.c b/components/protocomm/src/transports/protocomm_ble.c index 6c070e4001d8..322c6086411e 100644 --- a/components/protocomm/src/transports/protocomm_ble.c +++ b/components/protocomm/src/transports/protocomm_ble.c @@ -345,7 +345,13 @@ static void transport_simple_ble_disconnect(esp_gatts_cb_event_t event, esp_gatt if (ret != ESP_OK) { ESP_LOGE(TAG, "error closing the session after disconnect"); } else { - if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_DISCONNECTED, NULL, 0, portMAX_DELAY) != ESP_OK) { + protocomm_ble_event_t ble_event = {}; + /* Assign the event type */ + ble_event.evt_type = PROTOCOMM_TRANSPORT_BLE_DISCONNECTED; + /* Set the Disconnection handle */ + ble_event.conn_handle = param->disconnect.conn_id; + + if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_DISCONNECTED, &ble_event, sizeof(protocomm_ble_event_t), portMAX_DELAY) != ESP_OK) { ESP_LOGE(TAG, "Failed to post transport disconnection event"); } } @@ -371,7 +377,13 @@ static void transport_simple_ble_connect(esp_gatts_cb_event_t event, esp_gatt_if if (ret != ESP_OK) { ESP_LOGE(TAG, "error creating the session"); } else { - if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_CONNECTED, NULL, 0, portMAX_DELAY) != ESP_OK) { + protocomm_ble_event_t ble_event = {}; + /* Assign the event type */ + ble_event.evt_type = PROTOCOMM_TRANSPORT_BLE_CONNECTED; + /* Set the Connection handle */ + ble_event.conn_handle = param->connect.conn_id; + + if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_CONNECTED, &ble_event, sizeof(protocomm_ble_event_t), portMAX_DELAY) != ESP_OK) { ESP_LOGE(TAG, "Failed to post transport pairing event"); } } diff --git a/components/protocomm/src/transports/protocomm_nimble.c b/components/protocomm/src/transports/protocomm_nimble.c index 29db3940714a..1f6e55657831 100644 --- a/components/protocomm/src/transports/protocomm_nimble.c +++ b/components/protocomm/src/transports/protocomm_nimble.c @@ -569,7 +569,14 @@ static void transport_simple_ble_disconnect(struct ble_gap_event *event, void *a if (ret != ESP_OK) { ESP_LOGE(TAG, "error closing the session after disconnect"); } else { - if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_DISCONNECTED, NULL, 0, portMAX_DELAY) != ESP_OK) { + protocomm_ble_event_t ble_event = {}; + /* Assign the event type */ + ble_event.evt_type = PROTOCOMM_TRANSPORT_BLE_DISCONNECTED; + /* Set the Disconnection handle */ + ble_event.conn_handle = event->disconnect.conn.conn_handle; + ble_event.disconnect_reason = event->disconnect.reason; + + if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_DISCONNECTED, &ble_event, sizeof(protocomm_ble_event_t), portMAX_DELAY) != ESP_OK) { ESP_LOGE(TAG, "Failed to post transport disconnection event"); } } @@ -595,7 +602,14 @@ static void transport_simple_ble_connect(struct ble_gap_event *event, void *arg) if (ret != ESP_OK) { ESP_LOGE(TAG, "error creating the session"); } else { - if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_CONNECTED, NULL, 0, portMAX_DELAY) != ESP_OK) { + protocomm_ble_event_t ble_event = {}; + /* Assign the event type */ + ble_event.evt_type = PROTOCOMM_TRANSPORT_BLE_CONNECTED; + /* Set the Connection handle */ + ble_event.conn_handle = event->connect.conn_handle; + ble_event.conn_status = event->connect.status; + + if (esp_event_post(PROTOCOMM_TRANSPORT_BLE_EVENT, PROTOCOMM_TRANSPORT_BLE_CONNECTED, &ble_event, sizeof(protocomm_ble_event_t), portMAX_DELAY) != ESP_OK) { ESP_LOGE(TAG, "Failed to post transport pairing event"); } } From 007c2b155e2506d432d92c540227fb470af12372 Mon Sep 17 00:00:00 2001 From: diplfranzhoepfinger <37779037+diplfranzhoepfinger@users.noreply.github.com> Date: Thu, 2 Nov 2023 11:13:20 +0100 Subject: [PATCH 144/161] Update ledc_basic_example_main.c the order of initializers should match the declaration, to be able to also use this code in C++ --- .../peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c b/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c index 840c5bcd8785..1561da8d9d5c 100644 --- a/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c +++ b/examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c @@ -29,8 +29,8 @@ static void example_ledc_init(void) // Prepare and then apply the LEDC PWM timer configuration ledc_timer_config_t ledc_timer = { .speed_mode = LEDC_MODE, - .timer_num = LEDC_TIMER, .duty_resolution = LEDC_DUTY_RES, + .timer_num = LEDC_TIMER, .freq_hz = LEDC_FREQUENCY, // Set output frequency at 4 kHz .clk_cfg = LEDC_AUTO_CLK }; From 8ac4b48b2f886e5e378bd71984e281b1ac9899fb Mon Sep 17 00:00:00 2001 From: Omar Chebib Date: Thu, 2 Nov 2023 17:05:42 +0800 Subject: [PATCH 145/161] change(espcoredump): save RAM space by placing constants in flash All the log messages of espcoredump component used to be in DRAM, which would lower the available RAM space for the user application. Since the cache is always enabled after an exception, constants can be put in flash. --- .../include_core_dump/esp_core_dump_types.h | 7 ++++++- components/espcoredump/linker.lf | 12 +++++++----- components/espcoredump/src/core_dump_binary.c | 2 +- components/espcoredump/src/core_dump_checksum.c | 16 ++++++++-------- components/espcoredump/src/core_dump_common.c | 2 +- components/espcoredump/src/core_dump_elf.c | 2 +- components/espcoredump/src/core_dump_flash.c | 2 +- components/espcoredump/src/core_dump_uart.c | 16 ++++++++-------- .../espcoredump/src/port/riscv/core_dump_port.c | 2 +- .../espcoredump/src/port/xtensa/core_dump_port.c | 2 +- 10 files changed, 35 insertions(+), 28 deletions(-) diff --git a/components/espcoredump/include_core_dump/esp_core_dump_types.h b/components/espcoredump/include_core_dump/esp_core_dump_types.h index fa6b8bf8dcd3..578be2df21c0 100644 --- a/components/espcoredump/include_core_dump/esp_core_dump_types.h +++ b/components/espcoredump/include_core_dump/esp_core_dump_types.h @@ -19,7 +19,7 @@ extern "C" { #include "core_dump_checksum.h" #if CONFIG_ESP_COREDUMP_LOGS -#define ESP_COREDUMP_LOG( level, format, ... ) if (LOG_LOCAL_LEVEL >= level) { esp_rom_printf(DRAM_STR(format), esp_log_early_timestamp(), (const char *)TAG, ##__VA_ARGS__); } +#define ESP_COREDUMP_LOG( level, format, ... ) if (LOG_LOCAL_LEVEL >= level) { esp_rom_printf((format), esp_log_early_timestamp(), (const char *)TAG, ##__VA_ARGS__); } #else #define ESP_COREDUMP_LOG( level, format, ... ) // dummy define doing nothing #endif @@ -30,6 +30,11 @@ extern "C" { #define ESP_COREDUMP_LOGD( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_DEBUG, LOG_FORMAT(D, format), ##__VA_ARGS__) #define ESP_COREDUMP_LOGV( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_VERBOSE, LOG_FORMAT(V, format), ##__VA_ARGS__) +/** + * @brief Always print the given message, regardless of the log level + */ +#define ESP_COREDUMP_PRINT( format, ... ) do { esp_rom_printf((format), ##__VA_ARGS__); } while(0) + /** * @brief Assertion to be verified in a release context. Cannot be muted. */ diff --git a/components/espcoredump/linker.lf b/components/espcoredump/linker.lf index fe978a7b6ad7..d51f4b36368e 100644 --- a/components/espcoredump/linker.lf +++ b/components/espcoredump/linker.lf @@ -37,11 +37,13 @@ entries: archive: libespcoredump.a entries: if ESP_PANIC_HANDLER_IRAM = y: - core_dump_uart (noflash_text) - core_dump_flash (noflash_text) - core_dump_common (noflash_text) - core_dump_port (noflash_text) - core_dump_elf (noflash_text) + core_dump_uart (noflash) + core_dump_flash (noflash) + core_dump_common (noflash) + core_dump_port (noflash) + core_dump_elf (noflash) + core_dump_checksum (noflash) + core_dump_binary (noflash) else: * (default) diff --git a/components/espcoredump/src/core_dump_binary.c b/components/espcoredump/src/core_dump_binary.c index 819cff47cff1..d2a0122ef154 100644 --- a/components/espcoredump/src/core_dump_binary.c +++ b/components/espcoredump/src/core_dump_binary.c @@ -14,7 +14,7 @@ #if CONFIG_ESP_COREDUMP_DATA_FORMAT_BIN -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_binary"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_binary"; static esp_err_t esp_core_dump_save_task(core_dump_write_config_t *write_cfg, diff --git a/components/espcoredump/src/core_dump_checksum.c b/components/espcoredump/src/core_dump_checksum.c index b29d909fcf53..f61ad89b3d50 100644 --- a/components/espcoredump/src/core_dump_checksum.c +++ b/components/espcoredump/src/core_dump_checksum.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,7 @@ #if CONFIG_ESP_COREDUMP_ENABLE -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_checksum"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_checksum"; #define COREDUMP_SHA256_LEN 32 @@ -147,13 +147,13 @@ static void esp_core_dump_print_sha256(const char* msg, const uint8_t* sha_outpu /* As this function is only called by `esp_core_dump_print_checksum`, we * have the guarantee that sha_output is not NULL. */ if (msg != NULL) { - esp_rom_printf(DRAM_STR("%s='"), msg); + ESP_COREDUMP_PRINT("%s='", msg); } for (int i = 0; i < COREDUMP_SHA256_LEN; i++) { - esp_rom_printf(DRAM_STR("%02x"), sha_output[i]); + ESP_COREDUMP_PRINT("%02x", sha_output[i]); } - esp_rom_printf(DRAM_STR("'\r\n")); + ESP_COREDUMP_PRINT("'\r\n"); } #endif @@ -170,10 +170,10 @@ void esp_core_dump_print_checksum(const char* msg, core_dump_checksum_bytes chec #if CONFIG_ESP_COREDUMP_CHECKSUM_CRC32 if (msg != NULL) { - esp_rom_printf(DRAM_STR("%s='"), msg); + ESP_COREDUMP_PRINT("%s='", msg); } - esp_rom_printf(DRAM_STR("%08x"), *((const uint32_t*) checksum)); - esp_rom_printf(DRAM_STR("'\r\n")); + ESP_COREDUMP_PRINT("%08x", *((const uint32_t*) checksum)); + ESP_COREDUMP_PRINT("'\r\n"); #elif CONFIG_ESP_COREDUMP_CHECKSUM_SHA256 esp_core_dump_print_sha256(msg, (const uint8_t*) checksum); #endif diff --git a/components/espcoredump/src/core_dump_common.c b/components/espcoredump/src/core_dump_common.c index 302737578ded..70f8f77f6d38 100644 --- a/components/espcoredump/src/core_dump_common.c +++ b/components/espcoredump/src/core_dump_common.c @@ -15,7 +15,7 @@ #include "core_dump_elf.h" #include "core_dump_binary.h" -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_common"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_common"; #if CONFIG_ESP_COREDUMP_ENABLE diff --git a/components/espcoredump/src/core_dump_elf.c b/components/espcoredump/src/core_dump_elf.c index 42c8938e90e2..cd93d26b2100 100644 --- a/components/espcoredump/src/core_dump_elf.c +++ b/components/espcoredump/src/core_dump_elf.c @@ -72,7 +72,7 @@ typedef struct uint8_t app_elf_sha256[ELF_APP_SHA256_SIZE]; // sha256 of elf file } core_dump_elf_version_info_t; -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_elf"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_elf"; // Main ELF handle type typedef struct _core_dump_elf_t diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index 0b39a3f6dde7..89e6a728f1ea 100644 --- a/components/espcoredump/src/core_dump_flash.c +++ b/components/espcoredump/src/core_dump_flash.c @@ -15,7 +15,7 @@ #define BLANK_COREDUMP_SIZE 0xFFFFFFFF -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_flash"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_flash"; #if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH diff --git a/components/espcoredump/src/core_dump_uart.c b/components/espcoredump/src/core_dump_uart.c index 0071ac182150..c10297d6b79d 100644 --- a/components/espcoredump/src/core_dump_uart.c +++ b/components/espcoredump/src/core_dump_uart.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ #include "esp_core_dump_common.h" #include "esp_rom_sys.h" -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_uart"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_uart"; #if CONFIG_ESP_COREDUMP_ENABLE_TO_UART @@ -22,7 +22,7 @@ const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_uart" int esp_clk_cpu_freq(void); static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8_t *dst) { - const static DRAM_ATTR char b64[] = + const static char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int i, j, a, b, c; @@ -53,7 +53,7 @@ static esp_err_t esp_core_dump_uart_write_start(core_dump_write_data_t *priv) ESP_COREDUMP_ASSERT(priv != NULL); esp_core_dump_checksum_init(&wr_data->checksum_ctx); - esp_rom_printf(DRAM_STR("================= CORE DUMP START =================\r\n")); + ESP_COREDUMP_PRINT("================= CORE DUMP START =================\r\n"); return err; } @@ -74,12 +74,12 @@ static esp_err_t esp_core_dump_uart_write_end(core_dump_write_data_t *priv) size_t cs_len = esp_core_dump_checksum_finish(wr_data->checksum_ctx, &cs_addr); wr_data->off += cs_len; esp_core_dump_b64_encode((const uint8_t *)cs_addr, cs_len, (uint8_t*)&buf[0]); - esp_rom_printf(DRAM_STR("%s\r\n"), buf); + ESP_COREDUMP_PRINT("%s\r\n", buf); } - esp_rom_printf(DRAM_STR("================= CORE DUMP END =================\r\n")); + ESP_COREDUMP_PRINT("================= CORE DUMP END =================\r\n"); if (cs_addr) { - esp_core_dump_print_checksum(DRAM_STR("Coredump checksum"), cs_addr); + esp_core_dump_print_checksum("Coredump checksum", cs_addr); } return err; @@ -103,7 +103,7 @@ static esp_err_t esp_core_dump_uart_write_data(core_dump_write_data_t *priv, voi memcpy(tmp, addr, len); esp_core_dump_b64_encode((const uint8_t *)tmp, len, (uint8_t *)buf); addr += len; - esp_rom_printf(DRAM_STR("%s\r\n"), buf); + ESP_COREDUMP_PRINT("%s\r\n", buf); } if (wr_data) { diff --git a/components/espcoredump/src/port/riscv/core_dump_port.c b/components/espcoredump/src/port/riscv/core_dump_port.c index aeb36aafb368..00d76405023a 100644 --- a/components/espcoredump/src/port/riscv/core_dump_port.c +++ b/components/espcoredump/src/port/riscv/core_dump_port.c @@ -20,7 +20,7 @@ #include "esp_core_dump_port.h" /* TAG used for logs */ -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_port"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_port"; /* Code associated to RISC-V in ELF format */ #define COREDUMP_EM_RISCV 0xF3 diff --git a/components/espcoredump/src/port/xtensa/core_dump_port.c b/components/espcoredump/src/port/xtensa/core_dump_port.c index fd17ac2584de..452c4259f695 100644 --- a/components/espcoredump/src/port/xtensa/core_dump_port.c +++ b/components/espcoredump/src/port/xtensa/core_dump_port.c @@ -21,7 +21,7 @@ #include "esp_debug_helpers.h" #include "esp_cpu_utils.h" -const static DRAM_ATTR char TAG[] __attribute__((unused)) = "esp_core_dump_port"; +const static char TAG[] __attribute__((unused)) = "esp_core_dump_port"; #define min(a,b) ((a) < (b) ? (a) : (b)) #define max(a,b) ((a) < (b) ? (b) : (a)) From 0132cce1cc230f927fa50726d7a2e03142aa7202 Mon Sep 17 00:00:00 2001 From: Abhinav Kudnar Date: Wed, 18 Oct 2023 18:52:04 +0530 Subject: [PATCH 146/161] fix(nimble):Handled the Load access fault crash caused due to an invalid setting of index-varible 'reattempt_idx'. --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 98b88eacee2d..9cb8e1817dba 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 98b88eacee2daf00f19c4ff52855cc3327d12e81 +Subproject commit 9cb8e1817dba36cabbbaced62d9e36bf238158f7 From d3ca964e5f8aac59b76ed5cc6fb0c73ef968f7dd Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Fri, 3 Nov 2023 09:12:02 +0800 Subject: [PATCH 147/161] fix(ci): fixed misnamed kconfig option in https server ci config --- examples/protocols/https_server/simple/sdkconfig.ci | 2 +- tools/ci/ignore_build_warnings.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/protocols/https_server/simple/sdkconfig.ci b/examples/protocols/https_server/simple/sdkconfig.ci index 5c2b28801375..badfd866fe21 100644 --- a/examples/protocols/https_server/simple/sdkconfig.ci +++ b/examples/protocols/https_server/simple/sdkconfig.ci @@ -1,4 +1,4 @@ CONFIG_ESP_HTTPS_SERVER_ENABLE=y -CONFIG_ESP_TLS_CERT_SELECT_HOOK=y +CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK=y CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK=y CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/tools/ci/ignore_build_warnings.txt b/tools/ci/ignore_build_warnings.txt index dd9523ca8839..301da338fa97 100644 --- a/tools/ci/ignore_build_warnings.txt +++ b/tools/ci/ignore_build_warnings.txt @@ -99,3 +99,4 @@ warning: unknown kconfig symbol 'TINYUSB' assigned to 'y' in /builds/espressif/e warning: unknown kconfig symbol 'UNITY_FREERTOS_STACK_SIZE' assigned to '12288' in /builds/espressif/esp-idf/components/bt/test_apps/sdkconfig.defaults warning: unknown kconfig symbol 'WIFI_ENABLED' assigned to 'n' in /builds/espressif/esp-idf/examples/bluetooth/bluedroid/classic_bt/* warning: unknown kconfig symbol 'WPA3_SAE' assigned to 'y' in /builds/espressif/esp-idf/components/wpa_supplicant/test_apps/sdkconfig.defaults +warning: unknown kconfig symbol 'ESP_DEFAULT_CPU_FREQ_MHZ_80' assigned to 'y' in /builds/espressif/esp-idf/examples/openthread/ot_sleepy_device/deep_sleep/sdkconfig.defaults From 5c3a7ec88a5eba90c0460c5c550996190766a42c Mon Sep 17 00:00:00 2001 From: xuxiao Date: Mon, 23 Oct 2023 13:49:36 +0800 Subject: [PATCH 148/161] fix(wifi): fix esp32c6 rxctrl info is not correct --- components/esp_wifi/include/esp_now.h | 1 + components/esp_wifi/include/esp_wifi_he_types.h | 2 +- components/esp_wifi/lib | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/components/esp_wifi/include/esp_now.h b/components/esp_wifi/include/esp_now.h index 728c69ba5e5e..3e8e8e299d3b 100644 --- a/components/esp_wifi/include/esp_now.h +++ b/components/esp_wifi/include/esp_now.h @@ -97,6 +97,7 @@ typedef struct esp_now_rate_config { wifi_phy_mode_t phymode; /**< ESPNOW phymode of specified interface */ wifi_phy_rate_t rate; /**< ESPNOW rate of specified interface*/ bool ersu; /**< ESPNOW using ersu send frame*/ + bool dcm; /**< ESPNOW using dcm rate to send frame*/ } esp_now_rate_config_t; /** diff --git a/components/esp_wifi/include/esp_wifi_he_types.h b/components/esp_wifi/include/esp_wifi_he_types.h index 01f753dddb1e..507367e53a36 100644 --- a/components/esp_wifi/include/esp_wifi_he_types.h +++ b/components/esp_wifi/include/esp_wifi_he_types.h @@ -157,7 +157,7 @@ typedef struct { unsigned : 15; /**< reserved */ unsigned : 15; /**< reserved */ unsigned : 2; /**< reserved */ - unsigned noise_floor : 8; /**< the noise floor of the reception frame */ + signed noise_floor : 8; /**< the noise floor of the reception frame */ unsigned channel : 4; /**< the primary channel */ unsigned second : 4; /**< the second channel if in HT40 */ unsigned : 8; /**< reserved */ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 6c2a80c3abb0..090d16dd1f7e 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 6c2a80c3abb091e9c4434b5bebaf7df76c97daae +Subproject commit 090d16dd1f7e0a60fb63c9a6788c2de4bdac6975 From 9461993ec5676ac04ac54a9f989a272ce1c51ddd Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Tue, 17 Oct 2023 12:11:42 +0800 Subject: [PATCH 149/161] refactor(gpio): make gpio driver as component, and fix astyle --- components/app_trace/CMakeLists.txt | 2 +- components/driver/CMakeLists.txt | 26 +--- components/driver/Kconfig | 18 --- .../driver/test_apps/.build-test-rules.yml | 31 +++-- .../test_apps/gpio_extensions/README.md | 2 - .../legacy_sigma_delta_driver/CMakeLists.txt | 8 ++ .../legacy_sigma_delta_driver/README.md | 2 + .../main/CMakeLists.txt | 11 ++ .../main/test_app_main.c | 0 .../main/test_sigma_delta_legacy.c | 0 .../pytest_legacy_sigma_delta.py | 22 ++++ .../sdkconfig.ci.release | 0 .../sdkconfig.defaults | 0 components/driver/test_apps/rs485/README.md | 4 +- .../{gpio => sigma_delta}/CMakeLists.txt | 4 +- .../driver/test_apps/sigma_delta/README.md | 2 + .../test_apps/sigma_delta/main/CMakeLists.txt | 11 ++ .../main/test_app_main.c | 0 .../main/test_sdm.c | 0 .../sigma_delta/pytest_sigma_delta.py | 23 ++++ .../sdkconfig.ci.iram_safe | 0 .../sdkconfig.ci.release | 0 .../sdkconfig.defaults | 0 components/driver/test_apps/uart/README.md | 4 +- components/esp_adc/CMakeLists.txt | 2 +- .../esp_adc/test_apps/.build-test-rules.yml | 2 +- components/esp_driver_gpio/CMakeLists.txt | 33 +++++ components/esp_driver_gpio/Kconfig | 17 +++ .../include/driver/dedic_gpio.h | 0 .../include/driver/gpio.h | 0 .../include/driver/gpio_etm.h | 0 .../include/driver/gpio_filter.h | 0 .../include/driver/lp_io.h | 0 .../include/driver/rtc_io.h | 1 - .../include/esp_private}/glitch_filter_priv.h | 0 .../include/esp_private/gpio.h | 0 .../gpio => esp_driver_gpio}/linker.lf | 3 +- .../gpio => esp_driver_gpio/src}/dedic_gpio.c | 4 +- .../gpio => esp_driver_gpio/src}/gpio.c | 116 +++++++++--------- .../gpio => esp_driver_gpio/src}/gpio_etm.c | 0 .../src}/gpio_flex_glitch_filter.c | 2 +- .../src}/gpio_glitch_filter_ops.c | 2 +- .../src}/gpio_pin_glitch_filter.c | 2 +- .../gpio => esp_driver_gpio/src}/rtc_io.c | 0 .../test_apps/.build-test-rules.yml | 10 ++ .../test_apps/gpio/CMakeLists.txt | 21 ++++ .../test_apps/gpio/README.md | 0 .../test_apps/gpio/main/CMakeLists.txt | 6 +- .../test_apps/gpio/main/test_app_main.c | 29 +++++ .../test_apps/gpio/main/test_gpio.c | 0 .../test_apps/gpio/main/test_gpio.h | 0 .../test_apps/gpio/main/test_rtcio.c | 66 +++++----- .../test_apps/gpio/main/test_rtcio.h | 0 .../test_apps/gpio/pytest_gpio.py | 12 -- .../test_apps/gpio/sdkconfig.ci.iram_safe | 0 .../test_apps/gpio/sdkconfig.ci.release | 5 + .../test_apps/gpio/sdkconfig.defaults | 2 + .../test_apps/gpio_extensions/CMakeLists.txt | 2 +- .../test_apps/gpio_extensions/README.md | 2 + .../gpio_extensions/main/CMakeLists.txt | 6 +- .../gpio_extensions/main/test_app_main.c | 38 ++++++ .../main/test_dedicated_gpio.c | 0 .../gpio_extensions/main/test_gpio_filter.c | 0 .../gpio_extensions/main/test_hysteresis.c | 10 +- .../gpio_extensions/pytest_gpio_extensions.py | 13 -- .../gpio_extensions/sdkconfig.ci.iram_safe | 9 ++ .../gpio_extensions/sdkconfig.ci.release | 5 + .../gpio_extensions/sdkconfig.defaults | 2 + components/esp_driver_pcnt/CMakeLists.txt | 2 +- components/esp_eth/CMakeLists.txt | 2 +- components/esp_hw_support/CMakeLists.txt | 7 +- components/esp_lcd/CMakeLists.txt | 2 +- components/esp_pm/CMakeLists.txt | 2 +- components/esp_pm/linker.lf | 2 +- components/espcoredump/CMakeLists.txt | 12 +- components/fatfs/CMakeLists.txt | 2 +- components/hal/esp32/include/hal/gpio_ll.h | 1 + components/hal/esp32c2/include/hal/gpio_ll.h | 1 + components/hal/esp32c3/include/hal/gpio_ll.h | 1 + components/hal/esp32c6/include/hal/gpio_ll.h | 1 + components/hal/esp32h2/include/hal/gpio_ll.h | 1 + components/hal/esp32p4/include/hal/gpio_ll.h | 1 + components/hal/esp32s2/include/hal/gpio_ll.h | 1 + components/hal/esp32s3/include/hal/gpio_ll.h | 1 + components/soc/include/soc/rtc_io_periph.h | 3 +- components/spi_flash/CMakeLists.txt | 4 +- .../spi_flash/test_apps/.build-test-rules.yml | 4 +- components/usb/CMakeLists.txt | 2 +- docs/doxygen/Doxyfile | 12 +- .../jtag-debugging/debugging-examples.rst | 2 +- docs/en/contribute/documenting-code.rst | 2 +- .../jtag-debugging/debugging-examples.rst | 2 +- docs/zh_CN/contribute/documenting-code.rst | 2 +- examples/bluetooth/.build-test-rules.yml | 17 +-- .../common_components/button/CMakeLists.txt | 2 +- .../light_driver/CMakeLists.txt | 2 +- examples/ethernet/.build-test-rules.yml | 6 +- examples/peripherals/.build-test-rules.yml | 4 + .../hd_eeprom/components/eeprom/linker.lf | 15 ++- .../hd_eeprom/components/eeprom/spi_eeprom.c | 10 -- .../hd_eeprom/main/Kconfig.projbuild | 5 +- .../components/cmd_system/CMakeLists.txt | 2 +- tools/mocks/driver/CMakeLists.txt | 6 +- .../system/g1_components/CMakeLists.txt | 2 +- 104 files changed, 464 insertions(+), 271 deletions(-) delete mode 100644 components/driver/test_apps/gpio_extensions/README.md create mode 100644 components/driver/test_apps/legacy_sigma_delta_driver/CMakeLists.txt create mode 100644 components/driver/test_apps/legacy_sigma_delta_driver/README.md create mode 100644 components/driver/test_apps/legacy_sigma_delta_driver/main/CMakeLists.txt rename components/driver/test_apps/{gpio => legacy_sigma_delta_driver}/main/test_app_main.c (100%) rename components/driver/test_apps/{gpio => legacy_sigma_delta_driver}/main/test_sigma_delta_legacy.c (100%) create mode 100644 components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py rename components/driver/test_apps/{gpio => legacy_sigma_delta_driver}/sdkconfig.ci.release (100%) rename components/driver/test_apps/{gpio => legacy_sigma_delta_driver}/sdkconfig.defaults (100%) rename components/driver/test_apps/{gpio => sigma_delta}/CMakeLists.txt (88%) create mode 100644 components/driver/test_apps/sigma_delta/README.md create mode 100644 components/driver/test_apps/sigma_delta/main/CMakeLists.txt rename components/driver/test_apps/{gpio_extensions => sigma_delta}/main/test_app_main.c (100%) rename components/driver/test_apps/{gpio_extensions => sigma_delta}/main/test_sdm.c (100%) create mode 100644 components/driver/test_apps/sigma_delta/pytest_sigma_delta.py rename components/driver/test_apps/{gpio_extensions => sigma_delta}/sdkconfig.ci.iram_safe (100%) rename components/driver/test_apps/{gpio_extensions => sigma_delta}/sdkconfig.ci.release (100%) rename components/driver/test_apps/{gpio_extensions => sigma_delta}/sdkconfig.defaults (100%) create mode 100644 components/esp_driver_gpio/CMakeLists.txt create mode 100644 components/esp_driver_gpio/Kconfig rename components/{driver/gpio => esp_driver_gpio}/include/driver/dedic_gpio.h (100%) rename components/{driver/gpio => esp_driver_gpio}/include/driver/gpio.h (100%) rename components/{driver/gpio => esp_driver_gpio}/include/driver/gpio_etm.h (100%) rename components/{driver/gpio => esp_driver_gpio}/include/driver/gpio_filter.h (100%) rename components/{driver/gpio => esp_driver_gpio}/include/driver/lp_io.h (100%) rename components/{driver/gpio => esp_driver_gpio}/include/driver/rtc_io.h (99%) rename components/{driver/gpio => esp_driver_gpio/include/esp_private}/glitch_filter_priv.h (100%) rename components/{driver => esp_driver_gpio}/include/esp_private/gpio.h (100%) rename components/{driver/gpio => esp_driver_gpio}/linker.lf (80%) rename components/{driver/gpio => esp_driver_gpio/src}/dedic_gpio.c (99%) rename components/{driver/gpio => esp_driver_gpio/src}/gpio.c (94%) rename components/{driver/gpio => esp_driver_gpio/src}/gpio_etm.c (100%) rename components/{driver/gpio => esp_driver_gpio/src}/gpio_flex_glitch_filter.c (99%) rename components/{driver/gpio => esp_driver_gpio/src}/gpio_glitch_filter_ops.c (94%) rename components/{driver/gpio => esp_driver_gpio/src}/gpio_pin_glitch_filter.c (98%) rename components/{driver/gpio => esp_driver_gpio/src}/rtc_io.c (100%) create mode 100644 components/esp_driver_gpio/test_apps/.build-test-rules.yml create mode 100644 components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt rename components/{driver => esp_driver_gpio}/test_apps/gpio/README.md (100%) rename components/{driver => esp_driver_gpio}/test_apps/gpio/main/CMakeLists.txt (69%) create mode 100644 components/esp_driver_gpio/test_apps/gpio/main/test_app_main.c rename components/{driver => esp_driver_gpio}/test_apps/gpio/main/test_gpio.c (100%) rename components/{driver => esp_driver_gpio}/test_apps/gpio/main/test_gpio.h (100%) rename components/{driver => esp_driver_gpio}/test_apps/gpio/main/test_rtcio.c (80%) rename components/{driver => esp_driver_gpio}/test_apps/gpio/main/test_rtcio.h (100%) rename components/{driver => esp_driver_gpio}/test_apps/gpio/pytest_gpio.py (69%) rename components/{driver => esp_driver_gpio}/test_apps/gpio/sdkconfig.ci.iram_safe (100%) create mode 100644 components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.release create mode 100644 components/esp_driver_gpio/test_apps/gpio/sdkconfig.defaults rename components/{driver => esp_driver_gpio}/test_apps/gpio_extensions/CMakeLists.txt (87%) create mode 100644 components/esp_driver_gpio/test_apps/gpio_extensions/README.md rename components/{driver => esp_driver_gpio}/test_apps/gpio_extensions/main/CMakeLists.txt (82%) create mode 100644 components/esp_driver_gpio/test_apps/gpio_extensions/main/test_app_main.c rename components/{driver => esp_driver_gpio}/test_apps/gpio_extensions/main/test_dedicated_gpio.c (100%) rename components/{driver => esp_driver_gpio}/test_apps/gpio_extensions/main/test_gpio_filter.c (100%) rename components/{driver => esp_driver_gpio}/test_apps/gpio_extensions/main/test_hysteresis.c (93%) rename components/{driver => esp_driver_gpio}/test_apps/gpio_extensions/pytest_gpio_extensions.py (72%) create mode 100644 components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.iram_safe create mode 100644 components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.release create mode 100644 components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.defaults diff --git a/components/app_trace/CMakeLists.txt b/components/app_trace/CMakeLists.txt index 5e360703596a..2a185d544df8 100644 --- a/components/app_trace/CMakeLists.txt +++ b/components/app_trace/CMakeLists.txt @@ -64,7 +64,7 @@ idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" PRIV_INCLUDE_DIRS "${priv_include_dirs}" # Requires "driver" for GPTimer in "SEGGER_SYSVIEW_Config_FreeRTOS.c" - PRIV_REQUIRES soc driver + PRIV_REQUIRES soc driver esp_driver_gpio REQUIRES esp_timer LDFRAGMENTS linker.lf) diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index d26385711784..a4f4f3eb8779 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -6,9 +6,6 @@ endif() # Always compiled source files set(srcs - "gpio/gpio.c" - "gpio/gpio_glitch_filter_ops.c" - "gpio/rtc_io.c" "spi/spi_bus_lock.c") # Always included headers @@ -16,7 +13,6 @@ set(includes "include" "deprecated" "analog_comparator/include" "dac/include" - "gpio/include" "gptimer/include" "i2c/include" "i2s/include" @@ -35,8 +31,7 @@ set(includes "include" "usb_serial_jtag/include") # Always included linker fragments -set(ldfragments "linker.lf" - "gpio/linker.lf") +set(ldfragments "linker.lf") # ADC related source files (dprecated) if(CONFIG_SOC_ADC_SUPPORTED) @@ -71,23 +66,6 @@ if(CONFIG_SOC_PARLIO_SUPPORTED) list(APPEND srcs "parlio/parlio_common.c" "parlio/parlio_tx.c") endif() -# GPIO related source files -if(CONFIG_SOC_DEDICATED_GPIO_SUPPORTED) - list(APPEND srcs "gpio/dedic_gpio.c") -endif() - -if(CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER) - list(APPEND srcs "gpio/gpio_pin_glitch_filter.c") -endif() - -if(CONFIG_SOC_GPIO_FLEX_GLITCH_FILTER_NUM GREATER 0) - list(APPEND srcs "gpio/gpio_flex_glitch_filter.c") -endif() - -if(CONFIG_SOC_GPIO_SUPPORT_ETM) - list(APPEND srcs "gpio/gpio_etm.c") -endif() - # GPTimer related source files if(CONFIG_SOC_GPTIMER_SUPPORTED) list(APPEND srcs "gptimer/gptimer.c" @@ -248,7 +226,7 @@ else() REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support # for backward compatibility, the driver component needs to # have a public dependency on other "esp_driver_foo" components - esp_driver_pcnt + esp_driver_gpio esp_driver_pcnt LDFRAGMENTS ${ldfragments} ) endif() diff --git a/components/driver/Kconfig b/components/driver/Kconfig index 0394f995695e..5de2715b0f81 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -156,24 +156,6 @@ menu "Driver Configurations" orsource "./uart/Kconfig.uart" - menu "GPIO Configuration" - config GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL - bool "Support light sleep GPIO pullup/pulldown configuration for ESP32" - depends on IDF_TARGET_ESP32 - help - This option is intended to fix the bug that ESP32 is not able to switch to configured - pullup/pulldown mode in sleep. - If this option is selected, chip will automatically emulate the behaviour of switching, - and about 450B of source codes would be placed into IRAM. - - config GPIO_CTRL_FUNC_IN_IRAM - bool "Place GPIO control functions into IRAM" - default n - help - Place GPIO control functions (like intr_disable/set_level) into IRAM, - so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context. - endmenu # GPIO Configuration - menu "Sigma Delta Modulator Configuration" depends on SOC_SDM_SUPPORTED config SDM_CTRL_FUNC_IN_IRAM diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index 23f308bc54ae..b8ed1bf8048c 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -16,12 +16,6 @@ components/driver/test_apps/dac_test_apps/legacy_dac_driver: disable: - if: SOC_DAC_SUPPORTED != 1 -components/driver/test_apps/gpio_extensions: - disable: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: not supported yet # TODO: IDF-7551 - components/driver/test_apps/gptimer: disable: - if: SOC_GPTIMER_SUPPORTED != 1 @@ -97,6 +91,14 @@ components/driver/test_apps/legacy_rtc_temp_driver: disable: - if: SOC_TEMP_SENSOR_SUPPORTED != 1 +components/driver/test_apps/legacy_sigma_delta_driver: + disable: + - if: SOC_SDM_SUPPORTED != 1 + depends_filepatterns: + - components/driver/deprecated/**/* + depends_components: + - esp_driver_gpio + components/driver/test_apps/legacy_timer_driver: disable: - if: SOC_GPTIMER_SUPPORTED != 1 @@ -119,9 +121,7 @@ components/driver/test_apps/rmt: components/driver/test_apps/rs485: disable: - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-6511 + - if: SOC_UART_SUPPORTED != 1 disable_test: - if: IDF_TARGET != "esp32" temporary: true @@ -135,6 +135,14 @@ components/driver/test_apps/sdio: temporary: true reason: lack of runners +components/driver/test_apps/sigma_delta: + disable: + - if: SOC_SDM_SUPPORTED != 1 + depends_filepatterns: + - components/driver/sigma_delta/**/* + depends_components: + - esp_driver_gpio + components/driver/test_apps/spi/master: disable: - if: SOC_GPSPI_SUPPORTED != 1 @@ -174,17 +182,14 @@ components/driver/test_apps/twai: components/driver/test_apps/uart: disable: - if: SOC_UART_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32p4"] - temporary: true - reason: target(s) is not supported yet # TODO: IDF-6511 components/driver/test_apps/usb_serial_jtag: disable: - if: SOC_USB_SERIAL_JTAG_SUPPORTED != 1 depends_filepatterns: - - components/driver/gpio/**/* - components/driver/usb_serial_jtag/**/* depends_components: - hal - esp_hw_support # for clock - vfs + - esp_driver_gpio diff --git a/components/driver/test_apps/gpio_extensions/README.md b/components/driver/test_apps/gpio_extensions/README.md deleted file mode 100644 index a8b7833fa30d..000000000000 --- a/components/driver/test_apps/gpio_extensions/README.md +++ /dev/null @@ -1,2 +0,0 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/legacy_sigma_delta_driver/CMakeLists.txt b/components/driver/test_apps/legacy_sigma_delta_driver/CMakeLists.txt new file mode 100644 index 000000000000..23e05b8a327e --- /dev/null +++ b/components/driver/test_apps/legacy_sigma_delta_driver/CMakeLists.txt @@ -0,0 +1,8 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(legacy_sigma_delta_driver_test) diff --git a/components/driver/test_apps/legacy_sigma_delta_driver/README.md b/components/driver/test_apps/legacy_sigma_delta_driver/README.md new file mode 100644 index 000000000000..19f1d19a5490 --- /dev/null +++ b/components/driver/test_apps/legacy_sigma_delta_driver/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/legacy_sigma_delta_driver/main/CMakeLists.txt b/components/driver/test_apps/legacy_sigma_delta_driver/main/CMakeLists.txt new file mode 100644 index 000000000000..85392372b955 --- /dev/null +++ b/components/driver/test_apps/legacy_sigma_delta_driver/main/CMakeLists.txt @@ -0,0 +1,11 @@ +set(srcs "test_app_main.c") + +if(CONFIG_SOC_SDM_SUPPORTED) + list(APPEND srcs "test_sigma_delta_legacy.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} + PRIV_REQUIRES unity driver esp_driver_gpio + WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/gpio/main/test_app_main.c b/components/driver/test_apps/legacy_sigma_delta_driver/main/test_app_main.c similarity index 100% rename from components/driver/test_apps/gpio/main/test_app_main.c rename to components/driver/test_apps/legacy_sigma_delta_driver/main/test_app_main.c diff --git a/components/driver/test_apps/gpio/main/test_sigma_delta_legacy.c b/components/driver/test_apps/legacy_sigma_delta_driver/main/test_sigma_delta_legacy.c similarity index 100% rename from components/driver/test_apps/gpio/main/test_sigma_delta_legacy.c rename to components/driver/test_apps/legacy_sigma_delta_driver/main/test_sigma_delta_legacy.c diff --git a/components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py b/components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py new file mode 100644 index 000000000000..cba1b0ab0016 --- /dev/null +++ b/components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py @@ -0,0 +1,22 @@ +# SPDX-FileCopyrightText: 2023 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.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True) +def test_legacy_sigma_delta(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='sigma_delta') diff --git a/components/driver/test_apps/gpio/sdkconfig.ci.release b/components/driver/test_apps/legacy_sigma_delta_driver/sdkconfig.ci.release similarity index 100% rename from components/driver/test_apps/gpio/sdkconfig.ci.release rename to components/driver/test_apps/legacy_sigma_delta_driver/sdkconfig.ci.release diff --git a/components/driver/test_apps/gpio/sdkconfig.defaults b/components/driver/test_apps/legacy_sigma_delta_driver/sdkconfig.defaults similarity index 100% rename from components/driver/test_apps/gpio/sdkconfig.defaults rename to components/driver/test_apps/legacy_sigma_delta_driver/sdkconfig.defaults diff --git a/components/driver/test_apps/rs485/README.md b/components/driver/test_apps/rs485/README.md index a8b7833fa30d..bf47d80ec649 100644 --- a/components/driver/test_apps/rs485/README.md +++ b/components/driver/test_apps/rs485/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/gpio/CMakeLists.txt b/components/driver/test_apps/sigma_delta/CMakeLists.txt similarity index 88% rename from components/driver/test_apps/gpio/CMakeLists.txt rename to components/driver/test_apps/sigma_delta/CMakeLists.txt index 7ba8cc2d2ca1..2150ef0e3a7b 100644 --- a/components/driver/test_apps/gpio/CMakeLists.txt +++ b/components/driver/test_apps/sigma_delta/CMakeLists.txt @@ -5,13 +5,13 @@ cmake_minimum_required(VERSION 3.16) set(COMPONENTS main) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(gpio_test) +project(sigma_delta_test) if(CONFIG_COMPILER_DUMP_RTL_FILES) add_custom_target(check_test_app_sections ALL COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/ - --elf-file ${CMAKE_BINARY_DIR}/gpio_test.elf + --elf-file ${CMAKE_BINARY_DIR}/sigma_delta_test.elf find-refs --from-sections=.iram0.text --to-sections=.flash.text,.flash.rodata diff --git a/components/driver/test_apps/sigma_delta/README.md b/components/driver/test_apps/sigma_delta/README.md new file mode 100644 index 000000000000..19f1d19a5490 --- /dev/null +++ b/components/driver/test_apps/sigma_delta/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/sigma_delta/main/CMakeLists.txt b/components/driver/test_apps/sigma_delta/main/CMakeLists.txt new file mode 100644 index 000000000000..29c6893034e0 --- /dev/null +++ b/components/driver/test_apps/sigma_delta/main/CMakeLists.txt @@ -0,0 +1,11 @@ +set(srcs "test_app_main.c") + +if(CONFIG_SOC_SDM_SUPPORTED) + list(APPEND srcs "test_sdm.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} + PRIV_REQUIRES unity driver + WHOLE_ARCHIVE) diff --git a/components/driver/test_apps/gpio_extensions/main/test_app_main.c b/components/driver/test_apps/sigma_delta/main/test_app_main.c similarity index 100% rename from components/driver/test_apps/gpio_extensions/main/test_app_main.c rename to components/driver/test_apps/sigma_delta/main/test_app_main.c diff --git a/components/driver/test_apps/gpio_extensions/main/test_sdm.c b/components/driver/test_apps/sigma_delta/main/test_sdm.c similarity index 100% rename from components/driver/test_apps/gpio_extensions/main/test_sdm.c rename to components/driver/test_apps/sigma_delta/main/test_sdm.c diff --git a/components/driver/test_apps/sigma_delta/pytest_sigma_delta.py b/components/driver/test_apps/sigma_delta/pytest_sigma_delta.py new file mode 100644 index 000000000000..6f5763207d68 --- /dev/null +++ b/components/driver/test_apps/sigma_delta/pytest_sigma_delta.py @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded_idf import IdfDut + +CONFIGS = [ + 'iram_safe', + 'release', +] + + +@pytest.mark.esp32 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.esp32h2 +@pytest.mark.generic +@pytest.mark.parametrize('config', CONFIGS, indirect=True) +def test_sdm(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='sdm') diff --git a/components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe b/components/driver/test_apps/sigma_delta/sdkconfig.ci.iram_safe similarity index 100% rename from components/driver/test_apps/gpio_extensions/sdkconfig.ci.iram_safe rename to components/driver/test_apps/sigma_delta/sdkconfig.ci.iram_safe diff --git a/components/driver/test_apps/gpio_extensions/sdkconfig.ci.release b/components/driver/test_apps/sigma_delta/sdkconfig.ci.release similarity index 100% rename from components/driver/test_apps/gpio_extensions/sdkconfig.ci.release rename to components/driver/test_apps/sigma_delta/sdkconfig.ci.release diff --git a/components/driver/test_apps/gpio_extensions/sdkconfig.defaults b/components/driver/test_apps/sigma_delta/sdkconfig.defaults similarity index 100% rename from components/driver/test_apps/gpio_extensions/sdkconfig.defaults rename to components/driver/test_apps/sigma_delta/sdkconfig.defaults diff --git a/components/driver/test_apps/uart/README.md b/components/driver/test_apps/uart/README.md index a8b7833fa30d..bf47d80ec649 100644 --- a/components/driver/test_apps/uart/README.md +++ b/components/driver/test_apps/uart/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/esp_adc/CMakeLists.txt b/components/esp_adc/CMakeLists.txt index bef8434a40d0..180ef6e8cf1d 100644 --- a/components/esp_adc/CMakeLists.txt +++ b/components/esp_adc/CMakeLists.txt @@ -42,5 +42,5 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} - PRIV_REQUIRES driver efuse + PRIV_REQUIRES driver esp_driver_gpio efuse esp_pm esp_ringbuf LDFRAGMENTS linker.lf) diff --git a/components/esp_adc/test_apps/.build-test-rules.yml b/components/esp_adc/test_apps/.build-test-rules.yml index 4b1b071e72b5..ab0728836d83 100644 --- a/components/esp_adc/test_apps/.build-test-rules.yml +++ b/components/esp_adc/test_apps/.build-test-rules.yml @@ -6,8 +6,8 @@ components/esp_adc/test_apps/adc: - if: CONFIG_NAME == "gdma_iram_safe" and IDF_TARGET in ["esp32", "esp32s2", "esp32c2"] depends_components: - esp_adc + - esp_driver_gpio - efuse depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* # ADC continuous driver relies on SPI on ESP32S2 - components/driver/i2s/**/* # ADC continuous driver relies on I2S on ESP32 diff --git a/components/esp_driver_gpio/CMakeLists.txt b/components/esp_driver_gpio/CMakeLists.txt new file mode 100644 index 000000000000..dce1295124cb --- /dev/null +++ b/components/esp_driver_gpio/CMakeLists.txt @@ -0,0 +1,33 @@ +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 "src/gpio.c" + "src/gpio_glitch_filter_ops.c" + "src/rtc_io.c" + ) +set(public_include "include") + +if(CONFIG_SOC_DEDICATED_GPIO_SUPPORTED) + list(APPEND srcs "src/dedic_gpio.c") +endif() + +if(CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER) + list(APPEND srcs "src/gpio_pin_glitch_filter.c") +endif() + +if(CONFIG_SOC_GPIO_FLEX_GLITCH_FILTER_NUM GREATER 0) + list(APPEND srcs "src/gpio_flex_glitch_filter.c") +endif() + +if(CONFIG_SOC_GPIO_SUPPORT_ETM) + list(APPEND srcs "src/gpio_etm.c") +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${public_include} + PRIV_REQUIRES esp_pm + LDFRAGMENTS "linker.lf" + ) diff --git a/components/esp_driver_gpio/Kconfig b/components/esp_driver_gpio/Kconfig new file mode 100644 index 000000000000..36d2b13794ac --- /dev/null +++ b/components/esp_driver_gpio/Kconfig @@ -0,0 +1,17 @@ +menu "ESP-Driver:GPIO Configurations" + config GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL + bool "Support light sleep GPIO pullup/pulldown configuration for ESP32" + depends on IDF_TARGET_ESP32 + help + This option is intended to fix the bug that ESP32 is not able to switch to configured + pullup/pulldown mode in sleep. + If this option is selected, chip will automatically emulate the behaviour of switching, + and about 450B of source codes would be placed into IRAM. + + config GPIO_CTRL_FUNC_IN_IRAM + bool "Place GPIO control functions into IRAM" + default n + help + Place GPIO control functions (like intr_disable/set_level) into IRAM, + so that these functions can be IRAM-safe and able to be called in the other IRAM interrupt context. +endmenu diff --git a/components/driver/gpio/include/driver/dedic_gpio.h b/components/esp_driver_gpio/include/driver/dedic_gpio.h similarity index 100% rename from components/driver/gpio/include/driver/dedic_gpio.h rename to components/esp_driver_gpio/include/driver/dedic_gpio.h diff --git a/components/driver/gpio/include/driver/gpio.h b/components/esp_driver_gpio/include/driver/gpio.h similarity index 100% rename from components/driver/gpio/include/driver/gpio.h rename to components/esp_driver_gpio/include/driver/gpio.h diff --git a/components/driver/gpio/include/driver/gpio_etm.h b/components/esp_driver_gpio/include/driver/gpio_etm.h similarity index 100% rename from components/driver/gpio/include/driver/gpio_etm.h rename to components/esp_driver_gpio/include/driver/gpio_etm.h diff --git a/components/driver/gpio/include/driver/gpio_filter.h b/components/esp_driver_gpio/include/driver/gpio_filter.h similarity index 100% rename from components/driver/gpio/include/driver/gpio_filter.h rename to components/esp_driver_gpio/include/driver/gpio_filter.h diff --git a/components/driver/gpio/include/driver/lp_io.h b/components/esp_driver_gpio/include/driver/lp_io.h similarity index 100% rename from components/driver/gpio/include/driver/lp_io.h rename to components/esp_driver_gpio/include/driver/lp_io.h diff --git a/components/driver/gpio/include/driver/rtc_io.h b/components/esp_driver_gpio/include/driver/rtc_io.h similarity index 99% rename from components/driver/gpio/include/driver/rtc_io.h rename to components/esp_driver_gpio/include/driver/rtc_io.h index 4e9c2d0e3c20..27a161d65554 100644 --- a/components/driver/gpio/include/driver/rtc_io.h +++ b/components/esp_driver_gpio/include/driver/rtc_io.h @@ -13,7 +13,6 @@ #include "hal/rtc_io_types.h" #include "driver/gpio.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/components/driver/gpio/glitch_filter_priv.h b/components/esp_driver_gpio/include/esp_private/glitch_filter_priv.h similarity index 100% rename from components/driver/gpio/glitch_filter_priv.h rename to components/esp_driver_gpio/include/esp_private/glitch_filter_priv.h diff --git a/components/driver/include/esp_private/gpio.h b/components/esp_driver_gpio/include/esp_private/gpio.h similarity index 100% rename from components/driver/include/esp_private/gpio.h rename to components/esp_driver_gpio/include/esp_private/gpio.h diff --git a/components/driver/gpio/linker.lf b/components/esp_driver_gpio/linker.lf similarity index 80% rename from components/driver/gpio/linker.lf rename to components/esp_driver_gpio/linker.lf index 4ca65040df74..46d901a627c0 100644 --- a/components/driver/gpio/linker.lf +++ b/components/esp_driver_gpio/linker.lf @@ -1,9 +1,10 @@ [mapping:gpio_driver] -archive: libdriver.a +archive: libesp_driver_gpio.a entries: if GPIO_CTRL_FUNC_IN_IRAM = y: gpio: gpio_set_level (noflash) gpio: gpio_intr_disable (noflash) + gpio: gpio_get_level (noflash) [mapping:gpio_hal] archive: libhal.a diff --git a/components/driver/gpio/dedic_gpio.c b/components/esp_driver_gpio/src/dedic_gpio.c similarity index 99% rename from components/driver/gpio/dedic_gpio.c rename to components/esp_driver_gpio/src/dedic_gpio.c index b6ddc8e6d1a7..077efff88e15 100644 --- a/components/driver/gpio/dedic_gpio.c +++ b/components/esp_driver_gpio/src/dedic_gpio.c @@ -31,7 +31,6 @@ #include "hal/dedic_gpio_ll.h" #endif - static const char *TAG = "dedic_gpio"; typedef struct dedic_gpio_platform_t dedic_gpio_platform_t; @@ -313,7 +312,7 @@ esp_err_t dedic_gpio_del_bundle(dedic_gpio_bundle_handle_t bundle) s_platform[core_id]->out_occupied_mask &= ~(bundle->out_mask); s_platform[core_id]->in_occupied_mask &= ~(bundle->in_mask); if (s_platform[core_id]->in_occupied_mask == (UINT32_MAX & ~((1 << SOC_DEDIC_GPIO_IN_CHANNELS_NUM) - 1)) && - s_platform[core_id]->out_occupied_mask == (UINT32_MAX & ~((1 << SOC_DEDIC_GPIO_OUT_CHANNELS_NUM) - 1))) { + s_platform[core_id]->out_occupied_mask == (UINT32_MAX & ~((1 << SOC_DEDIC_GPIO_OUT_CHANNELS_NUM) - 1))) { recycle_all = true; } portEXIT_CRITICAL(&s_platform[core_id]->spinlock); @@ -349,7 +348,6 @@ esp_err_t dedic_gpio_get_in_mask(dedic_gpio_bundle_handle_t bundle, uint32_t *ma return ret; } - esp_err_t dedic_gpio_get_out_offset(dedic_gpio_bundle_handle_t bundle, uint32_t *offset) { esp_err_t ret = ESP_OK; diff --git a/components/driver/gpio/gpio.c b/components/esp_driver_gpio/src/gpio.c similarity index 94% rename from components/driver/gpio/gpio.c rename to components/esp_driver_gpio/src/gpio.c index e1d81a2b3e24..3e09f30a60e5 100644 --- a/components/driver/gpio/gpio.c +++ b/components/esp_driver_gpio/src/gpio.c @@ -10,8 +10,7 @@ #include "esp_heap_caps.h" #include "driver/gpio.h" #include "driver/rtc_io.h" -#include "soc/soc.h" -#include "soc/periph_defs.h" +#include "soc/interrupts.h" #if !CONFIG_FREERTOS_UNICORE #include "esp_ipc.h" #endif @@ -166,7 +165,7 @@ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type) return ESP_OK; } -static esp_err_t gpio_intr_enable_on_core(gpio_num_t gpio_num, uint32_t core_id) +static inline esp_err_t gpio_intr_enable_on_core(gpio_num_t gpio_num, uint32_t core_id) { gpio_hal_intr_enable_on_core(gpio_context.gpio_hal, gpio_num, core_id); return ESP_OK; @@ -176,11 +175,11 @@ esp_err_t gpio_intr_enable(gpio_num_t gpio_num) { GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&gpio_context.gpio_spinlock); - if(gpio_context.isr_core_id == GPIO_ISR_CORE_ID_UNINIT) { + if (gpio_context.isr_core_id == GPIO_ISR_CORE_ID_UNINIT) { gpio_context.isr_core_id = xPortGetCoreID(); } portEXIT_CRITICAL(&gpio_context.gpio_spinlock); - return gpio_intr_enable_on_core (gpio_num, gpio_context.isr_core_id); + return gpio_intr_enable_on_core(gpio_num, gpio_context.isr_core_id); } esp_err_t gpio_intr_disable(gpio_num_t gpio_num) @@ -274,30 +273,30 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) esp_err_t ret = ESP_OK; switch (pull) { - case GPIO_PULLUP_ONLY: - gpio_pulldown_dis(gpio_num); - gpio_pullup_en(gpio_num); - break; - - case GPIO_PULLDOWN_ONLY: - gpio_pulldown_en(gpio_num); - gpio_pullup_dis(gpio_num); - break; - - case GPIO_PULLUP_PULLDOWN: - gpio_pulldown_en(gpio_num); - gpio_pullup_en(gpio_num); - break; - - case GPIO_FLOATING: - gpio_pulldown_dis(gpio_num); - gpio_pullup_dis(gpio_num); - break; - - default: - ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull); - ret = ESP_ERR_INVALID_ARG; - break; + case GPIO_PULLUP_ONLY: + gpio_pulldown_dis(gpio_num); + gpio_pullup_en(gpio_num); + break; + + case GPIO_PULLDOWN_ONLY: + gpio_pulldown_en(gpio_num); + gpio_pullup_dis(gpio_num); + break; + + case GPIO_PULLUP_PULLDOWN: + gpio_pulldown_en(gpio_num); + gpio_pullup_en(gpio_num); + break; + + case GPIO_FLOATING: + gpio_pulldown_dis(gpio_num); + gpio_pullup_dis(gpio_num); + break; + + default: + ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull); + ret = ESP_ERR_INVALID_ARG; + break; } return ret; @@ -347,13 +346,13 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig) uint8_t pd_en = 0; if (pGPIOConfig->pin_bit_mask == 0 || - pGPIOConfig->pin_bit_mask & ~SOC_GPIO_VALID_GPIO_MASK) { + pGPIOConfig->pin_bit_mask & ~SOC_GPIO_VALID_GPIO_MASK) { ESP_LOGE(GPIO_TAG, "GPIO_PIN mask error "); return ESP_ERR_INVALID_ARG; } if (pGPIOConfig->mode & GPIO_MODE_DEF_OUTPUT && - pGPIOConfig->pin_bit_mask & ~SOC_GPIO_VALID_OUTPUT_GPIO_MASK) { + pGPIOConfig->pin_bit_mask & ~SOC_GPIO_VALID_OUTPUT_GPIO_MASK) { ESP_LOGE(GPIO_TAG, "GPIO can only be used as input mode"); return ESP_ERR_INVALID_ARG; } @@ -538,7 +537,7 @@ esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void gpio_context.gpio_isr_func[gpio_num].fn = isr_handler; gpio_context.gpio_isr_func[gpio_num].args = args; } - gpio_intr_enable_on_core (gpio_num, esp_intr_get_cpu(gpio_context.gpio_isr_handle)); + gpio_intr_enable_on_core(gpio_num, esp_intr_get_cpu(gpio_context.gpio_isr_handle)); portEXIT_CRITICAL(&gpio_context.gpio_spinlock); return ESP_OK; } @@ -577,7 +576,6 @@ void gpio_uninstall_isr_service(void) return; } - static void gpio_isr_register_on_core_static(void *param) { gpio_isr_alloc_t *p = (gpio_isr_alloc_t *)param; @@ -602,7 +600,7 @@ esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags, p.arg = arg; p.handle = handle; portENTER_CRITICAL(&gpio_context.gpio_spinlock); - if(gpio_context.isr_core_id == GPIO_ISR_CORE_ID_UNINIT) { + if (gpio_context.isr_core_id == GPIO_ISR_CORE_ID_UNINIT) { gpio_context.isr_core_id = xPortGetCoreID(); } portEXIT_CRITICAL(&gpio_context.gpio_spinlock); @@ -739,7 +737,7 @@ esp_err_t gpio_hold_dis(gpio_num_t gpio_num) #if SOC_RTCIO_HOLD_SUPPORTED ret = rtc_gpio_hold_dis(gpio_num); #endif - }else if (GPIO_HOLD_MASK[gpio_num]) { + } else if (GPIO_HOLD_MASK[gpio_num]) { portENTER_CRITICAL(&gpio_context.gpio_spinlock); gpio_hal_hold_dis(gpio_context.gpio_hal, gpio_num); portEXIT_CRITICAL(&gpio_context.gpio_spinlock); @@ -905,30 +903,30 @@ esp_err_t gpio_sleep_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) esp_err_t ret = ESP_OK; switch (pull) { - case GPIO_PULLUP_ONLY: - gpio_sleep_pulldown_dis(gpio_num); - gpio_sleep_pullup_en(gpio_num); - break; - - case GPIO_PULLDOWN_ONLY: - gpio_sleep_pulldown_en(gpio_num); - gpio_sleep_pullup_dis(gpio_num); - break; - - case GPIO_PULLUP_PULLDOWN: - gpio_sleep_pulldown_en(gpio_num); - gpio_sleep_pullup_en(gpio_num); - break; - - case GPIO_FLOATING: - gpio_sleep_pulldown_dis(gpio_num); - gpio_sleep_pullup_dis(gpio_num); - break; - - default: - ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull); - ret = ESP_ERR_INVALID_ARG; - break; + case GPIO_PULLUP_ONLY: + gpio_sleep_pulldown_dis(gpio_num); + gpio_sleep_pullup_en(gpio_num); + break; + + case GPIO_PULLDOWN_ONLY: + gpio_sleep_pulldown_en(gpio_num); + gpio_sleep_pullup_dis(gpio_num); + break; + + case GPIO_PULLUP_PULLDOWN: + gpio_sleep_pulldown_en(gpio_num); + gpio_sleep_pullup_en(gpio_num); + break; + + case GPIO_FLOATING: + gpio_sleep_pulldown_dis(gpio_num); + gpio_sleep_pullup_dis(gpio_num); + break; + + default: + ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull); + ret = ESP_ERR_INVALID_ARG; + break; } return ret; diff --git a/components/driver/gpio/gpio_etm.c b/components/esp_driver_gpio/src/gpio_etm.c similarity index 100% rename from components/driver/gpio/gpio_etm.c rename to components/esp_driver_gpio/src/gpio_etm.c diff --git a/components/driver/gpio/gpio_flex_glitch_filter.c b/components/esp_driver_gpio/src/gpio_flex_glitch_filter.c similarity index 99% rename from components/driver/gpio/gpio_flex_glitch_filter.c rename to components/esp_driver_gpio/src/gpio_flex_glitch_filter.c index 8a0138e46f29..1c16b1009497 100644 --- a/components/driver/gpio/gpio_flex_glitch_filter.c +++ b/components/esp_driver_gpio/src/gpio_flex_glitch_filter.c @@ -7,7 +7,7 @@ #include #include "freertos/FreeRTOS.h" #include "esp_check.h" -#include "glitch_filter_priv.h" +#include "esp_private/glitch_filter_priv.h" #include "esp_private/io_mux.h" #include "soc/soc_caps.h" #include "hal/gpio_glitch_filter_ll.h" diff --git a/components/driver/gpio/gpio_glitch_filter_ops.c b/components/esp_driver_gpio/src/gpio_glitch_filter_ops.c similarity index 94% rename from components/driver/gpio/gpio_glitch_filter_ops.c rename to components/esp_driver_gpio/src/gpio_glitch_filter_ops.c index 841d0953260e..001968575d40 100644 --- a/components/driver/gpio/gpio_glitch_filter_ops.c +++ b/components/esp_driver_gpio/src/gpio_glitch_filter_ops.c @@ -5,7 +5,7 @@ */ #include "esp_check.h" -#include "glitch_filter_priv.h" +#include "esp_private/glitch_filter_priv.h" static const char *TAG = "gpio-filter"; diff --git a/components/driver/gpio/gpio_pin_glitch_filter.c b/components/esp_driver_gpio/src/gpio_pin_glitch_filter.c similarity index 98% rename from components/driver/gpio/gpio_pin_glitch_filter.c rename to components/esp_driver_gpio/src/gpio_pin_glitch_filter.c index 877f345e4f9e..3778becfe7d0 100644 --- a/components/driver/gpio/gpio_pin_glitch_filter.c +++ b/components/esp_driver_gpio/src/gpio_pin_glitch_filter.c @@ -8,7 +8,7 @@ #include "freertos/FreeRTOS.h" #include "esp_check.h" #include "esp_pm.h" -#include "glitch_filter_priv.h" +#include "esp_private/glitch_filter_priv.h" #include "hal/gpio_ll.h" #include "esp_clk_tree.h" #include "esp_private/io_mux.h" diff --git a/components/driver/gpio/rtc_io.c b/components/esp_driver_gpio/src/rtc_io.c similarity index 100% rename from components/driver/gpio/rtc_io.c rename to components/esp_driver_gpio/src/rtc_io.c diff --git a/components/esp_driver_gpio/test_apps/.build-test-rules.yml b/components/esp_driver_gpio/test_apps/.build-test-rules.yml new file mode 100644 index 000000000000..13e104d9c9a8 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/.build-test-rules.yml @@ -0,0 +1,10 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/esp_driver_gpio/test_apps: + depends_components: + - esp_driver_gpio + +components/esp_driver_gpio/test_apps/gpio_extensions: + enable: + - if: SOC_DEDICATED_GPIO_SUPPORTED == 1 + - if: SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER == 1 or SOC_GPIO_FLEX_GLITCH_FILTER_NUM > 0 diff --git a/components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt b/components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt new file mode 100644 index 000000000000..886e85131ab0 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio/CMakeLists.txt @@ -0,0 +1,21 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(gpio_test) + +if(CONFIG_COMPILER_DUMP_RTL_FILES) + add_custom_target(check_test_app_sections ALL + COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py + --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_gpio/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --elf-file ${CMAKE_BINARY_DIR}/gpio_test.elf + find-refs + --from-sections=.iram0.text + --to-sections=.flash.text,.flash.rodata + --exit-code + DEPENDS ${elf} + ) +endif() diff --git a/components/driver/test_apps/gpio/README.md b/components/esp_driver_gpio/test_apps/gpio/README.md similarity index 100% rename from components/driver/test_apps/gpio/README.md rename to components/esp_driver_gpio/test_apps/gpio/README.md diff --git a/components/driver/test_apps/gpio/main/CMakeLists.txt b/components/esp_driver_gpio/test_apps/gpio/main/CMakeLists.txt similarity index 69% rename from components/driver/test_apps/gpio/main/CMakeLists.txt rename to components/esp_driver_gpio/test_apps/gpio/main/CMakeLists.txt index de29a112f9bb..54bda14eae00 100644 --- a/components/driver/test_apps/gpio/main/CMakeLists.txt +++ b/components/esp_driver_gpio/test_apps/gpio/main/CMakeLists.txt @@ -1,10 +1,6 @@ set(srcs "test_app_main.c" "test_gpio.c") -if(CONFIG_SOC_SDM_SUPPORTED) - list(APPEND srcs "test_sigma_delta_legacy.c") -endif() - if(CONFIG_SOC_RTCIO_PIN_COUNT GREATER 0) list(APPEND srcs "test_rtcio.c") endif() @@ -12,5 +8,5 @@ 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} - PRIV_REQUIRES unity driver spi_flash + PRIV_REQUIRES unity esp_driver_gpio spi_flash WHOLE_ARCHIVE) diff --git a/components/esp_driver_gpio/test_apps/gpio/main/test_app_main.c b/components/esp_driver_gpio/test_apps/gpio/main/test_app_main.c new file mode 100644 index 000000000000..bb65240ed5fb --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio/main/test_app_main.c @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "unity_test_utils.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in gpio/rtcio driver, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (100) + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD); +} + +void app_main(void) +{ + unity_run_menu(); +} diff --git a/components/driver/test_apps/gpio/main/test_gpio.c b/components/esp_driver_gpio/test_apps/gpio/main/test_gpio.c similarity index 100% rename from components/driver/test_apps/gpio/main/test_gpio.c rename to components/esp_driver_gpio/test_apps/gpio/main/test_gpio.c diff --git a/components/driver/test_apps/gpio/main/test_gpio.h b/components/esp_driver_gpio/test_apps/gpio/main/test_gpio.h similarity index 100% rename from components/driver/test_apps/gpio/main/test_gpio.h rename to components/esp_driver_gpio/test_apps/gpio/main/test_gpio.h diff --git a/components/driver/test_apps/gpio/main/test_rtcio.c b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c similarity index 80% rename from components/driver/test_apps/gpio/main/test_rtcio.c rename to components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c index 346d774b13cc..fcc12b8a97e6 100644 --- a/components/driver/test_apps/gpio/main/test_rtcio.c +++ b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.c @@ -36,10 +36,10 @@ TEST_CASE("RTCIO_input/output_test", "[rtcio]") // init rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_init(i) ); - RTCIO_CHECK( rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT) ); - RTCIO_CHECK( rtc_gpio_pullup_dis(i) ); - RTCIO_CHECK( rtc_gpio_pulldown_dis(i) ); + RTCIO_CHECK(rtc_gpio_init(i)); + RTCIO_CHECK(rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT)); + RTCIO_CHECK(rtc_gpio_pullup_dis(i)); + RTCIO_CHECK(rtc_gpio_pulldown_dis(i)); ESP_LOGI(TAG, "gpio %d init", i); } } @@ -49,7 +49,7 @@ TEST_CASE("RTCIO_input/output_test", "[rtcio]") ESP_LOGI(TAG, "RTCIO output level %d", level); for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_set_level(i, level) ); + RTCIO_CHECK(rtc_gpio_set_level(i, level)); vTaskDelay(10 / portTICK_PERIOD_MS); if (rtc_gpio_get_level(i) != level) { ESP_LOGE(TAG, "RTCIO input/output test err, gpio%d", i); @@ -63,7 +63,7 @@ TEST_CASE("RTCIO_input/output_test", "[rtcio]") // Deinit rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_deinit(i) ); + RTCIO_CHECK(rtc_gpio_deinit(i)); } } ESP_LOGI(TAG, "RTCIO input/output test over"); @@ -81,10 +81,10 @@ TEST_CASE("RTCIO_pullup/pulldown_test", "[rtcio]") for (int i = 0; i < TEST_GPIO_PIN_COUNT; i++) { int num = rtc_io_number_get(s_test_map[i]); if (rtc_gpio_is_valid_gpio(s_test_map[i]) && num > 0 && RTCIO_SUPPORT_PU_PD(num)) { - RTCIO_CHECK( rtc_gpio_init(s_test_map[i]) ); - RTCIO_CHECK( rtc_gpio_set_direction(s_test_map[i], RTC_GPIO_MODE_INPUT_ONLY) ); - RTCIO_CHECK( rtc_gpio_pullup_dis(s_test_map[i]) ); - RTCIO_CHECK( rtc_gpio_pulldown_dis(s_test_map[i]) ); + RTCIO_CHECK(rtc_gpio_init(s_test_map[i])); + RTCIO_CHECK(rtc_gpio_set_direction(s_test_map[i], RTC_GPIO_MODE_INPUT_ONLY)); + RTCIO_CHECK(rtc_gpio_pullup_dis(s_test_map[i])); + RTCIO_CHECK(rtc_gpio_pulldown_dis(s_test_map[i])); ESP_LOGI(TAG, "gpio %d init", s_test_map[i]); } } @@ -96,11 +96,11 @@ TEST_CASE("RTCIO_pullup/pulldown_test", "[rtcio]") int num = rtc_io_number_get(s_test_map[i]); if (rtc_gpio_is_valid_gpio(s_test_map[i]) && num > 0 && RTCIO_SUPPORT_PU_PD(num)) { if (level) { - RTCIO_CHECK( rtc_gpio_pulldown_dis(s_test_map[i]) ); - RTCIO_CHECK( rtc_gpio_pullup_en(s_test_map[i]) ); + RTCIO_CHECK(rtc_gpio_pulldown_dis(s_test_map[i])); + RTCIO_CHECK(rtc_gpio_pullup_en(s_test_map[i])); } else { - RTCIO_CHECK( rtc_gpio_pullup_dis(s_test_map[i]) ); - RTCIO_CHECK( rtc_gpio_pulldown_en(s_test_map[i]) ); + RTCIO_CHECK(rtc_gpio_pullup_dis(s_test_map[i])); + RTCIO_CHECK(rtc_gpio_pulldown_en(s_test_map[i])); } vTaskDelay(20 / portTICK_PERIOD_MS); if (rtc_gpio_get_level(s_test_map[i]) != level) { @@ -116,7 +116,7 @@ TEST_CASE("RTCIO_pullup/pulldown_test", "[rtcio]") for (int i = 0; i < TEST_GPIO_PIN_COUNT; i++) { int num = rtc_io_number_get(s_test_map[i]); if (rtc_gpio_is_valid_gpio(s_test_map[i]) && num > 0 && RTCIO_SUPPORT_PU_PD(num)) { - RTCIO_CHECK( rtc_gpio_deinit(s_test_map[i]) ); + RTCIO_CHECK(rtc_gpio_deinit(s_test_map[i])); } } ESP_LOGI(TAG, "RTCIO pullup/pulldown test over"); @@ -132,10 +132,10 @@ TEST_CASE("RTCIO_output_OD_test", "[rtcio]") // init rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_init(i) ); - RTCIO_CHECK( rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT_OD) ); - RTCIO_CHECK( rtc_gpio_pullup_en(i) ); - RTCIO_CHECK( rtc_gpio_pulldown_dis(i) ); + RTCIO_CHECK(rtc_gpio_init(i)); + RTCIO_CHECK(rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT_OD)); + RTCIO_CHECK(rtc_gpio_pullup_en(i)); + RTCIO_CHECK(rtc_gpio_pulldown_dis(i)); ESP_LOGI(TAG, "gpio %d init", i); } } @@ -145,7 +145,7 @@ TEST_CASE("RTCIO_output_OD_test", "[rtcio]") ESP_LOGI(TAG, "RTCIO output level %d", level); for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_set_level(i, level) ); + RTCIO_CHECK(rtc_gpio_set_level(i, level)); vTaskDelay(10 / portTICK_PERIOD_MS); if (rtc_gpio_get_level(i) != level) { ESP_LOGE(TAG, "RTCIO output OD test err, gpio%d", i); @@ -159,7 +159,7 @@ TEST_CASE("RTCIO_output_OD_test", "[rtcio]") // Deinit rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_deinit(i) ); + RTCIO_CHECK(rtc_gpio_deinit(i)); } } ESP_LOGI(TAG, "RTCIO output OD test over"); @@ -176,11 +176,11 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") // init rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_init(i) ); - RTCIO_CHECK( rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT_OD) ); - RTCIO_CHECK( rtc_gpio_pullup_en(i) ); - RTCIO_CHECK( rtc_gpio_pulldown_dis(i) ); - RTCIO_CHECK( rtc_gpio_set_level(i, 1) ); + RTCIO_CHECK(rtc_gpio_init(i)); + RTCIO_CHECK(rtc_gpio_set_direction(i, RTC_GPIO_MODE_INPUT_OUTPUT_OD)); + RTCIO_CHECK(rtc_gpio_pullup_en(i)); + RTCIO_CHECK(rtc_gpio_pulldown_dis(i)); + RTCIO_CHECK(rtc_gpio_set_level(i, 1)); ESP_LOGI(TAG, "gpio %d init, level 1", i); } } @@ -188,9 +188,9 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") // hold all output rtcio. for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_hold_en(i) ); + RTCIO_CHECK(rtc_gpio_hold_en(i)); vTaskDelay(10 / portTICK_PERIOD_MS); - RTCIO_CHECK( rtc_gpio_set_level(i, 0) ); + RTCIO_CHECK(rtc_gpio_set_level(i, 0)); ESP_LOGI(TAG, "RTCIO output pin hold, then set level 0"); vTaskDelay(10 / portTICK_PERIOD_MS); if (rtc_gpio_get_level(i) == 0) { @@ -203,7 +203,7 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") // unhold all rtcio. for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_hold_dis(i) ); + RTCIO_CHECK(rtc_gpio_hold_dis(i)); } } @@ -213,7 +213,7 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") ESP_LOGI(TAG, "RTCIO output level %d", level); for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_set_level(i, level) ); + RTCIO_CHECK(rtc_gpio_set_level(i, level)); vTaskDelay(10 / portTICK_PERIOD_MS); if (rtc_gpio_get_level(i) != level) { ESP_LOGE(TAG, "RTCIO output OD test err, gpio%d", i); @@ -227,7 +227,7 @@ TEST_CASE("RTCIO_output_hold_test", "[rtcio]") // Deinit rtcio for (int i = 0; i < GPIO_PIN_COUNT; i++) { if (GPIO_IS_VALID_OUTPUT_GPIO(i) && rtc_gpio_is_valid_gpio(i)) { - RTCIO_CHECK( rtc_gpio_deinit(i) ); + RTCIO_CHECK(rtc_gpio_deinit(i)); } } ESP_LOGI(TAG, "RTCIO hold test over"); @@ -282,6 +282,6 @@ static void rtcio_deep_sleep_hold_test_second_stage(void) * please use logic analyzer or oscilloscope */ TEST_CASE_MULTIPLE_STAGES("RTCIO_deep_sleep_output_hold_test", "[rtcio]", - rtcio_deep_sleep_hold_test_first_stage, - rtcio_deep_sleep_hold_test_second_stage) + rtcio_deep_sleep_hold_test_first_stage, + rtcio_deep_sleep_hold_test_second_stage) #endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) diff --git a/components/driver/test_apps/gpio/main/test_rtcio.h b/components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h similarity index 100% rename from components/driver/test_apps/gpio/main/test_rtcio.h rename to components/esp_driver_gpio/test_apps/gpio/main/test_rtcio.h diff --git a/components/driver/test_apps/gpio/pytest_gpio.py b/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py similarity index 69% rename from components/driver/test_apps/gpio/pytest_gpio.py rename to components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py index f0682a007d2d..09cba4204402 100644 --- a/components/driver/test_apps/gpio/pytest_gpio.py +++ b/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py @@ -17,18 +17,6 @@ def test_gpio(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='gpio') -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS, indirect=True) -def test_legacy_sigma_delta(dut: IdfDut) -> None: - dut.run_all_single_board_cases(group='sigma_delta') - - @pytest.mark.esp32 @pytest.mark.esp32s2 @pytest.mark.esp32s3 diff --git a/components/driver/test_apps/gpio/sdkconfig.ci.iram_safe b/components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.iram_safe similarity index 100% rename from components/driver/test_apps/gpio/sdkconfig.ci.iram_safe rename to components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.iram_safe diff --git a/components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.release b/components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.release new file mode 100644 index 000000000000..91d93f163e62 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio/sdkconfig.ci.release @@ -0,0 +1,5 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/esp_driver_gpio/test_apps/gpio/sdkconfig.defaults b/components/esp_driver_gpio/test_apps/gpio/sdkconfig.defaults new file mode 100644 index 000000000000..fa8ac618b948 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT_EN=n diff --git a/components/driver/test_apps/gpio_extensions/CMakeLists.txt b/components/esp_driver_gpio/test_apps/gpio_extensions/CMakeLists.txt similarity index 87% rename from components/driver/test_apps/gpio_extensions/CMakeLists.txt rename to components/esp_driver_gpio/test_apps/gpio_extensions/CMakeLists.txt index 42d10a855392..fb191523e9da 100644 --- a/components/driver/test_apps/gpio_extensions/CMakeLists.txt +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/CMakeLists.txt @@ -10,7 +10,7 @@ project(gpio_extension_test) if(CONFIG_COMPILER_DUMP_RTL_FILES) add_custom_target(check_test_app_sections ALL COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py - --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_gpio/,${CMAKE_BINARY_DIR}/esp-idf/hal/ --elf-file ${CMAKE_BINARY_DIR}/gpio_extension_test.elf find-refs --from-sections=.iram0.text diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/README.md b/components/esp_driver_gpio/test_apps/gpio_extensions/README.md new file mode 100644 index 000000000000..d2553ff6db36 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/README.md @@ -0,0 +1,2 @@ +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | diff --git a/components/driver/test_apps/gpio_extensions/main/CMakeLists.txt b/components/esp_driver_gpio/test_apps/gpio_extensions/main/CMakeLists.txt similarity index 82% rename from components/driver/test_apps/gpio_extensions/main/CMakeLists.txt rename to components/esp_driver_gpio/test_apps/gpio_extensions/main/CMakeLists.txt index 81700812a48e..3b4bd6d62041 100644 --- a/components/driver/test_apps/gpio_extensions/main/CMakeLists.txt +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/main/CMakeLists.txt @@ -8,10 +8,6 @@ if(CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER OR (CONFIG_SOC_GPIO_FLEX_GLITCH_FIL list(APPEND srcs "test_gpio_filter.c") endif() -if(CONFIG_SOC_SDM_SUPPORTED) - list(APPEND srcs "test_sdm.c") -endif() - if(CONFIG_SOC_GPIO_SUPPORT_PIN_HYS_FILTER) list(APPEND srcs "test_hysteresis.c") endif() @@ -19,5 +15,5 @@ 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} - PRIV_REQUIRES unity driver + PRIV_REQUIRES unity esp_driver_gpio WHOLE_ARCHIVE) diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_app_main.c b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_app_main.c new file mode 100644 index 000000000000..60becdb1e94d --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_app_main.c @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_utils.h" +#include "esp_heap_caps.h" + +// Some resources are lazy allocated in the driver, the threshold is left for that case +#define TEST_MEMORY_LEAK_THRESHOLD (300) + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + esp_reent_cleanup(); //clean up some of the newlib's lazy allocations + unity_utils_evaluate_leaks_direct(TEST_MEMORY_LEAK_THRESHOLD); +} + +void app_main(void) +{ + // ____ ____ ___ ___ _____ _ _____ _ + // / ___| _ \_ _/ _ \ | ____|_ _| |_ |_ _|__ ___| |_ + // | | _| |_) | | | | | | _| \ \/ / __| | |/ _ \/ __| __| + // | |_| | __/| | |_| | | |___ > <| |_ | | __/\__ \ |_ + // \____|_| |___\___/ |_____/_/\_\\__| |_|\___||___/\__| + printf(" ____ ____ ___ ___ _____ _ _____ _\r\n"); + printf(" / ___| _ \\_ _/ _ \\ | ____|_ _| |_ |_ _|__ ___| |_\r\n"); + printf("| | _| |_) | | | | | | _| \\ \\/ / __| | |/ _ \\/ __| __|\r\n"); + printf("| |_| | __/| | |_| | | |___ > <| |_ | | __/\\__ \\ |_\r\n"); + printf(" \\____|_| |___\\___/ |_____/_/\\_\\\\__| |_|\\___||___/\\__|\r\n"); + unity_run_menu(); +} diff --git a/components/driver/test_apps/gpio_extensions/main/test_dedicated_gpio.c b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_dedicated_gpio.c similarity index 100% rename from components/driver/test_apps/gpio_extensions/main/test_dedicated_gpio.c rename to components/esp_driver_gpio/test_apps/gpio_extensions/main/test_dedicated_gpio.c diff --git a/components/driver/test_apps/gpio_extensions/main/test_gpio_filter.c b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_gpio_filter.c similarity index 100% rename from components/driver/test_apps/gpio_extensions/main/test_gpio_filter.c rename to components/esp_driver_gpio/test_apps/gpio_extensions/main/test_gpio_filter.c diff --git a/components/driver/test_apps/gpio_extensions/main/test_hysteresis.c b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_hysteresis.c similarity index 93% rename from components/driver/test_apps/gpio_extensions/main/test_hysteresis.c rename to components/esp_driver_gpio/test_apps/gpio_extensions/main/test_hysteresis.c index e3acf87b9234..d75594d2a9f0 100644 --- a/components/driver/test_apps/gpio_extensions/main/test_hysteresis.c +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/main/test_hysteresis.c @@ -9,7 +9,6 @@ #include "unity.h" #include "driver/gpio.h" - /** * NOTE: To run this special feature test case, a slope analog signal is needed. * A simple RC circuit used here to formate pin switches to continuos slop signal. @@ -29,10 +28,9 @@ * which enabled the hysteresis feature directly to have a test. **/ - static void test_gpio_hysteresis_intr_handler(void *args) { - esp_rom_printf("%d\n", ++*((uint32_t *)args)); + esp_rom_printf("%d\n", ++ * ((uint32_t *)args)); } // This case is now tested only manually @@ -40,10 +38,10 @@ TEST_CASE("GPIO Input hysteresis filter", "[gpio_filter][timeout=50][ignore]") { const gpio_num_t TEST_HYS_IO = 26; const gpio_num_t TEST_WAVE_IO = 27; - uint32_t intr_cnt=0; + uint32_t intr_cnt = 0; gpio_config_t gpio_cfg = { - .pin_bit_mask = 1 << TEST_WAVE_IO, + .pin_bit_mask = (1 << TEST_WAVE_IO), .mode = GPIO_MODE_OUTPUT, .pull_down_en = GPIO_PULLDOWN_ENABLE, }; @@ -59,7 +57,7 @@ TEST_CASE("GPIO Input hysteresis filter", "[gpio_filter][timeout=50][ignore]") gpio_isr_handler_add(TEST_HYS_IO, test_gpio_hysteresis_intr_handler, &intr_cnt); // generate 5 rising and falling slopes to test gpio interrupt - for (uint8_t i=0; i<5; i++) { + for (uint8_t i = 0; i < 5; i++) { printf("----falling %dth\n", i); gpio_set_level(TEST_WAVE_IO, 0); vTaskDelay(1500); diff --git a/components/driver/test_apps/gpio_extensions/pytest_gpio_extensions.py b/components/esp_driver_gpio/test_apps/gpio_extensions/pytest_gpio_extensions.py similarity index 72% rename from components/driver/test_apps/gpio_extensions/pytest_gpio_extensions.py rename to components/esp_driver_gpio/test_apps/gpio_extensions/pytest_gpio_extensions.py index 7da5ce3c9d96..a51ae5e89d47 100644 --- a/components/driver/test_apps/gpio_extensions/pytest_gpio_extensions.py +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/pytest_gpio_extensions.py @@ -10,19 +10,6 @@ ] -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32h2 -@pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS, indirect=True) -def test_sdm(dut: IdfDut) -> None: - dut.run_all_single_board_cases(group='sdm') - - @pytest.mark.esp32c2 @pytest.mark.esp32c3 @pytest.mark.esp32c6 diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.iram_safe b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.iram_safe new file mode 100644 index 000000000000..9eb666b35b88 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.iram_safe @@ -0,0 +1,9 @@ +CONFIG_COMPILER_DUMP_RTL_FILES=y +CONFIG_COMPILER_OPTIMIZATION_NONE=y +# place non-ISR FreeRTOS functions in Flash +CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y +# silent the error check, as the error string are stored in rodata, causing RTL check failure +CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +# GPIO test uses IPC call, the default stack size of IPC task can satisfy the -O0 optimization +CONFIG_ESP_IPC_TASK_STACK_SIZE=2048 diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.release b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.release new file mode 100644 index 000000000000..91d93f163e62 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.ci.release @@ -0,0 +1,5 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.defaults b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.defaults new file mode 100644 index 000000000000..fa8ac618b948 --- /dev/null +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_FREERTOS_HZ=1000 +CONFIG_ESP_TASK_WDT_EN=n diff --git a/components/esp_driver_pcnt/CMakeLists.txt b/components/esp_driver_pcnt/CMakeLists.txt index fa3864076f8c..d146afbab477 100644 --- a/components/esp_driver_pcnt/CMakeLists.txt +++ b/components/esp_driver_pcnt/CMakeLists.txt @@ -11,7 +11,7 @@ else() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${public_include} PRIV_REQUIRES "esp_pm" - "driver" # will be replaced by esp_driver_gpio + "esp_driver_gpio" LDFRAGMENTS "linker.lf" ) endif() diff --git a/components/esp_eth/CMakeLists.txt b/components/esp_eth/CMakeLists.txt index 55f0fc093730..439180e557f3 100644 --- a/components/esp_eth/CMakeLists.txt +++ b/components/esp_eth/CMakeLists.txt @@ -67,7 +67,7 @@ endif() if(CONFIG_ETH_ENABLED) if(CONFIG_ETH_USE_SPI_ETHERNET) - idf_component_optional_requires(PUBLIC driver) + idf_component_optional_requires(PUBLIC driver esp_driver_gpio) endif() idf_component_optional_requires(PRIVATE esp_netif esp_pm) endif() diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index ad5e37ad6485..f996e17e520b 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -50,8 +50,11 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "sleep_retention.c" "sleep_system_peripheral.c" "sleep_clock.c") endif() - # [refactor-todo]: requires "driver" for GPIO and RTC (by sleep_gpio and sleep_modes) - list(APPEND priv_requires driver esp_timer) + # [refactor-todo] + list(APPEND priv_requires driver # for UART (by sleep_modes) + esp_driver_gpio # for GPIO and RTC (by sleep_gpio and sleep_modes) + esp_timer + esp_pm) list(APPEND priv_requires esp_mm) diff --git a/components/esp_lcd/CMakeLists.txt b/components/esp_lcd/CMakeLists.txt index 9e1c10b13744..aa0595a54dbc 100644 --- a/components/esp_lcd/CMakeLists.txt +++ b/components/esp_lcd/CMakeLists.txt @@ -27,5 +27,5 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${includes} PRIV_REQUIRES ${priv_requires} - REQUIRES driver + REQUIRES driver esp_driver_gpio LDFRAGMENTS linker.lf) diff --git a/components/esp_pm/CMakeLists.txt b/components/esp_pm/CMakeLists.txt index 72c974237112..a4b414e99b22 100644 --- a/components/esp_pm/CMakeLists.txt +++ b/components/esp_pm/CMakeLists.txt @@ -6,5 +6,5 @@ endif() idf_component_register(SRCS "pm_locks.c" "pm_trace.c" "pm_impl.c" INCLUDE_DIRS include - PRIV_REQUIRES esp_system driver esp_timer + PRIV_REQUIRES esp_system driver esp_driver_gpio esp_timer LDFRAGMENTS linker.lf) diff --git a/components/esp_pm/linker.lf b/components/esp_pm/linker.lf index ea712c420c61..b1809a422a85 100644 --- a/components/esp_pm/linker.lf +++ b/components/esp_pm/linker.lf @@ -77,7 +77,7 @@ entries: esp_time_impl:esp_set_time_from_rtc (noflash) [mapping:driver_pm] -archive: libdriver.a +archive: libesp_driver_gpio.a entries: if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y: gpio:gpio_sleep_pupd_config_unapply (noflash) diff --git a/components/espcoredump/CMakeLists.txt b/components/espcoredump/CMakeLists.txt index 3b1e88fce325..32eb4012087f 100644 --- a/components/espcoredump/CMakeLists.txt +++ b/components/espcoredump/CMakeLists.txt @@ -27,10 +27,14 @@ elseif(CONFIG_IDF_TARGET_ARCH_RISCV) endif() idf_component_register(SRCS ${srcs} - INCLUDE_DIRS ${includes} - PRIV_INCLUDE_DIRS ${priv_includes} - LDFRAGMENTS linker.lf - PRIV_REQUIRES esp_partition spi_flash bootloader_support mbedtls esp_rom soc esp_system driver) + INCLUDE_DIRS ${includes} + PRIV_INCLUDE_DIRS ${priv_includes} + LDFRAGMENTS linker.lf + PRIV_REQUIRES esp_partition spi_flash bootloader_support mbedtls esp_rom soc esp_system + esp_driver_gpio + # [refactor-todo] esp_flash_internal.h -> spi_common_internal.h requires cleanup + driver + ) if(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF) target_link_libraries(${COMPONENT_LIB} PRIVATE idf::esp_app_format) diff --git a/components/fatfs/CMakeLists.txt b/components/fatfs/CMakeLists.txt index b6a288e0d0cb..e9ae1f88744a 100644 --- a/components/fatfs/CMakeLists.txt +++ b/components/fatfs/CMakeLists.txt @@ -24,7 +24,7 @@ else() list(APPEND requires "sdmmc") - list(APPEND priv_requires "vfs") + list(APPEND priv_requires "vfs" "esp_driver_gpio") endif() idf_component_register(SRCS ${srcs} diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index 3a5963f26ce0..c78ec7d1127b 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.h @@ -508,6 +508,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { if (gpio_num < 32) { diff --git a/components/hal/esp32c2/include/hal/gpio_ll.h b/components/hal/esp32c2/include/hal/gpio_ll.h index ad705731104c..d9ae5c07ed51 100644 --- a/components/hal/esp32c2/include/hal/gpio_ll.h +++ b/components/hal/esp32c2/include/hal/gpio_ll.h @@ -332,6 +332,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { return (hw->in.in_data_next >> gpio_num) & 0x1; diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index 75e9e82c60e1..6ff4bf6492cb 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -344,6 +344,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { return (hw->in.data >> gpio_num) & 0x1; diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index 5bd7ea1178c1..a2aab0341b37 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -338,6 +338,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { return (hw->in.in_data_next >> gpio_num) & 0x1; diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index df08c857bed9..f9090a6fa30d 100644 --- a/components/hal/esp32h2/include/hal/gpio_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_ll.h @@ -380,6 +380,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, gpio_num_t gpio_num, uint32 * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, gpio_num_t gpio_num) { return (hw->in.in_data_next >> gpio_num) & 0x1; diff --git a/components/hal/esp32p4/include/hal/gpio_ll.h b/components/hal/esp32p4/include/hal/gpio_ll.h index b3c41a5faaac..986edcdacc72 100644 --- a/components/hal/esp32p4/include/hal/gpio_ll.h +++ b/components/hal/esp32p4/include/hal/gpio_ll.h @@ -411,6 +411,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { if (gpio_num < 32) { diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index 80de85988773..8eaf403644a2 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.h @@ -351,6 +351,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { if (gpio_num < 32) { diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index 394d7681d1a0..9fe90040f4b3 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -367,6 +367,7 @@ static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t * - 0 the GPIO input level is 0 * - 1 the GPIO input level is 1 */ +__attribute__((always_inline)) static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num) { if (gpio_num < 32) { diff --git a/components/soc/include/soc/rtc_io_periph.h b/components/soc/include/soc/rtc_io_periph.h index 95315e064b4b..3eadcfda1a0d 100644 --- a/components/soc/include/soc/rtc_io_periph.h +++ b/components/soc/include/soc/rtc_io_periph.h @@ -6,8 +6,7 @@ #pragma once - -#include "soc/soc.h" +#include //include soc related (generated) definitions #include "soc/soc_caps.h" diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 75879f1bd333..0133cf45aaeb 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -48,7 +48,9 @@ else() "spi_flash_os_func_noos.c") list(APPEND srcs ${cache_srcs}) - set(priv_requires bootloader_support app_update soc driver esp_mm) + set(priv_requires bootloader_support app_update soc esp_mm + driver esp_driver_gpio # TODO: IDF-8503 move spi_bus_lock to esp_hw_support component + ) endif() idf_component_register(SRCS "${srcs}" diff --git a/components/spi_flash/test_apps/.build-test-rules.yml b/components/spi_flash/test_apps/.build-test-rules.yml index a348aed09f59..1c73293f31a0 100644 --- a/components/spi_flash/test_apps/.build-test-rules.yml +++ b/components/spi_flash/test_apps/.build-test-rules.yml @@ -6,13 +6,13 @@ components/spi_flash/test_apps/esp_flash: temporary: true reason: target esp32p4 is not supported yet # TODO: IDF-7499 depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* - components/bootloader_support/bootloader_flash/**/* depends_components: - esp_mm - esp_psram - spi_flash + - esp_driver_gpio - esptool_py # Some flash related kconfigs are listed here. components/spi_flash/test_apps/flash_encryption: @@ -54,11 +54,11 @@ components/spi_flash/test_apps/mspi_test: temporary: true reason: not supported yet #TODO: IDF-7556 for p4 depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* - components/bootloader_support/bootloader_flash/**/* depends_components: - esp_mm - esp_psram - spi_flash + - esp_driver_gpio - esptool_py # Some flash related kconfigs are listed here. diff --git a/components/usb/CMakeLists.txt b/components/usb/CMakeLists.txt index aef5ea50ac7e..84fdacccc9d9 100644 --- a/components/usb/CMakeLists.txt +++ b/components/usb/CMakeLists.txt @@ -10,7 +10,7 @@ set(priv_include) # As CONFIG_USB_OTG_SUPPORTED comes from Kconfig, it is not evaluated yet # when components are being registered. # Thus, always add the (private) requirements, regardless of Kconfig -set(priv_require driver) # usb_phy driver relies on gpio driver API +set(priv_require esp_driver_gpio) # usb_phy driver relies on gpio driver API if(CONFIG_USB_OTG_SUPPORTED) list(APPEND srcs "hcd_dwc.c" diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 06df821f1a9a..516a1cf013a1 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -79,12 +79,6 @@ INPUT = \ $(PROJECT_PATH)/components/driver/dac/include/driver/dac_cosine.h \ $(PROJECT_PATH)/components/driver/dac/include/driver/dac_oneshot.h \ $(PROJECT_PATH)/components/driver/dac/include/driver/dac_types.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/dedic_gpio.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/gpio.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/gpio_etm.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/gpio_filter.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/lp_io.h \ - $(PROJECT_PATH)/components/driver/gpio/include/driver/rtc_io.h \ $(PROJECT_PATH)/components/driver/gptimer/include/driver/gptimer.h \ $(PROJECT_PATH)/components/driver/gptimer/include/driver/gptimer_etm.h \ $(PROJECT_PATH)/components/driver/gptimer/include/driver/gptimer_types.h \ @@ -139,6 +133,12 @@ INPUT = \ $(PROJECT_PATH)/components/esp_common/include/esp_check.h \ $(PROJECT_PATH)/components/esp_common/include/esp_err.h \ $(PROJECT_PATH)/components/esp_common/include/esp_idf_version.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/dedic_gpio.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/gpio.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/gpio_etm.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/gpio_filter.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/lp_io.h \ + $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/rtc_io.h \ $(PROJECT_PATH)/components/esp_driver_pcnt/include/driver/pulse_cnt.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_com.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_driver.h \ diff --git a/docs/en/api-guides/jtag-debugging/debugging-examples.rst b/docs/en/api-guides/jtag-debugging/debugging-examples.rst index 4b09aa1ac9e9..34f1cfea4fb4 100644 --- a/docs/en/api-guides/jtag-debugging/debugging-examples.rst +++ b/docs/en/api-guides/jtag-debugging/debugging-examples.rst @@ -497,7 +497,7 @@ If you enter ``s`` instead, then debugger will step inside subroutine calls:: Target halted. PRO_CPU: PC=0x400DB74B (active) APP_CPU: PC=0x400D1128 Target halted. PRO_CPU: PC=0x400DC04C (active) APP_CPU: PC=0x400D1128 Target halted. PRO_CPU: PC=0x400DC04F (active) APP_CPU: PC=0x400D1128 - gpio_set_level (gpio_num=GPIO_NUM_4, level=0) at /home/user-name/esp/esp-idf/components/driver/gpio/gpio.c:183 + gpio_set_level (gpio_num=GPIO_NUM_4, level=0) at /home/user-name/esp/esp-idf/components/esp_driver_gpio/src/gpio.c:183 183 GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG); (gdb) diff --git a/docs/en/contribute/documenting-code.rst b/docs/en/contribute/documenting-code.rst index aa5fcd73e3d3..5fc2c772527b 100644 --- a/docs/en/contribute/documenting-code.rst +++ b/docs/en/contribute/documenting-code.rst @@ -123,7 +123,7 @@ When writing code, please follow the guidelines below: For practical example see :component_file:`nvs_flash/include/nvs.h`. -4. You may want to go even further and skip some code like repetitive defines or enumerations. In such case, enclose the code within ``/** @cond */`` and ``/** @endcond */`` commands. Example of such implementation is provided in :component_file:`driver/gpio/include/driver/gpio.h`. +4. You may want to go even further and skip some code like repetitive defines or enumerations. In such case, enclose the code within ``/** @cond */`` and ``/** @endcond */`` commands. Example of such implementation is provided in :component_file:`esp_driver_gpio/include/driver/gpio.h`. 5. Use markdown to make your documentation even more readable. You will add headers, links, tables and more. :: diff --git a/docs/zh_CN/api-guides/jtag-debugging/debugging-examples.rst b/docs/zh_CN/api-guides/jtag-debugging/debugging-examples.rst index dbfa846cf064..c15f8c50e461 100644 --- a/docs/zh_CN/api-guides/jtag-debugging/debugging-examples.rst +++ b/docs/zh_CN/api-guides/jtag-debugging/debugging-examples.rst @@ -497,7 +497,7 @@ Target halted. PRO_CPU: PC=0x400DB74B (active) APP_CPU: PC=0x400D1128 Target halted. PRO_CPU: PC=0x400DC04C (active) APP_CPU: PC=0x400D1128 Target halted. PRO_CPU: PC=0x400DC04F (active) APP_CPU: PC=0x400D1128 - gpio_set_level (gpio_num=GPIO_NUM_4, level=0) at /home/user-name/esp/esp-idf/components/driver/gpio/gpio.c:183 + gpio_set_level (gpio_num=GPIO_NUM_4, level=0) at /home/user-name/esp/esp-idf/components/esp_driver_gpio/src/gpio.c:183 183 GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG); (gdb) diff --git a/docs/zh_CN/contribute/documenting-code.rst b/docs/zh_CN/contribute/documenting-code.rst index 0568aaa1b12d..a048b2984992 100644 --- a/docs/zh_CN/contribute/documenting-code.rst +++ b/docs/zh_CN/contribute/documenting-code.rst @@ -123,7 +123,7 @@ Doxygen 支持多种格式,并支持文档内部的多个详情级别,具有 如需更多应用示例,请参考 :component_file:`nvs_flash/include/nvs.h`。 -4. 如需进一步跳过重复定义或枚举等代码,可使用 ``/** @cond */`` 和 ``/** @endcond */`` 命令附上该代码。相关应用实例,请参考 :component_file:`driver/gpio/include/driver/gpio.h`。 +4. 如需进一步跳过重复定义或枚举等代码,可使用 ``/** @cond */`` 和 ``/** @endcond */`` 命令附上该代码。相关应用实例,请参考 :component_file:`esp_driver_gpio/include/driver/gpio.h`。 5. 使用 markdown 添加标题、链接和表格等,增强文档的可读性。 :: diff --git a/examples/bluetooth/.build-test-rules.yml b/examples/bluetooth/.build-test-rules.yml index 0da95ba3046a..279c3bed7601 100644 --- a/examples/bluetooth/.build-test-rules.yml +++ b/examples/bluetooth/.build-test-rules.yml @@ -24,8 +24,8 @@ examples/bluetooth/bluedroid/ble: examples/bluetooth/bluedroid/ble/ble_hid_device_demo: disable: - if: SOC_BT_SUPPORTED != 1 - depends_filepatterns: - - components/driver/gpio/**/* + depends_components: + - esp_driver_gpio examples/bluetooth/bluedroid/ble_50: disable: @@ -41,11 +41,11 @@ examples/bluetooth/bluedroid/classic_bt: - esp_log - esp_console - vfs + - esp_driver_gpio depends_filepatterns: - components/driver/dac/**/* - components/driver/i2s/**/* - components/driver/uart/**/* - - components/driver/gpio/**/* examples/bluetooth/bluedroid/coex/a2dp_gatts_coex: <<: *bt_default_depends @@ -84,9 +84,9 @@ examples/bluetooth/esp_ble_mesh: - vfs - mbedtls - touch_element + - esp_driver_gpio depends_filepatterns: - examples/bluetooth/esp_ble_mesh/common_components/**/* - - components/driver/gpio/**/* examples/bluetooth/esp_ble_mesh/aligenie_demo: enable: @@ -99,9 +99,9 @@ examples/bluetooth/esp_ble_mesh/aligenie_demo: - vfs - mbedtls - driver + - esp_driver_gpio depends_filepatterns: - examples/bluetooth/esp_ble_mesh/common_components/**/* - - components/driver/gpio/**/* examples/bluetooth/esp_ble_mesh/coex_test: enable: @@ -117,9 +117,9 @@ examples/bluetooth/esp_ble_mesh/coex_test: - esp_coex - esp_wifi - esp_netif + - esp_driver_gpio depends_filepatterns: - examples/bluetooth/esp_ble_mesh/common_components/**/* - - components/driver/gpio/**/* examples/bluetooth/esp_ble_mesh/wifi_coexist: disable: @@ -134,9 +134,9 @@ examples/bluetooth/esp_ble_mesh/wifi_coexist: - esp_coex - esp_wifi - esp_netif + - esp_driver_gpio depends_filepatterns: - examples/bluetooth/esp_ble_mesh/common_components/**/* - - components/driver/gpio/**/* examples/bluetooth/hci: <<: *bt_default_depends @@ -271,8 +271,9 @@ examples/bluetooth/nimble/throughput_app: <<: *bt_default_depends disable: - if: SOC_BLE_SUPPORTED != 1 + depends_components: + - esp_driver_gpio depends_filepatterns: - examples/bluetooth/nimble/common/**/* - examples/bluetooth/nimble/throughput_app/blecent_throughput/components/**/* - components/driver/uart/**/* - - components/driver/gpio/**/* diff --git a/examples/bluetooth/esp_ble_mesh/common_components/button/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/common_components/button/CMakeLists.txt index f9b07dafe524..24adc8d5b3f9 100644 --- a/examples/bluetooth/esp_ble_mesh/common_components/button/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/common_components/button/CMakeLists.txt @@ -1,3 +1,3 @@ idf_component_register(SRCS "button.c" "button_obj.cpp" INCLUDE_DIRS "." "include" - PRIV_REQUIRES driver esp_timer) + PRIV_REQUIRES esp_driver_gpio esp_timer) diff --git a/examples/bluetooth/esp_ble_mesh/common_components/light_driver/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/common_components/light_driver/CMakeLists.txt index 6dc16c7094cb..fe06e61668c2 100644 --- a/examples/bluetooth/esp_ble_mesh/common_components/light_driver/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/common_components/light_driver/CMakeLists.txt @@ -7,6 +7,6 @@ set(COMPONENT_SRCS set(COMPONENT_ADD_INCLUDEDIRS ". include") # requirements can't depend on config -set(COMPONENT_REQUIRES example_nvs driver) +set(COMPONENT_REQUIRES example_nvs driver esp_driver_gpio) register_component() diff --git a/examples/ethernet/.build-test-rules.yml b/examples/ethernet/.build-test-rules.yml index af1670d1c631..c0e129ef8017 100644 --- a/examples/ethernet/.build-test-rules.yml +++ b/examples/ethernet/.build-test-rules.yml @@ -8,8 +8,8 @@ examples/ethernet/basic: - esp_netif - lwip - esp_event + - esp_driver_gpio depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* examples/ethernet/enc28j60: @@ -22,8 +22,8 @@ examples/ethernet/enc28j60: - esp_netif - lwip - esp_event + - esp_driver_gpio depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* examples/ethernet/iperf: @@ -37,8 +37,8 @@ examples/ethernet/iperf: - lwip - esp_event - console + - esp_driver_gpio depends_filepatterns: - - components/driver/gpio/**/* - components/driver/spi/**/* - examples/common_components/iperf/**/* - examples/common_components/protocol_examples_common/**/* diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index e8c40bd3596f..834340c6e129 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -27,6 +27,10 @@ examples/peripherals/dac: disable: - if: SOC_DAC_SUPPORTED != 1 +examples/peripherals/gpio: + depends_components: + - esp_driver_gpio + examples/peripherals/gpio/matrix_keyboard: enable: - if: IDF_TARGET == "esp32s2" diff --git a/examples/peripherals/spi_master/hd_eeprom/components/eeprom/linker.lf b/examples/peripherals/spi_master/hd_eeprom/components/eeprom/linker.lf index b0d89b8d770b..e9b6befe51e6 100644 --- a/examples/peripherals/spi_master/hd_eeprom/components/eeprom/linker.lf +++ b/examples/peripherals/spi_master/hd_eeprom/components/eeprom/linker.lf @@ -5,20 +5,23 @@ [mapping:eeprom] archive: libeeprom.a entries: - * (noflash) + if EXAMPLE_USE_SPI1_PINS = y: + * (noflash) [mapping:ext_driver] -archive: libdriver.a +archive: libesp_driver_gpio.a entries: - # gpio_set_level, gpio_get_level, gpio_context, _gpio_hal, etc... - gpio (noflash) + if EXAMPLE_USE_SPI1_PINS = y: + gpio: gpio_intr_enable (noflash) [mapping:ext_soc] archive: libhal.a entries: - gpio_hal (noflash) + if EXAMPLE_USE_SPI1_PINS = y: + gpio_hal: gpio_hal_intr_enable_on_core (noflash) [mapping:ext_newlib] archive: libnewlib.a entries: - time:usleep (noflash) + if EXAMPLE_USE_SPI1_PINS = y: + time:usleep (noflash) diff --git a/examples/peripherals/spi_master/hd_eeprom/components/eeprom/spi_eeprom.c b/examples/peripherals/spi_master/hd_eeprom/components/eeprom/spi_eeprom.c index 4d0148239714..4e57ba6e6486 100644 --- a/examples/peripherals/spi_master/hd_eeprom/components/eeprom/spi_eeprom.c +++ b/examples/peripherals/spi_master/hd_eeprom/components/eeprom/spi_eeprom.c @@ -51,16 +51,6 @@ typedef struct eeprom_context_t eeprom_context_t; static const char TAG[] = "eeprom"; -// Workaround: The driver depends on some data in the flash and cannot be placed to DRAM easily for -// now. Using the version in LL instead. -#define gpio_set_level gpio_set_level_patch -#include "hal/gpio_ll.h" -static inline esp_err_t gpio_set_level_patch(gpio_num_t gpio_num, uint32_t level) -{ - gpio_ll_set_level(&GPIO, gpio_num, level); - return ESP_OK; -} - static esp_err_t eeprom_simple_cmd(eeprom_context_t *ctx, uint16_t cmd) { spi_transaction_t t = { diff --git a/examples/peripherals/spi_master/hd_eeprom/main/Kconfig.projbuild b/examples/peripherals/spi_master/hd_eeprom/main/Kconfig.projbuild index e48344e2fc11..4bee4e13813b 100644 --- a/examples/peripherals/spi_master/hd_eeprom/main/Kconfig.projbuild +++ b/examples/peripherals/spi_master/hd_eeprom/main/Kconfig.projbuild @@ -4,9 +4,12 @@ menu "Example Configuration" bool "The example uses SPI1 shared pins for EEPROM connection" default n depends on SPI_FLASH_SHARE_SPI1_BUS + select GPIO_CTRL_FUNC_IN_IRAM + select COMPILER_OPTIMIZATION_CHECKS_SILENT # silent the error check, as the error string are stored in rodata help Enable this option will make the EEPROM use SPI1 pins, which is shared with the main - flash chip. + flash chip. Therefore, when doing transaction on SPI1 bus, data cannot be fetched + from the flash, so all the data used during this time should be put into the internal RAM. Currently this example hasn't supported SPI1 pins on other chips yet. diff --git a/examples/system/console/advanced/components/cmd_system/CMakeLists.txt b/examples/system/console/advanced/components/cmd_system/CMakeLists.txt index 4c0eae43a74a..4fa5d30b9173 100644 --- a/examples/system/console/advanced/components/cmd_system/CMakeLists.txt +++ b/examples/system/console/advanced/components/cmd_system/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register(SRCS "cmd_system.c" "cmd_system_common.c" INCLUDE_DIRS . - REQUIRES console spi_flash driver) + REQUIRES console spi_flash driver esp_driver_gpio) target_sources(${COMPONENT_LIB} PRIVATE cmd_system_sleep.c) diff --git a/tools/mocks/driver/CMakeLists.txt b/tools/mocks/driver/CMakeLists.txt index 7460356fefcd..5733e1b34c85 100644 --- a/tools/mocks/driver/CMakeLists.txt +++ b/tools/mocks/driver/CMakeLists.txt @@ -5,14 +5,14 @@ message(STATUS "building DRIVER MOCKS (only SPI master, I2C, RMT, USB-serial and idf_component_get_property(original_driver_dir driver COMPONENT_OVERRIDEN_DIR) set(include_dirs + "${IDF_PATH}/components/esp_driver_gpio/include/driver" + "${IDF_PATH}/components/esp_driver_gpio/include" "${original_driver_dir}/i2c/include/driver" "${original_driver_dir}/spi/include/driver" - "${original_driver_dir}/gpio/include/driver" "${original_driver_dir}/rmt/include/driver" "${original_driver_dir}/usb_serial_jtag/include/driver" "${original_driver_dir}/i2c/include" "${original_driver_dir}/spi/include" - "${original_driver_dir}/gpio/include" "${original_driver_dir}/rmt/include" "${original_driver_dir}/usb_serial_jtag/include" "${CMAKE_CURRENT_SOURCE_DIR}/../hal/include") @@ -20,10 +20,10 @@ set(include_dirs idf_component_mock(INCLUDE_DIRS ${include_dirs} REQUIRES freertos MOCK_HEADER_FILES + ${IDF_PATH}/components/esp_driver_gpio/include/driver/gpio.h ${original_driver_dir}/spi/include/driver/spi_master.h ${original_driver_dir}/spi/include/driver/spi_common.h ${original_driver_dir}/i2c/include/driver/i2c.h - ${original_driver_dir}/gpio/include/driver/gpio.h ${original_driver_dir}/rmt/include/driver/rmt_rx.h ${original_driver_dir}/rmt/include/driver/rmt_tx.h ${original_driver_dir}/rmt/include/driver/rmt_common.h diff --git a/tools/test_apps/system/g1_components/CMakeLists.txt b/tools/test_apps/system/g1_components/CMakeLists.txt index 204005e1cdea..ceb1b6512ef6 100644 --- a/tools/test_apps/system/g1_components/CMakeLists.txt +++ b/tools/test_apps/system/g1_components/CMakeLists.txt @@ -35,7 +35,7 @@ set(extra_components_which_shouldnt_be_included cxx # [refactor-todo]: driver is a dependency of esp_pm, spi_flash, vfs, esp_wifi # all of these should be removed from G1 except for spi_flash. - driver esp_driver_pcnt + driver esp_driver_gpio esp_driver_pcnt # esp_app_format is dependency of bootloader_support, app_update esp_app_format # esp_bootloader_format is dependency of bootloader_support, app_update From c815fe67fa51a75ba0448dabbaee0555a429f887 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 3 Nov 2023 15:44:08 +0530 Subject: [PATCH 150/161] fix(wpa_supplicant): memzero wifi config before sending config event --- components/wpa_supplicant/esp_supplicant/src/esp_dpp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index d1e7256be6f0..aee399df9014 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -179,6 +179,7 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth, { wifi_config_t *wifi_cfg = &s_dpp_ctx.wifi_cfg; + os_memset(wifi_cfg, 0, sizeof(wifi_config_t)); if (conf->ssid_len) { os_memcpy(wifi_cfg->sta.ssid, conf->ssid, conf->ssid_len); } From b366dad79b51750483929a0cfbe57beaa2260a7c Mon Sep 17 00:00:00 2001 From: KonstantinKondrashov Date: Tue, 31 Oct 2023 22:02:37 +0800 Subject: [PATCH 151/161] fix(hal): Fix incorrect behavior of hal_memcpy Closes https://github.com/espressif/esp-idf/issues/12489 --- components/hal/platform_port/include/hal/misc.h | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/components/hal/platform_port/include/hal/misc.h b/components/hal/platform_port/include/hal/misc.h index c6e50ad8c315..29ef91136bda 100644 --- a/components/hal/platform_port/include/hal/misc.h +++ b/components/hal/platform_port/include/hal/misc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -66,11 +66,7 @@ extern "C" { * @param len The number of bytes to be copied * @return a pointer to destination */ -__attribute__((always_inline)) static inline void *hal_memcpy(void *dst_mem, const void *src_mem, size_t len) -{ - asm("" : "+r"(dst_mem), "+r"(src_mem)); - return memcpy(dst_mem, src_mem, len); -} +#define hal_memcpy(dst_mem, src_mem, len) (__extension__({memcpy(dst_mem, src_mem, len);})) /** * @brief Sets the first num bytes of the block of memory pointed by ptr to the specified value @@ -82,11 +78,7 @@ __attribute__((always_inline)) static inline void *hal_memcpy(void *dst_mem, con * @param len The number of bytes to be copied * @return a pointer to the memory area */ -__attribute__((always_inline)) static inline void *hal_memset(void *dst_mem, int value, size_t len) -{ - asm("" : "+r"(dst_mem)); - return memset(dst_mem, value, len); -} +#define hal_memset(dst_mem, value, len) (__extension__({memset(dst_mem, value, len);})) #ifdef __cplusplus } From b8a3141ef96d655271f9b4634c559b61a2bef2be Mon Sep 17 00:00:00 2001 From: Ngai-Fung Yip Date: Sat, 4 Nov 2023 08:48:57 +0800 Subject: [PATCH 152/161] fix: assert failed in example uart_async_rxtxtasks --- .../uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/peripherals/uart/uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c b/examples/peripherals/uart/uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c index 94c18378abf6..cf67cc86f335 100644 --- a/examples/peripherals/uart/uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c +++ b/examples/peripherals/uart/uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c @@ -72,6 +72,6 @@ static void rx_task(void *arg) void app_main(void) { init(); - xTaskCreate(rx_task, "uart_rx_task", 1024 * 2, NULL, configMAX_PRIORITIES, NULL); - xTaskCreate(tx_task, "uart_tx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(rx_task, "uart_rx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(tx_task, "uart_tx_task", 1024 * 2, NULL, configMAX_PRIORITIES - 2, NULL); } From 32e3ecb7887285d3bad4d6bdedf89d8f75d40c46 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 13 Sep 2023 17:27:05 +0530 Subject: [PATCH 153/161] fix(nimble): Added check to validate allowed random address --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 9cb8e1817dba..8b574a7b531d 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 9cb8e1817dba36cabbbaced62d9e36bf238158f7 +Subproject commit 8b574a7b531d85fe8dfb7b814c9241172a806226 From 10f06abf3233bbb0cec8ddced72d31afbc698bbb Mon Sep 17 00:00:00 2001 From: darshan Date: Wed, 18 Oct 2023 16:03:05 +0530 Subject: [PATCH 154/161] fix(nimble): Fixed incorrect handling of bonded devices --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 8b574a7b531d..aa7c2f175752 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 8b574a7b531d85fe8dfb7b814c9241172a806226 +Subproject commit aa7c2f17575287337bdcec2d91aa1c1284ae21ed From aabb59586019f3f71b1796d38b4702e23956e0dc Mon Sep 17 00:00:00 2001 From: Roshan Bangar Date: Wed, 30 Aug 2023 22:24:53 +0530 Subject: [PATCH 155/161] feat(nimble): Added example support for Current Time Service --- components/bt/CMakeLists.txt | 2 + components/bt/host/nimble/nimble | 2 +- .../nimble/ble_cts/cts_cent/CMakeLists.txt | 6 + .../nimble/ble_cts/cts_cent/README.md | 156 +++++ .../ble_cts/cts_cent/main/CMakeLists.txt | 4 + .../ble_cts/cts_cent/main/Kconfig.projbuild | 27 + .../ble_cts/cts_cent/main/ble_cts_cent.h | 29 + .../ble_cts/cts_cent/main/idf_component.yml | 3 + .../nimble/ble_cts/cts_cent/main/main.c | 560 ++++++++++++++++++ .../ble_cts/cts_cent/sdkconfig.defaults | 12 + .../nimble/ble_cts/cts_prph/CMakeLists.txt | 6 + .../nimble/ble_cts/cts_prph/README.md | 79 +++ .../ble_cts/cts_prph/main/CMakeLists.txt | 2 + .../ble_cts/cts_prph/main/Kconfig.projbuild | 14 + .../ble_cts/cts_prph/main/ble_cts_prph.h | 27 + .../nimble/ble_cts/cts_prph/main/gatt_svr.c | 163 +++++ .../ble_cts/cts_prph/main/idf_component.yml | 3 + .../nimble/ble_cts/cts_prph/main/main.c | 315 ++++++++++ .../ble_cts/cts_prph/sdkconfig.defaults | 12 + 19 files changed, 1421 insertions(+), 1 deletion(-) create mode 100644 examples/bluetooth/nimble/ble_cts/cts_cent/CMakeLists.txt create mode 100644 examples/bluetooth/nimble/ble_cts/cts_cent/README.md create mode 100644 examples/bluetooth/nimble/ble_cts/cts_cent/main/CMakeLists.txt create mode 100644 examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild create mode 100644 examples/bluetooth/nimble/ble_cts/cts_cent/main/ble_cts_cent.h create mode 100644 examples/bluetooth/nimble/ble_cts/cts_cent/main/idf_component.yml create mode 100644 examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c create mode 100644 examples/bluetooth/nimble/ble_cts/cts_cent/sdkconfig.defaults create mode 100644 examples/bluetooth/nimble/ble_cts/cts_prph/CMakeLists.txt create mode 100644 examples/bluetooth/nimble/ble_cts/cts_prph/README.md create mode 100644 examples/bluetooth/nimble/ble_cts/cts_prph/main/CMakeLists.txt create mode 100644 examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild create mode 100644 examples/bluetooth/nimble/ble_cts/cts_prph/main/ble_cts_prph.h create mode 100644 examples/bluetooth/nimble/ble_cts/cts_prph/main/gatt_svr.c create mode 100644 examples/bluetooth/nimble/ble_cts/cts_prph/main/idf_component.yml create mode 100644 examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c create mode 100644 examples/bluetooth/nimble/ble_cts/cts_prph/sdkconfig.defaults diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 736709fc5435..08f5e167b9fe 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -614,6 +614,7 @@ if(CONFIG_BT_ENABLED) host/nimble/nimble/nimble/host/services/ipss/include host/nimble/nimble/nimble/host/services/lls/include host/nimble/nimble/nimble/host/services/prox/include + host/nimble/nimble/nimble/host/services/cts/include host/nimble/nimble/nimble/host/services/tps/include host/nimble/nimble/nimble/host/util/include host/nimble/nimble/nimble/host/store/ram/include @@ -634,6 +635,7 @@ if(CONFIG_BT_ENABLED) "host/nimble/nimble/nimble/host/services/dis/src/ble_svc_dis.c" "host/nimble/nimble/nimble/host/services/lls/src/ble_svc_lls.c" "host/nimble/nimble/nimble/host/services/prox/src/ble_svc_prox.c" + "host/nimble/nimble/nimble/host/services/cts/src/ble_svc_cts.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/host/nimble/nimble b/components/bt/host/nimble/nimble index aa7c2f175752..6a14d2a3ec43 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit aa7c2f17575287337bdcec2d91aa1c1284ae21ed +Subproject commit 6a14d2a3ec43697fa332c5b26b955b8778b8c352 diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/CMakeLists.txt b/examples/bluetooth/nimble/ble_cts/cts_cent/CMakeLists.txt new file mode 100644 index 000000000000..30e34b1f9bee --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/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(cts_cent) diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/README.md b/examples/bluetooth/nimble/ble_cts/cts_cent/README.md new file mode 100644 index 000000000000..1dd4b84ff0e1 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/README.md @@ -0,0 +1,156 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# BLE CTS Cent Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example creates GATT client and performs passive scan, it then connects to peripheral device if the device advertises connectability and the device advertises support for the Current Time Service (0x1805) as primary service UUID. + +It performs following GATT operations against the specified peer: + +* Reads the Current Time characteristic. + +If the peer does not support a required service, characteristic, or descriptor, then the peer lied when it claimed support for the Current Time Service! When this happens, or if a GATT procedure fails, this function immediately terminates the connection. + +It uses ESP32's Bluetooth controller and NimBLE stack based BLE host. + +This example aims at understanding BLE service discovery, connection, encryption and characteristic operations. + +To test this demo, use any BLE GATT server app that advertises support for the Current Time Service (0x1805) and includes it in the GATT database. + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Hardware Required + +* A development board with ESP32/ESP32-C2/ESP32-C3/ESP32-S3/ESP32-H2/ESP32-C6 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) +* A USB cable for Power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. + +### Configure the Project + +Open the project configuration menu: + +```bash +idf.py menuconfig +``` + +In the `Example Configuration` menu: + +* Change the `Peer Address` option if needed. + +### Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(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. + +## Example Output + +This is the console output on successful connection: + +``` +I (358) BLE_INIT: BT controller compile version [59725b5] +I (358) BLE_INIT: Bluetooth MAC: 60:55:f9:68:c4:fa +I (368) phy_init: phy_version 1110,9c20f0a,Jul 27 2023,10:42:54 +I (408) NimBLE_CTS_CENT: BLE Host Task Started +I (408) NimBLE: GAP procedure initiated: stop advertising. + +I (408) NimBLE: GAP procedure initiated: discovery; +I (408) NimBLE: own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=1 +I (418) NimBLE: duration=forever +I (428) NimBLE: + +I (428) main_task: Returned from app_main() +I (628) NimBLE: GAP procedure initiated: connect; +I (628) NimBLE: peer_addr_type=1 peer_addr= +I (628) NimBLE: 6b:93:b5:30:71:cf +I (638) NimBLE: scan_itvl=16 scan_window=16 itvl_min=24 itvl_max=40 latency=0 supervision_timeout=256 min_ce_len=0 max_ce_len=0 own_addr_type=0 +I (648) NimBLE: + +I (908) NimBLE: Connection established +I (908) NimBLE: + +I (918) NimBLE: Connection secured + +I (1208) NimBLE: received indication; conn_handle=1 attr_handle=3 attr_len=4 + +I (1208) NimBLE: GAP procedure initiated: +I (1208) NimBLE: connection parameter update; conn_handle=1 itvl_min=6 itvl_max=6 latency=0 supervision_timeout=500 min_ce_len=0 max_ce_len=0 +I (1228) NimBLE: + +I (3568) NimBLE: encryption change event; status=0 +I (3568) NimBLE: GATT procedure initiated: discover all services + +I (3608) NimBLE: GATT procedure initiated: discover all characteristics; +I (3608) NimBLE: start_handle=1 end_handle=9 + +I (3658) NimBLE: GATT procedure initiated: discover all characteristics; +I (3658) NimBLE: start_handle=20 end_handle=26 + +I (3688) NimBLE: GATT procedure initiated: discover all characteristics; +I (3688) NimBLE: start_handle=134 end_handle=141 + +I (3718) NimBLE: GATT procedure initiated: discover all characteristics; +I (3718) NimBLE: start_handle=142 end_handle=151 + +I (3758) NimBLE: GATT procedure initiated: discover all characteristics; +I (3758) NimBLE: start_handle=152 end_handle=158 + +I (3788) NimBLE: GATT procedure initiated: discover all characteristics; +I (3788) NimBLE: start_handle=159 end_handle=65535 + +I (3818) NimBLE: GATT procedure initiated: discover all descriptors; +I (3818) NimBLE: chr_val_handle=136 end_handle=137 + +I (3838) NimBLE: GATT procedure initiated: discover all descriptors; +I (3838) NimBLE: chr_val_handle=144 end_handle=148 + +I (3898) NimBLE: GATT procedure initiated: discover all descriptors; +I (3898) NimBLE: chr_val_handle=150 end_handle=151 + +I (3908) NimBLE: GATT procedure initiated: discover all descriptors; +I (3908) NimBLE: chr_val_handle=161 end_handle=162 + +I (3928) NimBLE: GATT procedure initiated: discover all descriptors; +I (3928) NimBLE: chr_val_handle=164 end_handle=65535 + +I (3938) NimBLE: Service discovery complete; status=0 conn_handle=1 + +I (3938) NimBLE: GATT procedure initiated: read; +I (3938) NimBLE: att_handle=161 + +I (3958) NimBLE: Read Current time complete; status=0 conn_handle=1 +I (3958) NimBLE: attr_handle=161 value= +I (3958) NimBLE: 0xe7 +I (3958) NimBLE: :0x07 +I (3958) NimBLE: :0x08 +I (3968) NimBLE: :0x1e +I (3968) NimBLE: :0x14 +I (3968) NimBLE: :0x25 +I (3978) NimBLE: :0x02 +I (3978) NimBLE: :0x03 +I (3978) NimBLE: :0xf6 +I (3978) NimBLE: :0x00 +I (3988) NimBLE: + +I (3988) NimBLE_CTS_CENT: Date : 30/8/2023 +I (3998) NimBLE_CTS_CENT: hours : 20 minutes : 37 +I (3998) NimBLE_CTS_CENT: seconds : 2 + +I (4008) NimBLE_CTS_CENT: fractions : 0 + +``` + +## Troubleshooting + +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/bluetooth/nimble/ble_cts/cts_cent/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_cts/cts_cent/main/CMakeLists.txt new file mode 100644 index 000000000000..18d510d98825 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/CMakeLists.txt @@ -0,0 +1,4 @@ +set(srcs "main.c") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild new file mode 100644 index 000000000000..8cad8f99527c --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/Kconfig.projbuild @@ -0,0 +1,27 @@ +menu "Example Configuration" + + config EXAMPLE_PEER_ADDR + string "Peer Address" + default "ADDR_ANY" + help + Enter the peer address in aa:bb:cc:dd:ee:ff form to connect to a specific peripheral + + config EXAMPLE_ENCRYPTION + bool + prompt "Enable Link Encryption" + default y + help + This enables bonding and encryption after connection has been established. + + config EXAMPLE_EXTENDED_ADV + bool + depends on SOC_BLE_50_SUPPORTED + default y if SOC_ESP_NIMBLE_CONTROLLER + select BT_NIMBLE_EXT_ADV + prompt "Enable Extended Adv" + help + Use this option to enable extended advertising in the example. + If this option is disabled, ensure config BT_NIMBLE_EXT_ADV is + also disabled from Nimble stack menuconfig + +endmenu diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/main/ble_cts_cent.h b/examples/bluetooth/nimble/ble_cts/cts_cent/main/ble_cts_cent.h new file mode 100644 index 000000000000..2a734676bb86 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/ble_cts_cent.h @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_BLE_CTS_CENT_ +#define H_BLE_CTS_CENT_ + +#include "modlog/modlog.h" +#include "esp_central.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_adv_fields; +struct ble_gap_conn_desc; +struct ble_hs_cfg; +union ble_store_value; +union ble_store_key; + +/* 16 BIT CCCD UUID */ +#define BLE_SVC_CTS_DSC_CLT_CFG_UUID16 0x2902 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/main/idf_component.yml b/examples/bluetooth/nimble/ble_cts/cts_cent/main/idf_component.yml new file mode 100644 index 000000000000..db8886afea48 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/idf_component.yml @@ -0,0 +1,3 @@ +dependencies: + nimble_central_utils: + path: ${IDF_PATH}/examples/bluetooth/nimble/common/nimble_central_utils diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c b/examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c new file mode 100644 index 000000000000..fd235c4dfeb7 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/main/main.c @@ -0,0 +1,560 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_log.h" +#include "nvs_flash.h" +/* BLE */ +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#include "services/gap/ble_svc_gap.h" +#include "ble_cts_cent.h" +#include "services/cts/ble_svc_cts.h" + +static const char *tag = "NimBLE_CTS_CENT"; +static int ble_cts_cent_gap_event(struct ble_gap_event *event, void *arg); +static uint8_t peer_addr[6]; + +static char *day_of_week[7] = { + "Unknown" + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday" +}; +void ble_store_config_init(void); +static void ble_cts_cent_scan(void); + +void printtime(struct ble_svc_cts_curr_time ctime) { + ESP_LOGI(tag, "Date : %d/%d/%d %s", ctime.et_256.d_d_t.d_t.day, + ctime.et_256.d_d_t.d_t.month, + ctime.et_256.d_d_t.d_t.year, + day_of_week[ctime.et_256.d_d_t.day_of_week]); + ESP_LOGI(tag, "hours : %d minutes : %d ", + ctime.et_256.d_d_t.d_t.hours, + ctime.et_256.d_d_t.d_t.minutes); + ESP_LOGI(tag, "seconds : %d\n", ctime.et_256.d_d_t.d_t.seconds); + ESP_LOGI(tag, "fractions : %d\n", ctime.et_256.fractions_256); +} + +/** + * Application callback. Called when the read of the cts current time + * characteristic has completed. + */ +static int +ble_cts_cent_on_read(uint16_t conn_handle, + const struct ble_gatt_error *error, + struct ble_gatt_attr *attr, + void *arg) +{ + struct ble_svc_cts_curr_time ctime; /* store the read time */ + MODLOG_DFLT(INFO, "Read Current time complete; status=%d conn_handle=%d\n", + error->status, conn_handle); + if (error->status == 0) { + MODLOG_DFLT(INFO, " attr_handle=%d value=\n", attr->handle); + print_mbuf(attr->om); + } + else { + goto err; + } + MODLOG_DFLT(INFO, "\n"); + ble_hs_mbuf_to_flat(attr->om, &ctime, sizeof(ctime), NULL); + printtime(ctime); + return 0; +err: + /* Terminate the connection. */ + return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM); +} + +/** + * Performs read on the current time characteristic + * + */ +static int +ble_cts_cent_read_time(const struct peer *peer) +{ + + /* Subscribe to notifications for the Current Time Characteristic. + * A central enables notifications by writing two bytes (1, 0) to the + * characteristic's client-characteristic-configuration-descriptor (CCCD). + */ + const struct peer_chr *chr; + int rc; + + chr = peer_chr_find_uuid(peer, + BLE_UUID16_DECLARE(BLE_SVC_CTS_UUID16), + BLE_UUID16_DECLARE(BLE_SVC_CTS_CHR_UUID16_CURRENT_TIME)); + if (chr == NULL) { + MODLOG_DFLT(ERROR, "Error: Peer doesn't support the CTS " + " characteristic\n"); + goto err; + } + rc = ble_gattc_read(peer->conn_handle, chr->chr.val_handle, + ble_cts_cent_on_read, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Error: Failed to read characteristic; rc=%d\n", + rc); + goto err; + } + + return 0; +err: + /* Terminate the connection. */ + return ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM); +} + +/** + * Called when service discovery of the specified peer has completed. + */ +static void +ble_cts_cent_on_disc_complete(const struct peer *peer, int status, void *arg) +{ + + if (status != 0) { + /* Service discovery failed. Terminate the connection. */ + MODLOG_DFLT(ERROR, "Error: Service discovery failed; status=%d " + "conn_handle=%d\n", status, peer->conn_handle); + ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM); + return; + } + + /* Service discovery has completed successfully. Now we have a complete + * list of services, characteristics, and descriptors that the peer + * supports. + */ + MODLOG_DFLT(INFO, "Service discovery complete; status=%d " + "conn_handle=%d\n", status, peer->conn_handle); + + /* Now perform GATT procedure against the peer: read + * for the cts service. + */ + ble_cts_cent_read_time(peer); +} + +/** + * Initiates the GAP general discovery procedure. + */ +static void +ble_cts_cent_scan(void) +{ + uint8_t own_addr_type; + struct ble_gap_disc_params disc_params; + int rc; + + /* Figure out address to use while advertising (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } + + /* Tell the controller to filter duplicates; we don't want to process + * repeated advertisements from the same device. + */ + disc_params.filter_duplicates = 1; + + /** + * Perform a passive scan. I.e., don't send follow-up scan requests to + * each advertiser. + */ + disc_params.passive = 1; + + /* Use defaults for the rest of the parameters. */ + disc_params.itvl = 0; + disc_params.window = 0; + disc_params.filter_policy = 0; + disc_params.limited = 0; + + rc = ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &disc_params, + ble_cts_cent_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Error initiating GAP discovery procedure; rc=%d\n", + rc); + } +} + +/** + * Indicates whether we should try to connect to the sender of the specified + * advertisement. The function returns a positive result if the device + * advertises connectability and support for the Current Time Service. + */ + +#if CONFIG_EXAMPLE_EXTENDED_ADV +static int +ext_ble_cts_cent_should_connect(const struct ble_gap_ext_disc_desc *disc) +{ + int offset = 0; + int ad_struct_len = 0; + + if (disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND && + disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) { + return 0; + } + if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) { + ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR); + /* Convert string to address */ + sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &peer_addr[5], &peer_addr[4], &peer_addr[3], + &peer_addr[2], &peer_addr[1], &peer_addr[0]); + if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) { + return 0; + } + } + + /* The device has to advertise support for the CTS + * service (0x1805). + */ + do { + ad_struct_len = disc->data[offset]; + + if (!ad_struct_len) { + break; + } + + /* Search if cts UUID is advertised */ + if (disc->data[offset + 1] == 0x03) { + int temp = 2; + while(temp < disc->data[offset + 1]) { + if(disc->data[offset + temp] == 0x05 && + disc->data[offset + temp + 1] == 0x18) { + return 1; + } + temp += 2; + } + } + offset += ad_struct_len + 1; + } while ( offset < disc->length_data ); + + return 0; +} +#else + +static int +ble_cts_cent_should_connect(const struct ble_gap_disc_desc *disc) +{ + struct ble_hs_adv_fields fields; + int rc; + int i; + + /* The device has to be advertising connectability. */ + if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND && + disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) { + + return 0; + } + + rc = ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data); + if (rc != 0) { + return 0; + } + + if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) { + ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR); + /* Convert string to address */ + sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &peer_addr[5], &peer_addr[4], &peer_addr[3], + &peer_addr[2], &peer_addr[1], &peer_addr[0]); + if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) { + return 0; + } + } + + /* The device has to advertise support for the Current Time + * service (0x1805). + */ + for (i = 0; i < fields.num_uuids16; i++) { + if (ble_uuid_u16(&fields.uuids16[i].u) == BLE_SVC_CTS_UUID16) { + return 1; + } + } + + return 0; +} +#endif + +/** + * Connects to the sender of the specified advertisement of it looks + * interesting. A device is "interesting" if it advertises connectability and + * support for the Current Time service. + */ +static void +ble_cts_cent_connect_if_interesting(void *disc) +{ + uint8_t own_addr_type; + int rc; + ble_addr_t *addr; + + /* Don't do anything if we don't care about this advertiser. */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + if (!ext_ble_cts_cent_should_connect((struct ble_gap_ext_disc_desc *)disc)) { + return; + } +#else + if (!ble_cts_cent_should_connect((struct ble_gap_disc_desc *)disc)) { + return; + } +#endif + + /* 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; + } + + /* Figure out address to use for connect (no privacy for now) */ + rc = ble_hs_id_infer_auto(0, &own_addr_type); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc); + return; + } + + /* Try to connect the the advertiser. Allow 30 seconds (30000 ms) for + * timeout. + */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + addr = &((struct ble_gap_ext_disc_desc *)disc)->addr; +#else + addr = &((struct ble_gap_disc_desc *)disc)->addr; +#endif + rc = ble_gap_connect(own_addr_type, addr, 30000, NULL, + ble_cts_cent_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Error: Failed to connect to device; addr_type=%d " + "addr=%s; rc=%d\n", + addr->type, addr_str(addr->val), rc); + return; + } +} + +/** + * The nimble host executes this callback when a GAP event occurs. The + * application associates a GAP event callback with each connection that is + * established. ble_cts_cent uses the same callback for all connections. + * + * @param event The event being signalled. + * @param arg Application-specified argument; unused by + * ble_cts_cent. + * + * @return 0 if the application successfully handled the + * event; nonzero on failure. The semantics + * of the return code is specific to the + * particular GAP event being signalled. + */ +static int +ble_cts_cent_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_conn_desc desc; + struct ble_hs_adv_fields fields; + int rc; + + switch (event->type) { + case BLE_GAP_EVENT_DISC: + rc = ble_hs_adv_parse_fields(&fields, event->disc.data, + event->disc.length_data); + if (rc != 0) { + return 0; + } + + /* An advertisment 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: + /* A new connection was established or a connection attempt failed. */ + if (event->connect.status == 0) { + /* Connection successfully established. */ + MODLOG_DFLT(INFO, "Connection established "); + + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); + MODLOG_DFLT(INFO, "\n"); + + /* Remember peer. */ + rc = peer_add(event->connect.conn_handle); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Failed to add peer; rc=%d\n", rc); + return 0; + } + +#if CONFIG_EXAMPLE_ENCRYPTION + /** Initiate security - It will perform + * Pairing (Exchange keys) + * Bonding (Store keys) + * Encryption (Enable encryption) + * Will invoke event BLE_GAP_EVENT_ENC_CHANGE + **/ + rc = ble_gap_security_initiate(event->connect.conn_handle); + if (rc != 0) { + MODLOG_DFLT(INFO, "Security could not be initiated, rc = %d\n", rc); + return ble_gap_terminate(event->connect.conn_handle, + BLE_ERR_REM_USER_CONN_TERM); + } else { + MODLOG_DFLT(INFO, "Connection secured\n"); + } +#else + /* Perform service discovery */ + rc = peer_disc_all(event->connect.conn_handle, + ble_cts_cent_on_disc_complete, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc); + return 0; + } +#endif + } else { + /* Connection attempt failed; resume scanning. */ + MODLOG_DFLT(ERROR, "Error: Connection failed; status=%d\n", + event->connect.status); + ble_cts_cent_scan(); + } + + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + /* Connection terminated. */ + MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason); + print_conn_desc(&event->disconnect.conn); + MODLOG_DFLT(INFO, "\n"); + + /* Forget about peer. */ + peer_delete(event->disconnect.conn.conn_handle); + + /* Resume scanning. */ + ble_cts_cent_scan(); + return 0; + + case BLE_GAP_EVENT_DISC_COMPLETE: + MODLOG_DFLT(INFO, "discovery complete; reason=%d\n", + event->disc_complete.reason); + return 0; + + case BLE_GAP_EVENT_ENC_CHANGE: + /* Encryption has been enabled or disabled for this connection. */ + MODLOG_DFLT(INFO, "encryption change event; status=%d ", + event->enc_change.status); + rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); + assert(rc == 0); + print_conn_desc(&desc); +#if CONFIG_EXAMPLE_ENCRYPTION + /*** Go for service discovery after encryption has been successfully enabled ***/ + rc = peer_disc_all(event->connect.conn_handle, + ble_cts_cent_on_disc_complete, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc); + return 0; + } +#endif + return 0; + + case BLE_GAP_EVENT_NOTIFY_RX: + /* Peer sent us a notification or indication. */ + MODLOG_DFLT(INFO, "received %s; conn_handle=%d attr_handle=%d " + "attr_len=%d\n", + event->notify_rx.indication ? + "indication" : + "notification", + event->notify_rx.conn_handle, + event->notify_rx.attr_handle, + OS_MBUF_PKTLEN(event->notify_rx.om)); + + /* Attribute data is contained in event->notify_rx.om. Use + * `os_mbuf_copydata` to copy the data received in notification mbuf */ + return 0; + + case BLE_GAP_EVENT_MTU: + MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n", + event->mtu.conn_handle, + event->mtu.channel_id, + event->mtu.value); + return 0; + +#if CONFIG_EXAMPLE_EXTENDED_ADV + case BLE_GAP_EVENT_EXT_DISC: + /* An advertisment report was received during GAP discovery. */ + ext_print_adv_report(&event->disc); + + ble_cts_cent_connect_if_interesting(&event->disc); + return 0; +#endif + + default: + return 0; + } +} + +static void +ble_cts_cent_on_reset(int reason) +{ + MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); +} + +static void +ble_cts_cent_on_sync(void) +{ + int rc; + + /* Make sure we have proper identity address set (public preferred) */ + rc = ble_hs_util_ensure_addr(0); + assert(rc == 0); + + /* Begin scanning for a peripheral to connect to. */ + ble_cts_cent_scan(); +} + +void ble_cts_cent_host_task(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +void +app_main(void) +{ + int rc; + /* Initialize NVS — it is used to store PHY calibration data */ + 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()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ret = nimble_port_init(); + if (ret != ESP_OK) { + ESP_LOGE(tag, "Failed to init nimble %d ", ret); + return; + } + + /* Configure the host. */ + ble_hs_cfg.reset_cb = ble_cts_cent_on_reset; + ble_hs_cfg.sync_cb = ble_cts_cent_on_sync; + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + /* Initialize data structures to track connected peers. */ + rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64); + assert(rc == 0); + + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("nimble-cts-cent"); + assert(rc == 0); + + /* XXX Need to have template for store */ + ble_store_config_init(); + + nimble_port_freertos_init(ble_cts_cent_host_task); +} diff --git a/examples/bluetooth/nimble/ble_cts/cts_cent/sdkconfig.defaults b/examples/bluetooth/nimble/ble_cts/cts_cent/sdkconfig.defaults new file mode 100644 index 000000000000..c829fc5c002e --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_cent/sdkconfig.defaults @@ -0,0 +1,12 @@ +# Override some defaults so BT stack is enabled +# in this example + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/CMakeLists.txt b/examples/bluetooth/nimble/ble_cts/cts_prph/CMakeLists.txt new file mode 100644 index 000000000000..81409326b1f1 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/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(cts_prph) diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/README.md b/examples/bluetooth/nimble/ble_cts/cts_prph/README.md new file mode 100644 index 000000000000..9897fd4c527c --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/README.md @@ -0,0 +1,79 @@ +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +# BLE Current Time Service Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example creates GATT server demonstrating standard Current Time Service. + +It advertises support for the Current Time Service(0x1805) as primary service UUID. + +It uses ESP32's Bluetooth controller and NimBLE stack based BLE host + + +## How to Use Example + +Before project configuration and build, be sure to set the correct chip target using: + +```bash +idf.py set-target +``` + +### Hardware Required + +* A development board with ESP32/ESP32-C3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) +* A USB cable for Power supply and programming + +See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it. + +### Build and Flash + +Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(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. + +## Example Output + +This console output can be observed when client is connected to server : + +``` +I (357) BLE_INIT: BT controller compile version [59725b5] +I (357) BLE_INIT: Bluetooth MAC: 60:55:f9:68:c4:fa +I (367) phy_init: phy_version 1110,9c20f0a,Jul 27 2023,10:42:54 +I (407) NimBLE_cts_PRPH: BLE Host Task Started +I (407) NimBLE: GAP procedure initiated: stop advertising. + +I (407) NimBLE: Failed to restore IRKs from store; status=8 + +I (407) NimBLE: Device Address: +I (417) NimBLE: 60:55:f9:68:c4:fa +I (417) NimBLE: + +I (417) NimBLE: GAP procedure initiated: advertise; +I (427) NimBLE: disc_mode=2 +I (427) NimBLE: adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 +I (437) NimBLE: + +I (447) main_task: Returned from app_main() + +I (27317) NimBLE: GAP procedure initiated: advertise; +I (27317) NimBLE: disc_mode=2 +I (27327) NimBLE: adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0 +I (27337) NimBLE: + +I (31987) NimBLE: connection established; status=0 + +I (53297) NimBLE: subscribe event; cur_notify=1 + value handle; val_handle=12 + + I (68317) NimBLE: subscribe event; cur_notify=0 + value handle; val_handle=12 + +``` + +## Troubleshooting + +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/bluetooth/nimble/ble_cts/cts_prph/main/CMakeLists.txt b/examples/bluetooth/nimble/ble_cts/cts_prph/main/CMakeLists.txt new file mode 100644 index 000000000000..e8a76d0b091c --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" "gatt_svr.c" + INCLUDE_DIRS ".") diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild b/examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild new file mode 100644 index 000000000000..a52400353482 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/Kconfig.projbuild @@ -0,0 +1,14 @@ +menu "Example Configuration" + + config EXAMPLE_EXTENDED_ADV + bool + depends on SOC_BLE_50_SUPPORTED + default y if SOC_ESP_NIMBLE_CONTROLLER + select BT_NIMBLE_EXT_ADV + prompt "Enable Extended Adv" + help + Use this option to enable extended advertising in the example. + If this option is disabled, ensure config BT_NIMBLE_EXT_ADV is + also disabled from Nimble stack menuconfig + +endmenu diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/ble_cts_prph.h b/examples/bluetooth/nimble/ble_cts/cts_prph/main/ble_cts_prph.h new file mode 100644 index 000000000000..744130053f26 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/ble_cts_prph.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_BLE_CTS_PRPH_ +#define H_BLE_CTS_PRPH_ + +#include "nimble/ble.h" +#include "modlog/modlog.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_cfg; +struct ble_gatt_register_ctxt; + +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +int gatt_svr_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/gatt_svr.c b/examples/bluetooth/nimble/ble_cts/cts_prph/main/gatt_svr.c new file mode 100644 index 000000000000..7a5cc19367b1 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/gatt_svr.c @@ -0,0 +1,163 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "host/ble_hs.h" +#include "host/ble_uuid.h" +#include "services/gap/ble_svc_gap.h" +#include "services/gatt/ble_svc_gatt.h" +#include "ble_cts_prph.h" +#include "services/cts/ble_svc_cts.h" +#include +#include "sys/time.h" + + +void +gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) +{ + char buf[BLE_UUID_STR_LEN]; + + switch (ctxt->op) { + case BLE_GATT_REGISTER_OP_SVC: + MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n", + ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), + ctxt->svc.handle); + break; + + case BLE_GATT_REGISTER_OP_CHR: + MODLOG_DFLT(DEBUG, "registering characteristic %s with " + "def_handle=%d val_handle=%d\n", + ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), + ctxt->chr.def_handle, + ctxt->chr.val_handle); + break; + + case BLE_GATT_REGISTER_OP_DSC: + MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n", + ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), + ctxt->dsc.handle); + break; + + default: + assert(0); + break; + } +} + +static struct ble_svc_cts_local_time_info local_info = { .timezone = 0, .dst_offset = TIME_STANDARD }; +static struct timeval last_updated; +uint8_t adjust_reason; +int fetch_current_time(struct ble_svc_cts_curr_time *ctime) { + time_t now; + struct tm timeinfo; + struct timeval tv_now; + /* time given by 'time()' api does not persist after reboots */ + time(&now); + localtime_r(&now, &timeinfo); + gettimeofday(&tv_now, NULL); + if(ctime != NULL) { + /* fill date_time */ + ctime->et_256.d_d_t.d_t.year = timeinfo.tm_year + 1900; + ctime->et_256.d_d_t.d_t.month = timeinfo.tm_mon + 1; + ctime->et_256.d_d_t.d_t.day = timeinfo.tm_mday; + ctime->et_256.d_d_t.d_t.hours = timeinfo.tm_hour; + ctime->et_256.d_d_t.d_t.minutes = timeinfo.tm_min; + ctime->et_256.d_d_t.d_t.seconds = timeinfo.tm_sec; + + /* day of week */ + /* time gives day range of [0, 6], current_time_sevice + has day range of [1,7] */ + ctime->et_256.d_d_t.day_of_week = timeinfo.tm_wday + 1; + + /* fractions_256 */ + ctime->et_256.fractions_256 = (((uint64_t)tv_now.tv_usec * 256L )/ 1000000L); + + ctime->adjust_reason = adjust_reason; + } + return 0; +} + +int set_current_time(struct ble_svc_cts_curr_time ctime) { + time_t now; + struct tm timeinfo; + struct timeval tv_now; + /* fill date_time */ + timeinfo.tm_year= ctime.et_256.d_d_t.d_t.year - 1900 ; + timeinfo.tm_mon = ctime.et_256.d_d_t.d_t.month - 1; + timeinfo.tm_mday = ctime.et_256.d_d_t.d_t.day; + timeinfo.tm_hour = ctime.et_256.d_d_t.d_t.hours; + timeinfo.tm_min = ctime.et_256.d_d_t.d_t.minutes; + timeinfo.tm_sec = ctime.et_256.d_d_t.d_t.seconds; + timeinfo.tm_wday = ctime.et_256.d_d_t.day_of_week - 1; + now = mktime(&timeinfo); + tv_now.tv_sec = now; + settimeofday(&tv_now, NULL); + /* set the last updated */ + gettimeofday(&last_updated, NULL); + adjust_reason = ctime.adjust_reason; + return 0; +} + +int fetch_local_time_info(struct ble_svc_cts_local_time_info *info) { + + if(info != NULL) { + memcpy(info, &local_info, sizeof local_info); + } + return 0; +} + +int set_local_time_info(struct ble_svc_cts_local_time_info info) { + /* just store the dst offset and timezone locally + as we don't have the access to time using ntp server */ + local_info.timezone = info.timezone; + local_info.dst_offset = info.dst_offset; + gettimeofday(&last_updated, NULL); + return 0; +} +int fetch_reference_time_info(struct ble_svc_cts_reference_time_info *info) { + struct timeval tv_now; + uint64_t days_since_update; + uint64_t hours_since_update; + + gettimeofday(&tv_now, NULL); + /* subtract the time when the last time was updated */ + tv_now.tv_sec -= last_updated.tv_sec; /* ignore microseconds */ + info->time_source = TIME_SOURCE_MANUAL; + info->time_accuracy = 0; + days_since_update = (tv_now.tv_sec / 86400L); + hours_since_update = (tv_now.tv_sec / 3600); + info->days_since_update = days_since_update < 255 ? days_since_update : 255; + + if(days_since_update > 254) { + info->hours_since_update = 255; + } + else { + hours_since_update = (tv_now.tv_sec % 86400L) / 3600; + info->hours_since_update = hours_since_update; + } + adjust_reason = (CHANGE_OF_DST_MASK | CHANGE_OF_TIME_ZONE_MASK); + + return 0; +} +int +gatt_svr_init(void) +{ + struct ble_svc_cts_cfg cfg; + + ble_svc_gap_init(); + ble_svc_gatt_init(); + + cfg.fetch_time_cb = fetch_current_time; + cfg.local_time_info_cb = fetch_local_time_info; + cfg.ref_time_info_cb = fetch_reference_time_info; + cfg.set_time_cb = set_current_time; + cfg.set_local_time_info_cb = set_local_time_info; + ble_svc_cts_init(cfg); + + return 0; +} diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/idf_component.yml b/examples/bluetooth/nimble/ble_cts/cts_prph/main/idf_component.yml new file mode 100644 index 000000000000..d6e735fe7706 --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/idf_component.yml @@ -0,0 +1,3 @@ +dependencies: + nimble_peripheral_utils: + path: ${IDF_PATH}/examples/bluetooth/nimble/common/nimble_peripheral_utils diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c b/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c new file mode 100644 index 000000000000..53bb6897bc6a --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c @@ -0,0 +1,315 @@ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_log.h" +#include "nvs_flash.h" +#include "freertos/FreeRTOSConfig.h" +/* BLE */ +#include "nimble/nimble_port.h" +#include "nimble/nimble_port_freertos.h" +#include "host/ble_hs.h" +#include "host/util/util.h" +#include "console/console.h" +#include "services/gap/ble_svc_gap.h" +#include "ble_cts_prph.h" +#include "services/cts/ble_svc_cts.h" + +#if CONFIG_EXAMPLE_EXTENDED_ADV +static uint8_t ext_adv_pattern_1[] = { + 0x02, 0x01, 0x06, + 0x03, 0x03, 0xab, 0xcd, + 0x03, 0x03, 0x05, 0x18, + 0x12, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'c', 't', 's', '-', 'p', 'r', 'p', 'h', '-', 'e', +}; +#endif + +static const char *tag = "NimBLE_CTS_PRPH"; +static const char *device_name = "ble_cts_prph"; + +static int ble_cts_prph_gap_event(struct ble_gap_event *event, void *arg); + +static uint8_t ble_cts_prph_addr_type; + +/** + * Utility function to log an array of bytes. + */ +void +print_bytes(const uint8_t *bytes, int len) +{ + int i; + for (i = 0; i < len; i++) { + MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} + +void +print_addr(const void *addr) +{ + const uint8_t *u8p; + + u8p = addr; + MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); +} + +#if CONFIG_EXAMPLE_EXTENDED_ADV +/** + * Enables advertising with the following parameters: + * o General discoverable mode. + * o Undirected connectable mode. + */ +static void +ext_ble_cts_prph_advertise(void) +{ + struct ble_gap_ext_adv_params params; + struct os_mbuf *data; + uint8_t instance = 0; + int rc; + + /* First check if any instance is already active */ + if (ble_gap_ext_adv_active(instance)) { + return; + } + + /* use defaults for non-set params */ + memset (¶ms, 0, sizeof(params)); + + /* enable connectable advertising */ + params.connectable = 1; + + /* advertise using random addr */ + params.own_addr_type = BLE_OWN_ADDR_PUBLIC; + + params.primary_phy = BLE_HCI_LE_PHY_1M; + params.secondary_phy = BLE_HCI_LE_PHY_2M; + params.sid = 1; + + params.itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN; + params.itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MIN; + + /* configure instance 0 */ + rc = ble_gap_ext_adv_configure(instance, ¶ms, NULL, + ble_cts_prph_gap_event, NULL); + assert (rc == 0); + + /* in this case only scan response is allowed */ + + /* get mbuf for scan rsp data */ + data = os_msys_get_pkthdr(sizeof(ext_adv_pattern_1), 0); + assert(data); + + /* fill mbuf with scan rsp data */ + rc = os_mbuf_append(data, ext_adv_pattern_1, sizeof(ext_adv_pattern_1)); + assert(rc == 0); + + rc = ble_gap_ext_adv_set_data(instance, data); + assert (rc == 0); + + /* start advertising */ + rc = ble_gap_ext_adv_start(instance, 0, 0); + assert (rc == 0); +} +#else + +static void +ble_cts_prph_advertise(void) +{ + struct ble_gap_adv_params adv_params; + struct ble_hs_adv_fields fields; + int rc; + + /* + * Set the advertisement data included in our advertisements: + * o Flags (indicates advertisement type and other general info) + * o Advertising tx power + * o Device name + */ + memset(&fields, 0, sizeof(fields)); + + /* + * Advertise two flags: + * o Discoverability in forthcoming advertisement (general) + * o BLE-only (BR/EDR unsupported) + */ + fields.flags = BLE_HS_ADV_F_DISC_GEN | + BLE_HS_ADV_F_BREDR_UNSUP; + + /* + * Indicate that the TX power level field should be included; have the + * stack fill this value automatically. This is done by assigning the + * special value BLE_HS_ADV_TX_PWR_LVL_AUTO. + */ + fields.tx_pwr_lvl_is_present = 1; + fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + + fields.name = (uint8_t *)device_name; + fields.name_len = strlen(device_name); + fields.name_is_complete = 1; + + fields.uuids16 = (ble_uuid16_t[]) { + BLE_UUID16_INIT(BLE_SVC_CTS_UUID16) + }; + fields.num_uuids16 = 1; + fields.uuids16_is_complete = 1; + + rc = ble_gap_adv_set_fields(&fields); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc); + return; + } + + /* Begin advertising */ + memset(&adv_params, 0, sizeof(adv_params)); + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + rc = ble_gap_adv_start(ble_cts_prph_addr_type, NULL, BLE_HS_FOREVER, + &adv_params, ble_cts_prph_gap_event, NULL); + if (rc != 0) { + MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc); + return; + } +} +#endif + +static int +ble_cts_prph_gap_event(struct ble_gap_event *event, void *arg) +{ + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + /* 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); + + if (event->connect.status != 0) { + /* Connection failed; resume advertising */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + ext_ble_cts_prph_advertise(); +#else + ble_cts_prph_advertise(); +#endif + + } + break; + + case BLE_GAP_EVENT_DISCONNECT: + MODLOG_DFLT(INFO, "disconnect; reason=%d\n", event->disconnect.reason); + + /* Connection terminated; resume advertising */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + ext_ble_cts_prph_advertise(); +#else + ble_cts_prph_advertise(); +#endif + + break; + + case BLE_GAP_EVENT_ADV_COMPLETE: + MODLOG_DFLT(INFO, "adv complete\n"); +#if CONFIG_EXAMPLE_EXTENDED_ADV + ext_ble_cts_prph_advertise(); +#else + ble_cts_prph_advertise(); +#endif + break; + + case BLE_GAP_EVENT_SUBSCRIBE: + MODLOG_DFLT(INFO, "subscribe event; cur_notify=%d\n value handle; " + "val_handle=%d\n", + event->subscribe.cur_notify, event->subscribe.attr_handle); + + break; + + case BLE_GAP_EVENT_MTU: + MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d mtu=%d\n", + event->mtu.conn_handle, + event->mtu.value); + break; + + } + + return 0; +} + +static void +ble_cts_prph_on_sync(void) +{ + int rc; + + rc = ble_hs_id_infer_auto(0, &ble_cts_prph_addr_type); + assert(rc == 0); + + uint8_t addr_val[6] = {0}; + rc = ble_hs_id_copy_addr(ble_cts_prph_addr_type, addr_val, NULL); + + MODLOG_DFLT(INFO, "Device Address: "); + print_addr(addr_val); + MODLOG_DFLT(INFO, "\n"); + + /* Begin advertising */ +#if CONFIG_EXAMPLE_EXTENDED_ADV + ext_ble_cts_prph_advertise(); +#else + ble_cts_prph_advertise(); +#endif +} + +static void +ble_cts_prph_on_reset(int reason) +{ + MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason); +} + +void ble_cts_prph_host_task(void *param) +{ + ESP_LOGI(tag, "BLE Host Task Started"); + /* This function will return only when nimble_port_stop() is executed */ + nimble_port_run(); + + nimble_port_freertos_deinit(); +} + +void app_main(void) +{ + int rc; + + /* Initialize NVS — it is used to store PHY calibration data */ + 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()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK(ret); + + ret = nimble_port_init(); + if (ret != ESP_OK) { + MODLOG_DFLT(ERROR, "Failed to init nimble %d \n", ret); + return; + } + + /* Initialize the NimBLE host configuration */ + ble_hs_cfg.sync_cb = ble_cts_prph_on_sync; + ble_hs_cfg.reset_cb = ble_cts_prph_on_reset; + + /* Enable bonding */ + ble_hs_cfg.sm_bonding = 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; + + ble_hs_cfg.sm_sc = 1; + ble_hs_cfg.sm_mitm = 1; + + rc = gatt_svr_init(); + assert(rc == 0); + + /* Set the default device name */ + rc = ble_svc_gap_device_name_set(device_name); + assert(rc == 0); + + /* Start the task */ + nimble_port_freertos_init(ble_cts_prph_host_task); + +} diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/sdkconfig.defaults b/examples/bluetooth/nimble/ble_cts/cts_prph/sdkconfig.defaults new file mode 100644 index 000000000000..c829fc5c002e --- /dev/null +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/sdkconfig.defaults @@ -0,0 +1,12 @@ +# Override some defaults so BT stack is enabled +# in this example + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n +CONFIG_BT_BLUEDROID_ENABLED=n +CONFIG_BT_NIMBLE_ENABLED=y From 9cab732a29847eff070805a834b9da22a1bd689c Mon Sep 17 00:00:00 2001 From: zhangyanjiao Date: Mon, 6 Nov 2023 10:42:49 +0800 Subject: [PATCH 156/161] fix(wifi): fix rate check error in fragment --- components/esp_wifi/lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 090d16dd1f7e..a65d997669b9 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 090d16dd1f7e0a60fb63c9a6788c2de4bdac6975 +Subproject commit a65d997669b98f8348158fb5f47d9832b46eccc7 From 559fb2d2bffe6ceb11416b4442e26a0a6794daa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rohl=C3=ADnek?= Date: Mon, 16 Oct 2023 08:20:08 +0200 Subject: [PATCH 157/161] feat(storage): minimize platforms for tests --- examples/storage/.build-test-rules.yml | 30 ++++++++++++------- .../ext_flash_fatfs/pytest_ext_flash_fatfs.py | 1 - .../fatfsgen/main/fatfsgen_example_main.c | 1 - .../storage/nvs_rw_blob/pytest_nvs_rw_blob.py | 3 +- .../nvs_rw_value/pytest_nvs_rw_value.py | 3 +- .../pytest_nvs_rw_value_cxx.py | 3 +- .../sdspi/pytest_sdspi_card_example.py | 1 - .../semihost_vfs/pytest_semihost_vfs.py | 24 --------------- .../storage/spiffs/pytest_spiffs_example.py | 3 +- .../pytest_wear_levelling_example.py | 3 +- 10 files changed, 30 insertions(+), 42 deletions(-) diff --git a/examples/storage/.build-test-rules.yml b/examples/storage/.build-test-rules.yml index 30e10b7d3a08..7840ae2ad702 100644 --- a/examples/storage/.build-test-rules.yml +++ b/examples/storage/.build-test-rules.yml @@ -2,10 +2,11 @@ examples/storage/custom_flash_driver: depends_components: - - fatfs - - vfs - spi_flash - driver + disable_test: + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/emmc: depends_components: @@ -23,12 +24,11 @@ examples/storage/ext_flash_fatfs: - vfs - spi_flash - driver - - esp_system disable: - if: IDF_TARGET == "esp32p4" reason: not supported yet disable_test: - - if: IDF_TARGET not in ["esp32", "esp32s2"] + - if: IDF_TARGET not in ["esp32"] temporary: true reason: lack of runners @@ -36,7 +36,6 @@ examples/storage/fatfsgen: depends_components: - fatfs - vfs - - esp_system disable_test: - if: IDF_TARGET != "esp32" reason: only one target needed @@ -45,17 +44,23 @@ examples/storage/nvs_rw_blob: depends_components: - nvs_flash - driver - - esp_system + disable_test: + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/nvs_rw_value: depends_components: - nvs_flash - - nvs_system + disable_test: + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/nvs_rw_value_cxx: depends_components: - nvs_flash - - nvs_system + disable_test: + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/nvsgen: depends_components: @@ -100,7 +105,6 @@ examples/storage/perf_benchmark: - vfs - sdmmc - spiffs - - soc - wear_levelling - esp_partition - driver @@ -133,7 +137,7 @@ examples/storage/sd_card/sdspi: disable: - if: SOC_GPSPI_SUPPORTED != 1 disable_test: - - if: IDF_TARGET not in ["esp32", "esp32c3", "esp32s2"] + - if: IDF_TARGET not in ["esp32", "esp32c3"] temporary: true reason: lack of runners @@ -149,6 +153,9 @@ examples/storage/spiffs: depends_components: - spiffs - vfs + disable_test: + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed examples/storage/spiffsgen: depends_components: @@ -164,3 +171,6 @@ examples/storage/wear_levelling: - vfs - wear_levelling - fatfs + disable_test: + - if: IDF_TARGET not in ["esp32", "esp32c3"] + reason: only one target per arch needed diff --git a/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py b/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py index b3dfd1e5b97b..afe81763a3ab 100644 --- a/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py +++ b/examples/storage/ext_flash_fatfs/pytest_ext_flash_fatfs.py @@ -7,7 +7,6 @@ @pytest.mark.esp32 -@pytest.mark.esp32s2 @pytest.mark.external_flash def test_ext_flash_fatfs(dut: Dut) -> None: message_list = ('Initialized external Flash', diff --git a/examples/storage/fatfsgen/main/fatfsgen_example_main.c b/examples/storage/fatfsgen/main/fatfsgen_example_main.c index 491622c4e42a..1c0c94dc3f3f 100644 --- a/examples/storage/fatfsgen/main/fatfsgen_example_main.c +++ b/examples/storage/fatfsgen/main/fatfsgen_example_main.c @@ -9,7 +9,6 @@ #include #include "esp_vfs.h" #include "esp_vfs_fat.h" -#include "esp_system.h" #include "sdkconfig.h" #if CONFIG_EXAMPLE_FATFS_MODE_READ_ONLY diff --git a/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py b/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py index 422dee3bb067..01840dcda3a0 100644 --- a/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py +++ b/examples/storage/nvs_rw_blob/pytest_nvs_rw_blob.py @@ -11,7 +11,8 @@ from pytest_embedded import Dut -@pytest.mark.supported_targets +@pytest.mark.esp32 +@pytest.mark.esp32c3 def test_examples_nvs_rw_blob(dut: Dut) -> None: def expect_start_msg(index: int) -> None: dut.expect('Restart counter = {}'.format(index), timeout=10) diff --git a/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py b/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py index e7f2f30c2a9b..aae3f1e038cc 100644 --- a/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py +++ b/examples/storage/nvs_rw_value/pytest_nvs_rw_value.py @@ -8,7 +8,8 @@ from pytest_embedded import Dut -@pytest.mark.supported_targets +@pytest.mark.esp32 +@pytest.mark.esp32c3 def test_examples_nvs_rw_value(dut: Dut) -> None: for i, counter_state in zip_longest(range(4), ('The value is not initialized yet!',), fillvalue='Done'): dut.expect('Opening Non-Volatile Storage \\(NVS\\) handle... Done', timeout=20) diff --git a/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py b/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py index e2f990e8e8af..cd1237058cfa 100644 --- a/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py +++ b/examples/storage/nvs_rw_value_cxx/pytest_nvs_rw_value_cxx.py @@ -8,7 +8,8 @@ from pytest_embedded import Dut -@pytest.mark.supported_targets +@pytest.mark.esp32 +@pytest.mark.esp32c3 def test_examples_nvs_rw_value_cxx(dut: Dut) -> None: for i, counter_state in zip_longest(range(4), ('The value is not initialized yet!',), fillvalue='Done'): dut.expect('Opening Non-Volatile Storage \\(NVS\\) handle... Done', timeout=20) 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 480aa9f2d636..4f2b42bb58e4 100644 --- a/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py +++ b/examples/storage/sd_card/sdspi/pytest_sdspi_card_example.py @@ -11,7 +11,6 @@ @pytest.mark.esp32 @pytest.mark.esp32c3 # no runner available at the moment -@pytest.mark.esp32s2 @pytest.mark.sdcard_spimode def test_examples_sd_card_sdspi(dut: Dut) -> None: dut.expect('example: Initializing SD card', timeout=20) diff --git a/examples/storage/semihost_vfs/pytest_semihost_vfs.py b/examples/storage/semihost_vfs/pytest_semihost_vfs.py index 9345086b70b4..03dd2acdb2b7 100644 --- a/examples/storage/semihost_vfs/pytest_semihost_vfs.py +++ b/examples/storage/semihost_vfs/pytest_semihost_vfs.py @@ -34,30 +34,6 @@ def prepare() -> t.Generator[None, None, None]: f'-c \'set ESP_SEMIHOST_BASEDIR "{TEMP_DIR}"\' -f board/esp32-wrover-kit-3.3v.cfg', marks=[pytest.mark.esp32], ), - # pytest.param( - # 'esp,idf,jtag', - # 'y', - # f'-c \'set ESP_SEMIHOST_BASEDIR "{TEMP_DIR}"\' -f board/esp32c2-ftdi.cfg', - # marks=[pytest.mark.esp32c2], - # ), - # pytest.param( - # 'esp,idf,jtag', - # 'y', - # f'-c \'set ESP_SEMIHOST_BASEDIR "{TEMP_DIR}"\' -f board/esp32s2-kaluga-1.cfg', - # marks=[pytest.mark.esp32c3], - # ), - # pytest.param( - # 'esp,idf,jtag', - # 'y', - # f'-c \'set ESP_SEMIHOST_BASEDIR "{TEMP_DIR}"\' -f board/esp32s2-kaluga-1.cfg', - # marks=[pytest.mark.esp32s2], - # ), - # pytest.param( - # 'esp,idf,jtag', - # 'y', - # f'-c \'set ESP_SEMIHOST_BASEDIR "{TEMP_DIR}"\' -f board/esp32s2-kaluga-1.cfg', - # marks=[pytest.mark.esp32s3], - # ), ], indirect=True, ) diff --git a/examples/storage/spiffs/pytest_spiffs_example.py b/examples/storage/spiffs/pytest_spiffs_example.py index 0687ffe82f64..70e1540ecd67 100644 --- a/examples/storage/spiffs/pytest_spiffs_example.py +++ b/examples/storage/spiffs/pytest_spiffs_example.py @@ -7,7 +7,8 @@ from pytest_embedded import Dut -@pytest.mark.supported_targets +@pytest.mark.esp32 +@pytest.mark.esp32c3 def test_examples_spiffs(dut: Dut) -> None: message_list = (rb'example: Initializing SPIFFS', rb'example: Partition size: total: \d+, used: \d+', diff --git a/examples/storage/wear_levelling/pytest_wear_levelling_example.py b/examples/storage/wear_levelling/pytest_wear_levelling_example.py index c55352e02ac8..51ef1670acdf 100644 --- a/examples/storage/wear_levelling/pytest_wear_levelling_example.py +++ b/examples/storage/wear_levelling/pytest_wear_levelling_example.py @@ -8,7 +8,8 @@ from pytest_embedded import Dut -@pytest.mark.supported_targets +@pytest.mark.esp32 +@pytest.mark.esp32c3 def test_wear_levelling_example(dut: Dut) -> None: message_list = ('example: Mounting FAT filesystem', From 501dbcfacf77943000c258f643cb93a169209a8f Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Mon, 6 Nov 2023 16:39:28 +0800 Subject: [PATCH 158/161] ci(docs): stop build docs jobs from downloading artifacts --- .gitlab/ci/docs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab/ci/docs.yml b/.gitlab/ci/docs.yml index c0b5c6604bf4..95141ffdb94a 100644 --- a/.gitlab/ci/docs.yml +++ b/.gitlab/ci/docs.yml @@ -132,6 +132,7 @@ build_docs_html_full_prod: extends: - .build_docs_template - .doc-rules:build:docs-full-prod + dependencies: [] # Stop build_docs jobs from downloading all previous job's artifacts artifacts: when: always paths: @@ -184,6 +185,7 @@ build_docs_pdf_prod: extends: - .build_docs_template - .doc-rules:build:docs-full-prod + dependencies: [] # Stop build_docs jobs from downloading all previous job's artifacts artifacts: when: always paths: From 2ef14fe55e4ded342773b86df582fadc0958f453 Mon Sep 17 00:00:00 2001 From: morris Date: Fri, 27 Oct 2023 13:57:39 +0800 Subject: [PATCH 159/161] refactor(gptimer): refactor gptimer driver into a component --- components/app_trace/CMakeLists.txt | 4 ++-- components/app_trace/linker.lf | 2 +- .../app_trace/test_apps/main/CMakeLists.txt | 2 +- components/driver/CMakeLists.txt | 15 +++------------ components/driver/Kconfig | 4 ---- .../driver/test_apps/.build-test-rules.yml | 4 ---- .../esp_adc/test_apps/adc/main/CMakeLists.txt | 2 +- components/esp_driver_gptimer/CMakeLists.txt | 16 ++++++++++++++++ .../Kconfig} | 4 ++-- .../gptimer => esp_driver_gptimer}/README.md | 0 .../include/driver/gptimer.h | 0 .../include/driver/gptimer_etm.h | 0 .../include/driver/gptimer_types.h | 2 +- .../include/esp_private/gptimer.h | 0 .../gptimer => esp_driver_gptimer}/linker.lf | 2 +- .../gptimer => esp_driver_gptimer/src}/gptimer.c | 4 ++-- .../src}/gptimer_etm.c | 0 .../src}/gptimer_priv.c | 0 .../src}/gptimer_priv.h | 0 .../test_apps/.build-test-rules.yml | 7 +++++++ .../test_apps/gptimer/CMakeLists.txt | 2 +- .../test_apps/gptimer/README.md | 0 .../test_apps/gptimer/main/CMakeLists.txt | 0 .../test_apps/gptimer/main/test_app_main.c | 0 .../test_apps/gptimer/main/test_gptimer.c | 0 .../test_apps/gptimer/main/test_gptimer_iram.c | 0 .../test_apps/gptimer/pytest_gptimer.py | 0 .../gptimer/sdkconfig.ci.esp32c2_xtal26m | 0 .../test_apps/gptimer/sdkconfig.ci.iram_safe | 0 .../test_apps/gptimer/sdkconfig.ci.release | 0 .../test_apps/gptimer/sdkconfig.defaults | 0 components/esp_driver_pcnt/CMakeLists.txt | 16 +++++----------- .../esp_driver_pcnt/{Kconfig.pcnt => Kconfig} | 4 ++-- .../test_apps/.build-test-rules.yml | 5 +++++ .../test_apps/etm/main/CMakeLists.txt | 3 ++- .../spi_flash/test_apps/.build-test-rules.yml | 3 +-- docs/doxygen/Doxyfile | 6 +++--- examples/peripherals/.build-test-rules.yml | 12 +++++++++++- examples/system/.build-test-rules.yml | 2 +- .../system/g1_components/CMakeLists.txt | 2 +- .../components/test_utils/CMakeLists.txt | 4 +++- 41 files changed, 72 insertions(+), 55 deletions(-) create mode 100644 components/esp_driver_gptimer/CMakeLists.txt rename components/{driver/gptimer/Kconfig.gptimer => esp_driver_gptimer/Kconfig} (96%) rename components/{driver/gptimer => esp_driver_gptimer}/README.md (100%) rename components/{driver/gptimer => esp_driver_gptimer}/include/driver/gptimer.h (100%) rename components/{driver/gptimer => esp_driver_gptimer}/include/driver/gptimer_etm.h (100%) rename components/{driver/gptimer => esp_driver_gptimer}/include/driver/gptimer_types.h (88%) rename components/{driver => esp_driver_gptimer}/include/esp_private/gptimer.h (100%) rename components/{driver/gptimer => esp_driver_gptimer}/linker.lf (95%) rename components/{driver/gptimer => esp_driver_gptimer/src}/gptimer.c (98%) rename components/{driver/gptimer => esp_driver_gptimer/src}/gptimer_etm.c (100%) rename components/{driver/gptimer => esp_driver_gptimer/src}/gptimer_priv.c (100%) rename components/{driver/gptimer => esp_driver_gptimer/src}/gptimer_priv.h (100%) create mode 100644 components/esp_driver_gptimer/test_apps/.build-test-rules.yml rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/CMakeLists.txt (87%) rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/README.md (100%) rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/main/CMakeLists.txt (100%) rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/main/test_app_main.c (100%) rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/main/test_gptimer.c (100%) rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/main/test_gptimer_iram.c (100%) rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/pytest_gptimer.py (100%) rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/sdkconfig.ci.esp32c2_xtal26m (100%) rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/sdkconfig.ci.iram_safe (100%) rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/sdkconfig.ci.release (100%) rename components/{driver => esp_driver_gptimer}/test_apps/gptimer/sdkconfig.defaults (100%) rename components/esp_driver_pcnt/{Kconfig.pcnt => Kconfig} (95%) diff --git a/components/app_trace/CMakeLists.txt b/components/app_trace/CMakeLists.txt index 2a185d544df8..ff17766baead 100644 --- a/components/app_trace/CMakeLists.txt +++ b/components/app_trace/CMakeLists.txt @@ -63,8 +63,8 @@ endif() idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" PRIV_INCLUDE_DIRS "${priv_include_dirs}" - # Requires "driver" for GPTimer in "SEGGER_SYSVIEW_Config_FreeRTOS.c" - PRIV_REQUIRES soc driver esp_driver_gpio + PRIV_REQUIRES soc esp_driver_gptimer esp_driver_gpio + driver # TODO: replace with esp_driver_uart (IDF-8384) REQUIRES esp_timer LDFRAGMENTS linker.lf) diff --git a/components/app_trace/linker.lf b/components/app_trace/linker.lf index e9c57c845709..5054ea441945 100644 --- a/components/app_trace/linker.lf +++ b/components/app_trace/linker.lf @@ -15,7 +15,7 @@ entries: SEGGER_SYSVIEW_FreeRTOS (noflash) [mapping:app_trace_driver] -archive: libdriver.a +archive: libesp_driver_gptimer.a entries: if APPTRACE_SV_TS_SOURCE_GPTIMER = y: gptimer (noflash) diff --git a/components/app_trace/test_apps/main/CMakeLists.txt b/components/app_trace/test_apps/main/CMakeLists.txt index 7661fbba7684..45781494003f 100644 --- a/components/app_trace/test_apps/main/CMakeLists.txt +++ b/components/app_trace/test_apps/main/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register(SRCS "test_app_trace_main.c" "test_trace.c" INCLUDE_DIRS "." - PRIV_REQUIRES app_trace unity driver + PRIV_REQUIRES app_trace unity esp_driver_gptimer WHOLE_ARCHIVE) diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index a4f4f3eb8779..65a4add014eb 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -13,7 +13,6 @@ set(includes "include" "deprecated" "analog_comparator/include" "dac/include" - "gptimer/include" "i2c/include" "i2s/include" "ledc/include" @@ -66,17 +65,9 @@ if(CONFIG_SOC_PARLIO_SUPPORTED) list(APPEND srcs "parlio/parlio_common.c" "parlio/parlio_tx.c") endif() -# GPTimer related source files +# GPTimer legacy driver if(CONFIG_SOC_GPTIMER_SUPPORTED) - list(APPEND srcs "gptimer/gptimer.c" - "gptimer/gptimer_priv.c" - "deprecated/timer_legacy.c") - - list(APPEND ldfragments "gptimer/linker.lf") -endif() - -if(CONFIG_SOC_TIMER_SUPPORT_ETM) - list(APPEND srcs "gptimer/gptimer_etm.c") + list(APPEND srcs "deprecated/timer_legacy.c") endif() # I2C related source files @@ -226,7 +217,7 @@ else() REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support # for backward compatibility, the driver component needs to # have a public dependency on other "esp_driver_foo" components - esp_driver_gpio esp_driver_pcnt + esp_driver_gpio esp_driver_pcnt esp_driver_gptimer LDFRAGMENTS ${ldfragments} ) endif() diff --git a/components/driver/Kconfig b/components/driver/Kconfig index 5de2715b0f81..9b0729bb8d08 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -207,10 +207,6 @@ menu "Driver Configurations" Note that, this option only controls the Analog Comparator driver log, won't affect other drivers. endmenu # Analog Comparator Configuration - orsource "./gptimer/Kconfig.gptimer" - - orsource "../esp_driver_pcnt/Kconfig.pcnt" - orsource "./rmt/Kconfig.rmt" orsource "./mcpwm/Kconfig.mcpwm" diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index b8ed1bf8048c..bf271a81f778 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -16,10 +16,6 @@ components/driver/test_apps/dac_test_apps/legacy_dac_driver: disable: - if: SOC_DAC_SUPPORTED != 1 -components/driver/test_apps/gptimer: - disable: - - if: SOC_GPTIMER_SUPPORTED != 1 - components/driver/test_apps/i2c_test_apps: disable: - if: SOC_I2C_SUPPORTED != 1 # TODO: IDF-8070 diff --git a/components/esp_adc/test_apps/adc/main/CMakeLists.txt b/components/esp_adc/test_apps/adc/main/CMakeLists.txt index cde2d68cc25e..8b8cc4b08563 100644 --- a/components/esp_adc/test_apps/adc/main/CMakeLists.txt +++ b/components/esp_adc/test_apps/adc/main/CMakeLists.txt @@ -9,5 +9,5 @@ set(srcs "test_app_main.c" # 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} - PRIV_REQUIRES driver esp_wifi nvs_flash esp_adc test_utils efuse + PRIV_REQUIRES esp_driver_gptimer esp_driver_gpio esp_wifi nvs_flash esp_adc test_utils efuse WHOLE_ARCHIVE) diff --git a/components/esp_driver_gptimer/CMakeLists.txt b/components/esp_driver_gptimer/CMakeLists.txt new file mode 100644 index 000000000000..4ec99842f0f5 --- /dev/null +++ b/components/esp_driver_gptimer/CMakeLists.txt @@ -0,0 +1,16 @@ +set(srcs) +set(public_include "include") +if(CONFIG_SOC_GPTIMER_SUPPORTED) + list(APPEND srcs "src/gptimer.c" + "src/gptimer_priv.c") +endif() + +if(CONFIG_SOC_TIMER_SUPPORT_ETM) + list(APPEND srcs "src/gptimer_etm.c") +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${public_include} + PRIV_REQUIRES "esp_pm" + LDFRAGMENTS "linker.lf" + ) diff --git a/components/driver/gptimer/Kconfig.gptimer b/components/esp_driver_gptimer/Kconfig similarity index 96% rename from components/driver/gptimer/Kconfig.gptimer rename to components/esp_driver_gptimer/Kconfig index 5aeda6fd04fe..8aa5f2d9ba54 100644 --- a/components/driver/gptimer/Kconfig.gptimer +++ b/components/esp_driver_gptimer/Kconfig @@ -1,4 +1,4 @@ -menu "GPTimer Configuration" +menu "ESP-Driver:GPTimer Configurations" depends on SOC_GPTIMER_SUPPORTED config GPTIMER_ISR_HANDLER_IN_IRAM bool "Place GPTimer ISR handler into IRAM" @@ -36,4 +36,4 @@ menu "GPTimer Configuration" help Wether to enable the debug log message for GPTimer driver. Note that, this option only controls the GPTimer driver log, won't affect other drivers. -endmenu # GPTimer Configuration +endmenu diff --git a/components/driver/gptimer/README.md b/components/esp_driver_gptimer/README.md similarity index 100% rename from components/driver/gptimer/README.md rename to components/esp_driver_gptimer/README.md diff --git a/components/driver/gptimer/include/driver/gptimer.h b/components/esp_driver_gptimer/include/driver/gptimer.h similarity index 100% rename from components/driver/gptimer/include/driver/gptimer.h rename to components/esp_driver_gptimer/include/driver/gptimer.h diff --git a/components/driver/gptimer/include/driver/gptimer_etm.h b/components/esp_driver_gptimer/include/driver/gptimer_etm.h similarity index 100% rename from components/driver/gptimer/include/driver/gptimer_etm.h rename to components/esp_driver_gptimer/include/driver/gptimer_etm.h diff --git a/components/driver/gptimer/include/driver/gptimer_types.h b/components/esp_driver_gptimer/include/driver/gptimer_types.h similarity index 88% rename from components/driver/gptimer/include/driver/gptimer_types.h rename to components/esp_driver_gptimer/include/driver/gptimer_types.h index 8fc188d8289d..38abfd44181d 100644 --- a/components/driver/gptimer/include/driver/gptimer_types.h +++ b/components/esp_driver_gptimer/include/driver/gptimer_types.h @@ -35,7 +35,7 @@ typedef struct { * @param[in] user_ctx User data, passed from `gptimer_register_event_callbacks` * @return Whether a high priority task has been waken up by this function */ -typedef bool (*gptimer_alarm_cb_t) (gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx); +typedef bool (*gptimer_alarm_cb_t)(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx); #ifdef __cplusplus } diff --git a/components/driver/include/esp_private/gptimer.h b/components/esp_driver_gptimer/include/esp_private/gptimer.h similarity index 100% rename from components/driver/include/esp_private/gptimer.h rename to components/esp_driver_gptimer/include/esp_private/gptimer.h diff --git a/components/driver/gptimer/linker.lf b/components/esp_driver_gptimer/linker.lf similarity index 95% rename from components/driver/gptimer/linker.lf rename to components/esp_driver_gptimer/linker.lf index 11d7eeb26c1f..72f9e6eafd1e 100644 --- a/components/driver/gptimer/linker.lf +++ b/components/esp_driver_gptimer/linker.lf @@ -1,5 +1,5 @@ [mapping:gptimer_driver] -archive: libdriver.a +archive: libesp_driver_gptimer.a entries: if GPTIMER_ISR_HANDLER_IN_IRAM = y: gptimer: gptimer_default_isr (noflash) diff --git a/components/driver/gptimer/gptimer.c b/components/esp_driver_gptimer/src/gptimer.c similarity index 98% rename from components/driver/gptimer/gptimer.c rename to components/esp_driver_gptimer/src/gptimer.c index 61978935b1ee..447aebfbbfbd 100644 --- a/components/driver/gptimer/gptimer.c +++ b/components/esp_driver_gptimer/src/gptimer.c @@ -254,8 +254,8 @@ esp_err_t gptimer_register_event_callbacks(gptimer_handle_t timer, const gptimer isr_flags |= 1 << (timer->intr_priority); } ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(timer_group_periph_signals.groups[group_id].timer_irq_id[timer_id], isr_flags, - (uint32_t)timer_ll_get_intr_status_reg(timer->hal.dev), TIMER_LL_EVENT_ALARM(timer_id), - gptimer_default_isr, timer, &timer->intr), TAG, "install interrupt service failed"); + (uint32_t)timer_ll_get_intr_status_reg(timer->hal.dev), TIMER_LL_EVENT_ALARM(timer_id), + gptimer_default_isr, timer, &timer->intr), TAG, "install interrupt service failed"); } // enable/disable GPTimer interrupt events diff --git a/components/driver/gptimer/gptimer_etm.c b/components/esp_driver_gptimer/src/gptimer_etm.c similarity index 100% rename from components/driver/gptimer/gptimer_etm.c rename to components/esp_driver_gptimer/src/gptimer_etm.c diff --git a/components/driver/gptimer/gptimer_priv.c b/components/esp_driver_gptimer/src/gptimer_priv.c similarity index 100% rename from components/driver/gptimer/gptimer_priv.c rename to components/esp_driver_gptimer/src/gptimer_priv.c diff --git a/components/driver/gptimer/gptimer_priv.h b/components/esp_driver_gptimer/src/gptimer_priv.h similarity index 100% rename from components/driver/gptimer/gptimer_priv.h rename to components/esp_driver_gptimer/src/gptimer_priv.h diff --git a/components/esp_driver_gptimer/test_apps/.build-test-rules.yml b/components/esp_driver_gptimer/test_apps/.build-test-rules.yml new file mode 100644 index 000000000000..a48c8d7cfcfc --- /dev/null +++ b/components/esp_driver_gptimer/test_apps/.build-test-rules.yml @@ -0,0 +1,7 @@ +# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps + +components/esp_driver_gptimer/test_apps/gptimer: + disable: + - if: SOC_GPTIMER_SUPPORTED != 1 + depends_components: + - esp_driver_gptimer diff --git a/components/driver/test_apps/gptimer/CMakeLists.txt b/components/esp_driver_gptimer/test_apps/gptimer/CMakeLists.txt similarity index 87% rename from components/driver/test_apps/gptimer/CMakeLists.txt rename to components/esp_driver_gptimer/test_apps/gptimer/CMakeLists.txt index 50a85ed1dd5c..ba96212bd03e 100644 --- a/components/driver/test_apps/gptimer/CMakeLists.txt +++ b/components/esp_driver_gptimer/test_apps/gptimer/CMakeLists.txt @@ -10,7 +10,7 @@ project(gptimer_test) if(CONFIG_COMPILER_DUMP_RTL_FILES) add_custom_target(check_test_app_sections ALL COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py - --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_gptimer/,${CMAKE_BINARY_DIR}/esp-idf/hal/ --elf-file ${CMAKE_BINARY_DIR}/gptimer_test.elf find-refs --from-sections=.iram0.text diff --git a/components/driver/test_apps/gptimer/README.md b/components/esp_driver_gptimer/test_apps/gptimer/README.md similarity index 100% rename from components/driver/test_apps/gptimer/README.md rename to components/esp_driver_gptimer/test_apps/gptimer/README.md diff --git a/components/driver/test_apps/gptimer/main/CMakeLists.txt b/components/esp_driver_gptimer/test_apps/gptimer/main/CMakeLists.txt similarity index 100% rename from components/driver/test_apps/gptimer/main/CMakeLists.txt rename to components/esp_driver_gptimer/test_apps/gptimer/main/CMakeLists.txt diff --git a/components/driver/test_apps/gptimer/main/test_app_main.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_app_main.c similarity index 100% rename from components/driver/test_apps/gptimer/main/test_app_main.c rename to components/esp_driver_gptimer/test_apps/gptimer/main/test_app_main.c diff --git a/components/driver/test_apps/gptimer/main/test_gptimer.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c similarity index 100% rename from components/driver/test_apps/gptimer/main/test_gptimer.c rename to components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer.c diff --git a/components/driver/test_apps/gptimer/main/test_gptimer_iram.c b/components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_iram.c similarity index 100% rename from components/driver/test_apps/gptimer/main/test_gptimer_iram.c rename to components/esp_driver_gptimer/test_apps/gptimer/main/test_gptimer_iram.c diff --git a/components/driver/test_apps/gptimer/pytest_gptimer.py b/components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py similarity index 100% rename from components/driver/test_apps/gptimer/pytest_gptimer.py rename to components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py diff --git a/components/driver/test_apps/gptimer/sdkconfig.ci.esp32c2_xtal26m b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.esp32c2_xtal26m similarity index 100% rename from components/driver/test_apps/gptimer/sdkconfig.ci.esp32c2_xtal26m rename to components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.esp32c2_xtal26m diff --git a/components/driver/test_apps/gptimer/sdkconfig.ci.iram_safe b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.iram_safe similarity index 100% rename from components/driver/test_apps/gptimer/sdkconfig.ci.iram_safe rename to components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.iram_safe diff --git a/components/driver/test_apps/gptimer/sdkconfig.ci.release b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release similarity index 100% rename from components/driver/test_apps/gptimer/sdkconfig.ci.release rename to components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.ci.release diff --git a/components/driver/test_apps/gptimer/sdkconfig.defaults b/components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.defaults similarity index 100% rename from components/driver/test_apps/gptimer/sdkconfig.defaults rename to components/esp_driver_gptimer/test_apps/gptimer/sdkconfig.defaults diff --git a/components/esp_driver_pcnt/CMakeLists.txt b/components/esp_driver_pcnt/CMakeLists.txt index d146afbab477..6cf979b0cc6b 100644 --- a/components/esp_driver_pcnt/CMakeLists.txt +++ b/components/esp_driver_pcnt/CMakeLists.txt @@ -4,14 +4,8 @@ if(CONFIG_SOC_PCNT_SUPPORTED) list(APPEND srcs "src/pulse_cnt.c") endif() -if(BOOTLOADER_BUILD) - # Bootloader shall NOT depend on the drivers - idf_component_register() -else() - idf_component_register(SRCS ${srcs} - INCLUDE_DIRS ${public_include} - PRIV_REQUIRES "esp_pm" - "esp_driver_gpio" - LDFRAGMENTS "linker.lf" - ) -endif() +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${public_include} + PRIV_REQUIRES "esp_pm" "esp_driver_gpio" + LDFRAGMENTS "linker.lf" + ) diff --git a/components/esp_driver_pcnt/Kconfig.pcnt b/components/esp_driver_pcnt/Kconfig similarity index 95% rename from components/esp_driver_pcnt/Kconfig.pcnt rename to components/esp_driver_pcnt/Kconfig index 4a01e4514114..e7f2d526e566 100644 --- a/components/esp_driver_pcnt/Kconfig.pcnt +++ b/components/esp_driver_pcnt/Kconfig @@ -1,4 +1,4 @@ -menu "PCNT Configuration" +menu "ESP-Driver:PCNT Configurations" depends on SOC_PCNT_SUPPORTED config PCNT_CTRL_FUNC_IN_IRAM bool "Place PCNT control functions into IRAM" @@ -29,4 +29,4 @@ menu "PCNT Configuration" help Wether to enable the debug log message for PCNT driver. Note that, this option only controls the PCNT driver log, won't affect other drivers. -endmenu # PCNT Configuration +endmenu diff --git a/components/esp_hw_support/test_apps/.build-test-rules.yml b/components/esp_hw_support/test_apps/.build-test-rules.yml index dcb1f22d8857..badd45f01ace 100644 --- a/components/esp_hw_support/test_apps/.build-test-rules.yml +++ b/components/esp_hw_support/test_apps/.build-test-rules.yml @@ -13,6 +13,11 @@ components/esp_hw_support/test_apps/esp_hw_support_unity_tests: components/esp_hw_support/test_apps/etm: disable: - if: SOC_ETM_SUPPORTED != 1 + depends_components: + - esp_driver_gptimer + - esp_driver_gpio + - esp_timer + - driver # TODO: replace with esp_driver_mcpwm, esp_driver_ana_cmpr components/esp_hw_support/test_apps/host_test_linux: enable: diff --git a/components/esp_hw_support/test_apps/etm/main/CMakeLists.txt b/components/esp_hw_support/test_apps/etm/main/CMakeLists.txt index e7a895debdcb..7b84296f731c 100644 --- a/components/esp_hw_support/test_apps/etm/main/CMakeLists.txt +++ b/components/esp_hw_support/test_apps/etm/main/CMakeLists.txt @@ -29,5 +29,6 @@ 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} - PRIV_REQUIRES unity esp_timer driver + PRIV_REQUIRES unity esp_timer esp_driver_gptimer esp_driver_gpio + driver # TODO: replace with esp_driver_mcpwm (IDF-8379), esp_driver_ana_cmpr WHOLE_ARCHIVE) diff --git a/components/spi_flash/test_apps/.build-test-rules.yml b/components/spi_flash/test_apps/.build-test-rules.yml index 1c73293f31a0..ba39b0d3573e 100644 --- a/components/spi_flash/test_apps/.build-test-rules.yml +++ b/components/spi_flash/test_apps/.build-test-rules.yml @@ -38,10 +38,9 @@ components/spi_flash/test_apps/flash_suspend: - if: IDF_TARGET != "esp32c3" temporary: true reason: lack of runners - depends_filepatterns: - - components/driver/gptimer/**/* depends_components: - spi_flash + - esp_driver_gptimer components/spi_flash/test_apps/mspi_test: disable: diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 516a1cf013a1..53ba9d0e7e9d 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -79,9 +79,6 @@ INPUT = \ $(PROJECT_PATH)/components/driver/dac/include/driver/dac_cosine.h \ $(PROJECT_PATH)/components/driver/dac/include/driver/dac_oneshot.h \ $(PROJECT_PATH)/components/driver/dac/include/driver/dac_types.h \ - $(PROJECT_PATH)/components/driver/gptimer/include/driver/gptimer.h \ - $(PROJECT_PATH)/components/driver/gptimer/include/driver/gptimer_etm.h \ - $(PROJECT_PATH)/components/driver/gptimer/include/driver/gptimer_types.h \ $(PROJECT_PATH)/components/driver/i2c/include/driver/i2c.h \ $(PROJECT_PATH)/components/driver/i2s/include/driver/i2s_common.h \ $(PROJECT_PATH)/components/driver/i2s/include/driver/i2s_pdm.h \ @@ -139,6 +136,9 @@ INPUT = \ $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/gpio_filter.h \ $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/lp_io.h \ $(PROJECT_PATH)/components/esp_driver_gpio/include/driver/rtc_io.h \ + $(PROJECT_PATH)/components/esp_driver_gptimer/include/driver/gptimer.h \ + $(PROJECT_PATH)/components/esp_driver_gptimer/include/driver/gptimer_etm.h \ + $(PROJECT_PATH)/components/esp_driver_gptimer/include/driver/gptimer_types.h \ $(PROJECT_PATH)/components/esp_driver_pcnt/include/driver/pulse_cnt.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_com.h \ $(PROJECT_PATH)/components/esp_eth/include/esp_eth_driver.h \ diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index 834340c6e129..bba8410d58f9 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -299,13 +299,23 @@ examples/peripherals/temperature_sensor/temp_sensor_monitor: disable: - if: SOC_TEMPERATURE_SENSOR_INTR_SUPPORT != 1 -examples/peripherals/timer_group: +examples/peripherals/timer_group/gptimer: disable: - if: SOC_GPTIMER_SUPPORTED != 1 + depends_components: + - esp_driver_gptimer examples/peripherals/timer_group/gptimer_capture_hc_sr04: disable: - if: SOC_TIMER_SUPPORT_ETM != 1 + depends_components: + - esp_driver_gptimer + +examples/peripherals/timer_group/legacy_driver: + disable: + - if: SOC_GPTIMER_SUPPORTED != 1 + depends_components: + - driver # legacy driver is still located in the "driver" component examples/peripherals/touch_sensor: disable: diff --git a/examples/system/.build-test-rules.yml b/examples/system/.build-test-rules.yml index 7dac32024a94..812425a15b78 100644 --- a/examples/system/.build-test-rules.yml +++ b/examples/system/.build-test-rules.yml @@ -81,7 +81,7 @@ examples/system/eventfd: - if: SOC_GPTIMER_SUPPORTED != 1 depends_components: - vfs - - driver + - esp_driver_gptimer examples/system/flash_suspend: enable: diff --git a/tools/test_apps/system/g1_components/CMakeLists.txt b/tools/test_apps/system/g1_components/CMakeLists.txt index ceb1b6512ef6..582efb40ad0d 100644 --- a/tools/test_apps/system/g1_components/CMakeLists.txt +++ b/tools/test_apps/system/g1_components/CMakeLists.txt @@ -35,7 +35,7 @@ set(extra_components_which_shouldnt_be_included cxx # [refactor-todo]: driver is a dependency of esp_pm, spi_flash, vfs, esp_wifi # all of these should be removed from G1 except for spi_flash. - driver esp_driver_gpio esp_driver_pcnt + driver esp_driver_gpio esp_driver_pcnt esp_driver_gptimer # esp_app_format is dependency of bootloader_support, app_update esp_app_format # esp_bootloader_format is dependency of bootloader_support, app_update diff --git a/tools/unit-test-app/components/test_utils/CMakeLists.txt b/tools/unit-test-app/components/test_utils/CMakeLists.txt index 8a50233d5747..860cbf717fb0 100644 --- a/tools/unit-test-app/components/test_utils/CMakeLists.txt +++ b/tools/unit-test-app/components/test_utils/CMakeLists.txt @@ -16,5 +16,7 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS include REQUIRES esp_partition idf_test cmock - PRIV_REQUIRES perfmon esp_driver_pcnt driver esp_netif) + PRIV_REQUIRES perfmon esp_driver_pcnt esp_driver_gptimer esp_netif + driver # TODO: replace with esp_driver_rmt + ) target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") From f2304a5f7378be10721b4a125c364b1ded0294c0 Mon Sep 17 00:00:00 2001 From: morris Date: Fri, 3 Nov 2023 13:39:29 +0800 Subject: [PATCH 160/161] docs: adding migration guide about esp_driver_xyz components --- docs/en/migration-guides/index.rst | 1 + .../release-5.x/5.3/index.rst | 9 ++++++ .../release-5.x/5.3/peripherals.rst | 30 +++++++++++++++++++ docs/zh_CN/migration-guides/index.rst | 1 + .../release-5.x/5.3/index.rst | 9 ++++++ .../release-5.x/5.3/peripherals.rst | 30 +++++++++++++++++++ 6 files changed, 80 insertions(+) create mode 100644 docs/en/migration-guides/release-5.x/5.3/index.rst create mode 100644 docs/en/migration-guides/release-5.x/5.3/peripherals.rst create mode 100644 docs/zh_CN/migration-guides/release-5.x/5.3/index.rst create mode 100644 docs/zh_CN/migration-guides/release-5.x/5.3/peripherals.rst diff --git a/docs/en/migration-guides/index.rst b/docs/en/migration-guides/index.rst index 5ef50545688b..199427c2e9d3 100644 --- a/docs/en/migration-guides/index.rst +++ b/docs/en/migration-guides/index.rst @@ -12,3 +12,4 @@ ESP-IDF 5.x Migration Guide release-5.x/5.0/index release-5.x/5.1/index release-5.x/5.2/index + release-5.x/5.3/index diff --git a/docs/en/migration-guides/release-5.x/5.3/index.rst b/docs/en/migration-guides/release-5.x/5.3/index.rst new file mode 100644 index 000000000000..caccc5418757 --- /dev/null +++ b/docs/en/migration-guides/release-5.x/5.3/index.rst @@ -0,0 +1,9 @@ +Migration from 5.2 to 5.3 +------------------------- + +:link_to_translation:`zh_CN:[中文]` + +.. toctree:: + :maxdepth: 1 + + peripherals diff --git a/docs/en/migration-guides/release-5.x/5.3/peripherals.rst b/docs/en/migration-guides/release-5.x/5.3/peripherals.rst new file mode 100644 index 000000000000..7321835ee14b --- /dev/null +++ b/docs/en/migration-guides/release-5.x/5.3/peripherals.rst @@ -0,0 +1,30 @@ +Peripherals +=========== + +:link_to_translation:`zh_CN:[中文]` + +In order to control the dependence of other components on drivers at a smaller granularity, the original peripheral drivers under the `driver`` component were split into separate components: + +- `esp_driver_gptimer` - Driver for general purpose timers +- `esp_driver_pcnt` - Driver for pulse counter +- `esp_driver_gpio` - Driver for GPIO + +For compatibility, the original `driver`` component is still treated as an all-in-one component by registering these `esp_driver_xyz`` components as its public dependencies. In other words, you do not need to modify the CMake file of an existing project, but you now have a way to specify the specific peripheral driver that your project depends on. + +Originally, you may have used **linker.lf** to specify the link location of some driver functions in memory space, but now, because the location of the driver files have been moved, you need to make changes your **linker.lf** file accordingly. For example, a linker.lf file with the following entries: + +.. code-block:: none + + [mapping:my_mapping_scheme] + archive: libdriver.a + entries: + gpio (noflash) + +Should be changed to: + +.. code-block:: none + + [mapping:my_mapping_scheme] + archive: libesp_driver_gpio.a + entries: + gpio (noflash) diff --git a/docs/zh_CN/migration-guides/index.rst b/docs/zh_CN/migration-guides/index.rst index a451fb268d3b..c458c6398f3b 100644 --- a/docs/zh_CN/migration-guides/index.rst +++ b/docs/zh_CN/migration-guides/index.rst @@ -12,3 +12,4 @@ release-5.x/5.0/index release-5.x/5.1/index release-5.x/5.2/index + release-5.x/5.3/index diff --git a/docs/zh_CN/migration-guides/release-5.x/5.3/index.rst b/docs/zh_CN/migration-guides/release-5.x/5.3/index.rst new file mode 100644 index 000000000000..25aeb7dff3ff --- /dev/null +++ b/docs/zh_CN/migration-guides/release-5.x/5.3/index.rst @@ -0,0 +1,9 @@ +从 5.2 迁移到 5.3 +----------------- + +:link_to_translation:`en:[English]` + +.. toctree:: + :maxdepth: 1 + + peripherals diff --git a/docs/zh_CN/migration-guides/release-5.x/5.3/peripherals.rst b/docs/zh_CN/migration-guides/release-5.x/5.3/peripherals.rst new file mode 100644 index 000000000000..81411dc91f56 --- /dev/null +++ b/docs/zh_CN/migration-guides/release-5.x/5.3/peripherals.rst @@ -0,0 +1,30 @@ +外设 +==== + +:link_to_translation:`en:[English]` + +为了细粒度地控制其他组件对外设驱动的依赖,原先位于 `driver` 组件下的驱动程序被拆分到了各自独立的组件中。这些组件包括: + +- `esp_driver_gptimer` - 通用定时器驱动 +- `esp_driver_pcnt` - 脉冲计数器驱动 +- `esp_driver_gpio` - GPIO 驱动 + +为了兼容性,原来的 `driver` 组件仍然存在,并作为一个 “all-in-one" 的组件,将以上这些 `esp_driver_xyz` 组件注册成自己的公共依赖。换句话说,你无需修改既有项目的 CMake 文件,但是你现在多了一个途径去指定你项目依赖的具体的外设驱动。 + +原来你可能使用 **linker.lf** 指定了一些驱动函数在内存空间的链接位置,但是现在,因为驱动文件的位置发生了挪动,就需要你对 **linker.lf** 文件做出相应的改动的。假如,你的 linker.lf 文件里面有以下的条目: + +.. code-block:: none + + [mapping:my_mapping_scheme] + archive: libdriver.a + entries: + gpio (noflash) + +现在需要修改成: + +.. code-block:: none + + [mapping:my_mapping_scheme] + archive: libesp_driver_gpio.a + entries: + gpio (noflash) From d3be2541dee9657d7991182eba7b1c9b32fc94e5 Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 13 Oct 2023 16:02:45 +0800 Subject: [PATCH 161/161] fix(adc): rename ADC_ATTEN_DB_11 to ADC_ATTEN_DB_12 By design, it's 12 dB. There're errors among chips, so the actual attenuation will be 11dB more or less --- .../driver/deprecated/adc_i2s_deprecated.c | 2 +- components/driver/deprecated/adc_legacy.c | 2 +- .../test_apps/dac_test_apps/dac/main/test_dac.c | 2 +- .../legacy_dac_driver/main/test_legacy_dac.c | 6 +++--- .../legacy_i2s_driver/main/test_legacy_i2s.c | 2 +- .../legacy_adc_driver/main/test_legacy_adc.c | 4 ++-- components/efuse/esp32c2/esp_efuse_rtc_calib.c | 10 +++++----- .../deprecated/esp32/esp_adc_cal_legacy.c | 6 +++--- .../deprecated/esp32s2/esp_adc_cal_legacy.c | 2 +- components/esp_adc/esp32/adc_cali_line_fitting.c | 6 +++--- .../esp_adc/esp32c2/adc_cali_line_fitting.c | 2 +- .../esp_adc/esp32s2/adc_cali_line_fitting.c | 2 +- components/esp_adc/test_apps/adc/main/test_adc.c | 8 ++++---- .../esp_adc/test_apps/adc/main/test_adc_driver.c | 6 +++--- .../test_apps/adc/main/test_adc_driver_iram.c | 2 +- .../test_apps/adc/main/test_adc_performance.c | 16 ++++++++-------- .../esp_adc/test_apps/adc/main/test_adc_wifi.c | 2 +- .../esp_adc/test_apps/adc/main/test_common_adc.c | 4 ++-- .../esp_hw_support/port/esp32c3/adc2_init_cal.c | 4 ++-- .../esp_hw_support/port/esp32s2/adc2_init_cal.c | 4 ++-- components/hal/esp32s2/include/hal/adc_ll.h | 4 ++-- components/hal/esp32s3/include/hal/adc_ll.h | 4 ++-- components/hal/include/hal/adc_types.h | 9 +++++---- .../peripherals/adc_calibration.rst | 4 ++-- .../en/api-reference/peripherals/adc_oneshot.rst | 2 +- .../peripherals/adc_calibration.rst | 4 ++-- .../api-reference/peripherals/adc_oneshot.rst | 2 +- .../adc/oneshot_read/main/oneshot_read_main.c | 2 +- .../main/dac_continuous_example_main.c | 2 +- .../main/dac_cosine_example_main.c | 2 +- .../dac_oneshot/main/dac_oneshot_example_main.c | 2 +- .../ulp_fsm/ulp_adc/main/ulp/example_config.h | 2 +- .../ulp/ulp_riscv/adc/main/ulp/example_config.h | 2 +- 33 files changed, 67 insertions(+), 66 deletions(-) diff --git a/components/driver/deprecated/adc_i2s_deprecated.c b/components/driver/deprecated/adc_i2s_deprecated.c index 2971e476097a..e05eec2c4586 100644 --- a/components/driver/deprecated/adc_i2s_deprecated.c +++ b/components/driver/deprecated/adc_i2s_deprecated.c @@ -56,7 +56,7 @@ esp_pm_lock_handle_t adc_digi_arbiter_lock = NULL; ESP32 Depricated ADC APIs and functions ---------------------------------------------------------------*/ #define DIG_ADC_OUTPUT_FORMAT_DEFUALT (ADC_DIGI_FORMAT_12BIT) -#define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_11) +#define DIG_ADC_ATTEN_DEFUALT (ADC_ATTEN_DB_12) #define DIG_ADC_BIT_WIDTH_DEFUALT (3) //3 for ADC_WIDTH_BIT_12 /** diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c index b20df639e662..a88c42465d3e 100644 --- a/components/driver/deprecated/adc_legacy.c +++ b/components/driver/deprecated/adc_legacy.c @@ -802,7 +802,7 @@ int adc1_get_raw(adc1_channel_t channel) esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten) { ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_2), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 channel error"); - ESP_RETURN_ON_FALSE((atten <= ADC_ATTEN_DB_11), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 Atten Err"); + ESP_RETURN_ON_FALSE((atten <= ADC_ATTEN_DB_12), ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 Atten Err"); esp_err_t ret = ESP_OK; s_atten2_single[channel] = atten; diff --git a/components/driver/test_apps/dac_test_apps/dac/main/test_dac.c b/components/driver/test_apps/dac_test_apps/dac/main/test_dac.c index b6e17c985414..4a0a99f83e98 100644 --- a/components/driver/test_apps/dac_test_apps/dac/main/test_dac.c +++ b/components/driver/test_apps/dac_test_apps/dac/main/test_dac.c @@ -33,7 +33,7 @@ #define ADC_TEST_WIDTH ADC_BITWIDTH_13 #endif -#define ADC_TEST_ATTEN ADC_ATTEN_DB_11 +#define ADC_TEST_ATTEN ADC_ATTEN_DB_12 TEST_CASE("DAC_API_basic_logic_test", "[dac]") { diff --git a/components/driver/test_apps/dac_test_apps/legacy_dac_driver/main/test_legacy_dac.c b/components/driver/test_apps/dac_test_apps/legacy_dac_driver/main/test_legacy_dac.c index 7a2a5da90bfd..f612a37229d7 100644 --- a/components/driver/test_apps/dac_test_apps/legacy_dac_driver/main/test_legacy_dac.c +++ b/components/driver/test_apps/dac_test_apps/legacy_dac_driver/main/test_legacy_dac.c @@ -28,7 +28,7 @@ static const char *TAG = "test_dac"; #elif defined CONFIG_IDF_TARGET_ESP32S2 #define ADC_TEST_WIDTH ADC_WIDTH_BIT_13 //ESP32S2 only support 13 bit width #endif -#define ADC_TEST_ATTEN ADC_ATTEN_DB_11 +#define ADC_TEST_ATTEN ADC_ATTEN_DB_12 #if CONFIG_IDF_TARGET_ESP32 #define ADC_TEST_CHANNEL_NUM ADC2_CHANNEL_8 // GPIO25 @@ -174,8 +174,8 @@ TEST_CASE("esp32s2_adc2-dac_with_adc2_calibration", "[dac_legacy]") subtest_adc_dac(1250, &chars); printf("Test 11dB atten...\n"); - adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_11); - esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_13, 0, &chars); + adc2_config_channel_atten((adc2_channel_t)ADC_TEST_CHANNEL_NUM, ADC_ATTEN_DB_12); + esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_12, ADC_WIDTH_BIT_13, 0, &chars); printf("a %"PRIu32", b %"PRIu32"\n", chars.coeff_a, chars.coeff_b); subtest_adc_dac(1500, &chars); subtest_adc_dac(2500, &chars); diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c index 1c30ab7cd792..38e30e897741 100644 --- a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/main/test_legacy_i2s.c @@ -114,7 +114,7 @@ TEST_CASE("I2S_adc_test", "[i2s_legacy]") i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); // init ADC pad i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_4); - // enable adc sampling, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11 hard-coded in adc_i2s_mode_init + // enable adc sampling, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_12 hard-coded in adc_i2s_mode_init i2s_adc_enable(I2S_NUM_0); // init read buffer uint16_t *i2sReadBuffer = (uint16_t *)calloc(1024, sizeof(uint16_t)); diff --git a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c index 2a6a7176103f..a34adcffadbf 100644 --- a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c +++ b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c @@ -110,10 +110,10 @@ TEST_CASE("Legacy ADC oneshot high/low test", "[legacy_adc_oneshot]") int adc_raw = 0; //ADC1 config TEST_ESP_OK(adc1_config_width(ADC_WIDTH_BIT_DEFAULT)); - TEST_ESP_OK(adc1_config_channel_atten(ADC1_TEST_CHAN0, ADC_ATTEN_DB_11)); + TEST_ESP_OK(adc1_config_channel_atten(ADC1_TEST_CHAN0, ADC_ATTEN_DB_12)); #if ADC_TEST_ADC2 //ADC2 config - TEST_ESP_OK(adc2_config_channel_atten(ADC2_TEST_CHAN0, ADC_ATTEN_DB_11)); + TEST_ESP_OK(adc2_config_channel_atten(ADC2_TEST_CHAN0, ADC_ATTEN_DB_12)); #endif test_adc_set_io_level(ADC_UNIT_1, (adc1_channel_t)ADC1_TEST_CHAN0, 0); diff --git a/components/efuse/esp32c2/esp_efuse_rtc_calib.c b/components/efuse/esp32c2/esp_efuse_rtc_calib.c index c63dae5d2e17..79d91b231929 100644 --- a/components/efuse/esp32c2/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32c2/esp_efuse_rtc_calib.c @@ -28,12 +28,12 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a { assert((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && (version <= ESP_EFUSE_ADC_CALIB_VER_MAX)); - assert(atten <= ADC_ATTEN_DB_11); + assert(atten <= ADC_ATTEN_DB_12); (void) adc_unit; if (atten == ADC_ATTEN_DB_2_5 || atten == ADC_ATTEN_DB_6) { /** - * - ESP32C2 only supports HW calibration on ADC_ATTEN_DB_0 and ADC_ATTEN_DB_11 + * - ESP32C2 only supports HW calibration on ADC_ATTEN_DB_0 and ADC_ATTEN_DB_12 * - For other attenuation, we just return default value, which is 0. */ return 0; @@ -56,7 +56,7 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a if (atten == ADC_ATTEN_DB_0) { init_code = adc_icode_diff_atten0 + 2160; } else { - //ADC_ATTEN_DB_11 + //ADC_ATTEN_DB_12 init_code = adc_icode_diff_atten3 + adc_icode_diff_atten0 + 2160; } @@ -76,7 +76,7 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in if (atten == ADC_ATTEN_DB_2_5 || atten == ADC_ATTEN_DB_6) { /** - * - ESP32C2 only supports SW calibration on ADC_ATTEN_DB_0 and ADC_ATTEN_DB_11 + * - ESP32C2 only supports SW calibration on ADC_ATTEN_DB_0 and ADC_ATTEN_DB_12 * - For other attenuation, we need to return an error, informing upper layer SW calibration driver * to deal with the error. */ @@ -101,7 +101,7 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in *out_digi = adc_vol_diff_atten0 + 1540; *out_vol_mv = 400; } else { - //ADC_ATTEN_DB_11 + //ADC_ATTEN_DB_12 *out_digi = adc_vol_diff_atten0 + 1540 - adc_vol_diff_atten3 - 123; *out_vol_mv = 1370; } diff --git a/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c b/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c index 08603733d124..68c46e534b0e 100644 --- a/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c +++ b/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c @@ -316,7 +316,7 @@ esp_adc_cal_value_t esp_adc_cal_characterize(adc_unit_t adc_num, chars->bit_width = bit_width; chars->vref = (EFUSE_VREF_ENABLED && efuse_vref_present) ? read_efuse_vref() : default_vref; //Initialize fields for lookup table if necessary - if (LUT_ENABLED && atten == ADC_ATTEN_DB_11) { + if (LUT_ENABLED && atten == ADC_ATTEN_DB_12) { chars->low_curve = (adc_num == ADC_UNIT_1) ? lut_adc1_low : lut_adc2_low; chars->high_curve = (adc_num == ADC_UNIT_1) ? lut_adc1_high : lut_adc2_high; } else { @@ -336,8 +336,8 @@ uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_char adc_reading = ADC_12_BIT_RES - 1; //Set to 12bit res max } - if (LUT_ENABLED && (chars->atten == ADC_ATTEN_DB_11) && (adc_reading >= LUT_LOW_THRESH)) { //Check if in non-linear region - //Use lookup table to get voltage in non linear portion of ADC_ATTEN_DB_11 + if (LUT_ENABLED && (chars->atten == ADC_ATTEN_DB_12) && (adc_reading >= LUT_LOW_THRESH)) { //Check if in non-linear region + //Use lookup table to get voltage in non linear portion of ADC_ATTEN_DB_12 uint32_t lut_voltage = calculate_voltage_lut(adc_reading, chars->vref, chars->low_curve, chars->high_curve); if (adc_reading <= LUT_HIGH_THRESH) { //If ADC is transitioning from linear region to non-linear region //Linearly interpolate between linear voltage and lut voltage diff --git a/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c b/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c index 6e92f8f37e89..c59f27ad90ed 100644 --- a/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c +++ b/components/esp_adc/deprecated/esp32s2/esp_adc_cal_legacy.c @@ -75,7 +75,7 @@ static bool prepare_calib_data_for(adc_unit_t adc_num, adc_atten_t atten, adc_ca case ADC_ATTEN_DB_6: parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 1000; break; - case ADC_ATTEN_DB_11: + case ADC_ATTEN_DB_12: parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 2000; break; default: diff --git a/components/esp_adc/esp32/adc_cali_line_fitting.c b/components/esp_adc/esp32/adc_cali_line_fitting.c index adf79c4c3fbc..60710818584b 100644 --- a/components/esp_adc/esp32/adc_cali_line_fitting.c +++ b/components/esp_adc/esp32/adc_cali_line_fitting.c @@ -190,7 +190,7 @@ esp_err_t adc_cali_create_scheme_line_fitting(const adc_cali_line_fitting_config chars->atten = config->atten; chars->bitwidth = (config->bitwidth == ADC_BITWIDTH_DEFAULT) ? ADC_BITWIDTH_12 : config->bitwidth; //Initialize fields for lookup table if necessary - if (LUT_ENABLED && config->atten == ADC_ATTEN_DB_11) { + if (LUT_ENABLED && config->atten == ADC_ATTEN_DB_12) { chars->low_curve = (config->unit_id == ADC_UNIT_1) ? lut_adc1_low : lut_adc2_low; chars->high_curve = (config->unit_id == ADC_UNIT_1) ? lut_adc1_high : lut_adc2_high; } else { @@ -251,8 +251,8 @@ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage) raw = ADC_12_BIT_RES - 1; //Set to 12bit res max } - if (LUT_ENABLED && (ctx->atten == ADC_ATTEN_DB_11) && (raw >= LUT_LOW_THRESH)) { //Check if in non-linear region - //Use lookup table to get voltage in non linear portion of ADC_ATTEN_DB_11 + if (LUT_ENABLED && (ctx->atten == ADC_ATTEN_DB_12) && (raw >= LUT_LOW_THRESH)) { //Check if in non-linear region + //Use lookup table to get voltage in non linear portion of ADC_ATTEN_DB_12 uint32_t lut_voltage = calculate_voltage_lut(raw, ctx->vref, ctx->low_curve, ctx->high_curve); if (raw <= LUT_HIGH_THRESH) { //If ADC is transitioning from linear region to non-linear region //Linearly interpolate between linear voltage and lut voltage diff --git a/components/esp_adc/esp32c2/adc_cali_line_fitting.c b/components/esp_adc/esp32c2/adc_cali_line_fitting.c index 3ccf36eba435..c5a7b263cd1f 100644 --- a/components/esp_adc/esp32c2/adc_cali_line_fitting.c +++ b/components/esp_adc/esp32c2/adc_cali_line_fitting.c @@ -118,7 +118,7 @@ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage) static esp_err_t check_valid(const adc_cali_line_fitting_config_t *config) { ESP_RETURN_ON_FALSE(config->unit_id < SOC_ADC_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid ADC unit"); - ESP_RETURN_ON_FALSE((config->atten == ADC_ATTEN_DB_0 || config->atten == ADC_ATTEN_DB_11), ESP_ERR_NOT_SUPPORTED, TAG, "only ADC_ATTEN_DB_0 and ADC_ATTEN_DB_11 are supported"); + ESP_RETURN_ON_FALSE((config->atten == ADC_ATTEN_DB_0 || config->atten == ADC_ATTEN_DB_12), ESP_ERR_NOT_SUPPORTED, TAG, "only ADC_ATTEN_DB_0 and ADC_ATTEN_DB_12 are supported"); if (config->atten == ADC_ATTEN_DB_0) { ESP_LOGW(TAG, "Experimental: ADC Atten 0 calibration can now only used for inputs lower than 950mV. Calibration Scheme may get updated, DON'T USE FOR MASS PRODUCTION!"); } diff --git a/components/esp_adc/esp32s2/adc_cali_line_fitting.c b/components/esp_adc/esp32s2/adc_cali_line_fitting.c index 87ec4e7e3ed2..2e826e1f08a1 100644 --- a/components/esp_adc/esp32s2/adc_cali_line_fitting.c +++ b/components/esp_adc/esp32s2/adc_cali_line_fitting.c @@ -177,7 +177,7 @@ static bool prepare_calib_data_for(adc_unit_t unit_id, adc_atten_t atten, adc_ca case ADC_ATTEN_DB_6: parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 1000; break; - case ADC_ATTEN_DB_11: + case ADC_ATTEN_DB_12: parsed_data_storage->efuse_data.ver2.adc_calib_high_voltage = 2000; break; default: diff --git a/components/esp_adc/test_apps/adc/main/test_adc.c b/components/esp_adc/test_apps/adc/main/test_adc.c index ad65b3f82742..f568dde6c724 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc.c +++ b/components/esp_adc/test_apps/adc/main/test_adc.c @@ -66,7 +66,7 @@ TEST_CASE("ADC oneshot high/low test", "[adc_oneshot]") //-------------ADC1 TEST Channel 0 Config---------------// adc_oneshot_chan_cfg_t config = { .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, + .atten = ADC_ATTEN_DB_12, }; TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, ADC1_TEST_CHAN0, &config)); @@ -124,7 +124,7 @@ TEST_CASE("ADC oneshot stress test that get zero even if convent done", "[adc_on int test_num = 100; adc_channel_t channel = ADC1_TEST_CHAN1; - adc_atten_t atten = ADC_ATTEN_DB_11; + adc_atten_t atten = ADC_ATTEN_DB_12; adc_unit_t unit_id = ADC_UNIT_1; adc_oneshot_unit_handle_t adc1_handle; @@ -322,7 +322,7 @@ TEST_CASE("ADC continuous monitor init_deinit", "[adc]") adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0}; for (int i = 0; i < 1; i++) { - adc_pattern[i].atten = ADC_ATTEN_DB_11; + adc_pattern[i].atten = ADC_ATTEN_DB_12; adc_pattern[i].channel = i; adc_pattern[i].unit = ADC_UNIT_1; adc_pattern[i].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; @@ -440,7 +440,7 @@ TEST_CASE("ADC continuous monitor functionary", "[adc][manual][ignore]") adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0}; for (int i = 0; i < 2; i++) { - adc_pattern[i].atten = ADC_ATTEN_DB_11; + adc_pattern[i].atten = ADC_ATTEN_DB_12; adc_pattern[i].channel = TEST_ADC_CHANNEL; adc_pattern[i].unit = ADC_UNIT_1; adc_pattern[i].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; diff --git a/components/esp_adc/test_apps/adc/main/test_adc_driver.c b/components/esp_adc/test_apps/adc/main/test_adc_driver.c index a38f4270fe86..913820bd7715 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_driver.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_driver.c @@ -80,7 +80,7 @@ TEST_CASE("ADC oneshot fast work with ISR", "[adc_oneshot]") //-------------ADC1 TEST Channel 0 Config---------------// adc_oneshot_chan_cfg_t config = { .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, + .atten = ADC_ATTEN_DB_12, }; TEST_ESP_OK(adc_oneshot_config_channel(isr_test_ctx.oneshot_handle, ADC1_TEST_CHAN0, &config)); @@ -171,7 +171,7 @@ TEST_CASE("ADC continuous big conv_frame_size test", "[adc_continuous]") .format = ADC_DRIVER_TEST_OUTPUT_TYPE, }; adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0}; - adc_pattern[0].atten = ADC_ATTEN_DB_11; + adc_pattern[0].atten = ADC_ATTEN_DB_12; adc_pattern[0].channel = ADC1_TEST_CHAN0; adc_pattern[0].unit = ADC_UNIT_1; adc_pattern[0].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; @@ -229,7 +229,7 @@ TEST_CASE("ADC continuous flush internal pool", "[adc_continuous][mannual][ignor .format = ADC_DRIVER_TEST_OUTPUT_TYPE, }; adc_digi_pattern_config_t adc_pattern[SOC_ADC_PATT_LEN_MAX] = {0}; - adc_pattern[0].atten = ADC_ATTEN_DB_11; + adc_pattern[0].atten = ADC_ATTEN_DB_12; adc_pattern[0].channel = ADC1_TEST_CHAN0; adc_pattern[0].unit = ADC_UNIT_1; adc_pattern[0].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH; diff --git a/components/esp_adc/test_apps/adc/main/test_adc_driver_iram.c b/components/esp_adc/test_apps/adc/main/test_adc_driver_iram.c index a69d4fcf76b6..59c86a604298 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_driver_iram.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_driver_iram.c @@ -84,7 +84,7 @@ TEST_CASE("ADC oneshot fast work with ISR and Flash", "[adc_oneshot]") //-------------ADC1 TEST Channel 0 Config---------------// adc_oneshot_chan_cfg_t config = { .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, + .atten = ADC_ATTEN_DB_12, }; TEST_ESP_OK(adc_oneshot_config_channel(oneshot_handle, ADC1_TEST_CHAN0, &config)); diff --git a/components/esp_adc/test_apps/adc/main/test_adc_performance.c b/components/esp_adc/test_apps/adc/main/test_adc_performance.c index e0da5d9aef5e..82ef8dde0780 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_performance.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_performance.c @@ -269,29 +269,29 @@ TEST_CASE("ADC1 continuous raw average and std_deviation", "[adc_continuous][man TEST_CASE("ADC1 continuous std deviation performance, no filter", "[adc_continuous][performance]") { - float std = test_adc_continuous_std(ADC_ATTEN_DB_11, false, 0, true); + float std = test_adc_continuous_std(ADC_ATTEN_DB_12, false, 0, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER, "%.2f", std); } #if SOC_ADC_DIG_IIR_FILTER_SUPPORTED TEST_CASE("ADC1 continuous std deviation performance, with filter", "[adc_continuous][performance]") { - float std = test_adc_continuous_std(ADC_ATTEN_DB_11, false, 0, true); + float std = test_adc_continuous_std(ADC_ATTEN_DB_12, false, 0, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER, "%.2f", std); - std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_2, true); + std = test_adc_continuous_std(ADC_ATTEN_DB_12, true, ADC_DIGI_IIR_FILTER_COEFF_2, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_2, "%.2f", std); - std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_4, true); + std = test_adc_continuous_std(ADC_ATTEN_DB_12, true, ADC_DIGI_IIR_FILTER_COEFF_4, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_4, "%.2f", std); - std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_8, true); + std = test_adc_continuous_std(ADC_ATTEN_DB_12, true, ADC_DIGI_IIR_FILTER_COEFF_8, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_8, "%.2f", std); - std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_16, true); + std = test_adc_continuous_std(ADC_ATTEN_DB_12, true, ADC_DIGI_IIR_FILTER_COEFF_16, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_16, "%.2f", std); - std = test_adc_continuous_std(ADC_ATTEN_DB_11, true, ADC_DIGI_IIR_FILTER_COEFF_64, true); + std = test_adc_continuous_std(ADC_ATTEN_DB_12, true, ADC_DIGI_IIR_FILTER_COEFF_64, true); TEST_PERFORMANCE_LESS_THAN(ADC_CONTINUOUS_STD_ATTEN3_FILTER_64, "%.2f", std); } #endif //#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED @@ -375,7 +375,7 @@ TEST_CASE("ADC1 oneshot raw average and std_deviation", "[adc_oneshot][manual]") TEST_CASE("ADC1 oneshot std_deviation performance", "[adc_oneshot][performance]") { - float std = test_adc_oneshot_std(ADC_ATTEN_DB_11, true); + float std = test_adc_oneshot_std(ADC_ATTEN_DB_12, true); TEST_PERFORMANCE_LESS_THAN(ADC_ONESHOT_STD_ATTEN3, "%.2f", std); } /*--------------------------------------------------------------- diff --git a/components/esp_adc/test_apps/adc/main/test_adc_wifi.c b/components/esp_adc/test_apps/adc/main/test_adc_wifi.c index a967fcf9f8b1..b236f8ea2db5 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_wifi.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_wifi.c @@ -170,7 +170,7 @@ __attribute__((unused)) static void adc_work_with_wifi(adc_unit_t unit_id, adc_c //-------------ADC TEST Channel Config---------------// adc_oneshot_chan_cfg_t config = { .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, + .atten = ADC_ATTEN_DB_12, }; TEST_ESP_OK(adc_oneshot_config_channel(adc_handle, channel, &config)); diff --git a/components/esp_adc/test_apps/adc/main/test_common_adc.c b/components/esp_adc/test_apps/adc/main/test_common_adc.c index 7212d849c96c..7cf974c43f56 100644 --- a/components/esp_adc/test_apps/adc/main/test_common_adc.c +++ b/components/esp_adc/test_apps/adc/main/test_common_adc.c @@ -20,9 +20,9 @@ __attribute__((unused)) static const char *TAG = "TEST_ADC"; ADC Attenuation ---------------------------------------------------------------*/ #if CONFIG_IDF_TARGET_ESP32C2 -adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_11}; +adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_12}; #else -adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_2_5, ADC_ATTEN_DB_6, ADC_ATTEN_DB_11}; +adc_atten_t g_test_atten[TEST_ATTEN_NUMS] = {ADC_ATTEN_DB_0, ADC_ATTEN_DB_2_5, ADC_ATTEN_DB_6, ADC_ATTEN_DB_12}; #endif #if SOC_ADC_DIG_IIR_FILTER_SUPPORTED diff --git a/components/esp_hw_support/port/esp32c3/adc2_init_cal.c b/components/esp_hw_support/port/esp32c3/adc2_init_cal.c index edb92a8eb27e..096d3e85ab86 100644 --- a/components/esp_hw_support/port/esp32c3/adc2_init_cal.c +++ b/components/esp_hw_support/port/esp32c3/adc2_init_cal.c @@ -22,9 +22,9 @@ extern portMUX_TYPE rtc_spinlock; static __attribute__((constructor)) void adc2_init_code_calibration(void) { adc_hal_calibration_init(ADC_UNIT_2); - adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_11); + adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); portENTER_CRITICAL(&rtc_spinlock); - adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_11); + adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); portEXIT_CRITICAL(&rtc_spinlock); } diff --git a/components/esp_hw_support/port/esp32s2/adc2_init_cal.c b/components/esp_hw_support/port/esp32s2/adc2_init_cal.c index edb92a8eb27e..096d3e85ab86 100644 --- a/components/esp_hw_support/port/esp32s2/adc2_init_cal.c +++ b/components/esp_hw_support/port/esp32s2/adc2_init_cal.c @@ -22,9 +22,9 @@ extern portMUX_TYPE rtc_spinlock; static __attribute__((constructor)) void adc2_init_code_calibration(void) { adc_hal_calibration_init(ADC_UNIT_2); - adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_11); + adc_calc_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); portENTER_CRITICAL(&rtc_spinlock); - adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_11); + adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); portEXIT_CRITICAL(&rtc_spinlock); } diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index ad24bbed46b5..1344a64970d4 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -849,7 +849,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V - * - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below) + * - 11dB attenuation (ADC_ATTEN_DB_12) gives full-scale voltage 3.9V (see note below) * * @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured * bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.) @@ -861,7 +861,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV - * - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV + * - 11dB attenuation (ADC_ATTEN_DB_12) between 150 to 2450mV * * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. * diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index e0886a1db3b7..7e0f405e1fc9 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.h @@ -1109,7 +1109,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * - 0dB attenuation (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V * - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V - * - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below) + * - 11dB attenuation (ADC_ATTEN_DB_12) gives full-scale voltage 3.9V (see note below) * * @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured * bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.) @@ -1121,7 +1121,7 @@ static inline void adc_ll_rtc_set_arbiter_stable_cycle(uint32_t cycle) * - 0dB attenuation (ADC_ATTEN_DB_0) between 100 and 950mV * - 2.5dB attenuation (ADC_ATTEN_DB_2_5) between 100 and 1250mV * - 6dB attenuation (ADC_ATTEN_DB_6) between 150 to 1750mV - * - 11dB attenuation (ADC_ATTEN_DB_11) between 150 to 2450mV + * - 11dB attenuation (ADC_ATTEN_DB_12) between 150 to 2450mV * * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. * diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index ede6325c9aeb..063e3ab3c429 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -45,9 +45,10 @@ typedef enum { */ typedef enum { ADC_ATTEN_DB_0 = 0, ///