diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 8049f3477b..442b2c8f96 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -62,34 +62,66 @@ menu "Bootloader config" default 4 if BOOTLOADER_LOG_LEVEL_DEBUG default 5 if BOOTLOADER_LOG_LEVEL_VERBOSE - config BOOTLOADER_SPI_CUSTOM_WP_PIN - bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)" - depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT) - default y if BOOTLOADER_SPI_WP_PIN != 7 # backwards compatibility, can remove in IDF 5 - default n - help - This setting is only used if the SPI flash pins have been overridden by setting the eFuses - SPI_PAD_CONFIG_xxx, and the SPI flash mode is QIO or QOUT. - - When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka - ESP32 pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. The same pin is also used - for external SPIRAM if it is enabled. - - If this config item is set to N (default), the correct WP pin will be automatically used for any - Espressif chip or module with integrated flash. If a custom setting is needed, set this config item to - Y and specify the GPIO number connected to the WP. - - config BOOTLOADER_SPI_WP_PIN - int "Custom SPI Flash WP Pin" - range 0 33 - default 7 - depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT) - #depends on BOOTLOADER_SPI_CUSTOM_WP_PIN # backwards compatibility, can uncomment in IDF 5 - help - The option "Use custom SPI Flash WP Pin" must be set or this value is ignored + menu "Serial Flash Configurations" + config BOOTLOADER_SPI_CUSTOM_WP_PIN + bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)" + depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT) + default y if BOOTLOADER_SPI_WP_PIN != 7 # backwards compatibility, can remove in IDF 5 + default n + help + This setting is only used if the SPI flash pins have been overridden by setting the eFuses + SPI_PAD_CONFIG_xxx, and the SPI flash mode is QIO or QOUT. + + When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka + ESP32 pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. The same pin is also used + for external SPIRAM if it is enabled. + + If this config item is set to N (default), the correct WP pin will be automatically used for any + Espressif chip or module with integrated flash. If a custom setting is needed, set this config item to + Y and specify the GPIO number connected to the WP. + + config BOOTLOADER_SPI_WP_PIN + int "Custom SPI Flash WP Pin" + range 0 33 + default 7 + depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT) + #depends on BOOTLOADER_SPI_CUSTOM_WP_PIN # backwards compatibility, can uncomment in IDF 5 + help + The option "Use custom SPI Flash WP Pin" must be set or this value is ignored - If burning a customized set of SPI flash pins in eFuse and using QIO or QOUT mode for flash, set this - value to the GPIO number of the SPI flash WP pin. + If burning a customized set of SPI flash pins in eFuse and using QIO or QOUT mode for flash, set this + value to the GPIO number of the SPI flash WP pin. + + config BOOTLOADER_FLASH_DC_AWARE + bool "Allow app adjust Dummy Cycle bits in SPI Flash for higher frequency (READ HELP FIRST)" + help + This will force 2nd bootloader to be loaded by DOUT mode, and will restore Dummy Cycle setting by + resetting the Flash + + config BOOTLOADER_FLASH_XMC_SUPPORT + bool "Enable the support for flash chips of XMC (READ DOCS FIRST)" + default y + help + Perform the startup flow recommended by XMC. Please consult XMC for the details of this flow. + XMC chips will be forbidden to be used, when this option is disabled. + + DON'T DISABLE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. + + comment "Features below require specific hardware (READ DOCS FIRST!)" + + config BOOTLOADER_FLASH_32BIT_ADDR + bool + default y if ESPTOOLPY_FLASHSIZE_32MB || ESPTOOLPY_FLASHSIZE_64MB || ESPTOOLPY_FLASHSIZE_128MB + default n + help + This is a helper config for 32bits address flash. Invisible for users. + + config BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH + bool + default y if ESPTOOLPY_OCT_FLASH && BOOTLOADER_FLASH_32BIT_ADDR + default n + + endmenu choice BOOTLOADER_VDDSDIO_BOOST bool "VDDSDIO LDO voltage" @@ -405,6 +437,21 @@ menu "Bootloader config" (The application and bootoloader must be compiled with the same option). The RTC FAST memory has access only through PRO_CPU. + config BOOTLOADER_CUSTOM_RESERVE_RTC_IN_CRC + bool "Include custom memory in the CRC calculation" + depends on BOOTLOADER_CUSTOM_RESERVE_RTC + default n + help + This option allows the customer to use the legacy bootloader behavior when the + RTC FAST memory CRC calculation takes place. When this option is enabled, the + allocated user custom data will be taken into account in the CRC calculcation. + This means that any change to the custom data would need a CRC update to prevent + the bootloader from marking this data as corrupted. + If this option is disabled, the custom data will not be taken into account when + calculating the RTC FAST memory CRC. The user custom data can be changed freely, + without the need to update the CRC. + THIS OPTION MUST BE THE SAME FOR BOTH THE BOOTLOADER AND THE APPLICATION BUILDS. + config BOOTLOADER_CUSTOM_RESERVE_RTC_SIZE hex "Size in bytes for custom purposes" default 0 @@ -424,15 +471,6 @@ menu "Bootloader config" - "Reserve RTC FAST memory for custom purposes" - "GPIO triggers factory reset" - config BOOTLOADER_FLASH_XMC_SUPPORT - bool "Enable the support for flash chips of XMC (READ HELP FIRST)" - default y - help - Perform the startup flow recommended by XMC. Please consult XMC for the details of this flow. - XMC chips will be forbidden to be used, when this option is disabled. - - DON'T DISABLE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. - endmenu # Bootloader @@ -704,14 +742,12 @@ menu "Security features" config SECURE_BOOT_VERIFICATION_KEY string "Secure boot public signature verification key" - depends on SECURE_SIGNED_APPS && !SECURE_BOOT_BUILD_SIGNED_BINARIES && !SECURE_SIGNED_APPS_RSA_SCHEME + depends on SECURE_SIGNED_APPS && SECURE_SIGNED_APPS_ECDSA_SCHEME && !SECURE_BOOT_BUILD_SIGNED_BINARIES default "signature_verification_key.bin" help Path to a public key file used to verify signed images. Secure Boot V1: This ECDSA public key is compiled into the bootloader and/or app, to verify app images. - Secure Boot V2: This RSA public key is compiled into the signature block at - the end of the bootloader/app. Key file is in raw binary format, and can be extracted from a PEM formatted private key using the espsecure.py @@ -1009,6 +1045,22 @@ menu "Security features" DIS_DOWNLOAD_MANUAL_ENCRYPT, DIS_USB_JTAG, DIS_USB_SERIAL_JTAG, STRAP_JTAG_SEL, USB_PHY_SEL. endmenu # Potentially Insecure + config SECURE_FLASH_ENCRYPT_ONLY_IMAGE_LEN_IN_APP_PART + bool "Encrypt only the app image that is present in the partition of type app" + depends on SECURE_FLASH_ENC_ENABLED && !SECURE_FLASH_REQUIRE_ALREADY_ENABLED + default n + help + If set, optimise encryption time for the partition of type APP, + by only encrypting the app image that is present in the partition, + instead of the whole partition. + The image length used for encryption is derived from the image metadata, which + includes the size of the app image, checksum, hash and also the signature sector + when secure boot is enabled. + + If not set (default), the whole partition of type APP would be encrypted, + which increases the encryption time but might be useful if there + is any custom data appended to the firmware image. + config SECURE_FLASH_CHECK_ENC_EN_IN_APP bool "Check Flash Encryption enabled on app startup" depends on SECURE_FLASH_ENC_ENABLED diff --git a/components/bootloader/sdkconfig.rename b/components/bootloader/sdkconfig.rename index bdcfe36487..6aecd1523a 100644 --- a/components/bootloader/sdkconfig.rename +++ b/components/bootloader/sdkconfig.rename @@ -23,3 +23,5 @@ CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE CONFIG_SECURE_FLASH_ # Secure Boot Scheme CONFIG_SECURE_BOOT_ENABLED CONFIG_SECURE_BOOT_V1_ENABLED + +CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH diff --git a/components/bootloader/subproject/components/micro-ecc/micro-ecc b/components/bootloader/subproject/components/micro-ecc/micro-ecc index d037ec8954..24c60e2435 160000 --- a/components/bootloader/subproject/components/micro-ecc/micro-ecc +++ b/components/bootloader/subproject/components/micro-ecc/micro-ecc @@ -1 +1 @@ -Subproject commit d037ec89546fad14b5c4d5456c2e23a71e554966 +Subproject commit 24c60e243580c7868f4334a1ba3123481fe1aa48 diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash.h index b52553b03d..f0004a10b8 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash.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 */ @@ -54,6 +54,13 @@ esp_err_t bootloader_flash_reset_chip(void); */ bool bootloader_flash_is_octal_mode_enabled(void); +/** + * @brief Get the spi flash working mode. + * + * @return The mode of flash working mode, see `esp_rom_spiflash_read_mode_t` + */ +esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void); + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h index 8d161bd28c..75fcd6e3b9 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash_override.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 */ @@ -109,6 +109,17 @@ extern const bootloader_qio_info_t __attribute__((weak)) bootloader_flash_qe_sup */ esp_err_t __attribute__((weak)) bootloader_flash_unlock(void); +#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH +/** + * @brief Enable 32bits address flash(larger than 16MB) can map to cache. + * + * @param flash_mode SPI flash working mode. + * + * @note This can be overridden because it's attribute weak. + */ +void __attribute__((weak)) bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode); +#endif + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h index f46b87f63b..89edb7416e 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h @@ -52,6 +52,8 @@ extern "C" { #define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */ #define CMD_RESETEN 0x66 #define CMD_RESET 0x99 +#define CMD_FASTRD_4B 0x0C +#define CMD_SLOWRD_4B 0x13 /* Provide a Flash API for bootloader_support code, diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index 253d39046e..06e9780c52 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.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 */ @@ -124,6 +124,9 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) #include "hal/mmu_hal.h" #include "hal/mmu_ll.h" #include "hal/cache_hal.h" +#if CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/opi_flash.h" +#endif static const char *TAG = "bootloader_flash"; #if CONFIG_IDF_TARGET_ESP32 @@ -414,6 +417,33 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) return spi_to_esp_err(rc); } +#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH +void bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode) +{ + esp_rom_opiflash_spi0rd_t cache_rd = {}; + switch (flash_mode) { + case ESP_ROM_SPIFLASH_FASTRD_MODE: + cache_rd.addr_bit_len = 32; + cache_rd.dummy_bit_len = 8; + cache_rd.cmd = CMD_FASTRD_4B; + cache_rd.cmd_bit_len = 8; + break; + case ESP_ROM_SPIFLASH_SLOWRD_MODE: + cache_rd.addr_bit_len = 32; + cache_rd.dummy_bit_len = 0; + cache_rd.cmd = CMD_SLOWRD_4B; + cache_rd.cmd_bit_len = 8; + break; + default: + assert(false); + break; + } + cache_hal_disable(CACHE_TYPE_ALL); + esp_rom_opiflash_cache_mode_config(flash_mode, &cache_rd); + cache_hal_enable(CACHE_TYPE_ALL); +} +#endif + #endif // BOOTLOADER_BUILD @@ -760,3 +790,40 @@ bool IRAM_ATTR bootloader_flash_is_octal_mode_enabled(void) return false; #endif } + +esp_rom_spiflash_read_mode_t bootloader_flash_get_spi_mode(void) +{ + esp_rom_spiflash_read_mode_t spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE; +#if CONFIG_IDF_TARGET_ESP32 + uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0)); + if (spi_ctrl & SPI_FREAD_QIO) { + spi_mode = ESP_ROM_SPIFLASH_QIO_MODE; + } else if (spi_ctrl & SPI_FREAD_QUAD) { + spi_mode = ESP_ROM_SPIFLASH_QOUT_MODE; + } else if (spi_ctrl & SPI_FREAD_DIO) { + spi_mode = ESP_ROM_SPIFLASH_DIO_MODE; + } else if (spi_ctrl & SPI_FREAD_DUAL) { + spi_mode = ESP_ROM_SPIFLASH_DOUT_MODE; + } else if (spi_ctrl & SPI_FASTRD_MODE) { + spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + } else { + spi_mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + } +#else + uint32_t spi_ctrl = REG_READ(SPI_MEM_CTRL_REG(0)); + if (spi_ctrl & SPI_MEM_FREAD_QIO) { + spi_mode = ESP_ROM_SPIFLASH_QIO_MODE; + } else if (spi_ctrl & SPI_MEM_FREAD_QUAD) { + spi_mode = ESP_ROM_SPIFLASH_QOUT_MODE; + } else if (spi_ctrl & SPI_MEM_FREAD_DIO) { + spi_mode = ESP_ROM_SPIFLASH_DIO_MODE; + } else if (spi_ctrl & SPI_MEM_FREAD_DUAL) { + spi_mode = ESP_ROM_SPIFLASH_DOUT_MODE; + } else if (spi_ctrl & SPI_MEM_FASTRD_MODE) { + spi_mode = ESP_ROM_SPIFLASH_FASTRD_MODE; + } else { + spi_mode = ESP_ROM_SPIFLASH_SLOWRD_MODE; + } +#endif + return spi_mode; +} 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 151e469f3b..03db8c0cb4 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 @@ -260,7 +260,7 @@ esp_err_t bootloader_init_spi_flash(void) } #endif -#if CONFIG_SPI_FLASH_HPM_ENABLE +#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 @@ -272,7 +272,9 @@ esp_err_t bootloader_init_spi_flash(void) bootloader_enable_qio_mode(); } #endif - +#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH + bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode()); +#endif print_flash_info(&bootloader_image_hdr); update_flash_config(&bootloader_image_hdr); //ensure the flash is write-protected diff --git a/components/bootloader_support/include/esp_image_format.h b/components/bootloader_support/include/esp_image_format.h index 5ec2ff0282..f677b08fe5 100644 --- a/components/bootloader_support/include/esp_image_format.h +++ b/components/bootloader_support/include/esp_image_format.h @@ -33,6 +33,7 @@ typedef struct { uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS]; /* Data offsets for each segment */ uint32_t image_len; /* Length of image on flash, in bytes */ uint8_t image_digest[32]; /* appended SHA-256 digest */ + uint32_t secure_version; /* secure version for anti-rollback, it is covered by sha256 (set if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK=y) */ } esp_image_metadata_t; typedef enum { diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index fa5c13e25f..9250ca0bd5 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.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 */ @@ -282,6 +282,23 @@ esp_err_t esp_secure_boot_enable_secure_features(void); */ bool esp_secure_boot_cfg_verify_release_mode(void); + +#if !defined(BOOTLOADER_BUILD) && SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED + +/** @brief Returns the verification status of the image pointed by the part_pos argument against the public key digest present at index `efuse_digest_index` + * + * @param index[in] Index of public key digest present in efuse against which the image is to be verified + * @param part_pos[in] It is a pointer to the bootloader/app partition. + * + * @return + * - ESP_OK - if the image can be verified by the key at efuse_index. + * - ESP_FAIL - if the image cannot be verified by the key at efuse_index. + * - ESP_ERR_INVALID_ARG: Error in the passed arguments. + */ +esp_err_t esp_secure_boot_verify_with_efuse_digest_index(int efuse_digest_index, esp_partition_pos_t *part_pos); + +#endif // !defined(BOOTLOADER_BUILD) && SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED + #ifdef __cplusplus } #endif diff --git a/components/bootloader_support/src/bootloader_common_loader.c b/components/bootloader_support/src/bootloader_common_loader.c index a8c1ea97c0..8761fb9352 100644 --- a/components/bootloader_support/src/bootloader_common_loader.c +++ b/components/bootloader_support/src/bootloader_common_loader.c @@ -122,7 +122,7 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, #if CONFIG_BOOTLOADER_RESERVE_RTC_MEM static uint32_t rtc_retain_mem_size(void) { -#ifdef CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC +#if CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC && !CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC_IN_CRC /* A custom memory has been reserved by the user, do not consider this memory into CRC calculation as it may change without * the have the user updating the CRC. Return the offset of the custom field, which is equivalent to size of the structure * minus the size of everything after (including) `custom` */ diff --git a/components/bootloader_support/src/bootloader_console.c b/components/bootloader_support/src/bootloader_console.c index 798220290f..bf29c2638d 100644 --- a/components/bootloader_support/src/bootloader_console.c +++ b/components/bootloader_support/src/bootloader_console.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "sdkconfig.h" #include "bootloader_console.h" +#include "soc/soc_caps.h" #include "soc/uart_periph.h" #include "soc/uart_channel.h" #include "soc/io_mux_reg.h" @@ -19,6 +20,9 @@ #include "esp32s2/rom/usb/cdc_acm.h" #include "esp32s2/rom/usb/usb_common.h" #endif +#if CONFIG_ESP_CONSOLE_USB_CDC +#include "hal/usb_wrap_ll.h" +#endif #include "esp_rom_gpio.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" @@ -96,8 +100,11 @@ void bootloader_console_init(void) #endif esp_rom_uart_usb_acm_init(s_usb_cdc_buf, sizeof(s_usb_cdc_buf)); - esp_rom_uart_set_as_console(ESP_ROM_UART_USB); + esp_rom_uart_set_as_console(ESP_ROM_USB_OTG_NUM); esp_rom_install_channel_putc(1, bootloader_console_write_char_usb); + // Ensure that the USB FSLS PHY is mapped to the USB WRAP + usb_wrap_ll_phy_enable_pad(&USB_WRAP, true); + usb_wrap_ll_phy_enable_external(&USB_WRAP, false); } #endif //CONFIG_ESP_CONSOLE_USB_CDC diff --git a/components/bootloader_support/src/bootloader_panic.c b/components/bootloader_support/src/bootloader_panic.c index 6cff254ce6..aac9e72638 100644 --- a/components/bootloader_support/src/bootloader_panic.c +++ b/components/bootloader_support/src/bootloader_panic.c @@ -26,9 +26,11 @@ void abort(void) #if !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT esp_rom_printf("abort() was called at PC 0x%08x\r\n", (intptr_t)__builtin_return_address(0) - 3); #endif +#if CONFIG_ESP_DEBUG_OCDAWARE if (esp_cpu_dbgr_is_attached()) { esp_cpu_dbgr_break(); } +#endif while (1) { } } diff --git a/components/bootloader_support/src/bootloader_random_esp32c6.c b/components/bootloader_support/src/bootloader_random_esp32c6.c index 682e48544c..fec85a6a40 100644 --- a/components/bootloader_support/src/bootloader_random_esp32c6.c +++ b/components/bootloader_support/src/bootloader_random_esp32c6.c @@ -53,7 +53,7 @@ void bootloader_random_enable(void) // create patterns and set them in pattern table uint32_t pattern_one = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation - uint32_t pattern_two = SAR1_ATTEN; // we want channel 0 with max attenuation, channel doesn't really matter here + uint32_t pattern_two = (SAR2_CHANNEL << 2) | SAR1_ATTEN; // we want channel 9 with max attenuation uint32_t pattern_table = 0 | (pattern_two << 3 * PATTERN_BIT_WIDTH) | pattern_one << 2 * PATTERN_BIT_WIDTH; REG_WRITE(APB_SARADC_SAR_PATT_TAB1_REG, pattern_table); @@ -88,9 +88,6 @@ void bootloader_random_disable(void) REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC1_ENCAL_REF_ADDR, 0); REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); - // Revert PMU_RF_PWC_REG to it's initial value - CLEAR_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); - // disable ADC_CTRL_CLK (SAR ADC function clock) REG_WRITE(PCR_SARADC_CLKM_CONF_REG, 0x00404000); diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index af40d2ab23..b36ef65559 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,8 @@ #include "bootloader_util.h" #include "bootloader_common.h" #include "esp_rom_sys.h" +#include "esp_efuse.h" +#include "esp_app_desc.h" #include "bootloader_memory_utils.h" #include "soc/soc_caps.h" #if CONFIG_IDF_TARGET_ESP32 @@ -85,10 +87,10 @@ static bool should_map(uint32_t load_addr); static esp_err_t process_segments(esp_image_metadata_t *data, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum); /* Load or verify a segment */ -static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum); +static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata); /* split segment and verify if data_len is too long */ -static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum); +static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata); /* Verify the main image header */ static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent); @@ -233,6 +235,21 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_ } } } + +#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK + /* For anti-rollback case, reconfirm security version of the application to prevent FI attacks */ + bool sec_ver = false; + if (do_load) { + sec_ver = esp_efuse_check_secure_version(data->secure_version); + if (!sec_ver) { + err = ESP_FAIL; + goto err; + } + } + /* Ensure that the security version check passes for image loading scenario */ + ESP_FAULT_ASSERT(!do_load || sec_ver == true); +#endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK + #endif // BOOTLOADER_BUILD // Success! @@ -509,7 +526,7 @@ static esp_err_t process_segments(esp_image_metadata_t *data, bool silent, bool for (int i = 0; i < data->image.segment_count; i++) { esp_image_segment_header_t *header = &data->segments[i]; ESP_LOGV(TAG, "loading segment header %d at offset 0x%"PRIx32, i, next_addr); - CHECK_ERR(process_segment(i, next_addr, header, silent, do_load, sha_handle, checksum)); + CHECK_ERR(process_segment(i, next_addr, header, silent, do_load, sha_handle, checksum, data)); next_addr += sizeof(esp_image_segment_header_t); data->segment_data[i] = next_addr; next_addr += header->data_len; @@ -530,7 +547,7 @@ static esp_err_t process_segments(esp_image_metadata_t *data, bool silent, bool return err; } -static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum) +static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata) { esp_err_t err; @@ -588,7 +605,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0; /* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */ data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE)); - CHECK_ERR(process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum)); + CHECK_ERR(process_segment_data(index, load_addr, data_addr, data_len, do_load, sha_handle, checksum, metadata)); data_addr += data_len; data_len_remain -= data_len; } @@ -603,7 +620,42 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme return err; } -static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum) +#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK +/* The __attribute__((optimize("O0"))) is used to disable optimizations for this function, + * preventing the compiler from potentially optimizing data_buffer and reading data directly from src. + * This is crucial as we want to read from Flash only once, ensuring the integrity of the data. + */ +__attribute__((optimize("O0"))) +static size_t process_esp_app_desc_data(const uint32_t *src, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata) +{ + /* Using data_buffer here helps to securely read secure_version + * (for anti-rollback) from esp_app_desc_t, preventing FI attack. + * We read data from Flash into this buffer, which is covered by sha256. + * Therefore, if the flash is under attackers control and contents are modified + * the sha256 comparison will fail. + * + * The esp_app_desc_t structure is located in DROM and is always in segment #0. + * + * esp_app_desc_t is always at #0 segment (index==0). + * secure_version field of esp_app_desc_t is located at #2 word (w_i==1). + */ + uint32_t data_buffer[2]; + memcpy(data_buffer, src, sizeof(data_buffer)); + assert(data_buffer[0] == ESP_APP_DESC_MAGIC_WORD); + metadata->secure_version = data_buffer[1]; + if (checksum != NULL) { + *checksum ^= data_buffer[0] ^ data_buffer[1]; + } + if (sha_handle != NULL) { + bootloader_sha256_data(sha_handle, data_buffer, sizeof(data_buffer)); + } + ESP_FAULT_ASSERT(memcmp(data_buffer, src, sizeof(data_buffer)) == 0); + ESP_FAULT_ASSERT(memcmp(&metadata->secure_version, &src[1], sizeof(uint32_t)) == 0); + return sizeof(data_buffer); +} +#endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK + +static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum, esp_image_metadata_t *metadata) { // If we are not loading, and the checksum is empty, skip processing this // segment for data @@ -636,10 +688,24 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui #endif } uint32_t *dest = (uint32_t *)load_addr; -#endif +#endif // BOOTLOADER_BUILD const uint32_t *src = data; +#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK + // Case I: Bootloader verifying application + // Case II: Bootloader verifying bootloader + // Anti-rollback check should handle only Case I from above. + if (segment == 0 && metadata->start_addr != ESP_BOOTLOADER_OFFSET) { + ESP_LOGD(TAG, "additional anti-rollback check 0x%"PRIx32, data_addr); + // The esp_app_desc_t structure is located in DROM and is always in segment #0. + size_t len = process_esp_app_desc_data(src, sha_handle, checksum, metadata); + data_len -= len; + src += len / 4; + // In BOOTLOADER_BUILD, for DROM (segment #0) we do not load it into dest (only map it), do_load = false. + } +#endif // CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK + for (size_t i = 0; i < data_len; i += 4) { int w_i = i / 4; // Word index uint32_t w = src[w_i]; @@ -864,7 +930,7 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han bootloader_munmap(simple_hash); } -#if CONFIG_SECURE_BOOT_V2_ENABLED +#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME // End of the image needs to be padded all the way to a 4KB boundary, after the simple hash // (for apps they are usually already padded due to --secure-pad-v2, only a problem if this option was not used.) uint32_t padded_end = ALIGN_UP(end, FLASH_SECTOR_SIZE); @@ -874,7 +940,7 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han bootloader_munmap(padding); end = padded_end; } -#endif +#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME bootloader_sha256_finish(sha_handle, image_digest); @@ -914,9 +980,13 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han return ESP_ERR_IMAGE_INVALID; } -#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME // Adjust image length result to include the appended signature +#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME data->image_len = end - data->start_addr + sizeof(ets_secure_boot_signature_t); +#elif defined(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) + if (data->start_addr != ESP_BOOTLOADER_OFFSET) { + data->image_len = end - data->start_addr + sizeof(esp_secure_boot_sig_block_t); + } #endif #endif // SECURE_BOOT_CHECK_SIGNATURE diff --git a/components/bootloader_support/src/flash_encryption/flash_encrypt.c b/components/bootloader_support/src/flash_encryption/flash_encrypt.c index daf920564a..ab1d1d83d6 100644 --- a/components/bootloader_support/src/flash_encryption/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encryption/flash_encrypt.c @@ -393,14 +393,21 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit { esp_err_t err; bool should_encrypt = (partition->flags & PART_FLAG_ENCRYPTED); + uint32_t size = partition->pos.size; if (partition->type == PART_TYPE_APP) { /* check if the partition holds a valid unencrypted app */ - esp_image_metadata_t data_ignored; + esp_image_metadata_t image_data = {}; err = esp_image_verify(ESP_IMAGE_VERIFY, &partition->pos, - &data_ignored); + &image_data); should_encrypt = (err == ESP_OK); +#ifdef CONFIG_SECURE_FLASH_ENCRYPT_ONLY_IMAGE_LEN_IN_APP_PART + if (should_encrypt) { + // Encrypt only the app image instead of encrypting the whole partition + size = image_data.image_len; + } +#endif } else if ((partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) || (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_NVS_KEYS)) { /* check if we have ota data partition and the partition should be encrypted unconditionally */ @@ -411,9 +418,9 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit return ESP_OK; } else { /* should_encrypt */ - ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, partition->pos.size); + ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, size); - err = esp_flash_encrypt_region(partition->pos.offset, partition->pos.size); + err = esp_flash_encrypt_region(partition->pos.offset, size); ESP_LOGI(TAG, "Done encrypting"); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to encrypt partition %d", index); diff --git a/components/bootloader_support/src/secure_boot.c b/components/bootloader_support/src/secure_boot.c index 5e9b8832fc..9015bdfd5a 100644 --- a/components/bootloader_support/src/secure_boot.c +++ b/components/bootloader_support/src/secure_boot.c @@ -144,9 +144,9 @@ static esp_err_t secure_boot_v2_check(bool *need_fix) #endif #endif // CONFIG_SECURE_BOOT -#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT +#if (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT -static void rsa_check_signature_on_update_check(void) +static void check_signature_on_update_check(void) { // We rely on the keys used to sign this app to verify the next app on OTA, so make sure there is at // least one to avoid a stuck firmware @@ -164,7 +164,7 @@ static void rsa_check_signature_on_update_check(void) } #endif } -#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT +#endif // (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT void esp_secure_boot_init_checks(void) { @@ -184,9 +184,9 @@ void esp_secure_boot_init_checks(void) #endif // CONFIG_SECURE_BOOT -#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT - rsa_check_signature_on_update_check(); -#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT +#if (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT + check_signature_on_update_check(); +#endif // (CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME) && CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT } diff --git a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c b/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c index 7c4ad07f10..03c01161df 100644 --- a/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c +++ b/components/bootloader_support/src/secure_boot_v2/secure_boot_signatures_app.c @@ -22,6 +22,7 @@ #include "esp_secure_boot.h" #include "esp_ota_ops.h" #include "esp_efuse.h" +#include "esp_efuse_chip.h" #include "secure_boot_signature_priv.h" @@ -46,31 +47,32 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo return ESP_OK; } -esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests) +static esp_err_t calculate_image_public_key_digests(bool verify_image_digest, bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests, esp_partition_pos_t *part_pos) { - esp_image_metadata_t metadata; - const esp_partition_t* running_app_part = esp_ota_get_running_partition(); - if (running_app_part == NULL) { - ESP_LOGE(TAG, "Cannot get running partition"); - return ESP_FAIL; - } - const esp_partition_pos_t part_pos = { - .offset = running_app_part->address, - .size = running_app_part->size, - }; - esp_err_t err = esp_image_get_metadata(&part_pos, &metadata); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Error reading metadata from running app (err=0x%x)", err); + esp_image_metadata_t img_metadata = {0}; + esp_err_t ret = esp_image_get_metadata(part_pos, &img_metadata); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Error reading metadata from running app (err=0x%x)", ret); return ESP_FAIL; } - memset(public_key_digests, 0, sizeof(esp_image_sig_public_key_digests_t)); + uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0}; + uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0}; + size_t sig_block_addr = img_metadata.start_addr + ALIGN_UP(img_metadata.image_len, FLASH_SECTOR_SIZE); + + ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%"PRIu32" (sig block offset 0x%u)", img_metadata.start_addr, sig_block_addr); + + bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t)); - // Generating the SHA of the public key components in the signature block + if (verify_image_digest) { + ret = bootloader_sha256_flash_contents(img_metadata.start_addr, sig_block_addr - img_metadata.start_addr, image_digest); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "error generating image digest, %d", ret); + return ret; + } + } - // metadata.image_len doesn't include any padding to start of the signature sector, so pad it here - size_t sig_block_addr = metadata.start_addr + ALIGN_UP(metadata.image_len, FLASH_SECTOR_SIZE); - ESP_LOGD(TAG, "reading signatures for app address 0x%"PRIx32" sig block address 0x%x", part_pos.offset, sig_block_addr); + ESP_LOGD(TAG, "reading signature(s)"); for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) { ets_secure_boot_sig_block_t block; size_t addr = sig_block_addr + sizeof(ets_secure_boot_sig_block_t) * i; @@ -84,20 +86,59 @@ esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_publi #elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME bootloader_sha256_data(sig_block_sha, &block.ecdsa.key, sizeof(block.ecdsa.key)); #endif - bootloader_sha256_finish(sig_block_sha, public_key_digests->key_digests[i]); + bootloader_sha256_finish(sig_block_sha, key_digest); + if (verify_image_digest) { + // Check we can verify the image using this signature and this key + uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN]; + #if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME + bool verified = ets_rsa_pss_verify(&block.key, block.signature, image_digest, temp_verified_digest); + #elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME + bool verified = ets_ecdsa_verify(&block.ecdsa.key.point[0], block.ecdsa.signature, block.ecdsa.key.curve_id, image_digest, temp_verified_digest); + #endif + if (!verified) { + ESP_LOGE(TAG, "Secure boot key (%d) verification failed.", i); + continue; + } + ESP_LOGD(TAG, "Signature block (%d) is verified", i); + } + /* Copy the key digest to the buffer provided by the caller */ + memcpy((void *)public_key_digests->key_digests[public_key_digests->num_digests], key_digest, ESP_SECURE_BOOT_DIGEST_LEN); } public_key_digests->num_digests++; } } else { - ESP_LOGE(TAG, "Secure boot sign blocks cannot be read from a running app (err=0x%x)", err); + ESP_LOGE(TAG, "Secure boot sign blocks cannot be read from image at %lx (err=0x%x)", part_pos->offset, err); return ESP_FAIL; } } - if (public_key_digests->num_digests > 0) { - return ESP_OK; + + if (ret == ESP_OK && public_key_digests->num_digests > 0) { + ESP_LOGD(TAG, "Digests successfully calculated, %d valid signatures (image offset 0x%"PRIu32")", + public_key_digests->num_digests, img_metadata.start_addr); } - ESP_LOGE(TAG, "No signatures were found for the running app"); - return ESP_ERR_NOT_FOUND; + + if (public_key_digests->num_digests == 0) { + return ESP_ERR_NOT_FOUND; + } + return ret; +} + +esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests) +{ + esp_partition_pos_t part_pos; + const esp_partition_t* running_app_part = esp_ota_get_running_partition(); + if (running_app_part == NULL) { + ESP_LOGE(TAG, "Cannot get running partition"); + return ESP_FAIL; + } + part_pos.offset = running_app_part->address; + part_pos.size = running_app_part->size; + + esp_err_t err = calculate_image_public_key_digests(false, digest_public_keys, public_key_digests, &part_pos); + if (public_key_digests->num_digests == 0) { + ESP_LOGE(TAG, "No signatures were found for the running app"); + } + return err; } static esp_err_t get_secure_boot_key_digests(esp_image_sig_public_key_digests_t *public_key_digests) @@ -236,3 +277,33 @@ esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signa #endif #endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME || CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT + +#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED + +esp_err_t esp_secure_boot_verify_with_efuse_digest_index(int efuse_digest_index, esp_partition_pos_t *part_pos) +{ + if (!part_pos || (efuse_digest_index < 0 || efuse_digest_index >= SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS)) { + return ESP_ERR_INVALID_ARG; + } + esp_image_sig_public_key_digests_t img_key_digests = {0}; + esp_err_t ret = calculate_image_public_key_digests(true, true, &img_key_digests, part_pos); + if (ret != ESP_OK) { + return ESP_FAIL; + } + if (esp_efuse_get_digest_revoke(efuse_digest_index)) { + return ESP_FAIL; + } + + // Read key digests from efuse + esp_secure_boot_key_digests_t efuse_key_digests; + memset(&efuse_key_digests, 0, sizeof(esp_secure_boot_key_digests_t)); + esp_secure_boot_read_key_digests(&efuse_key_digests); + + for (int i = 0; i < img_key_digests.num_digests; i++) { + if (!memcmp(img_key_digests.key_digests[i], efuse_key_digests.key_digests[efuse_digest_index], ESP_SECURE_BOOT_KEY_DIGEST_LEN)) { + return ESP_OK; + } + } + return ESP_FAIL; +} +#endif // SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index dad1f0c81c..d7bad30b16 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -2,32 +2,42 @@ if(CONFIG_BT_ENABLED) set(srcs "") set(include_dirs "") + set(ldscripts "linker_common.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") + list(APPEND include_dirs include/esp32/include) + list(APPEND ldscripts "linker_rw_bt_controller.lf") + + elseif(CONFIG_IDF_TARGET_ESP32C3) + list(APPEND srcs "controller/esp32c3/bt.c") + list(APPEND include_dirs include/esp32c3/include) + list(APPEND ldscripts "linker_rw_bt_controller.lf") + + elseif(CONFIG_IDF_TARGET_ESP32S3) + list(APPEND srcs "controller/esp32c3/bt.c") + list(APPEND include_dirs include/esp32c3/include) + list(APPEND ldscripts "linker_rw_bt_controller.lf") + + elseif(CONFIG_IDF_TARGET_ESP32C2) + list(APPEND srcs "controller/esp32c2/bt.c") + list(APPEND include_dirs include/esp32c2/include) + set(ldscripts "linker_esp32c2.lf") + + elseif(CONFIG_IDF_TARGET_ESP32C6) + list(APPEND srcs "controller/esp32c6/bt.c") + list(APPEND include_dirs include/esp32c6/include) + list(APPEND ldscripts "linker_esp_ble_controller.lf") + + elseif(CONFIG_IDF_TARGET_ESP32H2) + list(APPEND srcs "controller/esp32h2/bt.c") + list(APPEND include_dirs include/esp32h2/include) + list(APPEND ldscripts "linker_esp_ble_controller.lf") - if(CONFIG_IDF_TARGET_ESP32) - list(APPEND srcs "controller/esp32/bt.c" - "controller/esp32/hli_api.c" - "controller/esp32/hli_vectors.S") - list(APPEND include_dirs include/esp32/include) - - elseif(CONFIG_IDF_TARGET_ESP32C3) - list(APPEND srcs "controller/esp32c3/bt.c") - list(APPEND include_dirs include/esp32c3/include) - - elseif(CONFIG_IDF_TARGET_ESP32S3) - list(APPEND srcs "controller/esp32c3/bt.c") - list(APPEND include_dirs include/esp32c3/include) - - elseif(CONFIG_IDF_TARGET_ESP32C2) - list(APPEND srcs "controller/esp32c2/bt.c") - list(APPEND include_dirs include/esp32c2/include) - - elseif(CONFIG_IDF_TARGET_ESP32C6) - list(APPEND srcs "controller/esp32c6/bt.c") - list(APPEND include_dirs include/esp32c6/include) + endif() - elseif(CONFIG_IDF_TARGET_ESP32H2) - list(APPEND srcs "controller/esp32h2/bt.c") - list(APPEND include_dirs include/esp32h2/include) endif() @@ -38,16 +48,19 @@ if(CONFIG_BT_ENABLED) common/btc/include common/include porting/mem/ + porting/include ) list(APPEND include_dirs common/api/include/api common/btc/profile/esp/blufi/include common/btc/profile/esp/include + common/hci_log/include ) list(APPEND srcs "common/btc/core/btc_alarm.c" "common/api/esp_blufi_api.c" + "common/hci_log/bt_hci_log.c" "common/btc/core/btc_manage.c" "common/btc/core/btc_task.c" "common/btc/profile/esp/blufi/blufi_prf.c" @@ -476,25 +489,51 @@ if(CONFIG_BT_ENABLED) if(CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT) - list(APPEND srcs - "porting/npl/freertos/src/npl_os_freertos.c" - "porting/nimble/src/os_msys_init.c" - ) + list(APPEND srcs + "porting/npl/freertos/src/npl_os_freertos.c" + "porting/mem/os_msys_init.c" + "porting/transport/src/hci_transport.c" + ) - list(APPEND include_dirs - porting/include - porting/nimble/include - porting/npl/freertos/include - porting/transport/include + if(CONFIG_BT_CONTROLLER_DISABLED) + list(APPEND srcs + "host/nimble/nimble/porting/nimble/src/hal_uart.c" ) - - if(CONFIG_BT_LE_HCI_INTERFACE_USE_UART) + elseif(CONFIG_BT_LE_HCI_INTERFACE_USE_RAM) + if(CONFIG_BT_NIMBLE_ENABLED) list(APPEND srcs - "porting/transport/uart/hci_uart.c" - ) + "porting/transport/driver/vhci/hci_driver_nimble.c" + "host/nimble/nimble/nimble/transport/esp_ipc/src/hci_esp_ipc.c" + ) + else() + list(APPEND srcs + "porting/transport/driver/vhci/hci_driver_standard.c" + ) endif() - endif() + elseif(CONFIG_BT_LE_HCI_INTERFACE_USE_UART) + list(APPEND srcs + "porting/transport/driver/common/hci_driver_util.c" + "porting/transport/driver/common/hci_driver_h4.c" + "porting/transport/driver/common/hci_driver_mem.c" + "porting/transport/driver/uart/hci_driver_uart_config.c" + ) + if(CONFIG_BT_LE_UART_HCI_DMA_MODE) + list(APPEND srcs + "porting/transport/driver/uart/hci_driver_uart_dma.c" + ) + else() + list(APPEND srcs + "porting/transport/driver/uart/hci_driver_uart.c" + ) + endif() + endif() + list(APPEND include_dirs + porting/include + porting/npl/freertos/include + porting/transport/include + ) + endif() if(NOT (CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS OR CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS)) list(APPEND include_dirs @@ -520,19 +559,23 @@ if(CONFIG_BT_ENABLED) if(CONFIG_BT_NIMBLE_ENABLED) list(APPEND include_dirs - host/nimble/nimble/nimble/host/include + host/nimble/nimble/nimble/include host/nimble/nimble/nimble/host/services/ans/include host/nimble/nimble/nimble/host/services/bas/include host/nimble/nimble/nimble/host/services/dis/include host/nimble/nimble/nimble/host/services/gap/include host/nimble/nimble/nimble/host/services/gatt/include host/nimble/nimble/nimble/host/services/hr/include + host/nimble/nimble/nimble/host/services/htp/include host/nimble/nimble/nimble/host/services/ias/include 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/services/hid/include + host/nimble/nimble/nimble/host/services/sps/include host/nimble/nimble/nimble/host/util/include host/nimble/nimble/nimble/host/store/ram/include host/nimble/nimble/nimble/host/store/config/include @@ -546,11 +589,15 @@ if(CONFIG_BT_ENABLED) "host/nimble/nimble/nimble/host/services/ipss/src/ble_svc_ipss.c" "host/nimble/nimble/nimble/host/services/ans/src/ble_svc_ans.c" "host/nimble/nimble/nimble/host/services/hr/src/ble_svc_hr.c" + "host/nimble/nimble/nimble/host/services/htp/src/ble_svc_htp.c" "host/nimble/nimble/nimble/host/services/gap/src/ble_svc_gap.c" "host/nimble/nimble/nimble/host/services/bas/src/ble_svc_bas.c" "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/services/hid/src/ble_svc_hid.c" + "host/nimble/nimble/nimble/host/services/sps/src/ble_svc_sps.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" @@ -569,6 +616,8 @@ if(CONFIG_BT_ENABLED) "host/nimble/nimble/nimble/host/src/ble_hs_mqueue.c" "host/nimble/nimble/nimble/host/src/ble_hs_periodic_sync.c" "host/nimble/nimble/nimble/host/src/ble_att.c" + "host/nimble/nimble/nimble/host/src/ble_ead.c" + "host/nimble/nimble/nimble/host/src/ble_aes_ccm.c" "host/nimble/nimble/nimble/host/src/ble_gattc.c" "host/nimble/nimble/nimble/host/src/ble_store.c" "host/nimble/nimble/nimble/host/src/ble_sm_lgcy.c" @@ -597,19 +646,36 @@ if(CONFIG_BT_ENABLED) "host/nimble/nimble/nimble/host/store/ram/src/ble_store_ram.c" "host/nimble/nimble/nimble/host/store/config/src/ble_store_config.c" "host/nimble/nimble/nimble/host/store/config/src/ble_store_nvs.c" + "host/nimble/nimble/nimble/host/src/ble_gattc_cache.c" + "host/nimble/nimble/nimble/host/src/ble_gattc_cache_conn.c" + ) + + if(CONFIG_BT_CONTROLLER_DISABLED AND CONFIG_BT_NIMBLE_TRANSPORT_UART) + list(APPEND srcs + "host/nimble/nimble/nimble/transport/uart_ll/src/hci_uart.c" + "host/nimble/nimble/nimble/transport/common/hci_h4/src/hci_h4.c" ) + endif() list(APPEND srcs "host/nimble/nimble/porting/nimble/src/nimble_port.c" "host/nimble/nimble/porting/npl/freertos/src/nimble_port_freertos.c" + "host/nimble/port/src/nvs_port.c" ) + list(APPEND include_dirs - porting/include host/nimble/nimble/porting/nimble/include host/nimble/port/include host/nimble/nimble/nimble/transport/include + host/nimble/nimble/nimble/include ) + if(CONFIG_BT_CONTROLLER_DISABLED) + list(APPEND include_dirs + host/nimble/nimble/nimble/transport/common/hci_h4/include + ) + endif() + if(NOT CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT) list(APPEND srcs "host/nimble/nimble/porting/nimble/src/endian.c" @@ -619,16 +685,23 @@ if(CONFIG_BT_ENABLED) "host/nimble/nimble/porting/nimble/src/os_msys_init.c" "host/nimble/nimble/porting/npl/freertos/src/npl_os_freertos.c" ) + + if(CONFIG_BT_CONTROLLER_DISABLED AND CONFIG_BT_NIMBLE_TRANSPORT_UART) + list(APPEND srcs + "host/nimble/nimble/porting/nimble/src/hal_uart.c" + ) + endif() + list(APPEND include_dirs + porting/include host/nimble/nimble/porting/npl/freertos/include - host/nimble/nimble/porting/nimble/include - host/nimble/nimble/nimble/include ) endif() - if(CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE) + if(CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE AND CONFIG_BT_CONTROLLER_ENABLED) list(APPEND srcs "host/nimble/esp-hci/src/esp_nimble_hci.c" + "host/nimble/nimble/nimble/transport/esp_ipc_legacy/src/hci_esp_ipc_legacy.c" ) list(APPEND include_dirs host/nimble/esp-hci/include @@ -691,13 +764,12 @@ if(CONFIG_BT_ENABLED) endif() -# requirements can't depend on config idf_component_register(SRCS "${srcs}" - INCLUDE_DIRS "${include_dirs}" - PRIV_INCLUDE_DIRS "${priv_include_dirs}" - REQUIRES esp_timer esp_wifi - PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls driver vfs - LDFRAGMENTS "linker.lf") + INCLUDE_DIRS "${include_dirs}" + PRIV_INCLUDE_DIRS "${priv_include_dirs}" + REQUIRES esp_timer esp_wifi + PRIV_REQUIRES nvs_flash soc esp_pm esp_phy esp_coex mbedtls driver vfs + LDFRAGMENTS "${ldscripts}") if(CONFIG_BT_ENABLED) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable) @@ -714,14 +786,8 @@ if(CONFIG_BT_ENABLED) target_link_directories(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c3_family/esp32s3") target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app) - elseif(CONFIG_IDF_TARGET_ESP32C2) - add_prebuilt_library(libble_app "controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a") - target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app) - elseif(CONFIG_IDF_TARGET_ESP32C6) - add_prebuilt_library(libble_app "controller/lib_esp32c6/esp32c6-bt-lib/libble_app.a") - target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app) - elseif(CONFIG_IDF_TARGET_ESP32H2) - add_prebuilt_library(libble_app "controller/lib_esp32h2/esp32h2-bt-lib/libble_app.a") + elseif(CONFIG_BT_CONTROLLER_ENABLED) + add_prebuilt_library(libble_app "controller/lib_${target}/${target}-bt-lib/libble_app.a") target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app) endif() diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 8f98c38eaf..4524c804e2 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. @@ -15,6 +14,7 @@ menu "Bluetooth" This helps to choose Bluetooth host stack config BT_BLUEDROID_ENABLED + depends on BT_CONTROLLER_ENABLED bool "Bluedroid - Dual-mode" help This option is recommended for classic Bluetooth or for dual-mode @@ -26,6 +26,7 @@ menu "Bluetooth" 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 @@ -68,6 +70,48 @@ menu "Bluetooth" source "$IDF_PATH/components/bt/controller/$IDF_TARGET/Kconfig.in" endmenu + config BT_RELEASE_IRAM + depends on BT_ENABLED && BT_LE_RELEASE_IRAM_SUPPORTED + bool "Release Bluetooth text (READ DOCS FIRST)" + default n + help + This option release Bluetooth text section and merge Bluetooth data, bss & text into + a large free heap region when esp_bt_mem_release is called, total saving ~21kB or more of IRAM. + ESP32-C2 only 3 configurable PMP entries available, rest of them are hard-coded. + We cannot split the memory into 3 different regions (IRAM, BLE-IRAM, DRAM). + So this option will disable the PMP (ESP_SYSTEM_PMP_IDRAM_SPLIT) + + config BT_HCI_LOG_DEBUG_EN + depends on BT_BLUEDROID_ENABLED || BT_NIMBLE_ENABLED + bool "Enable Bluetooth HCI debug mode" + default n + help + This option is used to enable bluetooth debug mode, which saves the hci layer data stream. + + config BT_HCI_LOG_DATA_BUFFER_SIZE + depends on BT_HCI_LOG_DEBUG_EN + int "Size of the cache used for HCI data in Bluetooth HCI debug mode (N*1024 bytes)" + range 1 100 + default 5 + help + This option is to configure the buffer size of the hci data steam cache in hci debug mode. + This is a ring buffer, the new data will overwrite the oldest data if the buffer is full. + + config BT_HCI_LOG_ADV_BUFFER_SIZE + depends on BT_HCI_LOG_DEBUG_EN + int "Size of the cache used for adv report in Bluetooth HCI debug mode (N*1024 bytes)" + range 1 100 + default 8 + help + This option is to configure the buffer size of the hci adv report cache in hci debug mode. + This is a ring buffer, the new data will overwrite the oldest data if the buffer is full. + + menu "Common Options" + visible if (BT_BLUEDROID_ENABLED || BT_NIMBLE_ENABLED) + + source "$IDF_PATH/components/bt/common/Kconfig.in" + endmenu + endmenu menuconfig BLE_MESH diff --git a/components/bt/common/Kconfig.in b/components/bt/common/Kconfig.in new file mode 100644 index 0000000000..6b19dd8ec0 --- /dev/null +++ b/components/bt/common/Kconfig.in @@ -0,0 +1,6 @@ +config BT_ALARM_MAX_NUM + int "Maximum number of Bluetooth alarms" + default 50 + help + This option decides the maximum number of alarms which + could be used by Bluetooth host. diff --git a/components/bt/common/btc/core/btc_task.c b/components/bt/common/btc/core/btc_task.c index 93f36b5e23..9bfd6fa8f2 100644 --- a/components/bt/common/btc/core/btc_task.c +++ b/components/bt/common/btc/core/btc_task.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -335,6 +335,13 @@ static void btc_deinit_mem(void) { #endif #endif +#if BTC_HF_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE + if (hf_local_param_ptr) { + osi_free(hf_local_param_ptr); + hf_local_param_ptr = NULL; + } +#endif + #if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE if (hf_client_local_param_ptr) { osi_free(hf_client_local_param_ptr); @@ -390,6 +397,13 @@ static bt_status_t btc_init_mem(void) { #endif #endif +#if BTC_HF_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE + if ((hf_local_param_ptr = (hf_local_param_t *)osi_malloc(BTC_HF_NUM_CB * sizeof(hf_local_param_t))) == NULL) { + goto error_exit; + } + memset((void *)hf_local_param_ptr, 0, BTC_HF_NUM_CB * sizeof(hf_local_param_t)); +#endif + #if BTC_HF_CLIENT_INCLUDED == TRUE && HFP_DYNAMIC_MEMORY == TRUE if ((hf_client_local_param_ptr = (hf_client_local_param_t *)osi_malloc(sizeof(hf_client_local_param_t))) == NULL) { goto error_exit; diff --git a/components/bt/common/btc/profile/esp/blufi/blufi_prf.c b/components/bt/common/btc/profile/esp/blufi/blufi_prf.c index 40b627c4d0..9620df5ce0 100644 --- a/components/bt/common/btc/profile/esp/blufi/blufi_prf.c +++ b/components/bt/common/btc/profile/esp/blufi/blufi_prf.c @@ -366,7 +366,7 @@ void btc_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list) int data_len; uint8_t *p; // malloc size: (len + RSSI + ssid buffer) * apCount; - uint malloc_size = (1 + 1 + sizeof(list->ssid)) * apCount; + uint32_t malloc_size = (1 + 1 + sizeof(list->ssid)) * apCount; p = data = osi_malloc(malloc_size); if (data == NULL) { BTC_TRACE_ERROR("malloc error\n"); @@ -375,7 +375,7 @@ void btc_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list) type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST); for (int i = 0; i < apCount; ++i) { - uint len = strlen((const char *)list[i].ssid); + uint32_t len = strlen((const char *)list[i].ssid); data_len = (p - data); //current_len + ssid + rssi + total_len_value if((data_len + len + 1 + 1) > malloc_size) { diff --git a/components/bt/common/btc/profile/esp/blufi/include/blufi_int.h b/components/bt/common/btc/profile/esp/blufi/include/blufi_int.h index 5730f14340..e85ad73d86 100644 --- a/components/bt/common/btc/profile/esp/blufi/include/blufi_int.h +++ b/components/bt/common/btc/profile/esp/blufi/include/blufi_int.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,11 @@ #include "btc/btc_task.h" #include "esp_blufi_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + #if (BLUFI_INCLUDED == TRUE) #define BTC_BLUFI_GREAT_VER 0x01 //Version + Subversion @@ -193,5 +198,10 @@ void btc_blufi_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); void btc_blufi_cb_deep_free(btc_msg_t *msg); -#endif /* __BLUFI_INT_H__ */ -#endif ///BLUFI_INCLUDED == TRUE +#endif ///BLUFI_INCLUDED == TRUE + +#ifdef __cplusplus +} +#endif + +#endif /* __BLUFI_INT_H__ */ diff --git a/components/bt/common/btc/profile/esp/blufi/include/esp_blufi.h b/components/bt/common/btc/profile/esp/blufi/include/esp_blufi.h index a368325dfe..db2203b1e6 100644 --- a/components/bt/common/btc/profile/esp/blufi/include/esp_blufi.h +++ b/components/bt/common/btc/profile/esp/blufi/include/esp_blufi.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,10 @@ #include "esp_gap_ble_api.h" #endif +#ifdef __cplusplus +extern "C" { +#endif + #define BLUFI_APP_UUID 0xFFFF #define BLUFI_DEVICE_NAME "BLUFI_DEVICE" @@ -96,4 +100,7 @@ void esp_blufi_send_encap(void *arg); int esp_blufi_handle_gap_events(struct ble_gap_event *event, void *arg); #endif +#ifdef __cplusplus +} +#endif #endif/* _ESP_BLUFI_ */ diff --git a/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c b/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c index 82c49c8b66..fc484c872f 100644 --- a/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c +++ b/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -124,7 +124,31 @@ static size_t write_value(uint16_t conn_handle, uint16_t attr_handle, } } - btc_blufi_recv_handler(&ctxt->om->om_data[0], ctxt->om->om_len); + /* Data may come in linked om. So retrieve all data */ + if (SLIST_NEXT(ctxt->om, om_next) != NULL) { + uint8_t *fw_buf = (uint8_t *)malloc(517 * sizeof(uint8_t)); + memset(fw_buf, 0x0, 517); + + memcpy(fw_buf, &ctxt->om->om_data[0], ctxt->om->om_len); + struct os_mbuf *last; + last = ctxt->om; + uint32_t offset = ctxt->om->om_len; + + while (SLIST_NEXT(last, om_next) != NULL) { + struct os_mbuf *temp = SLIST_NEXT(last, om_next); + memcpy(fw_buf + offset , &temp->om_data[0], temp->om_len); + offset += temp->om_len; + last = SLIST_NEXT(last, om_next); + temp = NULL; + } + btc_blufi_recv_handler(fw_buf, offset); + + free(fw_buf); + } + else { + btc_blufi_recv_handler(&ctxt->om->om_data[0], ctxt->om->om_len); + } + rc = ble_hs_mbuf_to_flat(ctxt->om, value->buf->om_data, value->buf->om_len, &len); if (rc != 0) { diff --git a/components/bt/common/btc/profile/esp/include/btc_blufi_prf.h b/components/bt/common/btc/profile/esp/include/btc_blufi_prf.h index 347c4428cd..1174f01ee0 100644 --- a/components/bt/common/btc/profile/esp/include/btc_blufi_prf.h +++ b/components/bt/common/btc/profile/esp/include/btc_blufi_prf.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,6 +21,11 @@ #define ESP_BLUFI_SUCCESS 0x00 #endif + +#ifdef __cplusplus +extern "C" { +#endif + #define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" #define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] @@ -100,4 +105,7 @@ void btc_blufi_call_deep_free(btc_msg_t *msg); uint16_t btc_blufi_get_version(void); +#ifdef __cplusplus +} +#endif #endif /* __BTC_BLUFI_PRF_H__ */ diff --git a/components/bt/common/hci_log/bt_hci_log.c b/components/bt/common/hci_log/bt_hci_log.c new file mode 100644 index 0000000000..e35bf1a7a6 --- /dev/null +++ b/components/bt/common/hci_log/bt_hci_log.c @@ -0,0 +1,334 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "hci_log/bt_hci_log.h" +#include "bt_common.h" +#include "osi/mutex.h" +#include "esp_attr.h" + +#if (BT_HCI_LOG_INCLUDED == TRUE) +#define BT_HCI_LOG_PRINT_TAG (1) +#define BT_HCI_LOG_DATA_BUF_SIZE (1024 * HCI_LOG_DATA_BUFFER_SIZE) +#define BT_HCI_LOG_ADV_BUF_SIZE (1024 * HCI_LOG_ADV_BUFFER_SIZE) + +typedef struct { + osi_mutex_t mutex_lock; + uint64_t log_record_in; + uint64_t log_record_out; + uint64_t buf_size; + uint8_t *p_hci_log_buffer; + uint8_t index; + bool overflow; +} bt_hci_log_t; + +static const char s_hex_to_char_mapping[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' +}; + +static bt_hci_log_t g_bt_hci_log_data_ctl = {0}; +static bt_hci_log_t g_bt_hci_log_adv_ctl = {0}; + +esp_err_t bt_hci_log_init(void) +{ + uint8_t *g_bt_hci_log_data_buffer = NULL; + uint8_t *g_bt_hci_log_adv_buffer = NULL; + + g_bt_hci_log_data_buffer = malloc(BT_HCI_LOG_DATA_BUF_SIZE); + if (!g_bt_hci_log_data_buffer) { + return ESP_ERR_NO_MEM; + } + g_bt_hci_log_adv_buffer = malloc(BT_HCI_LOG_ADV_BUF_SIZE); + if (!g_bt_hci_log_adv_buffer) { + if (g_bt_hci_log_data_buffer) { + free(g_bt_hci_log_data_buffer); + g_bt_hci_log_data_buffer = NULL; + } + return ESP_ERR_NO_MEM; + } + + memset(g_bt_hci_log_data_buffer, 0, BT_HCI_LOG_DATA_BUF_SIZE); + memset(g_bt_hci_log_adv_buffer, 0, BT_HCI_LOG_ADV_BUF_SIZE); + + memset(&g_bt_hci_log_data_ctl, 0, sizeof(bt_hci_log_t)); + g_bt_hci_log_data_ctl.buf_size = BT_HCI_LOG_DATA_BUF_SIZE; + g_bt_hci_log_data_ctl.p_hci_log_buffer = g_bt_hci_log_data_buffer; + + memset(&g_bt_hci_log_adv_ctl, 0, sizeof(bt_hci_log_t)); + g_bt_hci_log_adv_ctl.buf_size = BT_HCI_LOG_ADV_BUF_SIZE; + g_bt_hci_log_adv_ctl.p_hci_log_buffer = g_bt_hci_log_adv_buffer; + + osi_mutex_new((osi_mutex_t *)&g_bt_hci_log_data_ctl.mutex_lock); + osi_mutex_new((osi_mutex_t *)&g_bt_hci_log_adv_ctl.mutex_lock); + + return ESP_OK; +} + +esp_err_t bt_hci_log_deinit(void) +{ + if (g_bt_hci_log_data_ctl.p_hci_log_buffer) { + free(g_bt_hci_log_data_ctl.p_hci_log_buffer); + g_bt_hci_log_data_ctl.p_hci_log_buffer = NULL; + } + + if (g_bt_hci_log_adv_ctl.p_hci_log_buffer) { + free(g_bt_hci_log_adv_ctl.p_hci_log_buffer); + g_bt_hci_log_adv_ctl.p_hci_log_buffer = NULL; + } + + osi_mutex_free((osi_mutex_t *)&g_bt_hci_log_data_ctl.mutex_lock); + osi_mutex_free((osi_mutex_t *)&g_bt_hci_log_adv_ctl.mutex_lock); + + memset(&g_bt_hci_log_data_ctl, 0, sizeof(bt_hci_log_t)); + memset(&g_bt_hci_log_adv_ctl, 0, sizeof(bt_hci_log_t)); + + return ESP_OK; +} + +#if (BT_HCI_LOG_PRINT_TAG) +static char IRAM_ATTR *bt_data_type_to_str(uint8_t data_type) +{ + char *tag = NULL; + switch (data_type) + { + case HCI_LOG_DATA_TYPE_COMMAND: + // hci cmd data + tag = "C"; + break; + case HCI_LOG_DATA_TYPE_H2C_ACL: + // host to controller hci acl data + tag = "H"; + break; + case HCI_LOG_DATA_TYPE_SCO: + // hci sco data + tag = "S"; + break; + case HCI_LOG_DATA_TYPE_EVENT: + // hci event + tag = "E"; + break; + case HCI_LOG_DATA_TYPE_ADV: + // controller adv report data + tag = NULL; + break; + case HCI_LOG_DATA_TYPE_C2H_ACL: + // controller to host hci acl data + tag = "D"; + break; + case HCI_LOG_DATA_TYPE_SELF_DEFINE: + // self-defining data + tag = "S"; + break; + default: + // unknown data type + tag = "U"; + break; + } + + return tag; +} +#endif + +void bt_hci_log_record_hex(bt_hci_log_t *p_hci_log_ctl, uint8_t *hex, uint8_t hex_len) +{ + uint8_t hci_log_char; + uint8_t *g_hci_log_buffer; + + g_hci_log_buffer = p_hci_log_ctl->p_hci_log_buffer; + + while (hex_len--) + { + hci_log_char = ((*hex) >> 4); + + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = s_hex_to_char_mapping [hci_log_char]; + + if (++ p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + + hci_log_char = ((*hex) & 0x0f); + + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = s_hex_to_char_mapping [hci_log_char]; + + if (++p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = ' '; + + if (++ p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + + ++ hex; + } +} + +void bt_hci_log_record_string(bt_hci_log_t *p_hci_log_ctl, char *string) +{ + uint8_t *g_hci_log_buffer; + + g_hci_log_buffer = p_hci_log_ctl->p_hci_log_buffer; + + while (*string != '\0') { + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = *string; + ++string; + + if (++p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + } +} + +esp_err_t IRAM_ATTR bt_hci_log_record_data(bt_hci_log_t *p_hci_log_ctl, char *str, uint8_t data_type, uint8_t *data, uint8_t data_len) +{ + osi_mutex_t mutex_lock; + uint8_t *g_hci_log_buffer; + + if (!p_hci_log_ctl->p_hci_log_buffer) { + return ESP_FAIL; + } + + g_hci_log_buffer = p_hci_log_ctl->p_hci_log_buffer; + + if (!g_hci_log_buffer) { + return ESP_FAIL; + } + + mutex_lock = p_hci_log_ctl->mutex_lock; + osi_mutex_lock(&mutex_lock, OSI_MUTEX_MAX_TIMEOUT); + +#if (1) + // Add hci data index + bt_hci_log_record_hex(p_hci_log_ctl, &p_hci_log_ctl->index, 1); +#endif + +#if (BT_HCI_LOG_PRINT_TAG) + char *tag = NULL; + tag = bt_data_type_to_str(data_type); + + if (tag) { + bt_hci_log_record_string(p_hci_log_ctl, tag); + + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = ':'; + + if (++p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + } +#endif + + if (str) { + bt_hci_log_record_string(p_hci_log_ctl, str); + } + + bt_hci_log_record_hex(p_hci_log_ctl, data, data_len); + + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = '\n'; + + if (++p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + + p_hci_log_ctl->index ++; + + osi_mutex_unlock(&mutex_lock); + + return ESP_OK; +} + +void bt_hci_log_data_show(bt_hci_log_t *p_hci_log_ctl) +{ + volatile uint64_t log_record_in,log_record_out; + uint8_t *g_hci_log_buffer; + + if (!p_hci_log_ctl->p_hci_log_buffer) { + return; + } + + osi_mutex_t mutex_lock = p_hci_log_ctl->mutex_lock; + + osi_mutex_lock(&mutex_lock, OSI_MUTEX_MAX_TIMEOUT); + + log_record_in = p_hci_log_ctl->log_record_in; + log_record_out = p_hci_log_ctl->log_record_out; + + g_hci_log_buffer = p_hci_log_ctl->p_hci_log_buffer; + + if (p_hci_log_ctl->overflow) { + log_record_out = log_record_in; + printf("%c",g_hci_log_buffer[log_record_out]); + + if (++log_record_out >= p_hci_log_ctl->buf_size) { + log_record_out = 0; + } + } + + while (log_record_in != log_record_out) + { + printf("%c",g_hci_log_buffer[log_record_out]); + + if (++log_record_out >= p_hci_log_ctl->buf_size) { + log_record_out = 0; + } + } + + p_hci_log_ctl->log_record_out = log_record_out; + p_hci_log_ctl->overflow = false; + + osi_mutex_unlock(&mutex_lock); +} + +esp_err_t IRAM_ATTR bt_hci_log_record_hci_data(uint8_t data_type, uint8_t *data, uint8_t data_len) +{ + return bt_hci_log_record_data(&g_bt_hci_log_data_ctl, NULL, data_type, data, data_len); +} + +esp_err_t IRAM_ATTR bt_hci_log_record_custom_data(char *string, uint8_t *data, uint8_t data_len) +{ + return bt_hci_log_record_data(&g_bt_hci_log_data_ctl, string, HCI_LOG_DATA_TYPE_SELF_DEFINE, data, data_len); +} + +esp_err_t IRAM_ATTR bt_hci_log_record_hci_adv(uint8_t data_type, uint8_t *data, uint8_t data_len) +{ + return bt_hci_log_record_data(&g_bt_hci_log_adv_ctl, NULL, data_type, data, data_len); +} + +void bt_hci_log_hci_data_show(void) +{ + bt_hci_log_data_show(&g_bt_hci_log_data_ctl); +} + +void bt_hci_log_hci_adv_show(void) +{ + bt_hci_log_data_show(&g_bt_hci_log_adv_ctl); +} + +#endif // (BT_HCI_LOG_INCLUDED == TRUE) diff --git a/components/bt/common/hci_log/include/hci_log/bt_hci_log.h b/components/bt/common/hci_log/include/hci_log/bt_hci_log.h new file mode 100644 index 0000000000..512a307e44 --- /dev/null +++ b/components/bt/common/hci_log/include/hci_log/bt_hci_log.h @@ -0,0 +1,108 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_BT_HCI_LOG_H__ +#define __ESP_BT_HCI_LOG_H__ + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define HCI_LOG_DATA_TYPE_COMMAND (1) +#define HCI_LOG_DATA_TYPE_H2C_ACL (2) +#define HCI_LOG_DATA_TYPE_SCO (3) +#define HCI_LOG_DATA_TYPE_EVENT (4) +#define HCI_LOG_DATA_TYPE_ADV (5) +#define HCI_LOG_DATA_TYPE_SELF_DEFINE (6) +#define HCI_LOG_DATA_TYPE_C2H_ACL (7) + +/** + * + * @brief This function is called to record self-defining data + * @param string : data identification + * @param data : data + * @param data_len : the length of data + * + * @return ESP_OK - success, other - failed + * + */ +esp_err_t bt_hci_log_record_custom_data(char *string, uint8_t *data, uint8_t data_len); +/** + * + * @brief This function is called to print all hci data record + * + * + * @return None + * + */ +void bt_hci_log_hci_data_show(void); + +/** + * + * @brief This function is called to print all adv report + * + * + * @return None + * + */ +void bt_hci_log_hci_adv_show(void); + +/** + * + * @brief This function is called to init hci log env + * + * + * @return ESP_OK - success, other - failed + * + */ +esp_err_t bt_hci_log_init(void); + +/** + * + * @brief This function is called to deinit hci debug mode, + * and can only be called internally by Bluetooth + * + * + * @return ESP_OK - success, other - failed + * + */ +esp_err_t bt_hci_log_deinit(void); + +/** + * + * @brief This function is called to record hci data without adv report event, + * and can only be called internally by Bluetooth + * + * @param str : data type, define in bt_data_type_to_str() + * @param data : data + * @param data_len : the length of data + * + * @return ESP_OK - success, other - failed + * + */ +esp_err_t bt_hci_log_record_hci_data(uint8_t data_type, uint8_t *data, uint8_t data_len); + +/** + * + * @brief This function is called to record hci adv report event only + * and can only be called internally by Bluetooth + * + * @param str : data type, define in bt_data_type_to_str() + * @param data : data + * @param data_len : the length of data + * @return ESP_OK - success, other - failed + * + */ +esp_err_t bt_hci_log_record_hci_adv(uint8_t data_type, uint8_t *data, uint8_t data_len); + +#ifdef __cplusplus +} +#endif + +#endif /* _ESP_BT_HCI_LOG_H__ */ diff --git a/components/bt/common/include/bt_common.h b/components/bt/common/include/bt_common.h index 134cf33c5d..f3c5ba0e0d 100644 --- a/components/bt/common/include/bt_common.h +++ b/components/bt/common/include/bt_common.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -64,6 +64,24 @@ #define BT_BLE_DYNAMIC_ENV_MEMORY FALSE #endif +#if UC_BT_HCI_LOG_DEBUG_EN +#define BT_HCI_LOG_INCLUDED UC_BT_HCI_LOG_DEBUG_EN +#else +#define BT_HCI_LOG_INCLUDED FALSE +#endif + +#if UC_BT_HCI_LOG_DATA_BUFFER_SIZE +#define HCI_LOG_DATA_BUFFER_SIZE UC_BT_HCI_LOG_DATA_BUFFER_SIZE +#else +#define HCI_BUFFER_SIZE (5) +#endif + +#if UC_BT_HCI_ADV_BUFFER_SIZE +#define HCI_LOG_ADV_BUFFER_SIZE UC_BT_HCI_LOG_ADV_BUFFER_SIZE +#else +#define HCI_LOG_ADV_BUFFER_SIZE (5) +#endif + /* OS Configuration from User config (eg: sdkconfig) */ #define TASK_PINNED_TO_CORE UC_TASK_PINNED_TO_CORE #define BT_TASK_MAX_PRIORITIES configMAX_PRIORITIES diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index 9f6df2bdd4..7516304cf0 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-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -44,6 +44,15 @@ #define UC_BTC_TASK_STACK_SIZE 4096 #endif +/********************************************************** + * Alarm reference + **********************************************************/ +#ifdef CONFIG_BT_ALARM_MAX_NUM +#define UC_ALARM_MAX_NUM CONFIG_BT_ALARM_MAX_NUM +#else +#define UC_ALARM_MAX_NUM 50 +#endif + /********************************************************** * Trace reference **********************************************************/ @@ -92,4 +101,22 @@ #define UC_BT_BLUEDROID_MEM_DEBUG FALSE #endif +#ifdef CONFIG_BT_HCI_LOG_DEBUG_EN +#define UC_BT_HCI_LOG_DEBUG_EN TRUE +#else +#define UC_BT_HCI_LOG_DEBUG_EN FALSE +#endif + +#ifdef CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE +#define UC_BT_HCI_LOG_DATA_BUFFER_SIZE CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE +#else +#define UC_BT_HCI_LOG_DATA_BUFFER_SIZE (5) +#endif + +#ifdef CONFIG_BT_HCI_LOG_ADV_BUFFER_SIZE +#define UC_BT_HCI_LOG_ADV_BUFFER_SIZE CONFIG_BT_HCI_LOG_ADV_BUFFER_SIZE +#else +#define UC_BT_HCI_LOG_ADV_BUFFER_SIZE (5) +#endif + #endif /* __BT_USER_CONFIG_H__ */ diff --git a/components/bt/common/osi/config.c b/components/bt/common/osi/config.c index 6473b5a62b..fb6727a7a3 100644 --- a/components/bt/common/osi/config.c +++ b/components/bt/common/osi/config.c @@ -254,6 +254,32 @@ bool config_remove_section(config_t *config, const char *section) return list_remove(config->sections, sec); } +bool config_update_newest_section(config_t *config, const char *section) +{ + assert(config != NULL); + assert(section != NULL); + + list_node_t *first_node = list_begin(config->sections); + if (first_node == NULL) { + return false; + } + section_t *first_sec = list_node(first_node); + if (strcmp(first_sec->name, section) == 0) { + return true; + } + + for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) { + section_t *sec = list_node(node); + if (strcmp(sec->name, section) == 0) { + list_delete(config->sections, sec); + list_prepend(config->sections, sec); + return true; + } + } + + return false; +} + bool config_remove_key(config_t *config, const char *section, const char *key) { assert(config != NULL); diff --git a/components/bt/common/osi/include/osi/alarm.h b/components/bt/common/osi/include/osi/alarm.h index fe8344cdb9..0ac1d11cca 100644 --- a/components/bt/common/osi/include/osi/alarm.h +++ b/components/bt/common/osi/include/osi/alarm.h @@ -21,6 +21,7 @@ #include #include "esp_timer.h" +#include "bt_user_config.h" typedef struct alarm_t osi_alarm_t; typedef uint64_t period_ms_t; @@ -33,7 +34,7 @@ typedef enum { OSI_ALARM_ERR_INVALID_STATE = -3, } osi_alarm_err_t; -#define ALARM_CBS_NUM 50 +#define ALARM_CBS_NUM UC_ALARM_MAX_NUM #define ALARM_ID_BASE 1000 int osi_alarm_create_mux(void); diff --git a/components/bt/common/osi/include/osi/config.h b/components/bt/common/osi/include/osi/config.h index 4ca2c642a3..ce538282d8 100644 --- a/components/bt/common/osi/include/osi/config.h +++ b/components/bt/common/osi/include/osi/config.h @@ -99,6 +99,11 @@ void config_set_string(config_t *config, const char *section, const char *key, c // Neither |config| nor |section| may be NULL. bool config_remove_section(config_t *config, const char *section); +// Updates |section| to be the first section in |config|. Return true if |section| is in +// |config| and updated successfully, false otherwise. +// Neither |config| nor |section| may be NULL. +bool config_update_newest_section(config_t *config, const char *section); + // Removes one specific |key| residing in |section| of the |config|. Returns true // if the section and key were found and the key was removed, false otherwise. // None of |config|, |section|, or |key| may be NULL. diff --git a/components/bt/controller/esp32/Kconfig.in b/components/bt/controller/esp32/Kconfig.in index f9a505cf25..7254a6ae59 100644 --- a/components/bt/controller/esp32/Kconfig.in +++ b/components/bt/controller/esp32/Kconfig.in @@ -172,7 +172,7 @@ config BTDM_CTRL_PINNED_TO_CORE choice BTDM_CTRL_HCI_MODE_CHOICE prompt "HCI mode" help - Speicify HCI mode as VHCI or UART(H4) + Specify HCI mode as VHCI or UART(H4) config BTDM_CTRL_HCI_MODE_VHCI bool "VHCI" @@ -205,6 +205,11 @@ menu "HCI UART(H4) Options" help UART Baudrate for HCI. Please use standard baudrate. + config BTDM_CTRL_HCI_UART_FLOW_CTRL_EN + bool "Enable UART flow control" + depends on BTDM_CTRL_HCI_MODE_UART_H4 + default y + endmenu menu "MODEM SLEEP Options" @@ -351,7 +356,7 @@ config BTDM_SCAN_DUPL_CACHE_SIZE default 100 help Maximum number of devices which can be recorded in scan duplicate filter. - When the maximum amount of device in the filter is reached, the cache will be refreshed. + When the maximum amount of device in the filter is reached, the oldest device will be refreshed. config BTDM_SCAN_DUPL_CACHE_REFRESH_PERIOD int "Duplicate scan list refresh period (seconds)" @@ -393,6 +398,14 @@ config BTDM_CTRL_FULL_SCAN_SUPPORTED The full scan function is mainly used to provide BLE scan performance. This is required for scenes with high scan performance requirements, such as BLE Mesh scenes. +config BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX + bool "Disable active scan backoff" + default n + help + Disable active scan backoff. The bluetooth spec requires that scanners should run a backoff procedure to + minimize collision of scan request PDUs from nultiple scanners. If scan backoff is disabled, in active + scanning, scan request PDU will be sent every time when HW receives scannable ADV PDU. + config BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP bool "BLE adv report flow control supported" depends on (BTDM_CTRL_MODE_BTDM || BTDM_CTRL_MODE_BLE_ONLY) diff --git a/components/bt/controller/esp32/bt.c b/components/bt/controller/esp32/bt.c index ca923f4504..7523e5f47c 100644 --- a/components/bt/controller/esp32/bt.c +++ b/components/bt/controller/esp32/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -35,7 +35,7 @@ #include "soc/rtc.h" #include "soc/soc_memory_layout.h" #include "soc/dport_reg.h" -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #include "esp_timer.h" #if !CONFIG_FREERTOS_UNICORE #include "esp_ipc.h" @@ -89,7 +89,7 @@ do{\ } while(0) #define OSI_FUNCS_TIME_BLOCKING 0xffffffff -#define OSI_VERSION 0x00010004 +#define OSI_VERSION 0x00010005 #define OSI_MAGIC_VALUE 0xFADEBEAD /* Types definition @@ -176,6 +176,7 @@ struct osi_funcs_t { void (*_interrupt_l3_restore)(void); void *(* _customer_queue_create)(uint32_t queue_len, uint32_t item_size); int (* _coex_version_get)(unsigned int *major, unsigned int *minor, unsigned int *patch); + void (* _patch_apply)(void); uint32_t _magic; }; @@ -220,6 +221,8 @@ extern void bredr_sco_datapath_set(uint8_t data_path); extern void btdm_controller_scan_duplicate_list_clear(void); /* Shutdown */ extern void esp_bt_controller_shutdown(void); +extern void sdk_config_set_bt_pll_track_enable(bool enable); +extern void sdk_config_set_uart_flow_ctrl_enable(bool enable); extern char _bss_start_btdm; extern char _bss_end_btdm; @@ -230,16 +233,16 @@ extern uint32_t _data_end_btdm_rom; extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; -extern uint32_t _nimble_bss_start; -extern uint32_t _nimble_bss_end; -extern uint32_t _btdm_bss_start; -extern uint32_t _btdm_bss_end; +extern uint32_t _bt_controller_bss_start; +extern uint32_t _bt_controller_bss_end; extern uint32_t _bt_data_start; extern uint32_t _bt_data_end; -extern uint32_t _nimble_data_start; -extern uint32_t _nimble_data_end; -extern uint32_t _btdm_data_start; -extern uint32_t _btdm_data_end; +extern uint32_t _bt_controller_data_start; +extern uint32_t _bt_controller_data_end; + +extern void config_bt_funcs_reset(void); +extern void config_ble_funcs_reset(void); +extern void config_btdm_funcs_reset(void); /* Local Function Declare ********************************************************************* @@ -313,6 +316,7 @@ static void *customer_queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t i static void interrupt_l3_disable(void); static void interrupt_l3_restore(void); static void bt_controller_deinit_internal(void); +static void patch_apply(void); /* Local variable definition *************************************************************************** @@ -400,6 +404,7 @@ static const struct osi_funcs_t osi_funcs_ro = { ._customer_queue_create = NULL, #endif /* CONFIG_BTDM_CTRL_HLI */ ._coex_version_get = coex_version_get_wrapper, + ._patch_apply = patch_apply, ._magic = OSI_MAGIC_VALUE, }; @@ -751,7 +756,7 @@ static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block * @param item The message which will be send * @param hptw need do task yield or not * @return send success or not - * There is an issue here: When the queue is full, it may reture true but it send fail to the queue, sometimes. + * There is an issue here: When the queue is full, it may return true but it send fail to the queue, sometimes. * But in Bluetooth controller's isr, We don't care about the return value. * It only required tp send success when the queue is empty all the time. * So, this function meets the requirement. @@ -937,7 +942,7 @@ static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles) static void btdm_sleep_enter_phase2_wrapper(void) { if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) { - esp_phy_disable(); + esp_phy_disable(PHY_MODEM_BT); #ifdef CONFIG_PM_ENABLE if (s_pm_lock_acquired) { esp_pm_lock_release(s_pm_lock); @@ -945,7 +950,7 @@ static void btdm_sleep_enter_phase2_wrapper(void) } #endif } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) { - esp_phy_disable(); + esp_phy_disable(PHY_MODEM_BT); // pause bluetooth baseband periph_module_disable(PERIPH_BT_BASEBAND_MODULE); } @@ -961,7 +966,7 @@ static void btdm_sleep_exit_phase3_wrapper(void) #endif if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) { - esp_phy_enable(); + esp_phy_enable(PHY_MODEM_BT); btdm_check_and_init_bb(); #ifdef CONFIG_PM_ENABLE esp_timer_stop(s_btdm_slp_tmr); @@ -969,7 +974,7 @@ static void btdm_sleep_exit_phase3_wrapper(void) } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) { // resume bluetooth baseband periph_module_enable(PERIPH_BT_BASEBAND_MODULE); - esp_phy_enable(); + esp_phy_enable(PHY_MODEM_BT); } } @@ -1195,23 +1200,12 @@ static int coex_register_wifi_channel_change_callback_wrapper(void *cb) static int coex_version_get_wrapper(unsigned int *major, unsigned int *minor, unsigned int *patch) { #if CONFIG_SW_COEXIST_ENABLE - const char *ver_str = esp_coex_version_get(); - if (ver_str != NULL) { - unsigned int _major = 0, _minor = 0, _patch = 0; - if (sscanf(ver_str, "%u.%u.%u", &_major, &_minor, &_patch) != 3) { - return -1; - } - if (major != NULL) { - *major = _major; - } - if (minor != NULL) { - *minor = _minor; - } - if (patch != NULL) { - *patch = _patch; - } - return 0; - } + coex_version_t version; + ESP_ERROR_CHECK(coex_version_get_value(&version)); + *major = (unsigned int)version.major; + *minor = (unsigned int)version.minor; + *patch = (unsigned int)version.patch; + return 0; #endif return -1; } @@ -1283,7 +1277,45 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) return ret; } -esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) +typedef struct { + intptr_t start; + intptr_t end; + const char* name; +} bt_area_t; + + +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) +{ + esp_err_t ret = ESP_OK; + intptr_t mem_start = area->start; + intptr_t mem_end = area->end; + if (mem_start != mem_end) { + ESP_LOGD(BTDM_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + return ret; +} + +static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2) +{ + esp_err_t ret = ESP_OK; + + if (area1->end == area2->start) { + bt_area_t merged_area = { + .start = area1->start, + .end = area2->end, + .name = area1->name + }; + ret = esp_bt_mem_release_area(&merged_area); + } else { + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); + } + + return ret; +} + +static esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode) { bool update = true; intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL; @@ -1334,61 +1366,89 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) } } + return ESP_OK; +} + +esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) +{ + esp_err_t ret = ESP_OK; + + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } + if (mode == ESP_BT_MODE_BTDM) { - mem_start = (intptr_t)&_btdm_bss_start; - mem_end = (intptr_t)&_btdm_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release BTDM BSS [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)&_btdm_data_start; - mem_end = (intptr_t)&_btdm_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + + ret = esp_bt_mem_release_areas(&cont_data, &cont_bss); } - return ESP_OK; + + if (ret == ESP_OK) { + ret = esp_bt_controller_rom_mem_release(mode); + } + + return ret; } esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - int ret; - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; - ret = esp_bt_controller_mem_release(mode); - if (ret != ESP_OK) { - return ret; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; } + bt_area_t bss = { + .start = (intptr_t)&_bt_bss_start, + .end = (intptr_t)&_bt_bss_end, + .name = "BT BSS", + }; + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t data = { + .start = (intptr_t)&_bt_data_start, + .end = (intptr_t)&_bt_data_end, + .name = "BT Data", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + + /* + * Free data and BSS section for Bluetooth controller ROM code. + * Note that rom mem release must be performed before section _bt_data_start to _bt_data_end is released, + * otherwise `btdm_dram_available_region` will no longer be available when performing rom mem release and + * thus causing heap corruption. + */ + ret = esp_bt_controller_rom_mem_release(mode); + if (mode == ESP_BT_MODE_BTDM) { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_bt_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + /* Start by freeing Bluetooth BSS section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&bss, &cont_bss); } - mem_start = (intptr_t)&_nimble_bss_start; - mem_end = (intptr_t)&_nimble_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)&_nimble_data_start; - mem_end = (intptr_t)&_nimble_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); } } - return ESP_OK; + + return ret; } #if CONFIG_BTDM_CTRL_HLI @@ -1526,6 +1586,12 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE); #endif +#if CONFIG_BTDM_CTRL_HCI_UART_FLOW_CTRL_EN + sdk_config_set_uart_flow_ctrl_enable(true); +#else + sdk_config_set_uart_flow_ctrl_enable(false); +#endif + #ifdef CONFIG_PM_ENABLE if (!s_btdm_allow_light_sleep) { if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) { @@ -1641,11 +1707,23 @@ static void bt_shutdown(void) #else bt_controller_shutdown(NULL); #endif - esp_phy_disable(); + esp_phy_disable(PHY_MODEM_BT); return; } +static void patch_apply(void) +{ + config_btdm_funcs_reset(); + +#ifndef CONFIG_BTDM_CTRL_MODE_BLE_ONLY + config_bt_funcs_reset(); +#endif + +#ifndef CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY + config_ble_funcs_reset(); +#endif +} esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) { @@ -1667,7 +1745,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) esp_pm_lock_acquire(s_pm_lock); #endif - esp_phy_enable(); + esp_phy_enable(PHY_MODEM_BT); #if CONFIG_SW_COEXIST_ENABLE coex_enable(); @@ -1677,7 +1755,9 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) btdm_controller_enable_sleep(true); } - // inititalize bluetooth baseband + sdk_config_set_bt_pll_track_enable(true); + + // initialize bluetooth baseband btdm_check_and_init_bb(); ret = btdm_controller_enable(mode); @@ -1685,7 +1765,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif - esp_phy_disable(); + esp_phy_disable(PHY_MODEM_BT); #ifdef CONFIG_PM_ENABLE if (!s_btdm_allow_light_sleep) { esp_pm_lock_release(s_light_sleep_pm_lock); @@ -1725,7 +1805,7 @@ esp_err_t esp_bt_controller_disable(void) coex_disable(); #endif - esp_phy_disable(); + esp_phy_disable(PHY_MODEM_BT); btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; esp_unregister_shutdown_handler(bt_shutdown); @@ -1840,7 +1920,7 @@ esp_err_t esp_ble_scan_dupilcate_list_flush(void) /** * This function re-write controller's function, - * As coredump can not show paramerters in function which is in a .a file. + * As coredump can not show parameters in function which is in a .a file. * * After coredump fixing this issue, just delete this function. */ diff --git a/components/bt/controller/esp32c2/Kconfig.in b/components/bt/controller/esp32c2/Kconfig.in index fc0cdd9bb0..d05401c186 100644 --- a/components/bt/controller/esp32c2/Kconfig.in +++ b/components/bt/controller/esp32c2/Kconfig.in @@ -2,15 +2,15 @@ menu "HCI Config" choice BT_LE_HCI_INTERFACE - prompt "Select HCI interface" + prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM config BT_LE_HCI_INTERFACE_USE_RAM - bool "ram" + bool "VHCI" help Use RAM as HCI interface config BT_LE_HCI_INTERFACE_USE_UART - bool "uart" + bool "UART(H4)" help Use UART as HCI interface endchoice @@ -73,12 +73,26 @@ menu "HCI Config" UART_PARITY_ODD endchoice - config BT_LE_HCI_UART_TASK_STACK_SIZE - int "HCI uart task stack size" - depends on BT_LE_HCI_INTERFACE_USE_UART - default 1000 + config BT_LE_HCI_UART_RX_BUFFER_SIZE + int "The size of rx ring buffer memory" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 512 help - Set the size of uart task stack + The size of rx ring buffer memory + + config BT_LE_HCI_UART_TX_BUFFER_SIZE + int "The size of tx ring buffer memory" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 256 + help + The size of tx ring buffer memory + + config BT_LE_HCI_TRANS_TASK_STACK_SIZE + int "HCI transport task stack size" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 1024 + help + This configures stack size of hci transport task endmenu config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT @@ -147,7 +161,7 @@ if BT_LE_EXT_ADV Enable this option to start periodic advertisement. config BT_LE_PERIODIC_ADV_SYNC_TRANSFER - bool "Enable Transer Sync Events" + bool "Enable Transfer Sync Events" depends on BT_LE_ENABLE_PERIODIC_ADV default y help @@ -253,6 +267,72 @@ config BT_LE_CONTROLLER_TASK_STACK_SIZE help This configures stack size of NimBLE controller task +menuconfig BT_LE_CONTROLLER_LOG_ENABLED + bool "Controller log enable" + default n + help + Enable controller log + +config BT_LE_CONTROLLER_LOG_CTRL_ENABLED + bool "enable controller log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help + Enable controller log module + +config BT_LE_CONTROLLER_LOG_HCI_ENABLED + bool "enable HCI log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help + Enable hci log module + +config BT_LE_CONTROLLER_LOG_DUMP_ONLY + bool "Controller log dump mode only" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help + Only operate in dump mode + +config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + bool "Store ble controller logs to flash(Experimental)" + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Store ble controller logs to flash memory. + +config BT_LE_CONTROLLER_LOG_PARTITION_SIZE + int "size of ble controller log partition(Multiples of 4K)" + depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + +config BT_LE_LOG_CTRL_BUF1_SIZE + int "size of the first BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help + Configure the size of the first BLE controller LOG buffer. + +config BT_LE_LOG_CTRL_BUF2_SIZE + int "size of the second BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 1024 + help + Configure the size of the second BLE controller LOG buffer. + +config BT_LE_LOG_HCI_BUF_SIZE + int "size of the BLE HCI LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help + Configure the size of the BLE HCI LOG buffer. + config BT_LE_LL_RESOLV_LIST_SIZE int "BLE LL Resolving list size" range 1 5 @@ -301,7 +381,6 @@ config BT_LE_CRYPTO_STACK_MBEDTLS bool "Override TinyCrypt with mbedTLS for crypto computations" default y depends on !BT_NIMBLE_ENABLED - select MBEDTLS_ECP_RESTARTABLE select MBEDTLS_CMAC_C help Enable this option to choose mbedTLS instead of TinyCrypt for crypto @@ -345,7 +424,7 @@ config BT_LE_MAX_CONNECTIONS choice BT_LE_COEX_PHY_CODED_TX_RX_TLIM prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection" default BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS - depends on !BT_NIMBLE_ENABLED + depends on ESP_COEX_SW_COEXIST_ENABLE help When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to better avoid dramatic performance deterioration of Wi-Fi. @@ -363,7 +442,7 @@ endchoice config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF int - depends on !BT_NIMBLE_ENABLED + default 0 if !ESP_COEX_SW_COEXIST_ENABLE default 1 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN default 0 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS @@ -373,19 +452,24 @@ config BT_LE_SLEEP_ENABLE help Enable BLE sleep -choice BT_LE_WAKEUP_SOURCE - prompt "BLE light sleep wakeup source" - depends on BT_LE_SLEEP_ENABLE - default BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - config BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - bool "Use ESP timer to wakeup CPU" +choice BT_LE_LP_CLK_SRC + prompt "BLE low power clock source" + default BT_LE_LP_CLK_SRC_MAIN_XTAL + config BT_LE_LP_CLK_SRC_MAIN_XTAL + bool "Use main XTAL as RTC clock source" help - Use esp timer to wakeup CPU + User main XTAL as RTC clock source. + This option is recommended if external 32.768k XTAL is not available. + Using the external 32.768 kHz XTAL will have lower current consumption + in light sleep compared to using the main XTAL. - config BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - bool "Use BLE rtc timer to wakeup CPU" + config BT_LE_LP_CLK_SRC_DEFAULT + bool "Use system RTC slow clock source" help - Use BLE rtc timer to wakeup CPU + Use the same slow clock source as system RTC + Using any clock source other than external 32.768 kHz XTAL at pin0 supports only + legacy ADV and SCAN due to low clock accuracy. + endchoice config BT_LE_USE_ESP_TIMER @@ -394,3 +478,141 @@ config BT_LE_USE_ESP_TIMER default y help Set this option to use Esp Timer which has higher priority timer instead of FreeRTOS timer + +config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP + bool "BLE adv report flow control supported" + depends on BT_LE_ROLE_OBSERVER_ENABLE + default y + help + The function is mainly used to enable flow control for advertising reports. When it is enabled, + advertising reports will be discarded by the controller if the number of unprocessed advertising + reports exceeds the size of BLE adv report flow control. + +config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM + int "BLE adv report flow control number" + depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP + range 50 1000 + default 100 + help + The number of unprocessed advertising report that bluetooth host can save.If you set + `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost. + If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a + lot of adv packets and this may cause system memory run out. For example, if you set + it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set + `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv + packets as fast as possible, otherwise it will cause adv packets lost. + +config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD + int "BLE adv lost event threshold value" + depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP + range 1 1000 + default 20 + help + When adv report flow control is enabled, The ADV lost event will be generated when the number + of ADV packets lost in the controller reaches this threshold. It is better to set a larger value. + If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it + may cause adv packets lost more. +config BT_LE_RELEASE_IRAM_SUPPORTED + bool + default y + +config BT_LE_TX_CCA_ENABLED + bool "Enable TX CCA feature" + default n + help + Enable CCA feature to cancel sending the packet if the signal power is stronger than CCA threshold. + +config BT_LE_CCA_RSSI_THRESH + int "CCA RSSI threshold value" + depends on BT_LE_TX_CCA_ENABLED + range 20 100 + default 20 + help + Power threshold of CCA in unit of -1 dBm. + +config BT_LE_ROLE_CENTROL_ENABLE + bool "Enable BLE Centrol role function" + depends on !BT_NIMBLE_ENABLED + default y + help + Enable centrol role function. + +config BT_LE_ROLE_PERIPHERAL_ENABLE + bool "Enable BLE Peripheral role function" + depends on !BT_NIMBLE_ENABLED + default y + help + Enable Peripheral role function. + +config BT_LE_ROLE_BROADCASTER_ENABLE + bool "Enable BLE Broadcaster role function" + depends on !BT_NIMBLE_ENABLED + default y + help + Enable broadcaster role function. + +config BT_LE_ROLE_OBSERVER_ENABLE + bool "Enable BLE Observer role function" + depends on !BT_NIMBLE_ENABLED + default y + help + Enable observer role function. + +choice BT_LE_DFT_TX_POWER_LEVEL_DBM + prompt "BLE default Tx power level(dBm)" + default BT_LE_DFT_TX_POWER_LEVEL_P9 + help + Specify default Tx power level(dBm). + config BT_LE_DFT_TX_POWER_LEVEL_N24 + bool "-24dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N21 + bool "-21dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N18 + bool "-18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N15 + bool "-15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N12 + bool "-12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N9 + bool "-9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N6 + bool "-6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N3 + bool "-3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N0 + bool "0dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P3 + bool "+3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P6 + bool "+6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P9 + bool "+9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P12 + bool "+12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P15 + bool "+15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P18 + bool "+18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" +endchoice + +config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF + int + default -24 if BT_LE_DFT_TX_POWER_LEVEL_N24 + default -21 if BT_LE_DFT_TX_POWER_LEVEL_N21 + default -18 if BT_LE_DFT_TX_POWER_LEVEL_N18 + default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15 + default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12 + default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9 + default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6 + default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3 + default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0 + default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3 + default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6 + default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9 + default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12 + default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15 + default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18 + default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20 + default 0 diff --git a/components/bt/controller/esp32c2/bt.c b/components/bt/controller/esp32c2/bt.c index 45d0628dcb..3c5bf0b1b2 100644 --- a/components/bt/controller/esp32c2/bt.c +++ b/components/bt/controller/esp32c2/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,10 @@ #include "sdkconfig.h" +#if CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port.h" +#endif // CONFIG_BT_NIMBLE_ENABLED + #include "nimble/nimble_port_freertos.h" #ifdef ESP_PLATFORM @@ -24,11 +27,11 @@ #endif #if CONFIG_SW_COEXIST_ENABLE -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #endif #include "nimble/nimble_npl_os.h" -#include "nimble/ble_hci_trans.h" +#include "esp_hci_transport.h" #include "os/endian.h" #include "esp_bt.h" @@ -39,23 +42,25 @@ #include "soc/syscon_reg.h" #include "soc/modem_clkrst_reg.h" #include "esp_private/periph_ctrl.h" -#include "hci_uart.h" #include "bt_osi_mem.h" -#ifdef CONFIG_BT_BLUEDROID_ENABLED -#include "hci/hci_hal.h" -#endif +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#include "esp_private/sleep_modem.h" +#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_private/periph_ctrl.h" +#include "esp_private/esp_clk.h" #include "esp_sleep.h" #include "soc/syscon_reg.h" #include "soc/dport_access.h" #include "hal/efuse_ll.h" +#include "soc/rtc.h" + /* Macro definition ************************************************************************ */ @@ -68,16 +73,14 @@ #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf - -#ifdef CONFIG_BT_BLUEDROID_ENABLED -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -#define ACL_DATA_MBUF_LEADINGSPCAE 4 -#endif +typedef enum ble_rtc_slow_clk_src { + BT_SLOW_CLK_SRC_MAIN_XTAL, + BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0, +} ble_rtc_slow_clk_src_t; /* Types definition ************************************************************************ */ - struct osi_coex_funcs_t { uint32_t _magic; uint32_t _version; @@ -93,12 +96,12 @@ struct ext_funcs_t { int (*_esp_intr_free)(void **ret_handle); void *(* _malloc)(size_t size); void (*_free)(void *p); - void (*_hal_uart_start_tx)(int); - int (*_hal_uart_init_cbs)(int, hci_uart_tx_char, hci_uart_tx_done, hci_uart_rx_char, void *); - int (*_hal_uart_config)(int, int32_t, uint8_t, uint8_t, uart_parity_t, uart_hw_flowcontrol_t); - int (*_hal_uart_close)(int); - void (*_hal_uart_blocking_tx)(int, uint8_t); - int (*_hal_uart_init)(int, void *); + void (*_rsv1)(int); + int (*_rsv2)(int, int (*)(void *arg), int (*)(void *arg, uint8_t byte), int (*)(void *arg, uint8_t byte), void *); + int (*_rsv3)(int, int32_t, uint8_t, uint8_t, int, int); + int (*_rsv4)(int); + void (*_rsv5)(int, uint8_t); + int (*_rsv6)(int, void *); int (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); void (* _task_delete)(void *task_handle); void (*_osi_assert)(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2); @@ -110,13 +113,21 @@ struct ext_funcs_t { uint32_t magic; }; +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* External functions or variables ************************************************************************ */ - extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); extern int ble_controller_init(esp_bt_controller_config_t *cfg); +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +extern int ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int ble_log_deinit_async(void); +extern void ble_log_async_output_dump_all(bool output); +extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED extern int ble_controller_deinit(void); extern int ble_controller_enable(uint8_t mode); extern int ble_controller_disable(void); @@ -132,6 +143,9 @@ extern uint32_t r_os_cputime_get32(void); extern uint32_t r_os_cputime_ticks_to_usecs(uint32_t ticks); extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, void *w_arg, uint32_t us_to_enabled); extern void r_ble_rtc_wake_up_state_clr(void); +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +extern void esp_ble_set_wakeup_overhead(uint32_t overhead); +#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ extern int os_msys_init(void); extern void os_msys_buf_free(void); extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, @@ -142,14 +156,21 @@ extern int ble_txpwr_set(esp_ble_enhanced_power_type_t power_type, uint16_t hand extern int ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle); extern int ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info); extern void bt_track_pll_cap(void); +extern char *ble_controller_get_compile_version(void); +extern const char *r_ble_controller_get_rom_compile_version(void); +#if CONFIG_BT_RELEASE_IRAM +extern uint32_t _iram_bt_text_start; +extern uint32_t _bss_bt_end; +#endif + extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; -extern uint32_t _nimble_bss_start; -extern uint32_t _nimble_bss_end; -extern uint32_t _nimble_data_start; -extern uint32_t _nimble_data_end; +extern uint32_t _bt_controller_bss_start; +extern uint32_t _bt_controller_bss_end; extern uint32_t _bt_data_start; extern uint32_t _bt_data_end; +extern uint32_t _bt_controller_data_start; +extern uint32_t _bt_controller_data_end; /* Local Function Declaration ********************************************************************* @@ -158,17 +179,8 @@ static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status); static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no); -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); -static int hci_uart_config_wrapper(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); -static int hci_uart_close_wrapper(int uart_no); -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data); -static int hci_uart_init_wrapper(int uart_no, void *cfg); -#endif -static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in); +static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, + void *arg, void **ret_handle_in); static int esp_intr_free_wrapper(void **ret_handle); static void osi_assert_wrapper(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2); static uint32_t osi_random_wrapper(void); @@ -176,30 +188,260 @@ static void esp_reset_rpa_moudle(void); static int esp_ecc_gen_key_pair(uint8_t *pub, uint8_t *priv); static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** */ - /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; +enum log_out_mode { + LOG_DUMP_MEMORY, + LOG_ASYNC_OUT, + LOG_STORAGE_TO_FLASH, +}; + +bool log_is_inited = false; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY +uint8_t log_output_mode = LOG_DUMP_MEMORY; +#else +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; +#else +uint8_t log_output_mode = LOG_ASYNC_OUT; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + +void esp_bt_log_output_mode_set(uint8_t output_mode) +{ + log_output_mode = output_mode; +} + +uint8_t esp_bt_log_output_mode_get(void) +{ + return log_output_mode; +} + +esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) +{ + esp_err_t ret = ESP_OK; + interface_func_t bt_controller_log_interface; + bt_controller_log_interface = esp_bt_controller_log_interface; + bool task_create; + uint8_t buffers = 0; + + if (log_is_inited) { + return ret; + } + +#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + + switch (log_output_mode) { + case LOG_DUMP_MEMORY: + task_create = false; + break; + case LOG_ASYNC_OUT: + case LOG_STORAGE_TO_FLASH: + task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + if (log_output_mode == LOG_STORAGE_TO_FLASH) { + esp_bt_ctrl_log_partition_get_and_erase_first_block(); + } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + break; + default: + assert(0); + } + + ret = ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); + if (ret == ESP_OK) { + log_is_inited = true; + } + + return ret; +} + +void esp_bt_ontroller_log_deinit(void) +{ + ble_log_deinit_async(); + log_is_inited = false; +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#include "esp_partition.h" +#include "hal/wdt_hal.h" + +#define MAX_STORAGE_SIZE (CONFIG_BT_LE_CONTROLLER_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" + +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; + +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + assert(log_partition != NULL); + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + ble_log_async_output_dump_all(true); + stop_write = true; + esp_bt_ontroller_log_deinit(); + portEXIT_CRITICAL_SAFE(&spinlock); + + buffer = (const uint8_t *)mapped_ptr; + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + vTaskDelay(2); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + esp_rom_printf(":DUMP_END]\r\n"); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(log_output_mode); + assert(err == ESP_OK); + +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +{ + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + } else { + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); + } + + if (end) { + esp_rom_printf("\n"); + } + } +} + +void esp_ble_controller_log_dump_all(bool output) +{ + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_read_ctrl_log_from_flash(output); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + BT_ASSERT_PRINT("\r\n[DUMP_START:"); + ble_log_async_output_dump_all(output); + BT_ASSERT_PRINT(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + } +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* This variable tells if BLE is running */ static bool s_ble_active = false; #ifdef CONFIG_PM_ENABLE static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; #define BTDM_MIN_TIMER_UNCERTAINTY_US (200) -#endif /* #ifdef CONFIG_PM_ENABLE */ +#endif // CONFIG_PM_ENABLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER #define BLE_RTC_DELAY_US (1800) -#endif - -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER -#define BLE_RTC_DELAY_US (0) -static void ble_sleep_timer_callback(void *arg); -static DRAM_ATTR esp_timer_handle_t s_ble_sleep_timer = NULL; -#endif - static const struct osi_coex_funcs_t s_osi_coex_funcs_ro = { ._magic = OSI_COEX_MAGIC_VALUE, @@ -216,14 +458,6 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, ._free = bt_osi_mem_free, -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART - ._hal_uart_start_tx = hci_uart_start_tx_wrapper, - ._hal_uart_init_cbs = hci_uart_init_cbs_wrapper, - ._hal_uart_config = hci_uart_config_wrapper, - ._hal_uart_close = hci_uart_close_wrapper, - ._hal_uart_blocking_tx = hci_uart_blocking_tx_wrapper, - ._hal_uart_init = hci_uart_init_wrapper, -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, @@ -231,7 +465,7 @@ struct ext_funcs_t ext_funcs_ro = { ._ecc_gen_key_pair = esp_ecc_gen_key_pair, ._ecc_gen_dh_key = esp_ecc_gen_dh_key, ._esp_reset_rpa_moudle = esp_reset_rpa_moudle, - ._esp_bt_track_pll_cap = bt_track_pll_cap, + ._esp_bt_track_pll_cap = NULL, .magic = EXT_FUNC_MAGIC_VALUE, }; @@ -241,9 +475,13 @@ static void IRAM_ATTR esp_reset_rpa_moudle(void) DPORT_CLEAR_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, BLE_RPA_REST_BIT); } -static void IRAM_ATTR osi_assert_wrapper(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2) +static void IRAM_ATTR osi_assert_wrapper(const uint32_t ln, const char *fn, + uint32_t param1, uint32_t param2) { BT_ASSERT_PRINT("BLE assert: line %d in function %s, param: 0x%x, 0x%x", ln, fn, param1, param2); +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED + esp_ble_controller_log_dump_all(true); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED assert(0); } @@ -256,94 +494,16 @@ static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status) { #if CONFIG_SW_COEXIST_ENABLE coex_schm_status_bit_set(type, status); -#endif +#endif // CONFIG_SW_COEXIST_ENABLE } static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) { #if CONFIG_SW_COEXIST_ENABLE coex_schm_status_bit_clear(type, status); -#endif -} -#ifdef CONFIG_BT_BLUEDROID_ENABLED - -bool esp_vhci_host_check_send_available(void) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return false; - } - return true; -} - -/** - * Allocates an mbuf for use by the nimble host. - */ -static struct os_mbuf *ble_hs_mbuf_gen_pkt(uint16_t leading_space) -{ - struct os_mbuf *om; - int rc; - - om = os_msys_get_pkthdr(0, 0); - if (om == NULL) { - return NULL; - } - - if (om->om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -/** - * Allocates an mbuf suitable for an HCI ACL data packet. - * - * @return An empty mbuf on success; null on memory - * exhaustion. - */ -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } - -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; +#endif // CONFIG_SW_COEXIST_ENABLE } -#endif static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { return (uint32_t)xTaskCreatePinnedToCore(task_func, name, stack_depth, param, prio, task_handle, (core_id < portNUM_PROCESSORS ? core_id : tskNO_AFFINITY)); @@ -373,55 +533,6 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) -{ - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); - return rc; -} - - -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl) -{ - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - return rc; -} - -static int hci_uart_close_wrapper(int uart_no) -{ - int rc = -1; - rc = hci_uart_close(uart_no); - return rc; -} - -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) -{ - //This function is nowhere to use. -} - -static int hci_uart_init_wrapper(int uart_no, void *cfg) -{ - //This function is nowhere to use. - return 0; -} - -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; -} - static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) { int rc = esp_intr_alloc(source, flags | ESP_INTR_FLAG_IRAM, handler, arg, (intr_handle_t *)ret_handle_in); @@ -436,43 +547,23 @@ static int esp_intr_free_wrapper(void **ret_handle) return rc; } +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +void sleep_modem_light_sleep_overhead_set(uint32_t overhead) +{ + esp_ble_set_wakeup_overhead(overhead); +} +#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ + IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) { if (!s_ble_active) { return; } #ifdef CONFIG_PM_ENABLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - uint32_t delta_tick; - uint32_t us_to_sleep; - uint32_t sleep_tick; - uint32_t tick_invalid = *(uint32_t*)(arg); - assert(arg != NULL); - if (!tick_invalid) { - sleep_tick = r_os_cputime_get32(); - // start a timer to wake up and acquire the pm_lock before modem_sleep awakes - delta_tick = enable_tick - sleep_tick; - if (delta_tick & 0x80000000) { - return; - } - us_to_sleep = r_os_cputime_ticks_to_usecs(delta_tick); - if (us_to_sleep <= BTDM_MIN_TIMER_UNCERTAINTY_US) { - return; - } - esp_err_t err = esp_timer_start_once(s_ble_sleep_timer, us_to_sleep - BTDM_MIN_TIMER_UNCERTAINTY_US); - if (err != ESP_OK) { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ESP timer start failed\n"); - return; - } - } -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER r_ble_rtc_wake_up_state_clr(); -#endif esp_pm_lock_release(s_pm_lock); #endif // CONFIG_PM_ENABLE - esp_phy_disable(); + esp_phy_disable(PHY_MODEM_BT); s_ble_active = false; } @@ -481,7 +572,7 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) if (s_ble_active) { return; } - esp_phy_enable(); + esp_phy_enable(PHY_MODEM_BT); // need to check if need to call pm lock here #ifdef CONFIG_PM_ENABLE esp_pm_lock_acquire(s_pm_lock); @@ -489,17 +580,7 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) s_ble_active = true; } -#ifdef CONFIG_PM_ENABLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER -static void ble_sleep_timer_callback(void * arg) -{ - -} - -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER -#endif // CONFIG_PM_ENABLE - -esp_err_t controller_sleep_init(void) +esp_err_t controller_sleep_init(ble_rtc_slow_clk_src_t slow_clk_src) { esp_err_t rc = 0; #ifdef CONFIG_BT_LE_SLEEP_ENABLE @@ -507,7 +588,11 @@ esp_err_t controller_sleep_init(void) r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, 500 + BLE_RTC_DELAY_US); #ifdef CONFIG_PM_ENABLE - esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON); + if (slow_clk_src == BT_SLOW_CLK_SRC_MAIN_XTAL) { + esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON); + } else { + esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_AUTO); + } #endif // CONFIG_PM_ENABLE #endif // CONFIG_BT_LE_SLEEP_ENABLE @@ -518,107 +603,115 @@ esp_err_t controller_sleep_init(void) if (rc != ESP_OK) { goto error; } - esp_pm_lock_acquire(s_pm_lock); -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - esp_timer_create_args_t create_args = { - .callback = ble_sleep_timer_callback, - .arg = NULL, - .name = "btSlp" - }; - rc = esp_timer_create(&create_args, &s_ble_sleep_timer); - if (rc != ESP_OK) { - goto error; - } - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is ESP timer"); -#endif //CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE esp_sleep_enable_bt_wakeup(); ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer"); -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER + rc = esp_pm_register_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); + if (rc != ESP_OK) { + goto error; + } +#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE return rc; error: +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE + esp_sleep_disable_bt_wakeup(); + esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); +#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ /*lock should release first and then delete*/ if (s_pm_lock != NULL) { - esp_pm_lock_release(s_pm_lock); esp_pm_lock_delete(s_pm_lock); s_pm_lock = NULL; } -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - if (s_ble_sleep_timer != NULL) { - esp_timer_stop(s_ble_sleep_timer); - esp_timer_delete(s_ble_sleep_timer); - s_ble_sleep_timer = NULL; - } -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - esp_sleep_disable_bt_wakeup(); -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - #endif //CONFIG_PM_ENABLE return rc; } void controller_sleep_deinit(void) { -#ifdef CONFIG_PM_ENABLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER +#ifdef CONFIG_FREERTOS_USE_TICKLESS_IDLE r_ble_rtc_wake_up_state_clr(); esp_sleep_disable_bt_wakeup(); -#endif //CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_AUTO); - + esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); +#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE +#ifdef CONFIG_PM_ENABLE /*lock should release first and then delete*/ - if (s_ble_active) { - esp_pm_lock_release(s_pm_lock); - } - esp_pm_lock_delete(s_pm_lock); s_pm_lock = NULL; -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - if (s_ble_sleep_timer != NULL) { - esp_timer_stop(s_ble_sleep_timer); - esp_timer_delete(s_ble_sleep_timer); - s_ble_sleep_timer = NULL; - } -#endif //CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER #endif //CONFIG_PM_ENABLE } -void ble_rtc_clk_init(void) +static void esp_bt_rtc_slow_clk_select(ble_rtc_slow_clk_src_t slow_clk_src) { - // modem_clkrst_reg - // LP_TIMER_SEL_XTAL32K -> 0 - // LP_TIMER_SEL_XTAL -> 1 - // LP_TIMER_SEL_8M -> 0 - // LP_TIMER_SEL_RTC_SLOW -> 0 - SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S); - SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S); - SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_8M_S); - SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_RTC_SLOW_S); - + /* Select slow clock source for BT momdule */ + switch (slow_clk_src) { + case BT_SLOW_CLK_SRC_MAIN_XTAL: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_8M_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_RTC_SLOW_S); #ifdef CONFIG_XTAL_FREQ_26 - // LP_TIMER_CLK_DIV_NUM -> 130 - SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 129, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 129, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); #else - // LP_TIMER_CLK_DIV_NUM -> 250 - SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 249, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 249, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); #endif // CONFIG_XTAL_FREQ_26 - - // MODEM_CLKRST_ETM_CLK_ACTIVE -> 1 - // MODEM_CLKRST_ETM_CLK_SEL -> 0 + break; + case BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source"); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_8M_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_RTC_SLOW_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 0, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); + break; + default: + ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported slow clock"); + assert(0); + break; + } SET_PERI_REG_BITS(MODEM_CLKRST_ETM_CLK_CONF_REG, 1, 1, MODEM_CLKRST_ETM_CLK_ACTIVE_S); SET_PERI_REG_BITS(MODEM_CLKRST_ETM_CLK_CONF_REG, 1, 0, MODEM_CLKRST_ETM_CLK_SEL_S); +} + +static ble_rtc_slow_clk_src_t ble_rtc_clk_init(esp_bt_controller_config_t *cfg) +{ + ble_rtc_slow_clk_src_t slow_clk_src; +#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL +#ifdef CONFIG_XTAL_FREQ_26 + cfg->rtc_freq = 40000; +#else + cfg->rtc_freq = 32000; +#endif // CONFIG_XTAL_FREQ_26 + slow_clk_src = BT_SLOW_CLK_SRC_MAIN_XTAL; +#else + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + cfg->rtc_freq = 32768; + slow_clk_src = BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); +#ifdef CONFIG_XTAL_FREQ_26 + cfg->rtc_freq = 40000; +#else + cfg->rtc_freq = 32000; +#endif // CONFIG_XTAL_FREQ_26 + slow_clk_src = BT_SLOW_CLK_SRC_MAIN_XTAL; + } +#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + esp_bt_rtc_slow_clk_select(slow_clk_src); + return slow_clk_src; } esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; + ble_rtc_slow_clk_src_t rtc_clk_src; + uint8_t hci_transport_mode; + memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); @@ -630,7 +723,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) return ESP_ERR_INVALID_ARG; } - ble_rtc_clk_init(); + rtc_clk_src = ble_rtc_clk_init(cfg); ret = esp_register_ext_funcs(&ext_funcs_ro); if (ret != ESP_OK) { @@ -638,6 +731,15 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) return ret; } +#if DEFAULT_BT_LE_50_FEATURE_SUPPORT || DEFAULT_BT_LE_ROLE_CENTROL || DEFAULT_BT_LE_ROLE_OBSERVER + extern int esp_ble_rom_func_ptr_init_all(void); + esp_ble_rom_func_ptr_init_all(); +#else + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Init only legacy adv and slave function"); + extern int esp_ble_rom_func_ptr_init_legacy_adv_and_slave(void); + esp_ble_rom_func_ptr_init_legacy_adv_and_slave(); +#endif + /* Initialize the function pointers for OS porting */ npl_freertos_funcs_init(); struct npl_funcs_t *p_npl_funcs = npl_freertos_funcs_get(); @@ -675,18 +777,12 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif esp_phy_modem_init(); periph_module_enable(PERIPH_BT_MODULE); - - // init phy - esp_phy_enable(); - s_ble_active = true; - - // init bb - bt_bb_v2_init_cmplx(1); + periph_module_reset(PERIPH_BT_MODULE); if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "osi coex funcs reg failed"); ret = ESP_ERR_INVALID_ARG; - goto free_controller; + goto modem_deint; } #if CONFIG_SW_COEXIST_ENABLE @@ -695,10 +791,21 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ret = ble_controller_init(cfg); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_init failed %d", ret); - goto free_controller; + goto modem_deint; } - ret = controller_sleep_init(); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble rom commit:[%s]", r_ble_controller_get_rom_compile_version()); + +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED + ret = esp_bt_controller_log_init(log_output_mode); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); + goto controller_init_err; + } +#endif // CONFIG_BT_CONTROLLER_LOG_ENABLED + + ret = controller_sleep_init(rtc_clk_src); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "controller_sleep_init failed %d", ret); goto free_controller; @@ -707,20 +814,37 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) uint8_t mac[6]; ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + swap_in_place(mac, 6); esp_ble_ll_set_public_addr(mac); ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +controller_init_err: + esp_bt_ontroller_log_deinit(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED ble_controller_deinit(); - esp_phy_disable(); +modem_deint: esp_phy_modem_deinit(); + periph_module_disable(PERIPH_BT_MODULE); #if CONFIG_BT_NIMBLE_ENABLED ble_npl_eventq_deinit(nimble_port_get_dflt_eventq()); #endif // CONFIG_BT_NIMBLE_ENABLED @@ -740,15 +864,16 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); - if (s_ble_active) { - esp_phy_disable(); - s_ble_active = false; - } - +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED + esp_bt_ontroller_log_deinit(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED ble_controller_deinit(); + periph_module_disable(PERIPH_BT_MODULE); + #if CONFIG_BT_NIMBLE_ENABLED /* De-initialize default event queue */ ble_npl_eventq_deinit(nimble_port_get_dflt_eventq()); @@ -783,6 +908,17 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_FAIL; } + if (!s_ble_active) { +#if CONFIG_PM_ENABLE + esp_pm_lock_acquire(s_pm_lock); +#endif // CONFIG_PM_ENABLE + // init phy + esp_phy_enable(PHY_MODEM_BT); + s_ble_active = true; + } + // init bb + bt_bb_v2_init_cmplx(1); + #if CONFIG_SW_COEXIST_ENABLE coex_enable(); #endif @@ -798,6 +934,13 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif + if (s_ble_active) { + esp_phy_disable(PHY_MODEM_BT); +#if CONFIG_PM_ENABLE + esp_pm_lock_release(s_pm_lock); +#endif // CONFIG_PM_ENABLE + s_ble_active = false; + } return ret; } @@ -810,6 +953,14 @@ esp_err_t esp_bt_controller_disable(void) if (ble_controller_disable() != 0) { return ESP_FAIL; } + + if (s_ble_active) { + esp_phy_disable(PHY_MODEM_BT); +#if CONFIG_PM_ENABLE + esp_pm_lock_release(s_pm_lock); +#endif // CONFIG_PM_ENABLE + s_ble_active = false; + } #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif @@ -836,41 +987,108 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) return ret; } +typedef struct { + intptr_t start; + intptr_t end; + const char* name; +} bt_area_t; + +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) +{ + esp_err_t ret = ESP_OK; + intptr_t mem_start = area->start; + intptr_t mem_end = area->end; + if (mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + return ret; +} + +#ifndef CONFIG_BT_RELEASE_IRAM +static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2) +{ + esp_err_t ret = ESP_OK; + + if(area1->end == area2->start) { + bt_area_t merged_area = { + .start = area1->start, + .end = area2->end, + .name = area1->name + }; + ret = esp_bt_mem_release_area(&merged_area); + } else { + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); + } + + return ret; +} +#endif + esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - intptr_t mem_start, mem_end; - - if (mode & ESP_BT_MODE_BLE) { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + esp_err_t ret = ESP_OK; - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_bt_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } +#if CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT + /* Release Bluetooth text section and merge Bluetooth data, bss & text into a large free heap + * region when esp_bt_mem_release is called, total saving ~21kB or more of IRAM. ESP32-C2 has + * only 3 configurable PMP entries available, rest of them are hard-coded. We cannot split the + * memory into 3 different regions (IRAM, BLE-IRAM, DRAM). So `ESP_SYSTEM_PMP_IDRAM_SPLIT` needs + * to be disabled. + */ + #error "ESP_SYSTEM_PMP_IDRAM_SPLIT should be disabled to allow BT to be released" +#endif // CONFIG_BT_RELEASE_IRAM && CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT - mem_start = (intptr_t)&_nimble_bss_start; - mem_end = (intptr_t)&_nimble_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } - mem_start = (intptr_t)&_nimble_data_start; - mem_end = (intptr_t)&_nimble_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x]", mem_start, mem_end); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if ((mode & ESP_BT_MODE_BLE) == 0) { + return ret; } - return ESP_OK; +#if CONFIG_BT_RELEASE_IRAM + bt_area_t merged_region = { + .start = (intptr_t)MAP_IRAM_TO_DRAM((intptr_t)&_iram_bt_text_start), + .end = (intptr_t)&_bss_bt_end, + .name = "BT Text, BSS and Data" + }; + ret = esp_bt_mem_release_area(&merged_region); +#else + bt_area_t bss = { + .start = (intptr_t)&_bt_bss_start, + .end = (intptr_t)&_bt_bss_end, + .name = "BT BSS", + }; + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t data = { + .start = (intptr_t)&_bt_data_start, + .end = (intptr_t)&_bt_data_end, + .name = "BT Data", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + + /* Start by freeing Bluetooth BSS section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&bss, &cont_bss); + } + + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); + } +#endif + + return ret; } @@ -1000,14 +1218,11 @@ uint8_t esp_ble_get_chip_rev_version(void) return efuse_ll_get_chip_wafer_version_minor(); } - -#if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED == true) - +#if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) +#if CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #define BLE_SM_KEY_ERR 0x17 - #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS #include "mbedtls/aes.h" - #if CONFIG_BT_LE_SM_SC #include "mbedtls/cipher.h" #include "mbedtls/entropy.h" @@ -1015,7 +1230,9 @@ uint8_t esp_ble_get_chip_rev_version(void) #include "mbedtls/cmac.h" #include "mbedtls/ecdh.h" #include "mbedtls/ecp.h" -#endif + +static mbedtls_ecp_keypair keypair; +#endif // CONFIG_BT_LE_SM_SC #else #include "tinycrypt/aes.h" @@ -1025,15 +1242,15 @@ uint8_t esp_ble_get_chip_rev_version(void) #if CONFIG_BT_LE_SM_SC #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" -#endif - -#endif +#endif // CONFIG_BT_LE_SM_SC +#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS -#if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS -#if CONFIG_BT_LE_SM_SC -static mbedtls_ecp_keypair keypair; -#endif -#endif +/* Based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */ +static const uint8_t ble_sm_alg_dbg_priv_key[32] = { + 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, + 0xd2, 0x10, 0x3f, 0x50, 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, + 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd +}; int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey) @@ -1080,8 +1297,7 @@ int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_ } /* Set PRNG */ - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0)) != 0) { + if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) { goto exit; } @@ -1125,19 +1341,12 @@ int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_ if (rc == TC_CRYPTO_FAIL) { return BLE_SM_KEY_ERR; } -#endif +#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS swap_buf(out_dhkey, dh, 32); return 0; } -/* based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */ -static const uint8_t ble_sm_alg_dbg_priv_key[32] = { - 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, - 0xd2, 0x10, 0x3f, 0x50, 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, - 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd -}; - #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) { @@ -1183,7 +1392,7 @@ static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) return 0; } -#endif +#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS /** * pub: 64 bytes @@ -1199,7 +1408,6 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) uint8_t pk[64]; do { - #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS if (mbedtls_gen_keypair(pk, priv) != 0) { return BLE_SM_KEY_ERR; @@ -1208,17 +1416,16 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) if (uECC_make_key(pk, priv, &curve_secp256r1) != TC_CRYPTO_SUCCESS) { return BLE_SM_KEY_ERR; } -#endif - +#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS /* Make sure generated key isn't debug key. */ } while (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0); swap_buf(pub, pk, 32); swap_buf(&pub[32], &pk[32], 32); swap_in_place(priv, 32); -#endif - +#endif // CONFIG_BT_LE_SM_SC_DEBUG_KEYS return 0; } -#endif +#endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC +#endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) diff --git a/components/bt/include/esp32c2/include/esp_bt_cfg.h b/components/bt/controller/esp32c2/esp_bt_cfg.h similarity index 71% rename from components/bt/include/esp32c2/include/esp_bt_cfg.h rename to components/bt/controller/esp32c2/esp_bt_cfg.h index 814ec9d4e5..456ddcf9a8 100644 --- a/components/bt/include/esp32c2/include/esp_bt_cfg.h +++ b/components/bt/controller/esp32c2/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,7 +28,6 @@ extern "C" { #else #define BLE_LL_SCAN_PHY_NUMBER_N (1) #endif - #define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST MYNEWT_VAL(BLE_MAX_PERIODIC_ADVERTISER_LIST) #define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS) #define DEFAULT_BT_LE_MAX_CONNECTIONS MYNEWT_VAL(BLE_MAX_CONNECTIONS) @@ -40,8 +39,16 @@ extern "C" { #define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE) #define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT) - #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EFF + #if defined(CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT) + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) + #else + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) + #endif + #define DEFAULT_BT_LE_ROLE_OBSERVER MYNEWT_VAL(BLE_ROLE_OBSERVER) + #define DEFAULT_BT_LE_ROLE_CENTROL MYNEWT_VAL(BLE_ROLE_CENTRAL) + #define DEFAULT_BT_LE_ROLE_PERIPHERAL MYNEWT_VAL(BLE_ROLE_PERIPHERAL) + #define DEFAULT_BT_LE_ROLE_BROADCASTER MYNEWT_VAL(BLE_ROLE_BROADCASTER) #else #if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY @@ -53,13 +60,13 @@ extern "C" { #if defined(CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST) #define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST) #else - #define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (5) + #define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST (0) #endif #if defined(CONFIG_BT_LE_MAX_PERIODIC_SYNCS) #define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (CONFIG_BT_LE_MAX_PERIODIC_SYNCS) #else - #define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (1) + #define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS (0) #endif #if defined(CONFIG_BT_LE_MAX_CONNECTIONS) @@ -115,12 +122,52 @@ extern "C" { #else #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8) #endif + #if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT) + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) + #else + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) + #endif - #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF + #if defined(CONFIG_BT_LE_ROLE_CENTROL_ENABLE) + #define DEFAULT_BT_LE_ROLE_CENTROL (1) + #else + #define DEFAULT_BT_LE_ROLE_CENTROL (0) + #endif -#endif + #if defined(CONFIG_BT_LE_ROLE_PERIPHERAL_ENABLE) + #define DEFAULT_BT_LE_ROLE_PERIPHERAL (1) + #else + #define DEFAULT_BT_LE_ROLE_PERIPHERAL (0) + #endif + #if defined(CONFIG_BT_LE_ROLE_BROADCASTER_ENABLE) + #define DEFAULT_BT_LE_ROLE_BROADCASTER (1) + #else + #define DEFAULT_BT_LE_ROLE_BROADCASTER (0) + #endif + + #if defined(CONFIG_BT_LE_ROLE_OBSERVER_ENABLE) + #define DEFAULT_BT_LE_ROLE_OBSERVER (1) + #else + #define DEFAULT_BT_LE_ROLE_OBSERVER (0) + #endif + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif +#endif +#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART @@ -158,8 +205,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -168,8 +213,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ @@ -198,7 +241,7 @@ extern "C" { #define RTC_FREQ_N (32000) /* in Hz */ #endif // CONFIG_XTAL_FREQ_26 -#define BLE_LL_TX_PWR_DBM_N (9) +#define BLE_LL_TX_PWR_DBM_N (CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF) #define RUN_BQB_TEST (0) diff --git a/components/bt/controller/esp32c3/Kconfig.in b/components/bt/controller/esp32c3/Kconfig.in index 98274a2236..059e71dab8 100644 --- a/components/bt/controller/esp32c3/Kconfig.in +++ b/components/bt/controller/esp32c3/Kconfig.in @@ -23,7 +23,7 @@ config BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB default 0 help BLE ACL buffer have two methods to be allocated. One is persistent allocating - (alloate when controller initialise, never free until controller de-initialise) + (allocate when controller initialise, never free until controller de-initialise) another is dynamically allocating (allocate before TX and free after TX). choice BT_CTRL_PINNED_TO_CORE_CHOICE @@ -72,21 +72,35 @@ config BT_CTRL_HCI_TL HCI mode as VHCI or UART(H4) config BT_CTRL_ADV_DUP_FILT_MAX - int "The maxinum number of 5.0 extend duplicate scan filter" + int "The maximum number of 5.0 extend duplicate scan filter" range 1 500 default 30 help - The maxinum number of suplicate scan filter + The maximum number of suplicate scan filter -config BT_CTRL_HW_CCA - bool "HW CCA check enable" - default n +choice BT_BLE_CCA_MODE + prompt "BLE CCA mode" + default BT_BLE_CCA_MODE_NONE help - It enables HW CCA feature in controller + Define BT BLE CCA mode + + config BT_BLE_CCA_MODE_NONE + bool "NONE" + config BT_BLE_CCA_MODE_HW + bool "Hardware" + config BT_BLE_CCA_MODE_SW + bool "Software" +endchoice + +config BT_BLE_CCA_MODE + int + default 0 if BT_BLE_CCA_MODE_NONE + default 1 if BT_BLE_CCA_MODE_HW + default 2 if BT_BLE_CCA_MODE_SW config BT_CTRL_HW_CCA_VAL int "CCA threshold value" - range 20 60 + range 20 100 default 20 help It is the threshold value of HW CCA, if the value is 30, it means CCA threshold is -30 dBm. @@ -265,20 +279,19 @@ choice BT_CTRL_SCAN_DUPL_TYPE config BT_CTRL_SCAN_DUPL_TYPE_DEVICE bool "Scan Duplicate By Device Address" help - This way is to use advertiser address filtering. The adv packet of the same address is only - allowed to be reported once + Advertising packets with the same address, address type, and advertising type are reported once. config BT_CTRL_SCAN_DUPL_TYPE_DATA bool "Scan Duplicate By Advertising Data" help - This way is to use advertising data filtering. All same advertising data only allow to be reported - once even though they are from different devices. + Advertising packets with identical advertising data, address type, and advertising type + are reported only once, even if they originate from different devices. config BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE bool "Scan Duplicate By Device Address And Advertising Data" help - This way is to use advertising data and device address filtering. All different adv packets with - the same address are allowed to be reported. + Advertising packets with the same address, advertising data, address type, + and advertising type are reported only once. endchoice config BT_CTRL_SCAN_DUPL_TYPE @@ -333,7 +346,7 @@ config BT_CTRL_MESH_DUPL_SCAN_CACHE_SIZE choice BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection" default BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS - depends on ESP_WIFI_SW_COEXIST_ENABLE + depends on ESP_COEX_SW_COEXIST_ENABLE help When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to better avoid dramatic performance deterioration of Wi-Fi. @@ -351,7 +364,7 @@ endchoice config BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF int - default 0 if (!ESP_WIFI_SW_COEXIST_ENABLE) + default 0 if !ESP_COEX_SW_COEXIST_ENABLE default 1 if BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN default 0 if BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS @@ -454,3 +467,25 @@ config BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX Disable active scan backoff. The bluetooth spec requires that scanners should run a backoff procedure to minimize collision of scan request PDUs from nultiple scanners. If scan backoff is disabled, in active scanning, scan request PDU will be sent every time when HW receives scannable ADV PDU. + +config BT_BLE_ADV_DATA_LENGTH_ZERO_AUX + bool "Enable aux packet when ext adv data length is zero" + default n + help + When this option is enabled, auxiliary packets will be present in the events of + 'Non-Connectable and Non-Scannable' regardless of whether the advertising length is 0. + If this option is not enabled, auxiliary packets will only be present when the advertising length is not 0. + +config BT_CTRL_CHAN_ASS_EN + bool "Enable channel assessment" + default y + help + If this option is enabled, The Controller will records the communication quality + for each channel and then start a timer to check and update the channel map every 4 seconds. + +config BT_CTRL_LE_PING_EN + bool "Enable LE Ping procedure" + default y + help + If this option is disabled, The Controller will not start the LE authenticated payload timer. + This option is used for some compatibility problems related to LE ping procedure. diff --git a/components/bt/controller/esp32c3/bt.c b/components/bt/controller/esp32c3/bt.c index db9c2fbf1c..3f46e39c11 100644 --- a/components/bt/controller/esp32c3/bt.c +++ b/components/bt/controller/esp32c3/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,7 +34,7 @@ #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" #include "soc/soc_memory_layout.h" -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #include "esp_timer.h" #include "esp_sleep.h" #include "esp_rom_sys.h" @@ -66,6 +66,7 @@ // wakeup request sources enum { BTDM_ASYNC_WAKEUP_SRC_VHCI = 0, + BTDM_ASYNC_WAKEUP_REQ_COEX, BTDM_ASYNC_WAKEUP_SRC_DISA, BTDM_ASYNC_WAKEUP_SRC_TMR, BTDM_ASYNC_WAKEUP_SRC_MAX, @@ -75,12 +76,12 @@ enum { typedef union { struct { uint32_t enable : 1; // whether low power mode is required - uint32_t lpclk_sel : 2; // low power clock source + uint32_t lpclk_sel : 3; // low power clock source uint32_t mac_bb_pd : 1; // whether hardware(MAC, BB) force-power-down is required during sleep uint32_t wakeup_timer_required : 1; // whether system timer is needed uint32_t no_light_sleep : 1; // do not allow system to enter light sleep after bluetooth is enabled uint32_t main_xtal_pu : 1; // power up main XTAL - uint32_t reserved : 25; // reserved + uint32_t reserved : 24; // reserved }; uint32_t val; } btdm_lpcntl_t; @@ -112,9 +113,11 @@ do{\ } while(0) #define OSI_FUNCS_TIME_BLOCKING 0xffffffff -#define OSI_VERSION 0x00010006 +#define OSI_VERSION 0x00010009 #define OSI_MAGIC_VALUE 0xFADEBEAD +#define BLE_PWR_HDL_INVL 0xFFFF + /* Types definition ************************************************************************ */ @@ -139,15 +142,24 @@ typedef struct { typedef void (* osi_intr_handler)(void); +typedef struct { + int source; /*!< ISR source */ + int flags; /*!< ISR alloc flag */ + void (*fn)(void *); /*!< ISR function */ + void *arg; /*!< ISR function args*/ + intr_handle_t *handle; /*!< ISR handle */ + esp_err_t ret; +} btdm_isr_alloc_t; + /* OSI function */ struct osi_funcs_t { uint32_t _magic; uint32_t _version; - void (*_interrupt_set)(int cpu_no, int intr_source, int interrupt_no, int interrpt_prio); - void (*_interrupt_clear)(int interrupt_source, int interrupt_no); - void (*_interrupt_handler_set)(int interrupt_no, intr_handler_t fn, void *arg); - void (*_interrupt_disable)(void); - void (*_interrupt_restore)(void); + int (* _interrupt_alloc)(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle); + int (* _interrupt_free)(void *handle); + void (*_interrupt_handler_set_rsv)(int interrupt_no, intr_handler_t fn, void *arg); + void (*_global_intr_disable)(void); + void (*_global_intr_restore)(void); void (*_task_yield)(void); void (*_task_yield_from_isr)(void); void *(*_semphr_create)(uint32_t max, uint32_t init); @@ -186,13 +198,21 @@ struct osi_funcs_t { void (* _btdm_sleep_exit_phase3)(void); /* called from task */ void (* _coex_wifi_sleep_set)(bool sleep); int (* _coex_core_ble_conn_dyn_prio_get)(bool *low, bool *high); + int (* _coex_schm_register_btdm_callback)(void *callback); void (* _coex_schm_status_bit_set)(uint32_t type, uint32_t status); void (* _coex_schm_status_bit_clear)(uint32_t type, uint32_t status); - void (* _interrupt_on)(int intr_num); - void (* _interrupt_off)(int intr_num); + uint32_t (* _coex_schm_interval_get)(void); + uint8_t (* _coex_schm_curr_period_get)(void); + void *(* _coex_schm_curr_phase_get)(void); + int (* _interrupt_enable)(void *handle); + int (* _interrupt_disable)(void *handle); void (* _esp_hw_power_down)(void); void (* _esp_hw_power_up)(void); void (* _ets_backup_dma_copy)(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_rem); + void (* _ets_delay_us)(uint32_t us); + void (* _btdm_rom_table_ready)(void); + bool (* _coex_bt_wakeup_request)(void); + void (* _coex_bt_wakeup_request_end)(void); }; @@ -234,8 +254,8 @@ extern bool API_vhci_host_check_send_available(void); extern void API_vhci_host_send_packet(uint8_t *data, uint16_t len); extern int API_vhci_host_register_callback(const vhci_host_callback_t *callback); /* TX power */ -extern int ble_txpwr_set(int power_type, int power_level); -extern int ble_txpwr_get(int power_type); +extern int ble_txpwr_set(int power_type, uint16_t handle, int power_level); +extern int ble_txpwr_get(int power_type, uint16_t handle); extern uint16_t l2c_ble_link_get_tx_buf_num(void); extern void coex_pti_v2(void); @@ -244,6 +264,7 @@ extern bool btdm_deep_sleep_mem_init(void); extern void btdm_deep_sleep_mem_deinit(void); extern void btdm_ble_power_down_dma_copy(bool copy); extern uint8_t btdm_sleep_clock_sync(void); +extern void sdk_config_extend_set_pll_track(bool enable); #if CONFIG_MAC_BB_PD extern void esp_mac_bb_power_down(void); @@ -251,27 +272,24 @@ extern void esp_mac_bb_power_up(void); extern void ets_backup_dma_copy(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem); #endif +extern void btdm_cca_feature_enable(void); + extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; -extern uint32_t _btdm_bss_start; -extern uint32_t _btdm_bss_end; -extern uint32_t _nimble_bss_start; -extern uint32_t _nimble_bss_end; +extern uint32_t _bt_controller_bss_start; +extern uint32_t _bt_controller_bss_end; extern uint32_t _bt_data_start; extern uint32_t _bt_data_end; -extern uint32_t _btdm_data_start; -extern uint32_t _btdm_data_end; -extern uint32_t _nimble_data_start; -extern uint32_t _nimble_data_end; +extern uint32_t _bt_controller_data_start; +extern uint32_t _bt_controller_data_end; /* Local Function Declare ********************************************************************* */ -static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio); -static void interrupt_clear_wrapper(int intr_source, int intr_num); -static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg); -static void interrupt_disable(void); -static void interrupt_restore(void); +static int interrupt_alloc_wrapper(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle); +static int interrupt_free_wrapper(void *handle); +static void global_interrupt_disable(void); +static void global_interrupt_restore(void); static void task_yield_from_isr(void); static void *semphr_create_wrapper(uint32_t max, uint32_t init); static void semphr_delete_wrapper(void *semphr); @@ -303,13 +321,20 @@ static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles); static void btdm_sleep_enter_phase2_wrapper(void); static void btdm_sleep_exit_phase3_wrapper(void); static void coex_wifi_sleep_set_hook(bool sleep); +static int coex_schm_register_btdm_callback_wrapper(void *callback); static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status); static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); -static void interrupt_on_wrapper(int intr_num); -static void interrupt_off_wrapper(int intr_num); +static uint32_t coex_schm_interval_get_wrapper(void); +static uint8_t coex_schm_curr_period_get_wrapper(void); +static void * coex_schm_curr_phase_get_wrapper(void); +static int interrupt_enable_wrapper(void *handle); +static int interrupt_disable_wrapper(void *handle); static void btdm_hw_mac_power_up_wrapper(void); static void btdm_hw_mac_power_down_wrapper(void); static void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem); +static void btdm_funcs_table_ready_wrapper(void); +static bool coex_bt_wakeup_request(void); +static void coex_bt_wakeup_request_end(void); static void btdm_slp_tmr_callback(void *arg); @@ -324,11 +349,11 @@ static void bt_controller_deinit_internal(void); static const struct osi_funcs_t osi_funcs_ro = { ._magic = OSI_MAGIC_VALUE, ._version = OSI_VERSION, - ._interrupt_set = interrupt_set_wrapper, - ._interrupt_clear = interrupt_clear_wrapper, - ._interrupt_handler_set = interrupt_handler_set_wrapper, - ._interrupt_disable = interrupt_disable, - ._interrupt_restore = interrupt_restore, + ._interrupt_alloc = interrupt_alloc_wrapper, + ._interrupt_free = interrupt_free_wrapper, + ._interrupt_handler_set_rsv = NULL, + ._global_intr_disable = global_interrupt_disable, + ._global_intr_restore = global_interrupt_restore, ._task_yield = vPortYield, ._task_yield_from_isr = task_yield_from_isr, ._semphr_create = semphr_create_wrapper, @@ -367,13 +392,21 @@ static const struct osi_funcs_t osi_funcs_ro = { ._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper, ._coex_wifi_sleep_set = coex_wifi_sleep_set_hook, ._coex_core_ble_conn_dyn_prio_get = NULL, + ._coex_schm_register_btdm_callback = coex_schm_register_btdm_callback_wrapper, ._coex_schm_status_bit_set = coex_schm_status_bit_set_wrapper, ._coex_schm_status_bit_clear = coex_schm_status_bit_clear_wrapper, - ._interrupt_on = interrupt_on_wrapper, - ._interrupt_off = interrupt_off_wrapper, + ._coex_schm_interval_get = coex_schm_interval_get_wrapper, + ._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper, + ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper, + ._interrupt_enable = interrupt_enable_wrapper, + ._interrupt_disable = interrupt_disable_wrapper, ._esp_hw_power_down = btdm_hw_mac_power_down_wrapper, ._esp_hw_power_up = btdm_hw_mac_power_up_wrapper, ._ets_backup_dma_copy = btdm_backup_dma_copy_wrapper, + ._ets_delay_us = esp_rom_delay_us, + ._btdm_rom_table_ready = btdm_funcs_table_ready_wrapper, + ._coex_bt_wakeup_request = coex_bt_wakeup_request, + ._coex_bt_wakeup_request_end = coex_bt_wakeup_request_end, }; static DRAM_ATTR struct osi_funcs_t *osi_funcs_p; @@ -394,7 +427,7 @@ static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0; // semaphore used for blocking VHCI API to wait for controller to wake up static DRAM_ATTR QueueHandle_t s_wakeup_req_sem = NULL; // wakeup timer -static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr; +static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr = NULL; #ifdef CONFIG_PM_ENABLE static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock; @@ -453,36 +486,44 @@ static inline void esp_bt_power_domain_off(void) esp_wifi_bt_power_domain_off(); } -static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio) +static void btdm_intr_alloc(void *arg) { - esp_rom_route_intr_matrix(cpu_no, intr_source, intr_num); -#if __riscv - esprv_intc_int_set_priority(intr_num, intr_prio); - //esprv_intc_int_enable_level(1 << intr_num); - esprv_intc_int_set_type(intr_num, 0); -#endif + btdm_isr_alloc_t *p = arg; + p->ret = esp_intr_alloc(p->source, p->flags, p->fn, p->arg, p->handle); } -static void interrupt_clear_wrapper(int intr_source, int intr_num) +static int interrupt_alloc_wrapper(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle) { + btdm_isr_alloc_t p; + p.source = source; + p.flags = ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM; + p.fn = handler; + p.arg = arg; + p.handle = (intr_handle_t *)ret_handle; +#if CONFIG_FREERTOS_UNICORE + btdm_intr_alloc(&p); +#else + esp_ipc_call_blocking(cpu_id, btdm_intr_alloc, &p); +#endif + return p.ret; } -static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg) +static int interrupt_free_wrapper(void *handle) { - esp_cpu_intr_set_handler(n, fn, arg); + return esp_intr_free((intr_handle_t)handle); } -static void interrupt_on_wrapper(int intr_num) +static int interrupt_enable_wrapper(void *handle) { - esp_cpu_intr_enable(1 << intr_num); + return esp_intr_enable((intr_handle_t)handle); } -static void interrupt_off_wrapper(int intr_num) +static int interrupt_disable_wrapper(void *handle) { - esp_cpu_intr_disable(1<> 1; #define BTDM_MIN_TIMER_UNCERTAINTY_US (1800) +#define BTDM_RTC_SLOW_CLK_RC_DRIFT_PERCENT 7 assert(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US); // allow a maximum time uncertainty to be about 488ppm(1/2048) at least as clock drift // and set the timer in advance uint32_t uncertainty = (us_to_sleep >> 11); +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) { + uncertainty = us_to_sleep * BTDM_RTC_SLOW_CLK_RC_DRIFT_PERCENT / 100; + } +#endif + if (uncertainty < BTDM_MIN_TIMER_UNCERTAINTY_US) { uncertainty = BTDM_MIN_TIMER_UNCERTAINTY_US; } assert (s_lp_stat.wakeup_timer_started == 0); + // start a timer to wake up and acquire the pm_lock before modem_sleep awakes if (esp_timer_start_once(s_btdm_slp_tmr, us_to_sleep - uncertainty) == ESP_OK) { s_lp_stat.wakeup_timer_started = 1; } else { @@ -740,18 +788,18 @@ static void btdm_sleep_enter_phase2_wrapper(void) { if (btdm_controller_get_sleep_mode() == ESP_BT_SLEEP_MODE_1) { if (s_lp_stat.phy_enabled) { - esp_phy_disable(); + esp_phy_disable(PHY_MODEM_BT); s_lp_stat.phy_enabled = 0; } else { assert(0); } - if (s_lp_stat.pm_lock_released == 0) { #ifdef CONFIG_PM_ENABLE + if (s_lp_stat.pm_lock_released == 0) { esp_pm_lock_release(s_pm_lock); -#endif s_lp_stat.pm_lock_released = 1; } +#endif } } @@ -769,7 +817,7 @@ static void btdm_sleep_exit_phase3_wrapper(void) if (btdm_controller_get_sleep_mode() == ESP_BT_SLEEP_MODE_1) { if (s_lp_stat.phy_enabled == 0) { - esp_phy_enable(); + esp_phy_enable(PHY_MODEM_BT); s_lp_stat.phy_enabled = 1; } } @@ -840,6 +888,22 @@ static bool async_wakeup_request(int event) semphr_take_wrapper(s_wakeup_req_sem, OSI_FUNCS_TIME_BLOCKING); } break; + case BTDM_ASYNC_WAKEUP_REQ_COEX: + if (!btdm_power_state_active()) { + do_wakeup_request = true; +#if CONFIG_PM_ENABLE + if (s_lp_stat.pm_lock_released) { + esp_pm_lock_acquire(s_pm_lock); + s_lp_stat.pm_lock_released = 0; + } +#endif + btdm_wakeup_request(); + + if (s_lp_cntl.wakeup_timer_required && s_lp_stat.wakeup_timer_started) { + esp_timer_stop(s_btdm_slp_tmr); + s_lp_stat.wakeup_timer_started = 0; + } + } default: break; } @@ -859,6 +923,9 @@ static void async_wakeup_request_end(int event) case BTDM_ASYNC_WAKEUP_SRC_DISA: allow_to_sleep = true; break; + case BTDM_ASYNC_WAKEUP_REQ_COEX: + allow_to_sleep = false; + break; default: allow_to_sleep = true; break; @@ -871,18 +938,32 @@ static void async_wakeup_request_end(int event) return; } -static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status) +static void btdm_funcs_table_ready_wrapper(void) { -#if CONFIG_SW_COEXIST_ENABLE - coex_schm_status_bit_set(type, status); +#if BT_BLE_CCA_MODE == 2 + btdm_cca_feature_enable(); #endif } -static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) +bool bt_async_wakeup_request(void) { -#if CONFIG_SW_COEXIST_ENABLE - coex_schm_status_bit_clear(type, status); -#endif + return async_wakeup_request(BTDM_ASYNC_WAKEUP_SRC_VHCI); +} + +void bt_wakeup_request_end(void) +{ + async_wakeup_request_end(BTDM_ASYNC_WAKEUP_SRC_VHCI); +} + +static bool coex_bt_wakeup_request(void) +{ + return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX); +} + +static void coex_bt_wakeup_request_end(void) +{ + async_wakeup_request_end(BTDM_ASYNC_WAKEUP_REQ_COEX); + return; } bool esp_vhci_host_check_send_available(void) @@ -919,145 +1000,175 @@ static void btdm_controller_mem_init(void) btdm_controller_rom_data_init(); } -esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) +/** + * Release two memory areas to the heap. If both areas are consecutive, they will be released as + * a single area. + */ +typedef struct { + intptr_t start; + intptr_t end; + const char* name; +} bt_area_t; + +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) +{ + esp_err_t ret = ESP_OK; + intptr_t mem_start = area->start; + intptr_t mem_end = area->end; + if (mem_start != mem_end) { + ESP_LOGD(BT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + return ret; +} + +static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2) { - intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL; + esp_err_t ret = ESP_OK; + + if (area1->end == area2->start) { + bt_area_t merged_area = { + .start = area1->start, + .end = area2->end, + .name = area1->name + }; + ret = esp_bt_mem_release_area(&merged_area); + } else { + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); + } + + return ret; +} + +esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode) +{ + esp_err_t ret = ESP_OK; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { return ESP_ERR_INVALID_STATE; } - if (mode & ESP_BT_MODE_BLE) { - /* if the addresses of rom btdm .data and .bss are consecutive, - they are registered in the system heap as a piece of memory - */ - if(ets_rom_layout_p->data_end_btdm == ets_rom_layout_p->bss_start_btdm) { - mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm; - mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)ets_rom_layout_p->bss_start_btdm; - mem_end = (intptr_t)ets_rom_layout_p->bss_end_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + bt_area_t rom_btdm_data = { + .start = (intptr_t) ets_rom_layout_p->data_start_btdm, + .end = (intptr_t) ets_rom_layout_p->data_end_btdm, + .name = "ROM btdm data", + }; + bt_area_t rom_btdm_bss = { + .start = (intptr_t)ets_rom_layout_p->bss_start_btdm, + .end = (intptr_t)ets_rom_layout_p->bss_end_btdm, + .name = "ROM btdm BSS", + }; + bt_area_t rom_btdm_inter_data = { + .start = (intptr_t) ets_rom_layout_p->data_start_interface_btdm, + .end = (intptr_t) ets_rom_layout_p->data_end_interface_btdm, + .name = "ROM interface btdm data", + }; + bt_area_t rom_btdm_inter_bss = { + .start = (intptr_t)ets_rom_layout_p->bss_start_interface_btdm, + .end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm, + .name = "ROM interface btdm BSS", + }; - mem_start = (intptr_t)ets_rom_layout_p->data_start_btdm; - mem_end = (intptr_t)ets_rom_layout_p->data_end_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + ret = ESP_ERR_INVALID_STATE; + } + + if (mode & ESP_BT_MODE_BLE) { + /* Free BTDM memory used by the ROM */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&rom_btdm_data, &rom_btdm_bss); } - /* if the addresses of rom interface btdm .data and .bss are consecutive, - they are registered in the system heap as a piece of memory - */ - if(ets_rom_layout_p->data_end_interface_btdm == ets_rom_layout_p->bss_start_interface_btdm) { - mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm; - mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)ets_rom_layout_p->data_start_interface_btdm; - mem_end = (intptr_t)ets_rom_layout_p->data_end_interface_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)ets_rom_layout_p->bss_start_interface_btdm; - mem_end = (intptr_t)ets_rom_layout_p->bss_end_interface_btdm; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release rom interface btdm BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&rom_btdm_inter_data, &rom_btdm_inter_bss); } + } + return ret; +} + +esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode) +{ + esp_err_t ret = ESP_OK; + + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; } - return ESP_OK; + + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + + if (mode & ESP_BT_MODE_BLE) { + /* free data and BSS section for libbtdm_app.a */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&cont_data, &cont_bss); + } + /* free data and BSS section for Bluetooth controller ROM code */ + if (ret == ESP_OK) { + ret = esp_bt_controller_rom_mem_release(mode); + } + } + + return ret; } esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - int ret; - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; - ret = esp_bt_controller_mem_release(mode); - if (ret != ESP_OK) { - return ret; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; } - if (mode & ESP_BT_MODE_BLE) { - /* if the addresses of btdm .bss and bt .bss are consecutive, - they are registered in the system heap as a piece of memory - */ - if(_bt_bss_end == _btdm_bss_start) { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_btdm_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + bt_area_t bss = { + .start = (intptr_t)&_bt_bss_start, + .end = (intptr_t)&_bt_bss_end, + .name = "BT BSS", + }; + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t data = { + .start = (intptr_t)&_bt_data_start, + .end = (intptr_t)&_bt_data_end, + .name = "BT Data", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; - mem_start = (intptr_t)&_btdm_bss_start; - mem_end = (intptr_t)&_btdm_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release BTDM BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if (mode & ESP_BT_MODE_BLE) { + /* Start by freeing Bluetooth BSS section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&bss, &cont_bss); } - /* if the addresses of btdm .data and bt .data are consecutive, - they are registered in the system heap as a piece of memory - */ - if(_bt_data_end == _btdm_data_start) { - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_btdm_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_bt_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)&_btdm_data_start; - mem_end = (intptr_t)&_btdm_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); } - mem_start = (intptr_t)&_nimble_bss_start; - mem_end = (intptr_t)&_nimble_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)&_nimble_data_start; - mem_end = (intptr_t)&_nimble_data_end; - if (mem_start != mem_end) { - ESP_LOGD(BT_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x], len %d", mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); + /* free data and BSS section for Bluetooth controller ROM code */ + if (ret == ESP_OK) { + ret = esp_bt_controller_rom_mem_release(mode); } } - return ESP_OK; + + return ret; } static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) @@ -1092,79 +1203,11 @@ static void IRAM_ATTR btdm_mac_bb_power_up_cb(void) } #endif -esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) +// init low-power control resources +static esp_err_t btdm_low_power_mode_init(esp_bt_controller_config_t *cfg) { - esp_err_t err = ESP_FAIL; - - if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { - return ESP_ERR_INVALID_STATE; - } - - if (cfg == NULL) { - return ESP_ERR_INVALID_ARG; - } - - if (cfg->controller_task_prio != ESP_TASK_BT_CONTROLLER_PRIO - || cfg->controller_task_stack_size < ESP_TASK_BT_CONTROLLER_STACK) { - ESP_LOGE(BT_LOG_TAG, "Invalid controller task prioriy or stack size"); - return ESP_ERR_INVALID_ARG; - } - - if (cfg->bluetooth_mode != ESP_BT_MODE_BLE) { - ESP_LOGE(BT_LOG_TAG, "%s controller only support BLE only mode", __func__); - return ESP_ERR_NOT_SUPPORTED; - } - - if (cfg->bluetooth_mode & ESP_BT_MODE_BLE) { - if ((cfg->ble_max_act <= 0) || (cfg->ble_max_act > BT_CTRL_BLE_MAX_ACT_LIMIT)) { - ESP_LOGE(BT_LOG_TAG, "Invalid value of ble_max_act"); - return ESP_ERR_INVALID_ARG; - } - } - - if (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) { - if (cfg->sleep_clock == ESP_BT_SLEEP_CLOCK_NONE) { - ESP_LOGE(BT_LOG_TAG, "SLEEP_MODE_1 enabled but sleep clock not configured"); - return ESP_ERR_INVALID_ARG; - } - } - - // overwrite some parameters - cfg->magic = ESP_BT_CTRL_CONFIG_MAGIC_VAL; - -#if CONFIG_MAC_BB_PD - esp_mac_bb_pd_mem_init(); -#endif - esp_phy_modem_init(); - esp_bt_power_domain_on(); - - btdm_controller_mem_init(); + esp_err_t err = ESP_OK; -#if CONFIG_MAC_BB_PD - if (esp_register_mac_bb_pd_callback(btdm_mac_bb_power_down_cb) != 0) { - err = ESP_ERR_INVALID_ARG; - goto error; - } - - if (esp_register_mac_bb_pu_callback(btdm_mac_bb_power_up_cb) != 0) { - err = ESP_ERR_INVALID_ARG; - goto error; - } -#endif - - osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t)); - if (osi_funcs_p == NULL) { - return ESP_ERR_NO_MEM; - } - - memcpy(osi_funcs_p, &osi_funcs_ro, sizeof(struct osi_funcs_t)); - if (btdm_osi_funcs_register(osi_funcs_p) != 0) { - return ESP_ERR_INVALID_ARG; - } - - ESP_LOGI(BT_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version()); - - // init low-power control resources do { // set default values for global states or resources s_lp_stat.val = 0; @@ -1175,13 +1218,14 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) // configure and initialize resources s_lp_cntl.enable = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? 1 : 0; + s_lp_cntl.lpclk_sel = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? cfg->sleep_clock : ESP_BT_SLEEP_CLOCK_MAIN_XTAL; s_lp_cntl.no_light_sleep = 0; if (s_lp_cntl.enable) { #if CONFIG_MAC_BB_PD if (!btdm_deep_sleep_mem_init()) { err = ESP_ERR_NO_MEM; - goto error; + break; } s_lp_cntl.mac_bb_pd = 1; #endif @@ -1192,58 +1236,55 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) s_wakeup_req_sem = semphr_create_wrapper(1, 0); if (s_wakeup_req_sem == NULL) { err = ESP_ERR_NO_MEM; - goto error; + break; } btdm_vnd_offload_task_register(BTDM_VND_OL_SIG_WAKEUP_TMR, btdm_sleep_exit_phase0); - } - if (s_lp_cntl.wakeup_timer_required) { - esp_timer_create_args_t create_args = { - .callback = btdm_slp_tmr_callback, - .arg = NULL, - .name = "btSlp", - }; - if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) { - goto error; + if (s_lp_cntl.wakeup_timer_required) { + esp_timer_create_args_t create_args = { + .callback = btdm_slp_tmr_callback, + .arg = NULL, + .name = "btSlp", + }; + if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) { + break; + } } - } - // set default bluetooth sleep clock cycle and its fractional bits - btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT; - btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac); + // set default bluetooth sleep clock cycle and its fractional bits + btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT; + btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac); - // set default bluetooth sleep clock source - s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value -#if CONFIG_BT_CTRL_LPCLK_SEL_EXT_32K_XTAL - // check whether or not EXT_CRYS is working - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { - s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32 kHz XTAL - } else { - ESP_LOGW(BT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL) { // External 32 kHz XTAL + // check whether or not EXT_CRYS is working + if (rtc_clk_slow_src_get() != SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + ESP_LOGW(BT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + s_lp_cntl.lpclk_sel = ESP_BT_SLEEP_CLOCK_MAIN_XTAL; #if !CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP - s_lp_cntl.no_light_sleep = 1; + s_lp_cntl.no_light_sleep = 1; #endif - } -#elif (CONFIG_BT_CTRL_LPCLK_SEL_MAIN_XTAL) - ESP_LOGI(BT_LOG_TAG, "Bluetooth will use main XTAL as Bluetooth sleep clock."); + } + } else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_RTC_SLOW) { // Internal 136kHz RC oscillator + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) { + ESP_LOGW(BT_LOG_TAG, "Internal 136kHz RC oscillator. The accuracy of this clock is a lot larger than 500ppm which is " + "required in Bluetooth communication, so don't select this option in scenarios such as BLE connection state."); + } else { + ESP_LOGW(BT_LOG_TAG, "Internal 136kHz RC oscillator not detected."); + assert(0); + } + } else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_XTAL) { + ESP_LOGI(BT_LOG_TAG, "Bluetooth will use main XTAL as Bluetooth sleep clock."); #if !CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP - s_lp_cntl.no_light_sleep = 1; + s_lp_cntl.no_light_sleep = 1; #endif -#elif (CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW) - // check whether or not internal 150 kHz RC oscillator is working - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) { - s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // Internal 150 kHz RC oscillator - ESP_LOGW(BT_LOG_TAG, "Internal 150kHz RC osciallator. The accuracy of this clock is a lot larger than 500ppm which is " - "required in Bluetooth communication, so don't select this option in scenarios such as BLE connection state."); + } } else { - ESP_LOGW(BT_LOG_TAG, "Internal 150kHz RC oscillator not detected."); - assert(0); + s_lp_cntl.no_light_sleep = 1; } -#endif bool select_src_ret __attribute__((unused)); bool set_div_ret __attribute__((unused)); - if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL) { + if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_XTAL) { #ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON)); s_lp_cntl.main_xtal_pu = 1; @@ -1253,7 +1294,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) assert(select_src_ret && set_div_ret); btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT; btdm_lpcycle_us = 1 << (btdm_lpcycle_us_frac); - } else if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL32K) { + } else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL) { select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K); set_div_ret = btdm_lpclk_set_div(0); assert(select_src_ret && set_div_ret); @@ -1261,7 +1302,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) : (1000000 >> (15 - RTC_CLK_CAL_FRACT)); assert(btdm_lpcycle_us != 0); - } else if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_RTC_SLOW) { + } else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_RTC_SLOW) { select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW); set_div_ret = btdm_lpclk_set_div(0); assert(select_src_ret && set_div_ret); @@ -1269,7 +1310,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) btdm_lpcycle_us = esp_clk_slowclk_cal_get(); } else { err = ESP_ERR_INVALID_ARG; - goto error; + break; } #if CONFIG_SW_COEXIST_ENABLE coex_update_lpclk_interval(); @@ -1278,20 +1319,100 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #ifdef CONFIG_PM_ENABLE if (s_lp_cntl.no_light_sleep) { if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) { - err = ESP_ERR_NO_MEM; - goto error; + break; } ESP_LOGW(BT_LOG_TAG, "light sleep mode will not be able to apply when bluetooth is enabled."); } if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) { - err = ESP_ERR_NO_MEM; - goto error; + break; } else { s_lp_stat.pm_lock_released = 1; } #endif } while (0); + return err; +} + +esp_bt_sleep_clock_t esp_bt_get_lpclk_src(void) +{ + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED && + btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { + return ESP_BT_SLEEP_CLOCK_NONE; + } + + return s_lp_cntl.lpclk_sel; +} + +esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) +{ + esp_err_t err = ESP_FAIL; + + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } + + if (cfg == NULL) { + return ESP_ERR_INVALID_ARG; + } + + if (cfg->controller_task_prio != ESP_TASK_BT_CONTROLLER_PRIO + || cfg->controller_task_stack_size < ESP_TASK_BT_CONTROLLER_STACK) { + ESP_LOGE(BT_LOG_TAG, "Invalid controller task prioriy or stack size"); + return ESP_ERR_INVALID_ARG; + } + + if (cfg->bluetooth_mode != ESP_BT_MODE_BLE) { + ESP_LOGE(BT_LOG_TAG, "%s controller only support BLE only mode", __func__); + return ESP_ERR_NOT_SUPPORTED; + } + + if (cfg->bluetooth_mode & ESP_BT_MODE_BLE) { + if ((cfg->ble_max_act <= 0) || (cfg->ble_max_act > BT_CTRL_BLE_MAX_ACT_LIMIT)) { + ESP_LOGE(BT_LOG_TAG, "Invalid value of ble_max_act"); + return ESP_ERR_INVALID_ARG; + } + } + + if (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) { + if (cfg->sleep_clock == ESP_BT_SLEEP_CLOCK_NONE) { + ESP_LOGE(BT_LOG_TAG, "SLEEP_MODE_1 enabled but sleep clock not configured"); + return ESP_ERR_INVALID_ARG; + } + if (cfg->sleep_clock > ESP_BT_SLEEP_CLOCK_RTC_SLOW) { + ESP_LOGE(BT_LOG_TAG, "SLEEP_MODE_1 is enabled but this sleep clock is not supported"); + return ESP_ERR_INVALID_ARG; + } + } + + // overwrite some parameters + cfg->magic = ESP_BT_CTRL_CONFIG_MAGIC_VAL; + +#if CONFIG_MAC_BB_PD + esp_mac_bb_pd_mem_init(); +#endif + esp_phy_modem_init(); + esp_bt_power_domain_on(); + + btdm_controller_mem_init(); + + osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t)); + if (osi_funcs_p == NULL) { + return ESP_ERR_NO_MEM; + } + + memcpy(osi_funcs_p, &osi_funcs_ro, sizeof(struct osi_funcs_t)); + if (btdm_osi_funcs_register(osi_funcs_p) != 0) { + return ESP_ERR_INVALID_ARG; + } + + ESP_LOGI(BT_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version()); + + if ((err = btdm_low_power_mode_init(cfg)) != ESP_OK) { + ESP_LOGE(BT_LOG_TAG, "Low power module initialization failed"); + goto error; + } + #if CONFIG_SW_COEXIST_ENABLE coex_init(); #endif @@ -1299,14 +1420,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) periph_module_enable(PERIPH_BT_MODULE); periph_module_reset(PERIPH_BT_MODULE); - esp_phy_enable(); - s_lp_stat.phy_enabled = 1; - if (btdm_controller_init(cfg) != 0) { err = ESP_ERR_NO_MEM; goto error; } - coex_pti_v2(); btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; @@ -1332,79 +1449,70 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_OK; } -static void bt_controller_deinit_internal(void) +// deinit low power control resources +static void btdm_low_power_mode_deinit(void) { - periph_module_disable(PERIPH_BT_MODULE); - - if (s_lp_stat.phy_enabled) { - esp_phy_disable(); - s_lp_stat.phy_enabled = 0; - } - - // deinit low power control resources - do { - #if CONFIG_MAC_BB_PD - if (s_lp_cntl.mac_bb_pd) { - btdm_deep_sleep_mem_deinit(); - s_lp_cntl.mac_bb_pd = 0; - } + if (s_lp_cntl.mac_bb_pd) { + btdm_deep_sleep_mem_deinit(); + s_lp_cntl.mac_bb_pd = 0; + } #endif #ifdef CONFIG_PM_ENABLE - if (s_lp_cntl.no_light_sleep) { - if (s_light_sleep_pm_lock != NULL) { - esp_pm_lock_delete(s_light_sleep_pm_lock); - s_light_sleep_pm_lock = NULL; - } - } - - if (s_pm_lock != NULL) { - esp_pm_lock_delete(s_pm_lock); - s_pm_lock = NULL; - s_lp_stat.pm_lock_released = 0; + if (s_lp_cntl.no_light_sleep) { + if (s_light_sleep_pm_lock != NULL) { + esp_pm_lock_delete(s_light_sleep_pm_lock); + s_light_sleep_pm_lock = NULL; } + } + if (s_pm_lock != NULL) { + esp_pm_lock_delete(s_pm_lock); + s_pm_lock = NULL; + s_lp_stat.pm_lock_released = 0; + } #endif - if (s_lp_cntl.wakeup_timer_required) { - if (s_lp_stat.wakeup_timer_started) { - esp_timer_stop(s_btdm_slp_tmr); - } - s_lp_stat.wakeup_timer_started = 0; - esp_timer_delete(s_btdm_slp_tmr); - s_btdm_slp_tmr = NULL; + if (s_lp_cntl.wakeup_timer_required && s_btdm_slp_tmr != NULL) { + if (s_lp_stat.wakeup_timer_started) { + esp_timer_stop(s_btdm_slp_tmr); } + s_lp_stat.wakeup_timer_started = 0; + esp_timer_delete(s_btdm_slp_tmr); + s_btdm_slp_tmr = NULL; + } - if (s_lp_cntl.enable) { - btdm_vnd_offload_task_deregister(BTDM_VND_OL_SIG_WAKEUP_TMR); - if (s_wakeup_req_sem != NULL) { - semphr_delete_wrapper(s_wakeup_req_sem); - s_wakeup_req_sem = NULL; - } + if (s_lp_cntl.enable) { + btdm_vnd_offload_task_deregister(BTDM_VND_OL_SIG_WAKEUP_TMR); + if (s_wakeup_req_sem != NULL) { + semphr_delete_wrapper(s_wakeup_req_sem); + s_wakeup_req_sem = NULL; } + } - if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL) { + if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_XTAL) { #ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP - if (s_lp_cntl.main_xtal_pu) { - ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF)); - s_lp_cntl.main_xtal_pu = 0; - } + if (s_lp_cntl.main_xtal_pu) { + ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF)); + s_lp_cntl.main_xtal_pu = 0; + } #endif - btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW); - btdm_lpclk_set_div(0); + btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW); + btdm_lpclk_set_div(0); #if CONFIG_SW_COEXIST_ENABLE - coex_update_lpclk_interval(); + coex_update_lpclk_interval(); #endif - } + } - btdm_lpcycle_us = 0; - } while (0); + btdm_lpcycle_us = 0; +} -#if CONFIG_MAC_BB_PD - esp_unregister_mac_bb_pd_callback(btdm_mac_bb_power_down_cb); - esp_unregister_mac_bb_pu_callback(btdm_mac_bb_power_up_cb); -#endif +static void bt_controller_deinit_internal(void) +{ + periph_module_disable(PERIPH_BT_MODULE); + + btdm_low_power_mode_deinit(); esp_bt_power_domain_off(); #if CONFIG_MAC_BB_PD @@ -1434,6 +1542,12 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) return ESP_ERR_INVALID_ARG; } + /* Enable PHY when enabling controller to reduce power dissipation after controller init + * Notice the init order: esp_phy_enable() -> bt_bb_v2_init_cmplx() -> coex_pti_v2() + */ + esp_phy_enable(PHY_MODEM_BT); + s_lp_stat.phy_enabled = 1; + #if CONFIG_SW_COEXIST_ENABLE coex_enable(); #endif @@ -1448,16 +1562,33 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) s_lp_stat.pm_lock_released = 0; #endif +#if CONFIG_MAC_BB_PD + if (esp_register_mac_bb_pd_callback(btdm_mac_bb_power_down_cb) != 0) { + ret = ESP_ERR_INVALID_ARG; + goto error; + } + + if (esp_register_mac_bb_pu_callback(btdm_mac_bb_power_up_cb) != 0) { + ret = ESP_ERR_INVALID_ARG; + goto error; + } +#endif + if (s_lp_cntl.enable) { btdm_controller_enable_sleep(true); } } while (0); + // Disable pll track by default in BLE controller on ESP32-C3 and ESP32-S3 + sdk_config_extend_set_pll_track(false); + if (btdm_controller_enable(mode) != 0) { ret = ESP_ERR_INVALID_STATE; goto error; } + coex_pti_v2(); + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED; return ret; @@ -1465,6 +1596,11 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) error: // disable low power mode do { +#if CONFIG_MAC_BB_PD + esp_unregister_mac_bb_pd_callback(btdm_mac_bb_power_down_cb); + esp_unregister_mac_bb_pu_callback(btdm_mac_bb_power_up_cb); +#endif + btdm_controller_enable_sleep(false); #ifdef CONFIG_PM_ENABLE if (s_lp_cntl.no_light_sleep) { @@ -1480,6 +1616,10 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif + if (s_lp_stat.phy_enabled) { + esp_phy_disable(PHY_MODEM_BT); + s_lp_stat.phy_enabled = 0; + } return ret; } @@ -1498,11 +1638,20 @@ esp_err_t esp_bt_controller_disable(void) #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif + if (s_lp_stat.phy_enabled) { + esp_phy_disable(PHY_MODEM_BT); + s_lp_stat.phy_enabled = 0; + } btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; // disable low power mode do { +#if CONFIG_MAC_BB_PD + esp_unregister_mac_bb_pd_callback(btdm_mac_bb_power_down_cb); + esp_unregister_mac_bb_pu_callback(btdm_mac_bb_power_up_cb); +#endif + #ifdef CONFIG_PM_ENABLE if (s_lp_cntl.no_light_sleep) { esp_pm_lock_release(s_light_sleep_pm_lock); @@ -1525,16 +1674,89 @@ esp_bt_controller_status_t esp_bt_controller_get_status(void) return btdm_controller_status; } +static int enh_power_type_get(esp_ble_power_type_t power_type) +{ + switch (power_type) { + case ESP_BLE_PWR_TYPE_ADV: + return ESP_BLE_ENHANCED_PWR_TYPE_ADV; + case ESP_BLE_PWR_TYPE_SCAN: + return ESP_BLE_ENHANCED_PWR_TYPE_SCAN; + case ESP_BLE_PWR_TYPE_CONN_HDL0: + case ESP_BLE_PWR_TYPE_CONN_HDL1: + case ESP_BLE_PWR_TYPE_CONN_HDL2: + case ESP_BLE_PWR_TYPE_CONN_HDL3: + case ESP_BLE_PWR_TYPE_CONN_HDL4: + case ESP_BLE_PWR_TYPE_CONN_HDL5: + case ESP_BLE_PWR_TYPE_CONN_HDL6: + case ESP_BLE_PWR_TYPE_CONN_HDL7: + case ESP_BLE_PWR_TYPE_CONN_HDL8: + return ESP_BLE_ENHANCED_PWR_TYPE_CONN; + case ESP_BLE_PWR_TYPE_DEFAULT: + return ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT; + default: + break; + } + + return power_type; +} + /* extra functions */ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level) +{ + esp_err_t stat = ESP_FAIL; + uint16_t handle = BLE_PWR_HDL_INVL; + int enh_pwr_type = enh_power_type_get(power_type); + + if (power_type > ESP_BLE_PWR_TYPE_DEFAULT) { + return ESP_ERR_NOT_SUPPORTED; + } + + if (enh_pwr_type == ESP_BLE_ENHANCED_PWR_TYPE_CONN) { + handle = power_type; + } + + if (ble_txpwr_set(enh_pwr_type, handle, power_level) == 0) { + stat = ESP_OK; + } + + return stat; +} + +esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) +{ + esp_power_level_t lvl; + uint16_t handle = BLE_PWR_HDL_INVL; + int enh_pwr_type = enh_power_type_get(power_type); + + if (power_type > ESP_BLE_PWR_TYPE_DEFAULT) { + return ESP_PWR_LVL_INVALID; + } + + if (enh_pwr_type == ESP_BLE_ENHANCED_PWR_TYPE_CONN) { + handle = power_type; + } + + lvl = (esp_power_level_t)ble_txpwr_get(power_type, handle); + + return lvl; +} + +esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle, + esp_power_level_t power_level) { esp_err_t stat = ESP_FAIL; switch (power_type) { - case ESP_BLE_PWR_TYPE_ADV: - case ESP_BLE_PWR_TYPE_SCAN: - case ESP_BLE_PWR_TYPE_DEFAULT: - if (ble_txpwr_set(power_type, power_level) == 0) { + case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: + case ESP_BLE_ENHANCED_PWR_TYPE_INIT: + if (ble_txpwr_set(power_type, BLE_PWR_HDL_INVL, power_level) == 0) { + stat = ESP_OK; + } + break; + case ESP_BLE_ENHANCED_PWR_TYPE_ADV: + case ESP_BLE_ENHANCED_PWR_TYPE_CONN: + if (ble_txpwr_set(power_type, handle, power_level) == 0) { stat = ESP_OK; } break; @@ -1546,33 +1768,26 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ return stat; } -esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) +esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, + uint16_t handle) { - esp_power_level_t lvl; + int tx_level = 0; switch (power_type) { - case ESP_BLE_PWR_TYPE_ADV: - case ESP_BLE_PWR_TYPE_SCAN: - lvl = (esp_power_level_t)ble_txpwr_get(power_type); + case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: + case ESP_BLE_ENHANCED_PWR_TYPE_INIT: + tx_level = ble_txpwr_get(power_type, BLE_PWR_HDL_INVL); break; - case ESP_BLE_PWR_TYPE_CONN_HDL0: - case ESP_BLE_PWR_TYPE_CONN_HDL1: - case ESP_BLE_PWR_TYPE_CONN_HDL2: - case ESP_BLE_PWR_TYPE_CONN_HDL3: - case ESP_BLE_PWR_TYPE_CONN_HDL4: - case ESP_BLE_PWR_TYPE_CONN_HDL5: - case ESP_BLE_PWR_TYPE_CONN_HDL6: - case ESP_BLE_PWR_TYPE_CONN_HDL7: - case ESP_BLE_PWR_TYPE_CONN_HDL8: - case ESP_BLE_PWR_TYPE_DEFAULT: - lvl = (esp_power_level_t)ble_txpwr_get(ESP_BLE_PWR_TYPE_DEFAULT); + case ESP_BLE_ENHANCED_PWR_TYPE_ADV: + case ESP_BLE_ENHANCED_PWR_TYPE_CONN: + tx_level = ble_txpwr_get(power_type, handle); break; default: - lvl = ESP_PWR_LVL_INVALID; - break; + return ESP_PWR_LVL_INVALID; } - return lvl; + return (esp_power_level_t)tx_level; } esp_err_t esp_bt_sleep_enable (void) @@ -1642,4 +1857,55 @@ static void coex_wifi_sleep_set_hook(bool sleep) { } + +static int coex_schm_register_btdm_callback_wrapper(void *callback) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_register_callback(COEX_SCHM_CALLBACK_TYPE_BT, callback); +#else + return 0; +#endif +} + +static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) +{ +#if CONFIG_SW_COEXIST_ENABLE + coex_schm_status_bit_clear(type, status); +#endif +} + +static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status) +{ +#if CONFIG_SW_COEXIST_ENABLE + coex_schm_status_bit_set(type, status); +#endif +} + +static uint32_t coex_schm_interval_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_interval_get(); +#else + return 0; +#endif +} + +static uint8_t coex_schm_curr_period_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_curr_period_get(); +#else + return 1; +#endif +} + +static void * coex_schm_curr_phase_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_curr_phase_get(); +#else + return NULL; +#endif +} + #endif /* CONFIG_BT_ENABLED */ diff --git a/components/bt/controller/esp32c6/Kconfig.in b/components/bt/controller/esp32c6/Kconfig.in index 3af8ca90cf..07089db18e 100644 --- a/components/bt/controller/esp32c6/Kconfig.in +++ b/components/bt/controller/esp32c6/Kconfig.in @@ -2,19 +2,37 @@ menu "HCI Config" choice BT_LE_HCI_INTERFACE - prompt "Select HCI interface" + prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM config BT_LE_HCI_INTERFACE_USE_RAM - bool "ram" + bool "VHCI" help Use RAM as HCI interface config BT_LE_HCI_INTERFACE_USE_UART - bool "uart" + bool "UART(H4)" help Use UART as HCI interface endchoice + choice BT_LE_UART_HCI_MODE_CHOICE + prompt "UART HCI mode" + depends on BT_LE_HCI_INTERFACE_USE_UART + default BT_LE_UART_HCI_NO_DMA_MODE + help + Specify UART HCI mode: DMA or No DMA + + config BT_LE_UART_HCI_DMA_MODE + bool "UHCI(UART with DMA)(EXPERIMENTAL)" + help + UART HCI Mode with DMA functionality. + + config BT_LE_UART_HCI_NO_DMA_MODE + bool "UART(NO DMA)" + help + UART HCI Mode without DMA functionality. + endchoice + config BT_LE_HCI_UART_PORT int "HCI UART port" depends on BT_LE_HCI_INTERFACE_USE_UART @@ -73,12 +91,40 @@ menu "HCI Config" UART_PARITY_ODD endchoice - config BT_LE_HCI_UART_TASK_STACK_SIZE - int "HCI uart task stack size" - depends on BT_LE_HCI_INTERFACE_USE_UART - default 1000 + config BT_LE_HCI_UART_RX_BUFFER_SIZE + int "The size of rx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 512 + help + The size of rx ring buffer memory + + config BT_LE_HCI_UART_TX_BUFFER_SIZE + int "The size of tx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 256 + help + The size of tx ring buffer memory + + config BT_LE_HCI_TRANS_TASK_STACK_SIZE + int "HCI transport task stack size" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 1024 + help + This configures stack size of hci transport task + + config BT_LE_HCI_TRANS_RX_MEM_NUM + int "The amount of rx memory received at the same time" + depends on BT_LE_UART_HCI_DMA_MODE + default 3 + help + The amount of rx memory received at the same time + + config BT_LE_HCI_LLDESCS_POOL_NUM + int "The amount of lldecs memory for driver dma mode" + depends on BT_LE_UART_HCI_DMA_MODE + default 20 help - Set the size of uart task stack + The amount of lldecs memory for driver dma mode endmenu config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT @@ -147,7 +193,7 @@ if BT_LE_EXT_ADV Enable this option to start periodic advertisement. config BT_LE_PERIODIC_ADV_SYNC_TRANSFER - bool "Enable Transer Sync Events" + bool "Enable Transfer Sync Events" depends on BT_LE_ENABLE_PERIODIC_ADV default y help @@ -212,6 +258,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 @@ -260,18 +315,71 @@ config BT_LE_CONTROLLER_TASK_STACK_SIZE help This configures stack size of NimBLE controller task -config BT_LE_CONTROLLER_LOG_ENABLED +menuconfig BT_LE_CONTROLLER_LOG_ENABLED bool "Controller log enable" default n help - Enable controller log module + Enable controller log + +config BT_LE_CONTROLLER_LOG_CTRL_ENABLED + bool "enable controller log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help + Enable controller log module + +config BT_LE_CONTROLLER_LOG_HCI_ENABLED + bool "enable HCI log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help + Enable hci log module config BT_LE_CONTROLLER_LOG_DUMP_ONLY bool "Controller log dump mode only" depends on BT_LE_CONTROLLER_LOG_ENABLED default y help - Only operate in dump mode + Only operate in dump mode + +config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + bool "Store ble controller logs to flash(Experimental)" + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Store ble controller logs to flash memory. + +config BT_LE_CONTROLLER_LOG_PARTITION_SIZE + int "size of ble controller log partition(Multiples of 4K)" + depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + +config BT_LE_LOG_CTRL_BUF1_SIZE + int "size of the first BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help + Configure the size of the first BLE controller LOG buffer. + +config BT_LE_LOG_CTRL_BUF2_SIZE + int "size of the second BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 1024 + help + Configure the size of the second BLE controller LOG buffer. + +config BT_LE_LOG_HCI_BUF_SIZE + int "size of the BLE HCI LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help + Configure the size of the BLE HCI LOG buffer. config BT_LE_LL_RESOLV_LIST_SIZE int "BLE LL Resolving list size" @@ -321,7 +429,6 @@ config BT_LE_CRYPTO_STACK_MBEDTLS bool "Override TinyCrypt with mbedTLS for crypto computations" default y depends on !BT_NIMBLE_ENABLED - select MBEDTLS_ECP_RESTARTABLE select MBEDTLS_CMAC_C help Enable this option to choose mbedTLS instead of TinyCrypt for crypto @@ -338,7 +445,7 @@ config BT_LE_WHITELIST_SIZE config BT_LE_LL_DUP_SCAN_LIST_COUNT int "BLE duplicate scan list count" - range 1 100 + range 5 100 default 20 help config the max count of duplicate scan list @@ -353,7 +460,7 @@ config BT_LE_LL_SCA config BT_LE_MAX_CONNECTIONS int "Maximum number of concurrent connections" depends on !BT_NIMBLE_ENABLED - range 1 9 + range 1 70 default 3 help Defines maximum number of concurrent BLE connections. For ESP32, user @@ -365,7 +472,7 @@ config BT_LE_MAX_CONNECTIONS choice BT_LE_COEX_PHY_CODED_TX_RX_TLIM prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection" default BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS - depends on !BT_NIMBLE_ENABLED + depends on ESP_COEX_SW_COEXIST_ENABLE help When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to better avoid dramatic performance deterioration of Wi-Fi. @@ -383,7 +490,7 @@ endchoice config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF int - depends on !BT_NIMBLE_ENABLED + default 0 if !ESP_COEX_SW_COEXIST_ENABLE default 1 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN default 0 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS @@ -393,21 +500,6 @@ config BT_LE_SLEEP_ENABLE help Enable BLE sleep -choice BT_LE_WAKEUP_SOURCE - prompt "BLE light sleep wakeup source" - depends on BT_LE_SLEEP_ENABLE - default BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - config BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - bool "Use ESP timer to wakeup CPU" - help - Use esp timer to wakeup CPU - - config BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - bool "Use BLE rtc timer to wakeup CPU" - help - Use BLE rtc timer to wakeup CPU -endchoice - choice BT_LE_LP_CLK_SRC prompt "BLE low power clock source" default BT_LE_LP_CLK_SRC_MAIN_XTAL @@ -435,6 +527,38 @@ config BT_LE_USE_ESP_TIMER help Set this option to use Esp Timer which has higher priority timer instead of FreeRTOS timer +config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP + bool "BLE adv report flow control supported" + default y + help + The function is mainly used to enable flow control for advertising reports. When it is enabled, + advertising reports will be discarded by the controller if the number of unprocessed advertising + reports exceeds the size of BLE adv report flow control. + +config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM + int "BLE adv report flow control number" + depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP + range 50 1000 + default 100 + help + The number of unprocessed advertising report that bluetooth host can save.If you set + `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost. + If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a + lot of adv packets and this may cause system memory run out. For example, if you set + it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set + `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv + packets as fast as possible, otherwise it will cause adv packets lost. + +config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD + int "BLE adv lost event threshold value" + depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP + range 1 1000 + default 20 + help + When adv report flow control is enabled, The ADV lost event will be generated when the number + of ADV packets lost in the controller reaches this threshold. It is better to set a larger value. + If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it + may cause adv packets lost more. config BT_LE_SCAN_DUPL bool "BLE Scan Duplicate Options" @@ -482,15 +606,6 @@ config BT_LE_SCAN_DUPL_TYPE default 2 if BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE default 0 -config BT_LE_SCAN_DUPL_CACHE_SIZE - int "Maximum number of devices in scan duplicate filter" - depends on BT_LE_SCAN_DUPL - range 10 1000 - default 100 - help - Maximum number of devices which can be recorded in scan duplicate filter. - When the maximum amount of device in the filter is reached, the cache will be refreshed. - config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD int "Duplicate scan list refresh period (seconds)" depends on BT_LE_SCAN_DUPL @@ -506,3 +621,71 @@ config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD add new device information. 2. When the refresh period is up, the controller will clear all device information and start filtering again. + +config BT_LE_MSYS_INIT_IN_CONTROLLER + bool "Msys Mbuf Init in Controller" + default y + +config BT_LE_TX_CCA_ENABLED + bool "Enable TX CCA feature" + default n + help + Enable CCA feature to cancel sending the packet if the signal power is stronger than CCA threshold. + +config BT_LE_CCA_RSSI_THRESH + int "CCA RSSI threshold value" + depends on BT_LE_TX_CCA_ENABLED + range 20 100 + default 20 + help + Power threshold of CCA in unit of -1 dBm. + +choice BT_LE_DFT_TX_POWER_LEVEL_DBM + prompt "BLE default Tx power level(dBm)" + default BT_LE_DFT_TX_POWER_LEVEL_P9 + help + Specify default Tx power level(dBm). + config BT_LE_DFT_TX_POWER_LEVEL_N15 + bool "-15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N12 + bool "-12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N9 + bool "-9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N6 + bool "-6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N3 + bool "-3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N0 + bool "0dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P3 + bool "+3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P6 + bool "+6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P9 + bool "+9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P12 + bool "+12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P15 + bool "+15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P18 + bool "+18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" +endchoice + +config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF + int + default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15 + default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12 + default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9 + default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6 + default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3 + default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0 + default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3 + default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6 + default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9 + default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12 + default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15 + default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18 + default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20 + default 0 diff --git a/components/bt/controller/esp32c6/bt.c b/components/bt/controller/esp32c6/bt.c index 868a9ea486..0894f13aac 100644 --- a/components/bt/controller/esp32c6/bt.c +++ b/components/bt/controller/esp32c6/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,9 @@ #include "sdkconfig.h" +#if CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port.h" +#endif // CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port_freertos.h" #include "esp_private/esp_modem_clock.h" @@ -24,11 +26,11 @@ #endif // ESP_PLATFORM #if CONFIG_SW_COEXIST_ENABLE -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #endif // CONFIG_SW_COEXIST_ENABLE #include "nimble/nimble_npl_os.h" -#include "nimble/ble_hci_trans.h" +#include "esp_hci_transport.h" #include "os/endian.h" #include "esp_bt.h" @@ -37,16 +39,15 @@ #include "esp_pm.h" #include "esp_phy_init.h" #include "esp_private/periph_ctrl.h" -#include "hci_uart.h" #include "bt_osi_mem.h" -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if SOC_PM_RETENTION_HAS_CLOCK_BUG #include "esp_private/sleep_retention.h" -#endif +#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG -#ifdef CONFIG_BT_BLUEDROID_ENABLED -#include "hci/hci_hal.h" -#endif // CONFIG_BT_BLUEDROID_ENABLED +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#include "esp_private/sleep_modem.h" +#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -55,7 +56,7 @@ #include "esp_sleep.h" #include "hal/efuse_hal.h" - +#include "soc/rtc.h" /* Macro definition ************************************************************************ */ @@ -63,17 +64,11 @@ #define OSI_COEX_VERSION 0x00010006 #define OSI_COEX_MAGIC_VALUE 0xFADEBEAD -#define EXT_FUNC_VERSION 0x20221122 +#define EXT_FUNC_VERSION 0x20240422 #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf -#ifdef CONFIG_BT_BLUEDROID_ENABLED -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -#define ACL_DATA_MBUF_LEADINGSPCAE 4 -#endif // CONFIG_BT_BLUEDROID_ENABLED - - /* Types definition ************************************************************************ */ @@ -92,12 +87,6 @@ struct ext_funcs_t { int (*_esp_intr_free)(void **ret_handle); void *(* _malloc)(size_t size); void (*_free)(void *p); - void (*_hal_uart_start_tx)(int); - int (*_hal_uart_init_cbs)(int, hci_uart_tx_char, hci_uart_tx_done, hci_uart_rx_char, void *); - int (*_hal_uart_config)(int, int32_t, uint8_t, uint8_t, uart_parity_t, uart_hw_flowcontrol_t); - int (*_hal_uart_close)(int); - void (*_hal_uart_blocking_tx)(int, uint8_t); - int (*_hal_uart_init)(int, void *); int (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); void (* _task_delete)(void *task_handle); @@ -118,39 +107,45 @@ typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); ************************************************************************ */ extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); -extern int ble_controller_init(esp_bt_controller_config_t *cfg); +extern int r_ble_controller_init(esp_bt_controller_config_t *cfg); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create); -extern int ble_log_deinit_async(void); -extern void ble_log_async_output_dump_all(bool output); +extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int r_ble_log_deinit_async(void); +extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); +extern void r_ble_log_async_output_dump_all(bool output); +extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int ble_controller_deinit(void); -extern int ble_controller_enable(uint8_t mode); -extern int ble_controller_disable(void); +extern int r_ble_controller_deinit(void); +extern int r_ble_controller_enable(uint8_t mode); +extern int r_ble_controller_disable(void); extern int esp_register_ext_funcs (struct ext_funcs_t *); extern void esp_unregister_ext_funcs (void); -extern int esp_ble_ll_set_public_addr(const uint8_t *addr); +extern int r_esp_ble_ll_set_public_addr(const uint8_t *addr); extern int esp_register_npl_funcs (struct npl_funcs_t *p_npl_func); extern void esp_unregister_npl_funcs (void); extern void npl_freertos_mempool_deinit(void); -extern int os_msys_buf_alloc(void); extern uint32_t r_os_cputime_get32(void); extern uint32_t r_os_cputime_ticks_to_usecs(uint32_t ticks); -extern void ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, - void *w_arg, uint32_t us_to_enabled); +extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, + void *w_arg, uint32_t us_to_enabled); extern void r_ble_rtc_wake_up_state_clr(void); +extern int os_msys_init(void); +extern void os_msys_deinit(void); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); +extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ -extern int os_msys_init(void); -extern void os_msys_buf_free(void); +extern void r_esp_ble_change_rtc_freq(uint32_t freq); extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); extern int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv); -extern int ble_txpwr_set(esp_ble_enhanced_power_type_t power_type, uint16_t handle, int power_level); -extern int ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -extern int ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info); +extern int r_ble_txpwr_set(esp_ble_enhanced_power_type_t power_type, uint16_t handle, int power_level); +extern int r_ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle); +extern int r_ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info); +extern char *ble_controller_get_compile_version(void); +extern int esp_ble_register_bb_funcs(void); +extern void esp_ble_unregister_bb_funcs(void); extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; extern uint32_t _bt_controller_bss_start; @@ -168,16 +163,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no); -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); -static int hci_uart_config_wrapper(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); -static int hci_uart_close_wrapper(int uart_no); -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data); -static int hci_uart_init_wrapper(int uart_no, void *cfg); -#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in); static int esp_intr_free_wrapper(void **ret_handle); @@ -189,35 +174,226 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** */ /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; +enum log_out_mode { + LOG_DUMP_MEMORY, + LOG_ASYNC_OUT, + LOG_STORAGE_TO_FLASH, +}; -/* This variable tells if BLE is running */ -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE -static bool s_ble_backed_up = false; -#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE +bool log_is_inited = false; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY +uint8_t log_output_mode = LOG_DUMP_MEMORY; +#else +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; +#else +uint8_t log_output_mode = LOG_ASYNC_OUT; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY +void esp_bt_log_output_mode_set(uint8_t output_mode) +{ + log_output_mode = output_mode; +} + +uint8_t esp_bt_log_output_mode_get(void) +{ + return log_output_mode; +} + +esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) +{ + esp_err_t ret = ESP_OK; + interface_func_t bt_controller_log_interface; + bt_controller_log_interface = esp_bt_controller_log_interface; + bool task_create; + uint8_t buffers = 0; + + if (log_is_inited) { + return ret; + } + +#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + + switch (log_output_mode) { + case LOG_DUMP_MEMORY: + task_create = false; + break; + case LOG_ASYNC_OUT: + case LOG_STORAGE_TO_FLASH: + task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + if (log_output_mode == LOG_STORAGE_TO_FLASH) { + esp_bt_ctrl_log_partition_get_and_erase_first_block(); + } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + break; + default: + assert(0); + } + + ret = r_ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); + if (ret == ESP_OK) { + log_is_inited = true; + } + + return ret; +} + +void esp_bt_ontroller_log_deinit(void) +{ + r_ble_log_deinit_async(); + log_is_inited = false; +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#include "esp_partition.h" +#include "hal/wdt_hal.h" + +#define MAX_STORAGE_SIZE (CONFIG_BT_LE_CONTROLLER_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" + +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; + +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + r_ble_log_async_output_dump_all(true); + esp_bt_ontroller_log_deinit(); + stop_write = true; + + buffer = (const uint8_t *)mapped_ptr; + esp_panic_handler_reconfigure_wdts(5000); + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + esp_panic_handler_reconfigure_wdts(5000); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + + esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(log_output_mode); + assert(err == ESP_OK); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED + +/* This variable tells if BLE is running */ static bool s_ble_active = false; #ifdef CONFIG_PM_ENABLE static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; #define BTDM_MIN_TIMER_UNCERTAINTY_US (200) #endif // CONFIG_PM_ENABLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER #define BLE_RTC_DELAY_US_LIGHT_SLEEP (2500) #define BLE_RTC_DELAY_US_MODEM_SLEEP (500) -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER -#define BLE_RTC_DELAY_US_LIGHT_SLEEP (2000) -#define BLE_RTC_DELAY_US_MODEM_SLEEP (0) -static void ble_sleep_timer_callback(void *arg); -static DRAM_ATTR esp_timer_handle_t s_ble_sleep_timer = NULL; -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER static const struct osi_coex_funcs_t s_osi_coex_funcs_ro = { ._magic = OSI_COEX_MAGIC_VALUE, @@ -234,14 +410,6 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, ._free = bt_osi_mem_free, -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART - ._hal_uart_start_tx = hci_uart_start_tx_wrapper, - ._hal_uart_init_cbs = hci_uart_init_cbs_wrapper, - ._hal_uart_config = hci_uart_config_wrapper, - ._hal_uart_close = hci_uart_close_wrapper, - ._hal_uart_blocking_tx = hci_uart_blocking_tx_wrapper, - ._hal_uart_init = hci_uart_init_wrapper, -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, @@ -261,6 +429,9 @@ static void IRAM_ATTR osi_assert_wrapper(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2) { BT_ASSERT_PRINT("BLE assert: line %d in function %s, param: 0x%x, 0x%x", ln, fn, param1, param2); +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED + esp_ble_controller_log_dump_all(true); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED assert(0); } @@ -283,74 +454,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) #endif // CONFIG_SW_COEXIST_ENABLE } -#ifdef CONFIG_BT_BLUEDROID_ENABLED -bool esp_vhci_host_check_send_available(void) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return false; - } - return true; -} - -static struct os_mbuf *ble_hs_mbuf_gen_pkt(uint16_t leading_space) -{ - struct os_mbuf *om; - int rc; - - om = os_msys_get_pkthdr(0, 0); - if (om == NULL) { - return NULL; - } - - if (om->om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; -} -#endif // CONFIG_BT_BLUEDROID_ENABLED - static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { @@ -382,73 +485,6 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) -{ - if (!end) { - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x,", addr[i]); - } - - } else { - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x,", addr[i]); - } - esp_rom_printf("\n"); - } -} -#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) -{ - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); - return rc; -} - - -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, - uint8_t stop_bits, uart_parity_t parity, - uart_hw_flowcontrol_t flow_ctl) -{ - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - return rc; -} - -static int hci_uart_close_wrapper(int uart_no) -{ - int rc = -1; - rc = hci_uart_close(uart_no); - return rc; -} - -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) -{ - //This function is nowhere to use. -} - -static int hci_uart_init_wrapper(int uart_no, void *cfg) -{ - //This function is nowhere to use. - return 0; -} - -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; -} - static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) { @@ -465,47 +501,48 @@ static int esp_intr_free_wrapper(void **ret_handle) return rc; } +void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) +{ + /* Select slow clock source for BT momdule */ + switch (slow_clk_src) { + case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); + uint32_t chip_version = efuse_hal_chip_revision(); + if (chip_version == 0) { + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (400 - 1)); + } else{ + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1)); + } + break; + case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_XTAL32K: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_RC32K: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_EXT32K: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz oscillator as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); + break; + default: + } +} + IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) { if (!s_ble_active) { return; } #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - uint32_t delta_tick; - uint32_t us_to_sleep; - uint32_t sleep_tick; - uint32_t tick_invalid = *(uint32_t*)(arg); - assert(arg != NULL); - if (!tick_invalid) { - sleep_tick = r_os_cputime_get32(); - /* start a timer to wake up and acquire the pm_lock before modem_sleep awakes */ - delta_tick = enable_tick - sleep_tick; - if (delta_tick & 0x80000000) { - return; - } - us_to_sleep = r_os_cputime_ticks_to_usecs(delta_tick); - if (us_to_sleep <= BTDM_MIN_TIMER_UNCERTAINTY_US) { - return; - } - esp_err_t err = esp_timer_start_once(s_ble_sleep_timer, - us_to_sleep - BTDM_MIN_TIMER_UNCERTAINTY_US); - if (err != ESP_OK) { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ESP timer start failed"); - return; - } - } -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER r_ble_rtc_wake_up_state_clr(); -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER -#if SOC_PM_RETENTION_HAS_CLOCK_BUG - sleep_retention_do_extra_retention(true); - s_ble_backed_up = true; -#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ - esp_phy_disable(); + esp_phy_disable(PHY_MODEM_BT); #ifdef CONFIG_PM_ENABLE esp_pm_lock_release(s_pm_lock); #endif // CONFIG_PM_ENABLE @@ -518,30 +555,18 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) return; } #ifdef CONFIG_PM_ENABLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER esp_pm_lock_acquire(s_pm_lock); r_ble_rtc_wake_up_state_clr(); -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_RETENTION_HAS_CLOCK_BUG - sleep_retention_do_extra_retention(false); - s_ble_backed_up = false; -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_RETENTION_HAS_CLOCK_BUG */ #endif //CONFIG_PM_ENABLE - esp_phy_enable(); + esp_phy_enable(PHY_MODEM_BT); s_ble_active = true; } #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER -static void ble_sleep_timer_callback(void * arg) -{ - esp_pm_lock_acquire(s_pm_lock); -} -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - -esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) +static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) { uint8_t size; + int extra = *(int *)arg; const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) { @@ -550,12 +575,36 @@ esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) return err; } +static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) +{ + int retention_args = extra; + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } }, + .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC); + } + return err; +} + static void sleep_modem_ble_mac_modem_state_deinit(void) { - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_MAC); + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC); + if (err == ESP_OK) { + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC); + assert(err == ESP_OK); + } +} + +void sleep_modem_light_sleep_overhead_set(uint32_t overhead) +{ + r_esp_ble_set_wakeup_overhead(overhead); } #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ + esp_err_t controller_sleep_init(void) { esp_err_t rc = 0; @@ -563,10 +612,10 @@ esp_err_t controller_sleep_init(void) #ifdef CONFIG_BT_LE_SLEEP_ENABLE ESP_LOGW(NIMBLE_PORT_LOG_TAG, "BLE modem sleep is enabled"); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE - ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, + r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, BLE_RTC_DELAY_US_LIGHT_SLEEP); #else - ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, + r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, BLE_RTC_DELAY_US_MODEM_SLEEP); #endif /* FREERTOS_USE_TICKLESS_IDLE */ #endif // CONFIG_BT_LE_SLEEP_ENABLE @@ -576,49 +625,40 @@ esp_err_t controller_sleep_init(void) if (rc != ESP_OK) { goto error; } - esp_pm_lock_acquire(s_pm_lock); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - esp_timer_create_args_t create_args = { - .callback = ble_sleep_timer_callback, - .arg = NULL, - .name = "btSlp" - }; - rc = esp_timer_create(&create_args, &s_ble_sleep_timer); - if (rc != ESP_OK) { - goto error; - } - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is ESP timer"); -#endif //CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - +#if CONFIG_BT_LE_SLEEP_ENABLE && !CONFIG_MAC_BB_PD +#error "CONFIG_MAC_BB_PD required for BLE light sleep to run properly" +#endif // CONFIG_BT_LE_SLEEP_ENABLE && !CONFIG_MAC_BB_PD /* Create a new regdma link for BLE related register restoration */ rc = sleep_modem_ble_mac_modem_state_init(1); assert(rc == 0); -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER esp_sleep_enable_bt_wakeup(); ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer"); -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER + + rc = esp_pm_register_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); + if (rc != ESP_OK) { + goto error; + } + +#if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD + sleep_modem_register_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, + sleep_modem_mac_bb_power_up_prepare); +#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ return rc; error: #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER +#if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD + sleep_modem_unregister_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, + sleep_modem_mac_bb_power_up_prepare); +#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD esp_sleep_disable_bt_wakeup(); -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - if (s_ble_sleep_timer != NULL) { - esp_timer_stop(s_ble_sleep_timer); - esp_timer_delete(s_ble_sleep_timer); - s_ble_sleep_timer = NULL; - } -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER + esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ /*lock should release first and then delete*/ if (s_pm_lock != NULL) { - esp_pm_lock_release(s_pm_lock); esp_pm_lock_delete(s_pm_lock); s_pm_lock = NULL; } @@ -630,26 +670,17 @@ esp_err_t controller_sleep_init(void) void controller_sleep_deinit(void) { #if CONFIG_FREERTOS_USE_TICKLESS_IDLE - if (s_ble_backed_up) { - sleep_retention_module_deinit(); - s_ble_backed_up = false; - } -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER +#if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD + sleep_modem_unregister_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, + sleep_modem_mac_bb_power_up_prepare); +#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD r_ble_rtc_wake_up_state_clr(); esp_sleep_disable_bt_wakeup(); -#endif //CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER sleep_modem_ble_mac_modem_state_deinit(); -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - if (s_ble_sleep_timer != NULL) { - esp_timer_stop(s_ble_sleep_timer); - esp_timer_delete(s_ble_sleep_timer); - s_ble_sleep_timer = NULL; - } -#endif //CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER + esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ #ifdef CONFIG_PM_ENABLE /* lock should be released first */ - esp_pm_lock_release(s_pm_lock); esp_pm_lock_delete(s_pm_lock); s_pm_lock = NULL; #endif //CONFIG_PM_ENABLE @@ -667,16 +698,16 @@ typedef enum { }disc_duplicate_mode_t; -extern void filter_duplicate_mode_enable(disc_duplicate_mode_t mode); -extern void filter_duplicate_mode_disable(disc_duplicate_mode_t mode); -extern void filter_duplicate_set_ring_list_max_num(uint32_t max_num); -extern void scan_duplicate_cache_refresh_set_time(uint32_t period_time); +extern void r_filter_duplicate_mode_enable(disc_duplicate_mode_t mode); +extern void r_filter_duplicate_mode_disable(disc_duplicate_mode_t mode); +extern void r_filter_duplicate_set_ring_list_max_num(uint32_t max_num); +extern void r_scan_duplicate_cache_refresh_set_time(uint32_t period_time); int ble_vhci_disc_duplicate_mode_enable(int mode) { // TODO: use vendor hci to update - filter_duplicate_mode_enable(mode); + r_filter_duplicate_mode_enable(mode); return true; } @@ -684,19 +715,19 @@ int ble_vhci_disc_duplicate_mode_disable(int mode) { // TODO: use vendor hci to update - filter_duplicate_mode_disable(mode); + r_filter_duplicate_mode_disable(mode); return true; } int ble_vhci_disc_duplicate_set_max_cache_size(int max_cache_size){ // TODO: use vendor hci to update - filter_duplicate_set_ring_list_max_num(max_cache_size); + r_filter_duplicate_set_ring_list_max_num(max_cache_size); return true; } int ble_vhci_disc_duplicate_set_period_refresh_time(int refresh_period_time){ // TODO: use vendor hci to update - scan_duplicate_cache_refresh_set_time(refresh_period_time); + r_scan_duplicate_cache_refresh_set_time(refresh_period_time); return true; } @@ -706,7 +737,9 @@ int ble_vhci_disc_duplicate_set_period_refresh_time(int refresh_period_time){ void ble_controller_scan_duplicate_config(void) { uint32_t duplicate_mode = FILTER_DUPLICATE_DEFAULT; - uint32_t cache_size = CONFIG_BT_LE_SCAN_DUPL_CACHE_SIZE; + uint32_t cache_size = 100; +#if CONFIG_BT_LE_SCAN_DUPL == true + cache_size = CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT; if (CONFIG_BT_LE_SCAN_DUPL_TYPE == 0) { duplicate_mode = FILTER_DUPLICATE_ADDRESS | FILTER_DUPLICATE_PDUTYPE; } else if (CONFIG_BT_LE_SCAN_DUPL_TYPE == 1) { @@ -714,13 +747,14 @@ void ble_controller_scan_duplicate_config(void) } else if (CONFIG_BT_LE_SCAN_DUPL_TYPE == 2) { duplicate_mode = FILTER_DUPLICATE_ADDRESS | FILTER_DUPLICATE_ADVDATA; } - duplicate_mode |= FILTER_DUPLICATE_EXCEPTION_FOR_MESH; + ble_vhci_disc_duplicate_set_period_refresh_time(CONFIG_BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD); +#endif + ble_vhci_disc_duplicate_mode_disable(0xFFFFFFFF); ble_vhci_disc_duplicate_mode_enable(duplicate_mode); ble_vhci_disc_duplicate_set_max_cache_size(cache_size); - ble_vhci_disc_duplicate_set_period_refresh_time(CONFIG_BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD); } esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) @@ -728,9 +762,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) uint8_t mac[6]; esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; + uint32_t slow_clk_freq = 0; + uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_ERR_INVALID_STATE; @@ -761,7 +796,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_mem; } - ble_get_npl_element_info(cfg, &npl_info); + r_ble_get_npl_element_info(cfg, &npl_info); npl_freertos_set_controller_npl_info(&npl_info); if (npl_freertos_mempool_init() != 0) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "npl mempool init failed"); @@ -769,15 +804,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_mem; } - /* Initialize the global memory pool */ - ret = os_msys_buf_alloc(); - if (ret != ESP_OK) { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "os msys alloc failed"); - goto free_mem; - } - - os_msys_init(); - #if CONFIG_BT_NIMBLE_ENABLED /* ble_npl_eventq_init() needs to use npl functions in rom and * must be called after esp_bt_controller_init(). @@ -786,94 +812,116 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif // CONFIG_BT_NIMBLE_ENABLED /* Enable BT-related clocks */ modem_clock_module_enable(PERIPH_BT_MODULE); - + modem_clock_module_mac_reset(PERIPH_BT_MODULE); /* Select slow clock source for BT momdule */ #if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); - uint32_t chip_version = efuse_hal_chip_revision(); - if (chip_version == 0) { - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL, (400 - 1)); - } else{ - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL, (5 - 1)); - } + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); + slow_clk_freq = 100000; #else #if CONFIG_RTC_CLK_SRC_INT_RC - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_RC_SLOW, (5 - 1)); + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW); + slow_clk_freq = 30000; #elif CONFIG_RTC_CLK_SRC_EXT_CRYS - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source"); - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_XTAL32K, (1 - 1)); + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K); + slow_clk_freq = 32768; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); + slow_clk_freq = 100000; + } #elif CONFIG_RTC_CLK_SRC_INT_RC32K - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_RC32K, (1 - 1)); + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K); + slow_clk_freq = 32000; #elif CONFIG_RTC_CLK_SRC_EXT_OSC - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz oscillator as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_EXT32K, (1 - 1)); + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K); + slow_clk_freq = 32000; #else ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); assert(0); #endif #endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ esp_phy_modem_init(); - esp_phy_enable(); - esp_btbb_enable(); - s_ble_active = true; if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "osi coex funcs reg failed"); ret = ESP_ERR_INVALID_ARG; - goto free_controller; + goto modem_deint; } #if CONFIG_SW_COEXIST_ENABLE coex_init(); #endif // CONFIG_SW_COEXIST_ENABLE - ret = ble_controller_init(cfg); - if (ret != ESP_OK) { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_init failed %d", ret); - goto free_controller; - } - #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - ret = ble_log_init_async(bt_controller_log_interface, false); -#else - ret = ble_log_init_async(bt_controller_log_interface, true); -#endif // CONFIG_BT_CONTROLLER_LOG_DUMP + ret = esp_bt_controller_log_init(log_output_mode); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); - goto free_controller; + goto modem_deint; } #endif // CONFIG_BT_CONTROLLER_LOG_ENABLED + ret = esp_ble_register_bb_funcs(); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "esp_ble_register_bb_funcs failed %d", ret); + goto modem_deint; + } + + ret = r_ble_controller_init(cfg); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "r_ble_controller_init failed %d", ret); + goto modem_deint; + } + + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); + r_esp_ble_change_rtc_freq(slow_clk_freq); ble_controller_scan_duplicate_config(); + ret = os_msys_init(); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "msys_init failed %d", ret); + goto free_controller; + } + ret = controller_sleep_init(); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "controller_sleep_init failed %d", ret); goto free_controller; } + ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); swap_in_place(mac, 6); - esp_ble_ll_set_public_addr(mac); + r_esp_ble_ll_set_public_addr(mac); ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); - return ESP_OK; +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#if CONFIG_BT_LE_UART_HCI_DMA_MODE + hci_transport_mode = HCI_TRANSPORT_UART_UHCI; +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } + return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); + os_msys_deinit(); + r_ble_controller_deinit(); +modem_deint: + esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_log_deinit_async(); + esp_bt_ontroller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_controller_deinit(); - esp_btbb_disable(); - esp_phy_disable(); esp_phy_modem_deinit(); modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); @@ -881,7 +929,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ble_npl_eventq_deinit(nimble_port_get_dflt_eventq()); #endif // CONFIG_BT_NIMBLE_ENABLED free_mem: - os_msys_buf_free(); npl_freertos_mempool_deinit(); esp_unregister_npl_funcs(); npl_freertos_funcs_deinit(); @@ -897,30 +944,26 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); - esp_btbb_disable(); + os_msys_deinit(); - if (s_ble_active) { - esp_phy_disable(); - s_ble_active = false; - } esp_phy_modem_deinit(); modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); + r_ble_controller_deinit(); + esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_log_deinit_async(); + esp_bt_ontroller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_controller_deinit(); #if CONFIG_BT_NIMBLE_ENABLED /* De-initialize default event queue */ ble_npl_eventq_deinit(nimble_port_get_dflt_eventq()); #endif // CONFIG_BT_NIMBLE_ENABLED - os_msys_buf_free(); - esp_unregister_npl_funcs(); esp_unregister_ext_funcs(); @@ -947,12 +990,19 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_FAIL; } - + if (!s_ble_active) { +#if CONFIG_PM_ENABLE + esp_pm_lock_acquire(s_pm_lock); +#endif // CONFIG_PM_ENABLE + esp_phy_enable(PHY_MODEM_BT); + s_ble_active = true; + } + esp_btbb_enable(); #if CONFIG_SW_COEXIST_ENABLE coex_enable(); #endif // CONFIG_SW_COEXIST_ENABLE - if (ble_controller_enable(mode) != 0) { + if (r_ble_controller_enable(mode) != 0) { ret = ESP_FAIL; goto error; } @@ -963,6 +1013,14 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif + esp_btbb_disable(); + if (s_ble_active) { + esp_phy_disable(PHY_MODEM_BT); +#if CONFIG_PM_ENABLE + esp_pm_lock_release(s_pm_lock); +#endif // CONFIG_PM_ENABLE + s_ble_active = false; + } return ret; } @@ -972,12 +1030,20 @@ esp_err_t esp_bt_controller_disable(void) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_FAIL; } - if (ble_controller_disable() != 0) { + if (r_ble_controller_disable() != 0) { return ESP_FAIL; } #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif + esp_btbb_disable(); + if (s_ble_active) { + esp_phy_disable(PHY_MODEM_BT); +#if CONFIG_PM_ENABLE + esp_pm_lock_release(s_pm_lock); +#endif // CONFIG_PM_ENABLE + s_ble_active = false; + } ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; return ESP_OK; } @@ -1002,70 +1068,86 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) return ret; } + +typedef struct { + intptr_t start; + intptr_t end; + const char* name; +} bt_area_t; + +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) +{ + esp_err_t ret = ESP_OK; + intptr_t mem_start = area->start; + intptr_t mem_end = area->end; + if (mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + return ret; +} + +static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2) +{ + esp_err_t ret = ESP_OK; + + if (area1->end == area2->start) { + bt_area_t merged_area = { + .start = area1->start, + .end = area2->end, + .name = area1->name + }; + ret = esp_bt_mem_release_area(&merged_area); + } else { + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); + } + + return ret; +} + esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; - if (mode & ESP_BT_MODE_BLE) { - /* If the addresses of btdm .bss and bt .bss are consecutive, - * they are registered in the system heap as a piece of memory - */ - if(_bt_bss_end == _bt_controller_bss_start) { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_controller_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } - mem_start = (intptr_t)&_bt_controller_bss_start; - mem_end = (intptr_t)&_bt_controller_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + bt_area_t bss = { + .start = (intptr_t)&_bt_bss_start, + .end = (intptr_t)&_bt_bss_end, + .name = "BT BSS", + }; + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t data = { + .start = (intptr_t)&_bt_data_start, + .end = (intptr_t)&_bt_data_end, + .name = "BT Data", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + + if (mode & ESP_BT_MODE_BLE) { + /* Start by freeing Bluetooth BSS section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&bss, &cont_bss); } - /* If the addresses of btdm .data and bt .data are consecutive, - * they are registered in the system heap as a piece of memory - */ - if(_bt_data_end == _bt_controller_data_start) { - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_bt_controller_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_bt_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)&_bt_controller_data_start; - mem_end = (intptr_t)&_bt_controller_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller Data [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); } } - return ESP_OK; + return ret; } @@ -1082,7 +1164,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ case ESP_BLE_PWR_TYPE_DEFAULT: case ESP_BLE_PWR_TYPE_ADV: case ESP_BLE_PWR_TYPE_SCAN: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1095,7 +1177,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ case ESP_BLE_PWR_TYPE_CONN_HDL6: case ESP_BLE_PWR_TYPE_CONN_HDL7: case ESP_BLE_PWR_TYPE_CONN_HDL8: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type, power_level) == 0) { stat = ESP_OK; } break; @@ -1115,13 +1197,13 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { stat = ESP_OK; } break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: - if (ble_txpwr_set(power_type, handle, power_level) == 0) { + if (r_ble_txpwr_set(power_type, handle, power_level) == 0) { stat = ESP_OK; } break; @@ -1141,7 +1223,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) case ESP_BLE_PWR_TYPE_ADV: case ESP_BLE_PWR_TYPE_SCAN: case ESP_BLE_PWR_TYPE_DEFAULT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; case ESP_BLE_PWR_TYPE_CONN_HDL0: case ESP_BLE_PWR_TYPE_CONN_HDL1: @@ -1152,7 +1234,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) case ESP_BLE_PWR_TYPE_CONN_HDL6: case ESP_BLE_PWR_TYPE_CONN_HDL7: case ESP_BLE_PWR_TYPE_CONN_HDL8: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type); break; default: return ESP_PWR_LVL_INVALID; @@ -1174,11 +1256,11 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: - tx_level = ble_txpwr_get(power_type, handle); + tx_level = r_ble_txpwr_get(power_type, handle); break; default: return ESP_PWR_LVL_INVALID; @@ -1192,16 +1274,48 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po } #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +{ + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(1000); + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); + } + + if (end) { + esp_rom_printf("\n"); + } + portEXIT_CRITICAL_SAFE(&spinlock); + } +} + void esp_ble_controller_log_dump_all(bool output) { - ble_log_async_output_dump_all(output); + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_read_ctrl_log_from_flash(output); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + BT_ASSERT_PRINT("\r\n[DUMP_START:"); + r_ble_log_async_output_dump_all(output); + BT_ASSERT_PRINT(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + } } #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - -#if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED == true) +#if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) +#if CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #define BLE_SM_KEY_ERR 0x17 - #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS #include "mbedtls/aes.h" #if CONFIG_BT_LE_SM_SC @@ -1211,22 +1325,27 @@ void esp_ble_controller_log_dump_all(bool output) #include "mbedtls/cmac.h" #include "mbedtls/ecdh.h" #include "mbedtls/ecp.h" + +static mbedtls_ecp_keypair keypair; #endif // CONFIG_BT_LE_SM_SC + #else #include "tinycrypt/aes.h" #include "tinycrypt/constants.h" #include "tinycrypt/utils.h" + #if CONFIG_BT_LE_SM_SC #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" #endif // CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS -#if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS -#if CONFIG_BT_LE_SM_SC -static mbedtls_ecp_keypair keypair; -#endif // CONFIG_BT_LE_SM_SC -#endif// CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS +/* Based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */ +static const uint8_t ble_sm_alg_dbg_priv_key[32] = { + 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, + 0xd2, 0x10, 0x3f, 0x50, 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, + 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd +}; int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey) @@ -1273,8 +1392,7 @@ int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_ } /* Set PRNG */ - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0)) != 0) { + if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) { goto exit; } @@ -1324,19 +1442,10 @@ int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_ return 0; } -/* based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */ -static const uint8_t ble_sm_alg_dbg_priv_key[32] = { - 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, - 0xd2, 0x10, 0x3f, 0x50, 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, - 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd -}; - #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) { int rc = BLE_SM_KEY_ERR; - size_t olen = 0; - uint8_t pub[65] = {0}; mbedtls_entropy_context entropy = {0}; mbedtls_ctr_drbg_context ctr_drbg = {0}; @@ -1358,11 +1467,11 @@ static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) goto exit; } + size_t olen = 0; + uint8_t pub[65] = {0}; - if ((rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), - &keypair.MBEDTLS_PRIVATE(Q), - MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, pub, 65)) != 0) { + if ((rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, + &olen, pub, 65)) != 0) { goto exit; } @@ -1378,7 +1487,7 @@ static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) return 0; } -#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS +#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS /** * pub: 64 bytes @@ -1402,7 +1511,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) if (uECC_make_key(pk, priv, &curve_secp256r1) != TC_CRYPTO_SUCCESS) { return BLE_SM_KEY_ERR; } -#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS +#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS /* Make sure generated key isn't debug key. */ } while (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0); @@ -1410,7 +1519,8 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) swap_buf(&pub[32], &pk[32], 32); swap_in_place(priv, 32); #endif // CONFIG_BT_LE_SM_SC_DEBUG_KEYS - return 0; } -#endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED == true) + +#endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC +#endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) diff --git a/components/bt/include/esp32c6/include/esp_bt_cfg.h b/components/bt/controller/esp32c6/esp_bt_cfg.h similarity index 83% rename from components/bt/include/esp32c6/include/esp_bt_cfg.h rename to components/bt/controller/esp32c6/esp_bt_cfg.h index 3d5506b892..4e24c18614 100644 --- a/components/bt/include/esp32c6/include/esp_bt_cfg.h +++ b/components/bt/controller/esp32c6/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -39,8 +39,12 @@ extern "C" { #define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE) #define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT) - #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EFF #define DEFAULT_BT_LE_POWER_CONTROL_ENABLED MYNEWT_VAL(BLE_POWER_CONTROL) + #if defined(CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT) + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) + #else + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) + #endif #else #if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY @@ -115,16 +119,34 @@ extern "C" { #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8) #endif - #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF - #if defined(CONFIG_BT_LE_POWER_CONTROL_ENABLED) #define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (CONFIG_BT_LE_POWER_CONTROL_ENABLED) #else #define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (0) #endif -#endif + #if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT) + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) + #else + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) + #endif + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif +#endif +#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART @@ -162,8 +184,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -172,8 +192,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ @@ -196,19 +214,9 @@ extern "C" { #define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000) -#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL -#define RTC_FREQ_N (100000) /* in Hz */ -#else -#if CONFIG_RTC_CLK_SRC_INT_RC -#define RTC_FREQ_N (30000) /* in Hz */ -#elif CONFIG_RTC_CLK_SRC_EXT_CRYS #define RTC_FREQ_N (32768) /* in Hz */ -#else -#define RTC_FREQ_N (32000) /* in Hz */ -#endif -#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ -#define BLE_LL_TX_PWR_DBM_N (9) +#define BLE_LL_TX_PWR_DBM_N (CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF) #define RUN_BQB_TEST (0) diff --git a/components/bt/controller/esp32h2/Kconfig.in b/components/bt/controller/esp32h2/Kconfig.in index 454a054bf9..d188d03230 100644 --- a/components/bt/controller/esp32h2/Kconfig.in +++ b/components/bt/controller/esp32h2/Kconfig.in @@ -2,19 +2,37 @@ menu "HCI Config" choice BT_LE_HCI_INTERFACE - prompt "Select HCI interface" + prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM config BT_LE_HCI_INTERFACE_USE_RAM - bool "ram" + bool "VHCI" help Use RAM as HCI interface config BT_LE_HCI_INTERFACE_USE_UART - bool "uart" + bool "UART(H4)" help Use UART as HCI interface endchoice + choice BT_LE_UART_HCI_MODE_CHOICE + prompt "UART HCI mode" + depends on BT_LE_HCI_INTERFACE_USE_UART + default BT_LE_UART_HCI_NO_DMA_MODE + help + Specify UART HCI mode: DMA or No DMA + + config BT_LE_UART_HCI_DMA_MODE + bool "UHCI(UART with DMA)(EXPERIMENTAL)" + help + UART HCI Mode with DMA functionality. + + config BT_LE_UART_HCI_NO_DMA_MODE + bool "UART(NO DMA)" + help + UART HCI Mode without DMA functionality. + endchoice + config BT_LE_HCI_UART_PORT int "HCI UART port" depends on BT_LE_HCI_INTERFACE_USE_UART @@ -73,12 +91,40 @@ menu "HCI Config" UART_PARITY_ODD endchoice - config BT_LE_HCI_UART_TASK_STACK_SIZE - int "HCI uart task stack size" - depends on BT_LE_HCI_INTERFACE_USE_UART - default 1000 + config BT_LE_HCI_UART_RX_BUFFER_SIZE + int "The size of rx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 512 + help + The size of rx ring buffer memory + + config BT_LE_HCI_UART_TX_BUFFER_SIZE + int "The size of tx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 256 + help + The size of tx ring buffer memory + + config BT_LE_HCI_TRANS_TASK_STACK_SIZE + int "HCI transport task stack size" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 1024 + help + This configures stack size of hci transport task + + config BT_LE_HCI_TRANS_RX_MEM_NUM + int "The amount of rx memory received at the same time" + depends on BT_LE_UART_HCI_DMA_MODE + default 3 + help + The amount of rx memory received at the same time + + config BT_LE_HCI_LLDESCS_POOL_NUM + int "The amount of lldecs memory for driver dma mode" + depends on BT_LE_UART_HCI_DMA_MODE + default 20 help - Set the size of uart task stack + The amount of lldecs memory for driver dma mode endmenu config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT @@ -147,7 +193,7 @@ if BT_LE_EXT_ADV Enable this option to start periodic advertisement. config BT_LE_PERIODIC_ADV_SYNC_TRANSFER - bool "Enable Transer Sync Events" + bool "Enable Transfer Sync Events" depends on BT_LE_ENABLE_PERIODIC_ADV default y help @@ -260,18 +306,71 @@ config BT_LE_CONTROLLER_TASK_STACK_SIZE help This configures stack size of NimBLE controller task -config BT_LE_CONTROLLER_LOG_ENABLED +menuconfig BT_LE_CONTROLLER_LOG_ENABLED bool "Controller log enable" default n help - Enable controller log module + Enable controller log + +config BT_LE_CONTROLLER_LOG_CTRL_ENABLED + bool "enable controller log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help + Enable controller log module + +config BT_LE_CONTROLLER_LOG_HCI_ENABLED + bool "enable HCI log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help + Enable hci log module config BT_LE_CONTROLLER_LOG_DUMP_ONLY bool "Controller log dump mode only" depends on BT_LE_CONTROLLER_LOG_ENABLED default y help - Only operate in dump mode + Only operate in dump mode + +config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + bool "Store ble controller logs to flash(Experimental)" + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Store ble controller logs to flash memory. + +config BT_LE_CONTROLLER_LOG_PARTITION_SIZE + int "size of ble controller log partition(Multiples of 4K)" + depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + +config BT_LE_LOG_CTRL_BUF1_SIZE + int "size of the first BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help + Configure the size of the first BLE controller LOG buffer. + +config BT_LE_LOG_CTRL_BUF2_SIZE + int "size of the second BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 1024 + help + Configure the size of the second BLE controller LOG buffer. + +config BT_LE_LOG_HCI_BUF_SIZE + int "size of the BLE HCI LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help + Configure the size of the BLE HCI LOG buffer. config BT_LE_LL_RESOLV_LIST_SIZE int "BLE LL Resolving list size" @@ -321,7 +420,6 @@ config BT_LE_CRYPTO_STACK_MBEDTLS bool "Override TinyCrypt with mbedTLS for crypto computations" default y depends on !BT_NIMBLE_ENABLED - select MBEDTLS_ECP_RESTARTABLE select MBEDTLS_CMAC_C help Enable this option to choose mbedTLS instead of TinyCrypt for crypto @@ -338,7 +436,7 @@ config BT_LE_WHITELIST_SIZE config BT_LE_LL_DUP_SCAN_LIST_COUNT int "BLE duplicate scan list count" - range 1 100 + range 5 100 default 20 help config the max count of duplicate scan list @@ -353,7 +451,7 @@ config BT_LE_LL_SCA config BT_LE_MAX_CONNECTIONS int "Maximum number of concurrent connections" depends on !BT_NIMBLE_ENABLED - range 1 9 + range 1 35 default 3 help Defines maximum number of concurrent BLE connections. For ESP32, user @@ -365,7 +463,7 @@ config BT_LE_MAX_CONNECTIONS choice BT_LE_COEX_PHY_CODED_TX_RX_TLIM prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection" default BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS - depends on !BT_NIMBLE_ENABLED + depends on ESP_COEX_SW_COEXIST_ENABLE help When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to better avoid dramatic performance deterioration of Wi-Fi. @@ -383,7 +481,7 @@ endchoice config BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF int - depends on !BT_NIMBLE_ENABLED + default 0 if !ESP_COEX_SW_COEXIST_ENABLE default 1 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN default 0 if BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS @@ -393,21 +491,6 @@ config BT_LE_SLEEP_ENABLE help Enable BLE sleep -choice BT_LE_WAKEUP_SOURCE - prompt "BLE light sleep wakeup source" - depends on BT_LE_SLEEP_ENABLE - default BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - config BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - bool "Use ESP timer to wakeup CPU" - help - Use esp timer to wakeup CPU - - config BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - bool "Use BLE rtc timer to wakeup CPU" - help - Use BLE rtc timer to wakeup CPU -endchoice - choice BT_LE_LP_CLK_SRC prompt "BLE low power clock source" default BT_LE_LP_CLK_SRC_MAIN_XTAL @@ -436,6 +519,39 @@ config BT_LE_USE_ESP_TIMER Set this option to use Esp Timer which has higher priority timer instead of FreeRTOS timer +config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP + bool "BLE adv report flow control supported" + default y + help + The function is mainly used to enable flow control for advertising reports. When it is enabled, + advertising reports will be discarded by the controller if the number of unprocessed advertising + reports exceeds the size of BLE adv report flow control. + +config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM + int "BLE adv report flow control number" + depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP + range 50 1000 + default 100 + help + The number of unprocessed advertising report that bluetooth host can save.If you set + `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a small value, this may cause adv packets lost. + If you set `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` to a large value, bluetooth host may cache a + lot of adv packets and this may cause system memory run out. For example, if you set + it to 50, the maximum memory consumed by host is 35 * 50 bytes. Please set + `BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM` according to your system free memory and handle adv + packets as fast as possible, otherwise it will cause adv packets lost. + +config BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD + int "BLE adv lost event threshold value" + depends on BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP + range 1 1000 + default 20 + help + When adv report flow control is enabled, The ADV lost event will be generated when the number + of ADV packets lost in the controller reaches this threshold. It is better to set a larger value. + If you set `BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it + may cause adv packets lost more. + config BT_LE_SCAN_DUPL bool "BLE Scan Duplicate Options" default y @@ -482,16 +598,6 @@ config BT_LE_SCAN_DUPL_TYPE default 2 if BT_LE_SCAN_DUPL_TYPE_DATA_DEVICE default 0 - -config BT_LE_SCAN_DUPL_CACHE_SIZE - int "Maximum number of devices in scan duplicate filter" - depends on BT_LE_SCAN_DUPL - range 10 1000 - default 100 - help - Maximum number of devices which can be recorded in scan duplicate filter. - When the maximum amount of device in the filter is reached, the cache will be refreshed. - config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD int "Duplicate scan list refresh period (seconds)" depends on BT_LE_SCAN_DUPL @@ -507,3 +613,80 @@ config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD add new device information. 2. When the refresh period is up, the controller will clear all device information and start filtering again. + +config BT_LE_MSYS_INIT_IN_CONTROLLER + bool + default y + +config BT_LE_TX_CCA_ENABLED + bool "Enable TX CCA feature" + default n + help + Enable CCA feature to cancel sending the packet if the signal power is stronger than CCA threshold. + +config BT_LE_CCA_RSSI_THRESH + int "CCA RSSI threshold value" + depends on BT_LE_TX_CCA_ENABLED + range 20 100 + default 20 + help + Power threshold of CCA in unit of -1 dBm. + +choice BT_LE_DFT_TX_POWER_LEVEL_DBM + prompt "BLE default Tx power level(dBm)" + default BT_LE_DFT_TX_POWER_LEVEL_P9 + help + Specify default Tx power level(dBm). + config BT_LE_DFT_TX_POWER_LEVEL_N24 + bool "-24dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N21 + bool "-21dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N18 + bool "-18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N15 + bool "-15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N12 + bool "-12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N9 + bool "-9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N6 + bool "-6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N3 + bool "-3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N0 + bool "0dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P3 + bool "+3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P6 + bool "+6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P9 + bool "+9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P12 + bool "+12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P15 + bool "+15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P18 + bool "+18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" +endchoice + +config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF + int + default -24 if BT_LE_DFT_TX_POWER_LEVEL_N24 + default -21 if BT_LE_DFT_TX_POWER_LEVEL_N21 + default -18 if BT_LE_DFT_TX_POWER_LEVEL_N18 + default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15 + default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12 + default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9 + default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6 + default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3 + default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0 + default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3 + default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6 + default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9 + default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12 + default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15 + default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18 + default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20 + default 0 diff --git a/components/bt/controller/esp32h2/bt.c b/components/bt/controller/esp32h2/bt.c index 5acef98fa5..65c884bd68 100644 --- a/components/bt/controller/esp32h2/bt.c +++ b/components/bt/controller/esp32h2/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,9 @@ #include "sdkconfig.h" +#if CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port.h" +#endif // CONFIG_BT_NIMBLE_ENABLED #include "nimble/nimble_port_freertos.h" #include "esp_private/esp_modem_clock.h" @@ -24,11 +26,11 @@ #endif // ESP_PLATFORM #if CONFIG_SW_COEXIST_ENABLE -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #endif // CONFIG_SW_COEXIST_ENABLE #include "nimble/nimble_npl_os.h" -#include "nimble/ble_hci_trans.h" +#include "esp_hci_transport.h" #include "os/endian.h" #include "esp_bt.h" @@ -37,40 +39,31 @@ #include "esp_pm.h" #include "esp_phy_init.h" #include "esp_private/periph_ctrl.h" -#include "hci_uart.h" #include "bt_osi_mem.h" -#if SOC_PM_RETENTION_HAS_CLOCK_BUG +#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#include "esp_private/sleep_modem.h" #include "esp_private/sleep_retention.h" -#endif - -#ifdef CONFIG_BT_BLUEDROID_ENABLED -#include "hci/hci_hal.h" -#endif // CONFIG_BT_BLUEDROID_ENABLED +#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_private/periph_ctrl.h" #include "esp_sleep.h" +#include "soc/rtc.h" /* Macro definition ************************************************************************ */ #define NIMBLE_PORT_LOG_TAG "BLE_INIT" -#define OSI_COEX_VERSION 0x00010006 -#define OSI_COEX_MAGIC_VALUE 0xFADEBEAD +#define OSI_COEX_VERSION 0x00010006 +#define OSI_COEX_MAGIC_VALUE 0xFADEBEAD -#define EXT_FUNC_VERSION 0x20221122 +#define EXT_FUNC_VERSION 0x20240422 #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf -#ifdef CONFIG_BT_BLUEDROID_ENABLED -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -#define ACL_DATA_MBUF_LEADINGSPCAE 4 -#endif // CONFIG_BT_BLUEDROID_ENABLED - - /* Types definition ************************************************************************ */ @@ -89,12 +82,6 @@ struct ext_funcs_t { int (*_esp_intr_free)(void **ret_handle); void *(* _malloc)(size_t size); void (*_free)(void *p); - void (*_hal_uart_start_tx)(int); - int (*_hal_uart_init_cbs)(int, hci_uart_tx_char, hci_uart_tx_done, hci_uart_rx_char, void *); - int (*_hal_uart_config)(int, int32_t, uint8_t, uint8_t, uart_parity_t, uart_hw_flowcontrol_t); - int (*_hal_uart_close)(int); - void (*_hal_uart_blocking_tx)(int, uint8_t); - int (*_hal_uart_init)(int, void *); int (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); void (* _task_delete)(void *task_handle); @@ -114,39 +101,45 @@ typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); ************************************************************************ */ extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); -extern int ble_controller_init(esp_bt_controller_config_t *cfg); +extern int r_ble_controller_init(esp_bt_controller_config_t *cfg); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create); -extern int ble_log_deinit_async(void); -extern void ble_log_async_output_dump_all(bool output); +extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int r_ble_log_deinit_async(void); +extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); +extern void r_ble_log_async_output_dump_all(bool output); +extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int ble_controller_deinit(void); -extern int ble_controller_enable(uint8_t mode); -extern int ble_controller_disable(void); +extern int r_ble_controller_deinit(void); +extern int r_ble_controller_enable(uint8_t mode); +extern int r_ble_controller_disable(void); extern int esp_register_ext_funcs (struct ext_funcs_t *); extern void esp_unregister_ext_funcs (void); -extern int esp_ble_ll_set_public_addr(const uint8_t *addr); +extern int r_esp_ble_ll_set_public_addr(const uint8_t *addr); extern int esp_register_npl_funcs (struct npl_funcs_t *p_npl_func); extern void esp_unregister_npl_funcs (void); extern void npl_freertos_mempool_deinit(void); -extern int os_msys_buf_alloc(void); extern uint32_t r_os_cputime_get32(void); extern uint32_t r_os_cputime_ticks_to_usecs(uint32_t ticks); +extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, + void *w_arg, uint32_t us_to_enabled); +extern void r_ble_rtc_wake_up_state_clr(void); +extern int os_msys_init(void); +extern void os_msys_deinit(void); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); +extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ -extern void ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, - void *w_arg, uint32_t us_to_enabled); -extern void r_ble_rtc_wake_up_state_clr(void); -extern int os_msys_init(void); -extern void os_msys_buf_free(void); +extern void r_esp_ble_change_rtc_freq(uint32_t freq); extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); extern int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv); -extern int ble_txpwr_set(esp_ble_enhanced_power_type_t power_type, uint16_t handle, int power_level); -extern int ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -extern int ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info); +extern int r_ble_txpwr_set(esp_ble_enhanced_power_type_t power_type, uint16_t handle, int power_level); +extern int r_ble_txpwr_get(esp_ble_enhanced_power_type_t power_type, uint16_t handle); +extern int r_ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_count_info_t * npl_info); +extern char *ble_controller_get_compile_version(void); +extern int esp_ble_register_bb_funcs(void); +extern void esp_ble_unregister_bb_funcs(void); extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; extern uint32_t _bt_controller_bss_start; @@ -164,16 +157,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no); -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); -static int hci_uart_config_wrapper(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); -static int hci_uart_close_wrapper(int uart_no); -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data); -static int hci_uart_init_wrapper(int uart_no, void *cfg); -#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in); static int esp_intr_free_wrapper(void **ret_handle); @@ -185,12 +168,215 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // #if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** */ /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; +enum log_out_mode { + LOG_DUMP_MEMORY, + LOG_ASYNC_OUT, + LOG_STORAGE_TO_FLASH, +}; + +bool log_is_inited = false; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY +uint8_t log_output_mode = LOG_DUMP_MEMORY; +#else +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; +#else +uint8_t log_output_mode = LOG_ASYNC_OUT; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + +void esp_bt_log_output_mode_set(uint8_t output_mode) +{ + log_output_mode = output_mode; +} + +uint8_t esp_bt_log_output_mode_get(void) +{ + return log_output_mode; +} + +esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) +{ + esp_err_t ret = ESP_OK; + interface_func_t bt_controller_log_interface; + bt_controller_log_interface = esp_bt_controller_log_interface; + bool task_create; + uint8_t buffers = 0; + + if (log_is_inited) { + return ret; + } + +#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + + switch (log_output_mode) { + case LOG_DUMP_MEMORY: + task_create = false; + break; + case LOG_ASYNC_OUT: + case LOG_STORAGE_TO_FLASH: + task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + if (log_output_mode == LOG_STORAGE_TO_FLASH) { + esp_bt_ctrl_log_partition_get_and_erase_first_block(); + } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + break; + default: + assert(0); + } + + ret = r_ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); + if (ret == ESP_OK) { + log_is_inited = true; + } + return ret; +} + +void esp_bt_ontroller_log_deinit(void) +{ + r_ble_log_deinit_async(); + log_is_inited = false; +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#include "esp_partition.h" +#include "hal/wdt_hal.h" + +#define MAX_STORAGE_SIZE (CONFIG_BT_LE_CONTROLLER_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" + +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; + +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + r_ble_log_async_output_dump_all(true); + esp_bt_ontroller_log_deinit(); + stop_write = true; + + buffer = (const uint8_t *)mapped_ptr; + esp_panic_handler_reconfigure_wdts(5000); + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + esp_panic_handler_reconfigure_wdts(5000); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + + esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(log_output_mode); + assert(err == ESP_OK); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* This variable tells if BLE is running */ static bool s_ble_active = false; @@ -199,17 +385,8 @@ static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; #define BTDM_MIN_TIMER_UNCERTAINTY_US (200) #endif // CONFIG_PM_ENABLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER #define BLE_RTC_DELAY_US_LIGHT_SLEEP (5100) #define BLE_RTC_DELAY_US_MODEM_SLEEP (1500) -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER -#define BLE_RTC_DELAY_US_LIGHT_SLEEP (2000) -#define BLE_RTC_DELAY_US_MODEM_SLEEP (0) -static void ble_sleep_timer_callback(void *arg); -static DRAM_ATTR esp_timer_handle_t s_ble_sleep_timer = NULL; -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER static const struct osi_coex_funcs_t s_osi_coex_funcs_ro = { ._magic = OSI_COEX_MAGIC_VALUE, @@ -226,14 +403,6 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, ._free = bt_osi_mem_free, -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART - ._hal_uart_start_tx = hci_uart_start_tx_wrapper, - ._hal_uart_init_cbs = hci_uart_init_cbs_wrapper, - ._hal_uart_config = hci_uart_config_wrapper, - ._hal_uart_close = hci_uart_close_wrapper, - ._hal_uart_blocking_tx = hci_uart_blocking_tx_wrapper, - ._hal_uart_init = hci_uart_init_wrapper, -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, @@ -253,6 +422,9 @@ static void IRAM_ATTR osi_assert_wrapper(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2) { BT_ASSERT_PRINT("BLE assert: line %d in function %s, param: 0x%x, 0x%x", ln, fn, param1, param2); +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED + esp_ble_controller_log_dump_all(true); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED assert(0); } @@ -275,74 +447,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) #endif // CONFIG_SW_COEXIST_ENABLE } -#ifdef CONFIG_BT_BLUEDROID_ENABLED -bool esp_vhci_host_check_send_available(void) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return false; - } - return true; -} - -static struct os_mbuf *ble_hs_mbuf_gen_pkt(uint16_t leading_space) -{ - struct os_mbuf *om; - int rc; - - om = os_msys_get_pkthdr(0, 0); - if (om == NULL) { - return NULL; - } - - if (om->om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; -} -#endif // CONFIG_BT_BLUEDROID_ENABLED - static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { @@ -374,73 +478,6 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) -{ - if (!end) { - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x,", addr[i]); - } - - } else { - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x,", addr[i]); - } - esp_rom_printf("\n"); - } -} -#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) -{ - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); - return rc; -} - - -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, - uint8_t stop_bits, uart_parity_t parity, - uart_hw_flowcontrol_t flow_ctl) -{ - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - return rc; -} - -static int hci_uart_close_wrapper(int uart_no) -{ - int rc = -1; - rc = hci_uart_close(uart_no); - return rc; -} - -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) -{ - //This function is nowhere to use. -} - -static int hci_uart_init_wrapper(int uart_no, void *cfg) -{ - //This function is nowhere to use. - return 0; -} - -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; -} - static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) { @@ -457,46 +494,43 @@ static int esp_intr_free_wrapper(void **ret_handle) return rc; } +void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) +{ + /* Select slow clock source for BT momdule */ + switch (slow_clk_src) { + case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (320 - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_XTAL32K: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_RC32K: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_EXT32K: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz oscillator as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); + break; + default: + } +} + IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) { if (!s_ble_active) { return; } #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - uint32_t delta_tick; - uint32_t us_to_sleep; - uint32_t sleep_tick; - uint32_t tick_invalid = *(uint32_t*)(arg); - assert(arg != NULL); - if (!tick_invalid) { - sleep_tick = r_os_cputime_get32(); - /* start a timer to wake up and acquire the pm_lock before modem_sleep awakes */ - delta_tick = enable_tick - sleep_tick; - if (delta_tick & 0x80000000) { - return; - } - us_to_sleep = r_os_cputime_ticks_to_usecs(delta_tick); - if (us_to_sleep <= BTDM_MIN_TIMER_UNCERTAINTY_US) { - return; - } - esp_err_t err = esp_timer_start_once(s_ble_sleep_timer, - us_to_sleep - BTDM_MIN_TIMER_UNCERTAINTY_US); - if (err != ESP_OK) { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ESP timer start failed\n"); - return; - } - } -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER r_ble_rtc_wake_up_state_clr(); -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER -#if SOC_PM_RETENTION_HAS_CLOCK_BUG - sleep_retention_do_extra_retention(true); -#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ - esp_phy_disable(); + esp_phy_disable(PHY_MODEM_BT); #ifdef CONFIG_PM_ENABLE esp_pm_lock_release(s_pm_lock); #endif // CONFIG_PM_ENABLE @@ -509,29 +543,18 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) return; } #ifdef CONFIG_PM_ENABLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER esp_pm_lock_acquire(s_pm_lock); r_ble_rtc_wake_up_state_clr(); -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_RETENTION_HAS_CLOCK_BUG - sleep_retention_do_extra_retention(false); -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_RETENTION_HAS_CLOCK_BUG */ #endif //CONFIG_PM_ENABLE - esp_phy_enable(); + esp_phy_enable(PHY_MODEM_BT); s_ble_active = true; } #ifdef CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER -static void ble_sleep_timer_callback(void * arg) -{ - esp_pm_lock_acquire(s_pm_lock); -} -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - -static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) +static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) { uint8_t size; + int extra = *(int *)arg; const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) { @@ -540,12 +563,35 @@ static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) return err; } +static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) +{ + int retention_args = extra; + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } }, + .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC); + } + return err; +} + static void sleep_modem_ble_mac_modem_state_deinit(void) { - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_MAC); + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC); + if (err == ESP_OK) { + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC); + assert(err == ESP_OK); + } } -#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE +void sleep_modem_light_sleep_overhead_set(uint32_t overhead) +{ + r_esp_ble_set_wakeup_overhead(overhead); +} +#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ + esp_err_t controller_sleep_init(void) { @@ -554,10 +600,10 @@ esp_err_t controller_sleep_init(void) #ifdef CONFIG_BT_LE_SLEEP_ENABLE ESP_LOGW(NIMBLE_PORT_LOG_TAG, "BLE modem sleep is enabled"); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE - ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, + r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, BLE_RTC_DELAY_US_LIGHT_SLEEP); #else - ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, + r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, BLE_RTC_DELAY_US_MODEM_SLEEP); #endif /* FREERTOS_USE_TICKLESS_IDLE */ #endif // CONFIG_BT_LE_SLEEP_ENABLE @@ -567,49 +613,28 @@ esp_err_t controller_sleep_init(void) if (rc != ESP_OK) { goto error; } - esp_pm_lock_acquire(s_pm_lock); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - esp_timer_create_args_t create_args = { - .callback = ble_sleep_timer_callback, - .arg = NULL, - .name = "btSlp" - }; - rc = esp_timer_create(&create_args, &s_ble_sleep_timer); - if (rc != ESP_OK) { - goto error; - } - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is ESP timer"); -#endif //CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - /* Create a new regdma link for BLE related register restoration */ - rc = sleep_modem_ble_mac_modem_state_init(1); + rc = sleep_modem_ble_mac_modem_state_init(0); assert(rc == 0); -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER esp_sleep_enable_bt_wakeup(); ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer"); -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER + + rc = esp_pm_register_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); + if (rc != ESP_OK) { + goto error; + } #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ return rc; error: #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER esp_sleep_disable_bt_wakeup(); -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER - -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - if (s_ble_sleep_timer != NULL) { - esp_timer_stop(s_ble_sleep_timer); - esp_timer_delete(s_ble_sleep_timer); - s_ble_sleep_timer = NULL; - } -#endif // CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER + esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ /*lock should release first and then delete*/ if (s_pm_lock != NULL) { - esp_pm_lock_release(s_pm_lock); esp_pm_lock_delete(s_pm_lock); s_pm_lock = NULL; } @@ -621,22 +646,13 @@ esp_err_t controller_sleep_init(void) void controller_sleep_deinit(void) { #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER r_ble_rtc_wake_up_state_clr(); esp_sleep_disable_bt_wakeup(); -#endif //CONFIG_BT_LE_WAKEUP_SOURCE_BLE_RTC_TIMER sleep_modem_ble_mac_modem_state_deinit(); -#ifdef CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER - if (s_ble_sleep_timer != NULL) { - esp_timer_stop(s_ble_sleep_timer); - esp_timer_delete(s_ble_sleep_timer); - s_ble_sleep_timer = NULL; - } -#endif //CONFIG_BT_LE_WAKEUP_SOURCE_CPU_RTC_TIMER + esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ #ifdef CONFIG_PM_ENABLE /* lock should be released first */ - esp_pm_lock_release(s_pm_lock); esp_pm_lock_delete(s_pm_lock); s_pm_lock = NULL; #endif //CONFIG_PM_ENABLE @@ -654,16 +670,16 @@ typedef enum { }disc_duplicate_mode_t; -extern void filter_duplicate_mode_enable(disc_duplicate_mode_t mode); -extern void filter_duplicate_mode_disable(disc_duplicate_mode_t mode); -extern void filter_duplicate_set_ring_list_max_num(uint32_t max_num); -extern void scan_duplicate_cache_refresh_set_time(uint32_t period_time); +extern void r_filter_duplicate_mode_enable(disc_duplicate_mode_t mode); +extern void r_filter_duplicate_mode_disable(disc_duplicate_mode_t mode); +extern void r_filter_duplicate_set_ring_list_max_num(uint32_t max_num); +extern void r_scan_duplicate_cache_refresh_set_time(uint32_t period_time); int ble_vhci_disc_duplicate_mode_enable(int mode) { // TODO: use vendor hci to update - filter_duplicate_mode_enable(mode); + r_filter_duplicate_mode_enable(mode); return true; } @@ -671,19 +687,19 @@ int ble_vhci_disc_duplicate_mode_disable(int mode) { // TODO: use vendor hci to update - filter_duplicate_mode_disable(mode); + r_filter_duplicate_mode_disable(mode); return true; } int ble_vhci_disc_duplicate_set_max_cache_size(int max_cache_size){ // TODO: use vendor hci to update - filter_duplicate_set_ring_list_max_num(max_cache_size); + r_filter_duplicate_set_ring_list_max_num(max_cache_size); return true; } int ble_vhci_disc_duplicate_set_period_refresh_time(int refresh_period_time){ // TODO: use vendor hci to update - scan_duplicate_cache_refresh_set_time(refresh_period_time); + r_scan_duplicate_cache_refresh_set_time(refresh_period_time); return true; } @@ -693,7 +709,9 @@ int ble_vhci_disc_duplicate_set_period_refresh_time(int refresh_period_time){ void ble_controller_scan_duplicate_config(void) { uint32_t duplicate_mode = FILTER_DUPLICATE_DEFAULT; - uint32_t cache_size = CONFIG_BT_LE_SCAN_DUPL_CACHE_SIZE; + uint32_t cache_size = 100; +#if CONFIG_BT_LE_SCAN_DUPL == true + cache_size = CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT; if (CONFIG_BT_LE_SCAN_DUPL_TYPE == 0) { duplicate_mode = FILTER_DUPLICATE_ADDRESS | FILTER_DUPLICATE_PDUTYPE; } else if (CONFIG_BT_LE_SCAN_DUPL_TYPE == 1) { @@ -701,13 +719,14 @@ void ble_controller_scan_duplicate_config(void) } else if (CONFIG_BT_LE_SCAN_DUPL_TYPE == 2) { duplicate_mode = FILTER_DUPLICATE_ADDRESS | FILTER_DUPLICATE_ADVDATA; } - duplicate_mode |= FILTER_DUPLICATE_EXCEPTION_FOR_MESH; + ble_vhci_disc_duplicate_set_period_refresh_time(CONFIG_BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD); +#endif + ble_vhci_disc_duplicate_mode_disable(0xFFFFFFFF); ble_vhci_disc_duplicate_mode_enable(duplicate_mode); ble_vhci_disc_duplicate_set_max_cache_size(cache_size); - ble_vhci_disc_duplicate_set_period_refresh_time(CONFIG_BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD); } esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) @@ -715,9 +734,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) uint8_t mac[6]; esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; + uint32_t slow_clk_freq = 0; + uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_ERR_INVALID_STATE; @@ -748,7 +768,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_mem; } - ble_get_npl_element_info(cfg, &npl_info); + r_ble_get_npl_element_info(cfg, &npl_info); npl_freertos_set_controller_npl_info(&npl_info); if (npl_freertos_mempool_init() != 0) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "npl mempool init failed"); @@ -756,112 +776,128 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto free_mem; } - /* Initialize the global memory pool */ - ret = os_msys_buf_alloc(); - if (ret != ESP_OK) { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "os msys alloc failed"); - goto free_mem; - } - - os_msys_init(); - #if CONFIG_BT_NIMBLE_ENABLED /* ble_npl_eventq_init() needs to use npl functions in rom and * must be called after esp_bt_controller_init(). */ ble_npl_eventq_init(nimble_port_get_dflt_eventq()); #endif // CONFIG_BT_NIMBLE_ENABLED - /* Enable BT-related clocks */ modem_clock_module_enable(PERIPH_BT_MODULE); + modem_clock_module_mac_reset(PERIPH_BT_MODULE); + /* Select slow clock source for BT momdule */ #if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL, (320 - 1)); + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); + slow_clk_freq = 100000; #else #if CONFIG_RTC_CLK_SRC_INT_RC - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_RC_SLOW, (5 - 1)); + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW); + slow_clk_freq = 30000; #elif CONFIG_RTC_CLK_SRC_EXT_CRYS - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source"); - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_XTAL32K, (1 - 1)); + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K); + slow_clk_freq = 32768; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); + slow_clk_freq = 100000; + } #elif CONFIG_RTC_CLK_SRC_INT_RC32K - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_RC32K, (1 - 1)); + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K); + slow_clk_freq = 32000; #elif CONFIG_RTC_CLK_SRC_EXT_OSC - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz oscillator as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, MODEM_CLOCK_LPCLK_SRC_EXT32K, (1 - 1)); + esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K); + slow_clk_freq = 32000; #else ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); assert(0); #endif #endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ - esp_phy_enable(); - esp_btbb_enable(); - s_ble_active = true; if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "osi coex funcs reg failed"); ret = ESP_ERR_INVALID_ARG; - goto free_controller; + goto modem_deint; } #if CONFIG_SW_COEXIST_ENABLE coex_init(); #endif // CONFIG_SW_COEXIST_ENABLE - ret = ble_controller_init(cfg); - if (ret != ESP_OK) { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_init failed %d", ret); - goto free_controller; - } - #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - ret = ble_log_init_async(bt_controller_log_interface, false); -#else - ret = ble_log_init_async(bt_controller_log_interface, true); -#endif // CONFIG_BT_CONTROLLER_LOG_DUMP + ret = esp_bt_controller_log_init(log_output_mode); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); - goto free_controller; + goto modem_deint; } #endif // CONFIG_BT_CONTROLLER_LOG_ENABLED + ret = esp_ble_register_bb_funcs(); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "esp_ble_register_bb_funcs failed %d", ret); + goto modem_deint; + } + + ret = r_ble_controller_init(cfg); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "r_ble_controller_init failed %d", ret); + goto modem_deint; + } + + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); + r_esp_ble_change_rtc_freq(slow_clk_freq); ble_controller_scan_duplicate_config(); + ret = os_msys_init(); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "msys_init failed %d", ret); + goto free_controller; + } + ret = controller_sleep_init(); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "controller_sleep_init failed %d", ret); goto free_controller; } - ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); swap_in_place(mac, 6); - esp_ble_ll_set_public_addr(mac); + r_esp_ble_ll_set_public_addr(mac); ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); - return ESP_OK; +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#if CONFIG_BT_LE_UART_HCI_DMA_MODE + hci_transport_mode = HCI_TRANSPORT_UART_UHCI; +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } + return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); + os_msys_deinit(); + r_ble_controller_deinit(); +modem_deint: + esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_log_deinit_async(); + esp_bt_ontroller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_controller_deinit(); - esp_btbb_disable(); - esp_phy_disable(); modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); #if CONFIG_BT_NIMBLE_ENABLED ble_npl_eventq_deinit(nimble_port_get_dflt_eventq()); #endif // CONFIG_BT_NIMBLE_ENABLED free_mem: - os_msys_buf_free(); npl_freertos_mempool_deinit(); esp_unregister_npl_funcs(); npl_freertos_funcs_deinit(); @@ -877,29 +913,25 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); - esp_btbb_disable(); + os_msys_deinit(); - if (s_ble_active) { - esp_phy_disable(); - s_ble_active = false; - } modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); + r_ble_controller_deinit(); + esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_log_deinit_async(); + esp_bt_ontroller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_controller_deinit(); #if CONFIG_BT_NIMBLE_ENABLED /* De-initialize default event queue */ ble_npl_eventq_deinit(nimble_port_get_dflt_eventq()); #endif // CONFIG_BT_NIMBLE_ENABLED - os_msys_buf_free(); - esp_unregister_npl_funcs(); esp_unregister_ext_funcs(); @@ -926,12 +958,19 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_FAIL; } - + if (!s_ble_active) { +#if CONFIG_PM_ENABLE + esp_pm_lock_acquire(s_pm_lock); +#endif // CONFIG_PM_ENABLE + esp_phy_enable(PHY_MODEM_BT); + s_ble_active = true; + } + esp_btbb_enable(); #if CONFIG_SW_COEXIST_ENABLE coex_enable(); #endif // CONFIG_SW_COEXIST_ENABLE - if (ble_controller_enable(mode) != 0) { + if (r_ble_controller_enable(mode) != 0) { ret = ESP_FAIL; goto error; } @@ -942,6 +981,14 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif + esp_btbb_disable(); + if (s_ble_active) { + esp_phy_disable(PHY_MODEM_BT); +#if CONFIG_PM_ENABLE + esp_pm_lock_release(s_pm_lock); +#endif // CONFIG_PM_ENABLE + s_ble_active = false; + } return ret; } @@ -951,12 +998,20 @@ esp_err_t esp_bt_controller_disable(void) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_FAIL; } - if (ble_controller_disable() != 0) { + if (r_ble_controller_disable() != 0) { return ESP_FAIL; } #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif + esp_btbb_disable(); + if (s_ble_active) { + esp_phy_disable(PHY_MODEM_BT); +#if CONFIG_PM_ENABLE + esp_pm_lock_release(s_pm_lock); +#endif // CONFIG_PM_ENABLE + s_ble_active = false; + } ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; return ESP_OK; } @@ -981,70 +1036,86 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end) return ret; } + +typedef struct { + intptr_t start; + intptr_t end; + const char* name; +} bt_area_t; + +static esp_err_t esp_bt_mem_release_area(const bt_area_t *area) +{ + esp_err_t ret = ESP_OK; + intptr_t mem_start = area->start; + intptr_t mem_end = area->end; + if (mem_start != mem_end) { + ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start); + ret = try_heap_caps_add_region(mem_start, mem_end); + } + return ret; +} + +static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2) +{ + esp_err_t ret = ESP_OK; + + if (area1->end == area2->start) { + bt_area_t merged_area = { + .start = area1->start, + .end = area2->end, + .name = area1->name + }; + ret = esp_bt_mem_release_area(&merged_area); + } else { + esp_bt_mem_release_area(area1); + ret = esp_bt_mem_release_area(area2); + } + + return ret; +} + esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) { - intptr_t mem_start, mem_end; + esp_err_t ret = ESP_OK; - if (mode & ESP_BT_MODE_BLE) { - /* If the addresses of btdm .bss and bt .bss are consecutive, - * they are registered in the system heap as a piece of memory - */ - if(_bt_bss_end == _bt_controller_bss_start) { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_controller_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)&_bt_bss_start; - mem_end = (intptr_t)&_bt_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return ESP_ERR_INVALID_STATE; + } - mem_start = (intptr_t)&_bt_controller_bss_start; - mem_end = (intptr_t)&_bt_controller_bss_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller BSS [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + bt_area_t bss = { + .start = (intptr_t)&_bt_bss_start, + .end = (intptr_t)&_bt_bss_end, + .name = "BT BSS", + }; + bt_area_t cont_bss = { + .start = (intptr_t)&_bt_controller_bss_start, + .end = (intptr_t)&_bt_controller_bss_end, + .name = "BT Controller BSS", + }; + bt_area_t data = { + .start = (intptr_t)&_bt_data_start, + .end = (intptr_t)&_bt_data_end, + .name = "BT Data", + }; + bt_area_t cont_data = { + .start = (intptr_t)&_bt_controller_data_start, + .end = (intptr_t)&_bt_controller_data_end, + .name = "BT Controller Data" + }; + + if (mode & ESP_BT_MODE_BLE) { + /* Start by freeing Bluetooth BSS section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&bss, &cont_bss); } - /* If the addresses of btdm .data and bt .data are consecutive, - * they are registered in the system heap as a piece of memory - */ - if(_bt_data_end == _bt_controller_data_start) { - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_bt_controller_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release data [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - } else { - mem_start = (intptr_t)&_bt_data_start; - mem_end = (intptr_t)&_bt_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } - mem_start = (intptr_t)&_bt_controller_data_start; - mem_end = (intptr_t)&_bt_controller_data_end; - if (mem_start != mem_end) { - ESP_LOGD(NIMBLE_PORT_LOG_TAG, "Release Controller Data [0x%08x] - [0x%08x], len %d", - mem_start, mem_end, mem_end - mem_start); - ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end)); - } + /* Do the same thing with the Bluetooth data section */ + if (ret == ESP_OK) { + ret = esp_bt_mem_release_areas(&data, &cont_data); } } - return ESP_OK; + return ret; } @@ -1061,7 +1132,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ case ESP_BLE_PWR_TYPE_DEFAULT: case ESP_BLE_PWR_TYPE_ADV: case ESP_BLE_PWR_TYPE_SCAN: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1074,7 +1145,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ case ESP_BLE_PWR_TYPE_CONN_HDL6: case ESP_BLE_PWR_TYPE_CONN_HDL7: case ESP_BLE_PWR_TYPE_CONN_HDL8: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type, power_level) == 0) { stat = ESP_OK; } break; @@ -1094,13 +1165,13 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { stat = ESP_OK; } break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: - if (ble_txpwr_set(power_type, handle, power_level) == 0) { + if (r_ble_txpwr_set(power_type, handle, power_level) == 0) { stat = ESP_OK; } break; @@ -1120,7 +1191,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) case ESP_BLE_PWR_TYPE_ADV: case ESP_BLE_PWR_TYPE_SCAN: case ESP_BLE_PWR_TYPE_DEFAULT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; case ESP_BLE_PWR_TYPE_CONN_HDL0: case ESP_BLE_PWR_TYPE_CONN_HDL1: @@ -1131,7 +1202,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) case ESP_BLE_PWR_TYPE_CONN_HDL6: case ESP_BLE_PWR_TYPE_CONN_HDL7: case ESP_BLE_PWR_TYPE_CONN_HDL8: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_CONN, power_type); break; default: return ESP_PWR_LVL_INVALID; @@ -1153,11 +1224,11 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: - tx_level = ble_txpwr_get(power_type, handle); + tx_level = r_ble_txpwr_get(power_type, handle); break; default: return ESP_PWR_LVL_INVALID; @@ -1171,16 +1242,47 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po } #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +{ + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#endif //CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(1000); + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); + } + + if (end) { + esp_rom_printf("\n"); + } + portEXIT_CRITICAL_SAFE(&spinlock); + } +} + void esp_ble_controller_log_dump_all(bool output) { - ble_log_async_output_dump_all(output); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_read_ctrl_log_from_flash(output); +#else + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_reconfigure_wdts(5000); + BT_ASSERT_PRINT("\r\n[DUMP_START:"); + r_ble_log_async_output_dump_all(output); + BT_ASSERT_PRINT(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE } #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - -#if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED == true) +#if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) +#if CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #define BLE_SM_KEY_ERR 0x17 - #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS #include "mbedtls/aes.h" #if CONFIG_BT_LE_SM_SC @@ -1190,22 +1292,27 @@ void esp_ble_controller_log_dump_all(bool output) #include "mbedtls/cmac.h" #include "mbedtls/ecdh.h" #include "mbedtls/ecp.h" + +static mbedtls_ecp_keypair keypair; #endif // CONFIG_BT_LE_SM_SC + #else #include "tinycrypt/aes.h" #include "tinycrypt/constants.h" #include "tinycrypt/utils.h" + #if CONFIG_BT_LE_SM_SC #include "tinycrypt/cmac_mode.h" #include "tinycrypt/ecc_dh.h" #endif // CONFIG_BT_LE_SM_SC #endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS -#if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS -#if CONFIG_BT_LE_SM_SC -static mbedtls_ecp_keypair keypair; -#endif // CONFIG_BT_LE_SM_SC -#endif// CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS +/* Based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */ +static const uint8_t ble_sm_alg_dbg_priv_key[32] = { + 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, + 0xd2, 0x10, 0x3f, 0x50, 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, + 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd +}; int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey) @@ -1252,8 +1359,7 @@ int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_ } /* Set PRNG */ - if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - NULL, 0)) != 0) { + if ((rc = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) { goto exit; } @@ -1303,19 +1409,10 @@ int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_ return 0; } -/* based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */ -static const uint8_t ble_sm_alg_dbg_priv_key[32] = { - 0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, - 0xd2, 0x10, 0x3f, 0x50, 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, - 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd -}; - #if CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) { int rc = BLE_SM_KEY_ERR; - size_t olen = 0; - uint8_t pub[65] = {0}; mbedtls_entropy_context entropy = {0}; mbedtls_ctr_drbg_context ctr_drbg = {0}; @@ -1337,11 +1434,11 @@ static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) goto exit; } + size_t olen = 0; + uint8_t pub[65] = {0}; - if ((rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), - &keypair.MBEDTLS_PRIVATE(Q), - MBEDTLS_ECP_PF_UNCOMPRESSED, - &olen, pub, 65)) != 0) { + if ((rc = mbedtls_ecp_point_write_binary(&keypair.MBEDTLS_PRIVATE(grp), &keypair.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, + &olen, pub, 65)) != 0) { goto exit; } @@ -1357,7 +1454,7 @@ static int mbedtls_gen_keypair(uint8_t *public_key, uint8_t *private_key) return 0; } -#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS +#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS /** * pub: 64 bytes @@ -1381,7 +1478,7 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) if (uECC_make_key(pk, priv, &curve_secp256r1) != TC_CRYPTO_SUCCESS) { return BLE_SM_KEY_ERR; } -#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS +#endif // CONFIG_BT_LE_CRYPTO_STACK_MBEDTLS /* Make sure generated key isn't debug key. */ } while (memcmp(priv, ble_sm_alg_dbg_priv_key, 32) == 0); @@ -1389,7 +1486,8 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) swap_buf(&pub[32], &pk[32], 32); swap_in_place(priv, 32); #endif // CONFIG_BT_LE_SM_SC_DEBUG_KEYS - return 0; } -#endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED == true) + +#endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC +#endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) diff --git a/components/bt/include/esp32h2/include/esp_bt_cfg.h b/components/bt/controller/esp32h2/esp_bt_cfg.h similarity index 83% rename from components/bt/include/esp32h2/include/esp_bt_cfg.h rename to components/bt/controller/esp32h2/esp_bt_cfg.h index 339417c485..22a09be3ad 100644 --- a/components/bt/include/esp32h2/include/esp_bt_cfg.h +++ b/components/bt/controller/esp32h2/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -39,8 +39,12 @@ extern "C" { #define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE) #define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT) - #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EFF #define DEFAULT_BT_LE_POWER_CONTROL_ENABLED MYNEWT_VAL(BLE_POWER_CONTROL) + #if defined(CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT) + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) + #else + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) + #endif #else #if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY @@ -115,16 +119,34 @@ extern "C" { #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8) #endif - #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF - #if defined(CONFIG_BT_LE_POWER_CONTROL_ENABLED) #define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (CONFIG_BT_LE_POWER_CONTROL_ENABLED) #else #define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (0) #endif -#endif + #if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT) + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) + #else + #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) + #endif + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif +#endif +#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART @@ -162,8 +184,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -172,8 +192,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ @@ -196,20 +214,9 @@ extern "C" { #define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000) -#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL -#define RTC_FREQ_N (100000) /* in Hz */ -#else -#if CONFIG_RTC_CLK_SRC_INT_RC -#define RTC_FREQ_N (30000) /* in Hz */ -#elif CONFIG_RTC_CLK_SRC_EXT_CRYS #define RTC_FREQ_N (32768) /* in Hz */ -#else -#define RTC_FREQ_N (32000) /* in Hz */ -#endif -#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ - -#define BLE_LL_TX_PWR_DBM_N (9) +#define BLE_LL_TX_PWR_DBM_N (CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF) #define RUN_BQB_TEST (0) #define RUN_QA_TEST (0) diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index e1b3a29c58..f21a9ef6a4 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit e1b3a29c58a452a6c017113686262094afd87042 +Subproject commit f21a9ef6a4af418621fab356755151d309aae568 diff --git a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib index 5fcfd0e457..db84a7e453 160000 --- a/components/bt/controller/lib_esp32c2/esp32c2-bt-lib +++ b/components/bt/controller/lib_esp32c2/esp32c2-bt-lib @@ -1 +1 @@ -Subproject commit 5fcfd0e457a76ebb234086ccd6dc391690d69e90 +Subproject commit db84a7e4539c5d9e6b8ec882b82a5de0fb8400c7 diff --git a/components/bt/controller/lib_esp32c3_family b/components/bt/controller/lib_esp32c3_family index b438f60a29..ef1dfc5185 160000 --- a/components/bt/controller/lib_esp32c3_family +++ b/components/bt/controller/lib_esp32c3_family @@ -1 +1 @@ -Subproject commit b438f60a295183e7c67eb42ae05f4580f4b1ced0 +Subproject commit ef1dfc518572e9cda55f13906e32207b40ee280b diff --git a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib index d785de0a7c..aa8d03a0ff 160000 --- a/components/bt/controller/lib_esp32c6/esp32c6-bt-lib +++ b/components/bt/controller/lib_esp32c6/esp32c6-bt-lib @@ -1 +1 @@ -Subproject commit d785de0a7c46d9badcd73bc83c2e5cb78f7054b2 +Subproject commit aa8d03a0ff51c166267207e54002613bcedc576e diff --git a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib index 35bd3cd735..1db0566dcd 160000 --- a/components/bt/controller/lib_esp32h2/esp32h2-bt-lib +++ b/components/bt/controller/lib_esp32h2/esp32h2-bt-lib @@ -1 +1 @@ -Subproject commit 35bd3cd7352014d303a96c46d8ea8446ea0a9a54 +Subproject commit 1db0566dcdf5a0bd69632415f6dd148ab2ea0ac6 diff --git a/components/bt/esp_ble_mesh/Kconfig.in b/components/bt/esp_ble_mesh/Kconfig.in index 714c476b8e..cb2a41a6b9 100644 --- a/components/bt/esp_ble_mesh/Kconfig.in +++ b/components/bt/esp_ble_mesh/Kconfig.in @@ -6,15 +6,23 @@ if BLE_MESH help It is a temporary solution and needs further modifications. + config BLE_MESH_RANDOM_ADV_INTERVAL + bool "Support using random adv interval for mesh packets" + select BT_BLE_HIGH_DUTY_ADV_INTERVAL if BT_BLUEDROID_ENABLED + default n + help + Enable this option to allow using random advertising interval + for mesh packets. And this could help avoid collision of + advertising packets. + config BLE_MESH_USE_DUPLICATE_SCAN bool "Support Duplicate Scan in BLE Mesh" - depends on BT_BLUEDROID_ENABLED select BTDM_BLE_SCAN_DUPL if IDF_TARGET_ESP32 select BTDM_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32 - select BT_CTRL_BLE_SCAN_DUPL if IDF_TARGET_ESP32C3 - select BT_CTRL_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32C3 - select BT_LE_SCAN_DUPL if IDF_TARGET_ESP32C6 - select BT_LE_SCAN_DUPL if IDF_TARGET_ESP32H2 + select BT_CTRL_BLE_SCAN_DUPL if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 + select BT_CTRL_BLE_MESH_SCAN_DUPL_EN if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 + select BT_LE_SCAN_DUPL if IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2 + select BT_NIMBLE_VS_SUPPORT if BT_NIMBLE_ENABLED default y help Enable this option to allow using specific duplicate scan filter @@ -538,6 +546,20 @@ if BLE_MESH Provisioner can provision up to 20 nodes and each node contains two elements, then the replay protection list size of Provisioner should be at least 40. + config BLE_MESH_NOT_RELAY_REPLAY_MSG + bool "Not relay replayed messages in a mesh network" + depends on BLE_MESH_EXPERIMENTAL + default n + help + There may be many expired messages in a complex mesh network that would be + considered replayed messages. + Enable this option will refuse to relay such messages, which could help to + reduce invalid packets in the mesh network. + However, it should be noted that enabling this option may result in packet + loss in certain environments. + Therefore, users need to decide whether to enable this option according to + the actual usage situation. + config BLE_MESH_MSG_CACHE_SIZE int "Network message cache size" default 10 @@ -1241,4 +1263,12 @@ if BLE_MESH endmenu + config BLE_MESH_EXPERIMENTAL + bool "Make BLE Mesh experimental features visible" + default n + help + Make BLE Mesh Experimental features visible. + Experimental features list: + - CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG + endif # BLE_MESH diff --git a/components/bt/esp_ble_mesh/README.md b/components/bt/esp_ble_mesh/README.md index e25e0b3a36..83e9ea40fe 100644 --- a/components/bt/esp_ble_mesh/README.md +++ b/components/bt/esp_ble_mesh/README.md @@ -15,7 +15,7 @@ The ESP-BLE-MESH networking enables many-to-many (m:m) device communications and - [FAQ](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/esp_ble_mesh/ble_mesh_faq.html) - [API Reference](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/bluetooth/ble_mesh.html) - -### [ESP-BLE-MESH Examples](https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/esp_ble_mesh) + +### [ESP-BLE-MESH Examples](../../../examples/bluetooth/esp_ble_mesh) - Refer to **ESP-BLE-MESH Examples** of [Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/esp_ble_mesh/index.html##getting-started-with-ble-mesh) for the tutorials of ESP BLE Mesh examples. diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c index a469452f00..8212878608 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_common_api.c @@ -65,7 +65,9 @@ esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp esp_err_t esp_ble_mesh_deinit(esp_ble_mesh_deinit_param_t *param) { btc_ble_mesh_prov_args_t arg = {0}; + SemaphoreHandle_t semaphore = NULL; btc_msg_t msg = {0}; + esp_err_t ret = ESP_OK; if (param == NULL) { return ESP_ERR_INVALID_ARG; @@ -73,13 +75,36 @@ esp_err_t esp_ble_mesh_deinit(esp_ble_mesh_deinit_param_t *param) ESP_BLE_HOST_STATUS_CHECK(ESP_BLE_HOST_STATUS_ENABLED); + // Create a semaphore + if ((semaphore = xSemaphoreCreateCounting(1, 0)) == NULL) { + BT_ERR("Failed to create semaphore"); + return ESP_ERR_NO_MEM; + } + arg.mesh_deinit.param.erase_flash = param->erase_flash; + /* Transport semaphore pointer to BTC layer, and will give the semaphore in the BTC task */ + arg.mesh_deinit.semaphore = semaphore; msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; msg.act = BTC_BLE_MESH_ACT_DEINIT_MESH; - return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) - == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + if (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) != BT_STATUS_SUCCESS) { + vSemaphoreDelete(semaphore); + BT_ERR("Failed to start mesh deinit"); + return ESP_FAIL; + } + + /* Take the Semaphore, wait BLE Mesh de-initialization to finish. */ + __ASSERT(xSemaphoreTake(semaphore, 3000 / portTICK_PERIOD_MS) == pdTRUE, "BLE Mesh deinit take semaphore failed"); + /* Don't forget to delete the semaphore at the end. */ + vSemaphoreDelete(semaphore); + + ret = bt_mesh_host_deinit(); + if (ret != ESP_OK) { + return ret; + } + + return ESP_OK; } #endif /* CONFIG_BLE_MESH_DEINIT */ diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c index 3bc1a60eae..96ca756ebf 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -569,9 +569,9 @@ esp_err_t esp_ble_mesh_provisioner_set_heartbeat_filter_info(uint8_t op, esp_ble return ESP_ERR_INVALID_ARG; } - if (!ESP_BLE_MESH_ADDR_IS_UNICAST(info->hb_src) && - !ESP_BLE_MESH_ADDR_IS_UNICAST(info->hb_dst) && - !ESP_BLE_MESH_ADDR_IS_GROUP(info->hb_dst)) { + if (!(ESP_BLE_MESH_ADDR_IS_UNICAST(info->hb_src) && + (ESP_BLE_MESH_ADDR_IS_UNICAST(info->hb_dst) || + ESP_BLE_MESH_ADDR_IS_GROUP(info->hb_dst)))) { return ESP_ERR_INVALID_ARG; } diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c index 017164a7c2..586f6251b5 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -139,9 +139,9 @@ esp_err_t esp_ble_mesh_node_input_string(const char *string) msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_PROV; msg.act = BTC_BLE_MESH_ACT_INPUT_STRING; - memset(arg.input_string.string, 0, sizeof(arg.input_string.string)); - strncpy(arg.input_string.string, string, - MIN(strlen(string), sizeof(arg.input_string.string))); + + arg.input_string.string[sizeof(arg.input_string.string) - 1] = 0; + strncpy(arg.input_string.string, string, sizeof(arg.input_string.string) - 1); return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); @@ -162,8 +162,8 @@ esp_err_t esp_ble_mesh_set_unprovisioned_device_name(const char *name) msg.pid = BTC_PID_PROV; msg.act = BTC_BLE_MESH_ACT_SET_DEVICE_NAME; - memset(arg.set_device_name.name, 0, sizeof(arg.set_device_name.name)); - strncpy(arg.set_device_name.name, name, ESP_BLE_MESH_DEVICE_NAME_MAX_LEN); + arg.set_device_name.name[sizeof(arg.set_device_name.name) - 1] = 0; + strncpy(arg.set_device_name.name, name, sizeof(arg.set_device_name.name) - 1); return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); @@ -210,9 +210,8 @@ esp_err_t esp_ble_mesh_provisioner_input_string(const char *string, uint8_t link msg.pid = BTC_PID_PROV; msg.act = BTC_BLE_MESH_ACT_PROVISIONER_INPUT_STR; - memset(arg.provisioner_input_str.string, 0, sizeof(arg.provisioner_input_str.string)); - strncpy(arg.provisioner_input_str.string, string, - MIN(strlen(string), sizeof(arg.provisioner_input_str.string))); + arg.provisioner_input_str.string[sizeof(arg.provisioner_input_str.string) - 1] = 0; + strncpy(arg.provisioner_input_str.string, string, sizeof(arg.provisioner_input_str.string) - 1); arg.provisioner_input_str.link_idx = link_idx; return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_mesh_prov_args_t), NULL, NULL) diff --git a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h index f7209d8e5f..556565e7f2 100644 --- a/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h +++ b/components/bt/esp_ble_mesh/api/core/include/esp_ble_mesh_common_api.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,7 +33,10 @@ esp_err_t esp_ble_mesh_init(esp_ble_mesh_prov_t *prov, esp_ble_mesh_comp_t *comp /** * @brief De-initialize BLE Mesh module. * - * @note This function shall be invoked after esp_ble_mesh_client_model_deinit(). + * @note + * 1. This function shall be invoked after esp_ble_mesh_client_model_deinit(). + * 2. This function is strictly forbidden to run in any BTC Task Context + * (e.g. registered Mesh Event Callback). * * @param[in] param: Pointer to the structure of BLE Mesh deinit parameters. * diff --git a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h index 2134831306..3fadb19a16 100644 --- a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h +++ b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h @@ -68,6 +68,14 @@ typedef uint8_t esp_ble_mesh_octet8_t[ESP_BLE_MESH_OCTET8_LEN]; #define ESP_BLE_MESH_KEY_PRIMARY 0x0000 #define ESP_BLE_MESH_KEY_ANY 0xFFFF +/*!< Internal macros used to initialize array members */ +#define ESP_BLE_MESH_KEY_UNUSED_ELT_(IDX, _) ESP_BLE_MESH_KEY_UNUSED +#define ESP_BLE_MESH_ADDR_UNASSIGNED_ELT_(IDX, _) ESP_BLE_MESH_ADDR_UNASSIGNED +#define ESP_BLE_MESH_MODEL_KEYS_UNUSED \ + { LISTIFY(CONFIG_BLE_MESH_MODEL_KEY_COUNT, ESP_BLE_MESH_KEY_UNUSED_ELT_, (,)) } +#define ESP_BLE_MESH_MODEL_GROUPS_UNASSIGNED \ + { LISTIFY(CONFIG_BLE_MESH_MODEL_GROUP_COUNT, ESP_BLE_MESH_ADDR_UNASSIGNED_ELT_, (,)) } + /*!< Primary Network Key index */ #define ESP_BLE_MESH_NET_PRIMARY 0x000 @@ -264,26 +272,24 @@ typedef enum { #define ESP_BLE_MESH_SIG_MODEL(_id, _op, _pub, _user_data) \ { \ .model_id = (_id), \ - .op = _op, \ - .keys = { [0 ... (CONFIG_BLE_MESH_MODEL_KEY_COUNT - 1)] = \ - ESP_BLE_MESH_KEY_UNUSED }, \ .pub = _pub, \ - .groups = { [0 ... (CONFIG_BLE_MESH_MODEL_GROUP_COUNT - 1)] = \ - ESP_BLE_MESH_ADDR_UNASSIGNED }, \ + .keys = ESP_BLE_MESH_MODEL_KEYS_UNUSED, \ + .groups = ESP_BLE_MESH_MODEL_GROUPS_UNASSIGNED, \ + .op = _op, \ .user_data = _user_data, \ } /*!< This macro is associated with BLE_MESH_MODEL_VND_CB in mesh_access.h */ #define ESP_BLE_MESH_VENDOR_MODEL(_company, _id, _op, _pub, _user_data) \ { \ - .vnd.company_id = (_company), \ - .vnd.model_id = (_id), \ - .op = _op, \ + .vnd = { \ + .company_id = (_company), \ + .model_id = (_id), \ + }, \ .pub = _pub, \ - .keys = { [0 ... (CONFIG_BLE_MESH_MODEL_KEY_COUNT - 1)] = \ - ESP_BLE_MESH_KEY_UNUSED }, \ - .groups = { [0 ... (CONFIG_BLE_MESH_MODEL_GROUP_COUNT - 1)] = \ - ESP_BLE_MESH_ADDR_UNASSIGNED }, \ + .keys = ESP_BLE_MESH_MODEL_KEYS_UNUSED, \ + .groups = ESP_BLE_MESH_MODEL_GROUPS_UNASSIGNED, \ + .op = _op, \ .user_data = _user_data, \ } @@ -302,8 +308,8 @@ typedef enum { { \ .location = (_loc), \ .sig_model_count = ARRAY_SIZE(_mods), \ - .sig_models = (_mods), \ .vnd_model_count = ARRAY_SIZE(_vnd_mods), \ + .sig_models = (_mods), \ .vnd_models = (_vnd_mods), \ } @@ -416,8 +422,8 @@ typedef struct { #define ESP_BLE_MESH_MODEL_PUB_DEFINE(_name, _msg_len, _role) \ NET_BUF_SIMPLE_DEFINE_STATIC(bt_mesh_pub_msg_##_name, _msg_len); \ static esp_ble_mesh_model_pub_t _name = { \ - .update = (uint32_t)NULL, \ .msg = &bt_mesh_pub_msg_##_name, \ + .update = (uint32_t)NULL, \ .dev_role = _role, \ } diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c index 59be9f5d87..e5ab5a333d 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -57,6 +57,29 @@ #include "esp_ble_mesh_provisioning_api.h" #include "esp_ble_mesh_networking_api.h" +#if CONFIG_BLE_MESH_DEINIT +static SemaphoreHandle_t deinit_comp_semaphore; +#endif + +static inline void btc_ble_mesh_prov_cb_to_app_reprocess(esp_ble_mesh_prov_cb_event_t event, + esp_ble_mesh_prov_cb_param_t *param) +{ + switch (event) { +#if CONFIG_BLE_MESH_DEINIT + case ESP_BLE_MESH_DEINIT_MESH_COMP_EVT: + assert(deinit_comp_semaphore); + /* Give the semaphore when BLE Mesh de-initialization is finished. + * @note: At nimble host, once this lock is released, it will cause + * the btc task to be deleted. + */ + xSemaphoreGive(deinit_comp_semaphore); + break; +#endif + default: + break; + } +} + static inline void btc_ble_mesh_prov_cb_to_app(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_param_t *param) { @@ -65,6 +88,8 @@ static inline void btc_ble_mesh_prov_cb_to_app(esp_ble_mesh_prov_cb_event_t even if (btc_ble_mesh_cb) { btc_ble_mesh_cb(event, param); } + + btc_ble_mesh_prov_cb_to_app_reprocess(event, param); } static inline void btc_ble_mesh_model_cb_to_app(esp_ble_mesh_model_cb_event_t event, @@ -2268,6 +2293,8 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) case BTC_BLE_MESH_ACT_DEINIT_MESH: act = ESP_BLE_MESH_DEINIT_MESH_COMP_EVT; param.deinit_mesh_comp.err_code = bt_mesh_deinit((struct bt_mesh_deinit_param *)&arg->mesh_deinit.param); + /* Temporarily save the deinit semaphore and release it after the mesh deinit complete event is handled in the app layer */ + deinit_comp_semaphore = arg->mesh_deinit.semaphore; break; #endif /* CONFIG_BLE_MESH_DEINIT */ default: diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c index dde61d4138..b6d71f8d7f 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c @@ -79,7 +79,7 @@ void btc_ble_mesh_time_scene_client_arg_deep_free(btc_msg_t *msg) { btc_ble_mesh_time_scene_client_args_t *arg = NULL; - if (!msg || !msg->arg) { + if (!msg) { BT_ERR("%s, Invalid parameter", __func__); return; } @@ -166,7 +166,7 @@ static void btc_ble_mesh_time_scene_client_free_req_data(btc_msg_t *msg) { esp_ble_mesh_time_scene_client_cb_param_t *arg = NULL; - if (!msg || !msg->arg) { + if (!msg) { BT_ERR("%s, Invalid parameter", __func__); return; } @@ -293,7 +293,7 @@ void btc_ble_mesh_time_scene_client_call_handler(btc_msg_t *msg) esp_ble_mesh_time_scene_client_cb_param_t cb = {0}; bt_mesh_client_common_param_t common = {0}; - if (!msg || !msg->arg) { + if (!msg) { BT_ERR("%s, Invalid parameter", __func__); return; } @@ -353,7 +353,7 @@ void btc_ble_mesh_time_scene_client_cb_handler(btc_msg_t *msg) { esp_ble_mesh_time_scene_client_cb_param_t *param = NULL; - if (!msg || !msg->arg) { + if (!msg) { BT_ERR("%s, Invalid parameter", __func__); return; } diff --git a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h index b9cd0156d5..c61159bcea 100644 --- a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h +++ b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_prov.h @@ -309,6 +309,7 @@ typedef union { } model_unsub_group_addr; struct ble_mesh_deinit_args { esp_ble_mesh_deinit_param_t param; + SemaphoreHandle_t semaphore; } mesh_deinit; } btc_ble_mesh_prov_args_t; diff --git a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_time_scene_model.h b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_time_scene_model.h index 6c878dc776..850a77493e 100644 --- a/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_time_scene_model.h +++ b/components/bt/esp_ble_mesh/btc/include/btc_ble_mesh_time_scene_model.h @@ -45,6 +45,8 @@ void btc_ble_mesh_time_scene_client_cb_handler(btc_msg_t *msg); void btc_ble_mesh_time_scene_client_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); +void btc_ble_mesh_time_scene_client_arg_deep_free(btc_msg_t *msg); + void btc_ble_mesh_time_scene_client_publish_callback(uint32_t opcode, struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_atomic.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_atomic.h index 6d62840e46..aafe357f7f 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_atomic.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_atomic.h @@ -147,6 +147,33 @@ static inline bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, extern bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value); #endif +/** + * @brief Atomic CAS operation. + * + * This compares the contents of @a *target + * with the contents of @a excepted. If equal, + * the operation is a read-modify-write operation + * that writes @a new_val into @a *target and return true. + * If they are not equal, the operation is a read + * and return false. + * + * @param target Address of atomic variable. + * @param excepted Value of excepted. + * @param new_val Write if target value is equal to expected one. + * + * @return + * - true: Target value updated. + * - false: Target value not updated. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val) +{ + return __atomic_compare_exchange_n(target, &excepted, &new_val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} +#else +extern bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val); +#endif + /** * @cond INTERNAL_HIDDEN */ diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h index 33baa8cc81..bb63ee8eed 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h @@ -840,22 +840,22 @@ struct net_buf_pool { #if defined(CONFIG_BLE_MESH_NET_BUF_POOL_USAGE) #define NET_BUF_POOL_INITIALIZER(_pool, _alloc, _bufs, _count, _destroy) \ { \ - .alloc = _alloc, \ - .__bufs = (struct net_buf *)_bufs, \ .buf_count = _count, \ .uninit_count = _count, \ .avail_count = _count, \ - .destroy = _destroy, \ .name = STRINGIFY(_pool), \ + .destroy = _destroy, \ + .alloc = _alloc, \ + .__bufs = (struct net_buf *)_bufs, \ } #else #define NET_BUF_POOL_INITIALIZER(_pool, _alloc, _bufs, _count, _destroy) \ { \ - .alloc = _alloc, \ - .__bufs = (struct net_buf *)_bufs, \ .buf_count = _count, \ .uninit_count = _count, \ .destroy = _destroy, \ + .alloc = _alloc, \ + .__bufs = (struct net_buf *)_bufs, \ } #endif /* CONFIG_BLE_MESH_NET_BUF_POOL_USAGE */ diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_common.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_common.h index 2f6b7b1d4f..09fcceadeb 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_common.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_common.h @@ -67,6 +67,8 @@ uint8_t bt_mesh_get_device_role(struct bt_mesh_model *model, bool srv_send); int bt_mesh_rand(void *buf, size_t len); +uint32_t bt_mesh_get_rand(void); + #ifdef __cplusplus } #endif diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_util.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_util.h index c12c8d70a6..2173b2a2e9 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_util.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_util.h @@ -17,6 +17,7 @@ #include #include "esp_bit_defs.h" #include "mesh_types.h" +#include "mesh_utils_loops.h" #ifdef __cplusplus extern "C" { @@ -180,6 +181,40 @@ extern "C" { */ #define Z_IS_ENABLED3(ignore_this, val, ...) val +/* Used to remove brackets from around a single argument. */ +#define __DEBRACKET(...) __VA_ARGS__ + +#define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__) +#define UTIL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__ + +/** + * @brief Generates a sequence of code with configurable separator. + * + * Example: + * + * #define FOO(i, _) MY_PWM ## i + * { LISTIFY(PWM_COUNT, FOO, (,)) } + * + * The above two lines expand to: + * + * { MY_PWM0 , MY_PWM1 } + * + * @param LEN The length of the sequence. Must be an integer literal less + * than 255. + * @param F A macro function that accepts at least two arguments: + * F(i, ...). @p F is called repeatedly in the expansion. + * Its first argument @p i is the index in the sequence, and + * the variable list of arguments passed to LISTIFY are passed + * through to @p F. + * + * @param sep Separator (e.g. comma or semicolon). Must be in parentheses; + * this is required to enable providing a comma as separator. + * + * @note Calling LISTIFY with undefined arguments has undefined + * behavior. + */ +#define LISTIFY(LEN, F, sep, ...) UTIL_CAT(Z_UTIL_LISTIFY_, LEN)(F, sep, __VA_ARGS__) + const char *bt_hex(const void *buf, size_t len); void mem_rcopy(uint8_t *dst, uint8_t const *src, uint16_t len); diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_utils_loops.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_utils_loops.h new file mode 100644 index 0000000000..e454f1e071 --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_utils_loops.h @@ -0,0 +1,1051 @@ +/* + * SPDX-FileCopyrightText: 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Internals for looping macros + * + * Repetitive or obscure helper macros needed by mesh_util.h. + */ + +#ifndef _BLE_MESH_UTIL_LOOPS_H_ +#define _BLE_MESH_UTIL_LOOPS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Set of UTIL_LISTIFY particles */ +#define Z_UTIL_LISTIFY_0(F, sep, ...) + +#define Z_UTIL_LISTIFY_1(F, sep, ...) \ + F(0, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_2(F, sep, ...) \ + Z_UTIL_LISTIFY_1(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(1, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_3(F, sep, ...) \ + Z_UTIL_LISTIFY_2(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(2, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_4(F, sep, ...) \ + Z_UTIL_LISTIFY_3(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(3, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_5(F, sep, ...) \ + Z_UTIL_LISTIFY_4(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(4, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_6(F, sep, ...) \ + Z_UTIL_LISTIFY_5(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(5, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_7(F, sep, ...) \ + Z_UTIL_LISTIFY_6(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(6, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_8(F, sep, ...) \ + Z_UTIL_LISTIFY_7(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(7, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_9(F, sep, ...) \ + Z_UTIL_LISTIFY_8(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(8, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_10(F, sep, ...) \ + Z_UTIL_LISTIFY_9(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(9, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_11(F, sep, ...) \ + Z_UTIL_LISTIFY_10(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(10, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_12(F, sep, ...) \ + Z_UTIL_LISTIFY_11(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(11, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_13(F, sep, ...) \ + Z_UTIL_LISTIFY_12(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(12, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_14(F, sep, ...) \ + Z_UTIL_LISTIFY_13(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(13, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_15(F, sep, ...) \ + Z_UTIL_LISTIFY_14(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(14, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_16(F, sep, ...) \ + Z_UTIL_LISTIFY_15(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(15, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_17(F, sep, ...) \ + Z_UTIL_LISTIFY_16(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(16, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_18(F, sep, ...) \ + Z_UTIL_LISTIFY_17(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(17, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_19(F, sep, ...) \ + Z_UTIL_LISTIFY_18(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(18, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_20(F, sep, ...) \ + Z_UTIL_LISTIFY_19(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(19, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_21(F, sep, ...) \ + Z_UTIL_LISTIFY_20(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(20, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_22(F, sep, ...) \ + Z_UTIL_LISTIFY_21(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(21, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_23(F, sep, ...) \ + Z_UTIL_LISTIFY_22(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(22, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_24(F, sep, ...) \ + Z_UTIL_LISTIFY_23(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(23, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_25(F, sep, ...) \ + Z_UTIL_LISTIFY_24(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(24, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_26(F, sep, ...) \ + Z_UTIL_LISTIFY_25(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(25, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_27(F, sep, ...) \ + Z_UTIL_LISTIFY_26(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(26, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_28(F, sep, ...) \ + Z_UTIL_LISTIFY_27(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(27, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_29(F, sep, ...) \ + Z_UTIL_LISTIFY_28(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(28, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_30(F, sep, ...) \ + Z_UTIL_LISTIFY_29(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(29, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_31(F, sep, ...) \ + Z_UTIL_LISTIFY_30(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(30, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_32(F, sep, ...) \ + Z_UTIL_LISTIFY_31(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(31, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_33(F, sep, ...) \ + Z_UTIL_LISTIFY_32(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(32, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_34(F, sep, ...) \ + Z_UTIL_LISTIFY_33(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(33, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_35(F, sep, ...) \ + Z_UTIL_LISTIFY_34(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(34, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_36(F, sep, ...) \ + Z_UTIL_LISTIFY_35(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(35, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_37(F, sep, ...) \ + Z_UTIL_LISTIFY_36(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(36, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_38(F, sep, ...) \ + Z_UTIL_LISTIFY_37(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(37, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_39(F, sep, ...) \ + Z_UTIL_LISTIFY_38(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(38, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_40(F, sep, ...) \ + Z_UTIL_LISTIFY_39(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(39, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_41(F, sep, ...) \ + Z_UTIL_LISTIFY_40(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(40, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_42(F, sep, ...) \ + Z_UTIL_LISTIFY_41(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(41, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_43(F, sep, ...) \ + Z_UTIL_LISTIFY_42(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(42, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_44(F, sep, ...) \ + Z_UTIL_LISTIFY_43(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(43, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_45(F, sep, ...) \ + Z_UTIL_LISTIFY_44(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(44, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_46(F, sep, ...) \ + Z_UTIL_LISTIFY_45(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(45, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_47(F, sep, ...) \ + Z_UTIL_LISTIFY_46(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(46, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_48(F, sep, ...) \ + Z_UTIL_LISTIFY_47(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(47, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_49(F, sep, ...) \ + Z_UTIL_LISTIFY_48(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(48, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_50(F, sep, ...) \ + Z_UTIL_LISTIFY_49(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(49, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_51(F, sep, ...) \ + Z_UTIL_LISTIFY_50(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(50, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_52(F, sep, ...) \ + Z_UTIL_LISTIFY_51(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(51, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_53(F, sep, ...) \ + Z_UTIL_LISTIFY_52(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(52, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_54(F, sep, ...) \ + Z_UTIL_LISTIFY_53(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(53, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_55(F, sep, ...) \ + Z_UTIL_LISTIFY_54(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(54, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_56(F, sep, ...) \ + Z_UTIL_LISTIFY_55(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(55, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_57(F, sep, ...) \ + Z_UTIL_LISTIFY_56(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(56, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_58(F, sep, ...) \ + Z_UTIL_LISTIFY_57(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(57, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_59(F, sep, ...) \ + Z_UTIL_LISTIFY_58(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(58, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_60(F, sep, ...) \ + Z_UTIL_LISTIFY_59(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(59, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_61(F, sep, ...) \ + Z_UTIL_LISTIFY_60(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(60, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_62(F, sep, ...) \ + Z_UTIL_LISTIFY_61(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(61, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_63(F, sep, ...) \ + Z_UTIL_LISTIFY_62(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(62, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_64(F, sep, ...) \ + Z_UTIL_LISTIFY_63(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(63, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_65(F, sep, ...) \ + Z_UTIL_LISTIFY_64(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(64, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_66(F, sep, ...) \ + Z_UTIL_LISTIFY_65(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(65, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_67(F, sep, ...) \ + Z_UTIL_LISTIFY_66(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(66, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_68(F, sep, ...) \ + Z_UTIL_LISTIFY_67(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(67, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_69(F, sep, ...) \ + Z_UTIL_LISTIFY_68(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(68, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_70(F, sep, ...) \ + Z_UTIL_LISTIFY_69(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(69, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_71(F, sep, ...) \ + Z_UTIL_LISTIFY_70(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(70, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_72(F, sep, ...) \ + Z_UTIL_LISTIFY_71(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(71, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_73(F, sep, ...) \ + Z_UTIL_LISTIFY_72(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(72, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_74(F, sep, ...) \ + Z_UTIL_LISTIFY_73(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(73, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_75(F, sep, ...) \ + Z_UTIL_LISTIFY_74(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(74, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_76(F, sep, ...) \ + Z_UTIL_LISTIFY_75(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(75, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_77(F, sep, ...) \ + Z_UTIL_LISTIFY_76(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(76, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_78(F, sep, ...) \ + Z_UTIL_LISTIFY_77(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(77, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_79(F, sep, ...) \ + Z_UTIL_LISTIFY_78(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(78, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_80(F, sep, ...) \ + Z_UTIL_LISTIFY_79(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(79, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_81(F, sep, ...) \ + Z_UTIL_LISTIFY_80(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(80, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_82(F, sep, ...) \ + Z_UTIL_LISTIFY_81(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(81, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_83(F, sep, ...) \ + Z_UTIL_LISTIFY_82(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(82, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_84(F, sep, ...) \ + Z_UTIL_LISTIFY_83(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(83, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_85(F, sep, ...) \ + Z_UTIL_LISTIFY_84(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(84, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_86(F, sep, ...) \ + Z_UTIL_LISTIFY_85(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(85, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_87(F, sep, ...) \ + Z_UTIL_LISTIFY_86(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(86, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_88(F, sep, ...) \ + Z_UTIL_LISTIFY_87(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(87, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_89(F, sep, ...) \ + Z_UTIL_LISTIFY_88(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(88, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_90(F, sep, ...) \ + Z_UTIL_LISTIFY_89(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(89, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_91(F, sep, ...) \ + Z_UTIL_LISTIFY_90(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(90, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_92(F, sep, ...) \ + Z_UTIL_LISTIFY_91(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(91, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_93(F, sep, ...) \ + Z_UTIL_LISTIFY_92(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(92, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_94(F, sep, ...) \ + Z_UTIL_LISTIFY_93(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(93, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_95(F, sep, ...) \ + Z_UTIL_LISTIFY_94(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(94, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_96(F, sep, ...) \ + Z_UTIL_LISTIFY_95(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(95, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_97(F, sep, ...) \ + Z_UTIL_LISTIFY_96(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(96, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_98(F, sep, ...) \ + Z_UTIL_LISTIFY_97(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(97, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_99(F, sep, ...) \ + Z_UTIL_LISTIFY_98(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(98, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_100(F, sep, ...) \ + Z_UTIL_LISTIFY_99(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(99, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_101(F, sep, ...) \ + Z_UTIL_LISTIFY_100(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(100, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_102(F, sep, ...) \ + Z_UTIL_LISTIFY_101(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(101, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_103(F, sep, ...) \ + Z_UTIL_LISTIFY_102(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(102, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_104(F, sep, ...) \ + Z_UTIL_LISTIFY_103(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(103, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_105(F, sep, ...) \ + Z_UTIL_LISTIFY_104(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(104, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_106(F, sep, ...) \ + Z_UTIL_LISTIFY_105(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(105, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_107(F, sep, ...) \ + Z_UTIL_LISTIFY_106(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(106, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_108(F, sep, ...) \ + Z_UTIL_LISTIFY_107(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(107, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_109(F, sep, ...) \ + Z_UTIL_LISTIFY_108(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(108, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_110(F, sep, ...) \ + Z_UTIL_LISTIFY_109(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(109, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_111(F, sep, ...) \ + Z_UTIL_LISTIFY_110(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(110, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_112(F, sep, ...) \ + Z_UTIL_LISTIFY_111(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(111, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_113(F, sep, ...) \ + Z_UTIL_LISTIFY_112(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(112, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_114(F, sep, ...) \ + Z_UTIL_LISTIFY_113(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(113, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_115(F, sep, ...) \ + Z_UTIL_LISTIFY_114(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(114, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_116(F, sep, ...) \ + Z_UTIL_LISTIFY_115(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(115, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_117(F, sep, ...) \ + Z_UTIL_LISTIFY_116(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(116, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_118(F, sep, ...) \ + Z_UTIL_LISTIFY_117(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(117, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_119(F, sep, ...) \ + Z_UTIL_LISTIFY_118(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(118, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_120(F, sep, ...) \ + Z_UTIL_LISTIFY_119(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(119, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_121(F, sep, ...) \ + Z_UTIL_LISTIFY_120(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(120, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_122(F, sep, ...) \ + Z_UTIL_LISTIFY_121(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(121, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_123(F, sep, ...) \ + Z_UTIL_LISTIFY_122(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(122, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_124(F, sep, ...) \ + Z_UTIL_LISTIFY_123(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(123, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_125(F, sep, ...) \ + Z_UTIL_LISTIFY_124(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(124, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_126(F, sep, ...) \ + Z_UTIL_LISTIFY_125(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(125, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_127(F, sep, ...) \ + Z_UTIL_LISTIFY_126(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(126, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_128(F, sep, ...) \ + Z_UTIL_LISTIFY_127(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(127, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_129(F, sep, ...) \ + Z_UTIL_LISTIFY_128(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(128, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_130(F, sep, ...) \ + Z_UTIL_LISTIFY_129(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(129, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_131(F, sep, ...) \ + Z_UTIL_LISTIFY_130(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(130, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_132(F, sep, ...) \ + Z_UTIL_LISTIFY_131(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(131, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_133(F, sep, ...) \ + Z_UTIL_LISTIFY_132(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(132, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_134(F, sep, ...) \ + Z_UTIL_LISTIFY_133(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(133, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_135(F, sep, ...) \ + Z_UTIL_LISTIFY_134(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(134, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_136(F, sep, ...) \ + Z_UTIL_LISTIFY_135(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(135, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_137(F, sep, ...) \ + Z_UTIL_LISTIFY_136(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(136, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_138(F, sep, ...) \ + Z_UTIL_LISTIFY_137(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(137, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_139(F, sep, ...) \ + Z_UTIL_LISTIFY_138(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(138, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_140(F, sep, ...) \ + Z_UTIL_LISTIFY_139(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(139, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_141(F, sep, ...) \ + Z_UTIL_LISTIFY_140(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(140, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_142(F, sep, ...) \ + Z_UTIL_LISTIFY_141(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(141, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_143(F, sep, ...) \ + Z_UTIL_LISTIFY_142(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(142, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_144(F, sep, ...) \ + Z_UTIL_LISTIFY_143(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(143, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_145(F, sep, ...) \ + Z_UTIL_LISTIFY_144(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(144, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_146(F, sep, ...) \ + Z_UTIL_LISTIFY_145(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(145, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_147(F, sep, ...) \ + Z_UTIL_LISTIFY_146(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(146, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_148(F, sep, ...) \ + Z_UTIL_LISTIFY_147(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(147, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_149(F, sep, ...) \ + Z_UTIL_LISTIFY_148(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(148, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_150(F, sep, ...) \ + Z_UTIL_LISTIFY_149(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(149, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_151(F, sep, ...) \ + Z_UTIL_LISTIFY_150(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(150, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_152(F, sep, ...) \ + Z_UTIL_LISTIFY_151(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(151, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_153(F, sep, ...) \ + Z_UTIL_LISTIFY_152(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(152, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_154(F, sep, ...) \ + Z_UTIL_LISTIFY_153(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(153, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_155(F, sep, ...) \ + Z_UTIL_LISTIFY_154(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(154, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_156(F, sep, ...) \ + Z_UTIL_LISTIFY_155(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(155, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_157(F, sep, ...) \ + Z_UTIL_LISTIFY_156(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(156, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_158(F, sep, ...) \ + Z_UTIL_LISTIFY_157(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(157, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_159(F, sep, ...) \ + Z_UTIL_LISTIFY_158(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(158, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_160(F, sep, ...) \ + Z_UTIL_LISTIFY_159(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(159, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_161(F, sep, ...) \ + Z_UTIL_LISTIFY_160(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(160, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_162(F, sep, ...) \ + Z_UTIL_LISTIFY_161(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(161, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_163(F, sep, ...) \ + Z_UTIL_LISTIFY_162(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(162, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_164(F, sep, ...) \ + Z_UTIL_LISTIFY_163(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(163, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_165(F, sep, ...) \ + Z_UTIL_LISTIFY_164(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(164, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_166(F, sep, ...) \ + Z_UTIL_LISTIFY_165(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(165, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_167(F, sep, ...) \ + Z_UTIL_LISTIFY_166(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(166, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_168(F, sep, ...) \ + Z_UTIL_LISTIFY_167(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(167, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_169(F, sep, ...) \ + Z_UTIL_LISTIFY_168(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(168, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_170(F, sep, ...) \ + Z_UTIL_LISTIFY_169(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(169, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_171(F, sep, ...) \ + Z_UTIL_LISTIFY_170(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(170, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_172(F, sep, ...) \ + Z_UTIL_LISTIFY_171(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(171, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_173(F, sep, ...) \ + Z_UTIL_LISTIFY_172(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(172, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_174(F, sep, ...) \ + Z_UTIL_LISTIFY_173(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(173, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_175(F, sep, ...) \ + Z_UTIL_LISTIFY_174(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(174, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_176(F, sep, ...) \ + Z_UTIL_LISTIFY_175(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(175, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_177(F, sep, ...) \ + Z_UTIL_LISTIFY_176(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(176, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_178(F, sep, ...) \ + Z_UTIL_LISTIFY_177(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(177, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_179(F, sep, ...) \ + Z_UTIL_LISTIFY_178(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(178, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_180(F, sep, ...) \ + Z_UTIL_LISTIFY_179(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(179, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_181(F, sep, ...) \ + Z_UTIL_LISTIFY_180(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(180, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_182(F, sep, ...) \ + Z_UTIL_LISTIFY_181(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(181, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_183(F, sep, ...) \ + Z_UTIL_LISTIFY_182(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(182, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_184(F, sep, ...) \ + Z_UTIL_LISTIFY_183(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(183, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_185(F, sep, ...) \ + Z_UTIL_LISTIFY_184(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(184, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_186(F, sep, ...) \ + Z_UTIL_LISTIFY_185(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(185, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_187(F, sep, ...) \ + Z_UTIL_LISTIFY_186(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(186, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_188(F, sep, ...) \ + Z_UTIL_LISTIFY_187(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(187, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_189(F, sep, ...) \ + Z_UTIL_LISTIFY_188(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(188, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_190(F, sep, ...) \ + Z_UTIL_LISTIFY_189(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(189, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_191(F, sep, ...) \ + Z_UTIL_LISTIFY_190(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(190, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_192(F, sep, ...) \ + Z_UTIL_LISTIFY_191(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(191, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_193(F, sep, ...) \ + Z_UTIL_LISTIFY_192(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(192, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_194(F, sep, ...) \ + Z_UTIL_LISTIFY_193(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(193, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_195(F, sep, ...) \ + Z_UTIL_LISTIFY_194(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(194, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_196(F, sep, ...) \ + Z_UTIL_LISTIFY_195(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(195, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_197(F, sep, ...) \ + Z_UTIL_LISTIFY_196(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(196, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_198(F, sep, ...) \ + Z_UTIL_LISTIFY_197(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(197, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_199(F, sep, ...) \ + Z_UTIL_LISTIFY_198(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(198, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_200(F, sep, ...) \ + Z_UTIL_LISTIFY_199(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(199, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_201(F, sep, ...) \ + Z_UTIL_LISTIFY_200(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(200, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_202(F, sep, ...) \ + Z_UTIL_LISTIFY_201(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(201, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_203(F, sep, ...) \ + Z_UTIL_LISTIFY_202(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(202, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_204(F, sep, ...) \ + Z_UTIL_LISTIFY_203(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(203, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_205(F, sep, ...) \ + Z_UTIL_LISTIFY_204(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(204, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_206(F, sep, ...) \ + Z_UTIL_LISTIFY_205(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(205, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_207(F, sep, ...) \ + Z_UTIL_LISTIFY_206(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(206, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_208(F, sep, ...) \ + Z_UTIL_LISTIFY_207(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(207, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_209(F, sep, ...) \ + Z_UTIL_LISTIFY_208(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(208, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_210(F, sep, ...) \ + Z_UTIL_LISTIFY_209(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(209, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_211(F, sep, ...) \ + Z_UTIL_LISTIFY_210(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(210, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_212(F, sep, ...) \ + Z_UTIL_LISTIFY_211(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(211, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_213(F, sep, ...) \ + Z_UTIL_LISTIFY_212(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(212, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_214(F, sep, ...) \ + Z_UTIL_LISTIFY_213(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(213, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_215(F, sep, ...) \ + Z_UTIL_LISTIFY_214(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(214, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_216(F, sep, ...) \ + Z_UTIL_LISTIFY_215(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(215, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_217(F, sep, ...) \ + Z_UTIL_LISTIFY_216(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(216, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_218(F, sep, ...) \ + Z_UTIL_LISTIFY_217(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(217, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_219(F, sep, ...) \ + Z_UTIL_LISTIFY_218(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(218, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_220(F, sep, ...) \ + Z_UTIL_LISTIFY_219(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(219, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_221(F, sep, ...) \ + Z_UTIL_LISTIFY_220(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(220, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_222(F, sep, ...) \ + Z_UTIL_LISTIFY_221(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(221, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_223(F, sep, ...) \ + Z_UTIL_LISTIFY_222(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(222, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_224(F, sep, ...) \ + Z_UTIL_LISTIFY_223(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(223, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_225(F, sep, ...) \ + Z_UTIL_LISTIFY_224(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(224, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_226(F, sep, ...) \ + Z_UTIL_LISTIFY_225(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(225, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_227(F, sep, ...) \ + Z_UTIL_LISTIFY_226(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(226, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_228(F, sep, ...) \ + Z_UTIL_LISTIFY_227(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(227, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_229(F, sep, ...) \ + Z_UTIL_LISTIFY_228(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(228, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_230(F, sep, ...) \ + Z_UTIL_LISTIFY_229(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(229, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_231(F, sep, ...) \ + Z_UTIL_LISTIFY_230(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(230, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_232(F, sep, ...) \ + Z_UTIL_LISTIFY_231(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(231, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_233(F, sep, ...) \ + Z_UTIL_LISTIFY_232(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(232, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_234(F, sep, ...) \ + Z_UTIL_LISTIFY_233(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(233, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_235(F, sep, ...) \ + Z_UTIL_LISTIFY_234(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(234, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_236(F, sep, ...) \ + Z_UTIL_LISTIFY_235(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(235, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_237(F, sep, ...) \ + Z_UTIL_LISTIFY_236(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(236, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_238(F, sep, ...) \ + Z_UTIL_LISTIFY_237(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(237, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_239(F, sep, ...) \ + Z_UTIL_LISTIFY_238(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(238, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_240(F, sep, ...) \ + Z_UTIL_LISTIFY_239(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(239, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_241(F, sep, ...) \ + Z_UTIL_LISTIFY_240(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(240, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_242(F, sep, ...) \ + Z_UTIL_LISTIFY_241(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(241, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_243(F, sep, ...) \ + Z_UTIL_LISTIFY_242(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(242, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_244(F, sep, ...) \ + Z_UTIL_LISTIFY_243(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(243, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_245(F, sep, ...) \ + Z_UTIL_LISTIFY_244(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(244, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_246(F, sep, ...) \ + Z_UTIL_LISTIFY_245(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(245, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_247(F, sep, ...) \ + Z_UTIL_LISTIFY_246(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(246, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_248(F, sep, ...) \ + Z_UTIL_LISTIFY_247(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(247, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_249(F, sep, ...) \ + Z_UTIL_LISTIFY_248(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(248, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_250(F, sep, ...) \ + Z_UTIL_LISTIFY_249(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(249, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_251(F, sep, ...) \ + Z_UTIL_LISTIFY_250(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(250, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_252(F, sep, ...) \ + Z_UTIL_LISTIFY_251(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(251, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_253(F, sep, ...) \ + Z_UTIL_LISTIFY_252(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(252, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_254(F, sep, ...) \ + Z_UTIL_LISTIFY_253(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(253, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_255(F, sep, ...) \ + Z_UTIL_LISTIFY_254(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(254, __VA_ARGS__) + +#define Z_UTIL_LISTIFY_256(F, sep, ...) \ + Z_UTIL_LISTIFY_255(F, sep, __VA_ARGS__) __DEBRACKET sep \ + F(255, __VA_ARGS__) + +#ifdef __cplusplus +} +#endif + +#endif /* _BLE_MESH_UTIL_LOOPS_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_atomic.c b/components/bt/esp_ble_mesh/mesh_common/mesh_atomic.c index 67562bcc93..232ba3fa78 100644 --- a/components/bt/esp_ble_mesh/mesh_common/mesh_atomic.c +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_atomic.c @@ -13,7 +13,7 @@ /* * SPDX-FileCopyrightText: 2016 Intel Corporation * SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc. - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -170,4 +170,18 @@ bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target) return ret; } +bool bt_mesh_atomic_cas(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val) +{ + bt_mesh_atomic_lock(); + + if (*target == excepted) { + *target = new_val; + bt_mesh_atomic_unlock(); + return true; + } + + bt_mesh_atomic_unlock(); + return false; +} + #endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */ diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_common.c b/components/bt/esp_ble_mesh/mesh_common/mesh_common.c index 80c424200a..ea10429c66 100644 --- a/components/bt/esp_ble_mesh/mesh_common/mesh_common.c +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_common.c @@ -104,3 +104,8 @@ int bt_mesh_rand(void *buf, size_t len) return 0; } + +uint32_t bt_mesh_get_rand(void) +{ + return esp_random(); +} diff --git a/components/bt/esp_ble_mesh/mesh_core/adv.c b/components/bt/esp_ble_mesh/mesh_core/adv.c index b8bcf38966..29211267b7 100644 --- a/components/bt/esp_ble_mesh/mesh_core/adv.c +++ b/components/bt/esp_ble_mesh/mesh_core/adv.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -311,8 +311,7 @@ static void adv_thread(void *p) } /* busy == 0 means this was canceled */ - if (BLE_MESH_ADV(*buf)->busy) { - BLE_MESH_ADV(*buf)->busy = 0U; + if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(*buf), 1, 0)) { #if !defined(CONFIG_BLE_MESH_RELAY_ADV_BUF) if (adv_send(*buf)) { BT_WARN("Failed to send adv packet"); @@ -427,7 +426,7 @@ static void bt_mesh_unref_buf(bt_mesh_msg_t *msg) if (msg->arg) { buf = (struct net_buf *)msg->arg; - BLE_MESH_ADV(buf)->busy = 0U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0); if (buf->ref > 1U) { buf->ref = 1U; } @@ -471,7 +470,7 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, BLE_MESH_ADV(buf)->cb = cb; BLE_MESH_ADV(buf)->cb_data = cb_data; - BLE_MESH_ADV(buf)->busy = 1U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1); bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); @@ -573,7 +572,7 @@ void bt_mesh_relay_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *c BLE_MESH_ADV(buf)->cb = cb; BLE_MESH_ADV(buf)->cb_data = cb_data; - BLE_MESH_ADV(buf)->busy = 1U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1); msg.arg = (void *)net_buf_ref(buf); msg.src = src; @@ -736,7 +735,7 @@ static void bt_mesh_ble_adv_send(struct net_buf *buf, const struct bt_mesh_send_ BLE_MESH_ADV(buf)->cb = cb; BLE_MESH_ADV(buf)->cb_data = cb_data; - BLE_MESH_ADV(buf)->busy = 1U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 1); bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); @@ -755,7 +754,7 @@ static void ble_adv_tx_reset(struct ble_adv_tx *tx, bool unref) } bt_mesh_atomic_set(tx->flags, 0); memset(&tx->param, 0, sizeof(tx->param)); - BLE_MESH_ADV(tx->buf)->busy = 0U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(tx->buf), 0); if (unref) { net_buf_unref(tx->buf); } @@ -946,7 +945,8 @@ int bt_mesh_stop_ble_advertising(uint8_t index) /* busy 1, ref 1; busy 1, ref 2; * busy 0, ref 0; busy 0, ref 1; */ - if (BLE_MESH_ADV(tx->buf)->busy == 1U && + + if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(tx->buf)) && tx->buf->ref == 1U) { unref = false; } diff --git a/components/bt/esp_ble_mesh/mesh_core/adv.h b/components/bt/esp_ble_mesh/mesh_core/adv.h index 27108c203a..bcc333efa1 100644 --- a/components/bt/esp_ble_mesh/mesh_core/adv.h +++ b/components/bt/esp_ble_mesh/mesh_core/adv.h @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,7 @@ #ifndef _ADV_H_ #define _ADV_H_ +#include "mesh_atomic.h" #include "mesh_access.h" #include "mesh_bearer_adapt.h" @@ -23,7 +24,8 @@ extern "C" { /* The user data is a pointer (4 bytes) to struct bt_mesh_adv */ #define BLE_MESH_ADV_USER_DATA_SIZE 4 -#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf)) +#define BLE_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf)) +#define BLE_MESH_ADV_BUSY(buf) (BLE_MESH_ADV(buf)->busy) typedef struct bt_mesh_msg { bool relay; /* Flag indicates if the packet is a relayed one */ @@ -45,8 +47,10 @@ struct bt_mesh_adv { const struct bt_mesh_send_cb *cb; void *cb_data; - uint8_t type:3, - busy:1; + uint8_t type:3; + + bt_mesh_atomic_t busy; + uint8_t xmit; }; diff --git a/components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c b/components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c index a16fe928bf..e85797b685 100644 --- a/components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c +++ b/components/bt/esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA * SPDX-FileCopyrightText: 2015-2016 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,7 +67,7 @@ static struct bt_mesh_conn_cb *bt_mesh_gatts_conn_cb; static tBTA_GATTS_IF bt_mesh_gatts_if; static BD_ADDR bt_mesh_gatts_addr; static uint16_t svc_handle, char_handle; -static future_t *future_mesh; +static future_t *gatts_future_mesh; /* Static Functions */ static struct bt_mesh_gatt_attr *bt_mesh_gatts_find_attr_by_handle(uint16_t handle); @@ -99,6 +99,11 @@ int bt_mesh_host_init(void) return 0; } +int bt_mesh_host_deinit(void) +{ + return 0; +} + void bt_mesh_hci_init(void) { const uint8_t *features = controller_get_interface()->get_features_ble()->as_array; @@ -316,6 +321,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, tBLE_ADDR_TYPE addr_type_own = 0U; tBLE_BD_ADDR p_dir_bda = {0}; tBTM_BLE_AFP adv_fil_pol = 0U; + uint16_t interval = 0U; uint8_t adv_type = 0U; int err = 0; @@ -365,9 +371,24 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, adv_fil_pol = BLE_MESH_AP_SCAN_CONN_ALL; p_start_adv_cb = start_adv_completed_cb; + interval = param->interval_min; + +#if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL + /* If non-connectable mesh packets are transmitted with an adv interval + * not smaller than 10ms, then we will use a random adv interval between + * [interval / 2, interval] for them. + */ + if (adv_type == BLE_MESH_ADV_NONCONN_IND && interval >= 16) { + interval >>= 1; + interval += (bt_mesh_get_rand() % (interval + 1)); + + BT_INFO("%u->%u", param->interval_min, interval); + } +#endif + /* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */ BLE_MESH_BTM_CHECK_STATUS( - BTM_BleSetAdvParamsAll(param->interval_min, param->interval_max, adv_type, + BTM_BleSetAdvParamsAll(interval, interval, adv_type, addr_type_own, &p_dir_bda, channel_map, adv_fil_pol, p_start_adv_cb)); BLE_MESH_BTM_CHECK_STATUS(BTM_BleStartAdv()); @@ -518,6 +539,9 @@ static void bt_mesh_bta_gatts_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) case BTA_GATTS_REG_EVT: if (p_data->reg_oper.status == BTA_GATT_OK) { bt_mesh_gatts_if = p_data->reg_oper.server_if; + future_ready(gatts_future_mesh, FUTURE_SUCCESS); + } else { + future_ready(gatts_future_mesh, FUTURE_FAIL); } break; case BTA_GATTS_READ_EVT: { @@ -575,27 +599,27 @@ static void bt_mesh_bta_gatts_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data) break; case BTA_GATTS_CREATE_EVT: svc_handle = p_data->create.service_id; - BT_DBG("svc_handle %d, future_mesh %p", svc_handle, future_mesh); - if (future_mesh != NULL) { - future_ready(future_mesh, FUTURE_SUCCESS); + BT_DBG("svc_handle %d, gatts_future_mesh %p", svc_handle, gatts_future_mesh); + if (gatts_future_mesh != NULL) { + future_ready(gatts_future_mesh, FUTURE_SUCCESS); } break; case BTA_GATTS_ADD_INCL_SRVC_EVT: svc_handle = p_data->add_result.attr_id; - if (future_mesh != NULL) { - future_ready(future_mesh, FUTURE_SUCCESS); + if (gatts_future_mesh != NULL) { + future_ready(gatts_future_mesh, FUTURE_SUCCESS); } break; case BTA_GATTS_ADD_CHAR_EVT: char_handle = p_data->add_result.attr_id; - if (future_mesh != NULL) { - future_ready(future_mesh, FUTURE_SUCCESS); + if (gatts_future_mesh != NULL) { + future_ready(gatts_future_mesh, FUTURE_SUCCESS); } break; case BTA_GATTS_ADD_CHAR_DESCR_EVT: char_handle = p_data->add_result.attr_id; - if (future_mesh != NULL) { - future_ready(future_mesh, FUTURE_SUCCESS); + if (gatts_future_mesh != NULL) { + future_ready(gatts_future_mesh, FUTURE_SUCCESS); } break; case BTA_GATTS_DELELTE_EVT: @@ -921,11 +945,11 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) if (svc->attrs[i].uuid->type == BLE_MESH_UUID_TYPE_16) { switch (BLE_MESH_UUID_16(svc->attrs[i].uuid)->val) { case BLE_MESH_UUID_GATT_PRIMARY_VAL: { - future_mesh = future_new(); + gatts_future_mesh = future_new(); bta_uuid_to_bt_mesh_uuid(&bta_uuid, (struct bt_mesh_uuid *)svc->attrs[i].user_data); BTA_GATTS_CreateService(bt_mesh_gatts_if, &bta_uuid, 0, svc->attr_count, true); - if (future_await(future_mesh) == FUTURE_FAIL) { + if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add primary service"); return ESP_FAIL; } @@ -935,11 +959,11 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) break; } case BLE_MESH_UUID_GATT_SECONDARY_VAL: { - future_mesh = future_new(); + gatts_future_mesh = future_new(); bta_uuid_to_bt_mesh_uuid(&bta_uuid, (struct bt_mesh_uuid *)svc->attrs[i].user_data); BTA_GATTS_CreateService(bt_mesh_gatts_if, &bta_uuid, 0, svc->attr_count, false); - if (future_await(future_mesh) == FUTURE_FAIL) { + if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add secondary service"); return ESP_FAIL; } @@ -952,11 +976,11 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) break; } case BLE_MESH_UUID_GATT_CHRC_VAL: { - future_mesh = future_new(); + gatts_future_mesh = future_new(); struct bt_mesh_gatt_char *gatts_chrc = (struct bt_mesh_gatt_char *)svc->attrs[i].user_data; bta_uuid_to_bt_mesh_uuid(&bta_uuid, gatts_chrc->uuid); BTA_GATTS_AddCharacteristic(svc_handle, &bta_uuid, bt_mesh_perm_to_bta_perm(svc->attrs[i + 1].perm), gatts_chrc->properties, NULL, NULL); - if (future_await(future_mesh) == FUTURE_FAIL) { + if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add characteristic"); return ESP_FAIL; } @@ -978,10 +1002,10 @@ int bt_mesh_gatts_service_register(struct bt_mesh_gatt_service *svc) case BLE_MESH_UUID_ES_CONFIGURATION_VAL: case BLE_MESH_UUID_ES_MEASUREMENT_VAL: case BLE_MESH_UUID_ES_TRIGGER_SETTING_VAL: { - future_mesh = future_new(); + gatts_future_mesh = future_new(); bta_uuid_to_bt_mesh_uuid(&bta_uuid, svc->attrs[i].uuid); BTA_GATTS_AddCharDescriptor(svc_handle, bt_mesh_perm_to_bta_perm(svc->attrs[i].perm), &bta_uuid, NULL, NULL); - if (future_await(future_mesh) == FUTURE_FAIL) { + if (future_await(gatts_future_mesh) == FUTURE_FAIL) { BT_ERR("Failed to add descriptor"); return ESP_FAIL; } @@ -1615,6 +1639,7 @@ static void bt_mesh_bta_gattc_cb(tBTA_GATTC_EVT event, tBTA_GATTC *p_data) } break; case BTA_GATTC_CLOSE_EVT: + bta_gattc_clcb_dealloc_by_conn_id(p_data->close.conn_id); BT_DBG("BTA_GATTC_CLOSE_EVT"); break; case BTA_GATTC_CONNECT_EVT: { @@ -1723,7 +1748,19 @@ void bt_mesh_gatt_init(void) CONFIG_BLE_MESH_GATT_PROXY_SERVER tBT_UUID gatts_app_uuid = {LEN_UUID_128, {0}}; memset(&gatts_app_uuid.uu.uuid128, BLE_MESH_GATTS_APP_UUID_BYTE, LEN_UUID_128); + + gatts_future_mesh = future_new(); + if (!gatts_future_mesh) { + BT_ERR("Mesh gatts sync lock alloc failed"); + return; + } + BTA_GATTS_AppRegister(&gatts_app_uuid, bt_mesh_bta_gatts_cb); + + if (future_await(gatts_future_mesh) == FUTURE_FAIL) { + BT_ERR("Mesh gatts app register failed"); + return; + } #endif #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \ @@ -1977,6 +2014,16 @@ int bt_mesh_update_exceptional_list(uint8_t sub_code, uint32_t type, void *info) BT_ERR("Invalid Provisioning Link ID"); return -EINVAL; } + + /* When removing an unused link (i.e., Link ID is 0), and since + * Controller has never added this Link ID, it will cause error + * log been wrongly reported. + * Therefore, add this check here to avoid such occurrences. + */ + if (*(uint32_t*)info == 0) { + return 0; + } + sys_memcpy_swap(value, info, sizeof(uint32_t)); } diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index b2f57dcccd..1478fe1554 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -174,7 +174,7 @@ static void friend_clear(struct bt_mesh_friend *frnd, uint8_t reason) /* Cancel the sending if necessary */ if (frnd->pending_buf) { bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 2U, BLE_MESH_BUF_REF_EQUAL); - BLE_MESH_ADV(frnd->last)->busy = 0U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(frnd->last), 0); } else { bt_mesh_adv_buf_ref_debug(__func__, frnd->last, 1U, BLE_MESH_BUF_REF_EQUAL); } diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h index 66fbb7e43f..98961f4386 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h @@ -50,8 +50,8 @@ extern "C" { { \ .loc = (_loc), \ .model_count = ARRAY_SIZE(_mods), \ - .models = (_mods), \ .vnd_model_count = ARRAY_SIZE(_vnd_mods), \ + .models = (_mods), \ .vnd_models = (_vnd_mods), \ } @@ -255,14 +255,12 @@ struct bt_mesh_model_op { #define BLE_MESH_MODEL_CB(_id, _op, _pub, _user_data, _cb) \ { \ .id = (_id), \ - .op = (_op), \ - .keys = { [0 ... (CONFIG_BLE_MESH_MODEL_KEY_COUNT - 1)] = \ - BLE_MESH_KEY_UNUSED }, \ .pub = (_pub), \ - .groups = { [0 ... (CONFIG_BLE_MESH_MODEL_GROUP_COUNT - 1)] = \ - BLE_MESH_ADDR_UNASSIGNED }, \ - .user_data = (_user_data), \ + .keys = ESP_BLE_MESH_MODEL_KEYS_UNUSED, \ + .groups = ESP_BLE_MESH_MODEL_GROUPS_UNASSIGNED, \ + .op = (_op), \ .cb = (_cb), \ + .user_data = (_user_data), \ } /** @def BLE_MESH_MODEL_VND_CB @@ -280,14 +278,12 @@ struct bt_mesh_model_op { { \ .vnd.company = (_company), \ .vnd.id = (_id), \ - .op = (_op), \ .pub = (_pub), \ - .keys = { [0 ... (CONFIG_BLE_MESH_MODEL_KEY_COUNT - 1)] = \ - BLE_MESH_KEY_UNUSED }, \ - .groups = { [0 ... (CONFIG_BLE_MESH_MODEL_GROUP_COUNT - 1)] = \ - BLE_MESH_ADDR_UNASSIGNED }, \ - .user_data = (_user_data), \ + .keys = ESP_BLE_MESH_MODEL_KEYS_UNUSED, \ + .groups = ESP_BLE_MESH_MODEL_GROUPS_UNASSIGNED, \ + .op = (_op), \ .cb = (_cb), \ + .user_data = (_user_data), \ } /** @def BLE_MESH_TRANSMIT @@ -419,8 +415,8 @@ struct bt_mesh_model_pub { #define BLE_MESH_MODEL_PUB_DEFINE(_name, _update, _msg_len) \ NET_BUF_SIMPLE_DEFINE_STATIC(bt_mesh_pub_msg_##_name, _msg_len); \ static struct bt_mesh_model_pub _name = { \ - .update = _update, \ .msg = &bt_mesh_pub_msg_##_name, \ + .update = _update, \ } /** Model callback functions. */ diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h index 7bd95c78e0..f3cd101fc1 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h @@ -573,9 +573,9 @@ struct bt_mesh_gatt_attr { #define BLE_MESH_GATT_PRIMARY_SERVICE(_service) \ { \ .uuid = BLE_MESH_UUID_GATT_PRIMARY, \ - .perm = BLE_MESH_GATT_PERM_READ, \ .read = bt_mesh_gatts_attr_read_service, \ .user_data = _service, \ + .perm = BLE_MESH_GATT_PERM_READ, \ } /** @def BLE_MESH_GATT_SECONDARY_SERVICE @@ -588,9 +588,9 @@ struct bt_mesh_gatt_attr { #define BLE_MESH_GATT_SECONDARY_SERVICE(_service) \ { \ .uuid = BLE_MESH_UUID_GATT_SECONDARY, \ - .perm = BLE_MESH_GATT_PERM_READ, \ .read = bt_mesh_gatts_attr_read_service, \ .user_data = _service, \ + .perm = BLE_MESH_GATT_PERM_READ, \ } /** @def BLE_MESH_GATT_INCLUDE_SERVICE @@ -603,9 +603,9 @@ struct bt_mesh_gatt_attr { #define BLE_MESH_GATT_INCLUDE_SERVICE(_service_incl) \ { \ .uuid = BLE_MESH_UUID_GATT_INCLUDE, \ - .perm = BLE_MESH_GATT_PERM_READ, \ .read = bt_mesh_gatts_attr_read_included, \ .user_data = _service_incl, \ + .perm = BLE_MESH_GATT_PERM_READ, \ } /** @def BLE_MESH_GATT_CHARACTERISTIC @@ -619,10 +619,10 @@ struct bt_mesh_gatt_attr { #define BLE_MESH_GATT_CHARACTERISTIC(_uuid, _props) \ { \ .uuid = BLE_MESH_UUID_GATT_CHRC, \ - .perm = BLE_MESH_GATT_PERM_READ, \ .read = bt_mesh_gatts_attr_read_chrc, \ .user_data = (&(struct bt_mesh_gatt_char) { .uuid = _uuid, \ .properties = _props, }), \ + .perm = BLE_MESH_GATT_PERM_READ, \ } /** @def BLE_MESH_GATT_DESCRIPTOR @@ -639,10 +639,10 @@ struct bt_mesh_gatt_attr { #define BLE_MESH_GATT_DESCRIPTOR(_uuid, _perm, _read, _write, _value) \ { \ .uuid = _uuid, \ - .perm = _perm, \ .read = _read, \ .write = _write, \ .user_data = _value, \ + .perm = _perm, \ } /** @def BLE_MESH_GATT_SERVICE @@ -659,6 +659,7 @@ struct bt_mesh_gatt_attr { } int bt_mesh_host_init(void); +int bt_mesh_host_deinit(void); int bt_le_adv_start(const struct bt_mesh_adv_param *param, const struct bt_mesh_adv_data *ad, size_t ad_len, diff --git a/components/bt/esp_ble_mesh/mesh_core/main.c b/components/bt/esp_ble_mesh/mesh_core/main.c index a0a1b83813..880a829fcb 100644 --- a/components/bt/esp_ble_mesh/mesh_core/main.c +++ b/components/bt/esp_ble_mesh/mesh_core/main.c @@ -102,6 +102,11 @@ void bt_mesh_node_reset(void) return; } + if (bt_prov_active()) { + BT_WARN("%s, link is still active", __func__); + return; + } + bt_mesh.iv_index = 0U; bt_mesh.seq = 0U; @@ -197,6 +202,8 @@ static bool prov_bearers_valid(bt_mesh_prov_bearer_t bearers) int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) { + int err = 0; + if (bt_mesh_is_provisioned()) { BT_WARN("%s, Already", __func__); return -EALREADY; @@ -232,7 +239,11 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) if (IS_ENABLED(CONFIG_BLE_MESH_PB_ADV) && (bearers & BLE_MESH_PROV_ADV)) { /* Make sure we're scanning for provisioning invitations */ - bt_mesh_scan_enable(); + err = bt_mesh_scan_enable(); + if (err) { + return err; + } + /* Enable unprovisioned beacon sending */ bt_mesh_beacon_enable(); } @@ -637,7 +648,10 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) bt_mesh_beacon_enable(); } - bt_mesh_scan_enable(); + err = bt_mesh_scan_enable(); + if (err) { + return err; + } return 0; } diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index 2ca480f186..b57aabc399 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -967,18 +967,36 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, } /* Deliver to local network interface if necessary */ - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned() && - (bt_mesh_fixed_group_match(tx->ctx->addr) || - bt_mesh_elem_find(tx->ctx->addr))) { - if (cb && cb->start) { - cb->start(0, 0, cb_data); - } - net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); - if (cb && cb->end) { - cb->end(0, cb_data); + if (((IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) || + (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en())) && + (bt_mesh_fixed_group_match(tx->ctx->addr) || bt_mesh_elem_find(tx->ctx->addr))) { + /** + * If the target address isn't a unicast address, then the callback function + * will be called by `adv task` in place of here, to avoid the callback function + * being called twice. + * See BLEMESH24-76 for more details. + */ + if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { + if (cb && cb->start) { + cb->start(0, 0, cb_data); + } + + net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); + + if (cb && cb->end) { + cb->end(0, cb_data); + } + + k_work_submit(&bt_mesh.local_work); + + goto done; + } else { + net_buf_slist_put(&bt_mesh.local_queue, net_buf_ref(buf)); + k_work_submit(&bt_mesh.local_work); } - k_work_submit(&bt_mesh.local_work); - } else if (tx->ctx->send_ttl != 1U) { + } + + if (tx->ctx->send_ttl != 1U) { /* Deliver to the advertising network interface. Mesh spec * 3.4.5.2: "The output filter of the interface connected to * advertising or GATT bearers shall drop all messages with @@ -1265,7 +1283,7 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, #endif if (!buf) { - BT_ERR("Out of relay buffers"); + BT_INFO("Out of relay buffers"); return; } @@ -1432,9 +1450,7 @@ static bool ignore_net_msg(uint16_t src, uint16_t dst) } if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && - bt_mesh_is_provisioner_en() && - BLE_MESH_ADDR_IS_UNICAST(dst) && - bt_mesh_elem_find(dst)) { + bt_mesh_is_provisioner_en()) { /* If the destination address of the message is the element * address of Provisioner, but Provisioner fails to find the * node in its provisioning database, then this message will @@ -1509,7 +1525,11 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi, * was neither a local element nor an LPN we're Friends for. */ if (!BLE_MESH_ADDR_IS_UNICAST(rx.ctx.recv_dst) || - (!rx.local_match && !rx.friend_match)) { + (!rx.local_match && !rx.friend_match +#if CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG + && !rx.replay_msg +#endif + )) { net_buf_simple_restore(&buf, &state); bt_mesh_net_relay(&buf, &rx); } diff --git a/components/bt/esp_ble_mesh/mesh_core/net.h b/components/bt/esp_ble_mesh/mesh_core/net.h index f982c41cee..1ba79e65d7 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.h +++ b/components/bt/esp_ble_mesh/mesh_core/net.h @@ -294,6 +294,9 @@ struct bt_mesh_net_rx { ctl:1, /* Network Control */ net_if:2, /* Network interface */ local_match:1, /* Matched a local element */ +#if CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG + replay_msg:1, /* Replayed messages */ +#endif friend_match:1; /* Matched an LPN we're friends for */ uint16_t msg_cache_idx; /* Index of entry in message cache */ }; diff --git a/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c b/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c index 96dedbeb5d..45c5f7d929 100644 --- a/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c +++ b/components/bt/esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2017 Nordic Semiconductor ASA * SPDX-FileCopyrightText: 2015-2016 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -82,12 +82,14 @@ static uint8_t bt_mesh_gatts_addr[6]; #endif /* defined(CONFIG_BLE_MESH_NODE) && CONFIG_BLE_MESH_NODE */ +static bool g_host_init = false; + int bt_mesh_host_init(void) { - static bool init = false; int rc; - if (init == true) { + if (g_host_init == true) { + BT_WARN("Already initialized host for mesh!"); return -EALREADY; } @@ -102,7 +104,30 @@ int bt_mesh_host_init(void) } osi_alarm_init(); - init = true; + g_host_init = true; + + return 0; +} + +int bt_mesh_host_deinit(void) +{ + int rc; + + if (g_host_init == false) { + return -EALREADY; + } + + osi_alarm_deinit(); + + rc = osi_alarm_delete_mux(); + if (rc != 0) { + return -1; + } + + btc_deinit(); + + g_host_init = false; + return 0; } @@ -759,15 +784,17 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, const struct bt_mesh_adv_data *ad, size_t ad_len, const struct bt_mesh_adv_data *sd, size_t sd_len) { + struct ble_gap_adv_params adv_params; + uint8_t buf[BLE_HS_ADV_MAX_SZ]; + uint16_t interval = 0; + uint8_t buf_len = 0; + int err; + #if BLE_MESH_DEV if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) { return -EALREADY; } #endif - uint8_t buf[BLE_HS_ADV_MAX_SZ]; - uint8_t buf_len = 0; - int err; - struct ble_gap_adv_params adv_params; err = set_ad(ad, ad_len, buf, &buf_len); if (err) { @@ -798,8 +825,6 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, } memset(&adv_params, 0, sizeof adv_params); - adv_params.itvl_min = param->interval_min; - adv_params.itvl_max = param->interval_max; if (param->options & BLE_MESH_ADV_OPT_CONNECTABLE) { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; @@ -812,6 +837,25 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; } + interval = param->interval_min; + +#if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL + /* If non-connectable mesh packets are transmitted with an adv interval + * not smaller than 10ms, then we will use a random adv interval between + * [interval / 2, interval] for them. + */ + if (adv_params.conn_mode == BLE_GAP_CONN_MODE_NON && + adv_params.disc_mode == BLE_GAP_DISC_MODE_NON && interval >= 16) { + interval >>= 1; + interval += (bt_mesh_get_rand() % (interval + 1)); + + BT_INFO("%u->%u", param->interval_min, interval); + } +#endif + + adv_params.itvl_min = interval; + adv_params.itvl_max = interval; + again: err = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params, gap_event_cb, NULL); @@ -877,7 +921,7 @@ int bt_mesh_ble_adv_start(const struct bt_mesh_ble_adv_param *param, break; case BLE_MESH_ADV_NONCONN_IND: adv_params.conn_mode = BLE_GAP_CONN_MODE_NON; - adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; break; case BLE_MESH_ADV_DIRECT_IND_LOW_DUTY: adv_params.conn_mode = BLE_GAP_CONN_MODE_DIR; @@ -1268,18 +1312,18 @@ int bt_mesh_gatts_service_stop(struct bt_mesh_gatt_service *svc) { int rc; uint16_t handle; + if (!svc) { BT_ERR("%s, Invalid parameter", __func__); return -EINVAL; } - const ble_uuid_t *uuid; + if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROXY_VAL) { - uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL); + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle); } else { - uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL); + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); } - rc = ble_gatts_find_svc(uuid, &handle); assert(rc == 0); ble_gatts_svc_set_visibility(handle, 0); @@ -1293,14 +1337,13 @@ int bt_mesh_gatts_service_start(struct bt_mesh_gatt_service *svc) { int rc; uint16_t handle; - const ble_uuid_t *uuid; + if (BLE_MESH_UUID_16(svc->attrs[0].user_data)->val == BT_UUID_MESH_PROXY_VAL) { - uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL); + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), &handle); } else { - uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL); + rc = ble_gatts_find_svc(BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), &handle); } - rc = ble_gatts_find_svc(uuid, &handle); assert(rc == 0); ble_gatts_svc_set_visibility(handle, 1); @@ -1943,9 +1986,44 @@ int bt_mesh_encrypt_be(const uint8_t key[16], const uint8_t plaintext[16], } #if defined(CONFIG_BLE_MESH_USE_DUPLICATE_SCAN) -int bt_mesh_update_exceptional_list(uint8_t sub_code, uint8_t type, void *info) +int bt_mesh_update_exceptional_list(uint8_t sub_code, uint32_t type, void *info) { - BT_ERR("Unsupported for NimBLE host"); - return 0; + uint8_t value[6] = {0}; + int rc = 0; + + if ((sub_code > BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN) || + (sub_code < BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN && + type > BLE_MESH_EXCEP_LIST_TYPE_MESH_PROXY_ADV) || + (sub_code == BLE_MESH_EXCEP_LIST_SUB_CODE_CLEAN && + !(type & BLE_MESH_EXCEP_LIST_CLEAN_ALL_LIST))) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + if (type == BLE_MESH_EXCEP_LIST_TYPE_MESH_LINK_ID) { + if (!info) { + BT_ERR("Invalid Provisioning Link ID"); + return -EINVAL; + } + + /* When removing an unused link (i.e., Link ID is 0), and since + * Controller has never added this Link ID, it will cause error + * log been wrongly reported. + * Therefore, add this check here to avoid such occurrences. + */ + if (*(uint32_t*)info == 0) { + return 0; + } + + sys_memcpy_swap(value, info, sizeof(uint32_t)); + } + + BT_DBG("%s exceptional list, type 0x%08x", sub_code ? "Remove" : "Add", type); + +#if MYNEWT_VAL(BLE_HCI_VS) + rc = ble_gap_duplicate_exception_list(sub_code, type, value, NULL); +#endif + + return rc; } #endif diff --git a/components/bt/esp_ble_mesh/mesh_core/prov.c b/components/bt/esp_ble_mesh/mesh_core/prov.c index 29c3973152..3f8916e2df 100644 --- a/components/bt/esp_ble_mesh/mesh_core/prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/prov.c @@ -285,7 +285,7 @@ static void free_segments(void) link.tx.buf[i] = NULL; bt_mesh_adv_buf_ref_debug(__func__, buf, 3U, BLE_MESH_BUF_REF_SMALL); /* Mark as canceled */ - BLE_MESH_ADV(buf)->busy = 0U; + bt_mesh_atomic_set(&BLE_MESH_ADV_BUSY(buf), 0); net_buf_unref(buf); } @@ -1327,7 +1327,7 @@ static void prov_retransmit(struct k_work *work) break; } - if (BLE_MESH_ADV(buf)->busy) { + if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(buf))) { continue; } diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c index 81e95ac4c4..c4dff039dc 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +19,8 @@ #include "provisioner_prov.h" #include "provisioner_main.h" +#define PROV_SVC_ADV_RX_CHECK(pre, cur) ((cur) < (pre) ? ((cur) + (UINT32_MAX - (pre)) >= 200) : ((cur) - (pre) >= 200)) + #if CONFIG_BLE_MESH_PROVISIONER _Static_assert(BLE_MESH_MAX_CONN >= CONFIG_BLE_MESH_PBG_SAME_TIME, @@ -597,7 +599,7 @@ static int provisioner_start_prov_pb_adv(const uint8_t uuid[16], const bt_mesh_a if (is_unprov_dev_being_provision(uuid)) { bt_mesh_pb_adv_unlock(); - return -EALREADY; + return 0; } for (i = 0; i < CONFIG_BLE_MESH_PBA_SAME_TIME; i++) { @@ -658,7 +660,7 @@ static int provisioner_start_prov_pb_gatt(const uint8_t uuid[16], const bt_mesh_ if (is_unprov_dev_being_provision(uuid)) { bt_mesh_pb_gatt_unlock(); - return -EALREADY; + return 0; } for (i = CONFIG_BLE_MESH_PBA_SAME_TIME; i < BLE_MESH_PROV_SAME_TIME; i++) { @@ -1457,16 +1459,27 @@ static int bearer_ctl_send(const uint8_t idx, uint8_t op, void *data, uint8_t da static void send_link_open(const uint8_t idx) { int j; + uint8_t count; + + link[idx].link_id = 0; - /** Generate link ID, and may need to check if this id is - * currently being used, which may will not happen ever. - */ - bt_mesh_rand(&link[idx].link_id, sizeof(uint32_t)); while (1) { + count = 0; + + /* Make sure the generated Link ID is not 0 */ + while(link[idx].link_id == 0) { + bt_mesh_rand(&link[idx].link_id, sizeof(link[idx].link_id)); + if (count++ > 10) { + BT_ERR("Link ID error: all zero"); + return; + } + } + + /* Check if the generated Link ID is the same with other links */ for (j = 0; j < CONFIG_BLE_MESH_PBA_SAME_TIME; j++) { if (bt_mesh_atomic_test_bit(link[j].flags, LINK_ACTIVE) || link[j].linking) { if (link[idx].link_id == link[j].link_id) { - bt_mesh_rand(&link[idx].link_id, sizeof(uint32_t)); + bt_mesh_rand(&link[idx].link_id, sizeof(link[idx].link_id)); break; } } @@ -1700,7 +1713,7 @@ static void prov_capabilities(const uint8_t idx, const uint8_t *data) algorithms = sys_get_be16(&data[1]); BT_INFO("Algorithms: 0x%04x", algorithms); - if (algorithms != BIT(PROV_ALG_P256)) { + if (!(algorithms & BIT(PROV_ALG_P256))) { BT_ERR("Invalid algorithms 0x%04x", algorithms); goto fail; } @@ -3426,6 +3439,21 @@ int bt_mesh_provisioner_prov_deinit(bool erase) } #endif /* CONFIG_BLE_MESH_DEINIT */ +static bool bt_mesh_prov_svc_adv_filter(void) +{ + static uint32_t timestamp = 0; + static uint32_t pre_timestamp = 0; + + timestamp = k_uptime_get_32(); + + if (PROV_SVC_ADV_RX_CHECK(pre_timestamp, timestamp)) { + pre_timestamp = timestamp; + return false; + } + + return true; +} + static bool is_unprov_dev_info_callback_to_app(bt_mesh_prov_bearer_t bearer, const uint8_t uuid[16], const bt_mesh_addr_t *addr, uint16_t oob_info, int8_t rssi) { @@ -3443,6 +3471,11 @@ static bool is_unprov_dev_info_callback_to_app(bt_mesh_prov_bearer_t bearer, con if (i == ARRAY_SIZE(unprov_dev)) { BT_DBG("Device not in queue, notify to app layer"); + + if (adv_type == BLE_MESH_ADV_IND && bt_mesh_prov_svc_adv_filter()) { + return true; + } + if (notify_unprov_adv_pkt_cb) { notify_unprov_adv_pkt_cb(addr->val, addr->type, adv_type, uuid, oob_info, bearer, rssi); } diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.c b/components/bt/esp_ble_mesh/mesh_core/transport.c index 7d3f45310d..d62a6aa7b5 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.c +++ b/components/bt/esp_ble_mesh/mesh_core/transport.c @@ -2,7 +2,7 @@ /* * SPDX-FileCopyrightText: 2017 Intel Corporation - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -257,7 +257,15 @@ static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx) { bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 3U, BLE_MESH_BUF_REF_SMALL); - BLE_MESH_ADV(tx->seg[seg_idx])->busy = 0U; + /** + * When cancelling a segment that is still in the adv sending queue, `tx->seg_pending` + * must else be decremented by one. More detailed information + * can be found in BLEMESH24-26. + */ + if (bt_mesh_atomic_cas(&BLE_MESH_ADV_BUSY(tx->seg[seg_idx]), 1, 0)) { + tx->seg_pending--; + } + net_buf_unref(tx->seg[seg_idx]); tx->seg[seg_idx] = NULL; tx->nack_count--; @@ -388,7 +396,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) continue; } - if (BLE_MESH_ADV(seg)->busy) { + if (bt_mesh_atomic_get(&BLE_MESH_ADV_BUSY(seg))) { BT_DBG("Skipping segment that's still advertising"); continue; } @@ -711,6 +719,9 @@ bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl **match) return false; } else { +#if CONFIG_BLE_MESH_NOT_RELAY_REPLAY_MSG + rx->replay_msg = 1; +#endif return true; } } diff --git a/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c b/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c index 1b33438331..9db7093625 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c @@ -259,7 +259,8 @@ static void time_get(struct bt_mesh_model *model, change.time_status.subsecond = srv->state->time.subsecond; change.time_status.uncertainty = srv->state->time.uncertainty; change.time_status.time_authority = srv->state->time.time_authority; - change.time_status.tai_utc_delta_curr = srv->state->time.subsecond; + change.time_status.tai_utc_delta_curr = srv->state->time.tai_utc_delta_curr; + change.time_status.time_zone_offset_curr = srv->state->time.time_zone_offset_curr; bt_mesh_time_scene_server_cb_evt_to_btc( BTC_BLE_MESH_EVT_TIME_SCENE_SERVER_STATE_CHANGE, model, ctx, (const uint8_t *)&change, sizeof(change)); @@ -402,7 +403,8 @@ static void time_set(struct bt_mesh_model *model, change.time_set.subsecond = srv->state->time.subsecond; change.time_set.uncertainty = srv->state->time.uncertainty; change.time_set.time_authority = srv->state->time.time_authority; - change.time_set.tai_utc_delta_curr = srv->state->time.subsecond; + change.time_set.tai_utc_delta_curr = srv->state->time.tai_utc_delta_curr; + change.time_status.time_zone_offset_curr = srv->state->time.time_zone_offset_curr; break; case BLE_MESH_MODEL_OP_TIME_ZONE_SET: change.time_zone_set.time_zone_offset_new = srv->state->time.time_zone_offset_new; diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index e84f5a6064..bdcda374af 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -29,7 +29,7 @@ config BT_BLUEDROID_PINNED_TO_CORE config BT_BTU_TASK_STACK_SIZE int "Bluetooth Bluedroid Host Stack task stack size" depends on BT_BLUEDROID_ENABLED - default 4096 + default 4352 help This select btu task stack size @@ -47,6 +47,13 @@ config BT_CLASSIC_ENABLED help For now this option needs "SMP_ENABLE" to be set to yes +config BT_CLASSIC_BQB_ENABLED + bool "Host Qualitifcation support for Classic Bluetooth" + depends on BT_CLASSIC_ENABLED + default n + help + This enables functionalities of Host qualification for Classic Bluetooth. + config BT_A2DP_ENABLE bool "A2DP" depends on BT_CLASSIC_ENABLED @@ -69,21 +76,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" @@ -107,26 +116,26 @@ 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 + +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_SSP_ENABLED bool "Secure Simple Pairing" @@ -213,7 +222,10 @@ config BT_GATTS_ROBUST_CACHING_ENABLED depends on BT_GATTS_ENABLE default n help - This option enable gatt robust caching feature on server + This option enables the GATT robust caching feature on the server. + if turned on, the Client Supported Features characteristic, Database Hash characteristic, + and Server Supported Features characteristic will be included in the GAP SERVICE. + config BT_GATTS_DEVICE_NAME_WRITABLE bool "Allow to write device name by GATT clients" @@ -244,6 +256,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 @@ -254,7 +274,7 @@ config BT_GATTC_CACHE_NVS_FLASH config BT_GATTC_CONNECT_RETRY_COUNT int "The number of attempts to reconnect if the connection establishment failed" depends on BT_GATTC_ENABLE - range 0 7 + range 0 255 default 3 help The number of attempts to reconnect if the connection establishment failed @@ -274,6 +294,17 @@ config BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE In order to reduce the pairing time, slave actively initiates connection parameters update during pairing. +config BT_BLE_SMP_ID_RESET_ENABLE + bool "Reset device identity when all bonding records are deleted" + depends on BT_BLE_SMP_ENABLE + default n + help + There are tracking risks associated with using a fixed or static IRK. + If enabled this option, Bluedroid will assign a new randomly-generated IRK + when all pairing and bonding records are deleted. This would decrease the ability + of a previously paired peer to be used to determine whether a device + with which it previously shared an IRK is within range. + config BT_STACK_NO_LOG bool "Disable BT debug logs (minimize bin size)" depends on BT_BLUEDROID_ENABLED @@ -1035,7 +1066,7 @@ config BT_ACL_CONNECTIONS config BT_MULTI_CONNECTION_ENBALE bool "Enable BLE multi-conections" - depends on BT_BLUEDROID_ENABLED + depends on BT_BLE_ENABLED default y help Enable this option if there are multiple connections @@ -1056,7 +1087,7 @@ config BT_BLE_DYNAMIC_ENV_MEMORY config BT_BLE_HOST_QUEUE_CONG_CHECK bool "BLE queue congestion check" - depends on BT_BLUEDROID_ENABLED + depends on BT_BLE_ENABLED default n help When scanning and scan duplicate is not enabled, if there are a lot of adv packets around @@ -1068,6 +1099,14 @@ config BT_SMP_ENABLE depends on BT_BLUEDROID_ENABLED default BT_CLASSIC_ENABLED || BT_BLE_SMP_ENABLE +config BT_SMP_MAX_BONDS + int "BT/BLE maximum bond device count" + depends on BT_SMP_ENABLE + range 1 32 + default 15 + help + The number of security records for peer devices. + config BT_BLE_ACT_SCAN_REP_ADV_SCAN bool "Report adv data and scan response individually when BLE active scan" depends on BT_BLUEDROID_ENABLED && BT_BLE_ENABLED @@ -1081,7 +1120,7 @@ config BT_BLE_ACT_SCAN_REP_ADV_SCAN config BT_BLE_ESTAB_LINK_CONN_TOUT int "Timeout of BLE connection establishment" - depends on BT_BLUEDROID_ENABLED + depends on BT_BLE_ENABLED range 1 60 default 30 help @@ -1116,7 +1155,7 @@ config BT_BLE_RPA_SUPPORTED config BT_BLE_RPA_TIMEOUT int "Timeout of resolvable private address" - depends on BT_BLUEDROID_ENABLED + depends on BT_BLE_ENABLED range 1 3600 default 900 help @@ -1125,14 +1164,43 @@ 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_BLE_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER)) default y help - This enables BLE 5.0 features, this option only support esp32c3/esp32s3 chip + Enabling this option activates BLE 5.0 features. + This option is universally supported in chips that support BLE, except for ESP32. 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_BLE_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || SOC_ESP_NIMBLE_CONTROLLER)) 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_BLE_50_FEATURES_SUPPORTED && SOC_ESP_NIMBLE_CONTROLLER) + 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_BLE_50_FEATURES_SUPPORTED && SOC_ESP_NIMBLE_CONTROLLER) + default n + help + Enable the periodic advertising enhancements + +config BT_BLE_FEAT_CREATE_SYNC_ENH + bool "Enable create sync enhancements(reporting disable and duplicate filtering enable support)" + depends on (BT_BLE_50_FEATURES_SUPPORTED && SOC_ESP_NIMBLE_CONTROLLER) + default n + help + Enable the create sync enhancements + +config BT_BLE_HIGH_DUTY_ADV_INTERVAL + bool "Enable BLE high duty advertising interval feature" + depends on BT_BLE_ENABLED + default n + help + This enable BLE high duty advertising interval feature diff --git a/components/bt/host/bluedroid/api/esp_bt_main.c b/components/bt/host/bluedroid/api/esp_bt_main.c index 911897a89b..2767e2e52e 100644 --- a/components/bt/host/bluedroid/api/esp_bt_main.c +++ b/components/bt/host/bluedroid/api/esp_bt_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,8 @@ #include "esp_bt.h" #include "osi/future.h" #include "osi/allocator.h" +#include "hci_log/bt_hci_log.h" +#include "bt_common.h" static bool bd_already_enable = false; static bool bd_already_init = false; @@ -157,6 +159,10 @@ esp_err_t esp_bluedroid_init(void) bd_already_init = true; +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_init(); +#endif // (BT_HCI_LOG_INCLUDED == TRUE) + return ESP_OK; } @@ -199,6 +205,10 @@ esp_err_t esp_bluedroid_deinit(void) btc_deinit(); +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_deinit(); +#endif // (BT_HCI_LOG_INCLUDED == TRUE) + bd_already_init = false; return ESP_OK; 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 57e102d48f..4381161b91 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,6 +22,11 @@ esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback) return (btc_profile_cb_set(BTC_PID_GAP_BLE, callback) == 0 ? ESP_OK : ESP_FAIL); } +esp_gap_ble_cb_t esp_ble_gap_get_callback(void) +{ + return (esp_gap_ble_cb_t) btc_profile_cb_get(BTC_PID_GAP_BLE); +} + #if (BLE_42_FEATURE_SUPPORT == TRUE) esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data) { @@ -122,6 +127,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) @@ -138,7 +156,7 @@ esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params) if (ESP_BLE_IS_VALID_PARAM(params->min_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(params->max_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(params->timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && - (params->latency <= ESP_BLE_CONN_LATENCY_MAX || params->latency == ESP_BLE_CONN_PARAM_UNDEF) && + (params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((params->timeout * 10) >= ((1 + params->latency) * ((params->max_int * 5) >> 1))) && params->min_int <= params->max_int) { msg.sig = BTC_SIG_API_CALL; @@ -186,6 +204,48 @@ esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr) return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +esp_err_t esp_ble_gap_set_resolvable_private_address_timeout(uint16_t rpa_timeout) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (rpa_timeout < 0x0001 || rpa_timeout > 0x0E10) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT; + arg.set_rpa_timeout.rpa_timeout = rpa_timeout; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + + +esp_err_t esp_ble_gap_add_device_to_resolving_list(esp_bd_addr_t peer_addr, uint8_t addr_type, uint8_t *peer_irk) +{ + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (addr_type > BLE_ADDR_TYPE_RANDOM ||!peer_addr || (addr_type && ((peer_addr[0] & 0xC0) != 0xC0))) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_ADD_DEVICE_TO_RESOLVING_LIST; + + memcpy(arg.add_dev_to_resolving_list.addr, peer_addr, ESP_BD_ADDR_LEN); + arg.add_dev_to_resolving_list.addr_type = addr_type; + memcpy(arg.add_dev_to_resolving_list.irk, peer_irk, ESP_PEER_IRK_LEN); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + esp_err_t esp_ble_gap_clear_rand_addr(void) { btc_msg_t msg; @@ -281,6 +341,7 @@ esp_err_t esp_ble_gap_config_local_icon (uint16_t icon) case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV: case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD: case ESP_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_POD_AND_NAV: + case ESP_BLE_APPEARANCE_STANDALONE_SPEAKER: msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_ICON; @@ -354,7 +415,7 @@ esp_err_t esp_ble_gap_set_prefer_conn_params(esp_bd_addr_t bd_addr, if (ESP_BLE_IS_VALID_PARAM(min_conn_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(max_conn_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(supervision_tout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && - (slave_latency <= ESP_BLE_CONN_LATENCY_MAX || slave_latency == ESP_BLE_CONN_PARAM_UNDEF) && + (slave_latency <= ESP_BLE_CONN_LATENCY_MAX) && ((supervision_tout * 10) >= ((1 + slave_latency) * ((max_conn_int * 5) >> 1))) && min_conn_int <= max_conn_int) { msg.sig = BTC_SIG_API_CALL; @@ -470,8 +531,7 @@ esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_d ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); - if (raw_data == NULL - || (raw_data_len <= 0 || raw_data_len > ESP_BLE_SCAN_RSP_DATA_LEN_MAX)) { + if ((raw_data_len != 0 && raw_data == NULL) || raw_data_len > ESP_BLE_ADV_DATA_LEN_MAX) { return ESP_ERR_INVALID_ARG; } @@ -577,7 +637,11 @@ esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type, LOG_ERROR("ESP_BLE_APP_ENC_KEY_SIZE is deprecated, use ESP_GATT_PERM_ENCRYPT_KEY_SIZE in characteristic definition"); return ESP_ERR_NOT_SUPPORTED; } - + if (param_type == ESP_BLE_SM_MAX_KEY_SIZE || param_type == ESP_BLE_SM_MIN_KEY_SIZE) { + if (((uint8_t *)value)[0] > 16 || ((uint8_t *)value)[0] < 7) { + return ESP_ERR_INVALID_ARG; + } + } btc_msg_t msg = {0}; btc_ble_gap_args_t arg; @@ -818,6 +882,122 @@ esp_err_t esp_gap_ble_set_authorization(esp_bd_addr_t bd_addr, bool authorize) return ESP_FAIL; } +#if (BLE_42_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_dtm_tx_start(const esp_ble_dtm_tx_t *tx_params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (!tx_params) { + return ESP_ERR_INVALID_ARG; + } + + 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_DTM_TX_START; + + memcpy(&arg.dtm_tx_start, tx_params, sizeof(esp_ble_dtm_tx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_dtm_rx_start(const esp_ble_dtm_rx_t *rx_params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (!rx_params) { + return ESP_ERR_INVALID_ARG; + } + + 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_DTM_RX_START; + + memcpy(&arg.dtm_rx_start, rx_params, sizeof(esp_ble_dtm_rx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_dtm_enh_tx_start(const esp_ble_dtm_enh_tx_t *tx_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (!tx_params) { + return ESP_ERR_INVALID_ARG; + } + + 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_DTM_ENH_TX_START; + + memcpy(&arg.dtm_enh_tx_start, tx_params, sizeof(esp_ble_dtm_enh_tx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params) +{ + btc_msg_t msg = {0}; + btc_ble_5_gap_args_t arg; + + if (!rx_params) { + return ESP_ERR_INVALID_ARG; + } + + 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_DTM_ENH_RX_START; + + memcpy(&arg.dtm_enh_rx_start, rx_params, sizeof(esp_ble_dtm_enh_rx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +esp_err_t esp_ble_dtm_stop(void) +{ + btc_msg_t msg = {0}; + + 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_DTM_STOP; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_set_privacy_mode(esp_ble_addr_type_t addr_type, esp_bd_addr_t addr, esp_ble_privacy_mode_t mode) +{ + btc_msg_t msg; + btc_ble_gap_args_t arg; + + 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_SET_PRIVACY_MODE; + + arg.set_privacy_mode.addr_type = addr_type; + memcpy(arg.set_privacy_mode.addr, addr, sizeof(esp_bd_addr_t)); + arg.set_privacy_mode.privacy_mode = mode; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + #if (BLE_50_FEATURE_SUPPORT == TRUE) esp_err_t esp_ble_gap_read_phy(esp_bd_addr_t bd_addr) @@ -1052,8 +1232,13 @@ esp_err_t esp_ble_gap_periodic_adv_set_params(uint8_t instance, const esp_ble_ga } +#if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) +esp_err_t esp_ble_gap_config_periodic_adv_data_raw(uint8_t instance, uint16_t length, + const uint8_t *data, bool only_update_did) +#else esp_err_t esp_ble_gap_config_periodic_adv_data_raw(uint8_t instance, uint16_t length, const uint8_t *data) +#endif { btc_msg_t msg; btc_ble_5_gap_args_t arg; @@ -1067,13 +1252,22 @@ esp_err_t esp_ble_gap_config_periodic_adv_data_raw(uint8_t instance, uint16_t le arg.periodic_adv_cfg_data.instance = instance; arg.periodic_adv_cfg_data.len = length; arg.periodic_adv_cfg_data.data = (uint8_t *)data; +#if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) + arg.periodic_adv_cfg_data.only_update_did = only_update_did; +#else + arg.periodic_adv_cfg_data.only_update_did = false; +#endif return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), btc_gap_ble_arg_deep_copy, btc_gap_ble_arg_deep_free) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +#if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) +esp_err_t esp_ble_gap_periodic_adv_start(uint8_t instance,bool include_adi) +#else esp_err_t esp_ble_gap_periodic_adv_start(uint8_t instance) +#endif { btc_msg_t msg; btc_ble_5_gap_args_t arg; @@ -1084,6 +1278,11 @@ esp_err_t esp_ble_gap_periodic_adv_start(uint8_t instance) msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_PERIODIC_ADV_START; + #if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) + arg.periodic_adv_start.include_adi = include_adi; + #else + arg.periodic_adv_start.include_adi = false; + #endif arg.periodic_adv_start.instance = instance; return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) @@ -1298,7 +1497,7 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, if (ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(phy_1m_conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && - (phy_1m_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX || phy_1m_conn_params->latency == ESP_BLE_CONN_PARAM_UNDEF) && + (phy_1m_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((phy_1m_conn_params->supervision_timeout * 10) >= ((1 + phy_1m_conn_params->latency) * ((phy_1m_conn_params->interval_max * 5) >> 1))) && (phy_1m_conn_params->interval_min <= phy_1m_conn_params->interval_max)) { @@ -1322,7 +1521,7 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, if (ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(phy_2m_conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && - (phy_2m_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX || phy_2m_conn_params->latency == ESP_BLE_CONN_PARAM_UNDEF) && + (phy_2m_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((phy_2m_conn_params->supervision_timeout * 10) >= ((1 + phy_2m_conn_params->latency) * ((phy_2m_conn_params->interval_max * 5) >> 1))) && (phy_2m_conn_params->interval_min <= phy_2m_conn_params->interval_max)) { @@ -1346,7 +1545,7 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, if (ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->interval_min, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->interval_max, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) && ESP_BLE_IS_VALID_PARAM(phy_coded_conn_params->supervision_timeout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) && - (phy_coded_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX || phy_coded_conn_params->latency == ESP_BLE_CONN_PARAM_UNDEF) && + (phy_coded_conn_params->latency <= ESP_BLE_CONN_LATENCY_MAX) && ((phy_coded_conn_params->supervision_timeout * 10) >= ((1 + phy_coded_conn_params->latency) * ((phy_coded_conn_params->interval_max * 5) >> 1))) && (phy_coded_conn_params->interval_min <= phy_coded_conn_params->interval_max)) { @@ -1370,3 +1569,123 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, } #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +esp_err_t esp_ble_gap_periodic_adv_recv_enable(uint16_t sync_handle, uint8_t enable) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + 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_PERIODIC_ADV_RECV_ENABLE; + + arg.periodic_adv_recv_en.sync_handle = sync_handle; + arg.periodic_adv_recv_en.enable = enable; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_periodic_adv_sync_trans(esp_bd_addr_t addr, uint16_t service_data, uint16_t sync_handle) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (addr == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_SYNC_TRANS; + + memcpy(arg.periodic_adv_sync_trans.addr, addr, sizeof(esp_bd_addr_t)); + arg.periodic_adv_sync_trans.service_data = service_data; + arg.periodic_adv_sync_trans.sync_handle = sync_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_periodic_adv_set_info_trans(esp_bd_addr_t addr, uint16_t service_data, uint8_t adv_handle) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (addr == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS; + + memcpy(arg.periodic_adv_set_info_trans.addr, addr, sizeof(esp_bd_addr_t)); + arg.periodic_adv_set_info_trans.service_data = service_data; + arg.periodic_adv_set_info_trans.adv_handle = adv_handle; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_gap_set_periodic_adv_sync_trans_params(esp_bd_addr_t addr, const esp_ble_gap_past_params_t *params) +{ + btc_msg_t msg; + btc_ble_5_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + if (params == NULL) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS; + + if (addr) { + memcpy(arg.set_periodic_adv_sync_trans_params.addr, addr, sizeof(esp_bd_addr_t)); + } else { + memset(arg.set_periodic_adv_sync_trans_params.addr, 0, sizeof(esp_bd_addr_t)); + } + memcpy(&arg.set_periodic_adv_sync_trans_params.params, params, sizeof(esp_ble_gap_past_params_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + +esp_err_t esp_ble_gap_vendor_command_send(esp_ble_vendor_cmd_params_t *vendor_cmd_param) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + if (!vendor_cmd_param || !vendor_cmd_param->p_param_buf || !vendor_cmd_param->param_len) { + return ESP_ERR_INVALID_ARG; + } + // If command is not a VSC, return error + if ((vendor_cmd_param->opcode & VENDOR_HCI_CMD_MASK) != VENDOR_HCI_CMD_MASK) { + return ESP_ERR_INVALID_ARG; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT; + arg.vendor_cmd_send.opcode = vendor_cmd_param->opcode; + arg.vendor_cmd_send.param_len = vendor_cmd_param->param_len; + arg.vendor_cmd_send.p_param_buf = vendor_cmd_param->p_param_buf; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy, btc_gap_ble_arg_deep_free) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} diff --git a/components/bt/host/bluedroid/api/esp_gap_bt_api.c b/components/bt/host/bluedroid/api/esp_gap_bt_api.c index 6ff0b08a17..efed98b5d5 100644 --- a/components/bt/host/bluedroid/api/esp_gap_bt_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_bt_api.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 */ @@ -412,6 +412,10 @@ esp_err_t esp_bt_gap_set_qos(esp_bd_addr_t remote_bda, uint32_t t_poll) return ESP_ERR_INVALID_STATE; } + if (t_poll < ESP_BT_GAP_TPOLL_MIN || t_poll > ESP_BT_GAP_TPOLL_MAX) { + return ESP_ERR_INVALID_ARG; + } + msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GAP_BT; msg.act = BTC_GAP_BT_ACT_SET_QOS; @@ -420,4 +424,23 @@ esp_err_t esp_bt_gap_set_qos(esp_bd_addr_t remote_bda, uint32_t t_poll) arg.set_qos.t_poll = t_poll; return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } + +esp_err_t esp_bt_gap_set_acl_pkt_types(esp_bd_addr_t remote_bda, uint16_t pkt_types) +{ + btc_msg_t msg; + btc_gap_bt_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES; + + memcpy(&arg.set_acl_pkt_types.bda, remote_bda, sizeof(bt_bdaddr_t)); + arg.set_acl_pkt_types.pkt_types = pkt_types; + return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + #endif /* #if BTC_GAP_BT_INCLUDED == TRUE */ diff --git a/components/bt/host/bluedroid/api/esp_gattc_api.c b/components/bt/host/bluedroid/api/esp_gattc_api.c index 40f3d82d65..5f078b2809 100644 --- a/components/bt/host/bluedroid/api/esp_gattc_api.c +++ b/components/bt/host/bluedroid/api/esp_gattc_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,6 +29,11 @@ esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback) return ESP_OK; } +esp_gattc_cb_t esp_ble_gattc_get_callback(void) +{ + return (esp_gattc_cb_t) btc_profile_cb_get(BTC_PID_GATTC); +} + esp_err_t esp_ble_gattc_app_register(uint16_t app_id) { btc_msg_t msg = {0}; @@ -447,6 +452,41 @@ esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if, return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if, + uint16_t conn_id, esp_gattc_multi_t *read_multi, + esp_gatt_auth_req_t auth_req) +{ + btc_msg_t msg = {0}; + btc_ble_gattc_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id); + if (!gatt_check_connection_state_by_tcb(p_tcb)) { + LOG_WARN("%s, The connection not created.", __func__); + return ESP_ERR_INVALID_STATE; + } + + if (L2CA_CheckIsCongest(L2CAP_ATT_CID, p_tcb->peer_bda)) { + LOG_DEBUG("%s, the l2cap chanel is congest.", __func__); + return ESP_FAIL; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTC; + msg.act = BTC_GATTC_ACT_READ_MULTIPLE_VARIABLE_CHAR; + arg.read_multiple.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id); + arg.read_multiple.num_attr = read_multi->num_attr; + arg.read_multiple.auth_req = auth_req; + + if (read_multi->num_attr > 0) { + memcpy(arg.read_multiple.handles, read_multi->handles, sizeof(uint16_t)*read_multi->num_attr); + } else { + LOG_ERROR("%s(), the num_attr should not be 0.", __func__); + return ESP_FAIL; + } + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t handle, diff --git a/components/bt/host/bluedroid/api/esp_gatts_api.c b/components/bt/host/bluedroid/api/esp_gatts_api.c index 7fb6b58ea9..66fa5c6617 100644 --- a/components/bt/host/bluedroid/api/esp_gatts_api.c +++ b/components/bt/host/bluedroid/api/esp_gatts_api.c @@ -29,6 +29,11 @@ esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback) return (btc_profile_cb_set(BTC_PID_GATTS, callback) == 0 ? ESP_OK : ESP_FAIL); } +esp_gatts_cb_t esp_ble_gatts_get_callback(void) +{ + return (esp_gatts_cb_t) btc_profile_cb_get(BTC_PID_GATTS); +} + esp_err_t esp_ble_gatts_app_register(uint16_t app_id) { btc_msg_t msg = {0}; @@ -421,4 +426,17 @@ static esp_err_t esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t *char_ return ESP_OK; } +esp_err_t esp_ble_gatts_show_local_database(void) +{ + btc_msg_t msg = {0}; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GATTS; + msg.act = BTC_GATTS_ACT_SHOW_LOCAL_DATABASE; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + #endif ///GATTS_INCLUDED 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 918e08ca01..f17468dcc4 100644 --- a/components/bt/host/bluedroid/api/esp_hf_ag_api.c +++ b/components/bt/host/bluedroid/api/esp_hf_ag_api.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 */ @@ -171,6 +171,9 @@ esp_err_t esp_hf_ag_volume_control(esp_bd_addr_t remote_addr, esp_hf_volume_cont if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { return ESP_ERR_INVALID_STATE; } + if (volume < 0 || volume > 15) { + return ESP_ERR_INVALID_ARG; + } btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_HF; @@ -237,6 +240,9 @@ esp_err_t esp_hf_ag_devices_status_indchange(esp_bd_addr_t remote_addr, if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { return ESP_ERR_INVALID_STATE; } + if (signal < 0 || signal > 5) { + return ESP_ERR_INVALID_ARG; + } btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_HF; @@ -255,6 +261,27 @@ esp_err_t esp_hf_ag_devices_status_indchange(esp_bd_addr_t remote_addr, return (state == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } +esp_err_t esp_hf_ag_ciev_report(esp_bd_addr_t remote_addr, esp_hf_ciev_report_type_t ind_type, int value) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_CIEV_REPORT_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + memcpy(&(arg.ciev_rep.remote_addr), remote_addr, sizeof(esp_bd_addr_t)); + arg.ciev_rep.ind.type = ind_type; + arg.ciev_rep.ind.value = value; + + /* Switch to BTC context */ + bt_status_t state = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (state == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + esp_err_t esp_hf_ag_cind_response(esp_bd_addr_t remote_addr, esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state, @@ -264,6 +291,10 @@ esp_err_t esp_hf_ag_cind_response(esp_bd_addr_t remote_addr, if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { return ESP_ERR_INVALID_STATE; } + if (signal < 0 || signal > 5 || batt_lev < 0 || batt_lev > 5) { + return ESP_ERR_INVALID_ARG; + } + btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_HF; @@ -337,11 +368,14 @@ esp_err_t esp_hf_ag_clcc_response(esp_bd_addr_t remote_addr, int index, esp_hf_c return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } -esp_err_t esp_hf_ag_cnum_response(esp_bd_addr_t remote_addr, char *number, esp_hf_subscriber_service_type_t type) +esp_err_t esp_hf_ag_cnum_response(esp_bd_addr_t remote_addr, char *number, int number_type, esp_hf_subscriber_service_type_t service_type) { if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { return ESP_ERR_INVALID_STATE; } + if (number == NULL || number_type < 128 || number_type > 175) { + return ESP_ERR_INVALID_ARG; + } btc_msg_t msg; msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_HF; @@ -351,7 +385,8 @@ esp_err_t esp_hf_ag_cnum_response(esp_bd_addr_t remote_addr, char *number, esp_h memset(&arg, 0, sizeof(btc_hf_args_t)); memcpy(&(arg.cnum_rep), remote_addr, sizeof(esp_bd_addr_t)); arg.cnum_rep.number = number; //deep_copy - arg.cnum_rep.type = type; + arg.cnum_rep.number_type = number_type; + arg.cnum_rep.service_type = service_type; /* Switch to BTC context */ bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), @@ -512,10 +547,30 @@ esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_h } #if (BTM_SCO_HCI_INCLUDED == TRUE) +esp_err_t esp_hf_ag_pkt_stat_nums_get(uint16_t sync_conn_handle) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF; + msg.act = BTC_HF_REQUEST_PKT_STAT_EVT; + + btc_hf_args_t arg; + memset(&arg, 0, sizeof(btc_hf_args_t)); + arg.pkt_sync_hd.sync_conn_handle = sync_conn_handle; + + /* Switch to BTC context */ + bt_status_t status = btc_transfer_context(&msg, &arg, sizeof(btc_hf_args_t), NULL, NULL); + return (status == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} + void esp_hf_ag_outgoing_data_ready(void) { btc_hf_ci_sco_data(); } -#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE ) */ +#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */ #endif // BTC_HF_INCLUDED diff --git a/components/bt/host/bluedroid/api/esp_hf_client_api.c b/components/bt/host/bluedroid/api/esp_hf_client_api.c index 158847e155..9909f4423a 100644 --- a/components/bt/host/bluedroid/api/esp_hf_client_api.c +++ b/components/bt/host/bluedroid/api/esp_hf_client_api.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 */ @@ -515,8 +515,27 @@ esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; } +#if (BTM_SCO_HCI_INCLUDED == TRUE) +esp_err_t esp_hf_client_pkt_stat_nums_get(uint16_t sync_conn_handle) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + btc_msg_t msg; + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_HF_CLIENT; + msg.act = BTC_HF_CLIENT_REQUEST_PKT_STAT_EVT; + + btc_hf_client_args_t arg; + memset(&arg, 0, sizeof(btc_hf_client_args_t)); + arg.pkt_sync_hd.sync_conn_handle = sync_conn_handle; + + /* Switch to BTC context */ + bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_hf_client_args_t), NULL, NULL); + return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL; +} -#if (BTM_SCO_HCI_INCLUDED == TRUE ) void esp_hf_client_outgoing_data_ready(void) { BTA_HfClientCiData(); @@ -537,6 +556,6 @@ int32_t esp_hf_client_pcm_resample(void *src, uint32_t in_bytes, void *dst) return BTA_DmPcmResample(src, in_bytes, dst); } -#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE ) */ +#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */ #endif /* BTC_HF_CLIENT_INCLUDED */ diff --git a/components/bt/host/bluedroid/api/esp_spp_api.c b/components/bt/host/bluedroid/api/esp_spp_api.c index 0578691a22..fce84be056 100644 --- a/components/bt/host/bluedroid/api/esp_spp_api.c +++ b/components/bt/host/bluedroid/api/esp_spp_api.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 */ @@ -109,8 +109,11 @@ esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask, btc_spp_args_t arg; ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); - if (sec_mask != ESP_SPP_SEC_NONE && sec_mask != ESP_SPP_SEC_AUTHORIZE && sec_mask != ESP_SPP_SEC_AUTHENTICATE) { - LOG_WARN("Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only\n"); + if (sec_mask != ESP_SPP_SEC_NONE && + sec_mask != ESP_SPP_SEC_AUTHENTICATE && + sec_mask != (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)) { + LOG_WARN("Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHENTICATE" + "or (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) only\n"); } msg.sig = BTC_SIG_API_CALL; @@ -152,8 +155,16 @@ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask, return ESP_ERR_INVALID_ARG; } - if (sec_mask != ESP_SPP_SEC_NONE && sec_mask != ESP_SPP_SEC_AUTHORIZE && sec_mask != ESP_SPP_SEC_AUTHENTICATE) { - LOG_WARN("Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only\n"); + if (sec_mask != ESP_SPP_SEC_NONE && + sec_mask != ESP_SPP_SEC_AUTHENTICATE && + sec_mask != (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) && + sec_mask != ESP_SPP_SEC_IN_16_DIGITS && + sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE) && + sec_mask != (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)) { + LOG_WARN("Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHENTICATE," + "(ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT)," + "ESP_SPP_SEC_IN_16_DIGITS, (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE), or" + "(ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) only\n"); } msg.sig = BTC_SIG_API_CALL; diff --git a/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h b/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h index 99094d237a..a0ff920c31 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_a2dp_api.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 */ @@ -241,7 +241,7 @@ typedef int32_t (* esp_a2d_source_data_cb_t)(uint8_t *buf, int32_t len); * * @return * - ESP_OK: success - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: if callback is a NULL function pointer * */ @@ -258,7 +258,7 @@ esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback); * * @return * - ESP_OK: success - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: if callback is a NULL function pointer * */ @@ -275,7 +275,7 @@ esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback); * * @return * - ESP_OK: if the initialization request is sent successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -290,7 +290,7 @@ esp_err_t esp_a2d_sink_init(void); * * @return * - ESP_OK: if the deinitialization request is sent successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -306,7 +306,7 @@ esp_err_t esp_a2d_sink_deinit(void); * * @return * - ESP_OK: connect request is sent to lower layer successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -322,7 +322,7 @@ esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda); * * @return * - ESP_OK: disconnect request is sent to lower layer successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -339,7 +339,7 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda); * * @return * - ESP_OK: delay value is sent to lower layer successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -352,7 +352,7 @@ esp_err_t esp_a2d_sink_set_delay_value(uint16_t delay_value); * * @return * - ESP_OK: if the request is sent successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -368,7 +368,7 @@ esp_err_t esp_a2d_sink_get_delay_value(void); * * @return * - ESP_OK: control command is sent to lower layer successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -385,7 +385,7 @@ esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl); * * @return * - ESP_OK: if the initialization request is sent to lower layer successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -400,7 +400,7 @@ esp_err_t esp_a2d_source_init(void); * * @return * - ESP_OK: success - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -417,7 +417,7 @@ esp_err_t esp_a2d_source_deinit(void); * * @return * - ESP_OK: success - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: if callback is a NULL function pointer * */ @@ -433,7 +433,7 @@ esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callbac * * @return * - ESP_OK: connect request is sent to lower layer successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -448,7 +448,7 @@ esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda); * @param[in] remote_bda: remote bluetooth device address * @return * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ diff --git a/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h b/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h index 98c6fc1bdb..182f87600d 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h +++ b/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,7 @@ extern "C" { return ESP_ERR_INVALID_STATE; \ } -#define ESP_BT_STATUS_BASE_FOR_HCI_ERR 0X0100 /* base for coverting HCI error code to ESP status */ +#define ESP_BT_STATUS_BASE_FOR_HCI_ERR 0X0100 /* base for converting HCI error code to ESP status */ /* relate to BT_STATUS_xxx in bt_def.h */ /// Status Return Value @@ -47,7 +47,6 @@ typedef enum { ESP_BT_STATUS_MEMORY_FULL = 20, /* relate to BT_STATUS_MEMORY_FULL in bt_def.h */ ESP_BT_STATUS_EIR_TOO_LARGE, /* relate to BT_STATUS_EIR_TOO_LARGE in bt_def.h */ ESP_BT_STATUS_HCI_SUCCESS = ESP_BT_STATUS_BASE_FOR_HCI_ERR, - ESP_BT_STATUS_HCI_PENDING, ESP_BT_STATUS_HCI_ILLEGAL_COMMAND, ESP_BT_STATUS_HCI_NO_CONNECTION, ESP_BT_STATUS_HCI_HW_FAILURE, @@ -126,18 +125,20 @@ typedef uint8_t esp_link_key[ESP_BT_OCTET16_LEN]; /* Link Key */ /// Default GATT interface id #define ESP_DEFAULT_GATT_IF 0xff +#if BLE_HIGH_DUTY_ADV_INTERVAL +#define ESP_BLE_PRIM_ADV_INT_MIN 0x000008 /*!< Minimum advertising interval for undirected and low duty cycle directed advertising */ +#else #define ESP_BLE_PRIM_ADV_INT_MIN 0x000020 /*!< Minimum advertising interval for undirected and low duty cycle directed advertising */ +#endif #define ESP_BLE_PRIM_ADV_INT_MAX 0xFFFFFF /*!< Maximum advertising interval for undirected and low duty cycle directed advertising */ #define ESP_BLE_CONN_INT_MIN 0x0006 /*!< relate to BTM_BLE_CONN_INT_MIN in stack/btm_ble_api.h */ #define ESP_BLE_CONN_INT_MAX 0x0C80 /*!< relate to BTM_BLE_CONN_INT_MAX in stack/btm_ble_api.h */ #define ESP_BLE_CONN_LATENCY_MAX 499 /*!< relate to ESP_BLE_CONN_LATENCY_MAX in stack/btm_ble_api.h */ #define ESP_BLE_CONN_SUP_TOUT_MIN 0x000A /*!< relate to BTM_BLE_CONN_SUP_TOUT_MIN in stack/btm_ble_api.h */ #define ESP_BLE_CONN_SUP_TOUT_MAX 0x0C80 /*!< relate to ESP_BLE_CONN_SUP_TOUT_MAX in stack/btm_ble_api.h */ -#define ESP_BLE_CONN_PARAM_UNDEF 0xffff /* use this value when a specific value not to be overwritten */ /* relate to ESP_BLE_CONN_PARAM_UNDEF in stack/btm_ble_api.h */ -#define ESP_BLE_SCAN_PARAM_UNDEF 0xffffffff /* relate to ESP_BLE_SCAN_PARAM_UNDEF in stack/btm_ble_api.h */ /// Check the param is valid or not -#define ESP_BLE_IS_VALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max)) || ((x) == ESP_BLE_CONN_PARAM_UNDEF)) +#define ESP_BLE_IS_VALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max)) ) /// UUID type typedef struct { @@ -162,15 +163,18 @@ typedef enum { /// Bluetooth address length #define ESP_BD_ADDR_LEN 6 +/// Bluetooth peer irk +#define ESP_PEER_IRK_LEN 16 + /// Bluetooth device address typedef uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN]; /// BLE device address type typedef enum { - BLE_ADDR_TYPE_PUBLIC = 0x00, - BLE_ADDR_TYPE_RANDOM = 0x01, - BLE_ADDR_TYPE_RPA_PUBLIC = 0x02, - BLE_ADDR_TYPE_RPA_RANDOM = 0x03, + BLE_ADDR_TYPE_PUBLIC = 0x00, /*!< Public Device Address */ + BLE_ADDR_TYPE_RANDOM = 0x01, /*!< Random Device Address. To set this address, use the function esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr) */ + BLE_ADDR_TYPE_RPA_PUBLIC = 0x02, /*!< Resolvable Private Address (RPA) with public identity address */ + BLE_ADDR_TYPE_RPA_RANDOM = 0x03, /*!< Resolvable Private Address (RPA) with random identity address. To set this address, use the function esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr) */ } esp_ble_addr_type_t; /// white list address type diff --git a/components/bt/host/bluedroid/api/include/api/esp_bt_main.h b/components/bt/host/bluedroid/api/include/api/esp_bt_main.h index 74d9440aad..409ee01fd4 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_bt_main.h +++ b/components/bt/host/bluedroid/api/include/api/esp_bt_main.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,7 +40,10 @@ esp_bluedroid_status_t esp_bluedroid_get_status(void); esp_err_t esp_bluedroid_enable(void); /** - * @brief Disable bluetooth, must prior to esp_bluedroid_deinit(). + * @brief Disable Bluetooth, must be called prior to esp_bluedroid_deinit(). + * + * @note Before calling this API, ensure that all activities related to + * the application, such as connections, scans, etc., are properly closed. * * @return * - ESP_OK : Succeed 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 0fa1c4471a..3731bdb1a4 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -104,6 +104,7 @@ typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit #define ESP_BLE_APPEARANCE_CYCLING_CADENCE 0x0483 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_CADENCE in stack/btm_ble_api.h */ #define ESP_BLE_APPEARANCE_CYCLING_POWER 0x0484 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_POWER in stack/btm_ble_api.h */ #define ESP_BLE_APPEARANCE_CYCLING_SPEED_CADENCE 0x0485 /*!< relate to BTM_BLE_APPEARANCE_CYCLING_SPEED_CADENCE in stack/btm_ble_api.h */ +#define ESP_BLE_APPEARANCE_STANDALONE_SPEAKER 0x0841 /*!< relate to BTM_BLE_APPEARANCE_STANDALONE_SPEAKER in stack/btm_ble_api.h */ #define ESP_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 0x0C40 /*!< relate to BTM_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER in stack/btm_ble_api.h */ #define ESP_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 0x0C41 /*!< relate to BTM_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP in stack/btm_ble_api.h */ #define ESP_BLE_APPEARANCE_PULSE_OXIMETER_WRIST 0x0C42 /*!< relate to BTM_BLE_APPEARANCE_PULSE_OXIMETER_WRIST in stack/btm_ble_api.h */ @@ -125,6 +126,18 @@ typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit typedef uint8_t esp_ble_io_cap_t; /*!< combination of the io capability */ +#define BLE_DTM_PKT_PAYLOAD_0x00 0x00 /*!< PRBS9 sequence ‘11111111100000111101...’ (in transmission order) as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x01 0x01 /*!< Repeated ‘11110000’ (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x02 0x02 /*!< Repeated ‘10101010’ (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x03 0x03 /*!< PRBS15 sequence as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x04 0x04 /*!< Repeated ‘11111111’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_0x05 0x05 /*!< Repeated ‘00000000’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_0x06 0x06 /*!< Repeated ‘00001111’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_0x07 0x07 /*!< Repeated ‘01010101’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_MAX 0x08 /*!< 0x08 ~ 0xFF, Reserved for future use */ + +typedef uint8_t esp_ble_dtm_pkt_payload_t; + /// GAP BLE callback event type typedef enum { //BLE_42_FEATURE_SUPPORT @@ -133,7 +146,7 @@ typedef enum { ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT, /*!< When scan parameters set complete, the event comes */ ESP_GAP_BLE_SCAN_RESULT_EVT, /*!< When one scan result ready, the event comes each time */ ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw advertising data set complete, the event comes */ - ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw advertising data set complete, the event comes */ + ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw scan response data set complete, the event comes */ ESP_GAP_BLE_ADV_START_COMPLETE_EVT, /*!< When start advertising complete, the event comes */ ESP_GAP_BLE_SCAN_START_COMPLETE_EVT, /*!< When start scan complete, the event comes */ //BLE_INCLUDED @@ -144,7 +157,7 @@ typedef enum { ESP_GAP_BLE_PASSKEY_REQ_EVT, /*!< passkey request event */ ESP_GAP_BLE_OOB_REQ_EVT, /*!< OOB request event */ ESP_GAP_BLE_LOCAL_IR_EVT, /*!< BLE local IR (identity Root 128-bit random static value used to generate Long Term Key) event */ - ESP_GAP_BLE_LOCAL_ER_EVT, /*!< BLE local ER (Encryption Root vakue used to genrate identity resolving key) event */ + ESP_GAP_BLE_LOCAL_ER_EVT, /*!< BLE local ER (Encryption Root value used to generate identity resolving key) event */ ESP_GAP_BLE_NC_REQ_EVT, /*!< Numeric Comparison request event */ //BLE_42_FEATURE_SUPPORT ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT, /*!< When stop adv complete, the event comes */ @@ -202,6 +215,20 @@ typedef enum { ESP_GAP_BLE_SC_OOB_REQ_EVT, /*!< Secure Connection OOB request event */ ESP_GAP_BLE_SC_CR_LOC_OOB_EVT, /*!< Secure Connection create OOB data complete event */ ESP_GAP_BLE_GET_DEV_NAME_COMPLETE_EVT, /*!< When getting BT device name complete, the event comes */ + //BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER + ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT, /*!< when set periodic advertising receive enable complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT, /*!< when periodic advertising sync transfer complete, the event comes */ + ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT, /*!< when periodic advertising set info transfer complete, the event comes */ + ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT, /*!< when set periodic advertising sync transfer params complete, the event comes */ + 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_SET_RPA_TIMEOUT_COMPLETE_EVT, /*!< When set the Resolvable Private Address (RPA) timeout completes, the event comes */ + ESP_GAP_BLE_ADD_DEV_TO_RESOLVING_LIST_COMPLETE_EVT, /*!< when add a device to the resolving list completes, the event comes*/ + ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT, /*!< When vendor hci command complete, the event comes */ + ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT, /*!< When set privacy mode complete, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -216,6 +243,8 @@ typedef uint8_t esp_gap_ble_channels[ESP_GAP_BLE_CHANNELS_LEN]; /// Scan response data maximum length #define ESP_BLE_SCAN_RSP_DATA_LEN_MAX 31 +#define VENDOR_HCI_CMD_MASK (0x3F << 10) /**!< 0xFC00 */ + /* relate to BTM_BLE_AD_TYPE_xxx in stack/btm_ble_api.h */ /// The type of advertising data(not adv_type) typedef enum { @@ -333,7 +362,42 @@ typedef enum { ESP_BLE_SM_MAX_PARAM, } esp_ble_sm_param_t; +typedef enum { + /// DTM TX start event + DTM_TX_START_EVT = 0x00, + ///DTM RX start event + DTM_RX_START_EVT, + ///DTM test end event + DTM_TEST_STOP_EVT, +} esp_ble_dtm_update_evt_t; + +/** + * @brief Vendor HCI command parameters + */ +typedef struct { + uint16_t opcode; /*!< vendor hci command opcode */ + uint8_t param_len; /*!< the length of parameter */ + uint8_t *p_param_buf; /*!< the point of parameter buffer */ +} esp_ble_vendor_cmd_params_t; + #if (BLE_42_FEATURE_SUPPORT == TRUE) +/** +* @brief DTM TX parameters +*/ +typedef struct +{ + uint8_t tx_channel; /*!< channel for sending test data, tx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ + uint8_t len_of_data; /*!< length in bytes of payload data in each packet */ + esp_ble_dtm_pkt_payload_t pkt_payload; /*!< packet payload type. value range: 0x00-0x07 */ +} esp_ble_dtm_tx_t; +/** +* @brief DTM RX parameters +*/ +typedef struct +{ + uint8_t rx_channel; /*!< channel for test data reception, rx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ +} esp_ble_dtm_rx_t; + /// Advertising parameters typedef struct { uint16_t adv_int_min; /*!< Minimum advertising interval for @@ -411,7 +475,10 @@ typedef enum { typedef enum { BLE_SCAN_DUPLICATE_DISABLE = 0x0, /*!< the Link Layer should generate advertising reports to the host for each packet received */ BLE_SCAN_DUPLICATE_ENABLE = 0x1, /*!< the Link Layer should filter out duplicate advertising reports to the Host */ - BLE_SCAN_DUPLICATE_MAX = 0x2, /*!< 0x02 – 0xFF, Reserved for future use */ + #if (BLE_50_FEATURE_SUPPORT == TRUE) + BLE_SCAN_DUPLICATE_ENABLE_RESET, /*!< Duplicate filtering enabled, reset for each scan period, only supported in BLE 5.0. */ + #endif + BLE_SCAN_DUPLICATE_MAX /*!< Reserved for future use. */ } esp_ble_scan_duplicate_t; #if (BLE_42_FEATURE_SUPPORT == TRUE) /// Ble scan parameters @@ -564,6 +631,7 @@ typedef struct { esp_bd_addr_t bd_addr; /*!< peer address */ esp_ble_bond_key_info_t bond_key; /*!< the bond key information */ + esp_ble_addr_type_t bd_addr_type; /*!< peer address type */ } esp_ble_bond_dev_t; /*!< the ble bond device type */ @@ -594,21 +662,55 @@ typedef struct { esp_bt_octet16_t oob_r; /*!< the 128 bits of randomizer value */ } esp_ble_local_oob_data_t; +/** +* @brief Definition of the authentication failed reason +*/ +typedef enum { + // Failure reason defined in Bluetooth Core Spec 5.0 Vol3, Part H, 3.5.5 + ESP_AUTH_SMP_PASSKEY_FAIL = 78, /*!< The user input of passkey failed */ + ESP_AUTH_SMP_OOB_FAIL, /*!< The OOB data is not available */ + ESP_AUTH_SMP_PAIR_AUTH_FAIL, /*!< The authentication requirements cannot be met */ + ESP_AUTH_SMP_CONFIRM_VALUE_FAIL, /*!< The confirm value does not match the calculated comparison value */ + ESP_AUTH_SMP_PAIR_NOT_SUPPORT, /*!< Pairing is not supported by the device */ + ESP_AUTH_SMP_ENC_KEY_SIZE, /*!< The resultant encryption key size is not long enough */ + ESP_AUTH_SMP_INVALID_CMD, /*!< The SMP command received is not supported by this device */ + ESP_AUTH_SMP_UNKNOWN_ERR, /*!< Pairing failed due to an unspecified reason */ + ESP_AUTH_SMP_REPEATED_ATTEMPT, /*!< Pairing or authentication procedure is disallowed */ + ESP_AUTH_SMP_INVALID_PARAMETERS, /*!< The command length is invalid or that a parameter is outside the specified range */ + ESP_AUTH_SMP_DHKEY_CHK_FAIL, /*!< The DHKey Check value received doesn’t match the one calculated by the local device */ + ESP_AUTH_SMP_NUM_COMP_FAIL, /*!< The confirm values in the numeric comparison protocol do not match */ + ESP_AUTH_SMP_BR_PARING_IN_PROGR, /*!< Pairing Request sent over the BR/EDR transport is in progress */ + ESP_AUTH_SMP_XTRANS_DERIVE_NOT_ALLOW, /*!< The BR/EDR Link Key or BLE LTK cannot be used to derive */ + + // Failure reason defined in Bluedroid Host + ESP_AUTH_SMP_INTERNAL_ERR, /*!< Internal error in pairing procedure */ + ESP_AUTH_SMP_UNKNOWN_IO, /*!< Unknown IO capability, unable to decide association model */ + ESP_AUTH_SMP_INIT_FAIL, /*!< SMP pairing initiation failed */ + ESP_AUTH_SMP_CONFIRM_FAIL, /*!< The confirm value does not match */ + ESP_AUTH_SMP_BUSY, /*!< Pending security request on going */ + ESP_AUTH_SMP_ENC_FAIL, /*!< The Controller failed to start encryption */ + ESP_AUTH_SMP_STARTED, /*!< SMP pairing process started */ + ESP_AUTH_SMP_RSP_TIMEOUT, /*!< Security Manager timeout due to no SMP command being received */ + ESP_AUTH_SMP_DIV_NOT_AVAIL, /*!< Encrypted Diversifier value not available */ + ESP_AUTH_SMP_UNSPEC_ERR, /*!< Unspecified failed reason */ + ESP_AUTH_SMP_CONN_TOUT, /*!< Pairing process failed due to connection timeout */ +} esp_ble_auth_fail_rsn_t; + /** * @brief Structure associated with ESP_AUTH_CMPL_EVT */ typedef struct { - esp_bd_addr_t bd_addr; /*!< BD address peer device. */ - bool key_present; /*!< Valid link key value in key element */ - esp_link_key key; /*!< Link key associated with peer device. */ - uint8_t key_type; /*!< The type of Link Key */ - bool success; /*!< TRUE of authentication succeeded, FALSE if failed. */ - uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */ - esp_ble_addr_type_t addr_type; /*!< Peer device address type */ - esp_bt_dev_type_t dev_type; /*!< Device type */ - esp_ble_auth_req_t auth_mode; /*!< authentication mode */ -} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */ + esp_bd_addr_t bd_addr; /*!< BD address of peer device */ + bool key_present; /*!< True if the link key value is valid; false otherwise */ + esp_link_key key; /*!< Link key associated with peer device */ + uint8_t key_type; /*!< The type of link key */ + bool success; /*!< True if authentication succeeded; false otherwise */ + esp_ble_auth_fail_rsn_t fail_reason; /*!< The HCI reason/error code for failure when success is false */ + esp_ble_addr_type_t addr_type; /*!< Peer device address type */ + esp_bt_dev_type_t dev_type; /*!< Device type */ + esp_ble_auth_req_t auth_mode; /*!< Authentication mode */ +} esp_ble_auth_cmpl_t; /*!< The ble authentication complete cb type */ /** * @brief union associated with ble security @@ -668,6 +770,8 @@ typedef enum { ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_BEACON_TYPE, /*!< BLE mesh beacon AD type, the format is | Len | 0x2B | Beacon Type | Beacon Data | */ ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROV_SRV_ADV, /*!< BLE mesh provisioning service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1827 | .... |` */ ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROXY_SRV_ADV, /*!< BLE mesh adv with proxy service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1828 | .... |` */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROXY_SOLIC_ADV, /*!< BLE mesh adv with proxy service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1859 | .... |` */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_URI_ADV, /*!< BLE mesh URI adv, the format is ...| Len | 0x24 | data |... */ } esp_ble_duplicate_exceptional_info_type_t; typedef enum { @@ -675,7 +779,9 @@ typedef enum { ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST = BLE_BIT(1), /*!< duplicate scan exceptional mesh link ID list */ ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_BEACON_TYPE_LIST = BLE_BIT(2), /*!< duplicate scan exceptional mesh beacon type list */ ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_PROV_SRV_ADV_LIST = BLE_BIT(3), /*!< duplicate scan exceptional mesh adv with provisioning service uuid */ - ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_PROXY_SRV_ADV_LIST = BLE_BIT(4), /*!< duplicate scan exceptional mesh adv with provisioning service uuid */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_PROXY_SRV_ADV_LIST = BLE_BIT(4), /*!< duplicate scan exceptional mesh adv with proxy service uuid */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_PROXY_SOLIC_ADV_LIST = BLE_BIT(5), /*!< duplicate scan exceptional mesh adv with proxy solicitation PDU uuid */ + ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_URI_ADV_LIST = BLE_BIT(6), /*!< duplicate scan exceptional URI list */ ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ALL_LIST = 0xFFFF, /*!< duplicate scan exceptional all list */ } esp_duplicate_scan_exceptional_list_type_t; @@ -731,9 +837,9 @@ typedef uint8_t esp_ble_gap_all_phys_t; #define ESP_BLE_GAP_PRI_PHY_CODED ESP_BLE_GAP_PHY_CODED /*!< Primary Phy is LE CODED */ typedef uint8_t esp_ble_gap_pri_phy_t; // primary phy -#define ESP_BLE_GAP_PHY_1M_PREF_MASK (1 << 0) /*!< The Host prefers use the LE1M transmitter or reciever PHY */ -#define ESP_BLE_GAP_PHY_2M_PREF_MASK (1 << 1) /*!< The Host prefers use the LE2M transmitter or reciever PHY */ -#define ESP_BLE_GAP_PHY_CODED_PREF_MASK (1 << 2) /*!< The Host prefers use the LE CODED transmitter or reciever PHY */ +#define ESP_BLE_GAP_PHY_1M_PREF_MASK (1 << 0) /*!< The Host prefers use the LE1M transmitter or receiver PHY */ +#define ESP_BLE_GAP_PHY_2M_PREF_MASK (1 << 1) /*!< The Host prefers use the LE2M transmitter or receiver PHY */ +#define ESP_BLE_GAP_PHY_CODED_PREF_MASK (1 << 2) /*!< The Host prefers use the LE CODED transmitter or receiver PHY */ typedef uint8_t esp_ble_gap_phy_mask_t; #define ESP_BLE_GAP_PHY_OPTIONS_NO_PREF 0 /*!< The Host has no preferred coding when transmitting on the LE Coded PHY */ @@ -775,6 +881,10 @@ typedef uint8_t esp_ble_gap_adv_type_t; /// Extend advertising tx power, range: [-127, +126] dBm #define EXT_ADV_TX_PWR_NO_PREFERENCE (127) /*!< host has no preference for tx power */ + +/// max number of advertising sets to enable or disable +#define EXT_ADV_NUM_SETS_MAX (10) /*!< max evt instance num */ + /** * @brief ext adv parameters */ @@ -852,12 +962,22 @@ typedef struct { * @brief periodic adv sync parameters */ typedef struct { - esp_ble_gap_sync_t filter_policy; /*!< periodic advertising sync filter policy */ - uint8_t sid; /*!< periodic advertising sid */ - esp_ble_addr_type_t addr_type; /*!< periodic advertising address type */ - esp_bd_addr_t addr; /*!< periodic advertising address */ - uint16_t skip; /*!< the maximum number of periodic advertising events that can be skipped */ - uint16_t sync_timeout; /*!< synchronization timeout */ + esp_ble_gap_sync_t filter_policy; /*!< Configures the filter policy for periodic advertising sync: + 0: Use Advertising SID, Advertiser Address Type, and Advertiser Address parameters to determine the advertiser to listen to. + 1: Use the Periodic Advertiser List to determine the advertiser to listen to. */ + #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH) + esp_ble_gap_sync_t reports_disabled; /*!< Supported only by esp32c2, esp32c6, and esp32h2; can be set by menuconfig: + 0: Reporting initially enabled. + 1: Reporting initially disabled. */ + esp_ble_gap_sync_t filter_duplicates; /*!< Supported only by esp32c2, esp32c6, and esp32h2; can be set by menuconfig: + 0: Duplicate filtering initially disabled. + 1: Duplicate filtering initially enabled. */ + #endif + uint8_t sid; /*!< SID of the periodic advertising */ + esp_ble_addr_type_t addr_type; /*!< Address type of the periodic advertising */ + esp_bd_addr_t addr; /*!< Address of the periodic advertising */ + uint16_t skip; /*!< Maximum number of periodic advertising events that can be skipped */ + uint16_t sync_timeout; /*!< Synchronization timeout */ } esp_ble_gap_periodic_adv_sync_params_t; /** @@ -880,7 +1000,7 @@ typedef struct { esp_ble_gap_ext_adv_data_status_t data_status; /*!< data type */ uint8_t adv_data_len; /*!< extend advertising data length */ uint8_t adv_data[251]; /*!< extend advertising data */ -} esp_ble_gap_ext_adv_reprot_t; +} esp_ble_gap_ext_adv_report_t; /** * @brief periodic adv report parameters @@ -908,8 +1028,53 @@ typedef struct { uint8_t adv_clk_accuracy; /*!< periodic advertising clock accuracy */ } esp_ble_gap_periodic_adv_sync_estab_t; +/** +* @brief DTM TX parameters +*/ +typedef struct +{ + uint8_t tx_channel; /*!< channel for sending test data, tx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ + uint8_t len_of_data; /*!< length in bytes of payload data in each packet */ + esp_ble_dtm_pkt_payload_t pkt_payload; /*!< packet payload type. value range: 0x00-0x07 */ + esp_ble_gap_phy_t phy; /*!< the phy type used by the transmitter, coded phy with S=2:0x04 */ +} esp_ble_dtm_enh_tx_t; + +/** +* @brief DTM RX parameters +*/ +typedef struct +{ + uint8_t rx_channel; /*!< channel for test data reception, rx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ + esp_ble_gap_phy_t phy; /*!< the phy type used by the receiver, 1M phy: 0x01, 2M phy:0x02, coded phy:0x03 */ + uint8_t modulation_idx; /*!< modulation index, 0x00:standard modulation index, 0x01:stable modulation index */ +} esp_ble_dtm_enh_rx_t; + #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +/// Periodic advertising sync trans mode +#define ESP_BLE_GAP_PAST_MODE_NO_SYNC_EVT (0x00) /*!< No attempt is made to sync and no periodic adv sync transfer received event */ +#define ESP_BLE_GAP_PAST_MODE_NO_REPORT_EVT (0x01) /*!< An periodic adv sync transfer received event and no periodic adv report events */ +#define ESP_BLE_GAP_PAST_MODE_DUP_FILTER_DISABLED (0x02) /*!< Periodic adv report events will be enabled with duplicate filtering disabled */ +#define ESP_BLE_GAP_PAST_MODE_DUP_FILTER_ENABLED (0x03) /*!< Periodic adv report events will be enabled with duplicate filtering enabled */ +typedef uint8_t esp_ble_gap_past_mode_t; + +/** +* @brief periodic adv sync transfer parameters +*/ +typedef struct { + esp_ble_gap_past_mode_t mode; /*!< periodic advertising sync transfer mode */ + uint16_t skip; /*!< the number of periodic advertising packets that can be skipped */ + uint16_t sync_timeout; /*!< synchronization timeout for the periodic advertising train */ + uint8_t cte_type; /*!< periodic advertising sync transfer CET type */ +} esp_ble_gap_past_params_t; +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + +typedef enum{ + ESP_BLE_NETWORK_PRIVACY_MODE = 0X00, /*!< Network Privacy Mode for peer device (default) */ + ESP_BLE_DEVICE_PRIVACY_MODE = 0X01, /*!< Device Privacy Mode for peer device */ +} esp_ble_privacy_mode_t; + /** * @brief Gap callback parameters union */ @@ -996,6 +1161,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 @@ -1009,13 +1180,13 @@ typedef union { struct ble_update_conn_params_evt_param { esp_bt_status_t status; /*!< Indicate update connection parameters success status */ esp_bd_addr_t bda; /*!< Bluetooth device address */ - uint16_t min_int; /*!< Min connection interval */ - uint16_t max_int; /*!< Max connection interval */ + uint16_t min_int; /*!< Minimum connection interval. If the master initiates the connection parameter update, this value is not applicable for the slave and will be set to zero. */ + uint16_t max_int; /*!< Maximum connection interval. If the master initiates the connection parameter update, this value is not applicable for the slave and will be set to zero. */ uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */ - uint16_t conn_int; /*!< Current connection interval */ + uint16_t conn_int; /*!< Current connection interval in milliseconds, calculated as N × 1.25 ms */ uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80. - Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec */ - } update_conn_params; /*!< Event parameter of ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT */ + This value is calculated as N × 10 ms */ + } update_conn_params; /*!< Event parameter for ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT */ /** * @brief ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT */ @@ -1029,6 +1200,19 @@ typedef union { struct ble_local_privacy_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate the set local privacy operation success status */ } local_privacy_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_RPA_TIMEOUT_COMPLETE_EVT + */ + struct ble_rpa_timeout_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate the set RPA timeout operation success status */ + } set_rpa_timeout_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_RPA_TIMEOUT_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_ADD_DEV_TO_RESOLVING_LIST_COMPLETE_EVT + */ + struct ble_add_dev_to_resolving_list_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicates the success status of adding a device to the resolving list */ + } add_dev_to_resolving_list_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADD_DEV_TO_RESOLVING_LIST_COMPLETE_EVT */ + /** * @brief ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT */ @@ -1111,72 +1295,86 @@ typedef union { */ struct ble_ext_adv_set_rand_addr_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate extend advertising random address set status */ + uint8_t instance; /*!< extend advertising handle */ } ext_adv_set_rand_addr; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT */ struct ble_ext_adv_set_params_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate extend advertising parameters set status */ + uint8_t instance; /*!< extend advertising handle */ } ext_adv_set_params; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT */ struct ble_ext_adv_data_set_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate extend advertising data set status */ + uint8_t instance; /*!< extend advertising handle */ } ext_adv_data_set; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT */ struct ble_ext_adv_scan_rsp_set_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate extend advertising scan response data set status */ + uint8_t instance; /*!< extend advertising handle */ } scan_rsp_set; /*!< Event parameter of ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT */ struct ble_ext_adv_start_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate advertising start operation success status */ + uint8_t instance_num; /*!< extend advertising handle numble*/ + uint8_t instance[EXT_ADV_NUM_SETS_MAX]; /*!< extend advertising handle list*/ } ext_adv_start; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT */ struct ble_ext_adv_stop_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate advertising stop operation success status */ + uint8_t instance_num; /*!< extend advertising handle numble*/ + uint8_t instance[EXT_ADV_NUM_SETS_MAX]; /*!< extend advertising handle list*/ } ext_adv_stop; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT */ struct ble_ext_adv_set_remove_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate advertising stop operation success status */ + uint8_t instance; /*!< extend advertising handle */ } ext_adv_remove; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT */ struct ble_ext_adv_set_clear_cmpl_evt_param { esp_bt_status_t status; /*!< Indicate advertising stop operation success status */ + uint8_t instance; /*!< extend advertising handle */ } ext_adv_clear; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT */ struct ble_periodic_adv_set_params_cmpl_param { esp_bt_status_t status; /*!< Indicate periodic advertisingparameters set status */ + uint8_t instance; /*!< extend advertising handle */ } peroid_adv_set_params; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT */ struct ble_periodic_adv_data_set_cmpl_param { esp_bt_status_t status; /*!< Indicate periodic advertising data set status */ + uint8_t instance; /*!< extend advertising handle */ } period_adv_data_set; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT */ struct ble_periodic_adv_start_cmpl_param { esp_bt_status_t status; /*!< Indicate periodic advertising start status */ + uint8_t instance; /*!< extend advertising handle */ } period_adv_start; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT */ struct ble_periodic_adv_stop_cmpl_param { esp_bt_status_t status; /*!< Indicate periodic advertising stop status */ + uint8_t instance; /*!< extend advertising handle */ } period_adv_stop; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT @@ -1299,7 +1497,7 @@ typedef union { * @brief ESP_GAP_BLE_EXT_ADV_REPORT_EVT */ struct ble_ext_adv_report_param { - esp_ble_gap_ext_adv_reprot_t params; /*!< extend advertising report parameters */ + esp_ble_gap_ext_adv_report_t params; /*!< extend advertising report parameters */ } ext_adv_report; /*!< Event parameter of ESP_GAP_BLE_EXT_ADV_REPORT_EVT */ /** * @brief ESP_GAP_BLE_PERIODIC_ADV_REPORT_EVT @@ -1308,6 +1506,72 @@ typedef union { esp_ble_gap_periodic_adv_report_t params; /*!< periodic advertising report parameters */ } period_adv_report; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_REPORT_EVT */ #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT + */ + struct ble_periodic_adv_recv_enable_cmpl_param { + esp_bt_status_t status; /*!< Set periodic advertising receive enable status */ + } period_adv_recv_enable; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT + */ + struct ble_periodic_adv_sync_trans_cmpl_param { + esp_bt_status_t status; /*!< Periodic advertising sync transfer status */ + esp_bd_addr_t bda; /*!< The remote device address */ + } period_adv_sync_trans; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT + */ + struct ble_periodic_adv_set_info_trans_cmpl_param { + esp_bt_status_t status; /*!< Periodic advertising set info transfer status */ + esp_bd_addr_t bda; /*!< The remote device address */ + } period_adv_set_info_trans; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT + */ + struct ble_set_past_params_cmpl_param { + esp_bt_status_t status; /*!< Set periodic advertising sync transfer params status */ + esp_bd_addr_t bda; /*!< The remote device address */ + } set_past_params; /*!< Event parameter of ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT + */ + struct ble_periodic_adv_sync_trans_recv_param { + esp_bt_status_t status; /*!< Periodic advertising sync transfer received status */ + esp_bd_addr_t bda; /*!< The remote device address */ + uint16_t service_data; /*!< The value provided by the peer device */ + uint16_t sync_handle; /*!< Periodic advertising sync handle */ + uint8_t adv_sid; /*!< Periodic advertising set id */ + uint8_t adv_addr_type; /*!< Periodic advertiser address type */ + esp_bd_addr_t adv_addr; /*!< Periodic advertiser address */ + esp_ble_gap_phy_t adv_phy; /*!< Periodic advertising PHY */ + uint16_t adv_interval; /*!< Periodic advertising interval */ + uint8_t adv_clk_accuracy; /*!< Periodic advertising clock accuracy */ + } past_received; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT */ +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /** + * @brief ESP_GAP_BLE_DTM_TEST_UPDATE_EVT + */ + struct ble_dtm_state_update_evt_param { + esp_bt_status_t status; /*!< Indicate DTM operation success status */ + esp_ble_dtm_update_evt_t update_evt; /*!< DTM state change event, 0x00: DTM TX start, 0x01: DTM RX start, 0x02:DTM end */ + uint16_t num_of_pkt; /*!< number of packets received, only valid if update_evt is DTM_TEST_STOP_EVT and shall be reported as 0 for a transmitter */ + } dtm_state_update; /*!< Event parameter of ESP_GAP_BLE_DTM_TEST_UPDATE_EVT */ + /** + * @brief ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT + */ + struct vendor_cmd_cmpl_evt_param { + uint16_t opcode; /*!< vendor hci command opcode */ + uint16_t param_len; /*!< The length of parameter buffer */ + uint8_t *p_param_buf; /*!< The point of parameter buffer */ + } vendor_cmd_cmpl; /*!< Event parameter of ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT + */ + struct ble_set_privacy_mode_cmpl_evt_param { + esp_bt_status_t status; /*!< Indicate privacy mode set operation success status */ + } set_privacy_mode_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_PRIVACY_MODE_COMPLETE_EVT */ } esp_ble_gap_cb_param_t; /** @@ -1329,6 +1593,15 @@ typedef void (* esp_gap_ble_cb_t)(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_p */ esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback); +/** + * @brief This function is called to get the current gap callback + * + * @return + * - esp_gap_ble_cb_t : callback function + * + */ +esp_gap_ble_cb_t esp_ble_gap_get_callback(void); + #if (BLE_42_FEATURE_SUPPORT == TRUE) /** * @brief This function is called to override the BTA default ADV parameters. @@ -1432,9 +1705,17 @@ esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params); esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_data_length); /** - * @brief This function sets the static Random Address and Non-Resolvable Private Address for the application + * @brief This function allows configuring either a Non-Resolvable Private Address or a Static Random Address + * + * @param[in] rand_addr: The address to be configured. Refer to the table below for possible address subtypes: * - * @param[in] rand_addr: the random address which should be setting + * | address [47:46] | Address Type | + * |-----------------|--------------------------| + * | 0b00 | Non-Resolvable Private | + * | | Address | + * |-----------------|--------------------------| + * | 0b11 | Static Random Address | + * |-----------------|--------------------------| * * @return * - ESP_OK : success @@ -1443,6 +1724,44 @@ esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_ */ esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr); +/** + * @brief This function sets the length of time the Controller uses a Resolvable Private Address + * before generating and starting to use a new resolvable private address. + * + * @note Note: This function is currently not supported on the ESP32 but will be enabled in a future update. + * + * @param[in] rpa_timeout: The timeout duration in seconds for how long a Resolvable Private Address + * is used before a new one is generated. The value must be within the range specified by + * the Bluetooth specification (0x0001 to 0x0E10), which corresponds to a time range of + * 1 second to 1 hour. The default value is 0x0384 (900 seconds or 15 minutes). + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_set_resolvable_private_address_timeout(uint16_t rpa_timeout); + + +/** + * @brief This function adds a device to the resolving list used to generate and resolve Resolvable Private Addresses + * in the Controller. + * + * @note Note: This function shall not be used when address resolution is enabled in the Controller and: + * - Advertising (other than periodic advertising) is enabled, + * - Scanning is enabled, or + * - an HCI_LE_Create_Connection, HCI_LE_Extended_Create_Connection, or HCI_LE_Periodic_Advertising_Create_Sync command is pending. + * This command may be used at any time when address resolution is disabled in the Controller. + * The added device shall be set to Network Privacy mode. + * + * @param[in] peer_addr: The peer identity address of the device to be added to the resolving list. + * @param[in] addr_type: The address type of the peer identity address (BLE_ADDR_TYPE_PUBLIC or BLE_ADDR_TYPE_RANDOM). + * @param[in] peer_irk: The Identity Resolving Key (IRK) of the device. + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gap_add_device_to_resolving_list(esp_bd_addr_t peer_addr, uint8_t addr_type, uint8_t *peer_irk); /** * @brief This function clears the random address for the application * @@ -1454,9 +1773,8 @@ esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr); esp_err_t esp_ble_gap_clear_rand_addr(void); - /** - * @brief Enable/disable privacy on the local device + * @brief Enable/disable privacy (including address resolution) on the local device * * @param[in] privacy_enable - enable/disable privacy on remote device. * @@ -1537,6 +1855,7 @@ esp_err_t esp_ble_gap_set_prefer_conn_params(esp_bd_addr_t bd_addr, #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) /** * @brief Set device name to the local device + * Note: This API don't affect the advertising data * * @param[in] name - device name. * @@ -1585,7 +1904,7 @@ uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *leng * @brief This function is called to set raw advertising data. User need to fill * ADV data by self. * - * @param[in] raw_data : raw advertising data + * @param[in] raw_data : raw advertising data with the format: [Length 1][Data Type 1][Data 1][Length 2][Data Type 2][Data 2] ... * @param[in] raw_data_len : raw advertising data length , less than 31 bytes * * @return @@ -2038,6 +2357,22 @@ esp_err_t esp_ble_gap_ext_adv_set_clear(void); */ esp_err_t esp_ble_gap_periodic_adv_set_params(uint8_t instance, const esp_ble_gap_periodic_adv_params_t *params); +#if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) +/** +* @brief This function is used to set the data used in periodic advertising PDUs. +* +* @param[in] instance : identifies the advertising set whose periodic advertising parameters are being configured. +* @param[in] length : the length of periodic data +* @param[in] data : periodic data information +* @param[in] only_update_did : If true, only the Advertising DID of the periodic advertising will be updated, and the length and data parameters will be ignored. +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_config_periodic_adv_data_raw(uint8_t instance, uint16_t length, + const uint8_t *data, bool only_update_did); +#else /** * @brief This function is used to set the data used in periodic advertising PDUs. * @@ -2051,6 +2386,21 @@ esp_err_t esp_ble_gap_periodic_adv_set_params(uint8_t instance, const esp_ble_ga */ esp_err_t esp_ble_gap_config_periodic_adv_data_raw(uint8_t instance, uint16_t length, const uint8_t *data); +#endif + +#if (CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH) +/** +* @brief This function is used to request the Controller to enable the periodic advertising for the advertising set specified +* +* @param[in] instance : Used to identify an advertising set +* @param[in] include_adi : If true, the ADI (Advertising Data Info) field will be included in AUX_SYNC_IND PDUs +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_start(uint8_t instance,bool include_adi); +#else /** * @brief This function is used to request the Controller to enable the periodic advertising for the advertising set specified * @@ -2061,6 +2411,7 @@ esp_err_t esp_ble_gap_config_periodic_adv_data_raw(uint8_t instance, uint16_t le * */ esp_err_t esp_ble_gap_periodic_adv_start(uint8_t instance); +#endif /** * @brief This function is used to request the Controller to disable the periodic advertising for the advertising set specified @@ -2087,8 +2438,9 @@ esp_err_t esp_ble_gap_set_ext_scan_params(const esp_ble_ext_scan_params_t *param /** * @brief This function is used to enable scanning. * -* @param[in] duration : Scan duration -* @param[in] period : Time interval from when the Controller started its last Scan Duration until it begins the subsequent Scan Duration. +* @param[in] duration Scan duration time, where Time = N * 10 ms. Range: 0x0001 to 0xFFFF. +* @param[in] period Time interval from when the Controller started its last Scan Duration until it begins the subsequent Scan Duration. +* Time = N * 1.28 sec. Range: 0x0001 to 0xFFFF. * * @return - ESP_OK : success * - other : failed @@ -2197,6 +2549,163 @@ esp_err_t esp_ble_gap_prefer_ext_connect_params_set(esp_bd_addr_t addr, #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +/** +* @brief This function is used to set periodic advertising receive enable +* +* @param[in] sync_handle : Handle of periodic advertising sync +* @param[in] enable : Determines whether reporting and duplicate filtering are enabled or disabled +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_recv_enable(uint16_t sync_handle, uint8_t enable); + +/** +* @brief This function is used to transfer periodic advertising sync +* +* @param[in] addr : Peer device address +* @param[in] service_data : Service data used by Host +* @param[in] sync_handle : Handle of periodic advertising sync +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_sync_trans(esp_bd_addr_t addr, + uint16_t service_data, uint16_t sync_handle); + +/** +* @brief This function is used to transfer periodic advertising set info +* +* @param[in] addr : Peer device address +* @param[in] service_data : Service data used by Host +* @param[in] adv_handle : Handle of advertising set +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_periodic_adv_set_info_trans(esp_bd_addr_t addr, + uint16_t service_data, uint8_t adv_handle); + +/** +* @brief This function is used to set periodic advertising sync transfer params +* +* @param[in] addr : Peer device address +* @param[in] params : Params of periodic advertising sync transfer +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_set_periodic_adv_sync_trans_params(esp_bd_addr_t addr, + const esp_ble_gap_past_params_t *params); +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + +#if (BLE_42_FEATURE_SUPPORT == TRUE) + +/** +* @brief This function is used to start a test where the DUT generates reference packets +* at a fixed interval. +* +* @param[in] tx_params : DTM Transmitter parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_tx_start(const esp_ble_dtm_tx_t *tx_params); + +/** +* @brief This function is used to start a test where the DUT receives test reference packets +* at a fixed interval. +* +* @param[in] rx_params : DTM Receiver parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_rx_start(const esp_ble_dtm_rx_t *rx_params); +#endif //#if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) + +/** +* @brief This function is used to start a test where the DUT generates reference packets +* at a fixed interval. +* +* @param[in] tx_params : DTM Transmitter parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_enh_tx_start(const esp_ble_dtm_enh_tx_t *tx_params); + +/** +* @brief This function is used to start a test where the DUT receives test reference packets +* at a fixed interval. +* +* @param[in] rx_params : DTM Receiver parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params); +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +/** +* @brief This function is used to stop any test which is in progress +* +* +* @return - ESP_OK : success +* - other : failed +* +*/ +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); + +/** + * @brief This function is called to send vendor hci command. + * + * + * + * @param[in] vendor_cmd_param: vendor hci command parameters + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_vendor_command_send(esp_ble_vendor_cmd_params_t *vendor_cmd_param); + +/** + * @brief This function set the privacy mode of the device in resolving list. + * + * @note This feature is not supported on ESP32. + * + * @param[in] addr_type: The address type of the peer identity address (BLE_ADDR_TYPE_PUBLIC or BLE_ADDR_TYPE_RANDOM). + * @param[in] addr: The peer identity address of the device. + * @param[in] mode: The privacy mode of the device. + * + * @return + * - ESP_OK : success + * - other : failed + */ +esp_err_t esp_ble_gap_set_privacy_mode(esp_ble_addr_type_t addr_type, esp_bd_addr_t addr, esp_ble_privacy_mode_t mode); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h index 78d31125ce..dd5c6bf456 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h @@ -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 */ @@ -91,7 +91,35 @@ typedef struct { typedef uint8_t esp_bt_eir_type_t; - +/* ACL Packet Types */ +#define ESP_BT_ACL_PKT_TYPES_MASK_DM1 0x0008 +#define ESP_BT_ACL_PKT_TYPES_MASK_DH1 0x0010 +#define ESP_BT_ACL_PKT_TYPES_MASK_DM3 0x0400 +#define ESP_BT_ACL_PKT_TYPES_MASK_DH3 0x0800 +#define ESP_BT_ACL_PKT_TYPES_MASK_DM5 0x4000 +#define ESP_BT_ACL_PKT_TYPES_MASK_DH5 0x8000 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH1 0x0002 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH1 0x0004 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH3 0x0100 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH3 0x0200 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH5 0x1000 +#define ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH5 0x2000 + +// DM1 cann not be disabled. All options are mandatory to include DM1. +#define ESP_BT_ACL_DM1_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM1 | 0x330e) /* 0x330e */ +#define ESP_BT_ACL_DH1_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH1 | 0x330e) /* 0x331e */ +#define ESP_BT_ACL_DM3_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM3 | 0x330e) /* 0x370e */ +#define ESP_BT_ACL_DH3_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH3 | 0x330e) /* 0x3b0e */ +#define ESP_BT_ACL_DM5_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DM5 | 0x330e) /* 0x730e */ +#define ESP_BT_ACL_DH5_ONLY (ESP_BT_ACL_PKT_TYPES_MASK_DH5 | 0x330e) /* 0xb30e */ +#define ESP_BT_ACL_2_DH1_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH1 & 0x330e) /* 0x330c */ +#define ESP_BT_ACL_3_DH1_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH1 & 0x330e) /* 0x330a */ +#define ESP_BT_ACL_2_DH3_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH3 & 0x330e) /* 0x320e */ +#define ESP_BT_ACL_3_DH3_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH3 & 0x330e) /* 0x310e */ +#define ESP_BT_ACL_2_DH5_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_2_DH5 & 0x330e) /* 0x230e */ +#define ESP_BT_ACL_3_DH5_ONLY (~ESP_BT_ACL_PKT_TYPES_MASK_NO_3_DH5 & 0x330e) /* 0x130e */ + +typedef uint16_t esp_bt_acl_pkt_type_t; /* ESP_BT_EIR_FLAG bit definition */ #define ESP_BT_EIR_FLAG_LIMIT_DISC (0x01 << 0) @@ -106,6 +134,7 @@ typedef struct { bool fec_required; /*!< FEC is required or not, true by default */ bool include_txpower; /*!< EIR data include TX power, false by default */ bool include_uuid; /*!< EIR data include UUID, false by default */ + bool include_name; /*!< EIR data include device name, true by default */ uint8_t flag; /*!< EIR flags, see ESP_BT_EIR_FLAG for details, EIR will not include flag if it is 0, 0 by default */ uint16_t manufacturer_len; /*!< Manufacturer data length, 0 by default */ uint8_t *p_manufacturer_data; /*!< Manufacturer data point */ @@ -217,6 +246,7 @@ typedef enum { ESP_BT_GAP_QOS_CMPL_EVT, /*!< QOS complete event */ ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT, /*!< ACL connection complete status event */ ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT, /*!< ACL disconnection complete status event */ + ESP_BT_GAP_ACL_PKT_TYPE_CHANGED_EVT, /*!< Set ACL packet types event */ ESP_BT_GAP_EVT_MAX, } esp_bt_gap_cb_event_t; @@ -230,6 +260,11 @@ typedef enum { #define ESP_BT_GAP_MIN_INQ_LEN (0x01) /*!< Minimum inquiry duration, unit is 1.28s */ #define ESP_BT_GAP_MAX_INQ_LEN (0x30) /*!< Maximum inquiry duration, unit is 1.28s */ +/** Minimum, Default and Maximum poll interval **/ +#define ESP_BT_GAP_TPOLL_MIN (0x0006) /*!< Minimum poll interval, unit is 625 microseconds */ +#define ESP_BT_GAP_TPOLL_DFT (0x0028) /*!< Default poll interval, unit is 625 microseconds */ +#define ESP_BT_GAP_TPOLL_MAX (0x1000) /*!< Maximum poll interval, unit is 625 microseconds */ + /// GAP state callback parameters typedef union { /** @@ -371,6 +406,15 @@ typedef union { logical transport. unit is 0.625ms. */ } qos_cmpl; /*!< QoS complete parameter struct */ + /** + * @brief ESP_BT_GAP_ACL_PKT_TYPE_CHANGED_EVT + */ + struct set_acl_pkt_types_param { + esp_bt_status_t status; /*!< set ACL packet types status */ + esp_bd_addr_t bda; /*!< remote bluetooth device address */ + uint16_t pkt_types; /*!< packet types successfully set */ + } set_acl_pkt_types; /*!< set ACL packet types parameter struct */ + /** * @brief ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT */ @@ -785,6 +829,17 @@ esp_err_t esp_bt_gap_read_remote_name(esp_bd_addr_t remote_bda); */ esp_err_t esp_bt_gap_set_qos(esp_bd_addr_t remote_bda, uint32_t t_poll); +/** + * @brief Set ACL packet types. FOR INTERNAL TESTING ONLY. + * An ESP_BT_GAP_SET_ACL_PPKT_TYPES_EVT event will reported to + * the APP layer. + * + * @return - ESP_OK: success + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - other: failed + */ +esp_err_t esp_bt_gap_set_acl_pkt_types(esp_bd_addr_t remote_bda, esp_bt_acl_pkt_type_t pkt_types); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h b/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h index f2d658a208..77f03e8bf3 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gatt_defs.h @@ -1,337 +1,552 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __ESP_GATT_DEFS_H__ -#define __ESP_GATT_DEFS_H__ - +#pragma once #include "esp_bt_defs.h" #ifdef __cplusplus extern "C" { #endif -/// GATT INVALID UUID +/** @brief GATT INVALID UUID. */ #define ESP_GATT_ILLEGAL_UUID 0 -/// GATT INVALID HANDLE + +/** @brief GATT INVALID HANDLE. */ #define ESP_GATT_ILLEGAL_HANDLE 0 -/// GATT attribute max handle + +/** @brief GATT attribute max handle. */ #define ESP_GATT_ATTR_HANDLE_MAX UC_CONFIG_BT_GATT_MAX_SR_ATTRIBUTES -#define ESP_GATT_MAX_READ_MULTI_HANDLES 10 /* Max attributes to read in one request */ + +/** @brief Maximum number of attributes to read in one request. */ +#define ESP_GATT_MAX_READ_MULTI_HANDLES 10 -/**@{ - * All "ESP_GATT_UUID_xxx" is attribute types +/** + * @defgroup GATT_UUIDs GATT Service UUIDs + * @brief Definitions of GATT Service UUIDs. + * + * This module contains the definitions of standard GATT service UUIDs. These UUIDs + * identify the type of GATT service. + * @{ */ -#define ESP_GATT_UUID_IMMEDIATE_ALERT_SVC 0x1802 /* Immediate alert Service*/ -#define ESP_GATT_UUID_LINK_LOSS_SVC 0x1803 /* Link Loss Service*/ -#define ESP_GATT_UUID_TX_POWER_SVC 0x1804 /* TX Power Service*/ -#define ESP_GATT_UUID_CURRENT_TIME_SVC 0x1805 /* Current Time Service Service*/ -#define ESP_GATT_UUID_REF_TIME_UPDATE_SVC 0x1806 /* Reference Time Update Service*/ -#define ESP_GATT_UUID_NEXT_DST_CHANGE_SVC 0x1807 /* Next DST Change Service*/ -#define ESP_GATT_UUID_GLUCOSE_SVC 0x1808 /* Glucose Service*/ -#define ESP_GATT_UUID_HEALTH_THERMOM_SVC 0x1809 /* Health Thermometer Service*/ -#define ESP_GATT_UUID_DEVICE_INFO_SVC 0x180A /* Device Information Service*/ -#define ESP_GATT_UUID_HEART_RATE_SVC 0x180D /* Heart Rate Service*/ -#define ESP_GATT_UUID_PHONE_ALERT_STATUS_SVC 0x180E /* Phone Alert Status Service*/ -#define ESP_GATT_UUID_BATTERY_SERVICE_SVC 0x180F /* Battery Service*/ -#define ESP_GATT_UUID_BLOOD_PRESSURE_SVC 0x1810 /* Blood Pressure Service*/ -#define ESP_GATT_UUID_ALERT_NTF_SVC 0x1811 /* Alert Notification Service*/ -#define ESP_GATT_UUID_HID_SVC 0x1812 /* HID Service*/ -#define ESP_GATT_UUID_SCAN_PARAMETERS_SVC 0x1813 /* Scan Parameters Service*/ -#define ESP_GATT_UUID_RUNNING_SPEED_CADENCE_SVC 0x1814 /* Running Speed and Cadence Service*/ -#define ESP_GATT_UUID_Automation_IO_SVC 0x1815 /* Automation IO Service*/ -#define ESP_GATT_UUID_CYCLING_SPEED_CADENCE_SVC 0x1816 /* Cycling Speed and Cadence Service*/ -#define ESP_GATT_UUID_CYCLING_POWER_SVC 0x1818 /* Cycling Power Service*/ -#define ESP_GATT_UUID_LOCATION_AND_NAVIGATION_SVC 0x1819 /* Location and Navigation Service*/ -#define ESP_GATT_UUID_ENVIRONMENTAL_SENSING_SVC 0x181A /* Environmental Sensing Service*/ -#define ESP_GATT_UUID_BODY_COMPOSITION 0x181B /* Body Composition Service*/ -#define ESP_GATT_UUID_USER_DATA_SVC 0x181C /* User Data Service*/ -#define ESP_GATT_UUID_WEIGHT_SCALE_SVC 0x181D /* Weight Scale Service*/ -#define ESP_GATT_UUID_BOND_MANAGEMENT_SVC 0x181E /* Bond Management Service*/ -#define ESP_GATT_UUID_CONT_GLUCOSE_MONITOR_SVC 0x181F /* Continuous Glucose Monitoring Service*/ +/** @brief Immediate Alert Service UUID. */ +#define ESP_GATT_UUID_IMMEDIATE_ALERT_SVC 0x1802 +/** @brief Link Loss Service UUID. */ +#define ESP_GATT_UUID_LINK_LOSS_SVC 0x1803 +/** @brief TX Power Service UUID. */ +#define ESP_GATT_UUID_TX_POWER_SVC 0x1804 +/** @brief Current Time Service UUID. */ +#define ESP_GATT_UUID_CURRENT_TIME_SVC 0x1805 +/** @brief Reference Time Update Service UUID. */ +#define ESP_GATT_UUID_REF_TIME_UPDATE_SVC 0x1806 +/** @brief Next DST Change Service UUID. */ +#define ESP_GATT_UUID_NEXT_DST_CHANGE_SVC 0x1807 +/** @brief Glucose Service UUID. */ +#define ESP_GATT_UUID_GLUCOSE_SVC 0x1808 +/** @brief Health Thermometer Service UUID. */ +#define ESP_GATT_UUID_HEALTH_THERMOM_SVC 0x1809 +/** @brief Device Information Service UUID. */ +#define ESP_GATT_UUID_DEVICE_INFO_SVC 0x180A +/** @brief Heart Rate Service UUID. */ +#define ESP_GATT_UUID_HEART_RATE_SVC 0x180D +/** @brief Phone Alert Status Service UUID. */ +#define ESP_GATT_UUID_PHONE_ALERT_STATUS_SVC 0x180E +/** @brief Battery Service UUID. */ +#define ESP_GATT_UUID_BATTERY_SERVICE_SVC 0x180F +/** @brief Blood Pressure Service UUID. */ +#define ESP_GATT_UUID_BLOOD_PRESSURE_SVC 0x1810 +/** @brief Alert Notification Service UUID. */ +#define ESP_GATT_UUID_ALERT_NTF_SVC 0x1811 +/** @brief HID Service UUID. */ +#define ESP_GATT_UUID_HID_SVC 0x1812 +/** @brief Scan Parameters Service UUID. */ +#define ESP_GATT_UUID_SCAN_PARAMETERS_SVC 0x1813 +/** @brief Running Speed and Cadence Service UUID. */ +#define ESP_GATT_UUID_RUNNING_SPEED_CADENCE_SVC 0x1814 +/** @brief Automation IO Service UUID. */ +#define ESP_GATT_UUID_Automation_IO_SVC 0x1815 +/** @brief Cycling Speed and Cadence Service UUID. */ +#define ESP_GATT_UUID_CYCLING_SPEED_CADENCE_SVC 0x1816 +/** @brief Cycling Power Service UUID. */ +#define ESP_GATT_UUID_CYCLING_POWER_SVC 0x1818 +/** @brief Location and Navigation Service UUID. */ +#define ESP_GATT_UUID_LOCATION_AND_NAVIGATION_SVC 0x1819 +/** @brief Environmental Sensing Service UUID. */ +#define ESP_GATT_UUID_ENVIRONMENTAL_SENSING_SVC 0x181A +/** @brief Body Composition Service UUID. */ +#define ESP_GATT_UUID_BODY_COMPOSITION 0x181B +/** @brief User Data Service UUID. */ +#define ESP_GATT_UUID_USER_DATA_SVC 0x181C +/** @brief Weight Scale Service UUID. */ +#define ESP_GATT_UUID_WEIGHT_SCALE_SVC 0x181D +/** @brief Bond Management Service UUID. */ +#define ESP_GATT_UUID_BOND_MANAGEMENT_SVC 0x181E +/** @brief Continuous Glucose Monitoring Service UUID. */ +#define ESP_GATT_UUID_CONT_GLUCOSE_MONITOR_SVC 0x181F +/** @brief Primary Service UUID. */ #define ESP_GATT_UUID_PRI_SERVICE 0x2800 +/** @brief Secondary Service UUID. */ #define ESP_GATT_UUID_SEC_SERVICE 0x2801 +/** @brief Include Service UUID. */ #define ESP_GATT_UUID_INCLUDE_SERVICE 0x2802 -#define ESP_GATT_UUID_CHAR_DECLARE 0x2803 /* Characteristic Declaration*/ - -#define ESP_GATT_UUID_CHAR_EXT_PROP 0x2900 /* Characteristic Extended Properties */ -#define ESP_GATT_UUID_CHAR_DESCRIPTION 0x2901 /* Characteristic User Description*/ -#define ESP_GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */ -#define ESP_GATT_UUID_CHAR_SRVR_CONFIG 0x2903 /* Server Characteristic Configuration */ -#define ESP_GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/ -#define ESP_GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/ -#define ESP_GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */ -#define ESP_GATT_UUID_EXT_RPT_REF_DESCR 0x2907 /* External Report Reference */ -#define ESP_GATT_UUID_RPT_REF_DESCR 0x2908 /* Report Reference */ -#define ESP_GATT_UUID_NUM_DIGITALS_DESCR 0x2909 /* Number of Digitals */ -#define ESP_GATT_UUID_VALUE_TRIGGER_DESCR 0x290A /* Value Trigger Setting */ -#define ESP_GATT_UUID_ENV_SENSING_CONFIG_DESCR 0x290B /* Environmental Sensing Configuration */ -#define ESP_GATT_UUID_ENV_SENSING_MEASUREMENT_DESCR 0x290C /* Environmental Sensing Measurement */ -#define ESP_GATT_UUID_ENV_SENSING_TRIGGER_DESCR 0x290D /* Environmental Sensing Trigger Setting */ -#define ESP_GATT_UUID_TIME_TRIGGER_DESCR 0x290E /* Time Trigger Setting */ +/** @brief Characteristic Declaration UUID. */ +#define ESP_GATT_UUID_CHAR_DECLARE 0x2803 +/** @brief Characteristic Extended Properties UUID. */ +#define ESP_GATT_UUID_CHAR_EXT_PROP 0x2900 +/** @brief Characteristic User Description UUID. */ +#define ESP_GATT_UUID_CHAR_DESCRIPTION 0x2901 +/** @brief Client Characteristic Configuration UUID. */ +#define ESP_GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 +/** @brief Server Characteristic Configuration UUID. */ +#define ESP_GATT_UUID_CHAR_SRVR_CONFIG 0x2903 +/** @brief Characteristic Presentation Format UUID. */ +#define ESP_GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 +/** @brief Characteristic Aggregate Format UUID. */ +#define ESP_GATT_UUID_CHAR_AGG_FORMAT 0x2905 +/** @brief Characteristic Valid Range UUID. */ +#define ESP_GATT_UUID_CHAR_VALID_RANGE 0x2906 +/** @brief External Report Reference Descriptor UUID. */ +#define ESP_GATT_UUID_EXT_RPT_REF_DESCR 0x2907 +/** @brief Report Reference Descriptor UUID. */ +#define ESP_GATT_UUID_RPT_REF_DESCR 0x2908 +/** @brief Number of Digitals Descriptor UUID. */ +#define ESP_GATT_UUID_NUM_DIGITALS_DESCR 0x2909 +/** @brief Value Trigger Setting Descriptor UUID. */ +#define ESP_GATT_UUID_VALUE_TRIGGER_DESCR 0x290A +/** @brief Environmental Sensing Configuration Descriptor UUID. */ +#define ESP_GATT_UUID_ENV_SENSING_CONFIG_DESCR 0x290B +/** @brief Environmental Sensing Measurement Descriptor UUID. */ +#define ESP_GATT_UUID_ENV_SENSING_MEASUREMENT_DESCR 0x290C +/** @brief Environmental Sensing Trigger Setting Descriptor UUID. */ +#define ESP_GATT_UUID_ENV_SENSING_TRIGGER_DESCR 0x290D +/** @brief Time Trigger Setting Descriptor UUID. */ +#define ESP_GATT_UUID_TIME_TRIGGER_DESCR 0x290E /* GAP Profile Attributes */ +/** @brief GAP Device Name UUID. */ #define ESP_GATT_UUID_GAP_DEVICE_NAME 0x2A00 +/** @brief GAP Icon UUID. */ #define ESP_GATT_UUID_GAP_ICON 0x2A01 +/** @brief GAP Preferred Connection Parameters UUID. */ #define ESP_GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04 +/** @brief GAP Central Address Resolution UUID. */ #define ESP_GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6 /* Attribute Profile Attribute UUID */ +/** @brief GATT Service Changed UUID. */ #define ESP_GATT_UUID_GATT_SRV_CHGD 0x2A05 -/* Link ESP_Loss Service */ -#define ESP_GATT_UUID_ALERT_LEVEL 0x2A06 /* Alert Level */ -#define ESP_GATT_UUID_TX_POWER_LEVEL 0x2A07 /* TX power level */ +/* Link Loss Service */ +/** @brief Alert Level UUID. */ +#define ESP_GATT_UUID_ALERT_LEVEL 0x2A06 +/** @brief TX Power Level UUID. */ +#define ESP_GATT_UUID_TX_POWER_LEVEL 0x2A07 /* Current Time Service */ -#define ESP_GATT_UUID_CURRENT_TIME 0x2A2B /* Current Time */ -#define ESP_GATT_UUID_LOCAL_TIME_INFO 0x2A0F /* Local time info */ -#define ESP_GATT_UUID_REF_TIME_INFO 0x2A14 /* reference time information */ - -/* Network availability Profile */ -#define ESP_GATT_UUID_NW_STATUS 0x2A18 /* network availability status */ -#define ESP_GATT_UUID_NW_TRIGGER 0x2A1A /* Network availability trigger */ - -/* Phone alert */ -#define ESP_GATT_UUID_ALERT_STATUS 0x2A3F /* alert status */ -#define ESP_GATT_UUID_RINGER_CP 0x2A40 /* ringer control point */ -#define ESP_GATT_UUID_RINGER_SETTING 0x2A41 /* ringer setting */ +/** @brief Current Time UUID. */ +#define ESP_GATT_UUID_CURRENT_TIME 0x2A2B +/** @brief Local Time Info UUID. */ +#define ESP_GATT_UUID_LOCAL_TIME_INFO 0x2A0F +/** @brief Reference Time Information UUID. */ +#define ESP_GATT_UUID_REF_TIME_INFO 0x2A14 + +/* Network Availability Service */ +/** @brief Network Availability Status UUID. */ +#define ESP_GATT_UUID_NW_STATUS 0x2A18 +/** @brief Network Availability Trigger UUID. */ +#define ESP_GATT_UUID_NW_TRIGGER 0x2A1A + +/* Phone Alert Status Service */ +/** @brief Alert Status UUID. */ +#define ESP_GATT_UUID_ALERT_STATUS 0x2A3F +/** @brief Ringer Control Point UUID. */ +#define ESP_GATT_UUID_RINGER_CP 0x2A40 +/** @brief Ringer Setting UUID. */ +#define ESP_GATT_UUID_RINGER_SETTING 0x2A41 /* Glucose Service */ +/** @brief Glucose Measurement Characteristic UUID. */ #define ESP_GATT_UUID_GM_MEASUREMENT 0x2A18 +/** @brief Glucose Measurement Context Characteristic UUID. */ #define ESP_GATT_UUID_GM_CONTEXT 0x2A34 +/** @brief Glucose Control Point Characteristic UUID. */ #define ESP_GATT_UUID_GM_CONTROL_POINT 0x2A52 +/** @brief Glucose Feature Characteristic UUID. */ #define ESP_GATT_UUID_GM_FEATURE 0x2A51 -/* device information characteristic */ +/* Device Information Service Characteristics */ +/** @brief System ID Characteristic UUID. */ #define ESP_GATT_UUID_SYSTEM_ID 0x2A23 +/** @brief Model Number String Characteristic UUID. */ #define ESP_GATT_UUID_MODEL_NUMBER_STR 0x2A24 +/** @brief Serial Number String Characteristic UUID. */ #define ESP_GATT_UUID_SERIAL_NUMBER_STR 0x2A25 +/** @brief Firmware Revision String Characteristic UUID. */ #define ESP_GATT_UUID_FW_VERSION_STR 0x2A26 +/** @brief Hardware Revision String Characteristic UUID. */ #define ESP_GATT_UUID_HW_VERSION_STR 0x2A27 +/** @brief Software Revision String Characteristic UUID. */ #define ESP_GATT_UUID_SW_VERSION_STR 0x2A28 +/** @brief Manufacturer Name String Characteristic UUID. */ #define ESP_GATT_UUID_MANU_NAME 0x2A29 +/** @brief IEEE 11073-20601 Regulatory Certification Data List Characteristic UUID. */ #define ESP_GATT_UUID_IEEE_DATA 0x2A2A +/** @brief PnP ID Characteristic UUID. */ #define ESP_GATT_UUID_PNP_ID 0x2A50 -/* HID characteristics */ +/* HID Service Characteristics */ +/** @brief HID Information Characteristic UUID. */ #define ESP_GATT_UUID_HID_INFORMATION 0x2A4A +/** @brief HID Report Map Characteristic UUID. */ #define ESP_GATT_UUID_HID_REPORT_MAP 0x2A4B +/** @brief HID Control Point Characteristic UUID. */ #define ESP_GATT_UUID_HID_CONTROL_POINT 0x2A4C +/** @brief HID Report Characteristic UUID. */ #define ESP_GATT_UUID_HID_REPORT 0x2A4D +/** @brief HID Protocol Mode Characteristic UUID. */ #define ESP_GATT_UUID_HID_PROTO_MODE 0x2A4E +/** @brief HID Bluetooth Keyboard Input Characteristic UUID. */ #define ESP_GATT_UUID_HID_BT_KB_INPUT 0x2A22 +/** @brief HID Bluetooth Keyboard Output Characteristic UUID. */ #define ESP_GATT_UUID_HID_BT_KB_OUTPUT 0x2A32 +/** @brief HID Bluetooth Mouse Input Characteristic UUID. */ #define ESP_GATT_UUID_HID_BT_MOUSE_INPUT 0x2A33 - /// Heart Rate Measurement -#define ESP_GATT_HEART_RATE_MEAS 0x2A37 -/// Body Sensor Location -#define ESP_GATT_BODY_SENSOR_LOCATION 0x2A38 -/// Heart Rate Control Point -#define ESP_GATT_HEART_RATE_CNTL_POINT 0x2A39 +/* Heart Rate Service Characteristics */ +/** @brief Heart Rate Measurement Characteristic UUID. */ +#define ESP_GATT_HEART_RATE_MEAS 0x2A37 +/** @brief Body Sensor Location Characteristic UUID. */ +#define ESP_GATT_BODY_SENSOR_LOCATION 0x2A38 +/** @brief Heart Rate Control Point Characteristic UUID. */ +#define ESP_GATT_HEART_RATE_CNTL_POINT 0x2A39 -/* Battery Service characteristics */ +/* Battery Service Characteristics */ +/** @brief Battery Level Characteristic UUID. */ #define ESP_GATT_UUID_BATTERY_LEVEL 0x2A19 -/* Sensor Service */ +/* Sensor Service Characteristics */ +/** @brief Sensor Control Point Characteristic UUID. */ #define ESP_GATT_UUID_SC_CONTROL_POINT 0x2A55 +/** @brief Sensor Location Characteristic UUID. */ #define ESP_GATT_UUID_SENSOR_LOCATION 0x2A5D -/* Runners speed and cadence service */ +/* Running Speed and Cadence Service Characteristics */ +/** @brief RSC Measurement Characteristic UUID. */ #define ESP_GATT_UUID_RSC_MEASUREMENT 0x2A53 +/** @brief RSC Feature Characteristic UUID. */ #define ESP_GATT_UUID_RSC_FEATURE 0x2A54 -/* Cycling speed and cadence service */ +/* Cycling Speed and Cadence Service Characteristics */ +/** @brief CSC Measurement Characteristic UUID. */ #define ESP_GATT_UUID_CSC_MEASUREMENT 0x2A5B +/** @brief CSC Feature Characteristic UUID. */ #define ESP_GATT_UUID_CSC_FEATURE 0x2A5C -/* Scan ESP_Parameter characteristics */ +/* Scan Parameters Service Characteristics */ +/** @brief Scan Interval Window Characteristic UUID. */ #define ESP_GATT_UUID_SCAN_INT_WINDOW 0x2A4F +/** @brief Scan Refresh UUID. */ #define ESP_GATT_UUID_SCAN_REFRESH 0x2A31 +/* Additional GATT Services not covered yet */ +/** @} */ // End of group GATT_UUIDs + + /** - * @} + * @brief Defines the attribute write operation types from the client. + * + * These values are used to specify the type of write operation in a prepare write sequence. + * relate to BTA_GATT_PREP_WRITE_xxx in bta/bta_gatt_api.h. */ - -/* relate to BTA_GATT_PREP_WRITE_xxx in bta/bta_gatt_api.h */ -/// Attribute write data type from the client typedef enum { - ESP_GATT_PREP_WRITE_CANCEL = 0x00, /*!< Prepare write cancel */ /* relate to BTA_GATT_PREP_WRITE_CANCEL in bta/bta_gatt_api.h */ - ESP_GATT_PREP_WRITE_EXEC = 0x01, /*!< Prepare write execute */ /* relate to BTA_GATT_PREP_WRITE_EXEC in bta/bta_gatt_api.h */ + ESP_GATT_PREP_WRITE_CANCEL = 0x00, /*!< Prepare write cancel. Corresponds to BTA_GATT_PREP_WRITE_CANCEL. */ + ESP_GATT_PREP_WRITE_EXEC = 0x01, /*!< Prepare write execute. Corresponds to BTA_GATT_PREP_WRITE_EXEC. */ } esp_gatt_prep_write_type; -/* relate to BTA_GATT_xxx in bta/bta_gatt_api.h */ + /** - * @brief GATT success code and error codes + * @brief GATT operation status codes. + * + * These status codes are used to indicate the result of various GATT operations. + * relate to BTA_GATT_xxx in bta/bta_gatt_api.h . */ typedef enum { - ESP_GATT_OK = 0x0, /* relate to BTA_GATT_OK in bta/bta_gatt_api.h */ - ESP_GATT_INVALID_HANDLE = 0x01, /* 0x0001 */ /* relate to BTA_GATT_INVALID_HANDLE in bta/bta_gatt_api.h */ - ESP_GATT_READ_NOT_PERMIT = 0x02, /* 0x0002 */ /* relate to BTA_GATT_READ_NOT_PERMIT in bta/bta_gatt_api.h */ - ESP_GATT_WRITE_NOT_PERMIT = 0x03, /* 0x0003 */ /* relate to BTA_GATT_WRITE_NOT_PERMIT in bta/bta_gatt_api.h */ - ESP_GATT_INVALID_PDU = 0x04, /* 0x0004 */ /* relate to BTA_GATT_INVALID_PDU in bta/bta_gatt_api.h */ - ESP_GATT_INSUF_AUTHENTICATION = 0x05, /* 0x0005 */ /* relate to BTA_GATT_INSUF_AUTHENTICATION in bta/bta_gatt_api.h */ - ESP_GATT_REQ_NOT_SUPPORTED = 0x06, /* 0x0006 */ /* relate to BTA_GATT_REQ_NOT_SUPPORTED in bta/bta_gatt_api.h */ - ESP_GATT_INVALID_OFFSET = 0x07, /* 0x0007 */ /* relate to BTA_GATT_INVALID_OFFSET in bta/bta_gatt_api.h */ - ESP_GATT_INSUF_AUTHORIZATION = 0x08, /* 0x0008 */ /* relate to BTA_GATT_INSUF_AUTHORIZATION in bta/bta_gatt_api.h */ - ESP_GATT_PREPARE_Q_FULL = 0x09, /* 0x0009 */ /* relate to BTA_GATT_PREPARE_Q_FULL in bta/bta_gatt_api.h */ - ESP_GATT_NOT_FOUND = 0x0a, /* 0x000a */ /* relate to BTA_GATT_NOT_FOUND in bta/bta_gatt_api.h */ - ESP_GATT_NOT_LONG = 0x0b, /* 0x000b */ /* relate to BTA_GATT_NOT_LONG in bta/bta_gatt_api.h */ - ESP_GATT_INSUF_KEY_SIZE = 0x0c, /* 0x000c */ /* relate to BTA_GATT_INSUF_KEY_SIZE in bta/bta_gatt_api.h */ - ESP_GATT_INVALID_ATTR_LEN = 0x0d, /* 0x000d */ /* relate to BTA_GATT_INVALID_ATTR_LEN in bta/bta_gatt_api.h */ - ESP_GATT_ERR_UNLIKELY = 0x0e, /* 0x000e */ /* relate to BTA_GATT_ERR_UNLIKELY in bta/bta_gatt_api.h */ - ESP_GATT_INSUF_ENCRYPTION = 0x0f, /* 0x000f */ /* relate to BTA_GATT_INSUF_ENCRYPTION in bta/bta_gatt_api.h */ - ESP_GATT_UNSUPPORT_GRP_TYPE = 0x10, /* 0x0010 */ /* relate to BTA_GATT_UNSUPPORT_GRP_TYPE in bta/bta_gatt_api.h */ - ESP_GATT_INSUF_RESOURCE = 0x11, /* 0x0011 */ /* relate to BTA_GATT_INSUF_RESOURCE in bta/bta_gatt_api.h */ - - ESP_GATT_NO_RESOURCES = 0x80, /* 0x80 */ /* relate to BTA_GATT_NO_RESOURCES in bta/bta_gatt_api.h */ - ESP_GATT_INTERNAL_ERROR = 0x81, /* 0x81 */ /* relate to BTA_GATT_INTERNAL_ERROR in bta/bta_gatt_api.h */ - ESP_GATT_WRONG_STATE = 0x82, /* 0x82 */ /* relate to BTA_GATT_WRONG_STATE in bta/bta_gatt_api.h */ - ESP_GATT_DB_FULL = 0x83, /* 0x83 */ /* relate to BTA_GATT_DB_FULL in bta/bta_gatt_api.h */ - ESP_GATT_BUSY = 0x84, /* 0x84 */ /* relate to BTA_GATT_BUSY in bta/bta_gatt_api.h */ - ESP_GATT_ERROR = 0x85, /* 0x85 */ /* relate to BTA_GATT_ERROR in bta/bta_gatt_api.h */ - ESP_GATT_CMD_STARTED = 0x86, /* 0x86 */ /* relate to BTA_GATT_CMD_STARTED in bta/bta_gatt_api.h */ - ESP_GATT_ILLEGAL_PARAMETER = 0x87, /* 0x87 */ /* relate to BTA_GATT_ILLEGAL_PARAMETER in bta/bta_gatt_api.h */ - ESP_GATT_PENDING = 0x88, /* 0x88 */ /* relate to BTA_GATT_PENDING in bta/bta_gatt_api.h */ - ESP_GATT_AUTH_FAIL = 0x89, /* 0x89 */ /* relate to BTA_GATT_AUTH_FAIL in bta/bta_gatt_api.h */ - ESP_GATT_MORE = 0x8a, /* 0x8a */ /* relate to BTA_GATT_MORE in bta/bta_gatt_api.h */ - ESP_GATT_INVALID_CFG = 0x8b, /* 0x8b */ /* relate to BTA_GATT_INVALID_CFG in bta/bta_gatt_api.h */ - ESP_GATT_SERVICE_STARTED = 0x8c, /* 0x8c */ /* relate to BTA_GATT_SERVICE_STARTED in bta/bta_gatt_api.h */ - ESP_GATT_ENCRYPTED_MITM = ESP_GATT_OK, /* relate to BTA_GATT_ENCRYPED_MITM in bta/bta_gatt_api.h */ - ESP_GATT_ENCRYPTED_NO_MITM = 0x8d, /* 0x8d */ /* relate to BTA_GATT_ENCRYPED_NO_MITM in bta/bta_gatt_api.h */ - ESP_GATT_NOT_ENCRYPTED = 0x8e, /* 0x8e */ /* relate to BTA_GATT_NOT_ENCRYPTED in bta/bta_gatt_api.h */ - ESP_GATT_CONGESTED = 0x8f, /* 0x8f */ /* relate to BTA_GATT_CONGESTED in bta/bta_gatt_api.h */ - ESP_GATT_DUP_REG = 0x90, /* 0x90 */ /* relate to BTA_GATT_DUP_REG in bta/bta_gatt_api.h */ - ESP_GATT_ALREADY_OPEN = 0x91, /* 0x91 */ /* relate to BTA_GATT_ALREADY_OPEN in bta/bta_gatt_api.h */ - ESP_GATT_CANCEL = 0x92, /* 0x92 */ /* relate to BTA_GATT_CANCEL in bta/bta_gatt_api.h */ + ESP_GATT_OK = 0x0, /*!< 0x0, Operation successful. Corresponds to BTA_GATT_OK. */ + ESP_GATT_INVALID_HANDLE = 0x01, /*!< 0x01, Invalid handle. Corresponds to BTA_GATT_INVALID_HANDLE. */ + ESP_GATT_READ_NOT_PERMIT = 0x02, /*!< 0x02, Read operation not permitted. Corresponds to BTA_GATT_READ_NOT_PERMIT. */ + ESP_GATT_WRITE_NOT_PERMIT = 0x03, /*!< 0x03, Write operation not permitted. Corresponds to BTA_GATT_WRITE_NOT_PERMIT. */ + ESP_GATT_INVALID_PDU = 0x04, /*!< 0x04, Invalid PDU. Corresponds to BTA_GATT_INVALID_PDU. */ + ESP_GATT_INSUF_AUTHENTICATION = 0x05, /*!< 0x05, Insufficient authentication. Corresponds to BTA_GATT_INSUF_AUTHENTICATION. */ + ESP_GATT_REQ_NOT_SUPPORTED = 0x06, /*!< 0x06, Request not supported. Corresponds to BTA_GATT_REQ_NOT_SUPPORTED. */ + ESP_GATT_INVALID_OFFSET = 0x07, /*!< 0x07, Invalid offset. Corresponds to BTA_GATT_INVALID_OFFSET. */ + ESP_GATT_INSUF_AUTHORIZATION = 0x08, /*!< 0x08, Insufficient authorization. Corresponds to BTA_GATT_INSUF_AUTHORIZATION. */ + ESP_GATT_PREPARE_Q_FULL = 0x09, /*!< 0x09, Prepare queue full. Corresponds to BTA_GATT_PREPARE_Q_FULL. */ + ESP_GATT_NOT_FOUND = 0x0a, /*!< 0x0a, Not found. Corresponds to BTA_GATT_NOT_FOUND. */ + ESP_GATT_NOT_LONG = 0x0b, /*!< 0x0b, Not long. Corresponds to BTA_GATT_NOT_LONG. */ + ESP_GATT_INSUF_KEY_SIZE = 0x0c, /*!< 0x0c, Insufficient key size. Corresponds to BTA_GATT_INSUF_KEY_SIZE. */ + ESP_GATT_INVALID_ATTR_LEN = 0x0d, /*!< 0x0d, Invalid attribute length. Corresponds to BTA_GATT_INVALID_ATTR_LEN. */ + ESP_GATT_ERR_UNLIKELY = 0x0e, /*!< 0x0e, Unlikely error. Corresponds to BTA_GATT_ERR_UNLIKELY. */ + ESP_GATT_INSUF_ENCRYPTION = 0x0f, /*!< 0x0f, Insufficient encryption. Corresponds to BTA_GATT_INSUF_ENCRYPTION. */ + ESP_GATT_UNSUPPORT_GRP_TYPE = 0x10, /*!< 0x10, Unsupported group type. Corresponds to BTA_GATT_UNSUPPORT_GRP_TYPE. */ + ESP_GATT_INSUF_RESOURCE = 0x11, /*!< 0x11, Insufficient resource. Corresponds to BTA_GATT_INSUF_RESOURCE. */ + + /* Additional error codes specific to implementation or future use */ + ESP_GATT_NO_RESOURCES = 0x80, /*!< 0x80, No resources. Corresponds to BTA_GATT_NO_RESOURCES. */ + ESP_GATT_INTERNAL_ERROR = 0x81, /*!< 0x81, Internal error. Corresponds to BTA_GATT_INTERNAL_ERROR. */ + ESP_GATT_WRONG_STATE = 0x82, /*!< 0x82, Wrong state. Corresponds to BTA_GATT_WRONG_STATE. */ + ESP_GATT_DB_FULL = 0x83, /*!< 0x83, Database full. Corresponds to BTA_GATT_DB_FULL. */ + ESP_GATT_BUSY = 0x84, /*!< 0x84, Busy. Corresponds to BTA_GATT_BUSY. */ + ESP_GATT_ERROR = 0x85, /*!< 0x85, Generic error. Corresponds to BTA_GATT_ERROR. */ + ESP_GATT_CMD_STARTED = 0x86, /*!< 0x86, Command started. Corresponds to BTA_GATT_CMD_STARTED. */ + ESP_GATT_ILLEGAL_PARAMETER = 0x87, /*!< 0x87, Illegal parameter. Corresponds to BTA_GATT_ILLEGAL_PARAMETER. */ + ESP_GATT_PENDING = 0x88, /*!< 0x88, Operation pending. Corresponds to BTA_GATT_PENDING. */ + ESP_GATT_AUTH_FAIL = 0x89, /*!< 0x89, Authentication failed. Corresponds to BTA_GATT_AUTH_FAIL. */ + ESP_GATT_MORE = 0x8a, /*!< 0x8a, More data available. Corresponds to BTA_GATT_MORE. */ + ESP_GATT_INVALID_CFG = 0x8b, /*!< 0x8b, Invalid configuration. Corresponds to BTA_GATT_INVALID_CFG. */ + ESP_GATT_SERVICE_STARTED = 0x8c, /*!< 0x8c, Service started. Corresponds to BTA_GATT_SERVICE_STARTED. */ + ESP_GATT_ENCRYPTED_MITM = ESP_GATT_OK, /*!< 0x0, Encrypted, with MITM protection. Corresponds to BTA_GATT_ENCRYPTED_MITM. */ + ESP_GATT_ENCRYPTED_NO_MITM = 0x8d, /*!< 0x8d, Encrypted, without MITM protection. Corresponds to BTA_GATT_ENCRYPTED_NO_MITM. */ + ESP_GATT_NOT_ENCRYPTED = 0x8e, /*!< 0x8e, Not encrypted. Corresponds to BTA_GATT_NOT_ENCRYPTED. */ + ESP_GATT_CONGESTED = 0x8f, /*!< 0x8f, Congested. Corresponds to BTA_GATT_CONGESTED. */ + ESP_GATT_DUP_REG = 0x90, /*!< 0x90, Duplicate registration. Corresponds to BTA_GATT_DUP_REG. */ + ESP_GATT_ALREADY_OPEN = 0x91, /*!< 0x91, Already open. Corresponds to BTA_GATT_ALREADY_OPEN. */ + ESP_GATT_CANCEL = 0x92, /*!< 0x92, Operation cancelled. Corresponds to BTA_GATT_CANCEL. */ /* 0xE0 ~ 0xFC reserved for future use */ - ESP_GATT_STACK_RSP = 0xe0, /* 0xe0 */ /* relate to BTA_GATT_STACK_RSP in bta/bta_gatt_api.h */ - ESP_GATT_APP_RSP = 0xe1, /* 0xe1 */ /* relate to BTA_GATT_APP_RSP in bta/bta_gatt_api.h */ - //Error caused by customer application or stack bug - ESP_GATT_UNKNOWN_ERROR = 0xef, /* 0xef */ /* relate to BTA_GATT_UNKNOWN_ERROR in bta/bta_gatt_api.h */ - ESP_GATT_CCC_CFG_ERR = 0xfd, /* 0xFD Client Characteristic Configuration Descriptor Improperly Configured */ /* relate to BTA_GATT_CCC_CFG_ERR in bta/bta_gatt_api.h */ - ESP_GATT_PRC_IN_PROGRESS = 0xfe, /* 0xFE Procedure Already in progress */ /* relate to BTA_GATT_PRC_IN_PROGRESS in bta/bta_gatt_api.h */ - ESP_GATT_OUT_OF_RANGE = 0xff, /* 0xFF Attribute value out of range */ /* relate to BTA_GATT_OUT_OF_RANGE in bta/bta_gatt_api.h */ + ESP_GATT_STACK_RSP = 0xe0, /*!< 0xe0, Stack response. Corresponds to BTA_GATT_STACK_RSP. */ + ESP_GATT_APP_RSP = 0xe1, /*!< 0xe1, Application response. Corresponds to BTA_GATT_APP_RSP. */ + /* Error caused by customer application or stack bug */ + ESP_GATT_UNKNOWN_ERROR = 0xef, /*!< 0xef, Unknown error. Corresponds to BTA_GATT_UNKNOWN_ERROR. */ + ESP_GATT_CCC_CFG_ERR = 0xfd, /*!< 0xfd, Client Characteristic Configuration Descriptor improperly configured. Corresponds to BTA_GATT_CCC_CFG_ERR. */ + ESP_GATT_PRC_IN_PROGRESS = 0xfe, /*!< 0xfe, Procedure already in progress. Corresponds to BTA_GATT_PRC_IN_PROGRESS. */ + ESP_GATT_OUT_OF_RANGE = 0xff /*!< 0xff, Attribute value out of range. Corresponds to BTA_GATT_OUT_OF_RANGE. */ } esp_gatt_status_t; -/* relate to BTA_GATT_CONN_xxx in bta/bta_gatt_api.h */ + /** - * @brief Gatt Connection reason enum + * @brief Enumerates reasons for GATT connection. */ typedef enum { - ESP_GATT_CONN_UNKNOWN = 0, /*!< Gatt connection unknown */ /* relate to BTA_GATT_CONN_UNKNOWN in bta/bta_gatt_api.h */ - ESP_GATT_CONN_L2C_FAILURE = 1, /*!< General L2cap failure */ /* relate to BTA_GATT_CONN_L2C_FAILURE in bta/bta_gatt_api.h */ - ESP_GATT_CONN_TIMEOUT = 0x08, /*!< Connection timeout */ /* relate to BTA_GATT_CONN_TIMEOUT in bta/bta_gatt_api.h */ - ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13, /*!< Connection terminate by peer user */ /* relate to BTA_GATT_CONN_TERMINATE_PEER_USER in bta/bta_gatt_api.h */ - ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16, /*!< Connection terminated by local host */ /* relate to BTA_GATT_CONN_TERMINATE_LOCAL_HOST in bta/bta_gatt_api.h */ - ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e, /*!< Connection fail to establish */ /* relate to BTA_GATT_CONN_FAIL_ESTABLISH in bta/bta_gatt_api.h */ - ESP_GATT_CONN_LMP_TIMEOUT = 0x22, /*!< Connection fail for LMP response tout */ /* relate to BTA_GATT_CONN_LMP_TIMEOUT in bta/bta_gatt_api.h */ - ESP_GATT_CONN_CONN_CANCEL = 0x0100, /*!< L2CAP connection cancelled */ /* relate to BTA_GATT_CONN_CONN_CANCEL in bta/bta_gatt_api.h */ - ESP_GATT_CONN_NONE = 0x0101 /*!< No connection to cancel */ /* relate to BTA_GATT_CONN_NONE in bta/bta_gatt_api.h */ + ESP_GATT_CONN_UNKNOWN = 0, /*!< Unknown connection reason. Corresponds to BTA_GATT_CONN_UNKNOWN in bta/bta_gatt_api.h */ + ESP_GATT_CONN_L2C_FAILURE = 1, /*!< General L2CAP failure. Corresponds to BTA_GATT_CONN_L2C_FAILURE in bta/bta_gatt_api.h */ + ESP_GATT_CONN_TIMEOUT = 0x08, /*!< Connection timeout. Corresponds to BTA_GATT_CONN_TIMEOUT in bta/bta_gatt_api.h */ + ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13, /*!< Connection terminated by peer user. Corresponds to BTA_GATT_CONN_TERMINATE_PEER_USER in bta/bta_gatt_api.h */ + ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16, /*!< Connection terminated by local host. Corresponds to BTA_GATT_CONN_TERMINATE_LOCAL_HOST in bta/bta_gatt_api.h */ + ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e, /*!< Failure to establish connection. Corresponds to BTA_GATT_CONN_FAIL_ESTABLISH in bta/bta_gatt_api.h */ + ESP_GATT_CONN_LMP_TIMEOUT = 0x22, /*!< Connection failed due to LMP response timeout. Corresponds to BTA_GATT_CONN_LMP_TIMEOUT in bta/bta_gatt_api.h */ + ESP_GATT_CONN_CONN_CANCEL = 0x0100, /*!< L2CAP connection cancelled. Corresponds to BTA_GATT_CONN_CONN_CANCEL in bta/bta_gatt_api.h */ + ESP_GATT_CONN_NONE = 0x0101 /*!< No connection to cancel. Corresponds to BTA_GATT_CONN_NONE in bta/bta_gatt_api.h */ } esp_gatt_conn_reason_t; + /** - * @brief Gatt id, include uuid and instance id + * @brief Represents a GATT identifier. */ typedef struct { - esp_bt_uuid_t uuid; /*!< UUID */ - uint8_t inst_id; /*!< Instance id */ + esp_bt_uuid_t uuid; /*!< @brief The UUID component of the GATT ID. */ + uint8_t inst_id; /*!< @brief The instance ID component of the GATT ID, providing further differentiation of the GATT ID. */ } __attribute__((packed)) esp_gatt_id_t; + /** - * @brief Gatt service id, include id - * (uuid and instance id) and primary flag + * @brief Represents a GATT service identifier. */ typedef struct { - esp_gatt_id_t id; /*!< Gatt id, include uuid and instance */ - bool is_primary; /*!< This service is primary or not */ + esp_gatt_id_t id; /*!< @brief Encapsulates the UUID and instance ID of the GATT service. */ + bool is_primary; /*!< @brief Indicates if the service is primary. A value of true means it is a primary service, false indicates a secondary service. */ } __attribute__((packed)) esp_gatt_srvc_id_t; -/* relate to BTA_GATT_AUTH_REQ_xxx in bta/bta_gatt_api.h */ /** - * @brief Gatt authentication request type + * @brief Defines the GATT authentication request types. + * + * This enumeration lists the types of authentication requests that can be made. + * It corresponds to the `BTA_GATT_AUTH_REQ_xxx` values defined in `bta/bta_gatt_api.h`. + * The types include options for no authentication, unauthenticated encryption, authenticated encryption, + * and both signed versions with and without MITM (Man-In-The-Middle) protection. */ typedef enum { - ESP_GATT_AUTH_REQ_NONE = 0, /* relate to BTA_GATT_AUTH_REQ_NONE in bta/bta_gatt_api.h */ - ESP_GATT_AUTH_REQ_NO_MITM = 1, /* unauthenticated encryption */ /* relate to BTA_GATT_AUTH_REQ_NO_MITM in bta/bta_gatt_api.h */ - ESP_GATT_AUTH_REQ_MITM = 2, /* authenticated encryption */ /* relate to BTA_GATT_AUTH_REQ_MITM in bta/bta_gatt_api.h */ - ESP_GATT_AUTH_REQ_SIGNED_NO_MITM = 3, /* relate to BTA_GATT_AUTH_REQ_SIGNED_NO_MITM in bta/bta_gatt_api.h */ - ESP_GATT_AUTH_REQ_SIGNED_MITM = 4, /* relate to BTA_GATT_AUTH_REQ_SIGNED_MITM in bta/bta_gatt_api.h */ + ESP_GATT_AUTH_REQ_NONE = 0, /*!< No authentication required. Corresponds to BTA_GATT_AUTH_REQ_NONE. */ + ESP_GATT_AUTH_REQ_NO_MITM = 1, /*!< Unauthenticated encryption. Corresponds to BTA_GATT_AUTH_REQ_NO_MITM. */ + ESP_GATT_AUTH_REQ_MITM = 2, /*!< Authenticated encryption (MITM protection). Corresponds to BTA_GATT_AUTH_REQ_MITM. */ + ESP_GATT_AUTH_REQ_SIGNED_NO_MITM = 3, /*!< Signed data, no MITM protection. Corresponds to BTA_GATT_AUTH_REQ_SIGNED_NO_MITM. */ + ESP_GATT_AUTH_REQ_SIGNED_MITM = 4, /*!< Signed data with MITM protection. Corresponds to BTA_GATT_AUTH_REQ_SIGNED_MITM. */ } esp_gatt_auth_req_t; -/* relate to BTA_GATT_PERM_xxx in bta/bta_gatt_api.h */ + +/** + * @brief Defines GATT attribute permission flags. + * + * These permission flags are used to specify the security requirements for GATT attributes. + * They correlate directly with the BTA_GATT_PERM_xxx definitions found in bta/bta_gatt_api.h. + */ + +/** @defgroup GATT_PERMS GATT Attribute Permissions + * @brief Definitions of permission flags for GATT attributes. + * @{ + */ + +/** @brief Permission to read the attribute. Corresponds to BTA_GATT_PERM_READ. */ +#define ESP_GATT_PERM_READ (1 << 0) + +/** @brief Permission to read the attribute with encryption. Corresponds to BTA_GATT_PERM_READ_ENCRYPTED. */ +#define ESP_GATT_PERM_READ_ENCRYPTED (1 << 1) + +/** @brief Permission to read the attribute with encrypted MITM (Man In The Middle) protection. Corresponds to BTA_GATT_PERM_READ_ENC_MITM.*/ +#define ESP_GATT_PERM_READ_ENC_MITM (1 << 2) + +/** @brief Permission to write to the attribute. Corresponds to BTA_GATT_PERM_WRITE. */ +#define ESP_GATT_PERM_WRITE (1 << 4) + +/** @brief Permission to write to the attribute with encryption. Corresponds to BTA_GATT_PERM_WRITE_ENCRYPTED. */ +#define ESP_GATT_PERM_WRITE_ENCRYPTED (1 << 5) + +/** @brief Permission to write to the attribute with encrypted MITM protection. Corresponds to BTA_GATT_PERM_WRITE_ENC_MITM. */ +#define ESP_GATT_PERM_WRITE_ENC_MITM (1 << 6) + +/** @brief Permission for signed writes to the attribute. Corresponds to BTA_GATT_PERM_WRITE_SIGNED. */ +#define ESP_GATT_PERM_WRITE_SIGNED (1 << 7) + +/** @brief Permission for signed writes to the attribute with MITM protection. Corresponds to BTA_GATT_PERM_WRITE_SIGNED_MITM. */ +#define ESP_GATT_PERM_WRITE_SIGNED_MITM (1 << 8) + +/** @brief Permission to read the attribute with authorization. */ +#define ESP_GATT_PERM_READ_AUTHORIZATION (1 << 9) + +/** @brief Permission to write to the attribute with authorization. */ +#define ESP_GATT_PERM_WRITE_AUTHORIZATION (1 << 10) + +/** + * @brief Macro to specify minimum encryption key size. + * + * @param keysize The minimum size of the encryption key, in bytes. + */ +#define ESP_GATT_PERM_ENCRYPT_KEY_SIZE(keysize) (((keysize - 6) & 0xF) << 12) + +/** @} */ // End of GATT_PERMS group + +typedef uint16_t esp_gatt_perm_t; ///< Type to represent GATT attribute permissions. + + + +/** + * @brief Defines GATT characteristic properties. + * + * These properties are related to `BTA_GATT_CHAR_PROP_BIT_xxx` in `bta/bta_gatt_api.h`. + */ + +/** @defgroup GATT_CHAR_PROPERTIES GATT Characteristic Properties + * These properties define various capabilities of a GATT characteristic. + * @{ + */ +/** @brief Ability to broadcast.Corresponds to BTA_GATT_CHAR_PROP_BIT_BROADCAST. */ +#define ESP_GATT_CHAR_PROP_BIT_BROADCAST (1 << 0) + +/** @brief Ability to read.Corresponds to BTA_GATT_CHAR_PROP_BIT_READ. */ +#define ESP_GATT_CHAR_PROP_BIT_READ (1 << 1) + +/** @brief Ability to write without response.Corresponds to BTA_GATT_CHAR_PROP_BIT_WRITE_NR. */ +#define ESP_GATT_CHAR_PROP_BIT_WRITE_NR (1 << 2) + +/** @brief Ability to write.Corresponds to BTA_GATT_CHAR_PROP_BIT_WRITE. */ +#define ESP_GATT_CHAR_PROP_BIT_WRITE (1 << 3) + +/** @brief Ability to notify.Corresponds to BTA_GATT_CHAR_PROP_BIT_NOTIFY. */ +#define ESP_GATT_CHAR_PROP_BIT_NOTIFY (1 << 4) + +/** @brief Ability to indicate.Corresponds to BTA_GATT_CHAR_PROP_BIT_INDICATE. */ +#define ESP_GATT_CHAR_PROP_BIT_INDICATE (1 << 5) + +/** @brief Ability to authenticate.Corresponds to BTA_GATT_CHAR_PROP_BIT_AUTH. */ +#define ESP_GATT_CHAR_PROP_BIT_AUTH (1 << 6) + +/** @brief Has extended properties.Corresponds to BTA_GATT_CHAR_PROP_BIT_EXT_PROP. */ +#define ESP_GATT_CHAR_PROP_BIT_EXT_PROP (1 << 7) + +/** @} */ // end of GATT_CHAR_PROPERTIES + /** - * @brief Attribute permissions + * @typedef esp_gatt_char_prop_t + * @brief Type for characteristic properties bitmask. */ -#define ESP_GATT_PERM_READ (1 << 0) /* bit 0 - 0x0001 */ /* relate to BTA_GATT_PERM_READ in bta/bta_gatt_api.h */ -#define ESP_GATT_PERM_READ_ENCRYPTED (1 << 1) /* bit 1 - 0x0002 */ /* relate to BTA_GATT_PERM_READ_ENCRYPTED in bta/bta_gatt_api.h */ -#define ESP_GATT_PERM_READ_ENC_MITM (1 << 2) /* bit 2 - 0x0004 */ /* relate to BTA_GATT_PERM_READ_ENC_MITM in bta/bta_gatt_api.h */ -#define ESP_GATT_PERM_WRITE (1 << 4) /* bit 4 - 0x0010 */ /* relate to BTA_GATT_PERM_WRITE in bta/bta_gatt_api.h */ -#define ESP_GATT_PERM_WRITE_ENCRYPTED (1 << 5) /* bit 5 - 0x0020 */ /* relate to BTA_GATT_PERM_WRITE_ENCRYPTED in bta/bta_gatt_api.h */ -#define ESP_GATT_PERM_WRITE_ENC_MITM (1 << 6) /* bit 6 - 0x0040 */ /* relate to BTA_GATT_PERM_WRITE_ENC_MITM in bta/bta_gatt_api.h */ -#define ESP_GATT_PERM_WRITE_SIGNED (1 << 7) /* bit 7 - 0x0080 */ /* relate to BTA_GATT_PERM_WRITE_SIGNED in bta/bta_gatt_api.h */ -#define ESP_GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 - 0x0100 */ /* relate to BTA_GATT_PERM_WRITE_SIGNED_MITM in bta/bta_gatt_api.h */ -#define ESP_GATT_PERM_READ_AUTHORIZATION (1 << 9) /* bit 9 - 0x0200 */ -#define ESP_GATT_PERM_WRITE_AUTHORIZATION (1 << 10) /* bit 10 - 0x0400 */ -#define ESP_GATT_PERM_ENCRYPT_KEY_SIZE(keysize) (((keysize - 6) & 0xF) << 12) /* bit 12:15 - 0xF000 */ -typedef uint16_t esp_gatt_perm_t; - -/* relate to BTA_GATT_CHAR_PROP_BIT_xxx in bta/bta_gatt_api.h */ -/* definition of characteristic properties */ -#define ESP_GATT_CHAR_PROP_BIT_BROADCAST (1 << 0) /* 0x01 */ /* relate to BTA_GATT_CHAR_PROP_BIT_BROADCAST in bta/bta_gatt_api.h */ -#define ESP_GATT_CHAR_PROP_BIT_READ (1 << 1) /* 0x02 */ /* relate to BTA_GATT_CHAR_PROP_BIT_READ in bta/bta_gatt_api.h */ -#define ESP_GATT_CHAR_PROP_BIT_WRITE_NR (1 << 2) /* 0x04 */ /* relate to BTA_GATT_CHAR_PROP_BIT_WRITE_NR in bta/bta_gatt_api.h */ -#define ESP_GATT_CHAR_PROP_BIT_WRITE (1 << 3) /* 0x08 */ /* relate to BTA_GATT_CHAR_PROP_BIT_WRITE in bta/bta_gatt_api.h */ -#define ESP_GATT_CHAR_PROP_BIT_NOTIFY (1 << 4) /* 0x10 */ /* relate to BTA_GATT_CHAR_PROP_BIT_NOTIFY in bta/bta_gatt_api.h */ -#define ESP_GATT_CHAR_PROP_BIT_INDICATE (1 << 5) /* 0x20 */ /* relate to BTA_GATT_CHAR_PROP_BIT_INDICATE in bta/bta_gatt_api.h */ -#define ESP_GATT_CHAR_PROP_BIT_AUTH (1 << 6) /* 0x40 */ /* relate to BTA_GATT_CHAR_PROP_BIT_AUTH in bta/bta_gatt_api.h */ -#define ESP_GATT_CHAR_PROP_BIT_EXT_PROP (1 << 7) /* 0x80 */ /* relate to BTA_GATT_CHAR_PROP_BIT_EXT_PROP in bta/bta_gatt_api.h */ typedef uint8_t esp_gatt_char_prop_t; -/// GATT maximum attribute length -#define ESP_GATT_MAX_ATTR_LEN 600 //as same as GATT_MAX_ATTR_LEN +/** + * @brief Defines the maximum length of a GATT attribute. + * + * This definition specifies the maximum number of bytes that a GATT attribute can hold. + */ +#define ESP_GATT_MAX_ATTR_LEN 512 /*!< As same as GATT_MAX_ATTR_LEN. */ + +/** + * @brief Enumerates the possible sources of a GATT service discovery. + * + * This enumeration identifies the source of a GATT service discovery process, + * indicating whether the service information was obtained from a remote device, + * from NVS (Non-Volatile Storage) flash, or the source is unknown. + */ typedef enum { - ESP_GATT_SERVICE_FROM_REMOTE_DEVICE = 0, /* relate to BTA_GATTC_SERVICE_INFO_FROM_REMOTE_DEVICE in bta_gattc_int.h */ - ESP_GATT_SERVICE_FROM_NVS_FLASH = 1, /* relate to BTA_GATTC_SERVICE_INFO_FROM_NVS_FLASH in bta_gattc_int.h */ - ESP_GATT_SERVICE_FROM_UNKNOWN = 2, /* relate to BTA_GATTC_SERVICE_INFO_FROM_UNKNOWN in bta_gattc_int.h */ + ESP_GATT_SERVICE_FROM_REMOTE_DEVICE = 0, /*!< Service information from a remote device. Relates to BTA_GATTC_SERVICE_INFO_FROM_REMOTE_DEVICE. */ + ESP_GATT_SERVICE_FROM_NVS_FLASH = 1, /*!< Service information from NVS flash. Relates to BTA_GATTC_SERVICE_INFO_FROM_NVS_FLASH. */ + ESP_GATT_SERVICE_FROM_UNKNOWN = 2, /*!< Service source is unknown. Relates to BTA_GATTC_SERVICE_INFO_FROM_UNKNOWN. */ } esp_service_source_t; + /** - * @brief Attribute description (used to create database) + * @brief Defines an attribute's description. + * + * This structure is used to describe an attribute in the GATT database. It includes + * details such as the UUID of the attribute, its permissions, and its value. */ - typedef struct - { - uint16_t uuid_length; /*!< UUID length */ - uint8_t *uuid_p; /*!< UUID value */ - uint16_t perm; /*!< Attribute permission */ - uint16_t max_length; /*!< Maximum length of the element*/ - uint16_t length; /*!< Current length of the element*/ - uint8_t *value; /*!< Element value array*/ - } esp_attr_desc_t; +typedef struct +{ + uint16_t uuid_length; /*!< Length of the UUID in bytes. */ + uint8_t *uuid_p; /*!< Pointer to the UUID value. */ + uint16_t perm; /*!< Attribute permissions, defined by esp_gatt_perm_t. */ + uint16_t max_length; /*!< Maximum length of the attribute's value. */ + uint16_t length; /*!< Current length of the attribute's value. */ + uint8_t *value; /*!< Pointer to the attribute's value array. */ +} esp_attr_desc_t; /** - * @brief attribute auto response flag + * @brief Defines attribute control for GATT operations. + * + * This module provides definitions for controlling attribute auto responses + * in GATT operations. + */ + +/** @brief Response to Write/Read operations should be handled by the application. */ +#define ESP_GATT_RSP_BY_APP 0 + +/** @brief Response to Write/Read operations should be automatically handled by the GATT stack. */ +#define ESP_GATT_AUTO_RSP 1 + +/** + * @brief Defines the auto response setting for attribute operations. + * + * This structure is used to control whether the GATT stack or the application + * will handle responses to Read/Write operations. */ typedef struct { -#define ESP_GATT_RSP_BY_APP 0 -#define ESP_GATT_AUTO_RSP 1 /** - * @brief if auto_rsp set to ESP_GATT_RSP_BY_APP, means the response of Write/Read operation will by replied by application. - if auto_rsp set to ESP_GATT_AUTO_RSP, means the response of Write/Read operation will be replied by GATT stack automatically. + * @brief Controls who handles the response to Read/Write operations. + * + * - If set to @c ESP_GATT_RSP_BY_APP, the application is responsible for + * generating the response. + * - If set to @c ESP_GATT_AUTO_RSP, the GATT stack will automatically generate + * the response. */ uint8_t auto_rsp; } esp_attr_control_t; + /** - * @brief attribute type added to the gatt server database + * @brief attribute type added to the GATT server database */ typedef struct { @@ -370,116 +585,103 @@ typedef struct uint16_t end_hdl; /*!< Gatt end handle value of included 128 bit service */ } esp_gatts_incl128_svc_desc_t; /*!< Gatt include 128 bit service entry element */ -/// Gatt attribute value +/** + * @brief Represents a GATT attribute's value. + */ typedef struct { - uint8_t value[ESP_GATT_MAX_ATTR_LEN]; /*!< Gatt attribute value */ - uint16_t handle; /*!< Gatt attribute handle */ - uint16_t offset; /*!< Gatt attribute value offset */ - uint16_t len; /*!< Gatt attribute value length */ - uint8_t auth_req; /*!< Gatt authentication request */ + uint8_t value[ESP_GATT_MAX_ATTR_LEN]; /*!< Array holding the value of the GATT attribute. */ + uint16_t handle; /*!< Unique identifier (handle) of the GATT attribute. */ + uint16_t offset; /*!< Offset within the attribute's value, for partial updates. */ + uint16_t len; /*!< Current length of the data in the value array. */ + uint8_t auth_req; /*!< Authentication requirements for accessing this attribute. */ } esp_gatt_value_t; -/// GATT remote read request response type +/** + * @brief Represents the response type for a GATT remote read request. + */ typedef union { - esp_gatt_value_t attr_value; /*!< Gatt attribute structure */ - uint16_t handle; /*!< Gatt attribute handle */ + esp_gatt_value_t attr_value; /*!< The GATT attribute value, including its data, handle, and metadata. */ + uint16_t handle; /*!< Only the handle of the GATT attribute, when that's the only required information. */ } esp_gatt_rsp_t; + /** - * @brief Gatt write type - */ + * @brief Defines the types of GATT write operations. + */ typedef enum { - ESP_GATT_WRITE_TYPE_NO_RSP = 1, /*!< Gatt write attribute need no response */ - ESP_GATT_WRITE_TYPE_RSP, /*!< Gatt write attribute need remote response */ + ESP_GATT_WRITE_TYPE_NO_RSP = 1, /*!< Write operation where no response is needed. */ + ESP_GATT_WRITE_TYPE_RSP = 2, /*!< Write operation that requires a remote response. */ } esp_gatt_write_type_t; -/** - * @brief Connection parameters information - */ + +/** @brief Connection parameters for GATT. */ typedef struct { - uint16_t interval; /*!< connection interval */ - uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */ - uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80. - Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec - Time Range: 100 msec to 32 seconds */ + uint16_t interval; /*!< Connection interval. */ + uint16_t latency; /*!< Slave latency for the connection in number of connection events. */ + uint16_t timeout; /*!< Supervision timeout for the LE Link. */ } esp_gatt_conn_params_t; -#define ESP_GATT_IF_NONE 0xff /*!< If callback report gattc_if/gatts_if as this macro, means this event is not correspond to any app */ +/** @brief Macro indicating no specific GATT interface. */ +#define ESP_GATT_IF_NONE 0xff /*!< No specific application GATT interface. */ -typedef uint8_t esp_gatt_if_t; /*!< Gatt interface type, different application on GATT client use different gatt_if */ +/** @brief GATT interface type for client applications. */ +typedef uint8_t esp_gatt_if_t; -/** - * @brief the type of attribute element - */ +/** @brief Enumerates types of GATT database attributes. */ typedef enum { - ESP_GATT_DB_PRIMARY_SERVICE, /*!< Gattc primary service attribute type in the cache */ - ESP_GATT_DB_SECONDARY_SERVICE, /*!< Gattc secondary service attribute type in the cache */ - ESP_GATT_DB_CHARACTERISTIC, /*!< Gattc characteristic attribute type in the cache */ - ESP_GATT_DB_DESCRIPTOR, /*!< Gattc characteristic descriptor attribute type in the cache */ - ESP_GATT_DB_INCLUDED_SERVICE, /*!< Gattc include service attribute type in the cache */ - ESP_GATT_DB_ALL, /*!< Gattc all the attribute (primary service & secondary service & include service & char & descriptor) type in the cache */ -} esp_gatt_db_attr_type_t; /*!< Gattc attribute type element */ - -/** - * @brief read multiple attribute - */ + ESP_GATT_DB_PRIMARY_SERVICE, /*!< Primary service attribute. */ + ESP_GATT_DB_SECONDARY_SERVICE, /*!< Secondary service attribute. */ + ESP_GATT_DB_CHARACTERISTIC, /*!< Characteristic attribute. */ + ESP_GATT_DB_DESCRIPTOR, /*!< Descriptor attribute. */ + ESP_GATT_DB_INCLUDED_SERVICE, /*!< Included service attribute. */ + ESP_GATT_DB_ALL, /*!< All attribute types. */ +} esp_gatt_db_attr_type_t; + +/** @brief Represents multiple attributes for reading. */ typedef struct { - uint8_t num_attr; /*!< The number of the attribute */ - uint16_t handles[ESP_GATT_MAX_READ_MULTI_HANDLES]; /*!< The handles list */ -} esp_gattc_multi_t; /*!< The gattc multiple read element */ + uint8_t num_attr; /*!< Number of attributes. */ + uint16_t handles[ESP_GATT_MAX_READ_MULTI_HANDLES]; /*!< List of attribute handles. */ +} esp_gattc_multi_t; -/** - * @brief data base attribute element - */ +/** @brief GATT database attribute element. */ typedef struct { - esp_gatt_db_attr_type_t type; /*!< The attribute type */ - uint16_t attribute_handle; /*!< The attribute handle, it's valid for all of the type */ - uint16_t start_handle; /*!< The service start handle, it's valid only when the type = ESP_GATT_DB_PRIMARY_SERVICE or ESP_GATT_DB_SECONDARY_SERVICE */ - uint16_t end_handle; /*!< The service end handle, it's valid only when the type = ESP_GATT_DB_PRIMARY_SERVICE or ESP_GATT_DB_SECONDARY_SERVICE */ - esp_gatt_char_prop_t properties; /*!< The characteristic properties, it's valid only when the type = ESP_GATT_DB_CHARACTERISTIC */ - esp_bt_uuid_t uuid; /*!< The attribute uuid, it's valid for all of the type */ -} esp_gattc_db_elem_t; /*!< The gattc service data base element in the cache */ - -/** - * @brief service element - */ + esp_gatt_db_attr_type_t type; /*!< Attribute type. */ + uint16_t attribute_handle; /*!< Attribute handle. */ + uint16_t start_handle; /*!< Service start handle. */ + uint16_t end_handle; /*!< Service end handle. */ + esp_gatt_char_prop_t properties; /*!< Characteristic properties. */ + esp_bt_uuid_t uuid; /*!< Attribute UUID. */ +} esp_gattc_db_elem_t; + +/** @brief Represents a GATT service element. */ typedef struct { - bool is_primary; /*!< The service flag, true if the service is primary service, else is secondary service */ - uint16_t start_handle; /*!< The start handle of the service */ - uint16_t end_handle; /*!< The end handle of the service */ - esp_bt_uuid_t uuid; /*!< The uuid of the service */ -} esp_gattc_service_elem_t; /*!< The gattc service element */ + bool is_primary; /*!< Indicates if the service is primary. */ + uint16_t start_handle; /*!< Service start handle. */ + uint16_t end_handle; /*!< Service end handle. */ + esp_bt_uuid_t uuid; /*!< Service UUID. */ +} esp_gattc_service_elem_t; -/** - * @brief characteristic element - */ +/** @brief Represents a GATT characteristic element. */ typedef struct { - uint16_t char_handle; /*!< The characteristic handle */ - esp_gatt_char_prop_t properties; /*!< The characteristic properties */ - esp_bt_uuid_t uuid; /*!< The characteristic uuid */ -} esp_gattc_char_elem_t; /*!< The gattc characteristic element */ + uint16_t char_handle; /*!< Characteristic handle. */ + esp_gatt_char_prop_t properties; /*!< Characteristic properties. */ + esp_bt_uuid_t uuid; /*!< Characteristic UUID. */ +} esp_gattc_char_elem_t; -/** - * @brief descriptor element - */ +/** @brief Represents a GATT descriptor element. */ typedef struct { - uint16_t handle; /*!< The characteristic descriptor handle */ - esp_bt_uuid_t uuid; /*!< The characteristic descriptor uuid */ -} esp_gattc_descr_elem_t; /*!< The gattc descriptor type element */ + uint16_t handle; /*!< Descriptor handle. */ + esp_bt_uuid_t uuid; /*!< Descriptor UUID. */ +} esp_gattc_descr_elem_t; -/** - * @brief include service element - */ +/** @brief Represents an included GATT service element. */ typedef struct { - uint16_t handle; /*!< The include service current attribute handle */ - uint16_t incl_srvc_s_handle; /*!< The start handle of the service which has been included */ - uint16_t incl_srvc_e_handle; /*!< The end handle of the service which has been included */ - esp_bt_uuid_t uuid; /*!< The include service uuid */ -} esp_gattc_incl_svc_elem_t; /*!< The gattc include service element */ - + uint16_t handle; /*!< Current attribute handle of the included service. */ + uint16_t incl_srvc_s_handle; /*!< Start handle of the included service. */ + uint16_t incl_srvc_e_handle; /*!< End handle of the included service. */ + esp_bt_uuid_t uuid; /*!< Included service UUID. */ +} esp_gattc_incl_svc_elem_t; #ifdef __cplusplus } #endif - -#endif /* __ESP_GATT_DEFS_H__ */ diff --git a/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h b/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h index 2e179671f5..0c274e2032 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gattc_api.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -60,6 +60,7 @@ typedef enum { ESP_GATTC_SET_ASSOC_EVT = 44, /*!< When the ble gattc set the associated address complete, the event comes */ ESP_GATTC_GET_ADDR_LIST_EVT = 45, /*!< When the ble get gattc address list in cache finish, the event comes */ ESP_GATTC_DIS_SRVC_CMPL_EVT = 46, /*!< When the ble discover service complete, the event comes */ + ESP_GATTC_READ_MULTI_VAR_EVT = 47, /*!< When read multiple variable characteristic complete, the event comes */ } esp_gattc_cb_event_t; @@ -125,7 +126,7 @@ typedef union { } search_res; /*!< Gatt client callback param of ESP_GATTC_SEARCH_RES_EVT */ /** - * @brief ESP_GATTC_READ_CHAR_EVT, ESP_GATTC_READ_DESCR_EVT + * @brief ESP_GATTC_READ_CHAR_EVT, ESP_GATTC_READ_DESCR_EVT, ESP_GATTC_READ_MULTIPLE_EVT, ESP_GATTC_READ_MULTI_VAR_EVT */ struct gattc_read_char_evt_param { @@ -272,6 +273,15 @@ typedef void (* esp_gattc_cb_t)(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_ */ esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback); +/** + * @brief This function is called to get the current application callbacks + * with BTA GATTC module. + * + * @return + * - esp_gattC_cb_t : current callback + * + */ +esp_gattc_cb_t esp_ble_gattc_get_callback(void); /** * @brief This function is called to register application callbacks @@ -289,10 +299,14 @@ esp_err_t esp_ble_gattc_app_register(uint16_t app_id); /** * @brief This function is called to unregister an application - * from GATTC module. + * from the GATTC module. * * @param[in] gattc_if: Gatt client access interface. * + * @note Before calling this API, ensure that all activities + * related to the application, such as connections, scans, ADV, + * are properly closed. + * * @return * - ESP_OK: success * - other: failed @@ -358,6 +372,7 @@ esp_err_t esp_ble_gattc_send_mtu_req (esp_gatt_if_t gattc_if, uint16_t conn_id); * @brief This function is called to get service from local cache. * This function report service search result by a callback * event, and followed by a service search complete event. + * Note: 128-bit base UUID will automatically be converted to a 16-bit UUID in the search results. Other types of UUID remain unchanged. * * @param[in] gattc_if: Gatt client access interface. * @param[in] conn_id: connection ID. @@ -597,7 +612,7 @@ esp_gatt_status_t esp_ble_gattc_get_db(esp_gatt_if_t gattc_if, uint16_t conn_id, * * @param[in] gattc_if: Gatt client access interface. * @param[in] conn_id : connection ID. - * @param[in] handle : characteritic handle to read. + * @param[in] handle : characteristic handle to read. * @param[in] auth_req : authenticate request type * * @return @@ -651,6 +666,23 @@ esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_gattc_multi_t *read_multi, esp_gatt_auth_req_t auth_req); +/** + * @brief This function is called to read multiple variable length characteristic or + * characteristic descriptors. + * + * @param[in] gattc_if: Gatt client access interface. + * @param[in] conn_id : connection ID. + * @param[in] read_multi : pointer to the read multiple parameter. + * @param[in] auth_req : authenticate request type + * + * @return + * - ESP_OK: success + * - other: failed + * + */ +esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if, + uint16_t conn_id, esp_gattc_multi_t *read_multi, + esp_gatt_auth_req_t auth_req); /** * @brief This function is called to read a characteristics descriptor. diff --git a/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h b/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h index 1fb3a08141..0eb7ddd98b 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gatts_api.h @@ -295,6 +295,16 @@ typedef void (* esp_gatts_cb_t)(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_ */ esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback); +/** + * @brief This function is called to get the current application callbacks + * with BTA GATTS module. + * + * @return + * - esp_gatts_cb_t : current callback + * + */ +esp_gatts_cb_t esp_ble_gatts_get_callback(void); + /** * @brief This function is called to register application identifier * @@ -464,6 +474,7 @@ esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle); /** * @brief Send indicate or notify to GATT client. * Set param need_confirm as false will send notification, otherwise indication. + * Note: the size of indicate or notify data need less than MTU size,see "esp_ble_gattc_send_mtu_req". * * @param[in] gatts_if: GATT server access interface * @param[in] conn_id - connection id to indicate. @@ -572,6 +583,16 @@ esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id); */ esp_err_t esp_ble_gatts_send_service_change_indication(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda); +/** + * @brief Print local database (GATT service table) + * + * @return + * - ESP_OK : success + * - other : failed + * + */ +esp_err_t esp_ble_gatts_show_local_database(void); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h b/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h index adac556529..84086118f3 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.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 */ @@ -62,13 +62,22 @@ typedef enum ESP_HF_DIAL_EVT, /*!< Origin an outgoing call with specific number or the dial the last number */ ESP_HF_WBS_RESPONSE_EVT, /*!< Codec Status */ ESP_HF_BCS_RESPONSE_EVT, /*!< Final Codec Choice */ + ESP_HF_PKT_STAT_NUMS_GET_EVT, /*!< Request number of packet different status */ } esp_hf_cb_event_t; +/// Dial type of ESP_HF_DIAL_EVT +typedef enum +{ + ESP_HF_DIAL_NUM = 0, /*!< Dial with a phone number */ + ESP_HF_DIAL_VOIP, /*!< Dial with VoIP */ + ESP_HF_DIAL_MEM, /*!< Dial with a memory position */ +} esp_hf_dial_type_t; + /// HFP AG callback parameters typedef union { /** - * @brief ESP_HS_CONNECTION_STATE_EVT + * @brief ESP_HF_CONNECTION_STATE_EVT */ struct hf_conn_stat_param { esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */ @@ -83,6 +92,7 @@ typedef union struct hf_audio_stat_param { esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ esp_hf_audio_state_t state; /*!< Audio connection state */ + uint16_t sync_conn_handle; /*!< (e)SCO connection handle */ } audio_stat; /*!< AG callback param of ESP_HF_AUDIO_STATE_EVT */ /** @@ -97,6 +107,7 @@ typedef union * @brief ESP_HF_VOLUME_CONTROL_EVT */ struct hf_volume_control_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ esp_hf_volume_type_t type; /*!< Volume control target, speaker or microphone */ int volume; /*!< Gain, ranges from 0 to 15 */ } volume_control; /*!< AG callback param of ESP_HF_VOLUME_CONTROL_EVT */ @@ -105,48 +116,89 @@ typedef union * @brief ESP_HF_UNAT_RESPONSE_EVT */ struct hf_unat_rep_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ char *unat; /*!< Unknown AT command string */ - }unat_rep; /*!< AG callback param of ESP_HF_UNAT_RESPONSE_EVT */ - - /** - * @brief ESP_HF_CIND_RESPONSE_EVT - */ - struct hf_cind_param { - esp_hf_call_status_t call_status; /*!< call status indicator */ - esp_hf_call_setup_status_t call_setup_status; /*!< call setup status indicator */ - esp_hf_network_state_t svc; /*!< bluetooth proprietary call hold status indicator */ - int signal_strength; /*!< bluetooth proprietary call hold status indicator */ - esp_hf_roaming_status_t roam; /*!< bluetooth proprietary call hold status indicator */ - int battery_level; /*!< battery charge value, ranges from 0 to 5 */ - esp_hf_call_held_status_t call_held_status; /*!< bluetooth proprietary call hold status indicator */ - } cind; /*!< AG callback param of ESP_HF_CIND_RESPONSE_EVT */ + } unat_rep; /*!< AG callback param of ESP_HF_UNAT_RESPONSE_EVT */ /** * @brief ESP_HF_DIAL_EVT */ struct hf_out_call_param { esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + esp_hf_dial_type_t type; /*!< dial type */ char *num_or_loc; /*!< location in phone memory */ } out_call; /*!< AG callback param of ESP_HF_DIAL_EVT */ + /** + * @brief ESP_HF_IND_UPDATE_EVT + */ + struct hf_ind_upd_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } ind_upd; /*!< AG callback param of ESP_HF_IND_UPDATE_EVT */ + + /** + * @brief ESP_HF_CIND_RESPONSE_EVT + */ + struct hf_cind_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } cind_rep; /*!< AG callback param of ESP_HF_CIND_RESPONSE_EVT */ + + /** + * @brief ESP_HF_COPS_RESPONSE_EVT + */ + struct hf_cops_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } cops_rep; /*!< AG callback param of ESP_HF_COPS_RESPONSE_EVT */ + + /** + * @brief ESP_HF_CLCC_RESPONSE_EVT + */ + struct hf_clcc_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } clcc_rep; /*!< AG callback param of ESP_HF_CLCC_RESPONSE_EVT */ + + /** + * @brief ESP_HF_CNUM_RESPONSE_EVT + */ + struct hf_cnum_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } cnum_rep; /*!< AG callback param of ESP_HF_CNUM_RESPONSE_EVT */ + /** * @brief ESP_HF_VTS_RESPONSE_EVT */ struct hf_vts_rep_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ char *code; /*!< MTF code from HF Client */ - }vts_rep; /*!< AG callback param of ESP_HF_VTS_RESPONSE_EVT */ + } vts_rep; /*!< AG callback param of ESP_HF_VTS_RESPONSE_EVT */ /** * @brief ESP_HF_NREC_RESPONSE_EVT */ struct hf_nrec_param { - esp_hf_nrec_t state; /*!< NREC enabled or disabled */ + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ + esp_hf_nrec_t state; /*!< NREC enabled or disabled */ } nrec; /*!< AG callback param of ESP_HF_NREC_RESPONSE_EVT */ + /** + * @brief ESP_HF_ATA_RESPONSE_EVT + */ + struct hf_ata_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } ata_rep; /*!< AG callback param of ESP_HF_ATA_RESPONSE_EVT */ + + /** + * @brief ESP_HF_CHUP_RESPONSE_EVT + */ + struct hf_chup_rep_param { + esp_bd_addr_t remote_addr; /*!< remote bluetooth device address */ + } chup_rep; /*!< AG callback param of ESP_HF_CHUP_RESPONSE_EVT */ + /** * @brief ESP_HF_WBS_RESPONSE_EVT */ struct hf_wbs_rep_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ esp_hf_wbs_config_t codec; /*!< codec mode CVSD or mSBC */ } wbs_rep; /*!< AG callback param of ESP_HF_WBS_RESPONSE_EVT */ @@ -154,9 +206,23 @@ typedef union * @brief ESP_HF_BCS_RESPONSE_EVT */ struct hf_bcs_rep_param { + esp_bd_addr_t remote_addr; /*!< Remote bluetooth device address */ esp_hf_wbs_config_t mode; /*!< codec mode CVSD or mSBC */ } bcs_rep; /*!< AG callback param of ESP_HF_BCS_RESPONSE_EVT */ + /** + * @brief ESP_HF_PKT_STAT_NUMS_GET_EVT + */ + struct ag_pkt_status_nums { + uint32_t rx_total; /*!< the total number of packets received */ + uint32_t rx_correct; /*!< the total number of packets data correctly received */ + uint32_t rx_err; /*!< the total number of packets data with possible invalid */ + uint32_t rx_none; /*!< the total number of packets data no received */ + uint32_t rx_lost; /*!< the total number of packets data partially lost */ + uint32_t tx_total; /*!< the total number of packets send */ + uint32_t tx_discarded; /*!< the total number of packets send lost */ + } pkt_nums; /*!< AG callback param of ESP_HF_PKT_STAT_NUMS_GET_EVT */ + } esp_hf_cb_param_t; /*!< HFP AG callback param compound*/ /** @@ -208,7 +274,7 @@ typedef void (* esp_hf_cb_t) (esp_hf_cb_event_t event, esp_hf_cb_param_t *param) * * @return * - ESP_OK: success - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: if callback is a NULL function pointer * */ @@ -221,7 +287,7 @@ esp_err_t esp_hf_ag_register_callback(esp_hf_cb_t callback); * * @return * - ESP_OK: if the initialization request is sent successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -234,7 +300,7 @@ esp_err_t esp_hf_ag_init(void); * * @return * - ESP_OK: success - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -249,7 +315,7 @@ esp_err_t esp_hf_ag_deinit(void); * * @return * - ESP_OK: connect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -264,7 +330,7 @@ esp_err_t esp_hf_ag_slc_connect(esp_bd_addr_t remote_bda); * * @return * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -278,8 +344,8 @@ esp_err_t esp_hf_ag_slc_disconnect(esp_bd_addr_t remote_bda); * @param[in] remote_bda: remote bluetooth device address * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: audio connect request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -293,8 +359,8 @@ esp_err_t esp_hf_ag_audio_connect(esp_bd_addr_t remote_bda); * @param[in] remote_bda: remote bluetooth device address * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: audio disconnect request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -310,8 +376,8 @@ esp_err_t esp_hf_ag_audio_disconnect(esp_bd_addr_t remote_bda); * @param[in] value: 0 - voice recognition disabled, 1- voice recognition enabled * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: response of volume recognition is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -329,14 +395,15 @@ esp_err_t esp_hf_ag_vra_control(esp_bd_addr_t remote_bda, esp_hf_vr_state_t valu * @param[in] volume: gain of the speaker of microphone, ranges 0 to 15 * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: volume synchronization control is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if arguments are invalid * - ESP_FAIL: others * */ esp_err_t esp_hf_ag_volume_control(esp_bd_addr_t remote_bda, esp_hf_volume_control_target_t type, int volume); - /** +/** * * @brief Handle Unknown AT command from HFP Client. * As a precondition to use this API, Service Level Connection shall exist with HFP client. @@ -346,14 +413,14 @@ esp_err_t esp_hf_ag_volume_control(esp_bd_addr_t remote_bda, esp_hf_volume_contr * @param[in] unat: User AT command response to HF Client. * It will response "ERROR" by default if unat is NULL. * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: response of unknown AT command is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ esp_err_t esp_hf_ag_unknown_at_send(esp_bd_addr_t remote_addr, char *unat); - /** +/** * * @brief Unsolicited send extend AT error code to HFP Client. * As a precondition to use this API, Service Level Connection shall exist with HFP client. @@ -362,14 +429,14 @@ esp_err_t esp_hf_ag_unknown_at_send(esp_bd_addr_t remote_addr, char *unat); * @param[in] response_code: AT command response code * @param[in] error_code: CME error code * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: extend error code is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ esp_err_t esp_hf_ag_cmee_send(esp_bd_addr_t remote_bda, esp_hf_at_response_code_t response_code, esp_hf_cme_err_t error_code); - /** +/** * * @brief Unsolicited send device status notification to HFP Client. * As a precondition to use this API, Service Level Connection shall exist with HFP client. @@ -380,16 +447,36 @@ esp_err_t esp_hf_ag_cmee_send(esp_bd_addr_t remote_bda, esp_hf_at_response_code_ * @param[in] ntk_state: network service state * @param[in] signal: signal strength from 0 to 5 * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: device status notification is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if arguments are invalid * - ESP_FAIL: others * */ esp_err_t esp_hf_ag_devices_status_indchange(esp_bd_addr_t remote_addr, esp_hf_call_status_t call_state, - esp_hf_call_setup_status_t call_setup_state, - esp_hf_network_state_t ntk_state, int signal); + esp_hf_call_setup_status_t call_setup_state, + esp_hf_network_state_t ntk_state, int signal) __attribute__(( + deprecated("Please use esp_hf_ag_ciev_report") + )); + +/** + * + * @brief Send indicator report "+CIEV: " to HFP Client. "CIEV" means “indicator events reporting", + * and all indicator types can be sent one type at a time. + * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * + * @param[in] remote_addr: remote bluetooth device address + * @param[in] ind_type: indicator type + * @param[in] value: indicator value + * @return + * - ESP_OK: indicator report is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_ciev_report(esp_bd_addr_t remote_addr, esp_hf_ciev_report_type_t ind_type, int value); - /** +/** * * @brief Response to device individual indicators to HFP Client. * As a precondition to use this API, Service Level Connection shall exist with HFP client. @@ -403,8 +490,9 @@ esp_err_t esp_hf_ag_devices_status_indchange(esp_bd_addr_t remote_addr, esp_hf_c * @param[in] batt_lev: battery level from 0 to 5 * @param[in] call_held_status: call held status * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: response to device individual indicators is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if the arguments are invalid * - ESP_FAIL: others * */ @@ -422,8 +510,8 @@ esp_err_t esp_hf_ag_cind_response(esp_bd_addr_t remote_addr, * @param[in] remote_addr: remote bluetooth device address * @param[in] name: current operator name * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: reponse for AT+COPS command is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -435,7 +523,7 @@ esp_err_t esp_hf_ag_cops_response(esp_bd_addr_t remote_addr, char *name); * As a precondition to use this API, Service Level Connection shall exist with HFP client. * * @param[in] remote_addr: remote bluetooth device address - * @param[in] index: the index of current call + * @param[in] index: the index of current call, starting with 1, finishing response with 0 (send OK) * @param[in] dir: call direction (incoming/outgoing) * @param[in] current_call_state: current call state * @param[in] mode: current call mode (voice/data/fax) @@ -443,8 +531,8 @@ esp_err_t esp_hf_ag_cops_response(esp_bd_addr_t remote_addr, char *name); * @param[in] number: current call number * @param[in] type: international type or unknow * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: response to AT+CLCC command is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -459,14 +547,18 @@ esp_err_t esp_hf_ag_clcc_response(esp_bd_addr_t remote_addr, int index, esp_hf_c * * @param[in] remote_addr: remote bluetooth device address * @param[in] number: registration number - * @param[in] type: service type (unknown/voice/fax) + * @param[in] number_type: value of number type from + * 128-143: national or international, may contain prefix and/or escape digits + * 144-159: international, includes country code prefix, add "+" if needed + * 160-175: national, but no prefix nor escape digits + * @param[in] service_type: service type (unknown/voice/fax) * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: response for AT+CNUM command is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ -esp_err_t esp_hf_ag_cnum_response(esp_bd_addr_t remote_addr, char *number, esp_hf_subscriber_service_type_t type); +esp_err_t esp_hf_ag_cnum_response(esp_bd_addr_t remote_addr, char *number, int number_type, esp_hf_subscriber_service_type_t service_type); /** * @@ -476,8 +568,9 @@ esp_err_t esp_hf_ag_cnum_response(esp_bd_addr_t remote_addr, char *number, esp_h * @param[in] remote_addr: remote bluetooth device address * @param[in] state: in-band ring tone state * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: information of in-band ring tone is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_ARG: if arguments are invalid * - ESP_FAIL: others * */ @@ -496,8 +589,8 @@ esp_err_t esp_hf_ag_bsir(esp_bd_addr_t remote_addr, esp_hf_in_band_ring_state_t * @param[in] number: number of the incoming call * @param[in] call_addr_type: call address type * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: answer incoming call is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -518,8 +611,8 @@ esp_err_t esp_hf_ag_answer_call(esp_bd_addr_t remote_addr, int num_active, int n * @param[in] number: number of the incoming call * @param[in] call_addr_type: call address type * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: reject incoming call is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -531,6 +624,9 @@ esp_err_t esp_hf_ag_reject_call(esp_bd_addr_t remote_addr, int num_active, int n * * @brief Initiate a call from AG. * As a precondition to use this API, Service Level Connection shall exist with HFP client. + * If the AG is driven by the HF to call esp_hf_ag_out_call, it needs to response an OK or ERROR + * to HF. But if the AG is actively calling esp_hf_ag_out_call, it does not need to take a response + * to HF. * * @param[in] remote_addr: remote bluetooth device address * @param[in] num_active: the number of active call @@ -540,8 +636,8 @@ esp_err_t esp_hf_ag_reject_call(esp_bd_addr_t remote_addr, int num_active, int n * @param[in] number: number of the outgoing call * @param[in] call_addr_type: call address type * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: a call initiation is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -562,8 +658,8 @@ esp_err_t esp_hf_ag_out_call(esp_bd_addr_t remote_addr, int num_active, int num_ * @param[in] number: number of the call * @param[in] call_addr_type: call address type * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: end an ongoing call is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -580,12 +676,28 @@ esp_err_t esp_hf_ag_end_call(esp_bd_addr_t remote_addr, int num_active, int num_ * * @return * - ESP_OK: success - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: if callback is a NULL function pointer * */ esp_err_t esp_hf_ag_register_data_callback(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send); +/** + * + * @brief Get the number of packets received and sent + * + * This function is only used in the case that Voice Over HCI is enabled and the audio state is connected. + * When the operation is completed, the callback function will be called with ESP_HF_PKT_STAT_NUMS_GET_EVT. + * + * @param[in] sync_conn_handle: the (e)SCO connection handle + * + * @return + * - ESP_OK: if the request is sent successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_ag_pkt_stat_nums_get(uint16_t sync_conn_handle); /** * @brief Trigger the lower-layer to fetch and send audio data. diff --git a/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h b/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h index 449941fba7..9353fc032b 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.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 */ @@ -96,6 +96,7 @@ typedef enum { ESP_HF_CLIENT_BSIR_EVT, /*!< setting of in-band ring tone */ ESP_HF_CLIENT_BINP_EVT, /*!< requested number of last voice tag from AG */ ESP_HF_CLIENT_RING_IND_EVT, /*!< ring indication event */ + ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT, /*!< requested number of packet different status */ } esp_hf_client_cb_event_t; /// HFP client callback parameters @@ -116,6 +117,7 @@ typedef union { struct hf_client_audio_stat_param { esp_hf_client_audio_state_t state; /*!< audio connection state */ esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */ + uint16_t sync_conn_handle; /*!< (e)SCO connection handle */ } audio_stat; /*!< HF callback param of ESP_HF_CLIENT_AUDIO_STATE_EVT */ /** @@ -251,6 +253,19 @@ typedef union { const char *number; /*!< phone number corresponding to the last voice tag in the HF */ } binp; /*!< HF callback param of ESP_HF_CLIENT_BINP_EVT */ + /** + * @brief ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT + */ + struct hf_client_pkt_status_nums { + uint32_t rx_total; /*!< the total number of packets received */ + uint32_t rx_correct; /*!< the total number of packets data correctly received */ + uint32_t rx_err; /*!< the total number of packets data with possible invalid */ + uint32_t rx_none; /*!< the total number of packets data no received */ + uint32_t rx_lost; /*!< the total number of packets data partially lost */ + uint32_t tx_total; /*!< the total number of packets send */ + uint32_t tx_discarded; /*!< the total number of packets send lost */ + } pkt_nums; /*!< HF callback param of ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT */ + } esp_hf_client_cb_param_t; /*!< HFP client callback parameters */ /** @@ -298,7 +313,7 @@ typedef void (* esp_hf_client_cb_t)(esp_hf_client_cb_event_t event, esp_hf_clien * * @return * - ESP_OK: success - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: if callback is a NULL function pointer * */ @@ -311,7 +326,7 @@ esp_err_t esp_hf_client_register_callback(esp_hf_client_cb_t callback); * * @return * - ESP_OK: if the initialization request is sent successfully - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -324,7 +339,7 @@ esp_err_t esp_hf_client_init(void); * * @return * - ESP_OK: success - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -339,7 +354,7 @@ esp_err_t esp_hf_client_deinit(void); * * @return * - ESP_OK: connect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -354,7 +369,7 @@ esp_err_t esp_hf_client_connect(esp_bd_addr_t remote_bda); * * @return * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -367,8 +382,8 @@ esp_err_t esp_hf_client_disconnect(esp_bd_addr_t remote_bda); * * @param[in] remote_bda: remote bluetooth device address * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: connect audio request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -381,8 +396,8 @@ esp_err_t esp_hf_client_connect_audio(esp_bd_addr_t remote_bda); * * @param[in] remote_bda: remote bluetooth device address * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: disconnect audio request is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -394,8 +409,8 @@ esp_err_t esp_hf_client_disconnect_audio(esp_bd_addr_t remote_bda); * As a precondition to use this API, Service Level Connection shall exist with AG. * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: starting voice recognition is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -407,8 +422,8 @@ esp_err_t esp_hf_client_start_voice_recognition(void); * As a precondition to use this API, Service Level Connection shall exist with AG. * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: stoping voice recognition is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -423,8 +438,8 @@ esp_err_t esp_hf_client_stop_voice_recognition(void); * @param[in] volume: gain of the speaker of microphone, ranges 0 to 15 * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: volume update is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -438,8 +453,8 @@ esp_err_t esp_hf_client_volume_update(esp_hf_volume_control_target_t type, int v * @param[in] number: number string of the call. If NULL, the last number is called(aka re-dial) * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: a call placing is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -453,8 +468,8 @@ esp_err_t esp_hf_client_dial(const char *number); * @param[in] location: location of the number in the memory * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: a memory call placing is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -471,8 +486,8 @@ esp_err_t esp_hf_client_dial_memory(int location); * ESP_HF_CHLD_TYPE_REL_X or ESP_HF_CHLD_TYPE_PRIV_X * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: command AT+CHLD is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -486,8 +501,8 @@ esp_err_t esp_hf_client_send_chld_cmd(esp_hf_chld_type_t chld, int idx); * @param[in] btrh: response and hold action to send * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: command AT+BTRH is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -499,8 +514,8 @@ esp_err_t esp_hf_client_send_btrh_cmd(esp_hf_btrh_cmd_t btrh); * As a precondition to use this API, Service Level Connection shall exist with AG. * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: a call answering is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -508,12 +523,12 @@ esp_err_t esp_hf_client_answer_call(void); /** * - * @brief Reject an incoming call(send AT+CHUP command). + * @brief Reject an incoming call or terminate an ongoing call(send AT+CHUP command). * As a precondition to use this API, Service Level Connection shall exist with AG. * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: the call rejecting is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -525,8 +540,8 @@ esp_err_t esp_hf_client_reject_call(void); * As a precondition to use this API, Service Level Connection shall exist with AG. * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: query of current calls is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -538,8 +553,8 @@ esp_err_t esp_hf_client_query_current_calls(void); * As a precondition to use this API, Service Level Connection shall exist with AG. * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: query of current operator name is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -551,8 +566,8 @@ esp_err_t esp_hf_client_query_current_operator_name(void); * As a precondition to use this API, Service Level Connection shall exist with AG * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: the retrieving of subscriber information is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -566,8 +581,8 @@ esp_err_t esp_hf_client_retrieve_subscriber_info(void); * @param[in] code: dtmf code, single ascii character in the set 0-9, #, *, A-D * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: the DTMF codes are sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -587,7 +602,7 @@ esp_err_t esp_hf_client_send_dtmf(char code); * * @return * - ESP_OK: Feature enable request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -605,7 +620,7 @@ esp_err_t esp_hf_client_send_xapl(char *information, uint32_t features); * * @return * - ESP_OK: battery level is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -617,8 +632,8 @@ esp_err_t esp_hf_client_send_iphoneaccev(uint32_t bat_level, bool docked); * As a precondition to use this API, Service Level Connection shall exist with AG. * * @return - * - ESP_OK: disconnect request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_OK: the phone number request corresponding to last voice tag recorded is sent to lower layer + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -631,7 +646,7 @@ esp_err_t esp_hf_client_request_last_voice_tag_number(void); * * @return * - ESP_OK: NREC=0 request is sent to lower layer - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: others * */ @@ -648,13 +663,29 @@ esp_err_t esp_hf_client_send_nrec(void); * * @return * - ESP_OK: success - * - ESP_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled * - ESP_FAIL: if callback is a NULL function pointer * */ esp_err_t esp_hf_client_register_data_callback(esp_hf_client_incoming_data_cb_t recv, esp_hf_client_outgoing_data_cb_t send); +/** + * + * @brief Get the number of packets received and sent + * This function is only used in the case that Voice Over HCI is enabled and the audio state is connected. + * When the operation is completed, the callback function will be called with ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT. + * + * @param[in] sync_conn_handle: the (e)SCO connection handle + * + * @return + * - ESP_OK: if the request is sent successfully + * - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled + * - ESP_FAIL: others + * + */ +esp_err_t esp_hf_client_pkt_stat_nums_get(uint16_t sync_conn_handle); + /** * @brief Trigger the lower-layer to fetch and send audio data. * This function is only only used in the case that Voice Over HCI is enabled. After this diff --git a/components/bt/host/bluedroid/api/include/api/esp_hf_defs.h b/components/bt/host/bluedroid/api/include/api/esp_hf_defs.h index 114d60e2cd..b7671ff1e7 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hf_defs.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hf_defs.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 */ @@ -51,6 +51,17 @@ typedef enum ESP_HF_NETWORK_STATE_AVAILABLE } esp_hf_network_state_t; +/// +CIEV report type +typedef enum { + ESP_HF_IND_TYPE_CALL = 1, /*!< position of call indicator */ + ESP_HF_IND_TYPE_CALLSETUP, /*!< position of callsetup indicator */ + ESP_HF_IND_TYPE_SERVICE, /*!< position of service indicator */ + ESP_HF_IND_TYPE_SIGNAL, /*!< position of signal strength indicator, range: 0-5 */ + ESP_HF_IND_TYPE_ROAM, /*!< position of roaming indicator */ + ESP_HF_IND_TYPE_BATTCHG, /*!< position of battery charge indicator, range: 0-5 */ + ESP_HF_IND_TYPE_CALLHELD /*!< position of callheld indicator */ +} esp_hf_ciev_report_type_t; + /** +CIEV Service type */ typedef enum { @@ -60,7 +71,7 @@ typedef enum /// +CIND call status indicator values typedef enum { - ESP_HF_CALL_STATUS_NO_CALLS = 0, /*!< no call in progress */ + ESP_HF_CALL_STATUS_NO_CALLS = 0, /*!< no call in progress */ ESP_HF_CALL_STATUS_CALL_IN_PROGRESS = 1, /*!< call is present(active or held) */ } esp_hf_call_status_t; @@ -124,7 +135,7 @@ typedef enum { /// +CNUM service type of the phone number typedef enum { ESP_HF_SUBSCRIBER_SERVICE_TYPE_UNKNOWN = 0, /*!< unknown */ - ESP_HF_SUBSCRIBER_SERVICE_TYPE_VOICE, /*!< voice service */ + ESP_HF_SUBSCRIBER_SERVICE_TYPE_VOICE = 4, /*!< voice service */ ESP_HF_SUBSCRIBER_SERVICE_TYPE_FAX, /*!< fax service */ } esp_hf_subscriber_service_type_t; diff --git a/components/bt/host/bluedroid/api/include/api/esp_spp_api.h b/components/bt/host/bluedroid/api/include/api/esp_spp_api.h index 60008a646d..d2a0e09044 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_spp_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_spp_api.h @@ -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,10 +29,18 @@ extern "C" { } /* Security Setting Mask -Use these three mask mode: +Use these three mask modes on both sides: 1. ESP_SPP_SEC_NONE 2. ESP_SPP_SEC_AUTHENTICATE -3. (ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE) +3. (ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) +Use these three mask modes only on acceptor side: +1. ESP_SPP_SEC_IN_16_DIGITS +2. (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE) +3. (ESP_SPP_SEC_IN_16_DIGITS | ESP_SPP_SEC_AUTHENTICATE | ESP_SPP_SEC_ENCRYPT) +Due to certain limitations, do not use these mask modes: +1. ESP_SPP_SEC_AUTHORIZE +2. ESP_SPP_SEC_MODE4_LEVEL4 +3. ESP_SPP_SEC_MITM */ #define ESP_SPP_SEC_NONE 0x0000 /*!< No security. relate to BTA_SEC_NONE in bta/bta_api.h */ #define ESP_SPP_SEC_AUTHORIZE 0x0001 /*!< Authorization required (only needed for out going connection ) relate to BTA_SEC_AUTHORIZE in bta/bta_api.h*/ diff --git a/components/bt/host/bluedroid/bta/av/bta_av_aact.c b/components/bt/host/bluedroid/bta/av/bta_av_aact.c index 748f0669d6..9564f6a217 100644 --- a/components/bt/host/bluedroid/bta/av/bta_av_aact.c +++ b/components/bt/host/bluedroid/bta/av/bta_av_aact.c @@ -62,6 +62,11 @@ #define BTA_AV_RECONFIG_RETRY 6 #endif +/* avdt_handle to send abort command for AVDTP BQB test */ +#if A2D_SRC_BQB_INCLUDED +static uint8_t s_avdt_bqb_handle; +#endif /* CONFIG_BT_BQB_ENABLED */ + static void bta_av_st_rc_timer(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data); /* state machine states */ @@ -733,8 +738,7 @@ static void bta_av_adjust_seps_idx(tBTA_AV_SCB *p_scb, UINT8 avdt_handle) for (xx = 0; xx < BTA_AV_MAX_SEPS; xx++) { APPL_TRACE_DEBUG("av_handle: %d codec_type: %d", p_scb->seps[xx].av_handle, p_scb->seps[xx].codec_type); - if ((p_scb->seps[xx].av_handle && p_scb->codec_type == p_scb->seps[xx].codec_type) - && (p_scb->seps[xx].av_handle == avdt_handle)) { + if ((p_scb->seps[xx].av_handle) && (p_scb->seps[xx].av_handle == avdt_handle)) { p_scb->sep_idx = xx; p_scb->avdt_handle = p_scb->seps[xx].av_handle; break; @@ -1027,6 +1031,7 @@ void bta_av_cleanup(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) p_scb->wait = 0; p_scb->num_disc_snks = 0; p_scb->disc_rsn = 0; + p_scb->avdt_handle = 0; bta_sys_stop_timer(&p_scb->timer); if (p_scb->deregistring) { /* remove stream */ @@ -1415,6 +1420,10 @@ void bta_av_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) } } +#if A2D_SRC_BQB_INCLUDED + s_avdt_bqb_handle = p_scb->avdt_handle; +#endif /* A2D_SRC_BQB_INCLUDED */ + #if 0 /* TODO: implement the property enable/disable */ // This code is used to pass PTS TC for AVDTP ABORT char value[PROPERTY_VALUE_MAX] = {0}; @@ -1426,6 +1435,22 @@ void bta_av_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data) #endif /* #if 0*/ } +/******************************************************************************* +** +** Function avdt_bqb_abort +** +** Description Send AVDT abort request for BQB test +** +** Returns void +** +*******************************************************************************/ +#if A2D_SRC_BQB_INCLUDED +void avdt_bqb_abort(void) +{ + AVDT_AbortReq(s_avdt_bqb_handle); +} +#endif /* A2D_SRC_BQB_INCLUDED */ + /******************************************************************************* ** ** Function bta_av_security_ind 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 53eda0d2db..95be58bbb2 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -577,6 +577,14 @@ void bta_dm_disable (tBTA_DM_MSG *p_data) bta_dm_disable_search_and_disc(); bta_dm_cb.disabling = TRUE; +#if BLE_INCLUDED == TRUE + /* reset scan activity status*/ + btm_cb.ble_ctr_cb.scan_activity = 0; + + /* reset advertising activity status*/ + btm_cb.ble_ctr_cb.inq_var.state = 0; +#endif + #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE BTM_BleClearBgConnDev(); #endif @@ -604,6 +612,11 @@ void bta_dm_disable (tBTA_DM_MSG *p_data) btm_ble_resolving_list_cleanup (); //by TH, because cmn_ble_vsc_cb.max_filter has something mistake as btm_ble_adv_filter_cleanup #endif +#if BLE_INCLUDED == TRUE + // btm_ble_multi_adv_init is called when the host is enabled, so btm_ble_multi_adv_cleanup is called when the host is disabled. + btm_ble_multi_adv_cleanup(); +#endif + } /******************************************************************************* @@ -638,7 +651,7 @@ static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle) } /* Retrigger disable timer in case ACL disconnect failed, DISABLE_EVT still need - to be sent out to avoid jave layer disable timeout */ + to be sent out to avoid the layer disable timeout */ if (trigger_disc) { bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_timer_cback; bta_dm_cb.disable_timer.param = 1; @@ -694,6 +707,14 @@ void bta_dm_get_dev_name (tBTA_DM_MSG *p_data) } } +void bta_dm_send_vendor_hci(tBTA_DM_MSG *p_data) +{ + BTM_VendorSpecificCommand(p_data->vendor_hci_cmd.opcode, + p_data->vendor_hci_cmd.param_len, + p_data->vendor_hci_cmd.p_param_buf, + p_data->vendor_hci_cmd.vendor_hci_cb); +} + /******************************************************************************* ** ** Function bta_dm_set_afh_channels @@ -742,7 +763,7 @@ static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr, tBT_TRANSPORT tr APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is busy"); /* Remote name discovery is on going now so BTM cannot notify through "bta_dm_remname_cback" */ - /* adding callback to get notified that current reading remore name done */ + /* adding callback to get notified that current reading remote name done */ BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); return (TRUE); @@ -788,6 +809,7 @@ void bta_dm_config_eir (tBTA_DM_MSG *p_data) tBTA_DM_API_CONFIG_EIR *config_eir = &p_data->config_eir; p_bta_dm_eir_cfg->bta_dm_eir_fec_required = config_eir->eir_fec_required; + p_bta_dm_eir_cfg->bta_dm_eir_included_name = config_eir->eir_included_name; p_bta_dm_eir_cfg->bta_dm_eir_included_uuid = config_eir->eir_included_uuid; p_bta_dm_eir_cfg->bta_dm_eir_included_tx_power = config_eir->eir_included_tx_power; p_bta_dm_eir_cfg->bta_dm_eir_flags = config_eir->eir_flags; @@ -824,6 +846,28 @@ void bta_dm_config_eir (tBTA_DM_MSG *p_data) bta_dm_set_eir(NULL); } + +/******************************************************************************* +** +** Function bta_dm_set_acl_pkt_types +** +** Description Sets ACL packet types +** +** +** Returns void +** +*******************************************************************************/ +void bta_dm_set_acl_pkt_types (tBTA_DM_MSG *p_data) +{ + if (p_data->set_acl_pkt_types.set_acl_pkt_types_cb != NULL) { + BTM_SetAclPktTypes(p_data->set_acl_pkt_types.rmt_addr, + p_data->set_acl_pkt_types.pkt_types, + p_data->set_acl_pkt_types.set_acl_pkt_types_cb); + } else { + APPL_TRACE_ERROR("%s(), the callback function can't be NULL.", __func__); + } +} + #endif /******************************************************************************* ** @@ -1073,7 +1117,7 @@ void bta_dm_add_device (tBTA_DM_MSG *p_data) } if (p_dev->is_trusted) { - /* covert BTA service mask to BTM mask */ + /* convert BTA service mask to BTM mask */ while (p_dev->tm && (index < BTA_MAX_SERVICE_ID)) { if (p_dev->tm & (UINT32)(1 << index)) { @@ -1101,7 +1145,7 @@ void bta_dm_add_device (tBTA_DM_MSG *p_data) ** Function bta_dm_close_acl ** ** Description This function forces to close the connection to a remote device -** and optionaly remove the device from security database if +** and optionally remove the device from security database if ** required. **** *******************************************************************************/ @@ -2626,7 +2670,7 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr) &bta_dm_search_cb.services_found ); } - /* if seaching with EIR is not completed */ + /* if searching with EIR is not completed */ if (bta_dm_search_cb.services_to_search) { /* check whether connection already exists to the device if connection exists, we don't have to wait for ACL @@ -3700,7 +3744,7 @@ static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle) tBTA_SYS_HW_MSG *sys_enable_event; #if (BTA_DM_PM_INCLUDED == TRUE) - /* disable the power managment module */ + /* disable the power management module */ bta_dm_disable_pm(); #endif /* #if (BTA_DM_PM_INCLUDED == TRUE) */ @@ -4039,14 +4083,19 @@ static void bta_dm_set_eir (char *local_name) } return; } +#endif // BTA_EIR_CANNED_UUID_LIST - /* if local name is not provided, get it from controller */ - if ( local_name == NULL ) { - if ( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS ) { - APPL_TRACE_ERROR("Fail to read local device name for EIR"); + if (p_bta_dm_eir_cfg->bta_dm_eir_included_name) { + /* if local name is not provided, get it from controller */ + if ( local_name == NULL ) { + if ( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS ) { + APPL_TRACE_ERROR("Fail to read local device name for EIR"); + } } + } else { + local_name = NULL; } -#endif // BTA_EIR_CANNED_UUID_LIST + /* Allocate a buffer to hold HCI command */ if ((p_buf = (BT_HDR *)osi_malloc(BTM_CMD_BUF_SIZE)) == NULL) { @@ -4082,7 +4131,7 @@ static void bta_dm_set_eir (char *local_name) p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */ #endif // BTA_EIR_CANNED_UUID_LIST - /* if UUID doesn't fit remaing space, shorten local name */ + /* if UUID doesn't fit remaining space, shorten local name */ if ( local_name_len > (free_eir_length - 4 - num_uuid * LEN_UUID_16)) { APPL_TRACE_WARNING("BTA EIR: local name is shortened"); local_name_len = p_bta_dm_eir_cfg->bta_dm_eir_min_name_len; @@ -4092,15 +4141,16 @@ static void bta_dm_set_eir (char *local_name) } } - UINT8_TO_STREAM(p, local_name_len + 1); - UINT8_TO_STREAM(p, data_type); - eir_type[eir_type_num++] = data_type; + if (local_name != NULL) { + UINT8_TO_STREAM(p, local_name_len + 1); + UINT8_TO_STREAM(p, data_type); + eir_type[eir_type_num++] = data_type; memcpy(p, local_name, local_name_len); p += local_name_len; + free_eir_length -= local_name_len + 2; } - free_eir_length -= local_name_len + 2; /* if UUIDs are provided in configuration */ if (p_bta_dm_eir_cfg->bta_dm_eir_included_uuid) { @@ -4211,7 +4261,7 @@ static void bta_dm_set_eir (char *local_name) for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) { if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_128) { if ( num_uuid < max_num_uuid ) { - ARRAY16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid128); + ARRAY_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid128, LEN_UUID_128); num_uuid++; } else { data_type = BTM_EIR_MORE_128BITS_UUID_TYPE; @@ -4299,13 +4349,24 @@ static void bta_dm_set_eir (char *local_name) } } - if ( free_eir_length ) { + /* If there is no other data to be sent in the EIR packet, the Host shall + * send a name tag with zero length and the type field set to indicate + * that this is the complete name (i.e., total of 2 octets with length = + * 1). + */ + if (eir_type_num == 0) { + UINT8_TO_STREAM(p, 1); + UINT8_TO_STREAM(p, BTM_EIR_COMPLETE_LOCAL_NAME_TYPE); + free_eir_length -= 2; + } + + if (free_eir_length) { UINT8_TO_STREAM(p, 0); /* terminator of significant part */ } tBTM_STATUS btm_status = BTM_WriteEIR( p_buf, p_bta_dm_eir_cfg->bta_dm_eir_fec_required ); - if ( btm_status == BTM_MODE_UNSUPPORTED) { + if (btm_status == BTM_MODE_UNSUPPORTED) { status = BTA_WRONG_MODE; } else if (btm_status != BTM_SUCCESS) { status = BTA_FAILURE; @@ -4397,21 +4458,38 @@ static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result, ** Returns None ** *******************************************************************************/ -void bta_dm_eir_update_uuid(UINT16 uuid16, BOOLEAN adding) +void bta_dm_eir_update_uuid(tBT_UUID uuid, BOOLEAN adding) { - /* if this UUID is not advertised in EIR */ - if ( !BTM_HasEirService( p_bta_dm_eir_cfg->uuid_mask, uuid16 )) { - return; - } + /* 32 and 128-bit UUIDs go to the bta_dm_cb.custom_uuid array */ + if ((uuid.len == LEN_UUID_32) || (uuid.len == LEN_UUID_128)) { + if (adding) { + if (BTM_HasCustomEirService(bta_dm_cb.custom_uuid, uuid)) { + APPL_TRACE_EVENT("UUID is already added for EIR"); + return; + } + APPL_TRACE_EVENT("Adding %d-bit UUID into EIR", uuid.len * 8); - if ( adding ) { - APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16); + BTM_AddCustomEirService(bta_dm_cb.custom_uuid, uuid); + } else { + APPL_TRACE_EVENT("Removing %d-bit UUID from EIR", uuid.len * 8); - BTM_AddEirService( bta_dm_cb.eir_uuid, uuid16 ); + BTM_RemoveCustomEirService(bta_dm_cb.custom_uuid, uuid); + } } else { - APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16); + /* if this UUID is not advertised in EIR */ + if (!BTM_HasEirService(p_bta_dm_eir_cfg->uuid_mask, uuid.uu.uuid16)) { + return; + } + + if (adding) { + APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid.uu.uuid16); - BTM_RemoveEirService( bta_dm_cb.eir_uuid, uuid16 ); + BTM_AddEirService(bta_dm_cb.eir_uuid, uuid.uu.uuid16); + } else { + APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid.uu.uuid16); + + BTM_RemoveEirService(bta_dm_cb.eir_uuid, uuid.uu.uuid16); + } } #if CLASSIC_BT_INCLUDED bta_dm_set_eir (NULL); @@ -5092,7 +5170,7 @@ void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data) *******************************************************************************/ void bta_dm_ble_disconnect (tBTA_DM_MSG *p_data) { - L2CA_RemoveFixedChnl(L2CAP_ATT_CID, p_data->ble_disconnect.remote_bda); + L2CA_BleDisconnect(p_data->ble_disconnect.remote_bda); } /******************************************************************************* @@ -5101,14 +5179,14 @@ void bta_dm_ble_disconnect (tBTA_DM_MSG *p_data) ** ** Description This function set the LE random address for the device. ** -** Parameters: rand_addr:the random address whitch should be setting +** Parameters: rand_addr:the random address which should be setting ** Explanation: This function added by Yulong at 2016/9/9 *******************************************************************************/ void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data) { tBTM_STATUS status = BTM_SET_STATIC_RAND_ADDR_FAIL; if (p_data->set_addr.addr_type != BLE_ADDR_RANDOM) { - APPL_TRACE_ERROR("Invalid random adress type = %d\n", p_data->set_addr.addr_type); + APPL_TRACE_ERROR("Invalid random address type = %d\n", p_data->set_addr.addr_type); if(p_data->set_addr.p_set_rand_addr_cback) { (*p_data->set_addr.p_set_rand_addr_cback)(status); } @@ -5254,6 +5332,10 @@ void bta_dm_ble_scan (tBTA_DM_MSG *p_data) status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE); p_data->ble_scan.p_stop_scan_cback(status); } + + // reset BLE scan link state when stop scan + btm_ble_clear_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); + btm_ble_clear_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); } } @@ -5463,7 +5545,7 @@ void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data) } p_acl_cb->p_set_pkt_data_cback = p_data->ble_set_data_length.p_set_pkt_data_cback; - // if the value of the data length is same, triger callback directly + // if the value of the data length is same, trigger callback directly if(p_data->ble_set_data_length.tx_data_length == p_acl_cb->data_length_params.tx_len) { if(p_data->ble_set_data_length.p_set_pkt_data_cback) { (*p_data->ble_set_data_length.p_set_pkt_data_cback)(status, &p_acl_cb->data_length_params); @@ -5472,7 +5554,7 @@ void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data) } if(p_acl_cb->data_len_updating) { - // aleady have one cmd + // already have one cmd if(p_acl_cb->data_len_waiting) { status = BTM_ILLEGAL_ACTION; } else { @@ -5633,7 +5715,66 @@ void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data) p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE); } } + +void bta_dm_ble_gap_dtm_tx_start(tBTA_DM_MSG *p_data) +{ + BTM_BleTransmitterTest(p_data->dtm_tx_start.tx_channel, p_data->dtm_tx_start.len_of_data, p_data->dtm_tx_start.pkt_payload, p_data->dtm_tx_start.p_dtm_cmpl_cback); +} + +void bta_dm_ble_gap_dtm_rx_start(tBTA_DM_MSG *p_data) +{ + BTM_BleReceiverTest(p_data->dtm_rx_start.rx_channel, p_data->dtm_rx_start.p_dtm_cmpl_cback); +} + +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); + } + } +} + +void bta_dm_ble_gap_set_rpa_timeout(tBTA_DM_MSG *p_data) +{ + APPL_TRACE_API("%s, rpa_timeout = %d", __func__, p_data->set_rpa_timeout.rpa_timeout); + BTM_BleSetRpaTimeout(p_data->set_rpa_timeout.rpa_timeout,p_data->set_rpa_timeout.p_set_rpa_timeout_cback); +} + +void bta_dm_ble_gap_add_dev_to_resolving_list(tBTA_DM_MSG *p_data) +{ + APPL_TRACE_API("%s", __func__); + BTM_BleAddDevToResolvingList(p_data->add_dev_to_resolving_list.addr, + p_data->add_dev_to_resolving_list.addr_type, + p_data->add_dev_to_resolving_list.irk, + p_data->add_dev_to_resolving_list.p_add_dev_to_resolving_list_callback); +} + +void bta_dm_ble_gap_set_privacy_mode(tBTA_DM_MSG *p_data) +{ + APPL_TRACE_API("%s, privacy_mode = %d", __func__, p_data->ble_set_privacy_mode.privacy_mode); + BTM_BleSetPrivacyMode(p_data->ble_set_privacy_mode.addr_type, p_data->ble_set_privacy_mode.addr, + p_data->ble_set_privacy_mode.privacy_mode, p_data->ble_set_privacy_mode.p_cback); +} + #if (BLE_50_FEATURE_SUPPORT == TRUE) +void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data) +{ + BTM_BleEnhancedTransmitterTest(p_data->dtm_enh_tx_start.tx_channel, p_data->dtm_enh_tx_start.len_of_data, + p_data->dtm_enh_tx_start.pkt_payload, p_data->dtm_enh_tx_start.phy, p_data->dtm_enh_tx_start.p_dtm_cmpl_cback); +} + +void bta_dm_ble_gap_dtm_enhance_rx_start(tBTA_DM_MSG *p_data) +{ + BTM_BleEnhancedReceiverTest(p_data->dtm_enh_rx_start.rx_channel, p_data->dtm_enh_rx_start.phy, + p_data->dtm_enh_rx_start.modulation_index, p_data->dtm_enh_rx_start.p_dtm_cmpl_cback); +} + void bta_dm_ble_gap_read_phy(tBTA_DM_MSG *p_data) { //tBTM_STATUS btm_status = 0; @@ -5714,7 +5855,8 @@ void bta_dm_ble_gap_periodic_adv_cfg_data_raw(tBTA_DM_MSG *p_data) BTM_BlePeriodicAdvCfgDataRaw(p_data->ble_cfg_periodic_adv_data.instance, p_data->ble_cfg_periodic_adv_data.length, - p_data->ble_cfg_periodic_adv_data.data); + p_data->ble_cfg_periodic_adv_data.data, + p_data->ble_cfg_periodic_adv_data.only_update_did); } void bta_dm_ble_gap_periodic_adv_enable(tBTA_DM_MSG *p_data) @@ -5813,6 +5955,37 @@ void bta_dm_ble_gap_set_prefer_ext_conn_params(tBTA_DM_MSG *p_data) } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void bta_dm_ble_gap_periodic_adv_recv_enable(tBTA_DM_MSG *p_data) +{ + BTM_BlePeriodicAdvRecvEnable(p_data->ble_periodic_adv_recv_enable.sync_handle, + p_data->ble_periodic_adv_recv_enable.enable); +} + +void bta_dm_ble_gap_periodic_adv_sync_trans(tBTA_DM_MSG *p_data) +{ + BTM_BlePeriodicAdvSyncTrans(p_data->ble_periodic_adv_sync_trans.addr, + p_data->ble_periodic_adv_sync_trans.service_data, + p_data->ble_periodic_adv_sync_trans.sync_handle); +} + +void bta_dm_ble_gap_periodic_adv_set_info_trans(tBTA_DM_MSG *p_data) +{ + BTM_BlePeriodicAdvSetInfoTrans(p_data->ble_periodic_adv_set_info_trans.addr, + p_data->ble_periodic_adv_set_info_trans.service_data, + p_data->ble_periodic_adv_set_info_trans.adv_hanlde); +} + +void bta_dm_ble_gap_set_periodic_adv_sync_trans_params(tBTA_DM_MSG *p_data) +{ + BTM_BleSetPeriodicAdvSyncTransParams(p_data->ble_set_past_params.addr, + p_data->ble_set_past_params.params.mode, + p_data->ble_set_past_params.params.skip, + p_data->ble_set_past_params.params.sync_timeout, + p_data->ble_set_past_params.params.cte_type); +} +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) /******************************************************************************* ** ** Function bta_dm_ble_setup_storage @@ -6270,7 +6443,7 @@ static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id) } } else { - APPL_TRACE_ERROR("%s out of room to accomodate more service ids ble_raw_size = %d ble_raw_used = %d", __FUNCTION__, bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used ); + APPL_TRACE_ERROR("%s out of room to accommodate more service ids ble_raw_size = %d ble_raw_used = %d", __FUNCTION__, bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used ); } APPL_TRACE_API("%s service_id_uuid_len=%d ", __func__, service_id.uuid.len); 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 8f7e6d0ac6..83082e4b46 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -202,6 +202,21 @@ void BTA_DmGetDeviceName(tBTA_GET_DEV_NAME_CBACK *p_cback) } } +void BTA_DmsendVendorHciCmd(UINT16 opcode, UINT8 param_len, UINT8 *p_param_buf, tBTA_SEND_VENDOR_HCI_CMPL_CBACK p_vendor_cmd_complete_cback) +{ + tBTA_DM_API_SEND_VENDOR_HCI_CMD *p_msg; + if ((p_msg = (tBTA_DM_API_SEND_VENDOR_HCI_CMD *)osi_malloc(sizeof(tBTA_DM_API_SEND_VENDOR_HCI_CMD) + param_len)) != NULL) { + p_msg->hdr.event = BTA_DM_API_SEND_VENDOR_HCI_CMD_EVT; + p_msg->opcode = opcode; + p_msg->param_len = param_len; + p_msg->p_param_buf = (UINT8 *)(p_msg + 1); + memcpy(p_msg->p_param_buf, p_param_buf, param_len); + p_msg->vendor_hci_cb = p_vendor_cmd_complete_cback; + + bta_sys_sendmsg(p_msg); + } +} + #if (CLASSIC_BT_INCLUDED == TRUE) void BTA_DmConfigEir(tBTA_DM_EIR_CONF *eir_config) @@ -226,6 +241,7 @@ void BTA_DmConfigEir(tBTA_DM_EIR_CONF *eir_config) p_msg->hdr.event = BTA_DM_API_CONFIG_EIR_EVT; p_msg->eir_fec_required = eir_config->bta_dm_eir_fec_required; + p_msg->eir_included_name = eir_config->bta_dm_eir_included_name; p_msg->eir_included_tx_power = eir_config->bta_dm_eir_included_tx_power; p_msg->eir_included_uuid = eir_config->bta_dm_eir_included_uuid; p_msg->eir_flags = eir_config->bta_dm_eir_flags; @@ -270,6 +286,30 @@ void BTA_DmSetAfhChannels(const uint8_t *channels, tBTA_CMPL_CB *set_afh_cb) bta_sys_sendmsg(p_msg); } } + +/******************************************************************************* +** +** Function BTA_DmSetAclPktTypes +** +** Description This function sets the packet types used for ACL traffic. +** +** +** Returns void +** +*******************************************************************************/ +void BTA_DmSetAclPktTypes(BD_ADDR remote_addr, UINT16 pkt_types, tBTM_CMPL_CB *p_cb) +{ + tBTA_DM_API_SET_ACL_PKT_TYPES *p_msg; + + if ((p_msg = (tBTA_DM_API_SET_ACL_PKT_TYPES *) osi_malloc(sizeof(tBTA_DM_API_SET_ACL_PKT_TYPES))) != NULL) { + p_msg->hdr.event = BTA_DM_API_SET_ACL_PKT_TYPES_EVT; + bdcpy(p_msg->rmt_addr, remote_addr); + p_msg->pkt_types = pkt_types; + p_msg->set_acl_pkt_types_cb = p_cb; + + bta_sys_sendmsg(p_msg); + } +} #endif /// CLASSIC_BT_INCLUDED == TRUE #if (SDP_INCLUDED == TRUE) @@ -847,7 +887,7 @@ void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class, LINK_KEY link_key, ** ** Function BTA_DmRemoveDevice ** -** Description This function removes a device fromthe security database list of +** Description This function removes a device from the security database list of ** peer device. It manages unpairing even while connected. ** ** @@ -1065,7 +1105,7 @@ void BTA_DmAddBleDevice(BD_ADDR bd_addr, tBLE_ADDR_TYPE addr_type, int auth_mode ** Description Send BLE SMP passkey reply. ** ** Parameters: bd_addr - BD address of the peer -** accept - passkey entry sucessful or declined. +** accept - passkey entry successful or declined. ** passkey - passkey value, must be a 6 digit number, ** can be lead by 0. ** @@ -1744,6 +1784,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 /******************************************************************************* ** @@ -1881,7 +1944,7 @@ void BTA_DmDiscoverExt(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_services, ** p_services: if service is not empty, service discovery will be done. ** for all GATT based service condition, put num_uuid, and ** p_uuid is the pointer to the list of UUID values. -** p_cback: callback functino when search is completed. +** p_cback: callback function when search is completed. ** ** ** @@ -1969,7 +2032,7 @@ void BTA_DmBleUpdateConnectionParam(BD_ADDR bd_addr, UINT16 min_int, ** ** Description Enable/disable privacy on the local device ** -** Parameters: privacy_enable - enable/disabe privacy on remote device. +** Parameters: privacy_enable - enable/disable privacy on remote device. ** ** Returns void ** @@ -2021,7 +2084,7 @@ void BTA_DmBleConfigLocalIcon(uint16_t icon) ** ** Function BTA_BleEnableAdvInstance ** -** Description This function enable a Multi-ADV instance with the specififed +** Description This function enable a Multi-ADV instance with the specified ** adv parameters ** ** Parameters p_params: pointer to the adv parameter structure. @@ -2060,7 +2123,7 @@ void BTA_BleEnableAdvInstance (tBTA_BLE_ADV_PARAMS *p_params, ** ** Function BTA_BleUpdateAdvInstParam ** -** Description This function update a Multi-ADV instance with the specififed +** Description This function update a Multi-ADV instance with the specified ** adv parameters. ** ** Parameters inst_id: Adv instance to update the parameter. @@ -2091,7 +2154,7 @@ void BTA_BleUpdateAdvInstParam (UINT8 inst_id, tBTA_BLE_ADV_PARAMS *p_params) ** ** Function BTA_BleCfgAdvInstData ** -** Description This function configure a Multi-ADV instance with the specififed +** Description This function configure a Multi-ADV instance with the specified ** adv data or scan response data. ** ** Parameter inst_id: Adv instance to configure the adv data or scan response. @@ -2478,6 +2541,64 @@ void BTA_DmBleSetDataLength(BD_ADDR remote_device, UINT16 tx_data_length, tBTA_S } } +void BTA_DmBleDtmTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + tBTA_DM_API_BLE_DTM_TX_START *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_DTM_TX_START *)osi_malloc(sizeof(tBTA_DM_API_BLE_DTM_TX_START))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_DTM_TX_START_EVT; + p_msg->tx_channel = tx_channel; + p_msg->len_of_data = len_of_data; + p_msg->pkt_payload = pkt_payload; + p_msg->p_dtm_cmpl_cback = p_dtm_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleDtmRxStart(uint8_t rx_channel, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + tBTA_DM_API_BLE_DTM_RX_START *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_DTM_RX_START *)osi_malloc(sizeof(tBTA_DM_API_BLE_DTM_RX_START))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_DTM_RX_START_EVT; + p_msg->rx_channel= rx_channel; + p_msg->p_dtm_cmpl_cback = p_dtm_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleDtmStop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + tBTA_DM_API_BLE_DTM_STOP *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_DTM_STOP *)osi_malloc(sizeof(tBTA_DM_API_BLE_DTM_STOP))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_DTM_STOP_EVT; + p_msg->p_dtm_cmpl_cback = p_dtm_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleSetPrivacyMode(uint8_t addr_type, BD_ADDR addr, uint8_t privacy_mode, tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback) +{ + tBTA_DM_API_SET_PRIVACY_MODE *p_msg; + + if ((p_msg = (tBTA_DM_API_SET_PRIVACY_MODE *)osi_malloc(sizeof(tBTA_DM_API_SET_PRIVACY_MODE))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_SET_PRIVACY_MODE_EVT; + p_msg->addr_type = addr_type; + memcpy(p_msg->addr, addr, sizeof(BD_ADDR)); + p_msg->privacy_mode = privacy_mode; + p_msg->p_cback = p_cback; + bta_sys_sendmsg(p_msg); + } +} + #endif /******************************************************************************* @@ -2491,7 +2612,7 @@ void BTA_DmBleSetDataLength(BD_ADDR remote_device, UINT16 tx_data_length, tBTA_S ** ** Parameters: bd_addr - Address of the peer device ** transport - transport of the link to be encruypted -** p_callback - Pointer to callback function to indicat the +** p_callback - Pointer to callback function to indicate the ** link encryption status ** sec_act - This is the security action to indicate ** what kind of BLE security level is required for @@ -2671,7 +2792,7 @@ extern void BTA_DmBleStopAdvertising(void) ** ** Description This function set the random address for the APP ** -** Parameters rand_addr: the random address whith should be setting +** Parameters rand_addr: the random address with should be setting ** p_set_rand_addr_cback: complete callback ** Returns void ** @@ -2687,7 +2808,68 @@ extern void BTA_DmSetRandAddress(BD_ADDR rand_addr, tBTA_SET_RAND_ADDR_CBACK *p_ p_msg->hdr.event = BTA_DM_API_SET_RAND_ADDR_EVT; p_msg->addr_type = BLE_ADDR_RANDOM; p_msg->p_set_rand_addr_cback = p_set_rand_addr_cback; - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module + bta_sys_sendmsg(p_msg); + } +} +/******************************************************************************* +** +** Function BTA_DmBleSetRpaTimeout +** +** Description This function sets the Resolvable Private Address (RPA) timeout +** for the Bluetooth device. The RPA timeout defines how long an RPA +** remains in use before a new one is generated. +** +** Parameters rpa_timeout: The timeout in seconds within the range of 1s to 1 hour +** as defined by the Bluetooth specification. This duration +** specifies how long the controller uses an RPA before +** generating a new one. +** Returns void +** +** +*******************************************************************************/ +void BTA_DmBleSetRpaTimeout(uint16_t rpa_timeout,tBTA_SET_RPA_TIMEOUT_CMPL_CBACK *p_set_rpa_timeout_cback) +{ + tBTA_DM_API_SET_RPA_TIMEOUT *p_msg; + if ((p_msg = (tBTA_DM_API_SET_RPA_TIMEOUT *) osi_malloc(sizeof(tBTA_DM_API_SET_RPA_TIMEOUT))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_SET_RPA_TIMEOUT)); + p_msg->hdr.event = BTA_DM_API_SET_RPA_TIMEOUT_EVT; + p_msg->rpa_timeout = rpa_timeout; // Assign the RPA timeout value to the message + p_msg->p_set_rpa_timeout_cback = p_set_rpa_timeout_cback; + bta_sys_sendmsg(p_msg); + } +} + +/******************************************************************************* +** +** Function BTA_DmBleAddDevToResolvingList +** +** Description This function adds a device to the resolving list of the +** Bluetooth controller. The resolving list is used for resolving +** the identity of devices using resolvable private addresses (RPAs). +** +** Parameters addr: Bluetooth device address to be added to the resolving list +** addr_type: Type of the address (public or random) +** irk: Identity Resolving Key (IRK) of the device +** add_dev_to_resolving_list_callback: Callback function to be invoked +** upon completion of the operation +** +** Returns void +** +*******************************************************************************/ +void BTA_DmBleAddDevToResolvingList(BD_ADDR addr, + uint8_t addr_type, + PEER_IRK irk, + tBTA_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *add_dev_to_resolving_list_callback) +{ + tBTA_DM_API_ADD_DEV_TO_RESOLVING_LIST *p_msg; + if ((p_msg = (tBTA_DM_API_ADD_DEV_TO_RESOLVING_LIST *) osi_malloc(sizeof(tBTA_DM_API_ADD_DEV_TO_RESOLVING_LIST))) != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_ADD_DEV_TO_RESOLVING_LIST)); + p_msg->hdr.event = BTA_DM_API_ADD_DEV_TO_RESOLVING_LIST_EVT; + memcpy(p_msg->addr, addr, BD_ADDR_LEN); // Copy the device address to the message + p_msg->addr_type = addr_type; // Assign the address type to the message + memcpy(p_msg->irk, irk, PEER_IRK_LEN); // Copy the IRK to the message + p_msg->p_add_dev_to_resolving_list_callback = add_dev_to_resolving_list_callback; bta_sys_sendmsg(p_msg); } } @@ -2747,7 +2929,6 @@ void BTA_VendorCleanup (void) } #endif - btm_ble_multi_adv_cleanup(); } #if (BLE_50_FEATURE_SUPPORT == TRUE) void BTA_DmBleGapReadPHY(BD_ADDR addr) @@ -2758,7 +2939,7 @@ void BTA_DmBleGapReadPHY(BD_ADDR addr) memset(p_msg, 0, sizeof(tBTA_DM_API_READ_PHY)); p_msg->hdr.event = BTA_DM_API_READ_PHY_EVT; memcpy(p_msg->bd_addr, addr, BD_ADDR_LEN); - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2770,13 +2951,13 @@ void BTA_DmBleGapSetPreferedDefaultPHY(tBTA_DM_BLE_GAP_PHY_MASK tx_phy_mask, tBTA_DM_BLE_GAP_PHY_MASK rx_phy_mask) { tBTA_DM_API_SET_PER_DEF_PHY *p_msg; - APPL_TRACE_API("%s, Set prefered default phy.", __func__); + APPL_TRACE_API("%s, Set preferred default phy.", __func__); if ((p_msg = (tBTA_DM_API_SET_PER_DEF_PHY *) osi_malloc(sizeof(tBTA_DM_API_SET_PER_DEF_PHY))) != NULL) { memset(p_msg, 0, sizeof(tBTA_DM_API_SET_PER_DEF_PHY)); p_msg->hdr.event = BTA_DM_API_SET_PER_DEF_PHY_EVT; p_msg->tx_phy_mask = tx_phy_mask; p_msg->rx_phy_mask = rx_phy_mask; - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2791,7 +2972,7 @@ void BTA_DmBleGapSetPreferedPHY(BD_ADDR addr, UINT16 phy_options) { tBTA_DM_API_SET_PER_PHY *p_msg; - APPL_TRACE_API("%s, Set prefered phy.", __func__); + APPL_TRACE_API("%s, Set preferred phy.", __func__); if ((p_msg = (tBTA_DM_API_SET_PER_PHY *) osi_malloc(sizeof(tBTA_DM_API_SET_PER_PHY))) != NULL) { memset(p_msg, 0, sizeof(tBTA_DM_API_SET_PER_PHY)); p_msg->hdr.event = BTA_DM_API_SET_PER_PHY_EVT; @@ -2800,7 +2981,7 @@ void BTA_DmBleGapSetPreferedPHY(BD_ADDR addr, p_msg->tx_phy_mask = tx_phy_mask; p_msg->rx_phy_mask = rx_phy_mask; p_msg->phy_options = phy_options; - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2816,7 +2997,7 @@ void BTA_DmBleGapExtAdvSetRandaddr(UINT16 instance, BD_ADDR addr) p_msg->hdr.event = BTA_DM_API_SET_EXT_ADV_RAND_ADDR_EVT; p_msg->instance = instance; memcpy(&p_msg->rand_addr, addr, BD_ADDR_LEN); - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2834,7 +3015,7 @@ void BTA_DmBleGapExtAdvSetParams(UINT16 instance, p_msg->hdr.event = BTA_DM_API_SET_EXT_ADV_PARAMS_EVT; p_msg->instance = instance; memcpy(&p_msg->params, params, sizeof(tBTA_DM_BLE_GAP_EXT_ADV_PARAMS)); - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2853,11 +3034,11 @@ void BTA_DmBleGapConfigExtAdvDataRaw(BOOLEAN is_scan_rsp, UINT8 instance, UINT16 p_msg->is_scan_rsp = is_scan_rsp; p_msg->instance = instance; p_msg->length = length; - p_msg->data = (UINT8 *)(p_msg + 1); + p_msg->data = length != 0 ? (UINT8 *)(p_msg + 1) : NULL; if (data) { memcpy(p_msg->data, data, length); } - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2877,7 +3058,7 @@ void BTA_DmBleGapExtAdvEnable(BOOLEAN enable, UINT8 num, tBTA_DM_BLE_EXT_ADV *ex if (ext_adv) { memcpy(p_msg->ext_adv, ext_adv, sizeof(tBTA_DM_BLE_EXT_ADV)*num); } - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2892,7 +3073,7 @@ void BTA_DmBleGapExtAdvSetRemove(UINT8 instance) memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_EXT_ADV_SET_REMOVE)); p_msg->hdr.event = BTA_DM_API_EXT_ADV_SET_REMOVE_EVT; p_msg->instance = instance; - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2906,7 +3087,7 @@ void BTA_DmBleGapExtAdvSetClear(void) if ((p_msg = (tBTA_DM_API_BLE_EXT_ADV_SET_CLEAR *) osi_malloc(sizeof(tBTA_DM_API_BLE_EXT_ADV_SET_CLEAR))) != NULL) { memset(p_msg, 0, sizeof(tBTA_DM_API_BLE_EXT_ADV_SET_CLEAR)); p_msg->hdr.event = BTA_DM_API_EXT_ADV_SET_CLEAR_EVT; - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2923,7 +3104,7 @@ void BTA_DmBleGapPeriodicAdvSetParams(UINT8 instance, p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_SET_PARAMS_EVT; p_msg->instance = instance; memcpy(&p_msg->params, params, sizeof(tBTA_DM_BLE_Periodic_Adv_Params)); - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2932,7 +3113,7 @@ void BTA_DmBleGapPeriodicAdvSetParams(UINT8 instance, } void BTA_DmBleGapPeriodicAdvCfgDataRaw(UINT8 instance, UINT16 length, - const UINT8 *data) + const UINT8 *data,bool only_update_did) { tBTA_DM_API_CFG_PERIODIC_ADV_DATA *p_msg; APPL_TRACE_API("%s, Periodic ADV config data raw.", __func__); @@ -2943,7 +3124,9 @@ void BTA_DmBleGapPeriodicAdvCfgDataRaw(UINT8 instance, UINT16 length, p_msg->length = length; p_msg->data = (UINT8 *)(p_msg + 1); memcpy(p_msg->data, data, length); - //start sent the msg to the bta system control moudle + p_msg->data = length != 0 ? (UINT8 *)(p_msg + 1) : NULL; + p_msg->only_update_did = only_update_did; + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2951,7 +3134,7 @@ void BTA_DmBleGapPeriodicAdvCfgDataRaw(UINT8 instance, UINT16 length, } -void BTA_DmBleGapPeriodicAdvEnable(BOOLEAN enable, UINT8 instance) +void BTA_DmBleGapPeriodicAdvEnable(UINT8 enable, UINT8 instance) { tBTA_DM_API_ENABLE_PERIODIC_ADV *p_msg; APPL_TRACE_API("%s, Periodic ADV %s.", __func__, enable ? "start" : "stop"); @@ -2960,7 +3143,7 @@ void BTA_DmBleGapPeriodicAdvEnable(BOOLEAN enable, UINT8 instance) p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_ENABLE_EVT; p_msg->instance = instance; p_msg->enable = enable; - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2976,7 +3159,7 @@ void BTA_DmBleGapPeriodicAdvCreateSync(tBTA_DM_BLE_Periodic_Sync_Params *params) memset(p_msg, 0, sizeof(tBTA_DM_API_PERIODIC_ADV_SYNC)); p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_SYNC_EVT; memcpy(&p_msg->params, params, sizeof(tBTA_DM_BLE_Periodic_Sync_Params)); - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -2991,7 +3174,7 @@ void BTA_DmBleGapPeriodicAdvSyncCancel(void) if ((p_msg = (tBTA_DM_API_PERIODIC_ADV_SYNC_CANCEL *) osi_malloc(sizeof(tBTA_DM_API_PERIODIC_ADV_SYNC_CANCEL))) != NULL) { memset(p_msg, 0, sizeof(tBTA_DM_API_PERIODIC_ADV_SYNC_CANCEL)); p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_SYNC_CANCEL_EVT; - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -3007,7 +3190,7 @@ void BTA_DmBleGapPeriodicAdvSyncTerm(UINT16 sync_handle) memset(p_msg, 0, sizeof(tBTA_DM_API_PERIODIC_ADV_SYNC_TERM)); p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_SYNC_TERMINATE_EVT; p_msg->sync_handle = sync_handle; - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -3027,7 +3210,7 @@ void BTA_DmBleGapPeriodicAdvAddDevToList(tBLE_ADDR_TYPE addr_type, p_msg->addr_type = addr_type; p_msg->sid = sid; memcpy(p_msg->addr, addr, sizeof(BD_ADDR)); - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -3047,7 +3230,7 @@ void BTA_DmBleGapPeriodicAdvRemoveDevFromList(tBLE_ADDR_TYPE addr_type, p_msg->addr_type = addr_type; p_msg->sid = sid; memcpy(p_msg->addr, addr, sizeof(BD_ADDR)); - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -3062,7 +3245,7 @@ void BTA_DmBleGapPeriodicAdvClearDev(void) if ((p_msg = (tBTA_DM_API_PERIODIC_ADV_DEV_CLEAR *) osi_malloc(sizeof(tBTA_DM_API_PERIODIC_ADV_DEV_CLEAR))) != NULL) { memset(p_msg, 0, sizeof(tBTA_DM_API_PERIODIC_ADV_DEV_CLEAR)); p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_CLEAR_DEV_EVT; - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -3078,7 +3261,7 @@ void BTA_DmBleGapSetExtScanParams(tBTA_DM_BLE_EXT_SCAN_PARAMS *params) memset(p_msg, 0, sizeof(tBTA_DM_API_SET_EXT_SCAN_PARAMS)); p_msg->hdr.event = BTA_DM_API_SET_EXT_SCAN_PARAMS_EVT; memcpy(&p_msg->params, params, sizeof(tBTA_DM_BLE_EXT_SCAN_PARAMS)); - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -3096,7 +3279,7 @@ void BTA_DmBleGapExtScan(BOOLEAN start, UINT32 duration, UINT16 period) p_msg->start = start; p_msg->duration = duration; p_msg->period = period; - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -3130,7 +3313,7 @@ void BTA_DmBleGapPreferExtConnectParamsSet(BD_ADDR bd_addr, if (phy_coded_conn_params) { memcpy(&p_msg->phy_coded_conn_params, phy_coded_conn_params, sizeof(tBTA_DM_BLE_CONN_PARAMS)); } - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -3149,7 +3332,7 @@ void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_add p_msg->hdr.event = BTA_DM_API_EXT_CONN_EVT; p_msg->own_addr_type = own_addr_type; memcpy(p_msg->peer_addr, peer_addr, sizeof(BD_ADDR)); - //start sent the msg to the bta system control moudle + //start sent the msg to the bta system control module bta_sys_sendmsg(p_msg); } else { APPL_TRACE_ERROR("%s malloc failed", __func__); @@ -3157,19 +3340,106 @@ void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_add } +void BTA_DmBleDtmEnhTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, uint8_t phy, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + tBTA_DM_API_BLE_DTM_ENH_TX_START *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_DTM_ENH_TX_START *)osi_malloc(sizeof(tBTA_DM_API_BLE_DTM_ENH_TX_START))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_DTM_ENH_TX_START_EVT; + p_msg->tx_channel = tx_channel; + p_msg->len_of_data = len_of_data; + p_msg->pkt_payload = pkt_payload; + p_msg->phy = phy; + p_msg->p_dtm_cmpl_cback = p_dtm_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleDtmEnhRxStart(uint8_t rx_channel, uint8_t phy, uint8_t modulation_index, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + tBTA_DM_API_BLE_DTM_ENH_RX_START *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_DTM_ENH_RX_START *)osi_malloc(sizeof(tBTA_DM_API_BLE_DTM_ENH_RX_START))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_DTM_ENH_RX_START_EVT; + p_msg->rx_channel= rx_channel; + p_msg->phy = phy; + p_msg->modulation_index = modulation_index; + p_msg->p_dtm_cmpl_cback = p_dtm_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +} + #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) -uint8_t BTA_DmBlePeriodicAdvSetInfoTrans(uint8_t addr[6], uint16_t service_data, uint8_t adv_handle) +void BTA_DmBleGapPeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable) { - BTM_BlePeriodicAdvSetInfoTrans(addr, service_data, adv_handle); - return 0; + tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE *p_msg; + p_msg = (tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE *) osi_malloc(sizeof(tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE)); + if (p_msg != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE)); + p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_RECV_ENABLE_EVT; + p_msg->sync_handle = sync_handle; + p_msg->enable = enable; + //start sent the msg to the bta system control module + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } } -uint8_t BTA_DmBleSetPeriodicAdvSyncTransParams(uint8_t addr[6], uint8_t mode, uint16_t skip, uint16_t sync_timeout) +void BTA_DmBleGapPeriodicAdvSyncTrans(BD_ADDR peer_addr, UINT16 service_data, UINT16 sync_handle) { - BTM_BleSetPeriodicAdvSyncTransParams(addr, mode, skip, sync_timeout, 0); - return 0; + tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS *p_msg; + p_msg = (tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS *) osi_malloc(sizeof(tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS)); + if (p_msg != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS)); + p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_SYNC_TRANS_EVT; + memcpy(p_msg->addr, peer_addr, sizeof(BD_ADDR)); + p_msg->service_data = service_data; + p_msg->sync_handle = sync_handle; + //start sent the msg to the bta system control module + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapPeriodicAdvSetInfoTrans(BD_ADDR peer_addr, UINT16 service_data, UINT8 adv_handle) +{ + tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS *p_msg; + p_msg = (tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS *) osi_malloc(sizeof(tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS)); + if (p_msg != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS)); + p_msg->hdr.event = BTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS_EVT; + memcpy(p_msg->addr, peer_addr, sizeof(BD_ADDR)); + p_msg->service_data = service_data; + p_msg->adv_hanlde = adv_handle; + //start sent the msg to the bta system control module + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } +} + +void BTA_DmBleGapSetPeriodicAdvSyncTransParams(BD_ADDR peer_addr, tBTA_DM_BLE_PAST_PARAMS *params) +{ + tBTA_DM_API_SET_PAST_PARAMS *p_msg; + p_msg = (tBTA_DM_API_SET_PAST_PARAMS *) osi_malloc(sizeof(tBTA_DM_API_SET_PAST_PARAMS)); + if (p_msg != NULL) { + memset(p_msg, 0, sizeof(tBTA_DM_API_SET_PAST_PARAMS)); + p_msg->hdr.event = BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT; + memcpy(p_msg->addr, peer_addr, sizeof(BD_ADDR)); + memcpy(&p_msg->params, params, sizeof(tBTA_DM_BLE_PAST_PARAMS)); + //start sent the msg to the bta system control module + bta_sys_sendmsg(p_msg); + } else { + APPL_TRACE_ERROR("%s malloc failed", __func__); + } } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_cfg.c b/components/bt/host/bluedroid/bta/dm/bta_dm_cfg.c index 7586ef00f0..a4792ce846 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_cfg.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_cfg.c @@ -454,6 +454,7 @@ const UINT8 bta_dm_eir_uuid16_list[] = { 0x08, 0x11, /* Headset */ /* Extended Inquiry Response */ tBTA_DM_EIR_CONF bta_dm_eir_cfg = { BTM_EIR_DEFAULT_FEC_REQUIRED, /* FEC required */ + TRUE, /* Included local name */ 50, /* minimum length of local name when it is shortened */ /* if length of local name is longer than this and EIR has not enough */ /* room for all UUID list then local name is shortened to this length */ 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 69e729ef44..b37f29b8f8 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c @@ -52,6 +52,18 @@ tBTE_APPL_CFG bte_appl_cfg = { BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE, BTM_BLE_OOB_DISABLE, }; + +void bta_dm_co_security_param_init(void) +{ + bte_appl_cfg.ble_auth_req = BTA_LE_AUTH_REQ_SC_MITM_BOND; + bte_appl_cfg.ble_io_cap = BTM_LOCAL_IO_CAPS_BLE; + bte_appl_cfg.ble_init_key = BTM_BLE_INITIATOR_KEY_SIZE; + bte_appl_cfg.ble_resp_key = BTM_BLE_RESPONDER_KEY_SIZE; + bte_appl_cfg.ble_max_key_size = BTM_BLE_MAX_KEY_SIZE; + bte_appl_cfg.ble_min_key_size = BTM_BLE_MIN_KEY_SIZE; + bte_appl_cfg.ble_accept_auth_enable = BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE; + bte_appl_cfg.oob_support = BTM_BLE_OOB_DISABLE; +}; #endif #if (defined CLASSIC_BT_INCLUDED && CLASSIC_BT_INCLUDED == TRUE && BT_SSP_INCLUDED == TRUE) @@ -361,7 +373,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 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 0deb1e821e..4bbf06cb16 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -59,8 +59,10 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_disable, /* BTA_DM_API_DISABLE_EVT */ bta_dm_set_dev_name, /* BTA_DM_API_SET_NAME_EVT */ bta_dm_get_dev_name, /* BTA_DM_API_GET_NAME_EVT */ + bta_dm_send_vendor_hci, /* BTA_DM_API_SEND_VENDOR_HCI_CMD_EVT */ #if (CLASSIC_BT_INCLUDED == TRUE) bta_dm_config_eir, /* BTA_DM_API_CONFIG_EIR_EVT */ + bta_dm_set_acl_pkt_types, /* BTA_DM_API_SET_ACL_PKT_TYPES_EVT */ #endif bta_dm_set_afh_channels, /* BTA_DM_API_SET_AFH_CHANNELS_EVT */ #if (SDP_INCLUDED == TRUE) @@ -202,7 +204,25 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_set_ext_scan_params, /* BTA_DM_API_SET_EXT_SCAN_PARAMS_EVT */ bta_dm_ble_gap_ext_scan, /* BTA_DM_API_START_EXT_SCAN_EVT */ bta_dm_ble_gap_set_prefer_ext_conn_params, /* BTA_DM_API_SET_PERF_EXT_CONN_PARAMS_EVT */ + NULL, /* BTA_DM_API_EXT_CONN_EVT */ + bta_dm_ble_gap_dtm_enhance_tx_start, /* BTA_DM_API_DTM_ENH_TX_START_EVT */ + bta_dm_ble_gap_dtm_enhance_rx_start, /* BTA_DM_API_DTM_ENH_RX_START_EVT */ #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + bta_dm_ble_gap_periodic_adv_recv_enable, /* BTA_DM_API_PERIODIC_ADV_RECV_ENABLE_EVT */ + bta_dm_ble_gap_periodic_adv_sync_trans, /* BTA_DM_API_PERIODIC_ADV_SYNC_TRANS_EVT */ + bta_dm_ble_gap_periodic_adv_set_info_trans, /* BTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS_EVT */ + bta_dm_ble_gap_set_periodic_adv_sync_trans_params, /* BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT */ +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if BLE_INCLUDED == TRUE + 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 */ + bta_dm_ble_gap_set_rpa_timeout, /* BTA_DM_API_SET_RPA_TIMEOUT_EVT */ + bta_dm_ble_gap_add_dev_to_resolving_list, /* BTA_DM_API_ADD_DEV_TO_RESOLVING_LIST_EVT */ + bta_dm_ble_gap_set_privacy_mode, /* BTA_DM_API_SET_PRIVACY_MODE_EVT */ +#endif }; diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_qos.c b/components/bt/host/bluedroid/bta/dm/bta_dm_qos.c index 1239bae1f9..19a31b9449 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_qos.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_qos.c @@ -34,13 +34,13 @@ void bta_dm_set_qos(tBTA_DM_MSG *p_data) { FLOW_SPEC p_flow = { - .qos_flags = 0, /* TBD */ - .service_type = GUARANTEED, /* see below */ - .token_rate = 0, /* bytes/second */ - .token_bucket_size = 0, /* bytes */ - .peak_bandwidth = 0, /* bytes/second */ - .latency = 625 * p_data->qos_set.t_poll, /* microseconds */ - .delay_variation = 0xFFFFFFFF /* microseconds */ + .qos_flags = 0, /* TBD */ + .service_type = NO_TRAFFIC, /* service_type */ + .token_rate = 0, /* bytes/second */ + .token_bucket_size = 0, /* bytes */ + .peak_bandwidth = 0, /* bytes/second */ + .latency = 625 * p_data->qos_set.t_poll, /* microseconds */ + .delay_variation = 0xFFFFFFFF /* microseconds */ }; tBTM_STATUS status = BTM_SetQoS (p_data->qos_set.bd_addr, &p_flow, p_data->qos_set.p_cb); 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 243a9f3648..35ac3c3912 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 @@ -54,8 +54,10 @@ enum { BTA_DM_API_DISABLE_EVT, BTA_DM_API_SET_NAME_EVT, BTA_DM_API_GET_NAME_EVT, + BTA_DM_API_SEND_VENDOR_HCI_CMD_EVT, #if (CLASSIC_BT_INCLUDED == TRUE) BTA_DM_API_CONFIG_EIR_EVT, + BTA_DM_API_SET_ACL_PKT_TYPES_EVT, #endif BTA_DM_API_SET_AFH_CHANNELS_EVT, #if (SDP_INCLUDED == TRUE) @@ -74,7 +76,7 @@ enum { BTA_DM_API_PIN_REPLY_EVT, #endif ///SMP_INCLUDED == TRUE #if (BTA_DM_PM_INCLUDED == TRUE) - /* power manger events */ + /* power manager events */ BTA_DM_PM_BTM_STATUS_EVT, BTA_DM_PM_TIMER_EVT, #endif /* #if (BTA_DM_PM_INCLUDED == TRUE) */ @@ -199,7 +201,24 @@ enum { BTA_DM_API_START_EXT_SCAN_EVT, BTA_DM_API_SET_PERF_EXT_CONN_PARAMS_EVT, BTA_DM_API_EXT_CONN_EVT, + BTA_DM_API_DTM_ENH_TX_START_EVT, + BTA_DM_API_DTM_ENH_RX_START_EVT, #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + BTA_DM_API_PERIODIC_ADV_RECV_ENABLE_EVT, + BTA_DM_API_PERIODIC_ADV_SYNC_TRANS_EVT, + BTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS_EVT, + BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT, +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if BLE_INCLUDED == TRUE + 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, + BTA_DM_API_SET_RPA_TIMEOUT_EVT, + BTA_DM_API_ADD_DEV_TO_RESOLVING_LIST_EVT, + BTA_DM_API_SET_PRIVACY_MODE_EVT, +#endif BTA_DM_MAX_EVT }; @@ -236,10 +255,19 @@ typedef struct { tBTA_GET_DEV_NAME_CBACK *p_cback; } tBTA_DM_API_GET_NAME; +typedef struct { + BT_HDR hdr; + UINT16 opcode; + UINT8 param_len; + UINT8 *p_param_buf; + tBTA_SEND_VENDOR_HCI_CMPL_CBACK *vendor_hci_cb; +}tBTA_DM_API_SEND_VENDOR_HCI_CMD; + /* data type for BTA_DM_API_CONFIG_EIR_EVT */ typedef struct { BT_HDR hdr; BOOLEAN eir_fec_required; + BOOLEAN eir_included_name; BOOLEAN eir_included_tx_power; BOOLEAN eir_included_uuid; UINT8 eir_flags; @@ -257,6 +285,14 @@ typedef struct { tBTA_CMPL_CB *set_afh_cb; }tBTA_DM_API_SET_AFH_CHANNELS; +/* data type for BTA_DM_API_SET_ACL_PKT_TYPES_EVT */ +typedef struct { + BT_HDR hdr; + BD_ADDR rmt_addr; + UINT16 pkt_types; + tBTM_CMPL_CB *set_acl_pkt_types_cb; +} tBTA_DM_API_SET_ACL_PKT_TYPES; + /* data type for BTA_DM_API_GET_REMOTE_NAME_EVT */ typedef struct { BT_HDR hdr; @@ -609,7 +645,7 @@ typedef struct { tBTA_DM_BLE_SEL_CBACK *p_select_cback; } tBTA_DM_API_BLE_SET_BG_CONN_TYPE; -/* set prefered BLE connection parameters for a device */ +/* set preferred BLE connection parameters for a device */ typedef struct { BT_HDR hdr; BD_ADDR peer_bda; @@ -710,6 +746,20 @@ typedef struct { BT_HDR hdr; } tBTA_DM_APT_CLEAR_ADDR; +typedef struct { + BT_HDR hdr; + UINT16 rpa_timeout; + tBTA_SET_RPA_TIMEOUT_CMPL_CBACK *p_set_rpa_timeout_cback; +} tBTA_DM_API_SET_RPA_TIMEOUT; + +typedef struct { + BT_HDR hdr; // Event header + esp_bd_addr_t addr; // Bluetooth device address + UINT8 addr_type; // Type of the address + UINT8 irk[PEER_IRK_LEN]; // Identity Resolving Key (IRK) + tBTA_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *p_add_dev_to_resolving_list_callback; // Callback function pointer +} tBTA_DM_API_ADD_DEV_TO_RESOLVING_LIST; + /* set adv parameter for BLE advertising */ typedef struct { BT_HDR hdr; @@ -836,6 +886,38 @@ typedef struct { BD_ADDR remote_bda; } tBTA_DM_API_BLE_DISCONNECT; +typedef struct { + BT_HDR hdr; + UINT8 tx_channel; + UINT8 len_of_data; + UINT8 pkt_payload; + tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; +} tBTA_DM_API_BLE_DTM_TX_START; + +typedef struct { + BT_HDR hdr; + UINT8 rx_channel; + tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; +} tBTA_DM_API_BLE_DTM_RX_START; + +typedef struct { + BT_HDR hdr; + 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; + +typedef struct { + BT_HDR hdr; + tBLE_ADDR_TYPE addr_type; + BD_ADDR addr; + UINT8 privacy_mode; + tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback; +} tBTA_DM_API_SET_PRIVACY_MODE; + #endif /* BLE_INCLUDED */ /* data type for BTA_DM_API_REMOVE_ACL_EVT */ @@ -892,6 +974,22 @@ typedef struct { #endif #if (BLE_50_FEATURE_SUPPORT == TRUE) +typedef struct { + BT_HDR hdr; + UINT8 tx_channel; + UINT8 len_of_data; + UINT8 pkt_payload; + UINT8 phy; + tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; +} tBTA_DM_API_BLE_DTM_ENH_TX_START; +typedef struct { + BT_HDR hdr; + UINT8 rx_channel; + UINT8 phy; + UINT8 modulation_index; + tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; +} tBTA_DM_API_BLE_DTM_ENH_RX_START; + #define BTA_PHY_1M_MASK (1 << 0) #define BTA_PHY_2M_MASK (1 << 1) #define BTAS_PHY_CODED_MASK (1 << 2) @@ -962,12 +1060,13 @@ typedef struct { UINT8 instance; UINT16 length; UINT8 *data; + BOOLEAN only_update_did; } tBTA_DM_API_CFG_PERIODIC_ADV_DATA; typedef struct { BT_HDR hdr; UINT8 instance; - BOOLEAN enable; + UINT8 enable; } tBTA_DM_API_ENABLE_PERIODIC_ADV; typedef struct { @@ -1030,6 +1129,35 @@ typedef struct { BD_ADDR peer_addr; } tBTA_DM_API_EXT_CONN; #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) + +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +typedef struct { + BT_HDR hdr; + UINT16 sync_handle; + UINT8 enable; +} tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE; + +typedef struct { + BT_HDR hdr; + BD_ADDR addr; + UINT16 service_data; + UINT16 sync_handle; +} tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS; + +typedef struct { + BT_HDR hdr; + BD_ADDR addr; + UINT16 service_data; + UINT8 adv_hanlde; +} tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS; + +typedef struct { + BT_HDR hdr; + BD_ADDR addr; + tBTA_DM_BLE_PAST_PARAMS params; +} tBTA_DM_API_SET_PAST_PARAMS; +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /* union of all data types */ typedef union { /* event buffer header */ @@ -1038,9 +1166,11 @@ typedef union { tBTA_DM_API_SET_NAME set_name; tBTA_DM_API_GET_NAME get_name; + tBTA_DM_API_SEND_VENDOR_HCI_CMD vendor_hci_cmd; tBTA_DM_API_CONFIG_EIR config_eir; tBTA_DM_API_SET_AFH_CHANNELS set_afh_channels; + tBTA_DM_API_SET_ACL_PKT_TYPES set_acl_pkt_types; #if (SDP_INCLUDED == TRUE) tBTA_DM_API_GET_REMOTE_NAME get_rmt_name; #endif @@ -1134,6 +1264,8 @@ typedef union { tBTA_DM_API_BLE_SET_DATA_LENGTH ble_set_data_length; tBTA_DM_APT_SET_DEV_ADDR set_addr; tBTA_DM_APT_CLEAR_ADDR clear_addr; + tBTA_DM_API_SET_RPA_TIMEOUT set_rpa_timeout; + tBTA_DM_API_ADD_DEV_TO_RESOLVING_LIST add_dev_to_resolving_list; tBTA_DM_API_BLE_MULTI_ADV_ENB ble_multi_adv_enb; tBTA_DM_API_BLE_MULTI_ADV_PARAM ble_multi_adv_param; tBTA_DM_API_BLE_MULTI_ADV_DATA ble_multi_adv_data; @@ -1169,7 +1301,21 @@ typedef union { tBTA_DM_API_SET_EXT_SCAN_PARAMS ble_set_ext_scan_params; tBTA_DM_API_EXT_SCAN ble_ext_scan; tBTA_DM_API_SET_PER_EXT_CONN_PARAMS ble_set_per_ext_conn_params; + tBTA_DM_API_BLE_DTM_ENH_TX_START dtm_enh_tx_start; + tBTA_DM_API_BLE_DTM_ENH_RX_START dtm_enh_rx_start; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE ble_periodic_adv_recv_enable; + tBTA_DM_API_PERIODIC_ADV_SYNC_TRANS ble_periodic_adv_sync_trans; + tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS ble_periodic_adv_set_info_trans; + tBTA_DM_API_SET_PAST_PARAMS ble_set_past_params; +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + + 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; + tBTA_DM_API_SET_PRIVACY_MODE ble_set_privacy_mode; #endif tBTA_DM_API_REMOVE_ACL remove_acl; @@ -1304,7 +1450,7 @@ typedef struct { UINT32 role_policy_mask; /* the bits set indicates the modules that wants to remove role switch from the default link policy */ UINT16 cur_policy; /* current default link policy */ UINT16 rs_event; /* the event waiting for role switch */ - UINT8 cur_av_count; /* current AV connecions */ + UINT8 cur_av_count; /* current AV connections */ BOOLEAN disable_pair_mode; /* disable pair mode or not */ BOOLEAN conn_paired_only; /* allow connectable to paired device only or not */ tBTA_DM_API_SEARCH search_msg; @@ -1533,8 +1679,10 @@ extern void bta_dm_enable (tBTA_DM_MSG *p_data); extern void bta_dm_disable (tBTA_DM_MSG *p_data); extern void bta_dm_set_dev_name (tBTA_DM_MSG *p_data); extern void bta_dm_get_dev_name (tBTA_DM_MSG *p_data); +extern void bta_dm_send_vendor_hci(tBTA_DM_MSG *p_data); #if (CLASSIC_BT_INCLUDED == TRUE) extern void bta_dm_config_eir (tBTA_DM_MSG *p_data); +extern void bta_dm_set_acl_pkt_types (tBTA_DM_MSG *p_data); #endif extern void bta_dm_set_afh_channels (tBTA_DM_MSG *p_data); extern void bta_dm_read_rmt_name(tBTA_DM_MSG *p_data); @@ -1592,6 +1740,9 @@ extern void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data); extern void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data); extern void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data); extern void bta_dm_ble_update_duplicate_exceptional_list(tBTA_DM_MSG *p_data); +#if SMP_INCLUDED == TRUE +extern void bta_dm_co_security_param_init(void); +#endif #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE extern void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data); extern void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data); @@ -1601,7 +1752,16 @@ extern void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data); extern void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data); extern void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data); 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); +extern void bta_dm_ble_gap_set_rpa_timeout(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_add_dev_to_resolving_list(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_set_privacy_mode(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); +extern void bta_dm_ble_gap_dtm_enhance_rx_start(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_read_phy(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_prefer_default_phy(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_prefer_phy(tBTA_DM_MSG *p_data); @@ -1674,7 +1834,7 @@ extern void bta_dm_search_cancel_notify (tBTA_DM_MSG *p_data); extern void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG *p_data); extern void bta_dm_disc_rmt_name (tBTA_DM_MSG *p_data); extern tBTA_DM_PEER_DEVICE *bta_dm_find_peer_device(BD_ADDR peer_addr); -void bta_dm_eir_update_uuid(UINT16 uuid16, BOOLEAN adding); +void bta_dm_eir_update_uuid(tBT_UUID uuid, BOOLEAN adding); extern void bta_dm_enable_test_mode(tBTA_DM_MSG *p_data); extern void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data); @@ -1726,4 +1886,14 @@ extern void bta_dm_ble_gap_ext_scan(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_prefer_ext_conn_params(tBTA_DM_MSG *p_data); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +extern void bta_dm_ble_gap_periodic_adv_recv_enable(tBTA_DM_MSG *p_data); + +extern void bta_dm_ble_gap_periodic_adv_sync_trans(tBTA_DM_MSG *p_data); + +extern void bta_dm_ble_gap_periodic_adv_set_info_trans(tBTA_DM_MSG *p_data); + +extern void bta_dm_ble_gap_set_periodic_adv_sync_trans_params(tBTA_DM_MSG *p_data); +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + #endif /* BTA_DM_INT_H */ diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c index 361955262b..543b9b04bf 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_act.c @@ -63,7 +63,7 @@ static void bta_gattc_cmpl_sendmsg(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPLETE *p_data); static void bta_gattc_pop_command_to_send(tBTA_GATTC_CLCB *p_clcb); -static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg); +void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg); static void bta_gattc_enc_cmpl_cback(tGATT_IF gattc_if, BD_ADDR bda); static void bta_gattc_cong_cback (UINT16 conn_id, BOOLEAN congested); static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYPE type, tGATTS_DATA *p_data); @@ -122,8 +122,11 @@ void bta_gattc_reset_discover_st(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_STATUS statu static void bta_gattc_enable(tBTA_GATTC_CB *p_cb) { APPL_TRACE_DEBUG("bta_gattc_enable"); - - if (p_cb->state == BTA_GATTC_STATE_DISABLED) { + /* This is a workaround because the task priority of btc (BTA_GATTC_CLOSE_EVT + in that task) is lower than the priority of the btu task. + Consequently, the p_cb->state fails to be restored to BTA_GATTC_STATE_DISABLED + and remains in the BTA_GATTC_STATE_DISABLING state. */ + if (p_cb->state == BTA_GATTC_STATE_DISABLED || p_cb->state == BTA_GATTC_STATE_DISABLING) { /* initialize control block */ memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB)); bta_gattc_cb.auto_disc = true; @@ -151,7 +154,7 @@ void bta_gattc_disable(tBTA_GATTC_CB *p_cb) APPL_TRACE_DEBUG("bta_gattc_disable"); if (p_cb->state != BTA_GATTC_STATE_ENABLED) { - APPL_TRACE_ERROR("not enabled or disable in pogress"); + APPL_TRACE_ERROR("not enabled or disable in progress"); return; } @@ -200,7 +203,11 @@ void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data) cb_data.reg_oper.status = BTA_GATT_NO_RESOURCES; /* check if GATTC module is already enabled . Else enable */ - if (p_cb->state == BTA_GATTC_STATE_DISABLED) { + /* This is a workaround because the task priority of btc (BTA_GATTC_CLOSE_EVT + in that task) is lower than the priority of the btu task. + Consequently, the p_cb->state fails to be restored to BTA_GATTC_STATE_DISABLED + and remains in the BTA_GATTC_STATE_DISABLING state. */ + if (p_cb->state == BTA_GATTC_STATE_DISABLED || p_cb->state == BTA_GATTC_STATE_DISABLING) { bta_gattc_enable (p_cb); } /* todo need to check duplicate uuid */ @@ -220,7 +227,7 @@ void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data) if ((p_buf = (tBTA_GATTC_INT_START_IF *) osi_malloc(sizeof(tBTA_GATTC_INT_START_IF))) != NULL) { p_buf->hdr.event = BTA_GATTC_INT_START_IF_EVT; p_buf->client_if = p_cb->cl_rcb[i].client_if; - APPL_TRACE_DEBUG("GATTC getbuf sucess.\n"); + APPL_TRACE_DEBUG("GATTC getbuf success.\n"); bta_sys_sendmsg(p_buf); status = BTA_GATT_OK; } else { @@ -834,6 +841,9 @@ void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) (* p_cback)(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC *)&cb_data); } + // Please note that BTA_GATTC_CLOSE_EVT will run in the BTC task. + // because bta_gattc_deregister_cmpl did not execute as expected(this is a known issue), + // we will run it again in bta_gattc_clcb_dealloc_by_conn_id. if (p_clreg->num_clcb == 0 && p_clreg->dereg_pending) { bta_gattc_deregister_cmpl(p_clreg); } @@ -1174,6 +1184,37 @@ void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) } /******************************************************************************* ** +** Function bta_gattc_read_multi_var +** +** Description read multiple variable +** +** Returns None. +*********************************************************************************/ +void bta_gattc_read_multi_var(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) +{ + tBTA_GATT_STATUS status = BTA_GATT_OK; + tGATT_READ_PARAM read_param; + + if (bta_gattc_enqueue(p_clcb, p_data)) { + memset(&read_param, 0, sizeof(tGATT_READ_PARAM)); + + if (status == BTA_GATT_OK) { + read_param.read_multiple.num_handles = p_data->api_read_multi.num_attr; + read_param.read_multiple.auth_req = p_data->api_read_multi.auth_req; + memcpy(&read_param.read_multiple.handles, p_data->api_read_multi.handles, + sizeof(UINT16) * p_data->api_read_multi.num_attr); + + status = GATTC_Read(p_clcb->bta_conn_id, GATT_READ_MULTIPLE_VAR, &read_param); + } + + /* read fail */ + if (status != BTA_GATT_OK) { + bta_gattc_cmpl_sendmsg(p_clcb->bta_conn_id, GATTC_OPTYPE_READ, status, NULL); + } + } +} +/******************************************************************************* +** ** Function bta_gattc_write ** ** Description Write an attribute @@ -1289,7 +1330,8 @@ void bta_gattc_read_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_OP_CMPL *p_data) cb_data.read.handle = p_clcb->p_q_cmd->api_read.handle; } - if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) { + if (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT && + p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_VAR_EVT) { event = p_clcb->p_q_cmd->api_read.cmpl_evt; } else { event = p_clcb->p_q_cmd->api_read_multi.cmpl_evt; @@ -1426,7 +1468,9 @@ void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) return; } if (p_clcb->p_q_cmd->hdr.event != bta_gattc_opcode_to_int_evt[op - GATTC_OPTYPE_READ]) { - if ((p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT)&&(p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_BY_TYPE_EVT)) { + if ((p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_EVT) && + (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_BY_TYPE_EVT) && + (p_clcb->p_q_cmd->hdr.event != BTA_GATTC_API_READ_MULTI_VAR_EVT)) { mapped_op = p_clcb->p_q_cmd->hdr.event - BTA_GATTC_API_READ_EVT + GATTC_OPTYPE_READ; if ( mapped_op > GATTC_OPTYPE_INDICATION) { mapped_op = 0; @@ -1631,7 +1675,7 @@ void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) ** Returns void ** *******************************************************************************/ -static void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg) +void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg) { tBTA_GATTC_CB *p_cb = &bta_gattc_cb; tBTA_GATTC_IF client_if = p_clreg->client_if; @@ -2077,7 +2121,7 @@ void bta_gattc_process_indicate(UINT16 conn_id, tGATTC_OPTYPE op, tGATT_CL_COMPL bta_gattc_proc_other_indication(p_clcb, op, p_data, ¬ify); } } else if (op == GATTC_OPTYPE_INDICATION) { - /* no one intersted and need ack? */ + /* no one interested and need ack? */ APPL_TRACE_DEBUG("%s no one interested, ack now", __func__); GATTC_SendHandleValueConfirm(conn_id, handle); } @@ -2194,7 +2238,7 @@ static void bta_gattc_req_cback (UINT16 conn_id, UINT32 trans_id, tGATTS_REQ_TYP ** ** Function bta_gattc_init_clcb_conn ** -** Description Initaite a BTA CLCB connection +** Description Initiate a BTA CLCB connection ** ** Returns void ** @@ -2211,7 +2255,7 @@ void bta_gattc_init_clcb_conn(UINT8 cif, BD_ADDR remote_bda) return; } - /* initaite a new connection here */ + /* initiate a new connection here */ if ((p_clcb = bta_gattc_clcb_alloc(cif, remote_bda, BTA_GATT_TRANSPORT_LE)) != NULL) { gattc_data.hdr.layer_specific = p_clcb->bta_conn_id = conn_id; 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 f5e17a977c..6e2586d69c 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_api.c @@ -563,6 +563,42 @@ void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi, return; } +/******************************************************************************* +** +** Function BTA_GATTC_ReadMultipleVariable +** +** Description This function is called to read multiple variable length characteristic or +** characteristic descriptors. +** +** Parameters conn_id - connection ID. +** p_read_multi - pointer to the read multiple parameter. +** +** Returns None +** +*******************************************************************************/ +void BTA_GATTC_ReadMultipleVariable(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi, + tBTA_GATT_AUTH_REQ auth_req) +{ + tBTA_GATTC_API_READ_MULTI *p_buf; + UINT16 len = (UINT16)(sizeof(tBTA_GATTC_API_READ_MULTI)); + + if ((p_buf = (tBTA_GATTC_API_READ_MULTI *) osi_malloc(len)) != NULL) { + memset(p_buf, 0, len); + + p_buf->hdr.event = BTA_GATTC_API_READ_MULTI_VAR_EVT; + p_buf->hdr.layer_specific = conn_id; + p_buf->auth_req = auth_req; + p_buf->num_attr = p_read_multi->num_attr; + p_buf->cmpl_evt = BTA_GATTC_READ_MULTI_VAR_EVT; + if (p_buf->num_attr > 0) { + memcpy(p_buf->handles, p_read_multi->handles, sizeof(UINT16) * p_read_multi->num_attr); + } + + bta_sys_sendmsg(p_buf); + } + return; +} + /******************************************************************************* ** ** Function BTA_GATTC_Read_by_type @@ -896,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 { @@ -1181,30 +1217,5 @@ uint8_t BTA_GATTC_ReadLongChar(uint8_t gatt_if, uint16_t conn_id, uint16_t handl return 0; } - -uint8_t BTA_GATTC_ReadMultiVariableChar(uint8_t gatt_if, uint16_t conn_id, uint16_t num_handles, uint16_t *handles, uint8_t auth_req) -{ - tGATT_STATUS status; - tGATT_READ_PARAM read_param; - - if (num_handles > GATT_MAX_READ_MULTI_HANDLES) { - APPL_TRACE_ERROR("%s max read multi handlse %x", __func__, num_handles); - return -1; - } - - conn_id = (UINT16)((((UINT8)conn_id) << 8) | gatt_if); - memset (&read_param, 0, sizeof(tGATT_READ_PARAM)); - read_param.read_multiple.num_handles = num_handles; - memcpy(read_param.read_multiple.handles, handles, num_handles); - read_param.read_multiple.auth_req = auth_req; - - status = GATTC_Read(conn_id, GATT_READ_MULTIPLE_VAR, &read_param); - if (status != GATT_SUCCESS) { - APPL_TRACE_ERROR("%s status %x", __func__, status); - return -1; - } - - return 0; -} /* End BLE PTS */ #endif /* defined(GATTC_INCLUDED) && (GATTC_INCLUDED == TRUE) */ diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_co.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_co.c index 01b107cee9..8ec3a55dff 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_co.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_co.c @@ -139,7 +139,7 @@ static bool cacheOpen(BD_ADDR bda, bool to_save, UINT8 *index) return ((status == ESP_OK) ? true : false); } -static void cacheReset(BD_ADDR bda) +static void cacheReset(BD_ADDR bda, BOOLEAN update) { char fname[255] = {0}; getFilename(fname, bda); @@ -177,9 +177,16 @@ static void cacheReset(BD_ADDR bda) for(UINT8 i = index; i < (num - 1); i++) { memcpy(&cache_env->cache_addr[i], &cache_env->cache_addr[i+1], sizeof(cache_addr_info_t)); } + //clear the last cache when delete a addr + memset(&cache_env->cache_addr[num-1], 0, sizeof(cache_addr_info_t)); //reduced the number address counter also cache_env->num_addr--; + //don't need to update addr list to nvs flash + if (!update) { + return; + } + //update addr list to nvs flash if(cache_env->num_addr > 0) { //update @@ -376,7 +383,7 @@ void bta_gattc_co_cache_close(BD_ADDR server_bda, UINT16 conn_id) *******************************************************************************/ void bta_gattc_co_cache_reset(BD_ADDR server_bda) { - cacheReset(server_bda); + cacheReset(server_bda, TRUE); } void bta_gattc_co_cache_addr_init(void) @@ -503,6 +510,10 @@ UINT8 bta_gattc_co_find_hash_in_cache(hash_key_t hash_key) UINT8 bta_gattc_co_get_addr_num(void) { + if (cache_env == NULL) { + return 0; + } + return cache_env->num_addr; } @@ -520,26 +531,29 @@ void bta_gattc_co_cache_addr_save(BD_ADDR bd_addr, hash_key_t hash_key) UINT8 index = 0; UINT8 new_index = cache_env->num_addr; UINT8 *p_buf = osi_malloc(MAX_ADDR_LIST_CACHE_BUF); - // check the address list has the same hash key or not - if (bta_gattc_co_find_hash_in_cache(hash_key) != INVALID_ADDR_NUM) { - APPL_TRACE_DEBUG("%s(), the hash key already in the cache list.", __func__); - if ((index = bta_gattc_co_find_addr_in_cache(bd_addr)) != INVALID_ADDR_NUM) { - APPL_TRACE_DEBUG("%s(), the hash bd_addr already in the cache list, index = %x", __func__, index); - //if the bd_addr already in the address list, update the hash key in it. - memcpy(cache_env->cache_addr[index].addr, bd_addr, sizeof(BD_ADDR)); - memcpy(cache_env->cache_addr[index].hash_key, hash_key, sizeof(hash_key_t)); - } else { - //if the bd_addr didn't in the address list, added the bd_addr to the last of the address list. - memcpy(cache_env->cache_addr[new_index].hash_key, hash_key, sizeof(hash_key_t)); - memcpy(cache_env->cache_addr[new_index].addr, bd_addr, sizeof(BD_ADDR)); - cache_env->num_addr++; - } + if (p_buf == NULL) { + APPL_TRACE_ERROR("%s malloc failed!", __func__); + return; + } + // check the address list has the same address or not + // for the same address, it's hash key may be change due to service change + if ((index = bta_gattc_co_find_addr_in_cache(bd_addr)) != INVALID_ADDR_NUM) { + APPL_TRACE_DEBUG("%s the bd_addr already in the cache list, index = %x", __func__, index); + //if the bd_addr already in the address list, update the hash key in it. + memcpy(cache_env->cache_addr[index].addr, bd_addr, sizeof(BD_ADDR)); + memcpy(cache_env->cache_addr[index].hash_key, hash_key, sizeof(hash_key_t)); } else { - APPL_TRACE_DEBUG("%s(), num = %d", __func__, new_index + 1); + if (cache_env->num_addr >= MAX_DEVICE_IN_CACHE) { + APPL_TRACE_WARNING("%s cache list full and remove the oldest addr info", __func__); + cacheReset(cache_env->cache_addr[0].addr, FALSE); + } + new_index = cache_env->num_addr; + assert(new_index < MAX_DEVICE_IN_CACHE); memcpy(cache_env->cache_addr[new_index].addr, bd_addr, sizeof(BD_ADDR)); memcpy(cache_env->cache_addr[new_index].hash_key, hash_key, sizeof(hash_key_t)); cache_env->num_addr++; + APPL_TRACE_DEBUG("%s(), num = %d", __func__, cache_env->num_addr); } nvs_handle_t *fp = &cache_env->addr_fp; @@ -567,10 +581,10 @@ void bta_gattc_co_cache_addr_save(BD_ADDR bd_addr, hash_key_t hash_key) APPL_TRACE_ERROR("%s, Line = %d, nvs flash open fail, err_code = %x", __func__, __LINE__, err_code); } } + //free the buffer after used. osi_free(p_buf); return; - } BOOLEAN bta_gattc_co_cache_new_assoc_list(BD_ADDR src_addr, UINT8 index) diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c index bf5a9a9270..0cc55995a5 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_main.c @@ -66,6 +66,7 @@ enum { BTA_GATTC_RESTART_DISCOVER, BTA_GATTC_CFG_MTU, BTA_GATTC_READ_BY_TYPE, + BTA_GATTC_READ_MULTI_VAR, BTA_GATTC_IGNORE }; @@ -100,7 +101,8 @@ const tBTA_GATTC_ACTION bta_gattc_action[] = { bta_gattc_disc_close, bta_gattc_restart_discover, bta_gattc_cfg_mtu, - bta_gattc_read_by_type + bta_gattc_read_by_type, + bta_gattc_read_multi_var, }; @@ -137,6 +139,7 @@ static const UINT8 bta_gattc_st_idle[][BTA_GATTC_NUM_COLS] = { /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST}, /* BTA_GATTC_API_READ_BY_TYPE_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST}, + /* BTA_GATTC_API_READ_MULTI_VAR_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST}, }; /* state table for wait for open state */ @@ -167,6 +170,7 @@ static const UINT8 bta_gattc_st_w4_conn[][BTA_GATTC_NUM_COLS] = { /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_OPEN_FAIL, BTA_GATTC_IDLE_ST}, /* BTA_GATTC_API_READ_BY_TYPE_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST}, + /* BTA_GATTC_API_READ_MULTI_VAR_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST}, }; /* state table for open state */ @@ -198,6 +202,7 @@ static const UINT8 bta_gattc_st_connected[][BTA_GATTC_NUM_COLS] = { /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST}, /* BTA_GATTC_API_READ_BY_TYPE_EVT */ {BTA_GATTC_READ_BY_TYPE, BTA_GATTC_CONN_ST}, + /* BTA_GATTC_API_READ_MULTI_VAR_EVT */ {BTA_GATTC_READ_MULTI_VAR, BTA_GATTC_CONN_ST}, }; /* state table for discover state */ @@ -228,6 +233,7 @@ static const UINT8 bta_gattc_st_discover[][BTA_GATTC_NUM_COLS] = { /* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST}, /* BTA_GATTC_API_READ_BY_TYPE_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST}, + /* BTA_GATTC_API_READ_MULTI_VAR_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST}, }; /* type for state table */ @@ -487,6 +493,8 @@ static char *gattc_evt_code(tBTA_GATTC_INT_EVT evt_code) return "BTA_GATTC_API_CFG_MTU_EVT"; case BTA_GATTC_API_READ_BY_TYPE_EVT: return "BTA_GATTC_API_READ_BY_TYPE_EVT"; + case BTA_GATTC_API_READ_MULTI_VAR_EVT: + return "BTA_GATTC_API_READ_MULTI_VAR_EVT"; default: return "unknown GATTC event code"; } @@ -526,4 +534,17 @@ void bta_gattc_deinit(void) FREE_AND_RESET(bta_gattc_cb_ptr); #endif /* #if BTA_DYNAMIC_MEMORY */ } + +uint8_t bta_gattc_cl_rcb_active_count(void) +{ + uint8_t count = 0; + + for (uint8_t i = 0; i < BTA_GATTC_CL_MAX; i ++) { + if (bta_gattc_cb.cl_rcb[i].in_use) { + count++; + } + } + + return count; +} #endif /* GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE */ diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c index 74158e930f..b47a9d9733 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gattc_utils.c @@ -160,7 +160,7 @@ UINT8 bta_gattc_num_reg_app(void) ** ** Function bta_gattc_find_clcb_by_cif ** -** Description get clcb by client interface and remote bd adddress +** Description get clcb by client interface and remote bd address ** ** Returns pointer to the clcb ** @@ -322,12 +322,18 @@ void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb) } } +extern void bta_gattc_deregister_cmpl(tBTA_GATTC_RCB *p_clreg); void bta_gattc_clcb_dealloc_by_conn_id(UINT16 conn_id) { tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id); if (p_clcb) { + tBTA_GATTC_RCB *p_clreg = p_clcb->p_rcb; bta_gattc_clcb_dealloc(p_clcb); + // there is a workaround: if there is no connect, we will reset it. + if (p_clreg && p_clreg->num_clcb == 0 && p_clreg->dereg_pending) { + bta_gattc_deregister_cmpl(p_clreg); + } } } @@ -517,7 +523,7 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) cmd_data->api_write.p_value = (UINT8 *)(cmd_data + 1); memcpy(cmd_data->api_write.p_value, p_data->api_write.p_value, len); } else { - APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memery.", __func__, __LINE__); + APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__); return FALSE; } } else { @@ -525,7 +531,7 @@ BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data) memset(cmd_data, 0, sizeof(tBTA_GATTC_DATA)); memcpy(cmd_data, p_data, sizeof(tBTA_GATTC_DATA)); } else { - APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memery.", __func__, __LINE__); + APPL_TRACE_ERROR("%s(), line = %d, alloc fail, no memory.", __func__, __LINE__); return FALSE; } } @@ -679,7 +685,7 @@ BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda #if (!CONFIG_BT_STACK_NO_LOG) char bdstr[18] = {0}; #endif - APPL_TRACE_ERROR("%s unable to find the bg connection mask for: %s", __func__, + APPL_TRACE_WARNING("%s unable to find the bg connection mask for: %s", __func__, bdaddr_to_string((bt_bdaddr_t *)remote_bda_ptr, bdstr, sizeof(bdstr))); } return FALSE; @@ -919,7 +925,7 @@ BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda) ** ** Function bta_gattc_find_int_conn_clcb ** -** Description try to locate a clcb when an internal connecion event arrives. +** Description try to locate a clcb when an internal connection event arrives. ** ** Returns pointer to the clcb ** diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c index ca2538696d..d09eaa96b2 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_act.c @@ -495,11 +495,11 @@ void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_ /******************************************************************************* ** -** Function bta_gatts_add_char_descr +** Function bta_gatts_set_attr_value ** -** Description action function to add characteristic descriptor. +** Description This function is used to set the attribute value. ** -** Returns none. +** Returns None. ** *******************************************************************************/ void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg) @@ -526,8 +526,23 @@ void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_ } } +/******************************************************************************* +** +** Function bta_gatts_get_attr_value +** +** Description This function retrieves the attribute value associated with +** the given attribute handle. +** +** Returns tGATT_STATUS - GATT status indicating success or failure in +** retrieving the attribute value. +** +*******************************************************************************/ + tGATT_STATUS bta_gatts_get_attr_value(UINT16 attr_handle, UINT16 *length, UINT8 **value) { + if (GATTS_GetAttributeValueInternal(attr_handle, length, value) == 0) { + return 0; + } return GATTS_GetAttributeValue(attr_handle, length, value); } @@ -904,6 +919,22 @@ void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg) } } +/******************************************************************************* +** +** Function bta_gatts_show_local_database +** +** Description print loacl service database +** +** Returns none. +** +*******************************************************************************/ +void bta_gatts_show_local_database (void) +{ + if (GATTS_ShowLocalDatabase()) { + APPL_TRACE_ERROR("%s failed", __func__); + } +} + /******************************************************************************* ** ** Function bta_gatts_request_cback diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c index 03e584f12b..ffe3abec6a 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_api.c @@ -667,4 +667,14 @@ uint8_t BTA_GATTS_SendMultiNotification(uint8_t gatt_if, uint16_t conn_id, void return 0; } + +void BTA_GATTS_ShowLocalDatabase(void) +{ + BT_HDR *p_buf; + + if ((p_buf = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) { + p_buf->event = BTA_GATTS_API_SHOW_LOCAL_DATABASE_EVT; + bta_sys_sendmsg(p_buf); + } +} #endif /* BTA_GATT_INCLUDED */ diff --git a/components/bt/host/bluedroid/bta/gatt/bta_gatts_main.c b/components/bt/host/bluedroid/bta/gatt/bta_gatts_main.c index 993b384d7d..fe83d151bb 100644 --- a/components/bt/host/bluedroid/bta/gatt/bta_gatts_main.c +++ b/components/bt/host/bluedroid/bta/gatt/bta_gatts_main.c @@ -133,6 +133,9 @@ BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg) case BTA_GATTS_API_SEND_SERVICE_CHANGE_EVT: bta_gatts_send_service_change_indication((tBTA_GATTS_DATA *) p_msg); break; + case BTA_GATTS_API_SHOW_LOCAL_DATABASE_EVT: + bta_gatts_show_local_database(); + break; default: break; } @@ -149,4 +152,17 @@ void bta_gatts_deinit(void) #endif /* #if BTA_DYNAMIC_MEMORY */ } +uint8_t bta_gatts_srvc_active_count(void) +{ + uint8_t count = 0; + + for (uint8_t i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i ++) { + if (bta_gatts_cb.srvc_cb[i].in_use) { + count++; + } + } + + return count; +} + #endif /* GATTS_INCLUDED */ 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 45caacf67b..108358ca63 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 @@ -61,6 +61,7 @@ enum { BTA_GATTC_INT_DISCONN_EVT, BTA_GATTC_API_READ_BY_TYPE_EVT, + BTA_GATTC_API_READ_MULTI_VAR_EVT, BTA_GATTC_INT_START_IF_EVT, BTA_GATTC_API_REG_EVT, @@ -318,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; @@ -469,6 +466,7 @@ extern void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); +extern void bta_gattc_read_multi_var(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_ci_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); extern void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data); diff --git a/components/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h b/components/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h index 30f14ac4d5..51d6fd4ed6 100644 --- a/components/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h +++ b/components/bt/host/bluedroid/bta/gatt/include/bta_gatts_int.h @@ -53,7 +53,8 @@ enum { BTA_GATTS_API_CLOSE_EVT, BTA_GATTS_API_LISTEN_EVT, BTA_GATTS_API_DISABLE_EVT, - BTA_GATTS_API_SEND_SERVICE_CHANGE_EVT + BTA_GATTS_API_SEND_SERVICE_CHANGE_EVT, + BTA_GATTS_API_SHOW_LOCAL_DATABASE_EVT }; typedef UINT16 tBTA_GATTS_INT_EVT; @@ -251,6 +252,7 @@ extern void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg); extern void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg); extern void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg); extern void bta_gatts_send_service_change_indication (tBTA_GATTS_DATA *p_msg); +extern void bta_gatts_show_local_database (void); extern BOOLEAN bta_gatts_uuid_compare(tBT_UUID tar, tBT_UUID src); extern tBTA_GATTS_RCB *bta_gatts_find_app_rcb_by_app_if(tBTA_GATTS_IF server_if); diff --git a/components/bt/host/bluedroid/bta/hd/bta_hd_act.c b/components/bt/host/bluedroid/bta/hd/bta_hd_act.c index 8f655d73fe..220b86cf2f 100644 --- a/components/bt/host/bluedroid/bta/hd/bta_hd_act.c +++ b/components/bt/host/bluedroid/bta/hd/bta_hd_act.c @@ -722,6 +722,26 @@ extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data) bta_sys_idle(BTA_ID_HD, 1, p_cback->addr); } +/******************************************************************************* + * + * Function bta_hd_open_failure + * + * Description + * + * Returns void + * + ******************************************************************************/ +extern void bta_hd_open_failure(tBTA_HD_DATA *p_data) +{ + tBTA_HD_CBACK_DATA *p_cback = (tBTA_HD_CBACK_DATA *)p_data; + tBTA_HD cback_data = {0}; + + bdcpy(cback_data.conn.bda, p_cback->addr); + cback_data.conn.status = BTA_HD_ERROR; + cback_data.conn.conn_status = BTA_HD_CONN_STATE_DISCONNECTED; + bta_hd_cb.p_cback(BTA_HD_OPEN_EVT, &cback_data); +} + /******************************************************************************* * * Function bta_hd_cback diff --git a/components/bt/host/bluedroid/bta/hd/bta_hd_main.c b/components/bt/host/bluedroid/bta/hd/bta_hd_main.c index 2dd086cf2d..7faaf2d6cd 100644 --- a/components/bt/host/bluedroid/bta/hd/bta_hd_main.c +++ b/components/bt/host/bluedroid/bta/hd/bta_hd_main.c @@ -62,6 +62,7 @@ enum { BTA_HD_VC_UNPLUG_DONE_ACT, BTA_HD_SUSPEND_ACT, BTA_HD_EXIT_SUSPEND_ACT, + BTA_HD_OPEN_FAILURE, BTA_HD_NUM_ACTIONS }; @@ -74,7 +75,7 @@ const tBTA_HD_ACTION bta_hd_action[] = { bta_hd_disconnect_act, bta_hd_add_device_act, bta_hd_remove_device_act, bta_hd_send_report_act, bta_hd_report_error_act, bta_hd_vc_unplug_act, bta_hd_open_act, bta_hd_close_act, bta_hd_intr_data_act, bta_hd_get_report_act, bta_hd_set_report_act, bta_hd_set_protocol_act, - bta_hd_vc_unplug_done_act, bta_hd_suspend_act, bta_hd_exit_suspend_act, + bta_hd_vc_unplug_done_act, bta_hd_suspend_act, bta_hd_exit_suspend_act, bta_hd_open_failure }; /* state table information */ @@ -118,7 +119,7 @@ const uint8_t bta_hd_st_idle[][BTA_HD_NUM_COLS] = { /* BTA_HD_API_REPORT_ERROR_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, /* BTA_HD_API_VC_UNPLUG_EVT */ {BTA_HD_VC_UNPLUG_ACT, BTA_HD_IDLE_ST}, /* BTA_HD_INT_OPEN_EVT */ {BTA_HD_OPEN_ACT, BTA_HD_CONN_ST}, - /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, + /* BTA_HD_INT_CLOSE_EVT */ {BTA_HD_OPEN_FAILURE, BTA_HD_IDLE_ST}, /* BTA_HD_INT_INTR_DATA_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, /* BTA_HD_INT_GET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, /* BTA_HD_INT_SET_REPORT_EVT */ {BTA_HD_IGNORE, BTA_HD_IDLE_ST}, @@ -317,4 +318,21 @@ static const char *bta_hd_state_code(tBTA_HD_STATE state_code) return ""; } } + +#if BT_HID_DEVICE_BQB_INCLUDED +tBTA_STATUS bta_hd_bqb_set_local_di_record(void) +{ + tBTA_STATUS status = BTA_FAILURE; + + tBTA_DI_RECORD bqb_device_info; + bqb_device_info.vendor = 0; + bqb_device_info.vendor_id_source = 0xff; // BTA_HH_VENDOR_ID_INVALID + bqb_device_info.product = 1; + bqb_device_info.version = 0; + bqb_device_info.primary_record = TRUE; + + return BTA_DmSetLocalDiRecord(&bqb_device_info, &bta_hd_cb.sdp_handle); +} +#endif /* BT_HID_DEVICE_BQB_INCLUDED */ + #endif /* BTA_HD_INCLUDED */ diff --git a/components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h b/components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h index 7a515970e6..48ac7ed846 100644 --- a/components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h +++ b/components/bt/host/bluedroid/bta/hd/include/bta_hd_int.h @@ -164,5 +164,6 @@ extern void bta_hd_set_protocol_act(tBTA_HD_DATA *p_data); extern void bta_hd_vc_unplug_done_act(tBTA_HD_DATA *p_data); extern void bta_hd_suspend_act(tBTA_HD_DATA *p_data); extern void bta_hd_exit_suspend_act(tBTA_HD_DATA *p_data); +extern void bta_hd_open_failure(tBTA_HD_DATA *p_data); #endif diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c index cc92328267..c2e2773792 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_act.c @@ -397,10 +397,6 @@ void bta_ag_rfc_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) bta_sys_conn_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr); - /* call close call-out */ -#if (BTM_SCO_HCI_INCLUDED == TRUE) - bta_ag_sco_co_close(); -#endif /* call close cback */ (*bta_ag_cb.p_cback)(BTA_AG_CLOSE_EVT, (tBTA_AG *) &close); @@ -785,14 +781,17 @@ void bta_ag_rcvd_slc_ready(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) void bta_ag_setcodec(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) { #if (BTM_WBS_INCLUDED == TRUE) + UINT16 handle = p_data->api_setcodec.hdr.layer_specific; tBTA_AG_PEER_CODEC codec_type = p_data->api_setcodec.codec; tBTA_AG_VAL val; + val.hdr.handle = handle; + val.num = codec_type; + /* Check if the requested codec type is valid */ if((codec_type != BTA_AG_CODEC_NONE) && (codec_type != BTA_AG_CODEC_CVSD) && (codec_type != BTA_AG_CODEC_MSBC)) { - val.num = codec_type; val.hdr.status = BTA_AG_FAIL_RESOURCES; APPL_TRACE_ERROR("%s error: unsupported codec type %d", __func__, codec_type); (*bta_ag_cb.p_cback)(BTA_AG_WBS_EVT, (tBTA_AG *) &val); @@ -804,11 +803,9 @@ void bta_ag_setcodec(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) (codec_type == BTA_AG_CODEC_CVSD)) { p_scb->sco_codec = codec_type; p_scb->codec_updated = TRUE; - val.num = codec_type; val.hdr.status = BTA_AG_SUCCESS; APPL_TRACE_DEBUG("%s: Updated codec type %d", __func__, codec_type); } else { - val.num = codec_type; val.hdr.status = BTA_AG_FAIL_RESOURCES; APPL_TRACE_ERROR("%s error: unsupported codec type %d",__func__, codec_type); } diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c index 91a78c37eb..4b1d91eef5 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_api.c @@ -245,7 +245,6 @@ void BTA_AgAudioClose(UINT16 handle) } } - /******************************************************************************* ** ** Function BTA_AgResult @@ -297,7 +296,30 @@ void BTA_AgSetCodec(UINT16 handle, tBTA_AG_PEER_CODEC codec) } } -#if (BTM_SCO_HCI_INCLUDED == TRUE ) +#if (BTM_SCO_HCI_INCLUDED == TRUE) +/******************************************************************************* +** +** Function BTA_AgPktStatsNumsGet +** +** Description Specify the sync_conn_handle to be used for the packet numbers +** received or send. +** +** +** Returns void +** +*******************************************************************************/ +void BTA_AgPktStatsNumsGet(UINT16 handle, UINT16 sync_conn_handle) +{ + tBTA_AG_PKT_STAT_GET *p_buf; + + if ((p_buf = (tBTA_AG_PKT_STAT_GET *) osi_malloc(sizeof(tBTA_AG_PKT_STAT_GET))) != NULL) { + p_buf->hdr.event = BTA_AG_PKT_STAT_NUMS_GET_EVT; + p_buf->hdr.layer_specific = handle; + p_buf->sync_conn_handle = sync_conn_handle; + bta_sys_sendmsg(p_buf); + } +} + /************************************************************************************************ * Function BTA_AgCiData * @@ -317,6 +339,6 @@ void BTA_AgCiData(UINT16 handle) bta_sys_sendmsg(p_buf); } } -#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE ) */ +#endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE) */ #endif /* #if (BTA_AG_INCLUDED == TRUE)*/ diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c index 2f997c0f31..6bccfe1b7e 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_cmd.c @@ -36,6 +36,9 @@ #include "stack/port_api.h" #include "bta/utl.h" +#if BT_HF_AG_BQB_INCLUDED +static BOOLEAN s_bta_hf_ag_bqb_brsf_flag = false; +#endif /* BT_HF_AG_BQB_INCLUDED */ #if (BTA_AG_INCLUDED == TRUE) /***************************************************************************** @@ -146,6 +149,14 @@ enum BTA_AG_HF_CMD_BAC }; +/* dialing type of BTA_AG_HF_CMD_D */ +enum +{ + BTA_AG_HF_DIAL_NUM = 0, + BTA_AG_HF_DIAL_VOIP, + BTA_AG_HF_DIAL_MEM, +}; + /* HFP AT command interpreter table */ const tBTA_AG_AT_CMD bta_ag_hfp_cmd[] = { @@ -330,6 +341,22 @@ const UINT8 bta_ag_callsetup_ind_tbl[] = #define COLON_IDX_4_VGSVGM 4 #endif +/******************************************************************************* +** +** Function bta_hf_ag_bqb_brsf_ctrl +** +** Description Control the usage of BTA_AG_BQB_BRSF_FEAT_SPEC for BQB test +** +** Returns void +** +*******************************************************************************/ +#if BT_HF_AG_BQB_INCLUDED +void bta_hf_ag_bqb_brsf_ctrl(BOOLEAN enable) +{ + s_bta_hf_ag_bqb_brsf_flag = enable; +} +#endif /* BT_HF_AG_BQB_INCLUDED */ + /******************************************* * Funcitons Result ********************************************/ @@ -856,6 +883,8 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type, case BTA_AG_HF_CMD_D: { + UINT16 src = 0; + UINT16 dst = 0; /* Do not send OK for Dial cmds Let application decide whether to send OK or ERROR*/ /* if mem dial cmd, make sure string contains only digits */ if(p_arg[0] == '>') { @@ -863,6 +892,8 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type, event = 0; bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_DSTR); } + val.value = BTA_AG_HF_DIAL_MEM; + src = 1; } else if (p_arg[0] == 'V') { /* ATDV : Dial VoIP Call */ /* We do not check string. Code will be added later if needed. */ @@ -870,6 +901,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type, event = 0; bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED); } + val.value = BTA_AG_HF_DIAL_VOIP; } else { /* If dial cmd, make sure string contains only dial digits ** Dial digits are 0-9, A-C, *, #, + */ @@ -877,6 +909,17 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type, event = 0; bta_ag_send_error(p_scb, BTA_AG_ERR_INV_CHAR_IN_DSTR); } + val.value = BTA_AG_HF_DIAL_NUM; + } + if (event != 0) { + while ((val.str[dst] = p_arg[src]) != '\0') { + if (val.str[dst] == ';') { + val.str[dst] = '\0'; + break; + } + src++; + dst++; + } } break; } @@ -1001,7 +1044,15 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type, /* store peer features */ p_scb->peer_features = (UINT16) int_arg; /* send BRSF, send OK */ - bta_ag_send_result(p_scb, BTA_AG_RES_BRSF, NULL, (INT16) (p_scb->features & BTA_AG_BSRF_FEAT_SPEC)); +#if BT_HF_AG_BQB_INCLUDED + if (s_bta_hf_ag_bqb_brsf_flag == true) { + bta_ag_send_result(p_scb, BTA_AG_RES_BRSF, NULL, (INT16) (p_scb->features & BTA_AG_BQB_BRSF_FEAT_SPEC)); + } else { + bta_ag_send_result(p_scb, BTA_AG_RES_BRSF, NULL, (INT16) (p_scb->features & BTA_AG_BRSF_FEAT_SPEC)); + } +#else + bta_ag_send_result(p_scb, BTA_AG_RES_BRSF, NULL, (INT16) (p_scb->features & BTA_AG_BRSF_FEAT_SPEC)); +#endif /* BT_HF_AG_BQB_INCLUDED */ bta_ag_send_ok(p_scb); break; } @@ -1498,7 +1549,6 @@ void bta_ag_hfp_result(tBTA_AG_SCB *p_scb, tBTA_AG_API_RESULT *p_result) if (p_result->data.ok_flag != BTA_AG_OK_ERROR) { if (p_result->data.str[0] != 0) { bta_ag_send_result(p_scb, code, p_result->data.str, 0); - bta_ag_send_ok(p_scb); } if (p_result->data.ok_flag == BTA_AG_OK_DONE) { bta_ag_send_ok(p_scb); diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c index e3a505ddfd..bcf3cc6ec0 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_main.c @@ -91,6 +91,7 @@ enum BTA_AG_CI_SCO_DATA, BTA_AG_CI_RX_DATA, BTA_AG_RCVD_SLC_READY, + BTA_AG_PKT_STAT_NUMS, BTA_AG_NUM_ACTIONS }; @@ -133,7 +134,8 @@ const tBTA_AG_ACTION bta_ag_action[] = bta_ag_send_ring, bta_ag_ci_sco_data, bta_ag_ci_rx_data, - bta_ag_rcvd_slc_ready + bta_ag_rcvd_slc_ready, + bta_ag_pkt_stat_nums }; /* state table information */ @@ -167,7 +169,8 @@ const UINT8 bta_ag_st_init[][BTA_AG_NUM_COLS] = /* RING_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, /* SVC_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, /* CI_SCO_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, -/* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST} +/* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_INIT_ST}, +/* PKT_STAT_NUMS_GET_EVT */ {BTA_AG_PKT_STAT_NUMS, BTA_AG_IGNORE, BTA_AG_INIT_ST} }; /* state table for opening state */ @@ -196,7 +199,8 @@ const UINT8 bta_ag_st_opening[][BTA_AG_NUM_COLS] = /* RING_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, /* SVC_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, /* CI_SCO_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, -/* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST} +/* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_OPENING_ST}, +/* PKT_STAT_NUMS_GET_EVT */ {BTA_AG_PKT_STAT_NUMS, BTA_AG_IGNORE, BTA_AG_OPENING_ST} }; /* state table for open state */ @@ -225,7 +229,8 @@ const UINT8 bta_ag_st_open[][BTA_AG_NUM_COLS] = /* RING_TOUT_EVT */ {BTA_AG_SEND_RING, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, /* SVC_TOUT_EVT */ {BTA_AG_START_CLOSE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, /* CI_SCO_DATA_EVT */ {BTA_AG_CI_SCO_DATA, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, -/* CI_SLC_READY_EVT */ {BTA_AG_RCVD_SLC_READY, BTA_AG_IGNORE, BTA_AG_OPEN_ST} +/* CI_SLC_READY_EVT */ {BTA_AG_RCVD_SLC_READY, BTA_AG_IGNORE, BTA_AG_OPEN_ST}, +/* PKT_STAT_NUMS_GET_EVT */ {BTA_AG_PKT_STAT_NUMS, BTA_AG_IGNORE, BTA_AG_OPEN_ST} }; /* state table for closing state */ @@ -254,7 +259,8 @@ const UINT8 bta_ag_st_closing[][BTA_AG_NUM_COLS] = /* RING_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, /* SVC_TOUT_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, /* CI_SCO_DATA_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, -/* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST} +/* CI_SLC_READY_EVT */ {BTA_AG_IGNORE, BTA_AG_IGNORE, BTA_AG_CLOSING_ST}, +/* PKT_STAT_NUMS_GET_EVT */ {BTA_AG_PKT_STAT_NUMS, BTA_AG_IGNORE, BTA_AG_CLOSING_ST} }; /* type for state table */ @@ -357,6 +363,8 @@ static char *bta_ag_evt_str(UINT16 event, tBTA_AG_RES result) return "SCO data Callin"; case BTA_AG_CI_SLC_READY_EVT: return "SLC Ready Callin"; + case BTA_AG_PKT_STAT_NUMS_GET_EVT: + return "Get Packet Nums"; default: return "Unknown AG Event"; } diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c index 16d4398053..661d237266 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sco.c @@ -342,7 +342,7 @@ static void bta_ag_sco_read_cback(UINT16 sco_inx, BT_HDR *p_data, tBTM_SCO_DATA_ { if (status != BTM_SCO_DATA_CORRECT) { - APPL_TRACE_WARNING("bta_ag_sco_read_cback: status(%d)", status); + APPL_TRACE_DEBUG("bta_ag_sco_read_cback: status(%d)", status); } /* Callout function must free the data. */ @@ -475,6 +475,7 @@ static void bta_ag_cback_sco(tBTA_AG_SCB *p_scb, UINT8 event) sco.handle = bta_ag_scb_to_idx(p_scb); sco.app_id = p_scb->app_id; + sco.sync_conn_handle = BTM_ReadScoHandle(p_scb->sco_idx); /* call close cback */ (*bta_ag_cb.p_cback)(event, (tBTA_AG *) &sco); @@ -1477,6 +1478,32 @@ void bta_ag_sco_codec_nego(tBTA_AG_SCB *p_scb, BOOLEAN result) } #endif +/******************************************************************************* +** +** Function bta_ag_pkt_stat_nums +** +** Description Get the number of packet states +** +** +** Returns void +** +*******************************************************************************/ +void bta_ag_pkt_stat_nums(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) +{ + UNUSED(p_scb); + +#if (BTM_SCO_HCI_INCLUDED == TRUE) + tBTA_AG_PKT_STAT_NUMS pkt_stat_nums; + uint16_t sync_conn_handle = p_data->pkt_stat.sync_conn_handle; + BTM_PktStatNumsGet(sync_conn_handle, (tBTM_SCO_PKT_STAT_NUMS *) &pkt_stat_nums); + + /* call app cback */ + if (bta_ag_cb.p_cback) { + (*bta_ag_cb.p_cback)(BTA_AG_PKT_NUMS_GET_EVT, (tBTA_AG*) &pkt_stat_nums); + } +#endif +} + /******************************************************************************* ** ** Function bta_ag_sco_shutdown diff --git a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c index 583486126b..d35ad4f7c1 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c +++ b/components/bt/host/bluedroid/bta/hf_ag/bta_ag_sdp.c @@ -243,13 +243,16 @@ void bta_ag_del_records(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data) UNUSED(p_data); /* get services of all other registered servers */ - for (i = 0; i < BTA_AG_NUM_IDX; i++, p++) { + for (i = 0; i < BTA_AG_NUM_IDX; i++) { if (p_scb == p) { continue; } if (p->in_use && p->dealloc == FALSE) { others |= p->reg_services; } + if (i < BTA_AG_NUM_SCB) { + p++; + } } others >>= BTA_HSP_SERVICE_ID; services = p_scb->reg_services >> BTA_HSP_SERVICE_ID; diff --git a/components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h b/components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h index 0ba136d31d..9ced8b3665 100644 --- a/components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h +++ b/components/bt/host/bluedroid/bta/hf_ag/include/bta_ag_int.h @@ -76,16 +76,24 @@ #define BTA_AG_ACP 0 /* accepted connection */ #define BTA_AG_INT 1 /* initiating connection */ +#if BT_HF_AG_BQB_INCLUDED +/* feature mask that matches spec for BQB test */ +#define BTA_AG_BQB_BRSF_FEAT_SPEC (BTA_AG_FEAT_VOIP | \ + BTA_AG_FEAT_VTAG | BTA_AG_FEAT_CODEC | \ + BTA_AG_FEAT_ECS | BTA_AG_FEAT_ECC | \ + BTA_AG_FEAT_ESCO_S4 | BTA_AG_FEAT_EXTERR) +#endif /* BT_HF_AG_BQB_INCLUDED */ + /* feature mask that matches spec */ -#define BTA_AG_BSRF_FEAT_SPEC (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | \ - BTA_AG_FEAT_VREC | BTA_AG_FEAT_INBAND | \ - BTA_AG_FEAT_VTAG | BTA_AG_FEAT_REJECT | \ - BTA_AG_FEAT_ECS | BTA_AG_FEAT_ECC | \ - BTA_AG_FEAT_EXTERR | BTA_AG_FEAT_CODEC | \ - BTA_AG_FEAT_ESCO_S4| BTA_AG_FEAT_VOIP) - -#define BTA_AG_SDP_FEAT_SPEC (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | \ - BTA_AG_FEAT_VREC | BTA_AG_FEAT_INBAND | \ +#define BTA_AG_BRSF_FEAT_SPEC (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | \ + BTA_AG_FEAT_VREC | BTA_AG_FEAT_INBAND | \ + BTA_AG_FEAT_VTAG | BTA_AG_FEAT_REJECT | \ + BTA_AG_FEAT_ECS | BTA_AG_FEAT_ECC | \ + BTA_AG_FEAT_EXTERR | BTA_AG_FEAT_CODEC | \ + BTA_AG_FEAT_ESCO_S4 | BTA_AG_FEAT_VOIP) + +#define BTA_AG_SDP_FEAT_SPEC (BTA_AG_FEAT_3WAY | BTA_AG_FEAT_ECNR | \ + BTA_AG_FEAT_VREC | BTA_AG_FEAT_INBAND | \ BTA_AG_FEAT_VTAG) enum @@ -114,6 +122,7 @@ enum BTA_AG_SVC_TOUT_EVT, BTA_AG_CI_SCO_DATA_EVT, BTA_AG_CI_SLC_READY_EVT, + BTA_AG_PKT_STAT_NUMS_GET_EVT, BTA_AG_MAX_EVT, /* these events are handled outside of the state machine */ @@ -219,6 +228,13 @@ typedef struct char p_data[BTA_AG_MTU+1]; } tBTA_AG_CI_RX_WRITE; +/* data type for BTA_AG_PKT_STAT_NUMS_GET_EVT */ +typedef struct +{ + BT_HDR hdr; + UINT16 sync_conn_handle; +} tBTA_AG_PKT_STAT_GET; + /* union of all event datatypes */ typedef union { @@ -233,6 +249,7 @@ typedef union tBTA_AG_DISC_RESULT disc_result; tBTA_AG_RFC rfc; tBTA_AG_CI_RX_WRITE ci_rx_write; + tBTA_AG_PKT_STAT_GET pkt_stat; } tBTA_AG_DATA; /* type for each profile */ @@ -277,7 +294,7 @@ typedef struct tBTA_AG_SCO_MSBC_SETTINGS codec_msbc_settings; /* settings to be used for the impending eSCO */ TIMER_LIST_ENT cn_timer; /* codec negotiation timer */ #endif - UINT16 sco_idx; /* SCO handle */ + UINT16 sco_idx; /* SCO connection index */ BOOLEAN in_use; /* scb in use */ BOOLEAN dealloc; /* TRUE if service shutting down */ BOOLEAN clip_enabled; /* set to TRUE if HF enables CLIP reporting */ @@ -438,6 +455,7 @@ extern void bta_ag_ci_sco_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data); extern void bta_ag_set_esco_param(BOOLEAN set_reset, tBTM_ESCO_PARAMS *param); extern void bta_ag_ci_rx_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data); extern void bta_ag_rcvd_slc_ready(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data); +extern void bta_ag_pkt_stat_nums(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data); #endif /* #if (BTA_AG_INCLUDED == TRUE) */ diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c index 878198a372..6149d8c418 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_api.c @@ -61,7 +61,8 @@ static const uint8_t bta_hf_client_cb_data_size[] = { sizeof(tBTA_HF_CLIENT_VAL), // #define BTA_HF_CLIENT_BSIR_EVT 19 sizeof(tBTA_HF_CLIENT_NUMBER), // #define BTA_HF_CLIENT_BINP_EVT 20 sizeof(tBTA_HF_CLIENT_VAL), // #define BTA_HF_CLIENT_RING_INDICATION 21 - 0, // #define BTA_HF_CLIENT_DISABLE_EVT 30 + 0, // #define BTA_HF_CLIENT_DISABLE_EVT 22 + sizeof(tBTA_SCO_PKT_STAT_NUMS), // #define BTA_HF_CLIENT_PKT_STAT_NUMS_GET_EVT 23 }; /***************************************************************************** ** External Function Declarations @@ -299,7 +300,28 @@ void BTA_HfClientSendAT(UINT16 handle, tBTA_HF_CLIENT_AT_CMD_TYPE at, UINT32 val bta_sys_sendmsg(p_buf); } } -#if (BTM_SCO_HCI_INCLUDED == TRUE ) + +#if (BTM_SCO_HCI_INCLUDED == TRUE) +/******************************************************************************* +** +** Function BTA_HfClientPktStatsNumsGet +** +** Description Get the packet ststus numbers received and send for a specific (e)SCO connection handle. +** +** +** Returns void +** +*******************************************************************************/ +void BTA_HfClientPktStatsNumsGet(UINT16 sync_conn_handle) +{ + tBTA_HF_CLIENT_PKT_STAT_GET *p_buf; + if ((p_buf = (tBTA_HF_CLIENT_PKT_STAT_GET *) osi_malloc(sizeof(tBTA_HF_CLIENT_PKT_STAT_GET))) != NULL) { + p_buf->hdr.event = BTA_HF_CLIENT_PKT_NUMS_GET_EVT; + p_buf->sync_conn_handle = sync_conn_handle; + bta_sys_sendmsg(p_buf); + } +} + void BTA_HfClientCiData(void) { BT_HDR *p_buf; diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c index b47ffcac6e..4124a10f30 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_main.c @@ -25,6 +25,10 @@ #include "bta/bta_hf_client_api.h" #include "bta_hf_client_int.h" +#if BT_HF_CLIENT_BQB_INCLUDED +static BOOLEAN s_bta_hf_client_bqb_clip_flag = TRUE; +#endif /* BT_HF_CLIENT_BQB_INCLUDED */ + #if (BTA_HF_INCLUDED == TRUE) /* uncomment to enable extra debug */ /* #define BTA_HF_CLIENT_DEBUG TRUE */ @@ -75,6 +79,7 @@ enum { BTA_HF_CLIENT_SEND_AT_CMD, #if (BTM_SCO_HCI_INCLUDED == TRUE) BTA_HF_CLIENT_CI_SCO_DATA, + BTA_HF_CLIENT_PKT_STAT_NUMS, #endif BTA_HF_CLIENT_NUM_ACTIONS, }; @@ -111,8 +116,9 @@ const tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = { /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res, /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open, /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd, -#if (BTM_SCO_HCI_INCLUDED == TRUE ) +#if (BTM_SCO_HCI_INCLUDED == TRUE) /* BTA_HF_CLIENT_CI_SCO_DATA */ bta_hf_client_ci_sco_data, + /* BTA_HF_CLIENT_PKT_STAT_NUMS */ bta_hf_client_pkt_stat_nums, #endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */ }; @@ -143,6 +149,7 @@ const UINT8 bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = { /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, #if (BTM_SCO_HCI_INCLUDED == TRUE ) /* CI_SCO_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, + /* PKT_STAT_NUMS_GET_EVT */ {BTA_HF_CLIENT_PKT_STAT_NUMS, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_INIT_ST}, #endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */ }; @@ -166,8 +173,9 @@ const UINT8 bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = { /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, -#if (BTM_SCO_HCI_INCLUDED == TRUE ) +#if (BTM_SCO_HCI_INCLUDED == TRUE) /* CI_SCO_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, + /* PKT_STAT_NUMS_GET_EVT */ {BTA_HF_CLIENT_PKT_STAT_NUMS, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPENING_ST}, #endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */ }; @@ -193,6 +201,7 @@ const UINT8 bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = { /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, #if (BTM_SCO_HCI_INCLUDED == TRUE ) /* CI_SCO_DATA_EVT */ {BTA_HF_CLIENT_CI_SCO_DATA, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, + /* PKT_STAT_NUMS_GET_EVT */ {BTA_HF_CLIENT_PKT_STAT_NUMS, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_OPEN_ST}, #endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */ }; @@ -218,6 +227,7 @@ const UINT8 bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = { /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, #if (BTM_SCO_HCI_INCLUDED == TRUE ) /* CI_SCO_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, + /* PKT_STAT_NUMS_GET_EVT */ {BTA_HF_CLIENT_PKT_STAT_NUMS, BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_CLOSING_ST}, #endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */ }; @@ -241,6 +251,21 @@ tBTA_HF_CLIENT_CB bta_hf_client_cb; tBTA_HF_CLIENT_CB *bta_hf_client_cb_ptr; #endif +/******************************************************************************* +** +** Function bta_hf_client_bqb_clip_ctrl +** +** Description Control if send the command AT+CLIP for BQB test +** +** Returns void +** +*******************************************************************************/ +#if BT_HF_CLIENT_BQB_INCLUDED +void bta_hf_client_bqb_clip_ctrl(BOOLEAN enable) +{ + s_bta_hf_client_bqb_clip_flag = enable; +} +#endif /* BT_HF_CLIENT_BQB_INCLUDED */ /******************************************************************************* ** @@ -532,7 +557,14 @@ static void send_post_slc_cmd(void) bta_hf_client_send_at_cmee(TRUE); bta_hf_client_send_at_cops(FALSE); bta_hf_client_send_at_btrh(TRUE, 0); + +#if BT_HF_CLIENT_BQB_INCLUDED + if (s_bta_hf_client_bqb_clip_flag == TRUE) { + bta_hf_client_send_at_clip(TRUE); + } +#else bta_hf_client_send_at_clip(TRUE); +#endif /* BT_HF_CLIENT_BQB_INCLUDED */ } /******************************************************************************* @@ -640,6 +672,7 @@ static char *bta_hf_client_evt_str(UINT16 event) CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT) CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT) CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT) + CASE_RETURN_STR(BTA_HF_CLIENT_PKT_NUMS_GET_EVT) default: return "Unknown HF Client Event"; } diff --git a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c index 5d7c8ab528..d464a88925 100644 --- a/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c +++ b/components/bt/host/bluedroid/bta/hf_client/bta_hf_client_sco.c @@ -29,6 +29,10 @@ #include "hci/hci_audio.h" #endif +#if BT_HF_CLIENT_BQB_INCLUDED +static BOOLEAN s_bta_hf_client_bqb_esco_s1_flag = false; +#endif /* BT_HF_CLIENT_BQB_INCLUDED */ + #if (BTA_HF_INCLUDED == TRUE) #define BTA_HF_CLIENT_NO_EDR_ESCO (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 | \ BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | \ @@ -39,6 +43,7 @@ #define BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S3 1 /* eSCO setting for CVSD S3 */ #define BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2 2 /* eSCO setting for mSBC T2 */ #define BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S4 3 /* eSCO setting for CVSD S4 */ +#define BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S1 4 /* eSCO setting for CVSD S1 */ static const tBTM_ESCO_PARAMS bta_hf_client_esco_params[] = { /* SCO CVSD */ @@ -91,7 +96,23 @@ static const tBTM_ESCO_PARAMS bta_hf_client_esco_params[] = { BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), .retrans_effort = BTM_ESCO_RETRANS_QUALITY, + }, + /* ESCO CVSD S1 */ +#if BT_HF_CLIENT_BQB_INCLUDED + { + .rx_bw = BTM_64KBITS_RATE, + .tx_bw = BTM_64KBITS_RATE, + .max_latency = 7, + .voice_contfmt = BTM_VOICE_SETTING_CVSD, + /* Packet Types : EV3 */ + .packet_types = (HCI_ESCO_PKT_TYPES_MASK_EV3 | + BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | + BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 | + BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | + BTM_SCO_PKT_TYPES_MASK_NO_3_EV5), + .retrans_effort = BTM_ESCO_RETRANS_POWER, } +#endif /* BT_HF_CLIENT_BQB_INCLUDED */ }; enum { @@ -106,6 +127,22 @@ enum { #endif /* #if (BTM_SCO_HCI_INCLUDED == TRUE ) */ }; +/******************************************************************************* +** +** Function bta_hf_client_bqb_esco_s1_ctrl +** +** Description Control the usage of CVSD eSCO S1 parameter for BQB test +** +** Returns void +** +*******************************************************************************/ +#if BT_HF_CLIENT_BQB_INCLUDED +void bta_hf_client_bqb_esco_s1_ctrl(BOOLEAN enable) +{ + s_bta_hf_client_bqb_esco_s1_flag = enable; +} +#endif /* BT_HF_CLIENT_BQB_INCLUDED */ + static void bta_hf_client_sco_event(UINT8 event); /******************************************************************************* ** @@ -155,6 +192,7 @@ void bta_hf_client_cback_sco(UINT8 event) tBTA_HF_CLIENT_HDR evt; memset(&evt, 0, sizeof(evt)); + evt.sync_conn_handle = BTM_ReadScoHandle(bta_hf_client_cb.scb.sco_idx); /* call app cback */ (*bta_hf_client_cb.p_cback)(event, (tBTA_HF_CLIENT_HDR *) &evt); @@ -213,6 +251,11 @@ static void bta_hf_client_sco_conn_rsp(tBTM_ESCO_CONN_REQ_EVT_DATA *p_data) (bta_hf_client_cb.scb.features && BTA_HF_CLIENT_FEAT_ESCO_S4) && (bta_hf_client_cb.scb.peer_features && BTA_HF_CLIENT_PEER_ESCO_S4)) { index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S4; +#if BT_HF_CLIENT_BQB_INCLUDED + if (s_bta_hf_client_bqb_esco_s1_flag == true) { + index = BTA_HF_CLIENT_ESCO_PARAM_IDX_CVSD_S1; + } +#endif /* BT_HF_CLIENT_BQB_INCLUDED */ } else if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC) { index = BTA_HF_CLIENT_ESCO_PARAM_IDX_MSBC_T2; } @@ -237,7 +280,29 @@ static void bta_hf_client_sco_conn_rsp(tBTM_ESCO_CONN_REQ_EVT_DATA *p_data) BTM_EScoConnRsp(p_data->sco_inx, hci_status, &resp); } -#if (BTM_SCO_HCI_INCLUDED == TRUE ) +#if (BTM_SCO_HCI_INCLUDED == TRUE) +/******************************************************************************* +** +** Function bta_hf_client_pkt_stat_nums +** +** Description Get the packet status number +** +** +** Returns void +** +*******************************************************************************/ +void bta_hf_client_pkt_stat_nums(tBTA_HF_CLIENT_DATA *p_data) +{ + tBTA_SCO_PKT_STAT_NUMS pkt_stat_nums; + uint16_t sync_conn_handle = p_data->pkt_stat.sync_conn_handle; + BTM_PktStatNumsGet(sync_conn_handle, (tBTM_SCO_PKT_STAT_NUMS *) &pkt_stat_nums); + + /* call app cback */ + if (bta_hf_client_cb.p_cback) { + (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_PKT_STAT_NUMS_GET_EVT, (void*) &pkt_stat_nums); + } +} + /******************************************************************************* ** ** Function bta_hf_client_ci_sco_data @@ -254,6 +319,7 @@ void bta_hf_client_ci_sco_data(tBTA_HF_CLIENT_DATA *p_data) bta_hf_client_sco_event(BTA_HF_CLIENT_SCO_CI_DATA_E); } #endif + /******************************************************************************* ** ** Function bta_hf_client_sco_connreq_cback diff --git a/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_at.h b/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_at.h index caed82861b..2cf38acc2c 100644 --- a/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_at.h +++ b/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_at.h @@ -26,15 +26,6 @@ /* ASCII character string of arguments to the AT command */ #define BTA_HF_CLIENT_AT_MAX_LEN 512 -/* AT command table element */ -typedef struct { - const char *p_cmd; /* AT command string */ - UINT8 arg_type; /* allowable argument type syntax */ - UINT8 fmt; /* whether arg is int or string */ - UINT8 min; /* minimum value for int arg */ - INT16 max; /* maximum value for int arg */ -} tBTA_AG_AT_CMD; - /* callback function executed when command is parsed */ typedef void (tBTA_AG_AT_CMD_CBACK)(void *p_user, UINT16 cmd, UINT8 arg_type, char *p_arg, INT16 int_arg); diff --git a/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h b/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h index 60836dd576..0732a96c52 100644 --- a/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h +++ b/components/bt/host/bluedroid/bta/hf_client/include/bta_hf_client_int.h @@ -65,6 +65,7 @@ enum { BTA_HF_CLIENT_SEND_AT_CMD_EVT, #if (BTM_SCO_HCI_INCLUDED == TRUE ) BTA_HF_CLIENT_CI_SCO_DATA_EVT, + BTA_HF_CLIENT_PKT_NUMS_GET_EVT, #endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */ BTA_HF_CLIENT_MAX_EVT, @@ -121,6 +122,12 @@ typedef struct { char str[BTA_HF_CLIENT_MAX_LEN + 1]; } tBTA_HF_CLIENT_DATA_VAL; +/* data type for BTA_HF_CLIENT_PKT_NUMS_GET_EVT */ +typedef struct { + BT_HDR hdr; + UINT16 sync_conn_handle; +} tBTA_HF_CLIENT_PKT_STAT_GET; + /* union of all event datatypes */ typedef union { BT_HDR hdr; @@ -130,6 +137,7 @@ typedef union { tBTA_HF_CLIENT_DISC_RESULT disc_result; tBTA_HF_CLIENT_RFC rfc; tBTA_HF_CLIENT_DATA_VAL val; + tBTA_HF_CLIENT_PKT_STAT_GET pkt_stat; } tBTA_HF_CLIENT_DATA; @@ -302,6 +310,7 @@ extern void bta_hf_client_binp(char *number); extern void bta_hf_client_dial(tBTA_HF_CLIENT_DATA *p_data); extern void bta_hf_client_send_at_cmd(tBTA_HF_CLIENT_DATA *p_data); #if (BTM_SCO_HCI_INCLUDED == TRUE ) +extern void bta_hf_client_pkt_stat_nums(tBTA_HF_CLIENT_DATA *p_data); extern void bta_hf_client_ci_sco_data(tBTA_HF_CLIENT_DATA *p_data); #endif /* (BTM_SCO_HCI_INCLUDED == TRUE ) */ #endif /* #if (BTA_HF_INCLUDED == TRUE) */ diff --git a/components/bt/host/bluedroid/bta/hh/bta_hh_act.c b/components/bt/host/bluedroid/bta/hh/bta_hh_act.c index 604b5e95b5..6d933ee870 100644 --- a/components/bt/host/bluedroid/bta/hh/bta_hh_act.c +++ b/components/bt/host/bluedroid/bta/hh/bta_hh_act.c @@ -276,7 +276,7 @@ static void bta_hh_di_sdp_cback(UINT16 result) bta_hh_update_di_info(p_cb, di_rec.rec.vendor, di_rec.rec.product, di_rec.rec.version, 0); } - } else { /* no DI recrod available */ + } else { /* no DI record available */ bta_hh_update_di_info(p_cb, BTA_HH_VENDOR_ID_INVALID, 0, 0, 0); } @@ -358,7 +358,7 @@ void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) return; } - /* GetSDPRecord. at one time only one SDP precedure can be active */ + /* GetSDPRecord. at one time only one SDP procedure can be active */ else if (!bta_hh_cb.p_disc_db) { bta_hh_cb.p_disc_db = (tSDP_DISCOVERY_DB *) osi_malloc(p_bta_hh_cfg->sdp_db_size); @@ -429,6 +429,7 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) APPL_TRACE_DEBUG ("bta_hh_sdp_cmpl: HID_HostOpenDev failed: \ Status 0x%2X", ret); #endif + conn_dat.is_orig = HID_HostConnectOrig(p_cb->hid_handle); /* open fail, remove device from management device list */ HID_HostRemoveDev( p_cb->hid_handle); status = BTA_HH_ERR; @@ -452,8 +453,6 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) HID_HostRemoveDev( p_cb->incoming_hid_handle); } conn_dat.status = status; - /* check if host initiate the connection*/ - conn_dat.is_orig = !p_cb->incoming_conn; (* bta_hh_cb.p_cback)(BTA_HH_OPEN_EVT, (tBTA_HH *)&conn_dat); /* move state machine W4_CONN ->IDLE */ @@ -523,8 +522,7 @@ void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) memset((void *)&conn, 0, sizeof (tBTA_HH_CONN)); conn.handle = dev_handle; - /* check if host initiate the connection*/ - conn.is_orig = !p_cb->incoming_conn; + conn.is_orig = HID_HostConnectOrig(dev_handle); bdcpy(conn.bda, p_cb->addr); /* increase connection number */ @@ -596,7 +594,7 @@ void bta_hh_open_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) if (p_cb->app_id != 0) { bta_hh_sm_execute(p_cb, BTA_HH_OPEN_CMPL_EVT, p_data); } else - /* app_id == 0 indicates an incoming conenction request arrives without SDP + /* app_id == 0 indicates an incoming connection request arrives without SDP performed, do it first */ { /* store the handle here in case sdp fails - need to disconnect */ @@ -637,7 +635,7 @@ void bta_hh_data_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) ** ** Function bta_hh_handsk_act ** -** Description HID Host process a handshake acknoledgement. +** Description HID Host process a handshake acknowledgement. ** ** ** Returns void @@ -674,7 +672,7 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) p_cb->w4_evt = 0; break; - /* acknoledgement from HID device for SET_ transaction */ + /* acknowledgement from HID device for SET_ transaction */ case BTA_HH_SET_RPT_EVT: case BTA_HH_SET_PROTO_EVT: case BTA_HH_SET_IDLE_EVT : @@ -693,8 +691,7 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) case BTA_HH_OPEN_EVT: conn.status = p_data->hid_cback.data ? BTA_HH_ERR_PROTO : BTA_HH_OK; conn.handle = p_cb->hid_handle; - /* check if host initiate the connection*/ - conn.is_orig = !p_cb->incoming_conn; + conn.is_orig = HID_HostConnectOrig(p_cb->hid_handle); bdcpy(conn.bda, p_cb->addr); (* bta_hh_cb.p_cback)(p_cb->w4_evt, (tBTA_HH *)&conn); #if BTA_HH_DEBUG @@ -704,12 +701,12 @@ void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) break; default: - /* unknow transaction handshake response */ + /* unknown transaction handshake response */ APPL_TRACE_DEBUG("unknown transaction type"); break; } - /* transaction achknoledgement received, inform PM for mode change */ + /* transaction acknowledgement received, inform PM for mode change */ bta_sys_idle(BTA_ID_HH, p_cb->app_id, p_cb->addr); return; } @@ -799,7 +796,7 @@ void bta_hh_open_failure(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) conn_dat.status = (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR; /* check if host initiate the connection*/ - conn_dat.is_orig = !p_cb->incoming_conn; + conn_dat.is_orig = HID_HostConnectOrig(p_cb->hid_handle); bdcpy(conn_dat.bda, p_cb->addr); HID_HostCloseDev(p_cb->hid_handle); @@ -844,13 +841,13 @@ void bta_hh_close_act (tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data) /* Check reason for closing */ if ((reason & (HID_L2CAP_CONN_FAIL | HID_L2CAP_REQ_FAIL)) || /* Failure to initialize connection (page timeout or l2cap error) */ - (reason == HID_ERR_AUTH_FAILED) || /* Authenication error (while initiating) */ + (reason == HID_ERR_AUTH_FAILED) || /* Authentication error (while initiating) */ (reason == HID_ERR_L2CAP_FAILED)) { /* Failure creating l2cap connection */ /* Failure in opening connection */ conn_dat.handle = p_cb->hid_handle; conn_dat.status = (reason == HID_ERR_AUTH_FAILED) ? BTA_HH_ERR_AUTH_FAILED : BTA_HH_ERR; /* check if host initiate the connection*/ - conn_dat.is_orig = !p_cb->incoming_conn; + conn_dat.is_orig = HID_HostConnectOrig(p_cb->hid_handle); bdcpy(conn_dat.bda, p_cb->addr); HID_HostCloseDev(p_cb->hid_handle); diff --git a/components/bt/host/bluedroid/bta/hh/bta_hh_main.c b/components/bt/host/bluedroid/bta/hh/bta_hh_main.c index 663d28e96f..19f1045b1b 100644 --- a/components/bt/host/bluedroid/bta/hh/bta_hh_main.c +++ b/components/bt/host/bluedroid/bta/hh/bta_hh_main.c @@ -293,7 +293,7 @@ void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event, tBTA_HH_DATA *p_data) cback_data.conn.status = BTA_HH_ERR_DB_FULL; cback_data.conn.handle = BTA_HH_INVALID_HANDLE; /* check if host initiate the connection*/ - cback_data.conn.is_orig = !p_cb->incoming_conn; + cback_data.conn.is_orig = TRUE; break; /* DB full, BTA_HhAddDev */ case BTA_HH_API_MAINT_DEV_EVT: diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h index b407583485..35bb6ab5e6 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_ag_api.h @@ -158,6 +158,8 @@ typedef UINT8 tBTA_AG_RES; #endif #define BTA_AG_AUDIO_MSBC_OPEN_EVT 32 /* Audio connection with mSBC codec open */ +#define BTA_AG_PKT_NUMS_GET_EVT 33 /* AG packet status nums */ + /* Values below are for HFP only */ #define BTA_AG_AT_A_EVT 10 /* Answer a incoming call */ #define BTA_AG_AT_D_EVT 11 /* Place a call using number or memory dial */ @@ -261,15 +263,15 @@ typedef UINT8 tBTA_AG_BTRH_TYPE; #endif /* indicator constants HFP 1.1 and later */ -#define BTA_AG_IND_CALL 0 /* position of call indicator */ -#define BTA_AG_IND_CALLSETUP 1 /* position of callsetup indicator */ -#define BTA_AG_IND_SERVICE 2 /* position of service indicator */ +#define BTA_AG_IND_CALL 1 /* position of call indicator */ +#define BTA_AG_IND_CALLSETUP 2 /* position of callsetup indicator */ +#define BTA_AG_IND_SERVICE 3 /* position of service indicator */ /* indicator constants HFP 1.5 and later */ -#define BTA_AG_IND_SIGNAL 3 /* position of signal strength indicator */ -#define BTA_AG_IND_ROAM 4 /* position of roaming indicator */ -#define BTA_AG_IND_BATTCHG 5 /* position of battery charge indicator */ -#define BTA_AG_IND_CALLHELD 6 /* position of callheld indicator */ -#define BTA_AG_IND_BEARER 7 /* position of bearer indicator */ +#define BTA_AG_IND_SIGNAL 4 /* position of signal strength indicator */ +#define BTA_AG_IND_ROAM 5 /* position of roaming indicator */ +#define BTA_AG_IND_BATTCHG 6 /* position of battery charge indicator */ +#define BTA_AG_IND_CALLHELD 7 /* position of callheld indicator */ +#define BTA_AG_IND_BEARER 8 /* position of bearer indicator */ typedef UINT16 tBTA_AG_IND_TYPE; /* call indicator values */ @@ -327,6 +329,7 @@ typedef struct UINT16 handle; UINT8 app_id; tBTA_AG_STATUS status; + UINT16 sync_conn_handle; } tBTA_AG_HDR; /* data associated with BTA_AG_REGISTER_EVT */ @@ -405,6 +408,17 @@ typedef struct { char number[BTA_AG_NUMBER_LEN + 1]; } tBTA_AG_CNUM; +/* data associated with BTA_HF_CLIENT_PKT_STAT_NUMS_GET_EVT */ +typedef struct { + UINT32 rx_total; + UINT32 rx_correct; + UINT32 rx_err; + UINT32 rx_none; + UINT32 rx_lost; + UINT32 tx_total; + UINT32 tx_discarded; +} tBTA_AG_PKT_STAT_NUMS; + /* union of data associated with AG callback */ typedef union { @@ -421,6 +435,7 @@ typedef union tBTA_AG_AT_RESULT result; tBTA_AG_CLCC clcc; tBTA_AG_CNUM cnum; + tBTA_AG_PKT_STAT_NUMS pkt_num; } tBTA_AG; /* AG callback */ @@ -581,6 +596,18 @@ void BTA_AgSetCodec(UINT16 handle, tBTA_AG_PEER_CODEC codec); #if (BTM_SCO_HCI_INCLUDED == TRUE ) +/******************************************************************************* +** +** Function BTA_AgPktStatsNumsGet +** +** Description Get the Number of packets status received +** +** +** Returns void +** +*******************************************************************************/ +void BTA_AgPktStatsNumsGet(UINT16 handle, UINT16 sync_conn_handle); + /******************************************************************************* ** ** Function BTA_AgCiData 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 3a38169f13..4238e7bf75 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -303,6 +303,7 @@ typedef void (tBTA_DM_CONFIG_EIR_CBACK) (tBTA_STATUS status, UINT8 eir_type_num, typedef struct { BOOLEAN bta_dm_eir_fec_required; /* FEC required */ + BOOLEAN bta_dm_eir_included_name; /* Included device name or not */ UINT8 bta_dm_eir_min_name_len; /* minimum length of local name when it is shortened */ BOOLEAN bta_dm_eir_included_uuid; /* Included UUIDs or not */ @@ -397,7 +398,7 @@ typedef tBTM_BLE_128SERVICE tBTA_BLE_128SERVICE; typedef tBTM_BLE_32SERVICE tBTA_BLE_32SERVICE; typedef struct { - tBTA_BLE_INT_RANGE int_range; /* slave prefered conn interval range */ + tBTA_BLE_INT_RANGE int_range; /* slave preferred conn interval range */ tBTA_BLE_MANU *p_manu; /* manufacturer data */ tBTA_BLE_SERVICE *p_services; /* 16 bits services */ tBTA_BLE_128SERVICE *p_services_128b; /* 128 bits service */ @@ -416,6 +417,8 @@ typedef void (tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTA_STATUS st typedef void (tBTA_SET_ADV_DATA_CMPL_CBACK) (tBTA_STATUS status); +typedef tBTM_VSC_CMPL_CB tBTA_SEND_VENDOR_HCI_CMPL_CBACK; + typedef tBTM_START_ADV_CMPL_CBACK tBTA_START_ADV_CMPL_CBACK; typedef tBTM_START_STOP_ADV_CMPL_CBACK tBTA_START_STOP_ADV_CMPL_CBACK; @@ -424,12 +427,22 @@ typedef tBTM_UPDATE_WHITELIST_CBACK tBTA_UPDATE_WHITELIST_CBACK; typedef tBTM_SET_PKT_DATA_LENGTH_CBACK tBTA_SET_PKT_DATA_LENGTH_CBACK; +typedef tBTM_DTM_CMD_CMPL_CBACK tBTA_DTM_CMD_CMPL_CBACK; + typedef tBTM_SET_RAND_ADDR_CBACK tBTA_SET_RAND_ADDR_CBACK; typedef tBTM_SET_LOCAL_PRIVACY_CBACK tBTA_SET_LOCAL_PRIVACY_CBACK; +typedef tBTM_SET_RPA_TIMEOUT_CMPL_CBACK tBTA_SET_RPA_TIMEOUT_CMPL_CBACK; + +typedef tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK tBTA_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK; + +typedef tBTM_SET_PRIVACY_MODE_CMPL_CBACK tBTA_SET_PRIVACY_MODE_CMPL_CBACK; + typedef tBTM_CMPL_CB tBTA_CMPL_CB; +typedef tBTM_VSC_CMPL tBTA_VSC_CMPL; + typedef tBTM_TX_POWER_RESULTS tBTA_TX_POWER_RESULTS; typedef tBTM_RSSI_RESULTS tBTA_RSSI_RESULTS; @@ -437,6 +450,8 @@ typedef tBTM_RSSI_RESULTS tBTA_RSSI_RESULTS; typedef tBTM_SET_AFH_CHANNELS_RESULTS tBTA_SET_AFH_CHANNELS_RESULTS; typedef tBTM_BLE_SET_CHANNELS_RESULTS tBTA_BLE_SET_CHANNELS_RESULTS; +typedef tBTM_SET_ACL_PKT_TYPES_RESULTS tBTA_SET_ACL_PKT_TYPES_RESULTS; + typedef tBTM_REMOTE_DEV_NAME tBTA_REMOTE_DEV_NAME; /* advertising channel map */ @@ -653,7 +668,7 @@ typedef UINT8 tBTA_SIG_STRENGTH_MASK; // btla-specific -- #define BTA_DM_DEV_UNPAIRED_EVT 25 /* BT unpair event */ #define BTA_DM_HW_ERROR_EVT 26 /* BT Chip H/W error */ -#define BTA_DM_LE_FEATURES_READ 27 /* Cotroller specific LE features are read */ +#define BTA_DM_LE_FEATURES_READ 27 /* Controller specific LE features are read */ #define BTA_DM_ENER_INFO_READ 28 /* Energy info read */ #define BTA_DM_BLE_DEV_UNPAIRED_EVT 29 /* BLE unpair event */ #define BTA_DM_SP_KEY_REQ_EVT 30 /* Simple Pairing Passkey request */ @@ -1092,7 +1107,7 @@ typedef struct { #define BTA_DM_INQ_RES_EVT 0 /* Inquiry result for a peer device. */ #define BTA_DM_INQ_CMPL_EVT 1 /* Inquiry complete. */ #define BTA_DM_DISC_RES_EVT 2 /* Discovery result for a peer device. */ -#define BTA_DM_DISC_BLE_RES_EVT 3 /* Discovery result for BLE GATT based servoce on a peer device. */ +#define BTA_DM_DISC_BLE_RES_EVT 3 /* Discovery result for BLE GATT based service on a peer device. */ #define BTA_DM_DISC_CMPL_EVT 4 /* Discovery complete. */ #define BTA_DM_DI_DISC_CMPL_EVT 5 /* Discovery complete. */ #define BTA_DM_SEARCH_CANCEL_CMPL_EVT 6 /* Search cancelled */ @@ -1237,6 +1252,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); @@ -1529,6 +1546,10 @@ typedef struct { typedef struct { UINT8 filter_policy; + #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH) + UINT8 reports_disabled; + UINT8 filter_duplicates; + #endif UINT8 sid; tBLE_ADDR_TYPE addr_type; BD_ADDR addr; @@ -1596,7 +1617,14 @@ typedef struct { #define BTA_DM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT BTM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT #define BTA_DM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT #define BTA_DM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT -#define BTA_DM_BLE_5_GAP_UNKNOWN_EVT BTM_BLE_5_GAP_UNKNOWN_EVT +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define BTA_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT BTM_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT +#define BTA_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT +#define BTA_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT BTM_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT +#define BTA_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT +#define BTA_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define BTA_DM_BLE_5_GAP_UNKNOWN_EVT BTM_BLE_5_GAP_UNKNOWN_EVT typedef tBTM_BLE_5_GAP_EVENT tBTA_DM_BLE_5_GAP_EVENT; typedef tBTM_BLE_5_GAP_CB_PARAMS tBTA_DM_BLE_5_GAP_CB_PARAMS; @@ -1606,6 +1634,15 @@ extern tBTM_BLE_5_HCI_CBACK ble_5_hci_cb; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +typedef struct { + UINT8 mode; + UINT16 skip; + UINT16 sync_timeout; + UINT8 cte_type; +} tBTA_DM_BLE_PAST_PARAMS; +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /***************************************************************************** ** External Function Declarations *****************************************************************************/ @@ -1693,6 +1730,8 @@ extern void BTA_DmSetDeviceName(const char *p_name); *******************************************************************************/ extern void BTA_DmGetDeviceName(tBTA_GET_DEV_NAME_CBACK *p_cback); +extern void BTA_DmsendVendorHciCmd(UINT16 opcode, UINT8 param_len, UINT8 *p_param_buf, tBTA_SEND_VENDOR_HCI_CMPL_CBACK p_vendor_cmd_complete_cback); + /******************************************************************************* ** ** Function BTA_DmGetRemoteName @@ -1743,6 +1782,18 @@ void BTA_DmSetAfhChannels(const uint8_t *channels, tBTA_CMPL_CB *set_afh_cb); void BTA_DmSetQos(BD_ADDR bd_addr, UINT32 t_poll, tBTM_CMPL_CB *p_cb); #endif /// (BTA_DM_QOS_INCLUDED == TRUE) +/******************************************************************************* +** +** Function BTA_DmSetAclPktTypes +** +** Description This function sets the packet types used for ACL traffic. +** +** +** Returns void +** +*******************************************************************************/ +void BTA_DmSetAclPktTypes(BD_ADDR remote_addr, UINT16 pkt_types, tBTM_CMPL_CB *p_cb); + #if (BLE_INCLUDED == TRUE) /******************************************************************************* ** @@ -1843,7 +1894,7 @@ extern void BTA_DmDiscoverUUID(BD_ADDR bd_addr, tSDP_UUID *uuid, ** ** Function BTA_DmGetCachedRemoteName ** -** Description Retieve cached remote name if available +** Description Retrieve cached remote name if available ** ** Returns BTA_SUCCESS if cached name was retrieved ** BTA_FAILURE if cached name is not available @@ -2194,7 +2245,7 @@ extern void BTA_DmBleSetBgConnType(tBTA_DM_BLE_CONN_TYPE bg_conn_type, tBTA_DM_B ** Description Send BLE SMP passkey reply. ** ** Parameters: bd_addr - BD address of the peer -** accept - passkey entry sucessful or declined. +** accept - passkey entry successful or declined. ** passkey - passkey value, must be a 6 digit number, ** can be lead by 0. ** @@ -2360,7 +2411,7 @@ extern void BTA_DmSetBleScanFilterParams(tGATT_IF client_if, UINT32 scan_interva ** ** Parameters: adv_int_min - adv interval minimum ** adv_int_max - adv interval max -** p_dir_bda - directed adv initator address +** p_dir_bda - directed adv initiator address ** ** Returns void ** @@ -2386,7 +2437,7 @@ extern void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max, ** services: if service is not empty, service discovery will be done. ** for all GATT based service condition, put num_uuid, and ** p_uuid is the pointer to the list of UUID values. -** p_cback: callback functino when search is completed. +** p_cback: callback function when search is completed. ** ** ** @@ -2445,7 +2496,7 @@ extern void BTA_DmDiscoverByTransport(BD_ADDR bd_addr, tBTA_SERVICE_MASK_EXT *p_ ** ** Parameters: bd_addr - Address of the peer device ** transport - transport of the link to be encruypted -** p_callback - Pointer to callback function to indicat the +** p_callback - Pointer to callback function to indicate the ** link encryption status ** sec_act - This is the security action to indicate ** what knid of BLE security level is required for @@ -2502,7 +2553,11 @@ extern void BTA_DmBleStopAdvertising(void); extern void BTA_DmSetRandAddress(BD_ADDR rand_addr, tBTA_SET_RAND_ADDR_CBACK *p_set_rand_addr_cback); extern void BTA_DmClearRandAddress(void); - +extern void BTA_DmBleSetRpaTimeout(uint16_t rpa_timeout,tBTA_SET_RPA_TIMEOUT_CMPL_CBACK *p_set_rpa_timeout_cback); +extern void BTA_DmBleAddDevToResolvingList(BD_ADDR addr, + uint8_t addr_type, + PEER_IRK irk, + tBTA_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *add_dev_to_resolving_list_callback); #endif #if BLE_INCLUDED == TRUE @@ -2513,7 +2568,7 @@ extern void BTA_DmClearRandAddress(void); ** ** Description Enable/disable privacy on the local device ** -** Parameters: privacy_enable - enable/disabe privacy on remote device. +** Parameters: privacy_enable - enable/disable privacy on remote device. ** set_local_privacy_cback -callback to be called with result ** Returns void ** @@ -2540,7 +2595,7 @@ extern void BTA_DmBleConfigLocalIcon(uint16_t icon); ** Description Enable/disable privacy on a remote device ** ** Parameters: bd_addr - BD address of the peer -** privacy_enable - enable/disabe privacy on remote device. +** privacy_enable - enable/disable privacy on remote device. ** ** Returns void ** @@ -2595,6 +2650,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 @@ -2758,6 +2826,12 @@ extern void BTA_DmBleDisconnect(BD_ADDR bd_addr); *******************************************************************************/ extern void BTA_DmBleSetDataLength(BD_ADDR remote_device, UINT16 tx_data_length, tBTA_SET_PKT_DATA_LENGTH_CBACK *p_set_pkt_data_cback); +extern void BTA_DmBleDtmTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); +extern void BTA_DmBleDtmRxStart(uint8_t rx_channel, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); +extern void BTA_DmBleDtmStop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); + +extern void BTA_DmBleSetPrivacyMode(uint8_t addr_type, BD_ADDR addr, uint8_t privacy_mode, tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback); + /******************************************************************************* ** ** Function BTA_DmBleSetStorageParams @@ -2981,9 +3055,9 @@ extern void BTA_DmBleGapPeriodicAdvSetParams(UINT8 instance, tBTA_DM_BLE_Periodic_Adv_Params *params); extern void BTA_DmBleGapPeriodicAdvCfgDataRaw(UINT8 instance, UINT16 length, - const UINT8 *data); + const UINT8 *data,BOOLEAN only_update_did); -extern void BTA_DmBleGapPeriodicAdvEnable(BOOLEAN enable, UINT8 instance); +extern void BTA_DmBleGapPeriodicAdvEnable(UINT8 enable, UINT8 instance); extern void BTA_DmBleGapPeriodicAdvCreateSync(tBTA_DM_BLE_Periodic_Sync_Params *params); @@ -3012,8 +3086,22 @@ extern void BTA_DmBleGapPreferExtConnectParamsSet(BD_ADDR bd_addr, const tBTA_DM_BLE_CONN_PARAMS *phy_coded_conn_params); extern void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_addr); + +extern void BTA_DmBleDtmEnhTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, uint8_t phy, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); + +extern void BTA_DmBleDtmEnhRxStart(uint8_t rx_channel, uint8_t phy, uint8_t modulation_index, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +extern void BTA_DmBleGapPeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable); + +extern void BTA_DmBleGapPeriodicAdvSyncTrans(BD_ADDR peer_addr, UINT16 service_data, UINT16 sync_handle); + +extern void BTA_DmBleGapPeriodicAdvSetInfoTrans(BD_ADDR peer_addr, UINT16 service_data, UINT8 adv_handle); + +extern void BTA_DmBleGapSetPeriodicAdvSyncTransParams(BD_ADDR peer_addr, tBTA_DM_BLE_PAST_PARAMS *params); +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + #endif enum { diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h index f9f73ad1fe..183e3acc5a 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_gatt_api.h @@ -185,6 +185,7 @@ typedef UINT8 tBTA_GATT_STATUS; #define BTA_GATTC_ASSOC_EVT 39 /* GATTC association address event */ #define BTA_GATTC_GET_ADDR_LIST_EVT 40 /* GATTC get address list in the cache event */ #define BTA_GATTC_DIS_SRVC_CMPL_EVT 41 /* GATTC discover service complete */ +#define BTA_GATTC_READ_MULTI_VAR_EVT 42 /* GATTC read multiple variable event */ typedef UINT8 tBTA_GATTC_EVT; @@ -1136,6 +1137,21 @@ extern void BTA_GATTC_ExecuteWrite (UINT16 conn_id, BOOLEAN is_execute); extern void BTA_GATTC_ReadMultiple(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi, tBTA_GATT_AUTH_REQ auth_req); +/******************************************************************************* +** +** Function BTA_GATTC_ReadMultiple +** +** Description This function is called to read multiple variable length characteristic or +** characteristic descriptors. +** +** Parameters conn_id - connection ID. +** p_read_multi - read multiple parameters. +** +** Returns None +** +*******************************************************************************/ +extern void BTA_GATTC_ReadMultipleVariable(UINT16 conn_id, tBTA_GATTC_MULTI *p_read_multi, + tBTA_GATT_AUTH_REQ auth_req); /******************************************************************************* ** @@ -1542,6 +1558,16 @@ void BTA_GATTS_SendServiceChangeIndication(tBTA_GATTS_IF server_if, BD_ADDR remo extern void BTA_GATTS_Listen(tBTA_GATTS_IF server_if, BOOLEAN start, BD_ADDR_PTR target_bda); +/******************************************************************************* +** +** Function BTA_GATTS_ShowLocalDatabase +** +** Description print local service database. +** +** Returns void +** +*******************************************************************************/ +extern void BTA_GATTS_ShowLocalDatabase(void); extern void bta_gattc_clcb_dealloc_by_conn_id(UINT16 conn_id); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h index 15e785e871..ac834c7b6f 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_hf_client_api.h @@ -112,7 +112,8 @@ typedef UINT8 tBTA_HF_CLIENT_AT_RESULT_TYPE; #define BTA_HF_CLIENT_BSIR_EVT 19 /* in-band ring tone setting changed event */ #define BTA_HF_CLIENT_BINP_EVT 20 /* binp number event */ #define BTA_HF_CLIENT_RING_INDICATION 21 /* HF Client ring indication */ -#define BTA_HF_CLIENT_DISABLE_EVT 30 /* HF Client disabled */ +#define BTA_HF_CLIENT_DISABLE_EVT 22 /* HF Client disabled */ +#define BTA_HF_CLIENT_PKT_STAT_NUMS_GET_EVT 23 /* HF Client packet status nums */ typedef UINT8 tBTA_HF_CLIENT_EVT; @@ -163,6 +164,7 @@ typedef UINT8 tBTA_HF_CLIENT_AT_CMD_TYPE; /* data associated with most non-AT events */ /* placeholder, if not needed should be removed*/ typedef struct { + UINT16 sync_conn_handle; } tBTA_HF_CLIENT_HDR; /* data associated with BTA_HF_CLIENT_REGISTER_EVT */ @@ -232,6 +234,17 @@ typedef struct { UINT16 value; } tBTA_HF_CLIENT_VAL; +/* data associated with BTA_HF_CLIENT_PKT_STAT_NUMS_GET_EVT */ +typedef struct { + UINT32 rx_total; + UINT32 rx_correct; + UINT32 rx_err; + UINT32 rx_none; + UINT32 rx_lost; + UINT32 tx_total; + UINT32 tx_discarded; +} tBTA_SCO_PKT_STAT_NUMS; + /* union of data associated with AG callback */ typedef union { tBTA_HF_CLIENT_HDR hdr; @@ -245,6 +258,7 @@ typedef union { tBTA_HF_CLIENT_AT_RESULT result; tBTA_HF_CLIENT_CLCC clcc; tBTA_HF_CLIENT_CNUM cnum; + tBTA_SCO_PKT_STAT_NUMS pkt_num; } tBTA_HF_CLIENT; typedef UINT32 tBTA_HF_CLIENT_FEAT; @@ -380,6 +394,18 @@ void BTA_HfClientAudioClose(UINT16 handle); void BTA_HfClientSendAT(UINT16 handle, tBTA_HF_CLIENT_AT_CMD_TYPE at, UINT32 val1, UINT32 val2, const char *str); #if (BTM_SCO_HCI_INCLUDED == TRUE ) +/******************************************************************************* +** +** Function BTA_HfClientPktStatsNumsGet +** +** Description Get the Number of packets status received and send +** +** +** Returns void +** +*******************************************************************************/ +void BTA_HfClientPktStatsNumsGet(UINT16 sync_conn_handle); + void BTA_HfClientCiData(void); #endif /*#if (BTM_SCO_HCI_INCLUDED == TRUE ) */ diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_jv_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_jv_api.h index 241c97a86e..660ce5cf31 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_jv_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_jv_api.h @@ -847,7 +847,7 @@ extern tBTA_JV_STATUS BTA_JvRfcommConnect(tBTA_SEC sec_mask, ** BTA_JV_FAILURE, otherwise. ** *******************************************************************************/ -extern tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, tBTA_JV_RFCOMM_CBACK *p_cback, void *user_data); +extern tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, void *user_data); /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_sys.h b/components/bt/host/bluedroid/bta/include/bta/bta_sys.h index 87359b5a9f..54376de635 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_sys.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_sys.h @@ -143,7 +143,7 @@ typedef void (tBTA_SYS_SSR_CFG_CBACK)(UINT8 id, UINT8 app_id, UINT16 latency, UI #if (BTA_EIR_CANNED_UUID_LIST != TRUE) /* eir callback for adding/removeing UUID */ -typedef void (tBTA_SYS_EIR_CBACK)(UINT16 uuid16, BOOLEAN adding); +typedef void (tBTA_SYS_EIR_CBACK)(tBT_UUID uuid, BOOLEAN adding); #endif /* registration structure */ @@ -263,12 +263,20 @@ extern void bta_sys_notify_collision (BD_ADDR_PTR p_bda); #if (BTA_EIR_CANNED_UUID_LIST != TRUE) extern void bta_sys_eir_register(tBTA_SYS_EIR_CBACK *p_cback); -extern void bta_sys_add_uuid(UINT16 uuid16); +extern void bta_sys_add_uuid(UINT16 uuid); +extern void bta_sys_add_uuid_32(UINT32 uuid32); +extern void bta_sys_add_uuid_128(UINT8 *uuid128); extern void bta_sys_remove_uuid(UINT16 uuid16); +extern void bta_sys_remove_uuid_32(UINT32 uuid32); +extern void bta_sys_remove_uuid_128(UINT8 *uuid128); #else #define bta_sys_eir_register(ut) #define bta_sys_add_uuid(ut) +#define bta_sys_add_uuid_32(ut) +#define bta_sys_add_uuid_128(ut) #define bta_sys_remove_uuid(ut) +#define bta_sys_remove_uuid_32(ut) +#define bta_sys_remove_uuid_128(ut) #endif extern void bta_sys_set_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr); diff --git a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c index a739e7fce9..214ef746af 100644 --- a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c +++ b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c @@ -113,6 +113,10 @@ static void bta_jv_pm_conn_idle(tBTA_JV_PM_CB *p_cb); static void bta_jv_pm_state_change(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE state); tBTA_JV_STATUS bta_jv_set_pm_conn_state(tBTA_JV_PM_CB *p_cb, const tBTA_JV_CONN_STATE new_st); +#if BT_SDP_BQB_INCLUDED +static BOOLEAN s_sdp_bqb_add_language_attr_flag = FALSE; +#endif /* BT_SDP_BQB_INCLUDED */ + #if BTA_JV_RFCOMM_INCLUDED static tBTA_JV_PCB *bta_jv_add_rfc_port(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb_open); static int find_rfc_pcb(void *user_data, tBTA_JV_RFC_CB **cb, tBTA_JV_PCB **pcb); @@ -290,11 +294,10 @@ tBTA_JV_RFC_CB *bta_jv_rfc_port_to_cb(UINT16 port_handle) return p_cb; } -static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb, BOOLEAN close_server) +static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pcb, BOOLEAN close_server, BOOLEAN close_pending) { tBTA_JV_STATUS status = BTA_JV_SUCCESS; BOOLEAN remove_server = FALSE; - int close_pending = 0; UINT8 used = 0, i, listen = 0; tPORT_STATE port_state; @@ -317,11 +320,11 @@ static tBTA_JV_STATUS bta_jv_free_rfc_cb(tBTA_JV_RFC_CB *p_cb, tBTA_JV_PCB *p_pc switch (p_pcb->state) { case BTA_JV_ST_CL_CLOSING: case BTA_JV_ST_SR_CLOSING: - APPL_TRACE_WARNING("bta_jv_free_sr_rfc_cb: return on closing, port state:%d, " + APPL_TRACE_DEBUG("bta_jv_free_sr_rfc_cb: return on closing, port state:%d, " "scn:%d, p_pcb:%p, user_data:%p", p_pcb->state, p_cb->scn, p_pcb, p_pcb->user_data); status = BTA_JV_FAILURE; - return status; + break; case BTA_JV_ST_CL_OPEN: case BTA_JV_ST_CL_OPENING: APPL_TRACE_DEBUG("bta_jv_free_sr_rfc_cb: state: %d, scn:%d," @@ -1037,6 +1040,22 @@ void bta_jv_start_discovery(tBTA_JV_MSG *p_data) */ } +/******************************************************************************* +** +** Function sdp_bqb_add_language_attr_ctrl +** +** Description Control adding of the language attribute for SDP BQB test +** +** Returns void +** +*******************************************************************************/ +#if BT_SDP_BQB_INCLUDED +void sdp_bqb_add_language_attr_ctrl(BOOLEAN enable) +{ + s_sdp_bqb_add_language_attr_flag = enable; +} +#endif /* BT_SDP_BQB_INCLUDED */ + /** * @brief Adds a protocol list and service name (if provided) to an SDP record given by * sdp_handle, and marks it as browseable. This is a shortcut for defining a @@ -1088,6 +1107,19 @@ static bool create_base_record(const uint32_t sdp_handle, const char *name, cons return FALSE; } +#if BT_SDP_BQB_INCLUDED + // SDP/SR/SA/BV-09-C,SDP/SR/SSA/BV-13-C + if (s_sdp_bqb_add_language_attr_flag == TRUE) { + stage = "language_base"; + if (!SDP_AddLanguageBaseAttrIDList(sdp_handle, LANG_ID_CODE_ENGLISH, LANG_ID_CHAR_ENCODE_UTF8, LANGUAGE_BASE_ID)) { + APPL_TRACE_ERROR("create_base_record: failed to create base service " + "record, stage: %s, scn: %d, name: %s, with_obex: %d", + stage, channel, name, with_obex); + return FALSE; + } + } +#endif /* BT_SDP_BQB_INCLUDED */ + // Add the name to the SDP record. if (name[0] != '\0') { stage = "service_name"; @@ -1215,10 +1247,15 @@ void bta_jv_delete_record(tBTA_JV_MSG *p_data) *******************************************************************************/ static void bta_jv_l2cap_client_cback(UINT16 gap_handle, UINT16 event) { + if (gap_handle >= BTA_JV_MAX_L2C_CONN) { + APPL_TRACE_WARNING("Invalid gap_handle: %u", gap_handle); + return; + } + tBTA_JV_L2C_CB *p_cb = &bta_jv_cb.l2c_cb[gap_handle]; tBTA_JV evt_data = {0}; - if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback) { + if (!p_cb->p_cback) { return; } @@ -1369,12 +1406,17 @@ void bta_jv_l2cap_close(tBTA_JV_MSG *p_data) *******************************************************************************/ static void bta_jv_l2cap_server_cback(UINT16 gap_handle, UINT16 event) { + if (gap_handle >= BTA_JV_MAX_L2C_CONN) { + APPL_TRACE_WARNING("Invalid gap_handle: %u", gap_handle); + return; + } + tBTA_JV_L2C_CB *p_cb = &bta_jv_cb.l2c_cb[gap_handle]; tBTA_JV evt_data = {0}; tBTA_JV_L2CAP_CBACK *p_cback; void *user_data; - if (gap_handle >= BTA_JV_MAX_L2C_CONN && !p_cb->p_cback) { + if (!p_cb->p_cback) { return; } @@ -1686,6 +1728,7 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* dat UINT16 lcid; tBTA_JV_RFCOMM_CBACK *p_cback; /* the callback function */ tPORT_MGMT_CL_CALLBACK_ARG *p_mgmt_cb_arg = (tPORT_MGMT_CL_CALLBACK_ARG *)data; + void *user_data = NULL; APPL_TRACE_DEBUG( "bta_jv_port_mgmt_cl_cback:code:%d, port_handle%d", code, port_handle); if (NULL == p_cb || NULL == p_cb->p_cback) { @@ -1715,13 +1758,14 @@ static void bta_jv_port_mgmt_cl_cback(UINT32 code, UINT16 port_handle, void* dat evt_data.rfc_close.async = FALSE; evt_data.rfc_close.status = BTA_JV_SUCCESS; } - //p_pcb->state = BTA_JV_ST_NONE; - //p_pcb->cong = FALSE; p_cback = p_cb->p_cback; - p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, p_pcb->user_data); - //bta_jv_free_rfc_cb(p_cb, p_pcb); - } + user_data = p_pcb->user_data; + // To free up resources. + p_pcb->state = BTA_JV_ST_CL_CLOSING; + bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE, FALSE); + p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, user_data); + } } /******************************************************************************* @@ -1894,7 +1938,6 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data) tBTA_JV_API_RFCOMM_CLOSE *cc = &(p_data->rfcomm_close); tBTA_JV_RFC_CB *p_cb = NULL; tBTA_JV_PCB *p_pcb = NULL; - tBTA_JV evt_data = {0}; APPL_TRACE_DEBUG("%s, rfc handle:%d",__func__, cc->handle); if (!cc->handle) { APPL_TRACE_ERROR("%s, rfc handle is null", __func__); @@ -1905,20 +1948,9 @@ void bta_jv_rfcomm_close(tBTA_JV_MSG *p_data) if (!find_rfc_pcb(user_data, &p_cb, &p_pcb)) { return; } - if(cc->p_cback) { - evt_data.rfc_close.status = BTA_JV_SUCCESS; - evt_data.rfc_close.port_status = PORT_LOCAL_CLOSED; - evt_data.rfc_close.handle = cc->handle; - evt_data.rfc_close.async = TRUE; - if (p_pcb && (p_pcb->state == BTA_JV_ST_SR_LISTEN || - p_pcb->state == BTA_JV_ST_SR_OPEN || - p_pcb->state == BTA_JV_ST_CL_OPEN || - p_pcb->state == BTA_JV_ST_CL_OPENING)) { - evt_data.rfc_close.async = FALSE; - } - cc->p_cback(BTA_JV_RFCOMM_CLOSE_EVT, (tBTA_JV *)&evt_data, user_data); - } - bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE); + + bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE, TRUE); + APPL_TRACE_DEBUG("%s: sec id in use:%d, rfc_cb in use:%d",__func__, get_sec_id_used(), get_rfc_cb_used()); } @@ -2019,7 +2051,7 @@ static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *dat APPL_TRACE_ERROR("create new listen port, but upper layer reject connection"); p_pcb_new_listen->user_data = NULL; p_pcb->state = BTA_JV_ST_SR_LISTEN; - bta_jv_free_rfc_cb(p_cb, p_pcb_new_listen, FALSE); + bta_jv_free_rfc_cb(p_cb, p_pcb_new_listen, FALSE, FALSE); if (p_mgmt_cb_arg) { p_mgmt_cb_arg->accept = FALSE; } @@ -2059,10 +2091,11 @@ static void bta_jv_port_mgmt_sr_cback(UINT32 code, UINT16 port_handle, void *dat evt_data.rfc_close.async = FALSE; evt_data.rfc_close.status = BTA_JV_SUCCESS; } - //p_pcb->state = BTA_JV_ST_NONE; - p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, user_data); - //bta_jv_free_rfc_cb(p_cb, p_pcb); + // To free up resources. + p_pcb->state = BTA_JV_ST_SR_CLOSING; + bta_jv_free_rfc_cb(p_cb, p_pcb, FALSE, FALSE); + p_cback(BTA_JV_RFCOMM_CLOSE_EVT, &evt_data, user_data); APPL_TRACE_DEBUG("PORT_CLOSED after BTA_JV_RFCOMM_CLOSE_EVT: curr_sess:%d, max_sess:%d", p_cb->curr_sess, p_cb->max_sess); } @@ -2296,7 +2329,7 @@ void bta_jv_rfcomm_stop_server(tBTA_JV_MSG *p_data) } APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: p_pcb:%p, p_pcb->port_handle:%d", p_pcb, p_pcb->port_handle); - bta_jv_free_rfc_cb(p_cb, p_pcb, TRUE); + bta_jv_free_rfc_cb(p_cb, p_pcb, TRUE, FALSE); APPL_TRACE_DEBUG("bta_jv_rfcomm_stop_server: sec id in use:%d, rfc_cb in use:%d", get_sec_id_used(), get_rfc_cb_used()); } diff --git a/components/bt/host/bluedroid/bta/jv/bta_jv_api.c b/components/bt/host/bluedroid/bta/jv/bta_jv_api.c index 7ca6f7d567..7419501550 100644 --- a/components/bt/host/bluedroid/bta/jv/bta_jv_api.c +++ b/components/bt/host/bluedroid/bta/jv/bta_jv_api.c @@ -19,7 +19,7 @@ /****************************************************************************** * * This is the implementation of the JAVA API for Bluetooth Wireless - * Technology (JABWT) as specified by the JSR82 specificiation + * Technology (JABWT) as specified by the JSR82 specification * ******************************************************************************/ @@ -118,6 +118,11 @@ void BTA_JvDisable(tBTA_JV_RFCOMM_CBACK *p_cback) APPL_TRACE_API( "BTA_JvDisable"); bta_sys_deregister(BTA_ID_JV); + memset(&bta_jv_cb, 0, sizeof(tBTA_JV_CB)); + /* set handle to invalid value by default */ + for (int i = 0; i < BTA_JV_PM_MAX_NUM; i++) { + bta_jv_cb.pm_cb[i].handle = BTA_JV_PM_HANDLE_CLEAR; + } if ((p_buf = (tBTA_JV_API_DISABLE *) osi_malloc(sizeof(tBTA_JV_API_DISABLE))) != NULL) { p_buf->hdr.event = BTA_JV_API_DISABLE_EVT; p_buf->p_cback = p_cback; @@ -893,7 +898,7 @@ tBTA_JV_STATUS BTA_JvRfcommConfig(BOOLEAN enable_l2cap_ertm) ** ** Function BTA_JvRfcommConnect ** -** Description This function makes an RFCOMM conection to a remote BD +** Description This function makes an RFCOMM connection to a remote BD ** Address. ** When the connection is initiated or failed to initiate, ** tBTA_JV_RFCOMM_CBACK is called with BTA_JV_RFCOMM_CL_INIT_EVT @@ -939,7 +944,7 @@ tBTA_JV_STATUS BTA_JvRfcommConnect(tBTA_SEC sec_mask, ** BTA_JV_FAILURE, otherwise. ** *******************************************************************************/ -tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, tBTA_JV_RFCOMM_CBACK *p_cback, void *user_data) +tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, void *user_data) { tBTA_JV_STATUS status = BTA_JV_FAILURE; tBTA_JV_API_RFCOMM_CLOSE *p_msg; @@ -954,7 +959,6 @@ tBTA_JV_STATUS BTA_JvRfcommClose(UINT32 handle, tBTA_JV_RFCOMM_CBACK *p_cback, v p_msg->handle = handle; p_msg->p_cb = &bta_jv_cb.rfc_cb[hi]; p_msg->p_pcb = &bta_jv_cb.port_cb[p_msg->p_cb->rfc_hdl[si] - 1]; - p_msg->p_cback = p_cback; p_msg->user_data = user_data; bta_sys_sendmsg(p_msg); status = BTA_JV_SUCCESS; @@ -1205,7 +1209,7 @@ tBTA_JV_STATUS BTA_JvRfcommFlowControl(UINT32 handle, UINT16 credits_given) ** Parameters: handle, JV handle from RFCOMM or L2CAP ** app_id: app specific pm ID, can be BTA_JV_PM_ALL, see bta_dm_cfg.c for details ** BTA_JV_PM_ID_CLEAR: removes pm management on the handle. init_st is ignored and - ** BTA_JV_CONN_CLOSE is called implicitely + ** BTA_JV_CONN_CLOSE is called implicitly ** init_st: state after calling this API. typically it should be BTA_JV_CONN_OPEN ** ** Returns BTA_JV_SUCCESS, if the request is being processed. diff --git a/components/bt/host/bluedroid/bta/jv/include/bta_jv_int.h b/components/bt/host/bluedroid/bta/jv/include/bta_jv_int.h index af1e3699d3..d6cd785a85 100644 --- a/components/bt/host/bluedroid/bta/jv/include/bta_jv_int.h +++ b/components/bt/host/bluedroid/bta/jv/include/bta_jv_int.h @@ -340,7 +340,6 @@ typedef struct { UINT32 handle; tBTA_JV_RFC_CB *p_cb; tBTA_JV_PCB *p_pcb; - tBTA_JV_RFCOMM_CBACK *p_cback; void *user_data; } tBTA_JV_API_RFCOMM_CLOSE; #endif /* BTA_JV_RFCOMM_INCLUDED */ diff --git a/components/bt/host/bluedroid/bta/sys/bta_sys_conn.c b/components/bt/host/bluedroid/bta/sys/bta_sys_conn.c index 2d55dec48a..914df55d9c 100644 --- a/components/bt/host/bluedroid/bta/sys/bta_sys_conn.c +++ b/components/bt/host/bluedroid/bta/sys/bta_sys_conn.c @@ -527,8 +527,55 @@ void bta_sys_eir_register(tBTA_SYS_EIR_CBACK *p_cback) *******************************************************************************/ void bta_sys_add_uuid(UINT16 uuid16) { + tBT_UUID uuid; + uuid.len = LEN_UUID_16; + uuid.uu.uuid16 = uuid16; + + if (bta_sys_cb.eir_cb) { + bta_sys_cb.eir_cb(uuid, TRUE); + } +} + + +/******************************************************************************* +** +** Function bta_sys_add_uuid_32 +** +** Description Called by BTA subsystems to indicate to DM that new service +** class UUID is added. +** +** Returns void +** +*******************************************************************************/ +void bta_sys_add_uuid_32(UINT32 uuid32) +{ + tBT_UUID uuid; + uuid.len = LEN_UUID_32; + uuid.uu.uuid32 = uuid32; + + if (bta_sys_cb.eir_cb) { + bta_sys_cb.eir_cb(uuid, TRUE); + } +} + +/******************************************************************************* +** +** Function bta_sys_add_uuid_128 +** +** Description Called by BTA subsystems to indicate to DM that new service +** class UUID is added. +** +** Returns void +** +*******************************************************************************/ +void bta_sys_add_uuid_128(UINT8 *uuid128) +{ + tBT_UUID uuid; + uuid.len = LEN_UUID_128; + memcpy(&uuid.uu.uuid128, uuid128, LEN_UUID_128); + if (bta_sys_cb.eir_cb) { - bta_sys_cb.eir_cb(uuid16, TRUE ); + bta_sys_cb.eir_cb(uuid, TRUE); } } @@ -544,10 +591,57 @@ void bta_sys_add_uuid(UINT16 uuid16) *******************************************************************************/ void bta_sys_remove_uuid(UINT16 uuid16) { + tBT_UUID uuid; + uuid.len = LEN_UUID_16; + uuid.uu.uuid16 = uuid16; + + if (bta_sys_cb.eir_cb) { + bta_sys_cb.eir_cb(uuid, FALSE); + } +} + +/******************************************************************************* +** +** Function bta_sys_remove_uuid_32 +** +** Description Called by BTA subsystems to indicate to DM that the service +** class UUID is removed. +** +** Returns void +** +*******************************************************************************/ +void bta_sys_remove_uuid_32(UINT32 uuid32) +{ + tBT_UUID uuid; + uuid.len = LEN_UUID_32; + uuid.uu.uuid32 = uuid32; + if (bta_sys_cb.eir_cb) { - bta_sys_cb.eir_cb(uuid16, FALSE); + bta_sys_cb.eir_cb(uuid, FALSE); } } + +/******************************************************************************* +** +** Function bta_sys_remove_uuid_128 +** +** Description Called by BTA subsystems to indicate to DM that the service +** class UUID is removed. +** +** Returns void +** +*******************************************************************************/ +void bta_sys_remove_uuid_128(UINT8 *uuid128) +{ + tBT_UUID uuid; + uuid.len = LEN_UUID_128; + memcpy(&uuid.uu.uuid128, uuid128, LEN_UUID_128); + + if (bta_sys_cb.eir_cb) { + bta_sys_cb.eir_cb(uuid, FALSE); + } +} + #endif /******************************************************************************* 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 0dab8e1305..f20a7241e1 100644 --- a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,14 +15,14 @@ #if (SMP_INCLUDED == TRUE) -//the maximum nubmer of bonded devices +//the maximum number of bonded devices #define BONED_DEVICES_MAX_COUNT (BTM_SEC_MAX_DEVICE_RECORDS) static void _btc_storage_save(void) { uint16_t addr_section_count = 0; bt_bdaddr_t bd_addr; - uint32_t device_type = 0; + const btc_config_section_iter_t *need_remove_iter = NULL; const btc_config_section_iter_t *iter = btc_config_section_begin(); @@ -47,9 +47,7 @@ static void _btc_storage_save(void) continue; } - if (!string_is_bdaddr(section) || - !btc_config_get_int(section, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || - ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { + if (!string_is_bdaddr(section)) { iter = btc_config_section_next(iter); continue; } @@ -60,23 +58,24 @@ static void _btc_storage_save(void) addr_section_count ++; iter = btc_config_section_next(iter); } - /*exceeded the maximum nubmer of bonded devices, delete them */ + /*exceeded the maximum number of bonded devices, delete them */ if (need_remove_iter) { while(need_remove_iter != btc_config_section_end()) { const char *need_remove_section = btc_config_section_name(need_remove_iter); - if (!string_is_bdaddr(need_remove_section) || - !btc_config_get_int(need_remove_section, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || - ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { + if (!string_is_bdaddr(need_remove_section)) { need_remove_iter = btc_config_section_next(need_remove_iter); continue; } need_remove_iter = btc_config_section_next(need_remove_iter); //delete device info string_to_bdaddr(need_remove_section, &bd_addr); - BTM_SecDeleteDevice(bd_addr.address, BT_TRANSPORT_LE); + BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_LE); + BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_BR_EDR); //delete config info - if(btc_config_remove_section(need_remove_section)) { - BTIF_TRACE_WARNING("exceeded the maximum nubmer of bonded devices, delete the last device info : %s", need_remove_section); + if (btc_config_remove_section(need_remove_section)) { + // The need_remove_section has been freed + BTIF_TRACE_WARNING("Exceeded the maximum number of bonded devices. Deleting the last device info: %02x:%02x:%02x:%02x:%02x:%02x", + bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]); } } } @@ -201,6 +200,170 @@ bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, return ret; } +static bt_status_t _btc_storage_remove_all_ble_keys(const char *name) +{ + int ret = 0; + + if (name == NULL) { + return BT_STATUS_FAIL; + } + + if (btc_config_exist(name, BTC_BLE_STORAGE_ADDR_TYPE_STR)) { + ret |= btc_config_remove(name, BTC_BLE_STORAGE_ADDR_TYPE_STR); + } + if (btc_config_exist(name, BTC_BLE_STORAGE_LE_KEY_PENC_STR)) { + ret |= btc_config_remove(name, BTC_BLE_STORAGE_LE_KEY_PENC_STR); + } + if (btc_config_exist(name, BTC_BLE_STORAGE_LE_KEY_PID_STR)) { + ret |= btc_config_remove(name, BTC_BLE_STORAGE_LE_KEY_PID_STR); + } + if (btc_config_exist(name, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR)) { + ret |= btc_config_remove(name, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR); + } + if (btc_config_exist(name, BTC_BLE_STORAGE_LE_KEY_LENC_STR)) { + ret |= btc_config_remove(name, BTC_BLE_STORAGE_LE_KEY_LENC_STR); + } + if (btc_config_exist(name, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR)) { + ret |= btc_config_remove(name, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR); + } + if (btc_config_exist(name, BTC_BLE_STORAGE_LE_KEY_LID_STR)) { + ret |= btc_config_remove(name, BTC_BLE_STORAGE_LE_KEY_LID_STR); + } + + return ret; +} + +void btc_storage_remove_unused_sections(uint8_t *cur_addr, tBTM_LE_PID_KEYS *del_pid_key) +{ + bt_bdaddr_t bd_addr; + uint32_t device_type = 0; + + if (del_pid_key == NULL) { + return; + } + + btc_config_lock(); + + const btc_config_section_iter_t *iter = btc_config_section_begin(); + + while (iter != btc_config_section_end()) { + //store the next iter, if remove section, then will not loss the point + + const char *section = btc_config_section_name(iter); + if (string_is_bdaddr(section) && + !btc_config_exist(section, BTC_BLE_STORAGE_DEV_TYPE_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_ADDR_TYPE_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LINK_KEY_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PENC_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PID_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_LENC_STR) && + !btc_config_exist(section, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR)) { + iter = btc_config_section_next(iter); + btc_config_remove_section(section); + continue; + } + + if (!string_is_bdaddr(section) || + !btc_config_get_int(section, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || + ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { + iter = btc_config_section_next(iter); + continue; + } + + string_to_bdaddr(section, &bd_addr); + + char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0}; + + if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS) { + + tBTM_LE_PID_KEYS *pid_key = (tBTM_LE_PID_KEYS *) buffer; + + iter = btc_config_section_next(iter); + + if (memcmp(del_pid_key->static_addr, pid_key->static_addr, 6) == 0 && memcmp(cur_addr, bd_addr.address, 6) != 0 && del_pid_key->addr_type == pid_key->addr_type) { + if (device_type == BT_DEVICE_TYPE_DUMO) { + btc_config_set_int(section, BTC_BLE_STORAGE_DEV_TYPE_STR, BT_DEVICE_TYPE_BREDR); + _btc_storage_remove_all_ble_keys(section); + } else { + //delete unused sections + BTIF_TRACE_DEBUG("delete section %s\n", section); + btc_config_remove_section(section); + } + } + } else { + iter = btc_config_section_next(iter); + } + } + + btc_config_unlock(); + +} + +void btc_storage_delete_duplicate_ble_devices(void) +{ + bt_bdaddr_t bd_addr; + char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0}; + char temp_buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0}; + tBTM_LE_PID_KEYS *pid_key; + tBTM_LE_PID_KEYS *temp_pid_key; + uint32_t device_type = 0; + + bt_bdaddr_t temp_bd_addr; + + btc_config_lock(); + for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); + iter = btc_config_section_next(iter)) { + const char *name = btc_config_section_name(iter); + + if (!string_is_bdaddr(name) || + !btc_config_get_int(name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || + ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { + continue; + } + + string_to_bdaddr(name, &bd_addr); + if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS) + { + pid_key = (tBTM_LE_PID_KEYS *) buffer; + + const btc_config_section_iter_t *temp_iter = btc_config_section_next(iter); + while (temp_iter != NULL) + { + const char *temp_name = btc_config_section_name(temp_iter); + if (!string_is_bdaddr(temp_name) || !btc_config_get_int(temp_name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || + ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { + temp_iter = btc_config_section_next(temp_iter); + continue; + } + string_to_bdaddr(temp_name, &temp_bd_addr); + if (_btc_storage_get_ble_bonding_key(&temp_bd_addr, BTM_LE_KEY_PID, temp_buffer, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS) + { + temp_pid_key = (tBTM_LE_PID_KEYS *) temp_buffer; + if (memcmp(pid_key->static_addr, temp_pid_key->static_addr, 6) == 0 && pid_key->addr_type == temp_pid_key->addr_type) { + const char *temp_name = btc_config_section_name(temp_iter); + temp_iter = btc_config_section_next(temp_iter); + if (device_type == BT_DEVICE_TYPE_DUMO) { + btc_config_set_int(temp_name, BTC_BLE_STORAGE_DEV_TYPE_STR, BT_DEVICE_TYPE_BREDR); + _btc_storage_remove_all_ble_keys(temp_name); + } else { + BTC_TRACE_DEBUG("delete %s\n", temp_name); + btc_config_remove_section(temp_name); + } + } else { + temp_iter = btc_config_section_next(temp_iter); + } + } else { + temp_iter = btc_config_section_next(temp_iter); + } + } + + } + } + btc_config_unlock(); +} + + /******************************************************************************* ** ** Function btc_storage_remove_ble_bonding_keys @@ -219,27 +382,8 @@ 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); - if (btc_config_exist(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR)) { - ret |= btc_config_remove(bdstr, BTC_BLE_STORAGE_ADDR_TYPE_STR); - } - if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_PENC_STR)) { - ret |= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_PENC_STR); - } - if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_PID_STR)) { - ret |= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_PID_STR); - } - if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR)) { - ret |= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_PCSRK_STR); - } - if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_LENC_STR)) { - ret |= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_LENC_STR); - } - if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR)) { - ret |= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_LCSRK_STR); - } - if (btc_config_exist(bdstr, BTC_BLE_STORAGE_LE_KEY_LID_STR)) { - ret |= btc_config_remove(bdstr, BTC_BLE_STORAGE_LE_KEY_LID_STR); - } + ret = _btc_storage_remove_all_ble_keys(bdstr); + //here don't remove section, because config_save will check it _btc_storage_save(); return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; @@ -758,7 +902,7 @@ static void _btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bd *key_found = true; } } -static bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add) +bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add) { uint32_t device_type; int addr_type; @@ -800,61 +944,17 @@ static bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd if (key_found) { return BT_STATUS_SUCCESS; + } else { + BTC_TRACE_DEBUG("Remote device:%s, no link key or ble key found", remote_bd_addr); } return BT_STATUS_FAIL; } -static bt_status_t btc_storage_in_fetch_bonded_ble_devices(int add) -{ - bt_status_t status = BT_STATUS_FAIL; - uint32_t device_type = 0; - - btc_config_lock(); - for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); - iter = btc_config_section_next(iter)) { - const char *name = btc_config_section_name(iter); - - if (!string_is_bdaddr(name) || - !btc_config_get_int(name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || - ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { - continue; - } - BTC_TRACE_DEBUG("%s, name = %s", __func__, name); - if (_btc_storage_in_fetch_bonded_ble_device(name, add) != BT_STATUS_SUCCESS) { - BTC_TRACE_DEBUG("Remote device:%s, no link key or ble key found", name); - } else { - status = BT_STATUS_SUCCESS; - } - } - btc_config_unlock(); - - return status; -} - -/******************************************************************************* -** -** Function btc_storage_load_bonded_devices -** -** Description btc storage API - Loads all the bonded devices from NVRAM -** and adds to the BTA. -** Additionally, this API also invokes the adaper_properties_cb -** and remote_device_properties_cb for each of the bonded devices. -** -** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -bt_status_t btc_storage_load_bonded_ble_devices(void) -{ - bt_status_t status; - status = btc_storage_in_fetch_bonded_ble_devices(1); - BTC_TRACE_DEBUG("Storage load rslt %d\n", status); - return status; -} - bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num) { bt_bdaddr_t bd_addr; + int addr_t; char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0}; btc_config_lock(); @@ -876,6 +976,14 @@ bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev string_to_bdaddr(name, &bd_addr); memcpy(bond_dev->bd_addr, bd_addr.address, sizeof(bt_bdaddr_t)); + //get address type + if (_btc_storage_get_remote_addr_type((bt_bdaddr_t *)bond_dev->bd_addr, &addr_t) == BT_STATUS_SUCCESS) { + bond_dev->bd_addr_type = (uint8_t) addr_t; + } else { + // Set an invalid address type + bond_dev->bd_addr_type = 0xFF; + BTC_TRACE_ERROR("%s, %s get address type fail", __func__, name); + } //resolve the peer device long term key if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PENC, buffer, sizeof(tBTM_LE_PENC_KEYS)) == BT_STATUS_SUCCESS) { bond_dev->bond_key.key_mask |= ESP_BLE_ENC_KEY_MASK; diff --git a/components/bt/host/bluedroid/btc/core/btc_config.c b/components/bt/host/bluedroid/btc/core/btc_config.c index 32393636e7..004a577340 100644 --- a/components/bt/host/bluedroid/btc/core/btc_config.c +++ b/components/bt/host/bluedroid/btc/core/btc_config.c @@ -299,6 +299,14 @@ bool btc_config_remove_section(const char *section) return config_remove_section(config, section); } +bool btc_config_update_newest_section(const char *section) +{ + assert(config != NULL); + assert(section != NULL); + + return config_update_newest_section(config, section); +} + void btc_config_flush(void) { assert(config != NULL); diff --git a/components/bt/host/bluedroid/btc/core/btc_dm.c b/components/bt/host/bluedroid/btc/core/btc_dm.c index b0699685ce..8c55d7bbe3 100644 --- a/components/bt/host/bluedroid/btc/core/btc_dm.c +++ b/components/bt/host/bluedroid/btc/core/btc_dm.c @@ -10,6 +10,7 @@ #include "btc/btc_common.h" #include "btc/btc_dm.h" #include "btc/btc_main.h" +#include "btc/btc_util.h" #include "common/bt_trace.h" #include "common/bt_target.h" #include "btc/btc_storage.h" @@ -265,7 +266,12 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl) return; } - if (btc_storage_get_remote_addr_type(&bdaddr, &addr_type) != BT_STATUS_SUCCESS) { + if (btc_dm_cb.pairing_cb.ble.is_pid_key_rcvd) { + // delete unused section in NVS + btc_storage_remove_unused_sections(p_auth_cmpl->bd_addr, &btc_dm_cb.pairing_cb.ble.pid_key); + } + + if (btc_storage_get_remote_addr_type(&bdaddr, &addr_type) != BT_STATUS_SUCCESS) { btc_storage_set_remote_addr_type(&bdaddr, p_auth_cmpl->addr_type, true); } btc_storage_set_ble_dev_auth_mode(&bdaddr, p_auth_cmpl->auth_mode, true); @@ -684,18 +690,19 @@ static void btc_dm_acl_link_stat(tBTA_DM_ACL_LINK_STAT *p_acl_link_stat) #if (BTC_GAP_BT_INCLUDED == TRUE) esp_bt_gap_cb_param_t param; esp_bt_gap_cb_event_t event = ESP_BT_GAP_EVT_MAX; + bt_bdaddr_t bt_addr; switch (p_acl_link_stat->event) { case BTA_ACL_LINK_STAT_CONN_CMPL: { event = ESP_BT_GAP_ACL_CONN_CMPL_STAT_EVT; - param.acl_conn_cmpl_stat.stat = p_acl_link_stat->link_act.conn_cmpl.status | ESP_BT_STATUS_BASE_FOR_HCI_ERR; + param.acl_conn_cmpl_stat.stat = btc_hci_to_esp_status(p_acl_link_stat->link_act.conn_cmpl.status); param.acl_conn_cmpl_stat.handle = p_acl_link_stat->link_act.conn_cmpl.handle; memcpy(param.acl_conn_cmpl_stat.bda, p_acl_link_stat->link_act.conn_cmpl.bd_addr, ESP_BD_ADDR_LEN); break; } case BTA_ACL_LINK_STAT_DISCONN_CMPL: { event = ESP_BT_GAP_ACL_DISCONN_CMPL_STAT_EVT; - param.acl_disconn_cmpl_stat.reason = p_acl_link_stat->link_act.disconn_cmpl.reason | ESP_BT_STATUS_BASE_FOR_HCI_ERR; + param.acl_disconn_cmpl_stat.reason = btc_hci_to_esp_status(p_acl_link_stat->link_act.disconn_cmpl.reason); param.acl_disconn_cmpl_stat.handle = p_acl_link_stat->link_act.disconn_cmpl.handle; memcpy(param.acl_disconn_cmpl_stat.bda, p_acl_link_stat->link_act.disconn_cmpl.bd_addr, ESP_BD_ADDR_LEN); break; @@ -706,6 +713,18 @@ static void btc_dm_acl_link_stat(tBTA_DM_ACL_LINK_STAT *p_acl_link_stat) } } +#if (SMP_INCLUDED == TRUE) + if (p_acl_link_stat->event == BTA_ACL_LINK_STAT_CONN_CMPL && + p_acl_link_stat->link_act.conn_cmpl.status == HCI_SUCCESS) { + memcpy(bt_addr.address, p_acl_link_stat->link_act.conn_cmpl.bd_addr, sizeof(bt_addr.address)); + if (btc_storage_update_active_device(&bt_addr)) { + BTC_TRACE_EVENT("Device: %02x:%02x:%02x:%02x:%02x:%02x, is not in bond list", + bt_addr.address[0], bt_addr.address[1], + bt_addr.address[2], bt_addr.address[3], + bt_addr.address[4], bt_addr.address[5]); + } + } +#endif ///SMP_INCLUDED == TRUE esp_bt_gap_cb_t cb = (esp_bt_gap_cb_t)btc_profile_cb_get(BTC_PID_GAP_BT); if (cb) { cb(event, ¶m); @@ -737,11 +756,11 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg) case BTA_DM_ENABLE_EVT: { btc_clear_services_mask(); #if (SMP_INCLUDED == TRUE) - btc_storage_load_bonded_devices(); #if (BLE_INCLUDED == TRUE) + btc_storage_delete_duplicate_ble_devices(); +#endif ///BLE_INCLUDED == TRUE //load the bonding device to the btm layer - btc_storage_load_bonded_ble_devices(); -#endif ///BLE_INCLUDED == TRUE + btc_storage_load_bonded_devices(); #endif ///SMP_INCLUDED == TRUE /* Set initial device name, it can be overwritten later */ diff --git a/components/bt/host/bluedroid/btc/core/btc_main.c b/components/bt/host/bluedroid/btc/core/btc_main.c index 02e4bbc1e7..c1c694b8a2 100644 --- a/components/bt/host/bluedroid/btc/core/btc_main.c +++ b/components/bt/host/bluedroid/btc/core/btc_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -60,6 +60,7 @@ static void btc_init_bluetooth(void) #if (BLE_INCLUDED == TRUE) //load the ble local key which has been stored in the flash btc_dm_load_ble_local_keys(); + bta_dm_co_security_param_init(); #endif ///BLE_INCLUDED == TRUE #endif /* #if (SMP_INCLUDED) */ #if BTA_DYNAMIC_MEMORY @@ -116,3 +117,93 @@ void btc_main_call_handler(btc_msg_t *msg) break; } } + +uint32_t btc_get_ble_status(void) +{ + uint32_t status = BTC_BLE_STATUS_IDLE; + + #if (BLE_INCLUDED == TRUE) + // Number of active advertising + extern uint8_t btm_ble_adv_active_count(void); + if (btm_ble_adv_active_count()) { + status |= BIT(BTC_BLE_STATUS_ADV); + } + + // Number of active scanning + extern uint8_t btm_ble_scan_active_count(void); + if (btm_ble_scan_active_count()) { + status |= BIT(BTC_BLE_STATUS_SCAN); + } + + // Number of active GATT tcb + extern uint8_t gatt_tcb_active_count(void); + if (gatt_tcb_active_count()) { + status |= BIT(BTC_BLE_STATUS_CONN); + } + + #if (SMP_INCLUDED == TRUE) + // Number of recorded devices + extern uint8_t btm_ble_sec_dev_active_count(void); + if (btm_ble_sec_dev_active_count()) { + status |= BIT(BTC_BLE_STATUS_KEYS); + } + + // Number of saved bonded devices + if (btc_storage_get_num_ble_bond_devices()) { + status |= BIT(BTC_BLE_STATUS_BOND); + } + #endif + + #if (BLE_PRIVACY_SPT == TRUE) + // Privacy enabled + extern uint8_t btm_ble_privacy_is_enabled(void); + if (btm_ble_privacy_is_enabled()) { + status |= BIT(BTC_BLE_STATUS_PRIVACY); + } + #endif + #endif + + #if (BLE_50_FEATURE_SUPPORT == TRUE) + // Number of active extended advertsing + extern uint8_t btm_ble_ext_adv_active_count(void); + if (btm_ble_ext_adv_active_count()) { + status |= BIT(BTC_BLE_STATUS_EXT_ADV); + } + #endif + + // Number of active ACL connection + extern uint8_t btm_acl_active_count(void); + if (btm_acl_active_count()) { + status |= BIT(BTC_BLE_STATUS_CONN); + } + + // Number of active L2C plcb + extern uint8_t l2cu_plcb_active_count(void); + if (l2cu_plcb_active_count()) { + status |= BIT(BTC_BLE_STATUS_CONN); + } + + #if (GATTC_INCLUDED == TRUE) + // Number of registered GATTC APP + extern uint8_t bta_gattc_cl_rcb_active_count(void); + if (bta_gattc_cl_rcb_active_count()) { + status |= BIT(BTC_BLE_STATUS_GATTC_APP); + } + + // Number of saved GATTC cache + extern UINT8 bta_gattc_co_get_addr_num(void); + if (bta_gattc_co_get_addr_num()) { + status |= BIT(BTC_BLE_STATUS_GATTC_CACHE); + } + #endif + + #if (GATTS_INCLUDED == TRUE) + // Number of registered GATTS service + extern uint8_t bta_gatts_srvc_active_count(void); + if (bta_gatts_srvc_active_count()) { + status |= BIT(BTC_BLE_STATUS_GATTS_SRVC); + } + #endif + + return status; +} diff --git a/components/bt/host/bluedroid/btc/core/btc_storage.c b/components/bt/host/bluedroid/btc/core/btc_storage.c index 32de0fbb8f..1923dea0da 100644 --- a/components/bt/host/bluedroid/btc/core/btc_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_storage.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include "btc/btc_storage.h" +#include "btc/btc_ble_storage.h" #include "btc/btc_util.h" #include "osi/osi.h" #include "osi/allocator.h" @@ -35,8 +36,32 @@ bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr, BOOLEAN sc_support) { bdstr_t bdstr; - + bt_bdaddr_t bd_addr; bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + + /* device not in bond list and exceed the maximum number of bonded devices, delete the inactive bonded device */ + if (btc_storage_get_num_all_bond_devices() >= BTM_SEC_MAX_DEVICE_RECORDS && !btc_config_has_section(bdstr)) { + const btc_config_section_iter_t *iter = btc_config_section_begin(); + const btc_config_section_iter_t *remove_iter = iter; + /* find the first device(the last node) */ + while (iter != btc_config_section_end()) { + remove_iter = iter; + iter = btc_config_section_next(iter); + } + const char *remove_section = btc_config_section_name(remove_iter); + + // delete device info + string_to_bdaddr(remove_section, &bd_addr); + BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_BR_EDR); + BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_LE); + + // delete config info + if (btc_config_remove_section(remove_section)) { + BTC_TRACE_WARNING("exceeded the maximum nubmer of bonded devices, delete the first device info : %02x:%02x:%02x:%02x:%02x:%02x", + bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]); + } + } + BTC_TRACE_DEBUG("add to storage: Remote device:%s\n", bdstr); btc_config_lock(); @@ -52,65 +77,109 @@ bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr, return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; } -/******************************************************************************* -** -** Function btc_in_fetch_bonded_devices -** -** Description Internal helper function to fetch the bonded devices -** from NVRAM -** -** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise -** -*******************************************************************************/ -static bt_status_t btc_in_fetch_bonded_devices(int add) +#if (SMP_INCLUDED == TRUE) +static bt_status_t _btc_storage_in_fetch_bonded_bt_device(const char *remote_bd_addr, int add) { BOOLEAN bt_linkkey_file_found = FALSE; UINT8 sc_support = 0; - btc_config_lock(); - for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); iter = btc_config_section_next(iter)) { - const char *name = btc_config_section_name(iter); - if (!string_is_bdaddr(name)) { - continue; - } - - BTC_TRACE_DEBUG("Remote device:%s\n", name); - LINK_KEY link_key; + BTC_TRACE_DEBUG("Remote device:%s\n", remote_bd_addr); + LINK_KEY link_key; size_t size = sizeof(link_key); - if (btc_config_get_bin(name, BTC_STORAGE_LINK_KEY_STR, link_key, &size)) { + if (btc_config_get_bin(remote_bd_addr, BTC_STORAGE_LINK_KEY_STR, link_key, &size)) { int linkkey_type; - if (btc_config_get_int(name, BTC_STORAGE_LINK_KEY_TYPE_STR, &linkkey_type)) { + if (btc_config_get_int(remote_bd_addr, BTC_STORAGE_LINK_KEY_TYPE_STR, &linkkey_type)) { bt_bdaddr_t bd_addr; - string_to_bdaddr(name, &bd_addr); + string_to_bdaddr(remote_bd_addr, &bd_addr); if (add) { DEV_CLASS dev_class = {0, 0, 0}; int cod; int pin_length = 0; - if (btc_config_get_int(name, BTC_STORAGE_DEV_CLASS_STR, &cod)) { + if (btc_config_get_int(remote_bd_addr, BTC_STORAGE_DEV_CLASS_STR, &cod)) { uint2devclass((UINT32)cod, dev_class); } - btc_config_get_int(name, BTC_STORAGE_PIN_LENGTH_STR, &pin_length); + btc_config_get_int(remote_bd_addr, BTC_STORAGE_PIN_LENGTH_STR, &pin_length); size = sizeof(sc_support); - btc_config_get_bin(name, BTC_STORAGE_SC_SUPPORT, &sc_support, &size); -#if (SMP_INCLUDED == TRUE) + btc_config_get_bin(remote_bd_addr, BTC_STORAGE_SC_SUPPORT, &sc_support, &size); + BTA_DmAddDevice(bd_addr.address, dev_class, link_key, 0, 0, (UINT8)linkkey_type, 0, pin_length, (UINT8)sc_support); -#endif ///SMP_INCLUDED == TRUE } bt_linkkey_file_found = TRUE; } else { - BTC_TRACE_ERROR("bounded device:%s, LinkKeyType or PinLength is invalid\n", name); + BTC_TRACE_ERROR("bounded device:%s, LinkKeyType or PinLength is invalid\n", remote_bd_addr); } } if (!bt_linkkey_file_found) { - BTC_TRACE_DEBUG("Remote device:%s, no link key\n", name); + BTC_TRACE_DEBUG("Remote device:%s, no link key\n", remote_bd_addr); } - } - btc_config_unlock(); return BT_STATUS_SUCCESS; } +/******************************************************************************* +** +** Function btc_in_fetch_bonded_devices +** +** Description Internal helper function to fetch the bonded devices +** from NVRAM +** +** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise +** +*******************************************************************************/ +static bt_status_t btc_in_fetch_bonded_devices(int add) +{ + bt_status_t status = BT_STATUS_FAIL; + uint16_t dev_cnt = 0; + const btc_config_section_iter_t *remove_iter = NULL; + bt_bdaddr_t bd_addr; + + btc_config_lock(); + for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); iter = btc_config_section_next(iter)) { + const char *name = btc_config_section_name(iter); + if (!string_is_bdaddr(name)) { + continue; + } + dev_cnt ++; + /* if the number of device stored in nvs not exceed to BTM_SEC_MAX_DEVICE_RECORDS, load it */ + if (dev_cnt <= BTM_SEC_MAX_DEVICE_RECORDS) { + if (btc_config_exist(name, BTC_STORAGE_LINK_KEY_TYPE_STR) && btc_config_exist(name, BTC_STORAGE_PIN_LENGTH_STR) && + btc_config_exist(name, BTC_STORAGE_SC_SUPPORT) && btc_config_exist(name, BTC_STORAGE_LINK_KEY_STR)) { + /* load bt device */ + status = _btc_storage_in_fetch_bonded_bt_device(name, add); + } + if (btc_config_exist(name, BTC_BLE_STORAGE_DEV_TYPE_STR)) { +#if (BLE_INCLUDED == TRUE) + /* load ble device */ + status = _btc_storage_in_fetch_bonded_ble_device(name, add); +#endif ///BLE_INCLUDED == TRUE + } + } else { + /* delete the exceeded device info from nvs */ + remove_iter = iter; + while (remove_iter != btc_config_section_end()) { + const char *remove_section = btc_config_section_name(remove_iter); + string_to_bdaddr(remove_section, &bd_addr); + if (!string_is_bdaddr(remove_section)) { + remove_iter = btc_config_section_next(remove_iter); + continue; + } + remove_iter = btc_config_section_next(remove_iter); + /* delete config info */ + if (btc_config_remove_section(remove_section)) { + BTC_TRACE_WARNING("exceeded the maximum number of bonded devices, delete the exceed device info : %02x:%02x:%02x:%02x:%02x:%02x", + bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]); + } + } + /* write into nvs */ + btc_config_flush(); + break; + } + } + btc_config_unlock(); + + return status; +} /******************************************************************************* ** @@ -132,6 +201,33 @@ bt_status_t btc_storage_load_bonded_devices(void) return status; } +/******************************************************************************* +** +** Function btc_storage_update_active_device +** +** Description BTC storage API - Once an ACL link is established and remote +** bd_addr is already stored in NVRAM, update the config and update +** the remote device to be the newest active device, The updates will +** not be stored into NVRAM immediately. +** +** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise +** +*******************************************************************************/ +bool btc_storage_update_active_device(bt_bdaddr_t *remote_bd_addr) +{ + bdstr_t bdstr; + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); + bool ret = false; + BTC_TRACE_DEBUG("Update active device: Remote device:%s\n", bdstr); + + btc_config_lock(); + ret = btc_config_update_newest_section(bdstr); + btc_config_unlock(); + + return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; +} +#endif ///SMP_INCLUDED == TRUE + /******************************************************************************* ** ** Function btc_storage_remove_bonded_device @@ -490,3 +586,18 @@ bt_status_t btc_storage_remove_hidd(bt_bdaddr_t *remote_bd_addr) return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; } #endif //(defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE) + +int btc_storage_get_num_all_bond_devices(void) { + int num_dev = 0; + + btc_config_lock(); + for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); + iter = btc_config_section_next(iter)) { + const char *name = btc_config_section_name(iter); + if (string_is_bdaddr(name)) { + num_dev++; + } + } + btc_config_unlock(); + return num_dev; +} diff --git a/components/bt/host/bluedroid/btc/core/btc_util.c b/components/bt/host/bluedroid/btc/core/btc_util.c index 9818e7064b..5e29aba8be 100644 --- a/components/bt/host/bluedroid/btc/core/btc_util.c +++ b/components/bt/host/bluedroid/btc/core/btc_util.c @@ -338,8 +338,11 @@ esp_bt_status_t btc_hci_to_esp_status(uint8_t hci_status) case HCI_ERR_ILLEGAL_PARAMETER_FMT: esp_status = ESP_BT_STATUS_ERR_ILLEGAL_PARAMETER_FMT; break; + case HCI_ERR_UNSUPPORTED_VALUE: + esp_status = ESP_BT_STATUS_UNSUPPORTED; + break; default: - esp_status = ESP_BT_STATUS_FAIL; + esp_status = hci_status | ESP_BT_STATUS_BASE_FOR_HCI_ERR; break; } diff --git a/components/bt/host/bluedroid/btc/include/btc/btc_ble_storage.h b/components/bt/host/bluedroid/btc/include/btc/btc_ble_storage.h index 490e97fd5f..2cfb38b88b 100644 --- a/components/bt/host/bluedroid/btc/include/btc/btc_ble_storage.h +++ b/components/bt/host/bluedroid/btc/include/btc/btc_ble_storage.h @@ -16,6 +16,7 @@ #include "stack/bt_types.h" #include "common/bt_target.h" #include "esp_gap_ble_api.h" +#include "bta/bta_api.h" #if (SMP_INCLUDED == TRUE) #define BTC_LE_LOCAL_KEY_IR (1<<0) @@ -61,6 +62,8 @@ bt_status_t btc_storage_remove_ble_bonding_keys(bt_bdaddr_t *remote_bd_addr); bool btc_storage_compare_address_key_value(bt_bdaddr_t *remote_bd_addr, uint8_t key_type, void *key_value, int key_length); +bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add); + bt_status_t btc_storage_add_ble_local_key(char *key, uint8_t key_type, uint8_t key_length); bt_status_t btc_storage_remove_ble_local_keys(void); @@ -83,11 +86,14 @@ bt_status_t btc_storage_set_ble_dev_type(bt_bdaddr_t *bd_addr, bool flush); bt_status_t btc_storage_remove_ble_dev_type(bt_bdaddr_t *remote_bd_addr, bool flush); -bt_status_t btc_storage_load_bonded_ble_devices(void); - bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev, int dev_num); int btc_storage_get_num_ble_bond_devices(void); + +void btc_storage_delete_duplicate_ble_devices(void); + +void btc_storage_remove_unused_sections(uint8_t *cur_addr, tBTM_LE_PID_KEYS *del_pid_key); + #endif ///SMP_INCLUDED == TRUE #define BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR "GATT_CL_SUPP_FEAT" diff --git a/components/bt/host/bluedroid/btc/include/btc/btc_config.h b/components/bt/host/bluedroid/btc/include/btc/btc_config.h index 731859a8cb..41bb0258dc 100644 --- a/components/bt/host/bluedroid/btc/include/btc/btc_config.h +++ b/components/bt/host/bluedroid/btc/include/btc/btc_config.h @@ -28,6 +28,7 @@ bool btc_config_get_bin(const char *section, const char *key, uint8_t *value, si bool btc_config_set_bin(const char *section, const char *key, const uint8_t *value, size_t length); bool btc_config_remove(const char *section, const char *key); bool btc_config_remove_section(const char *section); +bool btc_config_update_newest_section(const char *section); size_t btc_config_get_bin_length(const char *section, const char *key); diff --git a/components/bt/host/bluedroid/btc/include/btc/btc_main.h b/components/bt/host/bluedroid/btc/include/btc/btc_main.h index 38be7ab7d8..df20a63878 100644 --- a/components/bt/host/bluedroid/btc/include/btc/btc_main.h +++ b/components/bt/host/bluedroid/btc/include/btc/btc_main.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,6 +28,20 @@ typedef enum { BTC_MAIN_FUTURE_NUM, } btc_main_future_type_t; +#define BTC_BLE_STATUS_IDLE 0 +typedef enum { + BTC_BLE_STATUS_ADV = 0, // Advertising exist + BTC_BLE_STATUS_EXT_ADV, // Extended advertising exist + BTC_BLE_STATUS_SCAN, // Scanning exist + BTC_BLE_STATUS_CONN, // Connection exist + BTC_BLE_STATUS_KEYS, // Device keys record exist + BTC_BLE_STATUS_BOND, // Bond info exist + BTC_BLE_STATUS_GATTC_CACHE, // GATTC cache exist + BTC_BLE_STATUS_GATTC_APP, // GATTC application exist + BTC_BLE_STATUS_GATTS_SRVC, // GATTS service exist + BTC_BLE_STATUS_PRIVACY, // Privacy enabled +} tBTC_BLE_STATUS; + future_t **btc_main_get_future_p(btc_main_future_type_t type); #if 0 diff --git a/components/bt/host/bluedroid/btc/include/btc/btc_storage.h b/components/bt/host/bluedroid/btc/include/btc/btc_storage.h index d87299ce2e..05c05430e7 100644 --- a/components/bt/host/bluedroid/btc/include/btc/btc_storage.h +++ b/components/bt/host/bluedroid/btc/include/btc/btc_storage.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 */ @@ -54,12 +54,14 @@ bt_status_t btc_storage_remove_bonded_device(bt_bdaddr_t *remote_bd_addr); /******************************************************************************* ** -** Function btc_storage_remove_bonded_device +** Function btc_storage_load_bonded_devices ** -** Description BTC storage API - Deletes the bonded device from NVRAM +** Description BTC storage API - Loads all the bonded devices from NVRAM +** and adds to the BTA. +** Additionally, this API also invokes the adaper_properties_cb +** and remote_device_properties_cb for each of the bonded devices. ** -** Returns BT_STATUS_SUCCESS if the deletion was successful, -** BT_STATUS_FAIL otherwise +** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise ** *******************************************************************************/ bt_status_t btc_storage_load_bonded_devices(void); @@ -87,6 +89,31 @@ int btc_storage_get_num_bt_bond_devices(void); *******************************************************************************/ bt_status_t btc_storage_get_bonded_bt_devices_list(bt_bdaddr_t *bond_dev, int *dev_num); +/******************************************************************************* +** +** Function btc_storage_get_num_all_bond_devices +** +** Description BTC storage API - get all the num of the bonded device from NVRAM +** +** Returns the num of the bonded device +** +*******************************************************************************/ +int btc_storage_get_num_all_bond_devices(void); + +/******************************************************************************* +** +** Function btc_storage_update_active_device +** +** Description BTC storage API - Once an ACL link is established and remote +** bd_addr is already stored in NVRAM, update the config and update +** the remote device to be the newest active device. The updates will +** not be stored into NVRAM immediately. +** +** Returns BT_STATUS_SUCCESS if successful, BT_STATUS_FAIL otherwise +** +*******************************************************************************/ +bool btc_storage_update_active_device(bt_bdaddr_t *remote_bd_addr); + #if (defined BTC_HH_INCLUDED && BTC_HH_INCLUDED == TRUE) /******************************************************************************* * @@ -164,8 +191,7 @@ bt_status_t btc_storage_set_hidd(bt_bdaddr_t *remote_bd_addr); ******************************************************************************/ bt_status_t btc_storage_remove_hidd(bt_bdaddr_t *remote_bd_addr); #endif //(defined BTC_HD_INCLUDED && BTC_HD_INCLUDED == TRUE) +#endif /* BTC_STORAGE_H */ #ifdef __cplusplus } #endif - -#endif /* BTC_STORAGE_H */ diff --git a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c index fbf861fd45..d388e94a6c 100644 --- a/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c +++ b/components/bt/host/bluedroid/btc/profile/std/a2dp/btc_a2dp_source.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 */ @@ -42,6 +42,13 @@ #if BTC_AV_SRC_INCLUDED +/***************************************************************************** + ** BQB global variables + *****************************************************************************/ +#if A2D_SRC_BQB_INCLUDED +bool a2dp_src_bqb_set_sbc_encoder_flag = FALSE; +#endif /* A2D_SRC_BQB_INCLUDED */ + /***************************************************************************** ** Constants *****************************************************************************/ @@ -928,6 +935,27 @@ static void btc_a2dp_source_enc_update(BT_HDR *p_msg) } } +#if A2D_SRC_BQB_INCLUDED +/******************************************************************************* + ** + ** Function btc_a2dp_source_bqb_sbc_encoder_set + ** + ** Description Set SBC encoder for bqb test cases A2DP/SRC/SET/BV-04-I and A2DP/SRC/SET/BV-06-I + ** + ** Returns void + ** + *******************************************************************************/ +void btc_a2dp_source_bqb_sbc_encoder_set(void) +{ + a2dp_source_local_param.btc_aa_src_cb.encoder.s16NumOfSubBands = 8; + a2dp_source_local_param.btc_aa_src_cb.encoder.s16NumOfBlocks = 8; + a2dp_source_local_param.btc_aa_src_cb.encoder.s16AllocationMethod = SBC_LOUDNESS; + a2dp_source_local_param.btc_aa_src_cb.encoder.s16ChannelMode = SBC_MONO; + a2dp_source_local_param.btc_aa_src_cb.encoder.s16SamplingFreq = SBC_sf44100; + SBC_Encoder_Init(&(a2dp_source_local_param.btc_aa_src_cb.encoder)); +} +#endif /* A2D_SRC_BQB_INCLUDED */ + /******************************************************************************* ** ** Function btc_a2dp_source_pcm2sbc_init @@ -998,6 +1026,12 @@ static void btc_a2dp_source_pcm2sbc_init(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_feedin } else { APPL_TRACE_DEBUG("%s no SBC reconfig needed", __FUNCTION__); } + +#if A2D_SRC_BQB_INCLUDED + if (a2dp_src_bqb_set_sbc_encoder_flag) { + btc_a2dp_source_bqb_sbc_encoder_set(); + } +#endif /* A2D_SRC_BQB_INCLUDED */ } /******************************************************************************* 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 809f665f72..3c6531b491 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -86,7 +86,8 @@ static void btc_gap_ble_get_dev_name_callback(UINT8 status, char *name) param.get_dev_name_cmpl.status = btc_btm_status_to_esp_status(status); param.get_dev_name_cmpl.name = (char *)osi_malloc(BTC_MAX_LOC_BD_NAME_LEN + 1); if (param.get_dev_name_cmpl.name) { - BCM_STRNCPY_S(param.get_dev_name_cmpl.name, name, BTC_MAX_LOC_BD_NAME_LEN + 1); + BCM_STRNCPY_S(param.get_dev_name_cmpl.name, name, BTC_MAX_LOC_BD_NAME_LEN); + param.get_dev_name_cmpl.name[BTC_MAX_LOC_BD_NAME_LEN] = '\0'; } else { param.get_dev_name_cmpl.status = ESP_BT_STATUS_NOMEM; } @@ -469,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; @@ -864,6 +884,40 @@ static void btc_set_local_privacy_callback(UINT8 status) } } +static void btc_set_rpa_timeout_callback(UINT8 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_SET_RPA_TIMEOUT_COMPLETE_EVT; + param.set_rpa_timeout_cmpl.status = btc_btm_status_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__); + } +} + +static void btc_add_dev_to_resolving_list_callback(UINT8 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_ADD_DEV_TO_RESOLVING_LIST_COMPLETE_EVT; + + param.add_dev_to_resolving_list_cmpl.status = btc_btm_status_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__); + } +} #if (SMP_INCLUDED == TRUE) static void btc_set_encryption_callback(BD_ADDR bd_addr, tBTA_TRANSPORT transport, tBTA_STATUS enc_status) @@ -928,34 +982,48 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, case BTA_DM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT: msg.act = ESP_GAP_BLE_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT; param.ext_adv_set_rand_addr.status = btc_btm_status_to_esp_status(params->set_ext_rand_addr.status); + param.ext_adv_set_rand_addr.instance = params->set_ext_rand_addr.instance; break; case BTA_DM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_EXT_ADV_SET_PARAMS_COMPLETE_EVT; - param.ext_adv_set_rand_addr.status = btc_btm_status_to_esp_status(params->set_params.status); + param.ext_adv_set_params.status = btc_btm_status_to_esp_status(params->set_params.status); + param.ext_adv_set_params.instance = params->set_params.instance; break; } case BTA_DM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_EXT_ADV_DATA_SET_COMPLETE_EVT; param.ext_adv_data_set.status = btc_btm_status_to_esp_status(params->adv_data_set.status); + param.ext_adv_data_set.instance = params->adv_data_set.instance; break; } case BTA_DM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT; param.scan_rsp_set.status = btc_btm_status_to_esp_status(params->scan_rsp_data_set.status); + param.scan_rsp_set.instance = params->scan_rsp_data_set.instance; break; } case BTA_DM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_EXT_ADV_START_COMPLETE_EVT; param.ext_adv_start.status = btc_btm_status_to_esp_status(params->adv_start.status); + for (UINT8 i = 0; i < params->adv_start.instance_num; i++) { + param.ext_adv_start.instance[i] = params->adv_start.instance[i]; + } + + param.ext_adv_start.instance_num = params->adv_start.instance_num; break; } case BTA_DM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT: msg.act = ESP_GAP_BLE_EXT_ADV_STOP_COMPLETE_EVT; param.ext_adv_stop.status = btc_btm_status_to_esp_status(params->adv_start.status); + for (UINT8 i = 0; i < params->adv_start.instance_num; i++) { + param.ext_adv_stop.instance[i] = params->adv_start.instance[i]; + } + param.ext_adv_stop.instance_num = params->adv_start.instance_num; break; case BTA_DM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT: msg.act = ESP_GAP_BLE_EXT_ADV_SET_REMOVE_COMPLETE_EVT; param.ext_adv_remove.status = btc_btm_status_to_esp_status(params->adv_start.status); + param.ext_adv_remove.instance = params->adv_start.instance[0]; break; case BTA_DM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT: msg.act = ESP_GAP_BLE_EXT_ADV_SET_CLEAR_COMPLETE_EVT; @@ -964,21 +1032,25 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, case BTA_DM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT; param.peroid_adv_set_params.status = btc_btm_status_to_esp_status(params->per_adv_set_params.status); + param.peroid_adv_set_params.instance = params->per_adv_set_params.instance; break; } case BTA_DM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_PERIODIC_ADV_DATA_SET_COMPLETE_EVT; param.period_adv_data_set.status = btc_btm_status_to_esp_status(params->per_adv_data_set.status); + param.period_adv_data_set.instance = params->per_adv_data_set.instance; break; } case BTA_DM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_PERIODIC_ADV_START_COMPLETE_EVT; param.period_adv_start.status = btc_btm_status_to_esp_status(params->per_adv_start.status); + param.period_adv_start.instance = params->per_adv_start.instance; break; } case BTA_DM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT: { msg.act = ESP_GAP_BLE_PERIODIC_ADV_STOP_COMPLETE_EVT; param.period_adv_stop.status = btc_btm_status_to_esp_status(params->per_adv_stop.status); + param.period_adv_stop.instance = params->per_adv_stop.instance; break; } case BTA_DM_BLE_5_GAP_PERIODIC_ADV_CREATE_SYNC_COMPLETE_EVT: { @@ -1040,7 +1112,7 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, break; case BTA_DM_BLE_5_GAP_EXT_ADV_REPORT_EVT: msg.act = ESP_GAP_BLE_EXT_ADV_REPORT_EVT; - memcpy(¶m.ext_adv_report.params, ¶ms->ext_adv_report, sizeof(esp_ble_gap_ext_adv_reprot_t)); + memcpy(¶m.ext_adv_report.params, ¶ms->ext_adv_report, sizeof(esp_ble_gap_ext_adv_report_t)); if (params->ext_adv_report.adv_data) { memcpy(param.ext_adv_report.params.adv_data, params->ext_adv_report.adv_data, params->ext_adv_report.adv_data_len); @@ -1098,6 +1170,40 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, param.periodic_adv_sync_estab.adv_clk_accuracy = params->sync_estab.adv_clk_accuracy; break; } +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + case BTA_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT: + msg.act = ESP_GAP_BLE_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT; + param.period_adv_recv_enable.status = btc_btm_status_to_esp_status(params->per_adv_recv_enable.status); + break; + case BTA_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT: + msg.act = ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT; + param.period_adv_sync_trans.status = btc_btm_status_to_esp_status(params->per_adv_sync_trans.status); + memcpy(param.period_adv_sync_trans.bda, params->per_adv_sync_trans.addr, sizeof(BD_ADDR)); + break; + case BTA_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT: + msg.act = ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT; + param.period_adv_set_info_trans.status = btc_btm_status_to_esp_status(params->per_adv_set_info_trans.status); + memcpy(param.period_adv_set_info_trans.bda, params->per_adv_set_info_trans.addr, sizeof(BD_ADDR)); + break; + case BTA_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT: + msg.act = ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT; + param.set_past_params.status = btc_btm_status_to_esp_status(params->set_past_params.status); + memcpy(param.set_past_params.bda, params->set_past_params.addr, sizeof(BD_ADDR)); + break; + case BTA_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT: + msg.act = ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT; + param.past_received.status = btc_btm_status_to_esp_status(params->past_recv.status); + memcpy(param.past_received.bda, params->past_recv.addr, sizeof(BD_ADDR)); + param.past_received.service_data = params->past_recv.service_data; + param.past_received.sync_handle = params->past_recv.sync_handle; + param.past_received.adv_sid = params->past_recv.adv_sid; + param.past_received.adv_addr_type = params->past_recv.adv_addr_type; + memcpy(param.past_received.adv_addr, params->past_recv.adv_addr, sizeof(BD_ADDR)); + param.past_received.adv_phy = params->past_recv.adv_phy; + param.past_received.adv_interval = params->past_recv.adv_interval; + param.past_received.adv_clk_accuracy = params->past_recv.adv_clk_accuracy; + break; +#endif default: break; } @@ -1110,6 +1216,146 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, } } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +void btc_dtm_tx_start_callback(void *p1) +{ + UINT8 status; + UINT8 *p; + p = (UINT8*) p1; + if (p1) { + STREAM_TO_UINT8(status, p); + BTC_TRACE_DEBUG("DTM TX start, status 0x%x\n", 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_DTM_TEST_UPDATE_EVT; + param.dtm_state_update.status = status; + param.dtm_state_update.update_evt = DTM_TX_START_EVT; + param.dtm_state_update.num_of_pkt = 0; + + 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_dtm_rx_start_callback(void *p1) +{ + + UINT8 status; + UINT8 *p; + p = (UINT8*) p1; + if (p1) { + STREAM_TO_UINT8(status, p); + BTC_TRACE_DEBUG("DTM RX start, status 0x%x\n", 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_DTM_TEST_UPDATE_EVT; + param.dtm_state_update.status = status; + param.dtm_state_update.update_evt = DTM_RX_START_EVT; + param.dtm_state_update.num_of_pkt = 0; + + 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_dtm_stop_callback(void *p1) +{ + UINT8 status; + UINT16 num_pkt; + UINT8 *p; + p = (UINT8*) p1; + if (p1) { + STREAM_TO_UINT8(status, p); + STREAM_TO_UINT16(num_pkt, p); + BTC_TRACE_DEBUG("DTM stop, status 0x%x num_pkt %d\n", status, num_pkt); + 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_DTM_TEST_UPDATE_EVT; + param.dtm_state_update.status = status; + param.dtm_state_update.update_evt = DTM_TEST_STOP_EVT; + param.dtm_state_update.num_of_pkt = num_pkt; + + 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__); + } + } +} + +static void btc_ble_vendor_hci_cmd_complete_callback(tBTA_VSC_CMPL *p_param) +{ + bool param_invalid = false; + if ((!p_param) || (!p_param->param_len) || (!p_param->p_param_buf)) { + BTC_TRACE_ERROR("%s param error\n", __func__); + param_invalid = true; + } + + esp_ble_gap_cb_param_t param = {0}; + 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_VENDOR_CMD_COMPLETE_EVT; + if (!param_invalid) { + param.vendor_cmd_cmpl.opcode = p_param->opcode; + param.vendor_cmd_cmpl.param_len = p_param->param_len; + param.vendor_cmd_cmpl.p_param_buf = p_param->p_param_buf; + } else { + if (p_param) { + param.vendor_cmd_cmpl.opcode = p_param->opcode; + } else { + param.vendor_cmd_cmpl.opcode = 0; + } + param.vendor_cmd_cmpl.param_len = 0; + param.vendor_cmd_cmpl.p_param_buf = NULL; + } + + ret = btc_transfer_context(&msg, ¶m, sizeof(esp_ble_gap_cb_param_t), btc_gap_ble_cb_deep_copy, btc_gap_ble_cb_deep_free); + + if (ret != BT_STATUS_SUCCESS) { + BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); + } +} + +static void btc_ble_set_privacy_mode_callback(UINT8 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_SET_PRIVACY_MODE_COMPLETE_EVT; + + param.set_privacy_mode_cmpl.status = btc_btm_status_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_get_whitelist_size(uint16_t *length) { BTM_BleGetWhiteListSize(length); @@ -1137,13 +1383,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) @@ -1219,6 +1469,19 @@ static void btc_ble_set_rand_addr (BD_ADDR rand_addr, tBTA_SET_RAND_ADDR_CBACK * } } +static void btc_ble_set_rpa_timeout(uint16_t rpa_timeout,tBTA_SET_RPA_TIMEOUT_CMPL_CBACK *set_rpa_timeout_cback) +{ + BTA_DmBleSetRpaTimeout(rpa_timeout,set_rpa_timeout_cback); +} + +static void btc_ble_add_device_to_resolving_list(BD_ADDR addr, + uint8_t addr_type, + uint8_t irk[], + tBTA_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *add_dev_to_resolving_list_callback) +{ + BTA_DmBleAddDevToResolvingList(addr, addr_type, irk, add_dev_to_resolving_list_callback); +} + static void btc_ble_clear_rand_addr (void) { BTA_DmClearRandAddress(); @@ -1239,6 +1502,45 @@ static void btc_gap_ble_set_channels(esp_gap_ble_channels channels) BTA_DmBleSetChannels(channels, btc_gap_ble_set_channels_cmpl_callback); } +#if (BLE_42_FEATURE_SUPPORT == TRUE) +static void btc_ble_dtm_tx_start(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + BTA_DmBleDtmTxStart(tx_channel, len_of_data, pkt_payload, p_dtm_cmpl_cback); +} + +static void btc_ble_dtm_rx_start(uint8_t rx_channel, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + + BTA_DmBleDtmRxStart(rx_channel, p_dtm_cmpl_cback); +} +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +static void btc_ble_dtm_enhance_tx_start(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, uint8_t phy, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + BTA_DmBleDtmEnhTxStart(tx_channel, len_of_data, pkt_payload, phy, p_dtm_cmpl_cback); +} + +static void btc_ble_dtm_enhance_rx_start(uint8_t rx_channel, uint8_t phy, uint8_t modulation_index, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + + BTA_DmBleDtmEnhRxStart(rx_channel, phy, modulation_index, p_dtm_cmpl_cback); +} +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +static void btc_ble_dtm_stop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + + BTA_DmBleDtmStop(p_dtm_cmpl_cback); +} + +static void btc_ble_set_privacy_mode(uint8_t addr_type, + BD_ADDR addr, + uint8_t privacy_mode, + tBTA_SET_PRIVACY_MODE_CMPL_CBACK *p_cback) +{ + BTA_DmBleSetPrivacyMode(addr_type, addr, privacy_mode, p_cback); +} void btc_gap_ble_cb_handler(btc_msg_t *msg) { @@ -1247,7 +1549,7 @@ void btc_gap_ble_cb_handler(btc_msg_t *msg) if (msg->act < ESP_GAP_BLE_EVT_MAX) { btc_gap_ble_cb_to_app(msg->act, param); } else { - BTC_TRACE_ERROR("%s, unknow msg->act = %d", __func__, msg->act); + BTC_TRACE_ERROR("%s, unknown msg->act = %d", __func__, msg->act); } btc_gap_ble_cb_deep_free(msg); @@ -1416,6 +1718,19 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) break; } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + case BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT: { + btc_ble_gap_args_t *src = (btc_ble_gap_args_t *)p_src; + btc_ble_gap_args_t *dst = (btc_ble_gap_args_t *)p_dest; + if (src->vendor_cmd_send.param_len) { + dst->vendor_cmd_send.p_param_buf = osi_malloc(src->vendor_cmd_send.param_len); + if (dst->vendor_cmd_send.p_param_buf) { + memcpy(dst->vendor_cmd_send.p_param_buf, src->vendor_cmd_send.p_param_buf, src->vendor_cmd_send.param_len); + } else { + BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + } + } + break; + } default: BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act); break; @@ -1424,7 +1739,22 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) { + esp_ble_gap_cb_param_t *src = (esp_ble_gap_cb_param_t *)p_src; + esp_ble_gap_cb_param_t *dst = (esp_ble_gap_cb_param_t *) p_dest; + switch (msg->act) { + case ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT: { + if (src->vendor_cmd_cmpl.param_len) { + dst->vendor_cmd_cmpl.p_param_buf = osi_malloc(src->vendor_cmd_cmpl.param_len); + if (dst->vendor_cmd_cmpl.p_param_buf) { + memcpy(dst->vendor_cmd_cmpl.p_param_buf, src->vendor_cmd_cmpl.p_param_buf, + src->vendor_cmd_cmpl.param_len); + } else { + BTC_TRACE_ERROR("%s, malloc failed\n", __func__); + } + } + break; + } default: BTC_TRACE_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act); break; @@ -1522,6 +1852,13 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg) break; } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + case BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT: { + uint8_t *p_param_buf = ((btc_ble_gap_args_t *)msg->arg)->vendor_cmd_send.p_param_buf; + if (p_param_buf) { + osi_free(p_param_buf); + } + break; + } default: BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act); break; @@ -1539,6 +1876,13 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg) } break; } + case ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT: { + uint8_t *value = ((esp_ble_gap_cb_param_t *)msg->arg)->vendor_cmd_cmpl.p_param_buf; + if (value) { + osi_free(value); + } + break; + } default: BTC_TRACE_DEBUG("Unhandled deep free %d", msg->act); break; @@ -1579,6 +1923,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, @@ -1596,6 +1943,17 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) btc_ble_set_rand_addr(bd_addr, btc_set_rand_addr_callback); break; } + case BTC_GAP_BLE_ACT_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT: { + btc_ble_set_rpa_timeout(arg->set_rpa_timeout.rpa_timeout,btc_set_rpa_timeout_callback); + break; + } + case BTC_GAP_BLE_ACT_ADD_DEVICE_TO_RESOLVING_LIST: { + btc_ble_add_device_to_resolving_list(arg->add_dev_to_resolving_list.addr, + arg->add_dev_to_resolving_list.addr_type, + arg->add_dev_to_resolving_list.irk, + btc_add_dev_to_resolving_list_callback); + break; + } case BTC_GAP_BLE_ACT_CLEAR_RAND_ADDRESS: { btc_ble_clear_rand_addr(); break; @@ -1873,11 +2231,12 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) BTC_TRACE_DEBUG("BTC_GAP_BLE_CFG_PERIODIC_ADV_DATA_RAW"); BTA_DmBleGapPeriodicAdvCfgDataRaw(arg_5->periodic_adv_cfg_data.instance, arg_5->periodic_adv_cfg_data.len, - (const UINT8 *)arg_5->periodic_adv_cfg_data.data); + (const UINT8 *)arg_5->periodic_adv_cfg_data.data, + arg_5->periodic_adv_cfg_data.only_update_did); break; case BTC_GAP_BLE_PERIODIC_ADV_START: BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_START"); - BTA_DmBleGapPeriodicAdvEnable(TRUE, arg_5->periodic_adv_start.instance); + BTA_DmBleGapPeriodicAdvEnable(((arg_5->periodic_adv_start.include_adi)<<1)|0x01, arg_5->periodic_adv_start.instance); break; case BTC_GAP_BLE_PERIODIC_ADV_STOP: BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_STOP"); @@ -1890,6 +2249,10 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) params.addr_type = arg_5->periodic_adv_create_sync.params.addr_type; params.skip = arg_5->periodic_adv_create_sync.params.skip; params.sync_timeout = arg_5->periodic_adv_create_sync.params.sync_timeout; + #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH) + params.reports_disabled = arg_5->periodic_adv_create_sync.params.reports_disabled; + params.filter_duplicates = arg_5->periodic_adv_create_sync.params.filter_duplicates; + #endif memcpy(params.addr, arg_5->periodic_adv_create_sync.params.addr, sizeof(BD_ADDR)); BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_CREATE_SYNC"); @@ -1959,6 +2322,59 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) (const tBTA_DM_BLE_CONN_PARAMS *)&arg_5->set_ext_conn_params.phy_coded_conn_params); break; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + case BTC_GAP_BLE_PERIODIC_ADV_RECV_ENABLE: + BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_RECV_ENABLE"); + BTA_DmBleGapPeriodicAdvRecvEnable(arg_5->periodic_adv_recv_en.sync_handle, + arg_5->periodic_adv_recv_en.enable); + break; + case BTC_GAP_BLE_PERIODIC_ADV_SYNC_TRANS: + BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_SYNC_TRANS"); + BTA_DmBleGapPeriodicAdvSyncTrans(arg_5->periodic_adv_sync_trans.addr, + arg_5->periodic_adv_sync_trans.service_data, + arg_5->periodic_adv_sync_trans.sync_handle); + break; + case BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS: + BTC_TRACE_DEBUG("BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS"); + BTA_DmBleGapPeriodicAdvSetInfoTrans(arg_5->periodic_adv_set_info_trans.addr, + arg_5->periodic_adv_set_info_trans.service_data, + arg_5->periodic_adv_set_info_trans.adv_handle); + break; + case BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS: + BTC_TRACE_DEBUG("BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS"); + BTA_DmBleGapSetPeriodicAdvSyncTransParams(arg_5->set_periodic_adv_sync_trans_params.addr, + (tBTA_DM_BLE_PAST_PARAMS *)&arg_5->set_periodic_adv_sync_trans_params.params); + break; +#endif +#if (BLE_42_FEATURE_SUPPORT == TRUE) + case BTC_GAP_BLE_DTM_TX_START: + btc_ble_dtm_tx_start(arg->dtm_tx_start.tx_channel, arg->dtm_tx_start.len_of_data, arg->dtm_tx_start.pkt_payload, btc_dtm_tx_start_callback); + break; + case BTC_GAP_BLE_DTM_RX_START: + btc_ble_dtm_rx_start(arg->dtm_rx_start.rx_channel, btc_dtm_rx_start_callback); + break; +#endif // if (BLE_42_FEATURE_SUPPORT == TRUE) + case BTC_GAP_BLE_DTM_STOP: + btc_ble_dtm_stop(btc_dtm_stop_callback); + break; +#if (BLE_50_FEATURE_SUPPORT == TRUE) + case BTC_GAP_BLE_DTM_ENH_TX_START: + btc_ble_dtm_enhance_tx_start(arg_5->dtm_enh_tx_start.tx_channel, arg_5->dtm_enh_tx_start.len_of_data, arg_5->dtm_enh_tx_start.pkt_payload, arg_5->dtm_enh_tx_start.phy, btc_dtm_tx_start_callback); + break; + case BTC_GAP_BLE_DTM_ENH_RX_START: + btc_ble_dtm_enhance_rx_start(arg_5->dtm_enh_rx_start.rx_channel, arg_5->dtm_enh_rx_start.phy, arg_5->dtm_enh_rx_start.modulation_index, btc_dtm_rx_start_callback); + break; +#endif // if (BLE_50_FEATURE_SUPPORT == TRUE) + case BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT: + BTA_DmsendVendorHciCmd(arg->vendor_cmd_send.opcode, + arg->vendor_cmd_send.param_len, + arg->vendor_cmd_send.p_param_buf, + btc_ble_vendor_hci_cmd_complete_callback); + break; + case BTC_GAP_BLE_SET_PRIVACY_MODE: + btc_ble_set_privacy_mode(arg->set_privacy_mode.addr_type, arg->set_privacy_mode.addr, + arg->set_privacy_mode.privacy_mode, btc_ble_set_privacy_mode_callback); + break; default: break; } @@ -1969,6 +2385,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) //register connection parameter update callback void btc_gap_callback_init(void) { + BTM_BleRegiseterPktLengthChangeCallback(btc_set_pkt_length_callback); BTM_BleRegiseterConnParamCallback(btc_update_conn_param_callback); #if (BLE_50_FEATURE_SUPPORT == TRUE) BTM_BleGapRegisterCallback(btc_ble_5_gap_callback); diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c index aeb1e8c217..f43e96390c 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c @@ -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 */ @@ -689,6 +689,7 @@ static void btc_gap_bt_config_eir(btc_gap_bt_args_t *arg) esp_bt_eir_data_t *eir_data = &arg->config_eir.eir_data; eir_config.bta_dm_eir_fec_required = eir_data->fec_required; + eir_config.bta_dm_eir_included_name = eir_data->include_name; eir_config.bta_dm_eir_included_tx_power = eir_data->include_txpower; eir_config.bta_dm_eir_included_uuid = eir_data->include_uuid; eir_config.bta_dm_eir_flags = eir_data->flag; @@ -725,6 +726,33 @@ static void btc_gap_bt_set_afh_channels(btc_gap_bt_args_t *arg) BTA_DmSetAfhChannels(arg->set_afh_channels.channels, btc_gap_bt_set_afh_channels_cmpl_callback); } +static void btc_gap_bt_set_acl_pkt_types_cmpl_callback(void *p_data) +{ + tBTA_SET_ACL_PKT_TYPES_RESULTS *result = (tBTA_SET_ACL_PKT_TYPES_RESULTS *)p_data; + esp_bt_gap_cb_param_t param; + bt_status_t ret; + btc_msg_t msg; + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BT; + msg.act = BTC_GAP_BT_SET_ACL_PKT_TYPES_EVT; + + param.set_acl_pkt_types.status = btc_btm_status_to_esp_status(result->status); + memcpy(param.set_acl_pkt_types.bda, result->rem_bda, sizeof(esp_bd_addr_t)); + param.set_acl_pkt_types.pkt_types = result->pkt_types; + + ret = btc_transfer_context(&msg, ¶m, sizeof(esp_bt_gap_cb_param_t), NULL, NULL); + if (ret != BT_STATUS_SUCCESS) { + BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); + } +} + +static void btc_gap_set_acl_pkt_types(btc_gap_bt_args_t *arg) +{ + BTA_DmSetAclPktTypes(arg->set_acl_pkt_types.bda.address, + arg->set_acl_pkt_types.pkt_types, + btc_gap_bt_set_acl_pkt_types_cmpl_callback); +} + static void btc_gap_bt_read_remote_name_cmpl_callback(void *p_data) { tBTA_REMOTE_DEV_NAME *result = (tBTA_REMOTE_DEV_NAME *)p_data; @@ -797,6 +825,7 @@ void btc_gap_bt_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) case BTC_GAP_BT_ACT_SET_AFH_CHANNELS: case BTC_GAP_BT_ACT_READ_REMOTE_NAME: case BTC_GAP_BT_ACT_SET_QOS: + case BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES: break; #if (BT_SSP_INCLUDED == TRUE) case BTC_GAP_BT_ACT_PASSKEY_REPLY: @@ -863,6 +892,7 @@ void btc_gap_bt_arg_deep_free(btc_msg_t *msg) case BTC_GAP_BT_ACT_SET_AFH_CHANNELS: case BTC_GAP_BT_ACT_READ_REMOTE_NAME: case BTC_GAP_BT_ACT_SET_QOS: + case BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES: break; #if (BT_SSP_INCLUDED == TRUE) case BTC_GAP_BT_ACT_PASSKEY_REPLY: @@ -965,6 +995,10 @@ void btc_gap_bt_call_handler(btc_msg_t *msg) btc_gap_bt_set_qos(arg); break; } + case BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES: { + btc_gap_set_acl_pkt_types(arg); + break; + } default: break; } @@ -1008,6 +1042,7 @@ void btc_gap_bt_cb_deep_free(btc_msg_t *msg) case BTC_GAP_BT_REMOVE_BOND_DEV_COMPLETE_EVT: case BTC_GAP_BT_QOS_EVT: #if (BT_SSP_INCLUDED == TRUE) + case BTC_GAP_BT_SET_ACL_PKT_TYPES_EVT: case BTC_GAP_BT_CFM_REQ_EVT: case BTC_GAP_BT_KEY_NOTIF_EVT: case BTC_GAP_BT_KEY_REQ_EVT: @@ -1092,6 +1127,10 @@ void btc_gap_bt_cb_handler(btc_msg_t *msg) btc_gap_bt_cb_to_app(ESP_BT_GAP_QOS_CMPL_EVT, (esp_bt_gap_cb_param_t *)msg->arg); break; } + case BTC_GAP_BT_SET_ACL_PKT_TYPES_EVT: { + btc_gap_bt_cb_to_app(ESP_BT_GAP_ACL_PKT_TYPE_CHANGED_EVT, (esp_bt_gap_cb_param_t *)msg->arg); + break; + } default: BTC_TRACE_ERROR("%s: Unhandled event (%d)!\n", __FUNCTION__, msg->act); break; diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c index a7b5346bd7..e69eed48f3 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 @@ -15,6 +15,8 @@ #include "common/bt_trace.h" #include "osi/allocator.h" #include "esp_gattc_api.h" +#include "btc/btc_storage.h" +#include "common/bt_defs.h" #if (GATTC_INCLUDED == TRUE) static inline void btc_gattc_cb_to_app(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) @@ -122,7 +124,8 @@ static void btc_gattc_copy_req_data(btc_msg_t *msg, void *p_dest, void *p_src) switch (msg->act) { case BTA_GATTC_READ_DESCR_EVT: case BTA_GATTC_READ_CHAR_EVT: - case BTA_GATTC_READ_MULTIPLE_EVT: { + case BTA_GATTC_READ_MULTIPLE_EVT: + case BTA_GATTC_READ_MULTI_VAR_EVT: { if (p_src_data->read.p_value && p_src_data->read.p_value->p_value) { p_dest_data->read.p_value = (tBTA_GATT_UNFMT *)osi_malloc(sizeof(tBTA_GATT_UNFMT) + p_src_data->read.p_value->len); p_dest_data->read.p_value->p_value = (uint8_t *)(p_dest_data->read.p_value + 1); @@ -158,7 +161,8 @@ static void btc_gattc_free_req_data(btc_msg_t *msg) switch (msg->act) { case BTA_GATTC_READ_DESCR_EVT: case BTA_GATTC_READ_CHAR_EVT: - case BTA_GATTC_READ_MULTIPLE_EVT: { + case BTA_GATTC_READ_MULTIPLE_EVT: + case BTA_GATTC_READ_MULTI_VAR_EVT: { if (arg->read.p_value) { osi_free(arg->read.p_value); } @@ -604,6 +608,14 @@ static void btc_gattc_read_multiple_char(btc_ble_gattc_args_t *arg) BTA_GATTC_ReadMultiple(arg->read_multiple.conn_id, &bta_multi, arg->read_multiple.auth_req); } +static void btc_gattc_read_multiple_variable_char(btc_ble_gattc_args_t *arg) +{ + tBTA_GATTC_MULTI bta_multi; + bta_multi.num_attr = arg->read_multiple.num_attr; + memcpy(bta_multi.handles, arg->read_multiple.handles, BTA_GATTC_MULTI_MAX); + BTA_GATTC_ReadMultipleVariable(arg->read_multiple.conn_id, &bta_multi, arg->read_multiple.auth_req); +} + static void btc_gattc_read_char_descr(btc_ble_gattc_args_t *arg) { BTA_GATTC_ReadCharDescr(arg->read_descr.conn_id, arg->read_descr.handle, arg->read_descr.auth_req); @@ -727,6 +739,9 @@ void btc_gattc_call_handler(btc_msg_t *msg) case BTC_GATTC_ACT_READ_MULTIPLE_CHAR: btc_gattc_read_multiple_char(arg); break; + case BTC_GATTC_ACT_READ_MULTIPLE_VARIABLE_CHAR: + btc_gattc_read_multiple_variable_char(arg); + break; case BTC_GATTC_ACT_READ_CHAR_DESCR: btc_gattc_read_char_descr(arg); break; @@ -864,6 +879,11 @@ void btc_gattc_cb_handler(btc_msg_t *msg) btc_gattc_cb_to_app(ESP_GATTC_READ_MULTIPLE_EVT, gattc_if, ¶m); break; } + case BTA_GATTC_READ_MULTI_VAR_EVT: { + set_read_value(&gattc_if, ¶m, &arg->read); + btc_gattc_cb_to_app(ESP_GATTC_READ_MULTI_VAR_EVT, gattc_if, ¶m); + break; + } case BTA_GATTC_WRITE_DESCR_EVT: { tBTA_GATTC_WRITE *write = &arg->write; @@ -906,7 +926,17 @@ void btc_gattc_cb_handler(btc_msg_t *msg) } case BTA_GATTC_CONNECT_EVT: { tBTA_GATTC_CONNECT *connect = &arg->connect; - +#if (SMP_INCLUDED == TRUE) + bt_bdaddr_t bt_addr; + + memcpy(bt_addr.address, connect->remote_bda, sizeof(bt_addr.address)); + if (btc_storage_update_active_device(&bt_addr)) { + BTC_TRACE_EVENT("Device: %02x:%02x:%02x:%02x:%02x:%02x, is not in bond list", + bt_addr.address[0], bt_addr.address[1], + bt_addr.address[2], bt_addr.address[3], + bt_addr.address[4], bt_addr.address[5]); + } +#endif ///SMP_INCLUDED == TRUE gattc_if = connect->client_if; param.connect.conn_id = BTC_GATT_GET_CONN_ID(connect->conn_id); param.connect.link_role = connect->link_role; diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c index 5badf5f45b..df9a4ceb19 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,8 @@ #include "osi/allocator.h" #include "btc/btc_main.h" #include "esp_gatts_api.h" +#include "btc/btc_storage.h" +#include "common/bt_defs.h" #if (GATTS_INCLUDED == TRUE) @@ -498,6 +500,11 @@ esp_gatt_status_t btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *lengt return BTA_GetAttributeValue(attr_handle, length, value); } +esp_gatt_status_t btc_gatts_show_local_database(void) +{ + BTA_GATTS_ShowLocalDatabase(); + return ESP_GATT_OK; +} static void btc_gatts_cb_param_copy_req(btc_msg_t *msg, void *p_dest, void *p_src) { @@ -741,6 +748,9 @@ void btc_gatts_call_handler(btc_msg_t *msg) BTA_GATTS_SendServiceChangeIndication(arg->send_service_change.gatts_if, remote_bda); break; } + case BTC_GATTS_ACT_SHOW_LOCAL_DATABASE: + BTA_GATTS_ShowLocalDatabase(); + break; default: break; } @@ -890,7 +900,17 @@ void btc_gatts_cb_handler(btc_msg_t *msg) btc_gatts_cb_to_app(ESP_GATTS_STOP_EVT, gatts_if, ¶m); break; - case BTA_GATTS_CONNECT_EVT: + case BTA_GATTS_CONNECT_EVT: { +#if (SMP_INCLUDED == TRUE) + bt_bdaddr_t bt_addr; + memcpy(bt_addr.address, p_data->conn.remote_bda, sizeof(bt_addr.address)); + if (btc_storage_update_active_device(&bt_addr)) { + BTC_TRACE_EVENT("Device: %02x:%02x:%02x:%02x:%02x:%02x, is not in bond list", + bt_addr.address[0], bt_addr.address[1], + bt_addr.address[2], bt_addr.address[3], + bt_addr.address[4], bt_addr.address[5]); + } +#endif ///SMP_INCLUDED == TRUE gatts_if = p_data->conn.server_if; param.connect.conn_id = BTC_GATT_GET_CONN_ID(p_data->conn.conn_id); param.connect.link_role = p_data->conn.link_role; @@ -902,6 +922,7 @@ void btc_gatts_cb_handler(btc_msg_t *msg) param.connect.conn_handle = p_data->conn.conn_handle; btc_gatts_cb_to_app(ESP_GATTS_CONNECT_EVT, gatts_if, ¶m); break; + } case BTA_GATTS_DISCONNECT_EVT: gatts_if = p_data->conn.server_if; param.disconnect.conn_id = BTC_GATT_GET_CONN_ID(p_data->conn.conn_id); diff --git a/components/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c b/components/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c index 84d006647a..6000f8324c 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c +++ b/components/bt/host/bluedroid/btc/profile/std/hf_ag/bta_ag_co.c @@ -82,7 +82,7 @@ static bta_ag_co_cb_t *bta_ag_co_cb_ptr; #define bta_ag_co_cb (*bta_ag_co_cb_ptr) #endif /* HFP_DYNAMIC_MEMORY == FALSE */ -static UINT8 hf_air_mode = BTM_SCO_AIR_MODE_TRANSPNT; +static UINT8 hf_air_mode = BTM_SCO_AIR_MODE_UNKNOWN; static UINT8 hf_inout_pkt_size = 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 bd27e0565d..a4c5faeb01 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -66,31 +66,41 @@ static UINT16 btc_max_hf_clients = BTC_HF_NUM_CB; #if HFP_DYNAMIC_MEMORY == FALSE static hf_local_param_t hf_local_param[BTC_HF_NUM_CB]; #else -static hf_local_param_t *hf_local_param; +hf_local_param_t *hf_local_param_ptr = NULL; #endif #if (BTM_WBS_INCLUDED == TRUE) #ifndef BTC_HF_FEATURES -#define BTC_HF_FEATURES ( BTA_AG_FEAT_ECNR | \ - BTA_AG_FEAT_REJECT | \ - BTA_AG_FEAT_ECS | \ - BTA_AG_FEAT_EXTERR | \ - BTA_AG_FEAT_VREC | \ - BTA_AG_FEAT_INBAND | \ - BTA_AG_FEAT_CODEC | \ - BTA_AG_FEAT_ESCO_S4| \ - BTA_AG_FEAT_UNAT) +#define BTC_HF_FEATURES ( BTA_AG_FEAT_ECNR | \ + BTA_AG_FEAT_REJECT | \ + BTA_AG_FEAT_ECS | \ + BTA_AG_FEAT_EXTERR | \ + BTA_AG_FEAT_VREC | \ + BTA_AG_FEAT_INBAND | \ + BTA_AG_FEAT_CODEC | \ + BTA_AG_FEAT_ESCO_S4 | \ + BTA_AG_FEAT_UNAT ) #endif #else #ifndef BTC_HF_FEATURES -#define BTC_HF_FEATURES ( BTA_AG_FEAT_ECNR | \ - BTA_AG_FEAT_REJECT | \ - BTA_AG_FEAT_ECS | \ - BTA_AG_FEAT_EXTERR | \ - BTA_AG_FEAT_VREC | \ - BTA_AG_FEAT_INBAND | \ - BTA_AG_FEAT_ESCO_S4| \ - BTA_AG_FEAT_UNAT) +#if BT_HF_AG_BQB_INCLUDED +#define BTC_HF_FEATURES ( BTA_AG_FEAT_REJECT | \ + BTA_AG_FEAT_ECS | \ + BTA_AG_FEAT_EXTERR | \ + BTA_AG_FEAT_VREC | \ + BTA_AG_FEAT_INBAND | \ + BTA_AG_FEAT_ESCO_S4 | \ + BTA_AG_FEAT_UNAT ) +#else +#define BTC_HF_FEATURES ( BTA_AG_FEAT_ECNR | \ + BTA_AG_FEAT_REJECT | \ + BTA_AG_FEAT_ECS | \ + BTA_AG_FEAT_EXTERR | \ + BTA_AG_FEAT_VREC | \ + BTA_AG_FEAT_INBAND | \ + BTA_AG_FEAT_ESCO_S4 | \ + BTA_AG_FEAT_UNAT ) +#endif /* BT_HF_AG_BQB_INCLUDED */ #endif #endif @@ -134,12 +144,12 @@ do { hf_local_param[idx].btc_hf_cb.num_active = 0; \ hf_local_param[idx].btc_hf_cb.num_held = 0; -#define CHECK_HF_IDX(idx) \ -do { \ - if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) { \ - BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx); \ - return; \ - } \ +#define CHECK_HF_IDX(idx) \ +do { \ + if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) { \ + BTC_TRACE_ERROR("%s:%d Invalid index %d", __FUNCTION__, __LINE__, idx); \ + return; \ + } \ } while (0) /************************************************************************************ @@ -214,37 +224,6 @@ static void send_indicator_update(UINT16 indicator, UINT16 value) BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_IND_RES, &ag_res); } -static void btc_hf_cind_evt(tBTA_AG_IND *ind) -{ - esp_hf_cb_param_t param; - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); - - switch (ind->type) { - case BTA_AG_IND_CALL: - param.cind.call_status = ind->value; - break; - case BTA_AG_IND_CALLSETUP: - param.cind.call_setup_status = ind->value; - break; - case BTA_AG_IND_SERVICE: - param.cind.svc = ind->value; - break; - case BTA_AG_IND_SIGNAL: - param.cind.signal_strength = ind->value; - break; - case BTA_AG_IND_ROAM: - param.cind.roam = ind->value; - break; - case BTA_AG_IND_BATTCHG: - param.cind.battery_level = ind->value; - break; - case BTA_AG_IND_CALLHELD: - param.cind.call_held_status = ind->value; - break; - } - btc_hf_cb_to_app(ESP_HF_CIND_RESPONSE_EVT, ¶m); -} - static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *param) { int param_len = 0; @@ -336,9 +315,20 @@ bt_status_t btc_hf_init(void) int idx = 0; BTC_TRACE_DEBUG("%s - max_hf_clients=%d", __func__, btc_max_hf_clients); + +#if HFP_DYNAMIC_MEMORY == TRUE + if (hf_local_param == NULL) { + if ((hf_local_param = (hf_local_param_t *)osi_malloc(BTC_HF_NUM_CB * sizeof(hf_local_param_t))) == NULL) { + BTC_TRACE_ERROR("%s malloc failed!", __func__); + return BT_STATUS_NOMEM; + } + } + memset((void *)hf_local_param, 0, BTC_HF_NUM_CB * sizeof(hf_local_param_t)); +#endif + /* Invoke the enable service API to the core to set the appropriate service_id * Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled (phone) - * othwerwise only HSP is enabled (tablet)*/ + * otherwise only HSP is enabled (tablet)*/ #if (defined(BTC_HF_SERVICES) && (BTC_HF_SERVICES & BTA_HFP_SERVICE_MASK)) btc_dm_enable_service(BTA_HFP_SERVICE_ID); #else @@ -362,13 +352,16 @@ void btc_hf_deinit(void) { BTC_TRACE_EVENT("%s", __FUNCTION__); btc_dm_disable_service(BTA_HFP_SERVICE_ID); + hf_local_param[0].btc_hf_cb.initialized = false; +} + +static void btc_hf_cb_release(void) +{ #if HFP_DYNAMIC_MEMORY == TRUE if (hf_local_param) { osi_free(hf_local_param); hf_local_param = NULL; } -#else - hf_local_param[0].btc_hf_cb.initialized = false; #endif } @@ -441,6 +434,21 @@ bt_status_t btc_hf_disconnect_audio(bt_bdaddr_t *bd_addr) return BT_STATUS_FAIL; } +static bt_status_t btc_hf_pkt_stat_nums_get(UINT16 sync_conn_handle) +{ + bt_status_t status = BT_STATUS_FAIL; +#if (BTM_SCO_HCI_INCLUDED == TRUE) + int idx = btc_hf_latest_connected_idx(); + CHECK_HF_SLC_CONNECTED(idx); + + if (idx != BTC_HF_INVALID_IDX) { + BTA_AgPktStatsNumsGet(hf_local_param[idx].btc_hf_cb.handle, sync_conn_handle); + status = BT_STATUS_SUCCESS; + } +#endif /*#if (BTM_SCO_HCI_INCLUDED == TRUE) */ + return status; +} + /************************************************************************************ ** AT cmd Handle ************************************************************************************/ @@ -541,7 +549,20 @@ static bt_status_t btc_hf_indchange_notification(bt_bdaddr_t *bd_addr, send_indicator_update(BTA_AG_IND_SIGNAL, signal); return BT_STATUS_SUCCESS; } - return BT_STATUS_SUCCESS; + return BT_STATUS_FAIL; +} + +// +CIEV<...> for device status update, send other indicators, e.g. roaming, battery, call held and bearer +bt_status_t btc_hf_ciev_report(bt_bdaddr_t *bd_addr, tBTA_AG_IND_TYPE indicator, uint16_t value) +{ + int idx = btc_hf_idx_by_bdaddr(bd_addr); + CHECK_HF_INIT(idx); + + if (is_connected(idx, bd_addr)) { + send_indicator_update(indicator, value); + return BT_STATUS_SUCCESS; + } + return BT_STATUS_FAIL; } //AT+CIND response @@ -623,7 +644,7 @@ static bt_status_t btc_hf_clcc_response(bt_bdaddr_t *bd_addr, int index, esp_hf_ } //AT+CNUM -static bt_status_t btc_hf_cnum_response(bt_bdaddr_t *bd_addr, const char *number, esp_hf_subscriber_service_type_t type) +static bt_status_t btc_hf_cnum_response(bt_bdaddr_t *bd_addr, const char *number, int number_type, esp_hf_subscriber_service_type_t service_type) { int idx = btc_hf_idx_by_bdaddr(bd_addr); CHECK_HF_SLC_CONNECTED(idx); @@ -631,11 +652,11 @@ static bt_status_t btc_hf_cnum_response(bt_bdaddr_t *bd_addr, const char *number if (is_connected(idx, bd_addr)) { tBTA_AG_RES_DATA ag_res; memset(&ag_res, 0, sizeof (ag_res)); - BTC_TRACE_EVENT("cnum_response: number = %s, type = %d", number, type); - if (number) { - sprintf(ag_res.str, ",\"%s\",%d",number, type); + BTC_TRACE_EVENT("cnum_response: number = %s, number type = %d, service type = %d", number, number_type, service_type); + if (service_type) { + sprintf(ag_res.str, ",\"%s\",%d,,%d",number, number_type, service_type); } else { - sprintf(ag_res.str, ",\"\",%d",type); + sprintf(ag_res.str, ",\"%s\",%d,,",number, number_type); } ag_res.ok_flag = BTA_AG_OK_DONE; BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, BTA_AG_CNUM_RES, &ag_res); @@ -732,7 +753,7 @@ static bt_status_t btc_hf_phone_state_update(bt_bdaddr_t *bd_addr,int num_active } /* CIND response should have been updated. */ BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res); - /* Just open SCO conenction. */ + /* Just open SCO connection. */ BTA_AgAudioOpen(ag_res.audio_handle); activeCallUpdated = TRUE; } @@ -1133,6 +1154,12 @@ void btc_hf_call_handler(btc_msg_t *msg) break; } + case BTC_HF_CIEV_REPORT_EVT: + { + btc_hf_ciev_report(&arg->ciev_rep.remote_addr, arg->ciev_rep.ind.type, arg->ciev_rep.ind.value); + break; + } + case BTC_HF_CIND_RESPONSE_EVT: { btc_hf_cind_response(&arg->cind_rep.remote_addr, @@ -1158,7 +1185,7 @@ void btc_hf_call_handler(btc_msg_t *msg) case BTC_HF_CNUM_RESPONSE_EVT: { - btc_hf_cnum_response(&arg->cnum_rep.remote_addr, arg->cnum_rep.number, arg->cnum_rep.type); + btc_hf_cnum_response(&arg->cnum_rep.remote_addr, arg->cnum_rep.number, arg->cnum_rep.number_type, arg->cnum_rep.service_type); break; } @@ -1206,8 +1233,13 @@ void btc_hf_call_handler(btc_msg_t *msg) case BTC_HF_REGISTER_DATA_CALLBACK_EVT: { btc_hf_reg_data_cb(arg->reg_data_cb.recv, arg->reg_data_cb.send); + break; } + case BTC_HF_REQUEST_PKT_STAT_EVT: + { + btc_hf_pkt_stat_nums_get(arg->pkt_sync_hd.sync_conn_handle); break; + } default: BTC_TRACE_WARNING("%s : unhandled event: %d\n", __FUNCTION__, msg->act); @@ -1225,11 +1257,16 @@ void btc_hf_cb_handler(btc_msg_t *msg) BTC_TRACE_DEBUG("%s: event = %s", __FUNCTION__, dump_hf_event(event)); + memset(¶m, 0, sizeof(esp_hf_cb_param_t)); + switch (event) { case BTA_AG_ENABLE_EVT: + break; case BTA_AG_DISABLE_EVT: + { + btc_hf_cb_release(); break; - + } case BTA_AG_REGISTER_EVT: { idx = p_data->hdr.handle - 1; @@ -1261,7 +1298,6 @@ void btc_hf_cb_handler(btc_msg_t *msg) } do { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); memcpy(param.conn_stat.remote_bda, &hf_local_param[idx].btc_hf_cb.connected_bda, sizeof(esp_bd_addr_t)); param.conn_stat.state = hf_local_param[idx].btc_hf_cb.connection_state; param.conn_stat.peer_feat = 0; @@ -1288,7 +1324,6 @@ void btc_hf_cb_handler(btc_msg_t *msg) hf_local_param[idx].btc_hf_cb.connection_state = ESP_HF_CONNECTION_STATE_SLC_CONNECTED; do { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); param.conn_stat.state = hf_local_param[idx].btc_hf_cb.connection_state; param.conn_stat.peer_feat = hf_local_param[idx].btc_hf_cb.peer_feat; param.conn_stat.chld_feat = hf_local_param[idx].btc_hf_cb.chld_feat; @@ -1309,7 +1344,6 @@ void btc_hf_cb_handler(btc_msg_t *msg) BTC_TRACE_DEBUG("%s: BTA_AG_CLOSE_EVT," "hf_local_param[%d].btc_hf_cb.handle = %d", __FUNCTION__, idx, hf_local_param[idx].btc_hf_cb.handle); do { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); param.conn_stat.state = ESP_HF_CONNECTION_STATE_DISCONNECTED; param.conn_stat.peer_feat = 0; param.conn_stat.chld_feat = 0; @@ -1328,9 +1362,9 @@ void btc_hf_cb_handler(btc_msg_t *msg) idx = p_data->hdr.handle - 1; CHECK_HF_IDX(idx); do { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); param.audio_stat.state = ESP_HF_AUDIO_STATE_CONNECTED; memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m); } while(0); break; @@ -1341,9 +1375,9 @@ void btc_hf_cb_handler(btc_msg_t *msg) idx = p_data->hdr.handle - 1; CHECK_HF_IDX(idx); do { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); param.audio_stat.state = ESP_HF_AUDIO_STATE_CONNECTED_MSBC; memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m); } while (0); break; @@ -1353,9 +1387,9 @@ void btc_hf_cb_handler(btc_msg_t *msg) idx = p_data->hdr.handle - 1; CHECK_HF_IDX(idx); do { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); param.audio_stat.state = ESP_HF_AUDIO_STATE_DISCONNECTED; memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda, sizeof(esp_bd_addr_t)); + param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m); } while(0); break; @@ -1366,8 +1400,8 @@ void btc_hf_cb_handler(btc_msg_t *msg) idx = p_data->hdr.handle - 1; CHECK_HF_IDX(idx); do { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); param.vra_rep.value = p_data->val.num; + memcpy(param.vra_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); btc_hf_cb_to_app(ESP_HF_BVRA_RESPONSE_EVT, ¶m); if (p_data->val.num) { btc_hf_connect_audio(&hf_local_param[idx].btc_hf_cb.connected_bda); @@ -1381,8 +1415,10 @@ void btc_hf_cb_handler(btc_msg_t *msg) case BTA_AG_SPK_EVT: case BTA_AG_MIC_EVT: { + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); do { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); + memcpy(param.volume_control.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); param.volume_control.type = (event == BTA_AG_SPK_EVT) ? ESP_HF_VOLUME_CONTROL_TARGET_SPK : ESP_HF_VOLUME_CONTROL_TARGET_MIC; param.volume_control.volume = p_data->val.num; btc_hf_cb_to_app(ESP_HF_VOLUME_CONTROL_EVT, ¶m); @@ -1392,46 +1428,67 @@ void btc_hf_cb_handler(btc_msg_t *msg) case BTA_AG_AT_UNAT_EVT: { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); - param.unat_rep.unat = p_data->val.str; - btc_hf_cb_to_app(ESP_HF_UNAT_RESPONSE_EVT, ¶m); + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); + do { + memcpy(param.unat_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + param.unat_rep.unat = p_data->val.str; + btc_hf_cb_to_app(ESP_HF_UNAT_RESPONSE_EVT, ¶m); + } while (0); break; } case BTA_AG_AT_CBC_EVT: { - btc_hf_cb_to_app(ESP_HF_IND_UPDATE_EVT, NULL); + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); + memcpy(param.ind_upd.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + btc_hf_cb_to_app(ESP_HF_IND_UPDATE_EVT, ¶m); break; } case BTA_AG_AT_CIND_EVT: { - btc_hf_cind_evt(&p_data->ind); + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); + memcpy(param.cind_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + btc_hf_cb_to_app(ESP_HF_CIND_RESPONSE_EVT, ¶m); break; } case BTA_AG_AT_COPS_EVT: { - btc_hf_cb_to_app(ESP_HF_COPS_RESPONSE_EVT, NULL); + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); + memcpy(param.cops_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + btc_hf_cb_to_app(ESP_HF_COPS_RESPONSE_EVT, ¶m); break; } case BTA_AG_AT_CLCC_EVT: { - btc_hf_cb_to_app(ESP_HF_CLCC_RESPONSE_EVT, NULL); + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); + memcpy(param.clcc_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + btc_hf_cb_to_app(ESP_HF_CLCC_RESPONSE_EVT, ¶m); break; } case BTA_AG_AT_CNUM_EVT: { - btc_hf_cb_to_app(ESP_HF_CNUM_RESPONSE_EVT, NULL); + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); + memcpy(param.cnum_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + btc_hf_cb_to_app(ESP_HF_CNUM_RESPONSE_EVT, ¶m); break; } case BTA_AG_AT_VTS_EVT: { + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); do { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); + memcpy(param.vts_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); param.vts_rep.code = p_data->val.str; btc_hf_cb_to_app(ESP_HF_VTS_RESPONSE_EVT, ¶m); } while(0); @@ -1440,8 +1497,10 @@ void btc_hf_cb_handler(btc_msg_t *msg) case BTA_AG_AT_NREC_EVT: { + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); do { - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); + memcpy(param.nrec.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); param.nrec.state = p_data->val.num; btc_hf_cb_to_app(ESP_HF_NREC_RESPONSE_EVT, ¶m); } while(0); @@ -1450,29 +1509,38 @@ void btc_hf_cb_handler(btc_msg_t *msg) case BTA_AG_AT_A_EVT: { - btc_hf_cb_to_app(ESP_HF_ATA_RESPONSE_EVT, NULL); + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); + memcpy(param.ata_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + btc_hf_cb_to_app(ESP_HF_ATA_RESPONSE_EVT, ¶m); break; } case BTA_AG_AT_CHUP_EVT: { - btc_hf_cb_to_app(ESP_HF_CHUP_RESPONSE_EVT, NULL); + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); + memcpy(param.chup_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + btc_hf_cb_to_app(ESP_HF_CHUP_RESPONSE_EVT, ¶m); break; } case BTA_AG_AT_BLDN_EVT: case BTA_AG_AT_D_EVT: { + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); do { if (event == BTA_AG_AT_D_EVT) { // dial_number_or_memory - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); + memcpy(param.out_call.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + param.out_call.type = p_data->val.value; param.out_call.num_or_loc = osi_malloc((strlen(p_data->val.str) + 1) * sizeof(char)); sprintf(param.out_call.num_or_loc, "%s", p_data->val.str); btc_hf_cb_to_app(ESP_HF_DIAL_EVT, ¶m); - send_indicator_update(BTA_AG_IND_CALLSETUP,BTA_AG_CALLSETUP_OUTGOING); osi_free(param.out_call.num_or_loc); } else if (event == BTA_AG_AT_BLDN_EVT) { //dial_last - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); + memcpy(param.out_call.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + param.out_call.num_or_loc = NULL; btc_hf_cb_to_app(ESP_HF_DIAL_EVT, ¶m); } } while(0); @@ -1498,7 +1566,7 @@ void btc_hf_cb_handler(btc_msg_t *msg) CHECK_HF_IDX(idx); BTC_TRACE_DEBUG("AG Bitmap of peer-codecs %d", p_data->val.num); #if (BTM_WBS_INCLUDED == TRUE) - /* If the peer supports mSBC and the BTC prefferred codec is also mSBC, then + /* If the peer supports mSBC and the BTC preferred codec is also mSBC, then ** we should set the BTA AG Codec to mSBC. This would trigger a +BCS to mSBC at the time ** of SCO connection establishment */ if ((btc_conf_hf_force_wbs == TRUE) && (p_data->val.num & BTA_AG_CODEC_MSBC)) { @@ -1515,23 +1583,37 @@ void btc_hf_cb_handler(btc_msg_t *msg) #if (BTM_WBS_INCLUDED == TRUE) case BTA_AG_WBS_EVT: { - BTC_TRACE_DEBUG("Set codec status %d codec %d 1=CVSD 2=MSBC", p_data->val.hdr.status, p_data->val.num); - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); - param.wbs_rep.codec = p_data->val.num; - btc_hf_cb_to_app(ESP_HF_WBS_RESPONSE_EVT, ¶m); + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); + do { + BTC_TRACE_DEBUG("Set codec status %d codec %d 1=CVSD 2=MSBC", p_data->val.hdr.status, p_data->val.num); + memcpy(param.wbs_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + param.wbs_rep.codec = p_data->val.num; + btc_hf_cb_to_app(ESP_HF_WBS_RESPONSE_EVT, ¶m); + } while (0); break; } case BTA_AG_AT_BCS_EVT: { - BTC_TRACE_DEBUG("AG final seleded codec is %d 1=CVSD 2=MSBC", p_data->val.num); - memset(¶m, 0, sizeof(esp_hf_cb_param_t)); - param.bcs_rep.mode = p_data->val.num; - /* No ESP_HF_WBS_NONE case, becuase HFP 1.6 supported device can send BCS */ - btc_hf_cb_to_app(ESP_HF_BCS_RESPONSE_EVT, ¶m); + idx = p_data->hdr.handle - 1; + CHECK_HF_IDX(idx); + do { + BTC_TRACE_DEBUG("AG final seleded codec is %d 1=CVSD 2=MSBC", p_data->val.num); + memcpy(param.bcs_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + param.bcs_rep.mode = p_data->val.num; + /* No ESP_HF_WBS_NONE case, because HFP 1.6 supported device can send BCS */ + btc_hf_cb_to_app(ESP_HF_BCS_RESPONSE_EVT, ¶m); + } while (0); break; } #endif + case BTA_AG_PKT_NUMS_GET_EVT: + { + memcpy(¶m.pkt_nums, &p_data->pkt_num, sizeof(struct ag_pkt_status_nums)); + btc_hf_cb_to_app(ESP_HF_PKT_STAT_NUMS_GET_EVT, ¶m); + break; + } default: BTC_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event); break; 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 e1a0cf8d68..3909a4c6f6 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 @@ -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 */ @@ -28,6 +28,10 @@ #include "esp_bt.h" #include +#if BT_HF_CLIENT_BQB_INCLUDED +static BOOLEAN s_bta_hf_client_bqb_esco_s4_flag = false; +#endif /* BT_HF_CLIENT_BQB_INCLUDED */ + #if (BTC_HF_CLIENT_INCLUDED == TRUE) /************************************************************************************ @@ -54,6 +58,21 @@ #endif +/******************************************************************************* +** +** Function bta_hf_client_bqb_esco_s4_ctrl +** +** Description Control the usage of BTA_HF_CLIENT_FEAT_ESCO_S4 for BQB test +** +** Returns void +** +*******************************************************************************/ +#if BT_HF_CLIENT_BQB_INCLUDED +void bta_hf_client_bqb_esco_s4_ctrl(BOOLEAN enable) +{ + s_bta_hf_client_bqb_esco_s4_flag = enable; +} +#endif /* BT_HF_CLIENT_BQB_INCLUDED */ /************************************************************************************ ** Static variables @@ -677,6 +696,24 @@ static bt_status_t btc_hf_client_send_nrec(void) return BT_STATUS_UNSUPPORTED; } +/******************************************************************************* +** +** Function btc_hf_client_pkt_stat_nums_get; +** +** Description Request packet status numbers for a specific (e)SCO connection handle +** +** Returns bt_status_t +** +*******************************************************************************/ +static bt_status_t btc_hf_client_pkt_stat_nums_get(UINT16 sync_conn_handle) +{ + CHECK_HF_CLIENT_SLC_CONNECTED(); +#if (BTM_SCO_HCI_INCLUDED == TRUE) + BTA_HfClientPktStatsNumsGet(sync_conn_handle); +#endif /*#if (BTM_SCO_HCI_INCLUDED == TRUE) */ + return BT_STATUS_SUCCESS; +} + /******************************************************************************* ** ** Function bte_hf_client_evt @@ -725,6 +762,11 @@ bt_status_t btc_hf_client_execute_service(BOOLEAN b_enable) if (btc_hf_client_version >= HFP_HF_VERSION_1_7) { hf_client_local_param.btc_hf_client_features |= BTA_HF_CLIENT_FEAT_ESCO_S4; +#if BT_HF_CLIENT_BQB_INCLUDED + if (s_bta_hf_client_bqb_esco_s4_flag == true) { + hf_client_local_param.btc_hf_client_features = BTA_HF_CLIENT_FEAT_ESCO_S4; + } +#endif /* BT_HF_CLIENT_BQB_INCLUDED */ BTC_TRACE_EVENT("eSCO S4 Setting Supported"); } @@ -802,6 +844,8 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) esp_hf_client_cb_param_t param; bdstr_t bdstr; + memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); + switch (event) { case BTA_HF_CLIENT_ENABLE_EVT: @@ -832,7 +876,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) } do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.conn_stat.state = hf_client_local_param.btc_hf_client_cb.state; param.conn_stat.peer_feat = 0; param.conn_stat.chld_feat = 0; @@ -858,7 +901,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) hf_client_local_param.btc_hf_client_cb.state = ESP_HF_CLIENT_CONNECTION_STATE_SLC_CONNECTED; do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.conn_stat.state = hf_client_local_param.btc_hf_client_cb.state; param.conn_stat.peer_feat = hf_client_local_param.btc_hf_client_cb.peer_feat; param.conn_stat.chld_feat = hf_client_local_param.btc_hf_client_cb.chld_feat; @@ -873,7 +915,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) if (hf_client_local_param.btc_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_INBAND) { do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.bsir.state = ESP_HF_CLIENT_IN_BAND_RINGTONE_PROVIDED; btc_hf_client_cb_to_app(ESP_HF_CLIENT_BSIR_EVT, ¶m); } while (0); @@ -885,7 +926,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) case BTA_HF_CLIENT_CLOSE_EVT: hf_client_local_param.btc_hf_client_cb.state = ESP_HF_CLIENT_CONNECTION_STATE_DISCONNECTED; do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.conn_stat.state = ESP_HF_CLIENT_CONNECTION_STATE_DISCONNECTED; param.conn_stat.peer_feat = 0; param.conn_stat.chld_feat = 0; @@ -906,7 +946,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) break; case BTA_HF_CLIENT_MIC_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.volume_control.type = ESP_HF_VOLUME_CONTROL_TARGET_MIC; param.volume_control.volume = p_data->val.value; @@ -915,7 +954,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) break; case BTA_HF_CLIENT_SPK_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.volume_control.type = ESP_HF_VOLUME_CONTROL_TARGET_SPK; param.volume_control.volume = p_data->val.value; @@ -924,7 +962,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) break; case BTA_HF_CLIENT_VOICE_REC_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.bvra.value = p_data->val.value; btc_hf_client_cb_to_app(ESP_HF_CLIENT_BVRA_EVT, ¶m); @@ -932,35 +969,30 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) break; case BTA_HF_CLIENT_OPERATOR_NAME_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.cops.name = p_data->operator.name; btc_hf_client_cb_to_app(ESP_HF_CLIENT_COPS_CURRENT_OPERATOR_EVT, ¶m); } while (0); break; case BTA_HF_CLIENT_CLIP_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.clip.number = p_data->number.number; btc_hf_client_cb_to_app(ESP_HF_CLIENT_CLIP_EVT, ¶m); } while (0); break; case BTA_HF_CLIENT_BINP_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.binp.number = p_data->number.number; btc_hf_client_cb_to_app(ESP_HF_CLIENT_BINP_EVT, ¶m); } while (0); break; case BTA_HF_CLIENT_CCWA_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.ccwa.number = p_data->number.number; btc_hf_client_cb_to_app(ESP_HF_CLIENT_CCWA_EVT, ¶m); } while (0); break; case BTA_HF_CLIENT_AT_RESULT_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.at_response.code = p_data->result.type; param.at_response.cme = p_data->result.cme; @@ -969,7 +1001,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) break; case BTA_HF_CLIENT_CLCC_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.clcc.idx = p_data->clcc.idx; param.clcc.dir = p_data->clcc.inc ? ESP_HF_CURRENT_CALL_DIRECTION_INCOMING : ESP_HF_CURRENT_CALL_DIRECTION_OUTGOING; @@ -982,7 +1013,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) break; case BTA_HF_CLIENT_CNUM_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.cnum.number = p_data->cnum.number; if (p_data->cnum.service == 4) { param.cnum.type = ESP_HF_SUBSCRIBER_SERVICE_TYPE_VOICE; @@ -998,7 +1028,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) case BTA_HF_CLIENT_BTRH_EVT: if (p_data->val.value <= ESP_HF_BTRH_STATUS_REJECTED) { do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.btrh.status = p_data->val.value; btc_hf_client_cb_to_app(ESP_HF_CLIENT_BTRH_EVT, ¶m); @@ -1006,7 +1035,6 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) } break; case BTA_HF_CLIENT_BSIR_EVT: - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); if (p_data->val.value != 0) { param.bsir.state = ESP_HF_CLIENT_IN_BAND_RINGTONE_PROVIDED; @@ -1019,28 +1047,28 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) break; case BTA_HF_CLIENT_AUDIO_OPEN_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_CONNECTED; memcpy(param.audio_stat.remote_bda, &hf_client_local_param.btc_hf_client_cb.connected_bda, sizeof(esp_bd_addr_t)); + param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, ¶m); } while (0); break; case BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC; memcpy(param.audio_stat.remote_bda, &hf_client_local_param.btc_hf_client_cb.connected_bda, sizeof(esp_bd_addr_t)); + param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, ¶m); } while (0); break; case BTA_HF_CLIENT_AUDIO_CLOSE_EVT: do { - memset(¶m, 0, sizeof(esp_hf_client_cb_param_t)); param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_DISCONNECTED; memcpy(param.audio_stat.remote_bda, &hf_client_local_param.btc_hf_client_cb.connected_bda, sizeof(esp_bd_addr_t)); + param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, ¶m); } while (0); break; @@ -1049,6 +1077,12 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) btc_hf_client_cb_to_app(ESP_HF_CLIENT_RING_IND_EVT, NULL); } while (0); break; + case BTA_HF_CLIENT_PKT_STAT_NUMS_GET_EVT: + { + memcpy(¶m.pkt_nums, &p_data->pkt_num, sizeof(struct hf_client_pkt_status_nums)); + btc_hf_client_cb_to_app(ESP_HF_CLIENT_PKT_STAT_NUMS_GET_EVT, ¶m); + break; + } default: BTC_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event); break; @@ -1132,6 +1166,9 @@ void btc_hf_client_call_handler(btc_msg_t *msg) case BTC_HF_CLIENT_SEND_IPHONEACCEV_EVT: btc_hf_client_send_iphoneaccev(arg->send_iphoneaccev.bat_level, arg->send_iphoneaccev.docked); break; + case BTC_HF_CLIENT_REQUEST_PKT_STAT_EVT: + btc_hf_client_pkt_stat_nums_get(arg->pkt_sync_hd.sync_conn_handle); + break; default: BTC_TRACE_WARNING("%s : unhandled event: %d\n", __FUNCTION__, msg->act); } diff --git a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c index 202f90b0a4..0d99c030b6 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c +++ b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c @@ -52,7 +52,7 @@ typedef enum { BTC_HD_DUMMY_REQ_EVT = 0 } btc_hd_req_evt_t; /******************************************************************************* * Static variables ******************************************************************************/ -btc_hd_cb_t btc_hd_cb; +btc_hd_cb_t btc_hd_cb = {0}; // static tBTA_HD_APP_INFO app_info; // static tBTA_HD_QOS_INFO in_qos; @@ -242,7 +242,7 @@ static void btc_hd_init(void) * Returns void * ******************************************************************************/ -static void btc_hd_unregister_app(void); +static void btc_hd_unregister_app(bool need_deinit); static void btc_hd_deinit(void) { BTC_TRACE_API("%s", __func__); @@ -261,12 +261,12 @@ static void btc_hd_deinit(void) } btc_hd_cb.service_dereg_active = FALSE; - btc_hd_cb.status = BTC_HD_DISABLING; - // unresgister app will also relase the connection + // unregister app will also release the connection // and disable after receiving unregister event from lower layer if (is_hidd_app_register()) { - btc_hd_unregister_app(); + btc_hd_unregister_app(true); } else { + btc_hd_cb.status = BTC_HD_DISABLING; BTC_TRACE_WARNING("%s disabling hid device service now", __func__); BTA_HdDisable(); } @@ -298,6 +298,10 @@ static void btc_hd_register_app(esp_hidd_app_param_t *p_app_param, esp_hidd_qos_ BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__); ret = ESP_HIDD_NEED_INIT; break; + } else if (btc_hd_cb.status == BTC_HD_DISABLING) { + BTC_TRACE_ERROR("%s: deinit is in progress!", __func__); + ret = ESP_HIDD_BUSY; + break; } if (is_hidd_app_register()) { @@ -359,7 +363,7 @@ static void btc_hd_register_app(esp_hidd_app_param_t *p_app_param, esp_hidd_qos_ * Returns void * ******************************************************************************/ -static void btc_hd_unregister_app(void) +static void btc_hd_unregister_app(bool need_deinit) { BTC_TRACE_API("%s", __func__); esp_hidd_status_t ret = ESP_HIDD_SUCCESS; @@ -368,6 +372,10 @@ static void btc_hd_unregister_app(void) BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__); ret = ESP_HIDD_NEED_INIT; break; + } else if (btc_hd_cb.status == BTC_HD_DISABLING) { + BTC_TRACE_ERROR("%s: deinit is in progress!", __func__); + ret = ESP_HIDD_BUSY; + break; } if (!is_hidd_app_register()) { @@ -382,11 +390,16 @@ static void btc_hd_unregister_app(void) break; } btc_hd_cb.service_dereg_active = TRUE; + + if (need_deinit) { + btc_hd_cb.status = BTC_HD_DISABLING; + } + BTA_HdUnregisterApp(); } while(0); if (ret != ESP_HIDD_SUCCESS) { - esp_hidd_cb_param_t param; + esp_hidd_cb_param_t param = {0}; param.unregister_app.status = ret; btc_hd_cb_to_app(ESP_HIDD_UNREGISTER_APP_EVT, ¶m); } @@ -405,30 +418,46 @@ static void btc_hd_connect(BD_ADDR bd_addr) { BTC_TRACE_API("%s", __func__); esp_hidd_status_t ret = ESP_HIDD_SUCCESS; + do { - if (!is_hidd_init()) { + switch (btc_hd_cb.status) { + case BTC_HD_DISABLED: BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__); ret = ESP_HIDD_NEED_INIT; break; + case BTC_HD_DISABLING: + BTC_TRACE_ERROR("%s: deinit is in progress!", __func__); + ret = ESP_HIDD_BUSY; + break; + case BTC_HD_CONNECTING: + case BTC_HD_DISCONNECTING: + BTC_TRACE_ERROR("%s: busy now, status:%d, try later!", __func__, btc_hd_cb.status); + ret = ESP_HIDD_BUSY; + break; + case BTC_HD_CONNECTED: + BTC_TRACE_ERROR("%s: already connect to the other HID host!", __func__); + ret = ESP_HIDD_NO_RES; + break; + default: + break; } - if (!is_hidd_app_register()) { - BTC_TRACE_ERROR("%s: application has not been registered, shall register first!", __func__); - ret = ESP_HIDD_NEED_REG; + if (ret != ESP_HIDD_SUCCESS) { break; } - if (btc_hd_cb.status == BTC_HD_CONNECTED) { - BTC_TRACE_ERROR("%s: already connect to the other HID host!", __func__); - ret = ESP_HIDD_NO_RES; + if (!is_hidd_app_register()) { + BTC_TRACE_ERROR("%s: application has not been registered, shall register first!", __func__); + ret = ESP_HIDD_NEED_REG; break; } BTA_HdConnect(bd_addr); + btc_hd_cb.status = BTC_HD_CONNECTING; } while (0); if (ret != ESP_HIDD_SUCCESS) { - esp_hidd_cb_param_t param; + esp_hidd_cb_param_t param = {0}; param.open.status = ret; param.open.conn_status = ESP_HIDD_CONN_STATE_DISCONNECTED; memcpy(param.open.bd_addr, bd_addr, BD_ADDR_LEN); @@ -449,30 +478,47 @@ static void btc_hd_disconnect(void) { BTC_TRACE_API("%s", __func__); esp_hidd_status_t ret = ESP_HIDD_SUCCESS; + do { - if (!is_hidd_init()) { + switch (btc_hd_cb.status) { + case BTC_HD_DISABLED: BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__); ret = ESP_HIDD_NEED_INIT; break; + case BTC_HD_DISABLING: + BTC_TRACE_ERROR("%s: deinit is in progress!", __func__); + ret = ESP_HIDD_BUSY; + break; + case BTC_HD_CONNECTING: + case BTC_HD_DISCONNECTING: + BTC_TRACE_ERROR("%s: busy now, status:%d, try later!", __func__, btc_hd_cb.status); + ret = ESP_HIDD_BUSY; + break; + case BTC_HD_ENABLED: + case BTC_HD_DISCONNECTED: + BTC_TRACE_ERROR("%s: no connection!", __func__); + ret = ESP_HIDD_NO_CONNECTION; + break; + default: + break; } - if (!is_hidd_app_register()) { - BTC_TRACE_ERROR("%s: application has not been registered, shall register first!", __func__); - ret = ESP_HIDD_NEED_REG; + if (ret != ESP_HIDD_SUCCESS) { break; } - if (btc_hd_cb.status != BTC_HD_CONNECTED) { - BTC_TRACE_ERROR("%s: already disconnected!", __func__); - ret = ESP_HIDD_NO_CONNECTION; + if (!is_hidd_app_register()) { + BTC_TRACE_ERROR("%s: application has not been registered, shall register first!", __func__); + ret = ESP_HIDD_NEED_REG; break; } BTA_HdDisconnect(); + btc_hd_cb.status = BTC_HD_DISCONNECTING; } while (0); if (ret != ESP_HIDD_SUCCESS) { - esp_hidd_cb_param_t param; + esp_hidd_cb_param_t param = {0}; param.close.status = ret; param.close.conn_status = ESP_HIDD_CONN_STATE_DISCONNECTED; btc_hd_cb_to_app(ESP_HIDD_CLOSE_EVT, ¶m); @@ -490,15 +536,41 @@ static void btc_hd_disconnect(void) ******************************************************************************/ static void btc_hd_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t len, uint8_t *p_data) { - tBTA_HD_REPORT report; - BTC_TRACE_API("%s: type=%d id=%d len=%d", __func__, type, id, len); + tBTA_HD_REPORT report = {0}; esp_hidd_status_t ret = ESP_HIDD_SUCCESS; + do { - if (!is_hidd_init()) { + switch (btc_hd_cb.status) { + case BTC_HD_DISABLED: BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__); ret = ESP_HIDD_NEED_INIT; break; + case BTC_HD_DISABLING: + BTC_TRACE_ERROR("%s: deinit is in progress!", __func__); + ret = ESP_HIDD_BUSY; + break; + case BTC_HD_CONNECTING: + case BTC_HD_DISCONNECTING: + BTC_TRACE_ERROR("%s: busy now, status:%d, try later!", __func__, btc_hd_cb.status); + ret = ESP_HIDD_BUSY; + break; + case BTC_HD_ENABLED: + case BTC_HD_DISCONNECTED: + if (type == ESP_HIDD_REPORT_TYPE_INTRDATA) { + BTC_TRACE_WARNING("%s: no connection, try to reconnect!", __func__); + btc_hd_cb.status = BTC_HD_CONNECTING; + } else { + BTC_TRACE_ERROR("%s: no connection!", __func__); + ret = ESP_HIDD_NO_CONNECTION; + } + break; + default: + break; + } + + if (ret != ESP_HIDD_SUCCESS) { + break; } if (!is_hidd_app_register()) { @@ -506,6 +578,7 @@ static void btc_hd_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t ret = ESP_HIDD_NEED_REG; break; } + if (type == ESP_HIDD_REPORT_TYPE_INTRDATA) { report.type = ESP_HIDD_REPORT_TYPE_INPUT; report.use_intr = TRUE; @@ -522,7 +595,7 @@ static void btc_hd_send_report(esp_hidd_report_type_t type, uint8_t id, uint16_t } while (0); if (ret != ESP_HIDD_SUCCESS) { - esp_hidd_cb_param_t param; + esp_hidd_cb_param_t param = {0}; param.send_report.status = ret; param.send_report.reason = 0; param.send_report.report_type = report.type; @@ -556,11 +629,18 @@ static void btc_hd_report_error(uint8_t error) ret = ESP_HIDD_NEED_REG; break; } + + if (btc_hd_cb.status != BTC_HD_CONNECTED) { + BTC_TRACE_ERROR("%s: no connection!", __func__); + ret = ESP_HIDD_NO_CONNECTION; + break; + } + BTA_HdReportError(error); } while (0); if (ret != ESP_HIDD_SUCCESS) { - esp_hidd_cb_param_t param; + esp_hidd_cb_param_t param = {0}; param.report_err.status = ret; param.report_err.reason = 0; btc_hd_cb_to_app(ESP_HIDD_REPORT_ERR_EVT, ¶m); @@ -580,11 +660,28 @@ static void btc_hd_virtual_cable_unplug(void) { BTC_TRACE_API("%s", __func__); esp_hidd_status_t ret = ESP_HIDD_SUCCESS; + do { - if (!is_hidd_init()) { + switch (btc_hd_cb.status) { + case BTC_HD_DISABLED: BTC_TRACE_ERROR("%s HD has not been initiated, shall init first!", __func__); ret = ESP_HIDD_NEED_INIT; break; + case BTC_HD_DISABLING: + BTC_TRACE_ERROR("%s: deinit is in progress!", __func__); + ret = ESP_HIDD_BUSY; + break; + case BTC_HD_CONNECTING: + case BTC_HD_DISCONNECTING: + BTC_TRACE_ERROR("%s: busy now, status:%d, try later!", __func__, btc_hd_cb.status); + ret = ESP_HIDD_BUSY; + break; + default: + break; + } + + if (ret != ESP_HIDD_SUCCESS) { + break; } if (!is_hidd_app_register()) { @@ -592,13 +689,18 @@ static void btc_hd_virtual_cable_unplug(void) ret = ESP_HIDD_NEED_REG; break; } + BTA_HdVirtualCableUnplug(); + + if (btc_hd_cb.status == BTC_HD_CONNECTED) { + btc_hd_cb.status = BTC_HD_DISCONNECTING; + } } while (0); if (ret != ESP_HIDD_SUCCESS) { - esp_hidd_cb_param_t param; - param.report_err.status = ret; - param.report_err.reason = 0; + esp_hidd_cb_param_t param = {0}; + param.vc_unplug.status = ret; + param.vc_unplug.conn_status = ESP_HIDD_CONN_STATE_DISCONNECTED; btc_hd_cb_to_app(ESP_HIDD_VC_UNPLUG_EVT, ¶m); } } @@ -630,7 +732,7 @@ void btc_hd_call_handler(btc_msg_t *msg) btc_hd_register_app(arg->register_app.app_param, arg->register_app.in_qos, arg->register_app.out_qos); break; case BTC_HD_UNREGISTER_APP_EVT: - btc_hd_unregister_app(); + btc_hd_unregister_app(false); break; case BTC_HD_CONNECT_EVT: btc_hd_connect(arg->connect.bd_addr); @@ -742,6 +844,8 @@ void btc_hd_cb_handler(btc_msg_t *msg) // } // btc_storage_set_hidd((bt_bdaddr_t *)&p_data->conn.bda); btc_hd_cb.status = BTC_HD_CONNECTED; + } else if (p_data->conn.conn_status == BTA_HD_CONN_STATE_DISCONNECTED) { + btc_hd_cb.status = BTC_HD_DISCONNECTED; } param.open.status = p_data->conn.status; param.open.conn_status = p_data->conn.conn_status; @@ -750,16 +854,15 @@ void btc_hd_cb_handler(btc_msg_t *msg) break; } case BTA_HD_CLOSE_EVT: - if (btc_hd_cb.forced_disc && p_data->conn.conn_status == BTA_HD_CONN_STATE_DISCONNECTED) { - bt_bdaddr_t *addr = (bt_bdaddr_t *)&p_data->conn.bda; - BTC_TRACE_WARNING("remote device was forcefully disconnected"); - btc_hd_remove_device(*addr); - btc_hd_cb.forced_disc = FALSE; - break; - } - - if (btc_hd_cb.status == BTC_HD_CONNECTED) { - btc_hd_cb.status = BTC_HD_ENABLED; + if (p_data->conn.conn_status == BTA_HD_CONN_STATE_DISCONNECTED) { + btc_hd_cb.status = BTC_HD_DISCONNECTED; + if (btc_hd_cb.forced_disc) { + bt_bdaddr_t *addr = (bt_bdaddr_t *)&p_data->conn.bda; + BTC_TRACE_WARNING("remote device was forcefully disconnected"); + btc_hd_remove_device(*addr); + btc_hd_cb.forced_disc = FALSE; + break; + } } param.close.status = p_data->conn.status; @@ -809,8 +912,9 @@ void btc_hd_cb_handler(btc_msg_t *msg) btc_hd_remove_device(*bd_addr); } - if (btc_hd_cb.status == BTC_HD_CONNECTED) { - btc_hd_cb.status = BTC_HD_ENABLED; + if (btc_hd_cb.status == BTC_HD_DISCONNECTING || btc_hd_cb.status == BTC_HD_CONNECTING || + btc_hd_cb.status == BTC_HD_CONNECTED) { + btc_hd_cb.status = BTC_HD_DISCONNECTED; param.close.status = p_data->conn.status; param.close.conn_status = p_data->conn.conn_status; btc_hd_cb_to_app(ESP_HIDD_CLOSE_EVT, ¶m); diff --git a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c index 7202371e7b..1d6f20201e 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c +++ b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c @@ -189,7 +189,7 @@ static btc_hh_device_t *btc_hh_find_connected_dev_by_bda(BD_ADDR bd_addr) * * Function btc_hh_stop_vup_timer * - * Description stop vitual unplug timer + * Description stop virtual unplug timer * * Returns void ******************************************************************************/ @@ -316,7 +316,7 @@ void btc_hh_remove_device(BD_ADDR bd_addr) for (i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) { p_added_dev = &btc_hh_cb.added_devices[i]; - if (p_added_dev->bd_addr == bd_addr) { + if (memcmp(p_added_dev->bd_addr, bd_addr, BD_ADDR_LEN) == 0) { BTA_HhRemoveDev(p_added_dev->dev_handle); btc_storage_remove_hid_info((bt_bdaddr_t *)p_added_dev->bd_addr); memset(p_added_dev->bd_addr, 0, 6); @@ -544,6 +544,11 @@ static void btc_hh_connect(btc_hidh_args_t *arg) BTC_TRACE_ERROR("%s exceeded the maximum supported HID device number %d!", __func__, BTC_HH_MAX_HID); ret = ESP_HIDH_ERR_NO_RES; break; + } else if (dev && dev->dev_status == ESP_HIDH_CONN_STATE_CONNECTED) { + BTC_TRACE_WARNING("%s Device[%s] already connected", __func__, + bdaddr_to_string((const bt_bdaddr_t *)arg->connect.bd_addr, bdstr, sizeof(bdstr))); + param.open.conn_status = ESP_HIDH_CONN_STATE_CONNECTED; + break; } for (int i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) { @@ -662,7 +667,7 @@ static void btc_hh_virtual_unplug(btc_hidh_args_t *arg) param.unplug.conn_status = ESP_HIDH_CONN_STATE_DISCONNECTING; param.unplug.handle = p_dev->dev_handle; } else if ((p_dev != NULL) && (p_dev->dev_status == ESP_HIDH_CONN_STATE_CONNECTED)) { - BTC_TRACE_WARNING("%s: Virtual unplug not suported, disconnecting device", __func__); + BTC_TRACE_WARNING("%s: Virtual unplug not supported, disconnecting device", __func__); /* start the timer */ btc_hh_start_vup_timer(arg->unplug.bd_addr); p_dev->local_vup = true; 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 afb47a1e82..69e95eb66d 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,7 @@ extern tBTA_BLE_ADV_DATA *gl_bta_scan_rsp_data_ptr; #define gl_bta_scan_rsp_data (*gl_bta_scan_rsp_data_ptr) #endif -#define BLE_ISVALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max)) || ((x) == ESP_BLE_CONN_PARAM_UNDEF)) +#define BLE_ISVALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max))) typedef enum { #if (BLE_42_FEATURE_SUPPORT == TRUE) @@ -84,8 +84,28 @@ typedef enum { BTC_GAP_BLE_START_EXT_SCAN, BTC_GAP_BLE_STOP_EXT_SCAN, BTC_GAP_BLE_SET_EXT_PEFER_CONNET_PARAMS, + BTC_GAP_BLE_DTM_ENH_TX_START, + BTC_GAP_BLE_DTM_ENH_RX_START, #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) BTC_GAP_BLE_ACT_GET_DEV_NAME, +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + BTC_GAP_BLE_PERIODIC_ADV_RECV_ENABLE, + BTC_GAP_BLE_PERIODIC_ADV_SYNC_TRANS, + BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS, + BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS, +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_42_FEATURE_SUPPORT == TRUE) + BTC_GAP_BLE_DTM_TX_START, + 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_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT, + BTC_GAP_BLE_ACT_ADD_DEVICE_TO_RESOLVING_LIST, + BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT, + BTC_GAP_BLE_SET_PRIVACY_MODE, } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ @@ -123,6 +143,16 @@ typedef union { struct set_rand_addr_args { esp_bd_addr_t rand_addr; } set_rand_addr; + // BTC_GAP_BLE_ACT_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT + struct set_rpa_timeout_args { + uint16_t rpa_timeout; + } set_rpa_timeout; + //BTC_GAP_BLE_ACT_ADD_DEVICE_TO_RESOLVING_LIST + struct add_dev_to_resolving_list_args { + esp_bd_addr_t addr; + uint8_t addr_type; + uint8_t irk[PEER_IRK_LEN]; + } add_dev_to_resolving_list; //BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY, struct cfg_local_privacy_args { bool privacy_enable; @@ -224,9 +254,29 @@ typedef union { struct set_channels_args { esp_gap_ble_channels channels; } set_channels; + struct dtm_tx_start_args { + uint8_t tx_channel; + uint8_t len_of_data; + uint8_t pkt_payload; + } dtm_tx_start; + struct dtm_rx_start_args { + uint8_t rx_channel; + } dtm_rx_start; + //BTC_DEV_VENDOR_HCI_CMD_EVT + struct vendor_cmd_send_args { + uint16_t opcode; + uint8_t param_len; + uint8_t *p_param_buf; + } vendor_cmd_send; + // BTC_GAP_BLE_SET_PRIVACY_MODE + struct set_privacy_mode { + esp_ble_addr_type_t addr_type; + esp_bd_addr_t addr; + uint8_t privacy_mode; + } set_privacy_mode; } btc_ble_gap_args_t; -#if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_50_FEATURE_SUPPORT == TRUE) typedef union { struct read_phy_args { esp_bd_addr_t bd_addr; @@ -290,9 +340,11 @@ typedef union { uint8_t instance; uint16_t len; uint8_t *data; + bool only_update_did; } periodic_adv_cfg_data; struct periodic_adv_start_args { + bool include_adi; uint8_t instance; } periodic_adv_start; @@ -342,6 +394,40 @@ typedef union { esp_bd_addr_t peer_addr; } ext_conn; +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + struct periodic_adv_recv_en_args { + uint16_t sync_handle; + uint8_t enable; + } periodic_adv_recv_en; + + struct periodic_adv_sync_trans_args { + esp_bd_addr_t addr; + uint16_t service_data; + uint16_t sync_handle; + } periodic_adv_sync_trans; + + struct periodic_adv_set_info_trans_args { + esp_bd_addr_t addr; + uint16_t service_data; + uint16_t adv_handle; + } periodic_adv_set_info_trans; + + struct set_periodic_adv_sync_trans_params_args { + esp_bd_addr_t addr; + esp_ble_gap_past_params_t params; + } set_periodic_adv_sync_trans_params; +#endif + struct dtm_enh_tx_start_args { + uint8_t tx_channel; + uint8_t len_of_data; + uint8_t pkt_payload; + uint8_t phy; + } dtm_enh_tx_start; + struct dtm_enh_rx_start_args { + uint8_t rx_channel; + uint8_t phy; + uint8_t modulation_index; + } dtm_enh_rx_start; } btc_ble_5_gap_args_t; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.h index 3f9c2da09e..4e93123d44 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_bt.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 */ @@ -31,6 +31,7 @@ typedef enum { BTC_GAP_BT_MODE_CHG_EVT, BTC_GAP_BT_REMOVE_BOND_DEV_COMPLETE_EVT, BTC_GAP_BT_QOS_EVT, + BTC_GAP_BT_SET_ACL_PKT_TYPES_EVT, }btc_gap_bt_evt_t; typedef enum { @@ -51,6 +52,7 @@ typedef enum { BTC_GAP_BT_ACT_SET_AFH_CHANNELS, BTC_GAP_BT_ACT_READ_REMOTE_NAME, BTC_GAP_BT_ACT_SET_QOS, + BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES, } btc_gap_bt_act_t; /* btc_bt_gap_args_t */ @@ -147,6 +149,12 @@ typedef union { uint32_t t_poll; } set_qos; + // BTC_GAP_BT_ACT_SET_ACL_PKT_TYPES + struct set_acl_pkt_types_args { + bt_bdaddr_t bda; + uint16_t pkt_types; + } set_acl_pkt_types; + } btc_gap_bt_args_t; void btc_gap_bt_call_handler(btc_msg_t *msg); diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h index 48481a8f9a..eeebb427f2 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gattc.h @@ -24,6 +24,7 @@ typedef enum { BTC_GATTC_ACT_SEARCH_SERVICE, BTC_GATTC_ACT_READ_CHAR, BTC_GATTC_ACT_READ_MULTIPLE_CHAR, + BTC_GATTC_ACT_READ_MULTIPLE_VARIABLE_CHAR, BTC_GATTC_ACT_READ_CHAR_DESCR, BTC_GATTC_ACT_READ_BY_TYPE, BTC_GATTC_ACT_WRITE_CHAR, diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gatts.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gatts.h index a8de3539a4..82ae435339 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gatts.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gatts.h @@ -30,6 +30,7 @@ typedef enum { BTC_GATTS_ACT_OPEN, BTC_GATTS_ACT_CLOSE, BTC_GATTS_ACT_SEND_SERVICE_CHANGE, + BTC_GATTS_ACT_SHOW_LOCAL_DATABASE, } btc_gatts_act_t; /* btc_ble_gatts_args_t */ @@ -164,6 +165,7 @@ void btc_gatts_cb_handler(btc_msg_t *msg); void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src); void btc_gatts_arg_deep_free(btc_msg_t *msg); esp_gatt_status_t btc_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, uint8_t **value); +esp_gatt_status_t btc_gatts_show_local_database(void); #endif /* __BTC_GATTS_H__ */ 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 7fe7460c10..313930a4d0 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 @@ -39,7 +39,15 @@ typedef enum { BTC_HD_UNPLUG_EVT, } BTC_HD_EVT; -typedef enum { BTC_HD_DISABLED = 0, BTC_HD_ENABLED, BTC_HD_CONNECTED, BTC_HD_DISABLING } BTC_HD_STATUS; +typedef enum { + BTC_HD_DISABLED = 0, + BTC_HD_ENABLED, + BTC_HD_DISABLING, + BTC_HD_CONNECTING, + BTC_HD_CONNECTED, + BTC_HD_DISCONNECTING, + BTC_HD_DISCONNECTED, +} BTC_HD_STATUS; /* BTIF-HD control block */ typedef struct { @@ -55,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_hf_ag.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h index 9ab6d6f0cf..5cecdd9951 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -44,6 +44,7 @@ typedef enum BTC_HF_UNAT_RESPONSE_EVT, BTC_HF_CME_ERR_EVT, BTC_HF_IND_NOTIFICATION_EVT, + BTC_HF_CIEV_REPORT_EVT, BTC_HF_CIND_RESPONSE_EVT, BTC_HF_COPS_RESPONSE_EVT, BTC_HF_CLCC_RESPONSE_EVT, @@ -55,7 +56,8 @@ typedef enum BTC_HF_OUT_CALL_EVT, BTC_HF_END_CALL_EVT, //REG - BTC_HF_REGISTER_DATA_CALLBACK_EVT + BTC_HF_REGISTER_DATA_CALLBACK_EVT, + BTC_HF_REQUEST_PKT_STAT_EVT } btc_hf_act_t; /* btc_hf_args_t */ @@ -108,6 +110,12 @@ typedef union int signal; } ind_change; + //BTC_HF_CIEV_REPORT_EVT + struct ciev_args { + bt_bdaddr_t remote_addr; + tBTA_AG_IND ind; + } ciev_rep; + //BTC_HF_CIND_RESPONSE_EVT struct cind_args { bt_bdaddr_t remote_addr; @@ -142,7 +150,8 @@ typedef union struct cnum_args { bt_bdaddr_t remote_addr; char *number; - esp_hf_subscriber_service_type_t type; + int number_type; + esp_hf_subscriber_service_type_t service_type; } cnum_rep; //BTC_HF_NREC_RESPONSE_EVT @@ -175,11 +184,16 @@ 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 ag_req_pkt_stat_sync_handle { + UINT16 sync_conn_handle; + } pkt_sync_hd; + } btc_hf_args_t; /************************************************************************************ @@ -219,6 +233,11 @@ typedef struct esp_hf_outgoing_data_cb_t btc_hf_outgoing_data_cb; } hf_local_param_t; +#if HFP_DYNAMIC_MEMORY == TRUE +extern hf_local_param_t *hf_local_param_ptr; +#define hf_local_param (hf_local_param_ptr) +#endif + /******************************************************************************* ** BTC HF AG Handle Hub ********************************************************************************/ 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 e8e65986a1..4f10371bd0 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 @@ -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 */ @@ -52,6 +52,7 @@ typedef enum { BTC_HF_CLIENT_SEND_NREC_EVT, BTC_HF_CLIENT_SEND_XAPL_EVT, BTC_HF_CLIENT_SEND_IPHONEACCEV_EVT, + BTC_HF_CLIENT_REQUEST_PKT_STAT_EVT, } btc_hf_client_act_t; /* btc_hf_client_args_t */ @@ -101,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; @@ -117,6 +118,12 @@ typedef union { uint32_t bat_level; bool docked; } send_iphoneaccev; + + // BTC_HF_CLIENT_REQUEST_PKT_STAT_EVT + struct hf_client_req_pkt_stat_sync_handle { + UINT16 sync_conn_handle; + } pkt_sync_hd; + } btc_hf_client_args_t; /************************************************************************************ 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 0e0cea8a06..ae6faefc1e 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/btc/profile/std/l2cap/btc_l2cap.c b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c index 577e341aa4..7c5157736a 100644 --- a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c +++ b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c @@ -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 */ @@ -63,6 +63,7 @@ typedef struct { int tx_mtu; uint8_t *write_data; osi_alarm_t *close_alarm; + void *alarm_arg; uint8_t role; uint16_t security; esp_bd_addr_t addr; @@ -192,6 +193,7 @@ static l2cap_slot_t *l2cap_malloc_slot(void) (*slot)->is_server = false; (*slot)->write_data = NULL; (*slot)->close_alarm = NULL; + (*slot)->alarm_arg = NULL; /* clear the old event bits */ if (l2cap_local_param.tx_event_group) { xEventGroupClearBits(l2cap_local_param.tx_event_group, SLOT_WRITE_BIT(i) | SLOT_CLOSE_BIT(i)); @@ -246,23 +248,41 @@ static void l2cap_free_slot(l2cap_slot_t *slot) free_slot_data(&slot->rx); if (slot->close_alarm) { osi_alarm_free(slot->close_alarm); + if (slot->alarm_arg) { + osi_free(slot->alarm_arg); + slot->alarm_arg = NULL; + } } osi_free(slot); } +static void l2cap_free_pending_slots(void) +{ + l2cap_slot_t *slot = NULL; + for (size_t i = 1; i <= BTA_JV_MAX_L2C_CONN; i++) { + slot = l2cap_local_param.l2cap_slots[i]; + if (slot) { + BTC_TRACE_WARNING("%s found slot(handle=0x%x) pending to close, close it now!", __func__, slot->handle); + l2cap_free_slot(slot); + } + } +} + static void close_timeout_handler(void *arg) { btc_msg_t msg; bt_status_t status; + l2cap_slot_t *slot = (l2cap_slot_t *)arg; msg.sig = BTC_SIG_API_CB; msg.pid = BTC_PID_L2CAP; msg.act = BTA_JV_L2CAP_CLOSE_EVT; - status = btc_transfer_context(&msg, arg, sizeof(tBTA_JV), NULL, NULL); + status = btc_transfer_context(&msg, slot->alarm_arg, sizeof(tBTA_JV), NULL, NULL); - if (arg) { - free(arg); + if (slot->alarm_arg) { + free(slot->alarm_arg); + slot->alarm_arg = NULL; } if (status != BT_STATUS_SUCCESS) { @@ -758,6 +778,7 @@ void btc_l2cap_cb_handler(btc_msg_t *msg) break; case BTA_JV_DISABLE_EVT: param.uninit.status = ESP_BT_L2CAP_SUCCESS; + l2cap_free_pending_slots(); BTA_JvFree(); osi_mutex_free(&l2cap_local_param.l2cap_slot_mutex); if (l2cap_local_param.tx_event_group) { @@ -818,9 +839,11 @@ void btc_l2cap_cb_handler(btc_msg_t *msg) break; } memcpy(p_arg, p_data, sizeof(tBTA_JV)); + slot->alarm_arg = (void *)p_arg; if ((slot->close_alarm = - osi_alarm_new("slot", close_timeout_handler, (void *)p_arg, VFS_CLOSE_TIMEOUT)) == NULL) { + osi_alarm_new("slot", close_timeout_handler, (void *)slot, VFS_CLOSE_TIMEOUT)) == NULL) { free(p_arg); + slot->alarm_arg = NULL; param.close.status = ESP_BT_L2CAP_NO_RESOURCE; osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); BTC_TRACE_ERROR("%s unable to malloc slot close_alarm!", __func__); @@ -828,6 +851,7 @@ void btc_l2cap_cb_handler(btc_msg_t *msg) } if (osi_alarm_set(slot->close_alarm, VFS_CLOSE_TIMEOUT) != OSI_ALARM_ERR_PASS) { free(p_arg); + slot->alarm_arg = NULL; osi_alarm_free(slot->close_alarm); param.close.status = ESP_BT_L2CAP_BUSY; osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); @@ -882,7 +906,6 @@ void btc_l2cap_cb_handler(btc_msg_t *msg) fixed_queue_enqueue(slot->rx.queue, p_data_buf, FIXED_QUEUE_MAX_TIMEOUT); } else { osi_free(p_data_buf); - break; } } osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); @@ -921,12 +944,11 @@ void btc_l2cap_cb_handler(btc_msg_t *msg) break; // to do disconnect } memset(p_data_buf, 0, count + sizeof(BT_HDR)); - p_data_buf->len = BTA_JvL2capRead(p_data->data_ind.handle, slot->id, p_data_buf->data, count); + p_data_buf->len = BTA_JvL2capRead(p_data->l2c_read.handle, slot->id, p_data_buf->data, count); if (p_data_buf->len > 0) { fixed_queue_enqueue(slot->rx.queue, p_data_buf, FIXED_QUEUE_MAX_TIMEOUT); } else { osi_free(p_data_buf); - break; } } osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); @@ -1036,7 +1058,7 @@ static ssize_t l2cap_vfs_write(int fd, const void * data, size_t size) if (!enqueue_status) { BTC_TRACE_DEBUG("%s tx_len:%d, fd:%d\n", __func__, fixed_queue_length(slot->tx.queue), fd); osi_mutex_unlock(&l2cap_local_param.l2cap_slot_mutex); - //block untill under water level, be closed or time out + //block until under water level, be closed or time out tx_event_group_val = xEventGroupWaitBits(l2cap_local_param.tx_event_group, SLOT_WRITE_BIT(serial) | SLOT_CLOSE_BIT(serial), pdTRUE, pdFALSE, VFS_WRITE_TIMEOUT / portTICK_PERIOD_MS); diff --git a/components/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c b/components/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c index c67dd71203..6eaf6cfb52 100644 --- a/components/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c +++ b/components/bt/host/bluedroid/btc/profile/std/sdp/btc_sdp.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -114,6 +114,44 @@ static void set_sdp_handle(int id, int handle) osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); } + +static bool get_sdp_record_by_handle(int handle, bluetooth_sdp_record* record) +{ + sdp_slot_t *slot = NULL; + + osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); + + for (int i = 0; i < SDP_MAX_RECORDS; i++) { + slot = sdp_local_param.sdp_slots[i]; + if ((slot != NULL) && (slot->sdp_handle == handle)) { + memcpy(record, slot->record_data, sizeof(bluetooth_sdp_record)); + osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); + return true; + } + } + + osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); + return false; +} + +static int get_sdp_slot_id_by_handle(int handle) +{ + sdp_slot_t *slot = NULL; + + osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); + + for (int i = 0; i < SDP_MAX_RECORDS; i++) { + slot = sdp_local_param.sdp_slots[i]; + if ((slot != NULL) && (slot->sdp_handle == handle)) { + osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); + return i; + } + } + + osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex); + return -1; +} + static sdp_slot_t *start_create_sdp(int id) { sdp_slot_t *sdp_slot = NULL; @@ -247,8 +285,8 @@ static int free_sdp_slot(int id) // Record have already been freed handle = -1; } - osi_free(slot); - slot = NULL; + osi_free(sdp_local_param.sdp_slots[id]); + sdp_local_param.sdp_slots[id] = NULL; return handle; } @@ -257,7 +295,6 @@ static int free_sdp_slot(int id) static int add_raw_sdp(const bluetooth_sdp_record* rec) { tSDP_PROTOCOL_ELEM protoList [2]; - UINT16 service = 0; UINT16 browse = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP; bool status = true; // Buffer capable to hold 2, 4 and 16-byte UUIDs @@ -273,18 +310,15 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec) return sdp_handle; } - if (rec->hdr.bt_uuid.len == 16) { - memcpy(&service, &rec->hdr.bt_uuid.uuid.uuid128[2], sizeof(service)); - UINT8_TO_BE_STREAM(p_temp, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES); - ARRAY_TO_BE_STREAM(p_temp, rec->hdr.bt_uuid.uuid.uuid128, LEN_UUID_128); - } else if (rec->hdr.bt_uuid.len == 2) { - memcpy(&service, &rec->hdr.bt_uuid.uuid.uuid16, sizeof(service)); - UINT8_TO_BE_STREAM(p_temp, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES); - UINT16_TO_BE_STREAM(p_temp, rec->hdr.bt_uuid.uuid.uuid16); - } else if (rec->hdr.bt_uuid.len == 4) { - memcpy(&service, &rec->hdr.bt_uuid.uuid.uuid16, sizeof(service)); - UINT8_TO_BE_STREAM(p_temp, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES); - UINT32_TO_BE_STREAM(p_temp, rec->hdr.bt_uuid.uuid.uuid32); + if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_16) { + UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES); + UINT16_TO_BE_STREAM (p_temp, rec->hdr.bt_uuid.uuid.uuid16); + } else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_32) { + UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_FOUR_BYTES); + UINT32_TO_BE_STREAM (p_temp, rec->hdr.bt_uuid.uuid.uuid32); + } else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_128) { + UINT8_TO_BE_STREAM (p_temp, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES); + ARRAY_TO_BE_STREAM (p_temp, rec->hdr.bt_uuid.uuid.uuid128, LEN_UUID_128); } else { SDP_DeleteRecord(sdp_handle); sdp_handle = 0; @@ -331,7 +365,13 @@ static int add_raw_sdp(const bluetooth_sdp_record* rec) sdp_handle = 0; BTC_TRACE_ERROR("%s() FAILED, status = %d", __func__, status); } else { - bta_sys_add_uuid(service); + if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_16) { + bta_sys_add_uuid(rec->hdr.bt_uuid.uuid.uuid16); + } else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_32) { + bta_sys_add_uuid_32(rec->hdr.bt_uuid.uuid.uuid32); + } else if (rec->hdr.bt_uuid.len == ESP_UUID_LEN_128) { + bta_sys_add_uuid_128((UINT8 *)&rec->hdr.bt_uuid.uuid.uuid128); + } BTC_TRACE_DEBUG("%s(): SDP Registered (handle 0x%08x)", __func__, sdp_handle); } @@ -842,7 +882,8 @@ static void btc_sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, void* user_da switch (event) { case BTA_SDP_CREATE_RECORD_USER_EVT: { if (p_data->status == BTA_SDP_SUCCESS) { - if(btc_handle_create_record_event((int)user_data) < 0) { + p_data->sdp_create_record.handle = btc_handle_create_record_event((int)user_data); + if (p_data->sdp_create_record.handle < 0) { p_data->status = BTA_SDP_FAILURE; } } @@ -981,9 +1022,31 @@ static void btc_sdp_remove_record(btc_sdp_args_t *arg) break; } + bluetooth_sdp_record rec; + if (get_sdp_record_by_handle(arg->remove_record.record_handle, &rec)) { + if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_16) { + bta_sys_remove_uuid(rec.hdr.bt_uuid.uuid.uuid16); + } else if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_32) { + bta_sys_remove_uuid_32(rec.hdr.bt_uuid.uuid.uuid32); + } else if (rec.hdr.bt_uuid.len == ESP_UUID_LEN_128) { + bta_sys_remove_uuid_128((UINT8 *)&rec.hdr.bt_uuid.uuid.uuid128); + } + } else { + BTC_TRACE_ERROR("%s SDP record with handle %d not found", + __func__, arg->remove_record.record_handle); + ret = ESP_SDP_NO_CREATE_RECORD; + break; + } + /* Get the Record handle, and free the slot */ /* The application layer record_handle is equivalent to the id of the btc layer */ - handle = free_sdp_slot(arg->remove_record.record_handle); + int slot = get_sdp_slot_id_by_handle(arg->remove_record.record_handle); + if (slot < 0) { + ret = ESP_SDP_NO_CREATE_RECORD; + break; + } + + handle = free_sdp_slot(slot); BTC_TRACE_DEBUG("Sdp Server %s id=%d to handle=0x%08x", __func__, arg->remove_record.record_handle, handle); diff --git a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c index 6a366c65ab..cf33449448 100644 --- a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c +++ b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c @@ -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 */ @@ -63,6 +63,7 @@ typedef struct { int fd; uint8_t *write_data; osi_alarm_t *close_alarm; + void *alarm_arg; esp_spp_role_t role; esp_spp_sec_t security; esp_bd_addr_t addr; @@ -149,6 +150,7 @@ static spp_slot_t *spp_malloc_slot(void) (*slot)->write_data_len = 0; (*slot)->is_writing = false; (*slot)->close_alarm = NULL; + (*slot)->alarm_arg = NULL; /* clear the old event bits */ if (spp_local_param.tx_event_group) { xEventGroupClearBits(spp_local_param.tx_event_group, SLOT_WRITE_BIT(i) | SLOT_CLOSE_BIT(i)); @@ -252,15 +254,17 @@ static void close_timeout_handler(void *arg) { btc_msg_t msg; bt_status_t status; + spp_slot_t *slot = (spp_slot_t *)arg; msg.sig = BTC_SIG_API_CB; msg.pid = BTC_PID_SPP; msg.act = BTA_JV_RFCOMM_CLOSE_EVT; - status = btc_transfer_context(&msg, arg, sizeof(tBTA_JV), NULL, NULL); + status = btc_transfer_context(&msg, slot->alarm_arg, sizeof(tBTA_JV), NULL, NULL); - if (arg) { - osi_free(arg); + if (slot->alarm_arg) { + osi_free(slot->alarm_arg); + slot->alarm_arg = NULL; } if (status != BT_STATUS_SUCCESS) { @@ -284,10 +288,26 @@ static void spp_free_slot(spp_slot_t *slot) free_slot_data(&slot->rx); if (slot->close_alarm) { osi_alarm_free(slot->close_alarm); + if (slot->alarm_arg) { + osi_free(slot->alarm_arg); + slot->alarm_arg = NULL; + } } osi_free(slot); } +static void spp_free_pending_slots(void) +{ + spp_slot_t *slot = NULL; + for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { + slot = spp_local_param.spp_slots[i]; + if (slot) { + BTC_TRACE_WARNING("%s found slot(rfc_handle=0x%x) pending to close, close it now!", __func__, slot->rfc_handle); + spp_free_slot(slot); + } + } +} + static inline void btc_spp_cb_to_app(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { esp_spp_cb_t btc_spp_cb = (esp_spp_cb_t)btc_profile_cb_get(BTC_PID_SPP); @@ -404,19 +424,6 @@ static void *btc_spp_rfcomm_inter_cb(tBTA_JV_EVT event, tBTA_JV *p_data, void *u slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_data->rfc_open.handle); BTA_JvSetPmProfile(p_data->rfc_open.handle, BTA_JV_PM_ID_1, BTA_JV_CONN_OPEN); break; - case BTA_JV_RFCOMM_CLOSE_EVT: - slot = spp_find_slot_by_id(id); - if (!slot) { - BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); - p_data->rfc_close.status = ESP_SPP_NO_CONNECTION; - break; - } - if (slot->rfc_handle && p_data->rfc_close.port_status != PORT_LOCAL_CLOSED) { - BTA_JvRfcommClose(slot->rfc_handle, NULL, (void *)slot->id); - } - p_data->rfc_close.status = BTA_JV_SUCCESS; - p_data->rfc_close.user_data = (void *)(uintptr_t)slot->id; - break; case BTA_JV_RFCOMM_DATA_IND_EVT: break; case BTA_JV_FREE_SCN_EVT: @@ -588,8 +595,7 @@ static void btc_spp_uninit(void) // first, remove all connection for (size_t i = 1; i <= MAX_RFC_PORTS; i++) { if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->is_server) { - BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, - (void *)spp_local_param.spp_slots[i]->id); + BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, (void *)spp_local_param.spp_slots[i]->id); } } // second, remove all server @@ -707,7 +713,7 @@ static void btc_spp_disconnect(btc_spp_args_t *arg) ret = ESP_SPP_NO_CONNECTION; break; } - BTA_JvRfcommClose(arg->disconnect.handle, (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, (void *)slot->id); + BTA_JvRfcommClose(arg->disconnect.handle, (void *)slot->id); osi_mutex_unlock(&spp_local_param.spp_slot_mutex); } while(0); @@ -815,9 +821,7 @@ static void btc_spp_stop_srv(btc_spp_args_t *arg) if (spp_local_param.spp_slots[i] != NULL && !spp_local_param.spp_slots[i]->is_server && spp_local_param.spp_slots[i]->sdp_handle > 0 && spp_local_param.spp_slots[i]->scn == srv_scn_arr[j]) { - BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, - (tBTA_JV_RFCOMM_CBACK *)btc_spp_rfcomm_inter_cb, - (void *)spp_local_param.spp_slots[i]->id); + BTA_JvRfcommClose(spp_local_param.spp_slots[i]->rfc_handle, (void *)spp_local_param.spp_slots[i]->id); } } } @@ -1155,28 +1159,27 @@ void btc_spp_cb_handler(btc_msg_t *msg) osi_mutex_unlock(&spp_local_param.spp_slot_mutex); break; case BTA_JV_RFCOMM_CLOSE_EVT: - param.close.status = p_data->rfc_close.status; + param.close.status = BTA_JV_SUCCESS; param.close.port_status = p_data->rfc_close.port_status; param.close.handle = p_data->rfc_close.handle; param.close.async = p_data->rfc_close.async; if (spp_local_param.spp_mode == ESP_SPP_MODE_CB) { - btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, ¶m); osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); - uint32_t id = (uintptr_t)p_data->rfc_close.user_data; - slot = spp_find_slot_by_id(id); + slot = spp_find_slot_by_handle(p_data->rfc_close.handle); if (!slot) { + param.close.status = ESP_SPP_NO_CONNECTION; osi_mutex_unlock(&spp_local_param.spp_slot_mutex); BTC_TRACE_ERROR("%s unable to find RFCOMM slot, event:%d!", __func__, event); break; } spp_free_slot(slot); osi_mutex_unlock(&spp_local_param.spp_slot_mutex); + btc_spp_cb_to_app(ESP_SPP_CLOSE_EVT, ¶m); } else { bool need_call = true; do { osi_mutex_lock(&spp_local_param.spp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT); - uint32_t id = (uintptr_t)p_data->rfc_close.user_data; - slot = spp_find_slot_by_id(id); + slot = spp_find_slot_by_handle(p_data->rfc_close.handle); if (!slot) { param.close.status = ESP_SPP_NO_CONNECTION; osi_mutex_unlock(&spp_local_param.spp_slot_mutex); @@ -1193,9 +1196,11 @@ void btc_spp_cb_handler(btc_msg_t *msg) break; } memcpy(p_arg, p_data, sizeof(tBTA_JV)); + slot->alarm_arg = (void *)p_arg; if ((slot->close_alarm = - osi_alarm_new("slot", close_timeout_handler, (void *)p_arg, VFS_CLOSE_TIMEOUT)) == NULL) { + osi_alarm_new("slot", close_timeout_handler, (void *)slot, VFS_CLOSE_TIMEOUT)) == NULL) { free(p_arg); + slot->alarm_arg = NULL; param.close.status = ESP_SPP_NO_RESOURCE; osi_mutex_unlock(&spp_local_param.spp_slot_mutex); BTC_TRACE_ERROR("%s unable to malloc slot close_alarm!", __func__); @@ -1203,6 +1208,7 @@ void btc_spp_cb_handler(btc_msg_t *msg) } if (osi_alarm_set(slot->close_alarm, VFS_CLOSE_TIMEOUT) != OSI_ALARM_ERR_PASS) { free(p_arg); + slot->alarm_arg = NULL; osi_alarm_free(slot->close_alarm); param.close.status = ESP_SPP_BUSY; osi_mutex_unlock(&spp_local_param.spp_slot_mutex); @@ -1314,6 +1320,7 @@ void btc_spp_cb_handler(btc_msg_t *msg) break; case BTA_JV_DISABLE_EVT: param.uninit.status = ESP_SPP_SUCCESS; + spp_free_pending_slots(); BTA_JvFree(); osi_mutex_free(&spp_local_param.spp_slot_mutex); if (spp_local_param.tx_event_group) { 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 20ac5f88a5..c8464551d9 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 @@ -95,6 +95,13 @@ #define UC_BT_SSP_ENABLED FALSE #endif +//BQB(BT) +#ifdef CONFIG_BT_CLASSIC_BQB_ENABLED +#define UC_BT_CLASSIC_BQB_ENABLED CONFIG_BT_CLASSIC_BQB_ENABLED +#else +#define UC_BT_CLASSIC_BQB_ENABLED FALSE +#endif + //BLE #ifdef CONFIG_BT_BLE_ENABLED #define UC_BT_BLE_ENABLED CONFIG_BT_BLE_ENABLED @@ -124,6 +131,30 @@ #define UC_BT_BLE_42_FEATURES_SUPPORTED FALSE #endif +#ifdef CONFIG_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER +#define UC_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER CONFIG_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER +#else +#define UC_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER FALSE +#endif + +#ifdef CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH +#define UC_BT_BLE_FEAT_PERIODIC_ADV_ENH CONFIG_BT_BLE_FEAT_PERIODIC_ADV_ENH +#else +#define UC_BT_BLE_FEAT_PERIODIC_ADV_ENH FALSE +#endif + +#ifdef CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH +#define UC_BT_BLE_FEAT_CREATE_SYNC_ENH CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH +#else +#define UC_BT_BLE_FEAT_CREATE_SYNC_ENH FALSE +#endif + +#ifdef CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL +#define UC_BT_BLE_HIGH_DUTY_ADV_INTERVAL CONFIG_BT_BLE_HIGH_DUTY_ADV_INTERVAL +#else +#define UC_BT_BLE_HIGH_DUTY_ADV_INTERVAL FALSE +#endif + //GATTS #ifdef CONFIG_BT_GATTS_ENABLE #define UC_BT_GATTS_ENABLE CONFIG_BT_GATTS_ENABLE @@ -145,6 +176,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 @@ -172,7 +210,19 @@ #define UC_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE FALSE #endif -//Device Nane Maximum Length +#ifdef CONFIG_BT_SMP_MAX_BONDS +#define UC_BT_SMP_MAX_BONDS CONFIG_BT_SMP_MAX_BONDS +#else +#define UC_BT_SMP_MAX_BONDS 8 +#endif + +#ifdef CONFIG_BT_BLE_SMP_ID_RESET_ENABLE +#define UC_BT_BLE_SMP_ID_RESET_ENABLE CONFIG_BT_BLE_SMP_ID_RESET_ENABLE +#else +#define UC_BT_BLE_SMP_ID_RESET_ENABLE FALSE +#endif + +//Device Name Maximum Length #ifdef CONFIG_BT_MAX_DEVICE_NAME_LEN #define UC_MAX_LOC_BD_NAME_LEN CONFIG_BT_MAX_DEVICE_NAME_LEN #else @@ -204,7 +254,7 @@ #endif //CONFIG_IDF_TARGET_ESP32 -#if (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3) +#if (CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2) //BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP #ifdef CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP #define UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP @@ -226,7 +276,7 @@ #define UC_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD 20 #endif -#endif //(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3) +#endif //(CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2) //BT ACL CONNECTIONS #ifdef CONFIG_BT_ACL_CONNECTIONS @@ -429,13 +479,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 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 6090cefdf6..eaf71090b1 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -90,49 +90,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_SSP_ENABLED #define BT_SSP_INCLUDED TRUE @@ -192,6 +193,30 @@ #define BLE_42_FEATURE_SUPPORT FALSE #endif +#if (UC_BT_BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER TRUE +#else +#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER FALSE +#endif + +#if (UC_BT_BLE_FEAT_PERIODIC_ADV_ENH == TRUE) +#define BLE_FEAT_PERIODIC_ADV_ENH TRUE +#else +#define BLE_FEAT_PERIODIC_ADV_ENH FALSE +#endif + +#if (UC_BT_BLE_FEAT_CREATE_SYNC_ENH == TRUE) +#define BLE_FEAT_CREATE_SYNC_ENH TRUE +#else +#define BLE_FEAT_CREATE_SYNC_ENH FALSE +#endif + +#if (UC_BT_BLE_HIGH_DUTY_ADV_INTERVAL == TRUE) +#define BLE_HIGH_DUTY_ADV_INTERVAL TRUE +#else +#define BLE_HIGH_DUTY_ADV_INTERVAL FALSE +#endif + #if (UC_BT_BLE_RPA_SUPPORTED == TRUE) #define CONTROLLER_RPA_LIST_ENABLE TRUE #else @@ -228,6 +253,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) @@ -246,6 +277,12 @@ #define SMP_SLAVE_CON_PARAMS_UPD_ENABLE FALSE #endif /* UC_BT_SMP_SLAVE_CON_PARAMS_UPD_ENABLE */ +#if (UC_BT_BLE_SMP_ID_RESET_ENABLE) +#define BLE_SMP_ID_RESET_ENABLE TRUE +#else +#define BLE_SMP_ID_RESET_ENABLE FALSE +#endif + #ifdef UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP #define BLE_ADV_REPORT_FLOW_CONTROL (UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP && BLE_INCLUDED) #endif /* UC_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP */ @@ -519,7 +556,13 @@ #define BTM_BLE_PRIVATE_ADDR_INT UC_BT_BLE_RPA_TIMEOUT #endif -/* This feature is used to eanble interleaved scan*/ +#if (UC_BT_CLASSIC_BQB_ENABLED == TRUE) +#define BT_CLASSIC_BQB_INCLUDED TRUE +#else +#define BT_CLASSIC_BQB_INCLUDED FALSE +#endif + +/* This feature is used to enable interleaved scan*/ #ifndef BTA_HOST_INTERLEAVE_SEARCH #define BTA_HOST_INTERLEAVE_SEARCH FALSE #endif @@ -849,13 +892,9 @@ #define BTM_DEFAULT_SCO_MODE 2 #endif -/* The number of security records for peer devices. 100 AS Default*/ +/* The number of security records for peer devices. 15 AS Default*/ #ifndef BTM_SEC_MAX_DEVICE_RECORDS -#if SMP_INCLUDED == TRUE -#define BTM_SEC_MAX_DEVICE_RECORDS 15 // 100 -#else -#define BTM_SEC_MAX_DEVICE_RECORDS 8 -#endif /* SMP_INCLUDED == TRUE */ +#define BTM_SEC_MAX_DEVICE_RECORDS UC_BT_SMP_MAX_BONDS #endif /* The number of security records for services. 32 AS Default*/ @@ -973,7 +1012,7 @@ /* TRUE to include Sniff Subrating */ #if (BTA_DM_PM_INCLUDED == TRUE) #ifndef BTM_SSR_INCLUDED -#define BTM_SSR_INCLUDED TRUE +#define BTM_SSR_INCLUDED FALSE #endif #endif /* BTA_DM_PM_INCLUDED */ @@ -1339,7 +1378,7 @@ #define GATT_CONFORMANCE_TESTING FALSE #endif -/* number of background connection device allowence, ideally to be the same as WL size +/* number of background connection device allowance, ideally to be the same as WL size */ #ifndef GATT_MAX_BG_CONN_DEV #define GATT_MAX_BG_CONN_DEV 8 /*MAX is 32*/ @@ -1430,6 +1469,12 @@ #define SDP_INCLUDED FALSE #endif +#if (SDP_INCLUDED == TRUE) && (BTA_JV_INCLUDED == TRUE) && (BT_CLASSIC_BQB_INCLUDED == TRUE) +#define BT_SDP_BQB_INCLUDED TRUE +#else +#define BT_SDP_BQB_INCLUDED FALSE +#endif + /* This is set to enable SDP server functionality. */ #ifndef SDP_SERVER_ENABLED #if SDP_INCLUDED == TRUE @@ -1498,7 +1543,7 @@ /* The maximum number of simultaneous client and server connections. */ #ifndef SDP_MAX_CONNECTIONS -#define SDP_MAX_CONNECTIONS 2 // 4 +#define SDP_MAX_CONNECTIONS 4 #endif /* The MTU size for the L2CAP configuration. */ @@ -1530,6 +1575,12 @@ #define RFCOMM_INCLUDED FALSE #endif +#if (RFCOMM_INCLUDED == TRUE) && (BT_CLASSIC_BQB_INCLUDED == TRUE) +#define BT_RFCOMM_BQB_INCLUDED TRUE +#else +#define BT_RFCOMM_BQB_INCLUDED FALSE +#endif + #ifndef BTA_JV_RFCOMM_INCLUDED #define BTA_JV_RFCOMM_INCLUDED FALSE #endif @@ -1957,6 +2008,24 @@ #define PAN_NAP_SECURITY_LEVEL 0 #endif +/****************************************************************************** +** +** HFP +** +******************************************************************************/ + +#if (BTC_HF_INCLUDED == TRUE) && (BT_CLASSIC_BQB_INCLUDED == TRUE) +#define BT_HF_AG_BQB_INCLUDED TRUE +#else +#define BT_HF_AG_BQB_INCLUDED FALSE +#endif + +#if (BTC_HF_CLIENT_INCLUDED == TRUE) && (BT_CLASSIC_BQB_INCLUDED == TRUE) +#define BT_HF_CLIENT_BQB_INCLUDED TRUE +#else +#define BT_HF_CLIENT_BQB_INCLUDED FALSE +#endif + /****************************************************************************** ** ** GAP @@ -2021,6 +2090,12 @@ #define HID_DEV_FLUSH_TO 0xffff #endif +#if (BTA_HD_INCLUDED == TRUE) && (HID_DEV_INCLUDED == TRUE) && (BT_CLASSIC_BQB_INCLUDED == TRUE) +#define BT_HID_DEVICE_BQB_INCLUDED TRUE +#else +#define BT_HID_DEVICE_BQB_INCLUDED FALSE +#endif + /************************************************************************* ** Definitions for Both HID-Host & Device */ @@ -2070,6 +2145,12 @@ #define A2D_INCLUDED FALSE #endif +#if (BTC_AV_SRC_INCLUDED == TRUE) && (BT_CLASSIC_BQB_INCLUDED == TRUE) +#define A2D_SRC_BQB_INCLUDED TRUE +#else +#define A2D_SRC_BQB_INCLUDED FALSE +#endif + /****************************************************************************** ** ** AVCTP @@ -2303,13 +2384,6 @@ The maximum number of payload octets that the local device can receive in a sing #define HEAP_ALLOCATION_FROM_SPIRAM_FIRST FALSE #endif -// TODO: add menuconfig and api for periodic adv sync transfer -#if (BLE_50_FEATURE_SUPPORT) -#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER TRUE -#else -#define BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER FALSE -#endif - #include "common/bt_trace.h" #endif /* BT_TARGET_H */ diff --git a/components/bt/host/bluedroid/device/controller.c b/components/bt/host/bluedroid/device/controller.c index 3a813d9a87..8d2349b4cd 100644 --- a/components/bt/host/bluedroid/device/controller.c +++ b/components/bt/host/bluedroid/device/controller.c @@ -30,7 +30,7 @@ #include "device/version.h" #include "osi/future.h" #if (BLE_50_FEATURE_SUPPORT == TRUE) -const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x0f\xff\xff" }; +const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\xff\xff\xff" }; #else const bt_event_mask_t BLE_EVENT_MASK = { "\x00\x00\x00\x00\x00\x00\x06\x7f" }; #endif diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index 1bf02aa1e3..96007404b5 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -31,14 +31,11 @@ #include "esp_bt.h" #include "stack/hcimsgs.h" -#if SOC_ESP_NIMBLE_CONTROLLER -#include "nimble/ble_hci_trans.h" -#endif - #if (C2H_FLOW_CONTROL_INCLUDED == TRUE) #include "l2c_int.h" #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE #include "stack/hcimsgs.h" +#include "hci_log/bt_hci_log.h" #define HCI_BLE_EVENT 0x3e #define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2) @@ -138,15 +135,20 @@ static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thr static void hci_hal_env_deinit(void) { - fixed_queue_free(hci_hal_env.rx_q, osi_free_func); - hci_hal_env.rx_q = NULL; + fixed_queue_t *rx_q = hci_hal_env.rx_q; + struct pkt_queue *adv_rpt_q = hci_hal_env.adv_rpt_q; + struct osi_event *upstream_data_ready = hci_hal_env.upstream_data_ready; - pkt_queue_destroy(hci_hal_env.adv_rpt_q, NULL); + hci_hal_env.rx_q = NULL; hci_hal_env.adv_rpt_q = NULL; - - osi_event_delete(hci_hal_env.upstream_data_ready); hci_hal_env.upstream_data_ready = NULL; + fixed_queue_free(rx_q, osi_free_func); + + pkt_queue_destroy(adv_rpt_q, NULL); + + osi_event_delete(upstream_data_ready); + #if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) hci_hal_env.cmd_buf_in_use = true; osi_alarm_cancel(hci_hal_env.adv_flow_monitor); @@ -206,6 +208,9 @@ static uint16_t transmit_data(serial_data_type_t type, BTTRC_DUMP_BUFFER("Transmit Pkt", data, length); +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_record_hci_data(data[0], &data[1], length - 1); +#endif // TX Data to target esp_vhci_host_send_packet(data, length); @@ -432,7 +437,7 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet) uint8_t len = 0; STREAM_TO_UINT8(len, stream); #endif - HCI_TRACE_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n", + HCI_TRACE_ERROR("Workaround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n", packet->len, len); osi_free(packet); return; @@ -531,6 +536,26 @@ static void host_send_pkt_available_cb(void) hci_downstream_data_post(OSI_THREAD_MAX_TIMEOUT); } + +void bt_record_hci_data(uint8_t *data, uint16_t len) +{ +#if (BT_HCI_LOG_INCLUDED == TRUE) + if ((data[0] == DATA_TYPE_EVENT) && (data[1] == HCI_BLE_EVENT) && ((data[3] == HCI_BLE_ADV_PKT_RPT_EVT) || (data[3] == HCI_BLE_DIRECT_ADV_EVT) +#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) + || (data[3] == HCI_BLE_ADV_DISCARD_REPORT_EVT) +#endif // (BLE_ADV_REPORT_FLOW_CONTROL == TRUE) + #if (BLE_50_FEATURE_SUPPORT == TRUE) + || (data[3] == HCI_BLE_EXT_ADV_REPORT_EVT) || (data[3] == HCI_BLE_PERIOD_ADV_REPORT_EVT) +#endif // (BLE_50_FEATURE_SUPPORT == TRUE) + )) { + bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2); + } else { + uint8_t data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]); + bt_hci_log_record_hci_data(data_type, &data[1], len - 1); + } +#endif // (BT_HCI_LOG_INCLUDED == TRUE) +} + static int host_recv_pkt_cb(uint8_t *data, uint16_t len) { //Target has packet to host, malloc new buffer for packet @@ -542,13 +567,15 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) return 0; } + bt_record_hci_data(data, len); + bool is_adv_rpt = host_recv_adv_packet(data); if (!is_adv_rpt) { pkt_size = BT_HDR_SIZE + len; pkt = (BT_HDR *) osi_calloc(pkt_size); if (!pkt) { - HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__); + HCI_TRACE_ERROR("%s couldn't acquire memory for inbound data buffer.\n", __func__); assert(0); } @@ -590,39 +617,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) return 0; } -#if SOC_ESP_NIMBLE_CONTROLLER -int -ble_hs_hci_rx_evt(uint8_t *hci_ev, void *arg) -{ - if(esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) { - return 0; - } - uint16_t len = hci_ev[1] + 3; - uint8_t *data = (uint8_t *)malloc(len); - data[0] = 0x04; - memcpy(&data[1], hci_ev, len - 1); - ble_hci_trans_buf_free(hci_ev); - host_recv_pkt_cb(data, len); - free(data); - return 0; -} - - -int -ble_hs_rx_data(struct os_mbuf *om, void *arg) -{ - uint16_t len = om->om_len + 1; - uint8_t *data = (uint8_t *)malloc(len); - data[0] = 0x02; - os_mbuf_copydata(om, 0, len - 1, &data[1]); - host_recv_pkt_cb(data, len); - free(data); - os_mbuf_free_chain(om); - return 0; -} - -#endif static const esp_vhci_host_callback_t vhci_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 3f67b84825..cd7119e2c7 100644 --- a/components/bt/host/bluedroid/hci/hci_layer.c +++ b/components/bt/host/bluedroid/hci/hci_layer.c @@ -140,6 +140,10 @@ void hci_shut_down(void) bool hci_downstream_data_post(uint32_t timeout) { + if (hci_host_env.downstream_data_ready == NULL) { + HCI_TRACE_WARNING("%s downstream_data_ready event not created", __func__); + return false; + } return osi_thread_post_event(hci_host_env.downstream_data_ready, timeout); } @@ -259,7 +263,7 @@ static void transmit_command( // in case the upper layer didn't already command->event = MSG_STACK_TO_HC_HCI_CMD; - HCI_TRACE_DEBUG("HCI Enqueue Comamnd opcode=0x%x\n", metadata->opcode); + HCI_TRACE_DEBUG("HCI Enqueue Command opcode=0x%x\n", metadata->opcode); BTTRC_DUMP_BUFFER(NULL, command->data + command->offset, command->len); fixed_pkt_queue_enqueue(hci_host_env.command_queue, linked_pkt, FIXED_PKT_QUEUE_MAX_TIMEOUT); @@ -405,6 +409,7 @@ static void command_timed_out(void *context) { hci_cmd_metadata_t *metadata = (hci_cmd_metadata_t *)(wait_entry->data); HCI_TRACE_ERROR("%s hci layer timeout waiting for response to a command. opcode: 0x%x", __func__, metadata->opcode); + UNUSED(metadata); } } diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index 58f6f21b8e..4b7e7eedce 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -2117,6 +2117,70 @@ tBTM_STATUS BTM_ReadTxPower (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_C return (BTM_UNKNOWN_ADDR); } +tBTM_STATUS BTM_SetAclPktTypes(BD_ADDR remote_bda, UINT16 pkt_types, tBTM_CMPL_CB *p_cb) +{ +#if CLASSIC_BT_INCLUDED == TRUE + tBTM_STATUS ret = BTM_UNKNOWN_ADDR; + tACL_CONN *p; + tBTM_SET_ACL_PKT_TYPES_RESULTS result; + + /* If someone already waiting on the version, do not allow another */ + if (btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb) { + result.status = HCI_ERR_REPEATED_ATTEMPTS; + (*p_cb)(&result); + return (BTM_BUSY);; + } + + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR); + + if (p != (tACL_CONN *)NULL) { + btu_start_timer (&btm_cb.devcb.set_acl_pkt_types_timer, BTU_TTYPE_BTM_ACL, + BTM_DEV_REPLY_TIMEOUT); + + btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb = p_cb; + if (btm_set_packet_types(p, pkt_types) != BTM_CMD_STARTED) { + btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb = NULL; + btu_stop_timer (&btm_cb.devcb.set_acl_pkt_types_timer); + result.status = HCI_ERR_MEMORY_FULL; + (*p_cb)(&result); + ret = BTM_NO_RESOURCES; + } else { + ret = BTM_CMD_STARTED; + } + } + /* If here, no BD Addr found */ + return ret; +#else + return BTM_NO_RESOURCES; +#endif +} + +void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types) +{ +#if CLASSIC_BT_INCLUDED == TRUE + BTM_TRACE_DEBUG ("btm_acl_pkt_types_changed\n"); + tACL_CONN *conn = NULL; + tBTM_SET_ACL_PKT_TYPES_RESULTS results; + btu_stop_timer (&btm_cb.devcb.set_acl_pkt_types_timer); + + /* If there is a callback registered for packet types changed, call it */ + if (btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb) { + if (status == HCI_SUCCESS) { + results.status = BTM_SUCCESS; + } else { + results.status = BTM_BAD_VALUE_RET; + } + results.pkt_types = pkt_types; + /* Search through the list of active channels for the correct BD Addr */ + if ((conn = btm_handle_to_acl(handle)) != NULL) { + memcpy(results.rem_bda, conn->remote_addr, BD_ADDR_LEN); + (*btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb)(&results); + } + btm_cb.devcb.p_set_acl_pkt_types_cmpl_cb = NULL; + } +#endif +} + #if (BLE_INCLUDED == TRUE) tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb) { @@ -2659,37 +2723,33 @@ void btm_acl_connected(BD_ADDR bda, UINT16 handle, UINT8 link_type, UINT8 enc_mo *******************************************************************************/ void btm_acl_disconnected(UINT16 handle, UINT8 reason) { - BOOLEAN need_report = TRUE; + + /* Report BR/EDR ACL disconnection result to upper layer */ + tACL_CONN *conn = btm_handle_to_acl(handle); + if (conn) { +#if BLE_INCLUDED == TRUE + if (conn->transport == BT_TRANSPORT_BR_EDR) +#endif + { + tBTM_ACL_LINK_STAT_EVENT_DATA evt_data = { + .event = BTM_ACL_DISCONN_CMPL_EVT, + .link_act.disconn_cmpl.reason = reason, + .link_act.disconn_cmpl.handle = handle, + }; + bdcpy(evt_data.link_act.disconn_cmpl.bd_addr, conn->remote_addr); + btm_acl_link_stat_report(&evt_data); + } + } #if BTM_SCO_INCLUDED == TRUE /* If L2CAP doesn't know about it, send it to SCO */ if (!l2c_link_hci_disc_comp (handle, reason)) { btm_sco_removed (handle, reason); - need_report = FALSE; } #else l2c_link_hci_disc_comp(handle, reason); #endif /* BTM_SCO_INCLUDED */ - if (need_report) { - /* Report BR/EDR ACL disconnection result to upper layer */ - tACL_CONN *conn = btm_handle_to_acl(handle); - if (conn) { -#if BLE_INCLUDED == TRUE - if (conn->transport == BT_TRANSPORT_BR_EDR) -#endif - { - tBTM_ACL_LINK_STAT_EVENT_DATA evt_data = { - .event = BTM_ACL_DISCONN_CMPL_EVT, - .link_act.disconn_cmpl.reason = reason, - .link_act.disconn_cmpl.handle = handle, - }; - bdcpy(evt_data.link_act.disconn_cmpl.bd_addr, conn->remote_addr); - btm_acl_link_stat_report(&evt_data); - } - } - } - #if (SMP_INCLUDED == TRUE) /* Notify security manager */ btm_sec_disconnected(handle, reason); diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index 69e5404a2e..0d1e8fd626 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -217,7 +217,7 @@ void BTM_BleLoadLocalKeys(UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key) break; default: - BTM_TRACE_ERROR("unknow local key type: %d", key_type); + BTM_TRACE_ERROR("unknown local key type: %d", key_type); break; } } @@ -694,7 +694,7 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR BTM_TRACE_DEBUG ("btm_find_dev_type - unknown device, BR/EDR assumed"); } } - } else { /* there is a security device record exisitng */ + } else { /* there is a security device record existing */ /* new inquiry result, overwrite device type in security device record */ if (p_inq_info) { p_dev_rec->device_type = p_inq_info->results.device_type; @@ -707,7 +707,7 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR } else if (memcmp(p_dev_rec->ble.pseudo_addr, remote_bda, BD_ADDR_LEN) == 0) { *p_dev_type = BT_DEVICE_TYPE_BLE; *p_addr_type = p_dev_rec->ble.ble_addr_type; - } else { /* matching static adddress only */ + } else { /* matching static address only */ *p_dev_type = BT_DEVICE_TYPE_BREDR; *p_addr_type = BLE_ADDR_PUBLIC; } @@ -1061,7 +1061,7 @@ tBTM_SEC_ACTION btm_ble_determine_security_act(BOOLEAN is_originator, BD_ADDR bd ** LE link for LE COC. ** ** Parameter bdaddr: remote device address. -** psm : PSM of the LE COC sevice. +** psm : PSM of the LE COC service. ** is_originator: TRUE if outgoing connection. ** p_callback : Pointer to the callback function. ** p_ref_data : Pointer to be returned along with the callback. @@ -1078,7 +1078,7 @@ BOOLEAN btm_ble_start_sec_check(BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_originat /* If there is no application registered with this PSM do not allow connection */ if (!p_serv_rec) { - BTM_TRACE_WARNING ("%s PSM: %d no application registerd", __func__, psm); + BTM_TRACE_WARNING ("%s PSM: %d no application registered", __func__, psm); (*p_callback) (bd_addr, BT_TRANSPORT_LE, p_ref_data, BTM_MODE_UNSUPPORTED); return FALSE; } @@ -1151,7 +1151,7 @@ void btm_ble_rand_enc_complete (UINT8 *p, UINT16 op_code, tBTM_RAND_ENC_CB *p_en /* If there was a callback address for vcs complete, call it */ if (p_enc_cplt_cback && p) { - /* Pass paramters to the callback function */ + /* Pass parameters to the callback function */ STREAM_TO_UINT8(params.status, p); /* command status */ if (params.status == HCI_SUCCESS) { @@ -1208,7 +1208,7 @@ void btm_ble_increment_sign_ctr(BD_ADDR bd_addr, BOOLEAN is_local ) ** Function btm_ble_get_enc_key_type ** ** Description This function is to get the BLE key type that has been exchanged -** in betweem local device and peer device. +** in between local device and peer device. ** ** Returns p_key_type: output parameter to carry the key type value. ** @@ -1235,7 +1235,7 @@ BOOLEAN btm_ble_get_enc_key_type(BD_ADDR bd_addr, UINT8 *p_key_types) ** ** Description This function is called to read the local DIV ** -** Returns TRUE - if a valid DIV is availavle +** Returns TRUE - if a valid DIV is available *******************************************************************************/ BOOLEAN btm_get_local_div (BD_ADDR bd_addr, UINT16 *p_div) { @@ -1487,7 +1487,7 @@ void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE BTM_TRACE_DEBUG ("dev_rec sec_flags=0x%x", p_dev_rec->sec_flags); - /* currently encrpted */ + /* currently encrypted */ if (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED) { if (p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED) { cur_sec_level = BTM_LE_SEC_AUTHENTICATED; @@ -1691,7 +1691,7 @@ tBTM_STATUS btm_ble_start_encrypt(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk) ** ** Function btm_ble_link_encrypted ** -** Description This function is called when LE link encrption status is changed. +** Description This function is called when LE link encryption status is changed. ** ** Returns void ** @@ -1949,7 +1949,7 @@ static void btm_ble_resolve_random_addr_on_conn_cmpl(void *p_rec, void *p_data) ** Function btm_ble_connected ** ** Description This function is when a LE connection to the peer device is -** establsihed +** established ** ** Returns void ** @@ -2060,7 +2060,7 @@ void btm_ble_conn_complete(UINT8 *p, UINT16 evt_len, BOOLEAN enhanced) peer_addr_type = bda_type; match = btm_identity_addr_to_random_pseudo (bda, &bda_type, FALSE); - /* possiblly receive connection complete with resolvable random on + /* possibly receive connection complete with resolvable random on slave role while the device has been paired */ /* It will cause that scanner doesn't send scan request to advertiser @@ -2143,6 +2143,16 @@ void btm_ble_create_ll_conn_complete (UINT8 status) if (status != HCI_SUCCESS) { btm_ble_set_conn_st(BLE_CONN_IDLE); btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status); + if(l2cb.is_ble_connecting) { + /* see L2CA_CancelBleConnectReq() */ + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(l2cb.ble_connecting_bda, BT_TRANSPORT_LE); + /* Do not remove lcb if an LE link is already up as a peripheral */ + if (p_lcb != NULL && + !(p_lcb->link_role == HCI_ROLE_SLAVE && BTM_ACL_IS_CONNECTED(l2cb.ble_connecting_bda))) { + p_lcb->disc_reason = L2CAP_CONN_CANCEL; + l2cu_release_lcb (p_lcb); + } + } } } @@ -2300,7 +2310,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) ** Function BTM_BleDataSignature ** ** Description This function is called to sign the data using AES128 CMAC -** algorith. +** algorithm. ** ** Parameter bd_addr: target device the data to be signed for. ** p_text: singing data @@ -2308,7 +2318,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) ** signature: output parameter where data signature is going to ** be stored. ** -** Returns TRUE if signing sucessul, otherwise FALSE. +** Returns TRUE if signing successful, otherwise FALSE. ** *******************************************************************************/ #if (SMP_INCLUDED == TRUE) @@ -2491,7 +2501,7 @@ BOOLEAN BTM_BleSecurityProcedureIsRunning(BD_ADDR bd_addr) ** Function BTM_BleGetSupportedKeySize ** ** Description This function gets the maximum encryption key size in bytes -** the local device can suport. +** the local device can support. ** record. ** ** Returns the key size or 0 if the size can't be retrieved. @@ -2907,5 +2917,55 @@ BOOLEAN btm_get_current_conn_params(BD_ADDR bda, UINT16 *interval, UINT16 *laten return FALSE; } +uint8_t btm_ble_adv_active_count(void) +{ + uint8_t count = 0; + tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; + + if (p_cb->state & BTM_BLE_ADVERTISING) { + count++; + } + + return count; +} + +uint8_t btm_ble_scan_active_count(void) +{ + uint8_t count = 0; + tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; + + if (p_cb->state & BTM_BLE_SCANNING) { + count++; + } + + return count; +} + +#if (SMP_INCLUDED == TRUE) +uint8_t btm_ble_sec_dev_active_count(void) +{ + tBTM_SEC_DEV_REC *p_dev_rec = NULL; + list_node_t *p_node = NULL; + uint8_t count = 0; + + /* First look for the non-paired devices for the oldest entry */ + for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { + p_dev_rec = list_node(p_node); + if (p_dev_rec && (p_dev_rec->sec_flags & BTM_SEC_IN_USE) && (p_dev_rec->ble.key_type != BTM_LE_KEY_NONE)) { + count++; + } + } + + return count; +} +#endif + +#if (BLE_PRIVACY_SPT == TRUE) +uint8_t btm_ble_privacy_is_enabled(void) +{ + tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; + return (p_cb->privacy_mode != BTM_PRIVACY_NONE); +} +#endif #endif /* BLE_INCLUDED */ diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 9ee45872da..f595e3e6ef 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -11,6 +11,7 @@ #include #include "l2c_int.h" #if (BLE_50_FEATURE_SUPPORT == TRUE) +#define SET_BIT(t, n) (t |= 1UL << (n)) tBTM_BLE_EXTENDED_CB extend_adv_cb; tBTM_BLE_5_HCI_CBACK ble_5_hci_cb; @@ -26,6 +27,7 @@ static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len, typedef struct { uint16_t ter_con_handle; bool invalid; + bool enabled; UINT8 instance; int duration; int max_events; @@ -35,7 +37,8 @@ typedef struct { tBTM_EXT_ADV_RECORD adv_record[MAX_BLE_ADV_INSTANCE] = {0}; extern void btm_ble_inter_set(bool extble_inter); -static char *btm_ble_hci_status_to_str(tHCI_STATUS status) +#if !UC_BT_STACK_NO_LOG +static const char *btm_ble_hci_status_to_str(tHCI_STATUS status) { switch(status) { case HCI_SUCCESS: @@ -184,6 +187,7 @@ static char *btm_ble_hci_status_to_str(tHCI_STATUS status) return NULL; } +#endif /* !UC_BT_STACK_NO_LOG */ void btm_ble_extendadvcb_init(void) { @@ -328,7 +332,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr) __func__, btm_ble_hci_status_to_str(err), err); status = BTM_ILLEGAL_VALUE; } else { - // set random address success, update address infor + // set random address success, update address info if(extend_adv_cb.inst[instance].configured && extend_adv_cb.inst[instance].connetable) { BTM_BleSetStaticAddr(rand_addr); BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr); @@ -336,8 +340,8 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr) } end: - cb_params.status = status; - + cb_params.set_ext_rand_addr.status = status; + cb_params.set_ext_rand_addr.instance = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_RAND_ADDR_COMPLETE_EVT, &cb_params); return status; @@ -412,11 +416,12 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err); status = BTM_ILLEGAL_VALUE; } else { - // set addr success, update address infor + // set addr success, update address info BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr); } } - cb_params.status = status; + cb_params.set_params.status = status; + cb_params.set_params.instance = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params); return status; @@ -467,7 +472,14 @@ tBTM_STATUS BTM_BleConfigExtendedAdvDataRaw(BOOLEAN is_scan_rsp, UINT8 instance, } while (rem_len); end: - cb_params.status = status; + if (is_scan_rsp) { + cb_params.scan_rsp_data_set.status = status; + cb_params.scan_rsp_data_set.instance = instance; + } else { + cb_params.adv_data_set.status = status; + cb_params.adv_data_set.instance = instance; + } + BTM_ExtBleCallbackTrigger(is_scan_rsp ? BTM_BLE_5_GAP_EXT_SCAN_RSP_DATA_SET_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_DATA_SET_COMPLETE_EVT, &cb_params); return status; @@ -537,6 +549,7 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_ for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) { adv_record[i].invalid = false; + adv_record[i].enabled = false; adv_record[i].instance = INVALID_VALUE; adv_record[i].duration = INVALID_VALUE; adv_record[i].max_events = INVALID_VALUE; @@ -547,6 +560,7 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_ { uint8_t index = ext_adv[i].instance; adv_record[index].invalid = false; + adv_record[index].enabled = false; adv_record[index].instance = INVALID_VALUE; adv_record[index].duration = INVALID_VALUE; adv_record[index].max_events = INVALID_VALUE; @@ -560,6 +574,7 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_ { uint8_t index = ext_adv[i].instance; adv_record[index].invalid = true; + adv_record[index].enabled = true; adv_record[index].instance = ext_adv[i].instance; adv_record[index].duration = ext_adv[i].duration; adv_record[index].max_events = ext_adv[i].max_events; @@ -567,7 +582,12 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_ } } - cb_params.status = status; + cb_params.adv_start.status = status; + cb_params.adv_start.instance_num = num; + for (uint8_t i = 0; i < num; i++) { + cb_params.adv_start.instance[i] = ext_adv[i].instance; + } + BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT, &cb_params); return status; @@ -585,12 +605,12 @@ tBTM_STATUS BTM_BleStartExtAdvRestart(uint8_t con_handle) } } - if((index >= MAX_BLE_ADV_INSTANCE) || (!adv_record[index].invalid) || (adv_record[index].retry_count > GATTC_CONNECT_RETRY_COUNT)) { + if((index >= MAX_BLE_ADV_INSTANCE) || (!adv_record[index].invalid)) { return BTM_WRONG_MODE; } adv_record[index].retry_count ++; - BTM_TRACE_DEBUG("remote device did not reveive aux connect response, retatrt the extend adv to reconnect, adv handle %d con_handle %d\n", index, con_handle); + BTM_TRACE_DEBUG("remote device did not receive aux connect response, retatrt the extend adv to reconnect, adv handle %d con_handle %d\n", index, con_handle); ext_adv.instance = adv_record[index].instance; ext_adv.duration = adv_record[index].duration; ext_adv.max_events = adv_record[index].max_events; @@ -622,7 +642,9 @@ tBTM_STATUS BTM_BleExtAdvSetRemove(UINT8 instance) end: - cb_params.status = status; + cb_params.adv_start.status = status; + cb_params.adv_start.instance_num = 1; + cb_params.adv_start.instance[0] = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_REMOVE_COMPLETE_EVT, &cb_params); @@ -648,7 +670,7 @@ tBTM_STATUS BTM_BleExtAdvSetClear(void) } } - cb_params.status = status; + cb_params.adv_start.status = status; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_EXT_ADV_SET_CLEAR_COMPLETE_EVT, &cb_params); @@ -686,14 +708,15 @@ tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Pa end: - cb_params.status = status; + cb_params.per_adv_set_params.status = status; + cb_params.per_adv_set_params.instance = instance; BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_SET_PARAMS_COMPLETE_EVT, &cb_params); return status; } -tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data) +tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data,BOOLEAN only_update_did) { tBTM_STATUS status = BTM_SUCCESS; tHCI_STATUS err = HCI_SUCCESS; @@ -701,6 +724,13 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data UINT8 operation = 0; UINT16 data_offset = 0; tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + if (only_update_did) + { + len = 0; + data = NULL; + rem_len = 0; + operation = BTM_BLE_ADV_DATA_OP_UNCHANGED_DATA; + } if ((status = btm_ble_ext_adv_set_data_validate(instance, len, data)) != BTM_SUCCESS) { BTM_TRACE_ERROR("%s, invalid extend adv data.", __func__); @@ -710,12 +740,14 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data do { UINT8 send_data_len = (rem_len > BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX) ? BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX : rem_len; - if (len <= BTM_BLE_EXT_ADV_DATA_LEN_MAX) { - operation = BTM_BLE_ADV_DATA_OP_COMPLETE; + if (len <= BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX) { + if (!only_update_did) { + operation = BTM_BLE_ADV_DATA_OP_COMPLETE; + } } else { if (rem_len == len) { operation = BTM_BLE_ADV_DATA_OP_FIRST_FRAG; - } else if (rem_len <= BTM_BLE_EXT_ADV_DATA_LEN_MAX) { + } else if (rem_len <= BTM_BLE_PERIODIC_ADV_DATA_LEN_MAX) { operation = BTM_BLE_ADV_DATA_OP_LAST_FRAG; } else { operation = BTM_BLE_ADV_DATA_OP_INTERMEDIATE_FRAG; @@ -731,13 +763,15 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data } while(rem_len); end: - cb_params.status = status; + cb_params.per_adv_data_set.status = status; + cb_params.per_adv_data_set.instance = instance; + BTM_ExtBleCallbackTrigger(BTM_BLE_5_GAP_PERIODIC_ADV_DATA_SET_COMPLETE_EVT, &cb_params); return status; } -tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, BOOLEAN enable) +tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, UINT8 enable) { tBTM_STATUS status = BTM_SUCCESS; tHCI_STATUS err = HCI_SUCCESS; @@ -755,8 +789,13 @@ tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, BOOLEAN enable) } end: - - cb_params.status = status; + if (enable) { + cb_params.per_adv_start.status = status; + cb_params.per_adv_start.instance = instance; + } else { + cb_params.per_adv_stop.status = status; + cb_params.per_adv_stop.instance = instance; + } BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_PERIODIC_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_PERIODIC_ADV_STOP_COMPLETE_EVT, &cb_params); @@ -777,14 +816,37 @@ tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params) } if ((params->sync_timeout < 0x0a || params->sync_timeout > 0x4000) - || (params->filter_policy > 0x01) || (params->addr_type > 0x01) || - (params->sid > 0xf) || (params->skip > 0x01F3)) { + || (params->filter_policy > 0x01) + #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH) + || (params->reports_disabled > 0x01) + || (params->filter_duplicates > 0x01) + #endif + /*If the Periodic Advertiser List is not used, + the Advertising_SID, Advertiser Address_Type, and Advertiser Address + parameters specify the periodic advertising device to listen to; otherwise they + shall be ignored.*/ + || (params->filter_policy == 0 && params->addr_type > 0x01) + || (params->filter_policy == 0 && params->sid > 0xf) + || (params->skip > 0x01F3)) { status = BTM_ILLEGAL_VALUE; BTM_TRACE_ERROR("%s, The sync parameters is invalid.", __func__); goto end; } + uint8_t option = 0x00; + if (params->filter_policy) { + SET_BIT(option, 0); + } + + #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH) + if (params->reports_disabled) { + SET_BIT(option, 1); + } + if (params->filter_duplicates) { + SET_BIT(option, 2); + } + #endif - if (!btsnd_hcic_ble_periodic_adv_create_sync(params->filter_policy, params->sid, params->addr_type, + if (!btsnd_hcic_ble_periodic_adv_create_sync(option, params->sid, params->addr_type, params->addr, params->sync_timeout, 0)) { BTM_TRACE_ERROR("LE PA CreateSync cmd failed"); status = BTM_ILLEGAL_VALUE; @@ -1081,7 +1143,7 @@ static tBTM_STATUS btm_ble_ext_adv_params_validate(tBTM_BLE_GAP_EXT_ADV_PARAMS * static tBTM_STATUS btm_ble_ext_adv_set_data_validate(UINT8 instance, UINT16 len, UINT8 *data) { - if (!data) { + if (data == NULL && len > 0) { BTM_TRACE_ERROR("%s, the extend adv data is NULL. line %d", __func__, __LINE__); return BTM_ILLEGAL_VALUE; } @@ -1166,6 +1228,7 @@ void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params) adv_record[params->adv_handle].ter_con_handle = INVALID_VALUE; adv_record[params->adv_handle].invalid = false; } + adv_record[params->adv_handle].enabled = false; memcpy(&cb_params.adv_term, params, sizeof(tBTM_BLE_ADV_TERMINAT)); @@ -1281,34 +1344,158 @@ void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *par } +uint8_t btm_ble_ext_adv_active_count(void) +{ + uint8_t count = 0; + + for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) { + if (adv_record[i].enabled == true) { + count++; + } + } + + return count; +} + #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void btm_ble_periodic_adv_sync_trans_complete(UINT16 op_code, UINT8 hci_status, UINT16 conn_handle) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + UINT8 evt = BTM_BLE_5_GAP_UNKNOWN_EVT; + tL2C_LCB *p_lcb = l2cu_find_lcb_by_handle(conn_handle); + + switch (op_code) { + case HCI_BLE_PERIOD_ADV_SYNC_TRANS: + evt = BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT; + break; + case HCI_BLE_PERIOD_ADV_SET_INFO_TRANS: + evt = BTM_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT; + break; + case HCI_BLE_SET_PAST_PARAMS: + evt = BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT; + break; + default: + return; + } + + cb_params.per_adv_sync_trans.status = BTM_SUCCESS; + if(hci_status != HCI_SUCCESS) { + cb_params.per_adv_sync_trans.status = BTM_ILLEGAL_VALUE; + BTM_TRACE_ERROR("%s error status %d", __func__, hci_status); + } + + if(p_lcb) { + memcpy(cb_params.per_adv_sync_trans.addr, p_lcb->remote_bd_addr, BD_ADDR_LEN); + } + + BTM_ExtBleCallbackTrigger(evt, &cb_params); +} + +void BTM_BlePeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable) +{ + tHCI_STATUS err = HCI_SUCCESS; + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if ((err = btsnd_hcic_ble_set_periodic_adv_recv_enable(sync_handle, enable)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); + status = BTM_ILLEGAL_VALUE; + } + + cb_params.status = status; + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT, &cb_params); +} + +void BTM_BlePeriodicAdvSyncTrans(BD_ADDR bd_addr, UINT16 service_data, UINT16 sync_handle) +{ + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); + if (!p_lcb) { + BTM_TRACE_ERROR("%s, invalid parameters", __func__); + status = BTM_ILLEGAL_VALUE; + } + + if (status != BTM_SUCCESS) { + cb_params.per_adv_sync_trans.status = status; + memcpy(cb_params.per_adv_sync_trans.addr, bd_addr, sizeof(BD_ADDR)); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT, &cb_params); + return; + } + + btsnd_hcic_ble_periodic_adv_sync_trans(p_lcb->handle, service_data, sync_handle); +} + void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 adv_handle) { + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); if (!p_lcb) { BTM_TRACE_ERROR("%s, invalid parameters", __func__); - return; + status = BTM_ILLEGAL_VALUE; } - if (!btsnd_hcic_ble_periodic_adv_set_info_trans(p_lcb->handle, service_data, adv_handle)) { - BTM_TRACE_ERROR("%s, hci cmd error", __func__); + if (status != BTM_SUCCESS) { + cb_params.per_adv_sync_trans.status = status; + memcpy(cb_params.per_adv_sync_trans.addr, bd_addr, sizeof(BD_ADDR)); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT, &cb_params); + return; } + + btsnd_hcic_ble_periodic_adv_set_info_trans(p_lcb->handle, service_data, adv_handle); } void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) { - tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); + tBTM_STATUS status = BTM_SUCCESS; + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + // Set default past params + if (bdaddr_is_empty((bt_bdaddr_t *)bd_addr)) { + tHCI_STATUS err = HCI_SUCCESS; + if ((err = btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(mode, skip, sync_timeout, cte_type)) != HCI_SUCCESS) { + BTM_TRACE_ERROR("%s cmd err=0x%x", __func__, err); + status = BTM_ILLEGAL_VALUE; + } + + cb_params.set_past_params.status = status; + memset(cb_params.set_past_params.addr, 0, sizeof(BD_ADDR)); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT, &cb_params); + return; + } + + tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); if (!p_lcb) { BTM_TRACE_ERROR("%s, invalid parameters", __func__); + status = BTM_ILLEGAL_VALUE; + } + + if (status != BTM_SUCCESS) { + cb_params.set_past_params.status = status; + memcpy(cb_params.set_past_params.addr, bd_addr, sizeof(BD_ADDR)); + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT, &cb_params); return; } - if (!btsnd_hcic_ble_set_periodic_adv_sync_trans_params(p_lcb->handle, mode, skip, sync_timeout, cte_type)) { - BTM_TRACE_ERROR("%s, hci cmd error", __func__); + btsnd_hcic_ble_set_periodic_adv_sync_trans_params(p_lcb->handle, mode, skip, sync_timeout, cte_type); +} + +void btm_ble_periodic_adv_sync_trans_recv_evt(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV *params) +{ + tBTM_BLE_5_GAP_CB_PARAMS cb_params = {0}; + + if (!params) { + BTM_TRACE_ERROR("%s, Invalid params.", __func__); + return; } + + memcpy(&cb_params.past_recv, params, sizeof(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV)); + + BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT, &cb_params); } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c index dd6c0a176e..4cb282b79a 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_bgconn.c @@ -298,7 +298,7 @@ BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr, tBLE_ADDR_ addr_type = p_dev_rec->ble.static_addr_type; } - // white list must be public address or static random address + // The device to be added to white list must be public address or random address if(addr_type == BLE_ADDR_RANDOM) { /* A static address is a 48-bit randomly generated address and shall meet the following requirements: @@ -307,8 +307,7 @@ BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr, tBLE_ADDR_ • All bits of the random part of the address shall not be equal to 0 */ invalid_rand_addr_b[0] = invalid_rand_addr_b[0] | BT_STATIC_RAND_ADDR_MASK; - if((bd_addr[0] & BT_STATIC_RAND_ADDR_MASK) == BT_STATIC_RAND_ADDR_MASK - && memcmp(invalid_rand_addr_a, bd_addr, BD_ADDR_LEN) != 0 + if(memcmp(invalid_rand_addr_a, bd_addr, BD_ADDR_LEN) != 0 && memcmp(invalid_rand_addr_b, bd_addr, BD_ADDR_LEN) != 0){ // do nothing } else { 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 8daf84bbca..15b4a042d8 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -70,7 +70,7 @@ static tBTM_BLE_VSC_CB *cmn_ble_gap_vsc_cb_ptr; static tBTM_BLE_CTRL_FEATURES_CBACK *p_ctrl_le_feature_rd_cmpl_cback = NULL; #endif -tBTM_CallbackFunc conn_param_update_cb; +tBTM_CallbackFunc conn_callback_func; /******************************************************************************* ** Local functions *******************************************************************************/ @@ -309,7 +309,21 @@ void btm_ble_sem_free(void) *******************************************************************************/ void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb) { - conn_param_update_cb.update_conn_param_cb = update_conn_param_cb; + conn_callback_func.update_conn_param_cb = update_conn_param_cb; +} + +/******************************************************************************* +** +** Function BTM_BleRegiseterPktLengthChangeCallback +** +** Description Registers a callback function for packet length changes. +** +** Returns void +** +*******************************************************************************/ +void BTM_BleRegiseterPktLengthChangeCallback(tBTM_SET_PKT_DATA_LENGTH_CBACK *ptk_len_chane_cb) +{ + conn_callback_func.set_pkt_data_length_cb = ptk_len_chane_cb; } /******************************************************************************* @@ -374,6 +388,12 @@ void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy) &p_cb->adv_addr_type); } + uint8_t null_addr[BD_ADDR_LEN] = {0}; + if ((p_cb->evt_type == 0x01 || p_cb->evt_type == 0x04) && memcmp(p_addr_ptr, null_addr, BD_ADDR_LEN) == 0) { + /* directed advertising */ + return; + } + btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_SLOW_INT), (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : @@ -869,15 +889,6 @@ BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode, tBTM_SET_LOCAL_PRIVACY_CBACK return FALSE; } - if (p_cb->inq_var.state != BTM_BLE_IDLE) { - BTM_TRACE_ERROR("Advertising or scaning now, can't set privacy "); - if (random_cb && random_cb->set_local_privacy_cback){ - (*random_cb->set_local_privacy_cback)(BTM_SET_PRIVACY_FAIL); - random_cb->set_local_privacy_cback = NULL; - } - return FALSE; - } - #if (defined(GAP_INCLUDED) && GAP_INCLUDED == TRUE && GATTS_INCLUDED == TRUE) uint8_t addr_resolution = 0; #endif /* defined(GAP_INCLUDED) && GAP_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */ @@ -886,22 +897,12 @@ BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode, tBTM_SET_LOCAL_PRIVACY_CBACK memset(p_cb->addr_mgnt_cb.resolvale_addr, 0, BD_ADDR_LEN); p_cb->addr_mgnt_cb.own_addr_type = BLE_ADDR_PUBLIC; p_cb->privacy_mode = BTM_PRIVACY_NONE; - if (random_cb && random_cb->set_local_privacy_cback){ - (*random_cb->set_local_privacy_cback)(BTM_SET_PRIVACY_SUCCESS); - random_cb->set_local_privacy_cback = NULL; - } // Disable RPA function btsnd_hcic_ble_set_addr_resolution_enable(FALSE); } else { /* privacy is turned on*/ #if (CONTROLLER_RPA_LIST_ENABLE == FALSE) /* always set host random address, used when privacy 1.1 or priavcy 1.2 is disabled */ btm_gen_resolvable_private_addr((void *)btm_gen_resolve_paddr_low); -#else - /* Controller generates RPA, Host don't need to set random address */ - if (random_cb && random_cb->set_local_privacy_cback){ - (*random_cb->set_local_privacy_cback)(BTM_SET_PRIVACY_SUCCESS); - random_cb->set_local_privacy_cback = NULL; - } #endif if (BTM_BleMaxMultiAdvInstanceCount() > 0) { @@ -1019,7 +1020,7 @@ uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK * memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr, BD_ADDR_LEN); btsnd_hcic_ble_set_random_addr(btm_cb.ble_ctr_cb.addr_mgnt_cb.resolvale_addr); }else { - BTM_TRACE_ERROR ("No random address yet, please set random address and try\n"); + BTM_TRACE_ERROR ("No random address yet, please set random address using API \"esp_ble_gap_set_rand_addr\" and retry\n"); if(cb) { (* cb)(HCI_ERR_ESP_VENDOR_FAIL); } @@ -1068,17 +1069,28 @@ uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK * #else uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb) { + tBTM_LE_RANDOM_CB *p_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; + if((*own_bda_type == BLE_ADDR_RANDOM) || (*own_bda_type == BLE_ADDR_RANDOM_ID)) { - if((btm_cb.ble_ctr_cb.addr_mgnt_cb.exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RANDOM) != BTM_BLE_GAP_ADDR_BIT_RANDOM) { + if((p_cb->exist_addr_bit & BTM_BLE_GAP_ADDR_BIT_RANDOM) != BTM_BLE_GAP_ADDR_BIT_RANDOM) { BTM_TRACE_ERROR("No random address yet, please set random address and try\n"); if(cb) { (* cb)(HCI_ERR_ESP_VENDOR_FAIL); } return BTM_ILLEGAL_VALUE; } + + // If a device is using RPA, it shall also have an Identity Address + if ((*own_bda_type == BLE_ADDR_RANDOM_ID) && BTM_BLE_IS_NON_RESLVE_BDA(p_cb->static_rand_addr)) { + BTM_TRACE_ERROR("No identity address yet, please set static random address and try\n"); + if (cb) { + (* cb)(HCI_ERR_ESP_VENDOR_FAIL); + } + return BTM_ILLEGAL_VALUE; + } } - btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = *own_bda_type; + p_cb->own_addr_type = *own_bda_type; return BTM_SUCCESS; } @@ -1341,7 +1353,7 @@ tBTM_STATUS BTM_BleSetConnectableMode(tBTM_BLE_CONN_MODE connectable_mode) ** ** Function btm_set_conn_mode_adv_init_addr ** -** Description set initator address type and local address type based on adv +** Description set initiator address type and local address type based on adv ** mode. ** ** @@ -2009,7 +2021,7 @@ tBTM_STATUS BTM_BleSetRandAddress(BD_ADDR rand_addr) } if (btm_cb.ble_ctr_cb.inq_var.state != BTM_BLE_IDLE) { - BTM_TRACE_ERROR("Advertising or scaning now, can't set randaddress %d", btm_cb.ble_ctr_cb.inq_var.state); + BTM_TRACE_ERROR("Advertising or scanning now, can't set randaddress %d", btm_cb.ble_ctr_cb.inq_var.state); return BTM_SET_STATIC_RAND_ADDR_FAIL; } memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, rand_addr, BD_ADDR_LEN); @@ -2038,7 +2050,7 @@ void BTM_BleClearRandAddress(void) { tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; if (btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type == BLE_ADDR_RANDOM && (p_cb->inq_var.state != BTM_BLE_IDLE)) { - BTM_TRACE_ERROR("Advertising or scaning now, can't restore public address "); + BTM_TRACE_ERROR("Advertising or scanning now, can't restore public address "); return; } memset(btm_cb.ble_ctr_cb.addr_mgnt_cb.static_rand_addr, 0, BD_ADDR_LEN); @@ -2098,7 +2110,7 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length) STREAM_TO_UINT8(length, p); - while ( length && (p - p_adv <= BTM_BLE_CACHE_ADV_DATA_MAX)) { + while ( length && (p - p_adv < BTM_BLE_CACHE_ADV_DATA_MAX)) { STREAM_TO_UINT8(adv_type, p); if ( adv_type == type ) { @@ -2106,7 +2118,15 @@ UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length) *p_length = length - 1; /* minus the length of type */ return p; } + p += length - 1; /* skip the length of data */ + + /* Break loop if advertising data is in an incorrect format, + as it may lead to memory overflow */ + if (p >= p_adv + BTM_BLE_CACHE_ADV_DATA_MAX) { + break; + } + STREAM_TO_UINT8(length, p); } @@ -3291,6 +3311,7 @@ static void btm_ble_appearance_to_cod(UINT16 appearance, UINT8 *dev_class) case BTM_BLE_APPEARANCE_CYCLING_CADENCE: case BTM_BLE_APPEARANCE_CYCLING_POWER: case BTM_BLE_APPEARANCE_CYCLING_SPEED_CADENCE: + case BTM_BLE_APPEARANCE_STANDALONE_SPEAKER: case BTM_BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS: case BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION: case BTM_BLE_APPEARANCE_OUTDOOR_SPORTS_LOCATION_AND_NAV: @@ -3363,7 +3384,11 @@ BOOLEAN btm_ble_update_inq_result(BD_ADDR bda, tINQ_DB_ENT *p_i, UINT8 addr_type if (evt_type != BTM_BLE_SCAN_RSP_EVT) { p_cur->ble_evt_type = evt_type; } - +#if BTM_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY + if (evt_type == BTM_BLE_SCAN_RSP_EVT) { + p_cur->ble_evt_type = evt_type; + } +#endif p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */ if (p_le_inq_cb->adv_len != 0) { @@ -3724,7 +3749,7 @@ static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt /* never been report as an LE device */ if (p_i && (!(p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) || - /* scan repsonse to be updated */ + /* scan response to be updated */ (!p_i->scan_rsp))) { update = TRUE; } else if (BTM_BLE_IS_DISCO_ACTIVE(btm_cb.ble_ctr_cb.scan_activity)) { @@ -3984,6 +4009,9 @@ static void btm_ble_stop_discover(void) if(btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE)) { osi_sem_take(&scan_enable_sem, OSI_SEM_MAX_TIMEOUT); } + /* reset status */ + btm_ble_clear_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT); + btm_ble_clear_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT); } if (p_scan_cb) { @@ -3998,7 +4026,7 @@ static void btm_ble_stop_discover(void) ** ** Description Set or clear adv states in topology mask ** -** Returns operation status. TRUE if sucessful, FALSE otherwise. +** Returns operation status. TRUE if successful, FALSE otherwise. ** *******************************************************************************/ typedef BOOLEAN (BTM_TOPOLOGY_FUNC_PTR)(tBTM_BLE_STATE_MASK); @@ -4259,7 +4287,7 @@ void btm_ble_timeout(TIMER_LIST_ENT *p_tle) break; case BTU_TTYPE_BLE_GAP_LIM_DISC: - /* lim_timeout expiried, limited discovery should exit now */ + /* lim_timeout expired, limited discovery should exit now */ btm_cb.btm_inq_vars.discoverable_mode &= ~BTM_BLE_LIMITED_DISCOVERABLE; btm_ble_set_adv_flag(btm_cb.btm_inq_vars.connectable_mode, btm_cb.btm_inq_vars.discoverable_mode); break; @@ -4677,6 +4705,62 @@ 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; +} +BOOLEAN BTM_BleSetRpaTimeout(uint16_t rpa_timeout,tBTM_SET_RPA_TIMEOUT_CMPL_CBACK *p_set_rpa_timeout_cback) +{ + if ((btsnd_hcic_ble_set_rand_priv_addr_timeout(rpa_timeout)) != TRUE) { + BTM_TRACE_ERROR("Set RPA Timeout error, rpa_timeout:0x%04x",rpa_timeout); + return FALSE; + } + btm_cb.devcb.p_ble_set_rpa_timeout_cmpl_cb = p_set_rpa_timeout_cback; + return TRUE; +} + +BOOLEAN BTM_BleAddDevToResolvingList(BD_ADDR addr, + uint8_t addr_type, + uint8_t irk[], + tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *p_add_dev_to_resolving_list_callback) +{ + UINT8 *local_irk = btm_cb.devcb.id_keys.irk; + if ((btsnd_hcic_ble_add_device_resolving_list(addr_type, addr, irk, local_irk)) != TRUE) { + BTM_TRACE_ERROR("Add device to resolving list error"); + return FALSE; + } + btm_cb.devcb.p_add_dev_to_resolving_list_cmpl_cb = p_add_dev_to_resolving_list_callback; + return TRUE; +} + +BOOLEAN BTM_BleSetPrivacyMode(UINT8 addr_type, BD_ADDR bd_addr, UINT8 privacy_mode, tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_callback) +{ + if (btsnd_hcic_ble_set_privacy_mode(addr_type, bd_addr, privacy_mode) != TRUE) { + BTM_TRACE_ERROR("LE SetPrivacyMode Mode=%d: error", privacy_mode); + return FALSE; + } + + btm_cb.devcb.p_set_privacy_mode_cmpl_cb = p_callback; + 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_ble_multi_adv.c b/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c index 443dd64edf..bc300b0235 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_multi_adv.c @@ -824,6 +824,13 @@ void btm_ble_multi_adv_init(void) *******************************************************************************/ void btm_ble_multi_adv_cleanup(void) { +#if BTM_DYNAMIC_MEMORY == TRUE + if (btm_multi_adv_cb_ptr == NULL) + { + BTM_TRACE_WARNING("%s memory has been freed", __func__); + return; + } +#endif if (btm_multi_adv_cb.p_adv_inst) { osi_free(btm_multi_adv_cb.p_adv_inst); btm_multi_adv_cb.p_adv_inst = NULL; diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c index 5477be2b1c..9ddf746ae9 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c @@ -275,6 +275,14 @@ void btm_ble_add_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len) { UINT8 status; STREAM_TO_UINT8(status, p); + if (btm_cb.devcb.p_add_dev_to_resolving_list_cmpl_cb) { + tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *p_cb = btm_cb.devcb.p_add_dev_to_resolving_list_cmpl_cb; + if (p_cb) { + (*p_cb)(status); + } + } else { + BTM_TRACE_DEBUG("no resolving list callback"); + } BTM_TRACE_DEBUG("%s status = %d", __func__, status); @@ -322,7 +330,7 @@ void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len) BTM_TRACE_DEBUG("%s status = %d", __func__, status); if (!btm_ble_deq_resolving_pending(pseudo_bda)) { - BTM_TRACE_ERROR("%s no pending resolving list operation", __func__); + BTM_TRACE_DEBUG("%s no pending resolving list operation", __func__); return; } @@ -377,6 +385,103 @@ void btm_ble_read_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len) btm_ble_refresh_peer_resolvable_private_addr(pseudo_bda, rra, rra_type); } } + +/******************************************************************************* +** +** Function btm_ble_set_addr_resolution_enable_complete +** +** Description This function is called when the command to set address +** resolution enable completes. +** +** Parameters p: Pointer to the command complete event data. +** evt_len: Length of the event data. +** +** Returns void +** +*******************************************************************************/ +void btm_ble_set_addr_resolution_enable_complete(UINT8 *p, UINT16 evt_len) +{ + UINT8 status; + + STREAM_TO_UINT8(status, p); + + BTM_TRACE_DEBUG("%s status = %d", __func__, status); + + tBTM_LE_RANDOM_CB *random_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; + + if (!(random_cb && random_cb->set_local_privacy_cback)) { + return; + } + + if (status == HCI_SUCCESS) { + random_cb->set_local_privacy_cback(BTM_SUCCESS); + return; + } else if (status == HCI_ERR_COMMAND_DISALLOWED) { + BTM_TRACE_ERROR("a non-connected activity is ongoing, such as advertising and scanning"); + } else { + BTM_TRACE_ERROR("set local privacy failed"); + } + random_cb->set_local_privacy_cback(BTM_ILLEGAL_VALUE); +} + +/******************************************************************************* +** +** Function btm_ble_set_rpa_timeout_complete +** +** Description This function is called when the LE Set Resolvable Private +** Address Timeout command completes. +** +** Parameters p: Pointer to the command complete event data. +** evt_len: Length of the event data. +** +** Returns void +** +*******************************************************************************/ +void btm_ble_set_rpa_timeout_complete(UINT8 *p, UINT16 evt_len) +{ + UINT8 status; + + // Extract the status of the command completion from the event data + STREAM_TO_UINT8(status, p); + + BTM_TRACE_DEBUG("%s status = %d", __func__, status); + + tBTM_SET_RPA_TIMEOUT_CMPL_CBACK *p_cb = btm_cb.devcb.p_ble_set_rpa_timeout_cmpl_cb; + + if (p_cb) { + (*p_cb)(status); + } + +} + +/******************************************************************************* +** +** Function btm_ble_set_privacy_mode_complete +** +** Description This function is called when the LE Set Privacy Mode command completes. +** +** Parameters p: Pointer to the command complete event data. +** evt_len: Length of the event data. +** +** Returns void +** +*******************************************************************************/ +void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len) +{ + UINT8 status; + + // Extract the status of the command completion from the event data + STREAM_TO_UINT8(status, p); + + BTM_TRACE_DEBUG("%s status = 0x%x", __func__, status); + + tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_cb = btm_cb.devcb.p_set_privacy_mode_cmpl_cb; + + if (p_cb) { + (*p_cb)(status); + } +} + /******************************************************************************* VSC that implement controller based privacy ********************************************************************************/ @@ -420,7 +525,7 @@ void btm_ble_resolving_list_vsc_op_cmpl (tBTM_VSC_CMPL *p_params) ** Description This function to remove an IRK entry from the list ** ** Parameters ble_addr_type: address type -** ble_addr: LE adddress +** ble_addr: LE address ** ** Returns status ** @@ -434,10 +539,18 @@ tBTM_STATUS btm_ble_remove_resolving_list_entry(tBTM_SEC_DEV_REC *p_dev_rec) tBTM_STATUS st = BTM_NO_RESOURCES; if (controller_get_interface()->supports_ble_privacy()) { + #if CONTROLLER_RPA_LIST_ENABLE if (btsnd_hcic_ble_rm_device_resolving_list(p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr)) { st = BTM_CMD_STARTED; } + #else + // do nothing + /* It will cause that scanner doesn't send scan request to advertiser + * which has sent IRK to us and we have stored the IRK in controller. + * It is a hardware limitation. The preliminary solution is not to + * send key to the controller, but to resolve the random address in host. */ + #endif } else { UINT8 param[20] = {0}; UINT8 *p = param; @@ -902,7 +1015,7 @@ void btm_ble_enable_resolving_list(UINT8 rl_mask) ** ** Function btm_ble_resolving_list_empty ** -** Description check to see if resoving list is empty or not +** Description check to see if resolving list is empty or not ** ** Returns TRUE: empty; FALSE non-empty ** @@ -1027,13 +1140,16 @@ void btm_ble_add_default_entry_to_resolving_list(void) /* * Add local IRK entry with 00:00:00:00:00:00 address. This entry will * be used to generate RPA for non-directed advertising if own_addr_type - * is set to rpa_pub since we use all-zero address as peer addres in + * is set to rpa_pub since we use all-zero address as peer address in * such case. Peer IRK should be left all-zero since this is not for an * actual peer. */ BD_ADDR peer_addr = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; BT_OCTET16 peer_irk = {0x0}; + // Remove the existing entry in resolving list When resetting the device identity + btsnd_hcic_ble_rm_device_resolving_list(BLE_ADDR_PUBLIC, peer_addr); + btsnd_hcic_ble_add_device_resolving_list (BLE_ADDR_PUBLIC, peer_addr, peer_irk, btm_cb.devcb.id_keys.irk); } #endif diff --git a/components/bt/host/bluedroid/stack/btm/btm_dev.c b/components/bt/host/bluedroid/stack/btm/btm_dev.c index d83da09907..5a337342a9 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_dev.c +++ b/components/bt/host/bluedroid/stack/btm/btm_dev.c @@ -178,20 +178,31 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, *******************************************************************************/ BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr, tBT_TRANSPORT transport) { - tBTM_SEC_DEV_REC *p_dev_rec; if (BTM_IsAclConnectionUp(bd_addr, transport)) { BTM_TRACE_WARNING("%s FAILED: Cannot Delete when connection is active\n", __func__); return FALSE; } + if ((p_dev_rec = btm_find_dev(bd_addr)) != NULL) { /* Tell controller to get rid of the link key, if it has one stored */ BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL); - btm_sec_free_dev(p_dev_rec, transport); + btm_sec_free_dev(p_dev_rec, transport); } +#if (BLE_SMP_ID_RESET_ENABLE == TRUE) + /* + * There are tracking risks associated with using a fixed or static IRK. + * A best-practices approach, when all pairing and bonding records are deleted, + * assign a new randomly-generated IRK. + */ + if (list_is_empty(btm_cb.p_sec_dev_rec_list)) { + btm_ble_reset_id(); + } +#endif + return TRUE; } @@ -592,7 +603,7 @@ void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec) p_target_rec->ble.ble_addr_type = p_dev_rec->ble.ble_addr_type; p_target_rec->device_type |= p_dev_rec->device_type; /* Remove the unused device from the list */ - list_remove(btm_cb.p_sec_dev_rec_list, p_dev_rec); + list_remove(btm_cb.p_sec_dev_rec_list, p_dev_rec); } break; } @@ -639,7 +650,7 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) tBTM_SEC_DEV_REC *p_dev_rec = NULL; tBTM_SEC_DEV_REC *p_oldest = NULL; list_node_t *p_node = NULL; - UINT32 ot = 0xFFFFFFFF; + UINT32 old_ts = 0xFFFFFFFF; /* First look for the non-paired devices for the oldest entry */ for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { @@ -649,13 +660,13 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) continue; /* Device is paired so skip it */ } - if (p_dev_rec->timestamp < ot) { + if (p_dev_rec->timestamp < old_ts) { p_oldest = p_dev_rec; - ot = p_dev_rec->timestamp; + old_ts = p_dev_rec->timestamp; } } - if (ot != 0xFFFFFFFF) { + if (old_ts != 0xFFFFFFFF) { return (p_oldest); } @@ -665,9 +676,9 @@ tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) continue; } - if (p_dev_rec->timestamp < ot) { + if (p_dev_rec->timestamp < old_ts) { p_oldest = p_dev_rec; - ot = p_dev_rec->timestamp; + old_ts = p_dev_rec->timestamp; } } return (p_oldest); diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index ab7aa917c1..d092e2b71e 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -714,9 +714,18 @@ 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; + break; } +#endif // (BLE_INCLUDED == TRUE) tBTM_VSC_CMPL vcs_cplt_params; /* If there was a callback address for vcs complete, call it */ @@ -727,7 +736,7 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len, vcs_cplt_params.p_param_buf = p; (*p_vsc_cplt_cback)(&vcs_cplt_params); /* Call the VSC complete callback function */ } -#endif + } /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/btm/btm_inq.c b/components/bt/host/bluedroid/stack/btm/btm_inq.c index 21ebe81b9b..b8da232795 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/components/bt/host/bluedroid/stack/btm/btm_inq.c @@ -2535,9 +2535,125 @@ void BTM_AddEirService( UINT32 *p_eir_uuid, UINT16 uuid16 ) } } + +/******************************************************************************* +** +** Function btm_compare_uuid +** +** Description Helper function for custom service managing routines. +** +** Parameters uuid1 - pointer to the first tBT_UUID struct +** uuid2 - pointer to the second tBT_UUID struct +** +** Returns true if UUID structs are identical +** +*******************************************************************************/ +static bool btm_compare_uuid(tBT_UUID *uuid1, tBT_UUID *uuid2) +{ + if (uuid1->len != uuid2->len) { + return FALSE; + } + + return (memcmp(&uuid1->uu, &uuid2->uu, uuid1->len) == 0); +} + +/******************************************************************************* +** +** Function btm_find_empty_custom_uuid_slot +** +** Description Helper function for custom service managing routines. +** +** Parameters custom_uuid - pointer to custom_uuid array in tBTA_DM_CB +** uuid - UUID struct +** +** Returns Slot number if there is empty slot, +** otherwise - BTA_EIR_SERVER_NUM_CUSTOM_UUID +** +*******************************************************************************/ +static UINT8 btm_find_empty_custom_uuid_slot(tBT_UUID *custom_uuid, tBT_UUID uuid) +{ + for (UINT8 xx = 0; xx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; xx++) { + if (custom_uuid[xx].len == 0) { + return xx; + } + } + return BTA_EIR_SERVER_NUM_CUSTOM_UUID; +} + +/******************************************************************************* +** +** Function btm_find_match_custom_uuid_slot +** +** Description Helper function for custom service managing routines. +** +** Parameters custom_uuid - pointer to custom_uuid array in tBTA_DM_CB +** uuid - UUID struct +** +** Returns Slot number if given UUID is already in slots array, +** otherwise - BTA_EIR_SERVER_NUM_CUSTOM_UUID +** +*******************************************************************************/ +static UINT8 btm_find_match_custom_uuid_slot(tBT_UUID *custom_uuid, tBT_UUID uuid) +{ + for (UINT8 xx = 0; xx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; xx++) { + if (btm_compare_uuid(&custom_uuid[xx], &uuid)) { + return xx; + } + } + return BTA_EIR_SERVER_NUM_CUSTOM_UUID; +} + +/******************************************************************************* +** +** Function BTM_HasCustomEirService +** +** Description This function is called to know if UUID is already in custom +** UUID list. +** +** Parameters custom_uuid - pointer to custom_uuid array in tBTA_DM_CB +** uuid - UUID struct +** +** Returns TRUE - if found +** FALSE - if not found +** +*******************************************************************************/ +BOOLEAN BTM_HasCustomEirService(tBT_UUID *custom_uuid, tBT_UUID uuid) +{ + UINT8 match_slot = btm_find_match_custom_uuid_slot(custom_uuid, uuid); + + if (match_slot == BTA_EIR_SERVER_NUM_CUSTOM_UUID) { + return FALSE; + } + return TRUE; +} + /******************************************************************************* ** -** Function BTM_RemoveEirService +** Function BTM_AddCustomEirService +** +** Description This function is called to add a custom UUID. +** +** Parameters custom_uuid - pointer to custom_uuid array in tBTA_DM_CB +** uuid - UUID struct +** +** Returns None +** +*******************************************************************************/ +void BTM_AddCustomEirService(tBT_UUID *custom_uuid, tBT_UUID uuid) +{ + UINT8 empty_slot = btm_find_empty_custom_uuid_slot(custom_uuid, uuid); + + if (empty_slot == BTA_EIR_SERVER_NUM_CUSTOM_UUID) { + BTM_TRACE_WARNING("No space to add UUID for EIR"); + } else { + memcpy(&(custom_uuid[empty_slot]), &(uuid), sizeof(tBT_UUID)); + BTM_TRACE_EVENT("UUID saved in %d slot", empty_slot); + } +} + +/******************************************************************************* +** +** Function BTM_RemoveCustomEirService ** ** Description This function is called to remove a service in bit map of UUID list. ** @@ -2557,6 +2673,30 @@ void BTM_RemoveEirService( UINT32 *p_eir_uuid, UINT16 uuid16 ) } } +/******************************************************************************* +** +** Function BTM_RemoveCustomEirService +** +** Description This function is called to remove a a custom UUID. +** +** Parameters custom_uuid - pointer to custom_uuid array in tBTA_DM_CB +** uuid - UUID struct +** +** Returns None +** +*******************************************************************************/ +void BTM_RemoveCustomEirService(tBT_UUID *custom_uuid, tBT_UUID uuid) +{ + UINT8 match_slot = btm_find_match_custom_uuid_slot(custom_uuid, uuid); + + if (match_slot == BTA_EIR_SERVER_NUM_CUSTOM_UUID) { + BTM_TRACE_WARNING("UUID is not found for EIR"); + return; + } else { + memset(&(custom_uuid[match_slot]), 0, sizeof(tBT_UUID)); + } +} + /******************************************************************************* ** ** Function BTM_GetEirSupportedServices diff --git a/components/bt/host/bluedroid/stack/btm/btm_main.c b/components/bt/host/bluedroid/stack/btm/btm_main.c index 5ddfa85a99..8e49aa3e6d 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_main.c +++ b/components/bt/host/bluedroid/stack/btm/btm_main.c @@ -117,3 +117,19 @@ void btm_free(void) btm_ble_sem_free(); #endif } + +uint8_t btm_acl_active_count(void) +{ + list_node_t *p_node = NULL; + tACL_CONN *p_acl_conn = NULL; + uint8_t count = 0; + + for (p_node = list_begin(btm_cb.p_acl_db_list); p_node; p_node = list_next(p_node)) { + p_acl_conn = list_node(p_node); + if (p_acl_conn && p_acl_conn->in_use) { + count++; + } + } + + return count; +} diff --git a/components/bt/host/bluedroid/stack/btm/btm_pm.c b/components/bt/host/bluedroid/stack/btm/btm_pm.c index 5f1950e02a..4c52348ecd 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_pm.c +++ b/components/bt/host/bluedroid/stack/btm/btm_pm.c @@ -243,7 +243,8 @@ tBTM_STATUS BTM_SetPowerMode (UINT8 pm_id, BD_ADDR remote_bda, tBTM_PM_PWR_MD *p /* if mode == hold or pending, return */ if ( (p_cb->state == BTM_PM_STS_HOLD) || (p_cb->state == BTM_PM_STS_PENDING) || - (btm_cb.pm_pend_link_hdl != BTM_INVALID_HANDLE) ) { /* command pending */ + (btm_cb.pm_pend_link_hdl != BTM_INVALID_HANDLE) || + (p_cb->state & BTM_PM_STORED_MASK) ) { /* command pending */ if (p_acl_cb->hci_handle != btm_cb.pm_pend_link_hdl) { /* set the stored mask */ p_cb->state |= BTM_PM_STORED_MASK; diff --git a/components/bt/host/bluedroid/stack/btm/btm_sco.c b/components/bt/host/bluedroid/stack/btm/btm_sco.c index 6f5dd7806d..53a9768a1a 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_sco.c +++ b/components/bt/host/bluedroid/stack/btm/btm_sco.c @@ -341,6 +341,82 @@ void btm_sco_process_num_completed_pkts (UINT8 *p) return; } + +/******************************************************************************* +** +** Function btm_pkt_stat_nums_update +** +** Description Update the number of received SCO data packet status. +** +** Returns void +** +*******************************************************************************/ +static void btm_pkt_stat_nums_update(uint16_t sco_inx, uint8_t pkt_status) +{ + tSCO_CONN *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx]; + p_ccb->pkt_stat_nums.rx_total++; + if (pkt_status == BTM_SCO_DATA_CORRECT) { + p_ccb->pkt_stat_nums.rx_correct++; + } else if (pkt_status == BTM_SCO_DATA_PAR_ERR) { + p_ccb->pkt_stat_nums.rx_err++; + } else if (pkt_status == BTM_SCO_DATA_NONE) { + p_ccb->pkt_stat_nums.rx_none++; + } else { + p_ccb->pkt_stat_nums.rx_lost++; + } +} + +/******************************************************************************* +** +** Function btm_pkt_stat_send_nums_update +** +** Description Update the number of send packet status. +** +** Returns void +** +*******************************************************************************/ +static void btm_pkt_stat_send_nums_update(uint16_t sco_inx, uint8_t pkt_status) +{ + tSCO_CONN *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx]; + p_ccb->pkt_stat_nums.tx_total++; + if (pkt_status != BTM_SUCCESS && pkt_status != BTM_NO_RESOURCES && pkt_status != BTM_SCO_BAD_LENGTH) { + p_ccb->pkt_stat_nums.tx_discarded++; + } +} + +/******************************************************************************* +** +** Function btm_pkt_stat_nums_reset +** +** Description This function is called to reset the number of packet status struct +** +** Returns void +** +*******************************************************************************/ +static void btm_pkt_stat_nums_reset(uint16_t sco_inx) +{ + memset(&btm_cb.sco_cb.sco_db[sco_inx].pkt_stat_nums, 0, sizeof(tBTM_SCO_PKT_STAT_NUMS)); +} + +/******************************************************************************* +** +** Function BTM_PktStatNumsGet +** +** Description This function is called to get the number of packet status struct +** +** Returns void +** +*******************************************************************************/ +void BTM_PktStatNumsGet(uint16_t sync_conn_handle, tBTM_SCO_PKT_STAT_NUMS *p_pkt_nums) +{ + uint16_t sco_inx = btm_find_scb_by_handle(sync_conn_handle); + if (sco_inx < BTM_MAX_SCO_LINKS) { + memcpy(p_pkt_nums, &btm_cb.sco_cb.sco_db[sco_inx].pkt_stat_nums, sizeof(tBTM_SCO_PKT_STAT_NUMS)); + } else { + memset(p_pkt_nums, 0, sizeof(tBTM_SCO_PKT_STAT_NUMS)); + } +} + #endif /* BTM_SCO_HCI_INCLUDED == TRUE */ /******************************************************************************* @@ -374,6 +450,7 @@ void btm_route_sco_data(BT_HDR *p_msg) { osi_free (p_msg); } else { + btm_pkt_stat_nums_update(sco_inx, pkt_status); (*btm_cb.sco_cb.p_data_cb)(sco_inx, p_msg, (tBTM_SCO_DATA_FLAG) pkt_status); } } else { /* no mapping handle SCO connection is active, free the buffer */ @@ -457,10 +534,11 @@ tBTM_STATUS BTM_WriteScoData (UINT16 sco_inx, BT_HDR *p_buf) status = BTM_UNKNOWN_ADDR; } - if (status != BTM_SUCCESS && status!= BTM_NO_RESOURCES) { + if (status != BTM_SUCCESS && status!= BTM_NO_RESOURCES && status != BTM_SCO_BAD_LENGTH) { BTM_TRACE_WARNING ("stat %d", status); osi_free(p_buf); } + btm_pkt_stat_send_nums_update(sco_inx, status); return (status); #else @@ -955,7 +1033,7 @@ void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle, #endif btm_cb.sco_cb.sco_disc_reason = hci_status; - BTM_TRACE_ERROR("%s, handle %x", __FUNCTION__, hci_handle); + BTM_TRACE_API("%s, handle %x", __FUNCTION__, hci_handle); #if (BTM_MAX_SCO_LINKS>0) for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) { if (((p->state == SCO_ST_CONNECTING) || @@ -994,6 +1072,7 @@ void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle, } #if BTM_SCO_HCI_INCLUDED == TRUE p->sent_not_acked = 0; + btm_pkt_stat_nums_reset(xx); #endif p->state = SCO_ST_CONNECTED; p->hci_handle = hci_handle; 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 c709dd0a48..0f8888fb1b 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 @@ -84,8 +84,10 @@ typedef UINT8 tBTM_BLE_SEC_REQ_ACT; #define BLE_STATIC_PRIVATE_MSB_MASK 0x3f -#define BLE_RESOLVE_ADDR_MSB 0x40 /* most significant bit, bit7, bit6 is 01 to be resolvable random */ +#define BLE_NON_RESOLVE_ADDR_MSB 0x00 /* most significant bit, bit7, bit6 is 00 to be non-resolvable random */ +#define BLE_RESOLVE_ADDR_MSB 0x40 /* most significant bit, bit7, bit6 is 01 to be resolvable random */ #define BLE_RESOLVE_ADDR_MASK 0xc0 /* bit 6, and bit7 */ +#define BTM_BLE_IS_NON_RESLVE_BDA(x) ((x[0] & BLE_RESOLVE_ADDR_MASK) == BLE_NON_RESOLVE_ADDR_MSB) #define BTM_BLE_IS_RESOLVE_BDA(x) ((x[0] & BLE_RESOLVE_ADDR_MASK) == BLE_RESOLVE_ADDR_MSB) /* LE scan activity bit mask, continue with LE inquiry bits */ @@ -157,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; @@ -310,7 +313,7 @@ typedef struct { #define BTM_PRIVACY_NONE 0 /* BLE no privacy */ #define BTM_PRIVACY_1_1 1 /* BLE privacy 1.1, do not support privacy 1.0 */ #define BTM_PRIVACY_1_2 2 /* BLE privacy 1.2 */ -#define BTM_PRIVACY_MIXED 3 /* BLE privacy mixed mode, broadcom propietary mode */ +#define BTM_PRIVACY_MIXED 3 /* BLE privacy mixed mode, broadcom proprietary mode */ typedef UINT8 tBTM_PRIVACY_MODE; /* data length change event callback */ @@ -482,6 +485,8 @@ BOOLEAN btm_random_pseudo_to_identity_addr(BD_ADDR random_pseudo, UINT8 *p_stati void btm_ble_refresh_peer_resolvable_private_addr(BD_ADDR pseudo_bda, BD_ADDR rra, UINT8 rra_type); void btm_ble_refresh_local_resolvable_private_addr(BD_ADDR pseudo_addr, BD_ADDR local_rpa); void btm_ble_read_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len) ; +void btm_ble_set_addr_resolution_enable_complete(UINT8 *p, UINT16 evt_len) ; +void btm_ble_set_rpa_timeout_complete(UINT8 *p, UINT16 evt_len) ; void btm_ble_remove_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len); void btm_ble_add_resolving_list_entry_complete(UINT8 *p, UINT16 evt_len); void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len); @@ -492,6 +497,7 @@ void btm_ble_enable_resolving_list_for_platform (UINT8 rl_mask); void btm_ble_resolving_list_init(UINT8 max_irk_list_sz); void btm_ble_resolving_list_cleanup(void); void btm_ble_add_default_entry_to_resolving_list(void); +void btm_ble_set_privacy_mode_complete(UINT8 *p, UINT16 evt_len); #endif void btm_ble_multi_adv_configure_rpa (tBTM_BLE_MULTI_ADV_INST *p_inst); @@ -532,6 +538,10 @@ void btm_ble_periodic_adv_sync_lost_evt(tBTM_BLE_PERIOD_ADV_SYNC_LOST *params); void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *params); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void btm_ble_periodic_adv_sync_trans_recv_evt(tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV *params); +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /* #ifdef __cplusplus } diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 781999e6b5..47a398c87f 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -214,6 +214,10 @@ tBTM_CMPL_CB *p_tx_power_cmpl_cb;/* Callback function to be called TIMER_LIST_ENT afh_channels_timer; tBTM_CMPL_CB *p_afh_channels_cmpl_cb; /* Callback function to be called When */ /* set AFH channels is completed */ + +TIMER_LIST_ENT set_acl_pkt_types_timer; +tBTM_CMPL_CB *p_set_acl_pkt_types_cmpl_cb; /* Callback function to be called when */ +/* set ACL packet types is completed */ #endif DEV_CLASS dev_class; /* Local device class */ @@ -224,6 +228,13 @@ TIMER_LIST_ENT ble_channels_timer; tBTM_CMPL_CB *p_ble_channels_cmpl_cb; /* Callback function to be called When ble set host channels is completed */ +tBTM_SET_RPA_TIMEOUT_CMPL_CBACK *p_ble_set_rpa_timeout_cmpl_cb; /* Callback function to be called When + ble set rpa timeout is completed */ + +tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *p_add_dev_to_resolving_list_cmpl_cb; + +tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_set_privacy_mode_cmpl_cb; + tBTM_CMPL_CB *p_le_test_cmd_cmpl_cb; /* Callback function to be called when LE test mode command has been sent successfully */ @@ -347,7 +358,7 @@ typedef struct { UINT8 inqfilt_type; /* Contains the inquiry filter type (BD ADDR, COD, or Clear) */ #define BTM_INQ_INACTIVE_STATE 0 -#define BTM_INQ_CLR_FILT_STATE 1 /* Currently clearing the inquiry filter preceeding the inquiry request */ +#define BTM_INQ_CLR_FILT_STATE 1 /* Currently clearing the inquiry filter preceding the inquiry request */ /* (bypassed if filtering is not used) */ #define BTM_INQ_SET_FILT_STATE 2 /* Sets the new filter (or turns off filtering) in this state */ #define BTM_INQ_ACTIVE_STATE 3 /* Actual inquiry or periodic inquiry is in progress */ @@ -431,6 +442,7 @@ typedef struct { #define BTM_SCO_XMIT_QUEUE_HIGH_WM 20 fixed_queue_t *xmit_data_q; /* SCO data transmitting queue */ INT16 sent_not_acked; + tBTM_SCO_PKT_STAT_NUMS pkt_stat_nums; #endif tBTM_SCO_CB *p_conn_cb; /* Callback for when connected */ tBTM_SCO_CB *p_disc_cb; /* Callback for when disconnect */ @@ -937,8 +949,8 @@ typedef struct { UINT8 acl_disc_reason; UINT8 trace_level; UINT8 busy_level; /* the current busy level */ - BOOLEAN is_paging; /* TRUE, if paging is in progess */ - BOOLEAN is_inquiry; /* TRUE, if inquiry is in progess */ + BOOLEAN is_paging; /* TRUE, if paging is in progress */ + BOOLEAN is_inquiry; /* TRUE, if inquiry is in progress */ fixed_queue_t *page_queue; BOOLEAN paging; BOOLEAN discing; @@ -951,9 +963,11 @@ typedef struct { typedef struct{ //connection parameters update callback tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb; + // setting packet data length callback + tBTM_SET_PKT_DATA_LENGTH_CBACK *set_pkt_data_length_cb; }tBTM_CallbackFunc; -extern tBTM_CallbackFunc conn_param_update_cb; +extern tBTM_CallbackFunc conn_callback_func; /* security action for L2CAP COC channels */ #define BTM_SEC_OK 1 #define BTM_SEC_ENCRYPT 2 /* encrypt the link with current key */ @@ -1040,6 +1054,7 @@ tACL_CONN *btm_handle_to_acl (UINT16 hci_handle); void btm_read_link_policy_complete (UINT8 *p); void btm_read_rssi_complete (UINT8 *p); void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble); +void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types); void btm_read_link_quality_complete (UINT8 *p); tBTM_STATUS btm_set_packet_types (tACL_CONN *p, UINT16 pkt_types); void btm_process_clk_off_comp_evt (UINT16 hci_handle, UINT16 clock_offset); @@ -1085,6 +1100,9 @@ void btm_create_sync_callback(UINT8 status); void btm_set_phy_callback(UINT8 status); void btm_read_phy_callback(uint8_t hci_status, uint16_t conn_handle, uint8_t tx_phy, uint8_t rx_phy); #endif +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void btm_ble_periodic_adv_sync_trans_complete(UINT16 op_code, UINT8 hci_status, UINT16 conn_handle); +#endif /* Internal functions provided by btm_sco.c ******************************************** */ diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 9fdc789cf9..4140a4d79c 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -90,7 +90,7 @@ static void btu_hcif_loopback_command_evt (void); static void btu_hcif_data_buf_overflow_evt (void); static void btu_hcif_max_slots_changed_evt (void); static void btu_hcif_read_clock_off_comp_evt (UINT8 *p); -static void btu_hcif_conn_pkt_type_change_evt (void); +static void btu_hcif_conn_pkt_type_change_evt (UINT8 *p); static void btu_hcif_qos_violation_evt (UINT8 *p); static void btu_hcif_page_scan_mode_change_evt (void); static void btu_hcif_page_scan_rep_mode_chng_evt (void); @@ -284,7 +284,7 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg) btu_hcif_read_clock_off_comp_evt (p); break; case HCI_CONN_PKT_TYPE_CHANGE_EVT: - btu_hcif_conn_pkt_type_change_evt (); + btu_hcif_conn_pkt_type_change_evt (p); break; case HCI_QOS_VIOLATION_EVT: btu_hcif_qos_violation_evt (p); @@ -949,6 +949,7 @@ static void btu_hcif_esco_connection_chg_evt (UINT8 *p) static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_len, void *p_cplt_cback) { + uint8_t status; switch (opcode) { case HCI_INQUIRY_CANCEL: /* Tell inquiry processing that we are done */ @@ -1011,7 +1012,6 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_ble_clear_white_list_complete(p, evt_len); break; case HCI_BLE_WRITE_ADV_PARAMS: { - uint8_t status; STREAM_TO_UINT8 (status, p); if(status != HCI_SUCCESS) { HCI_TRACE_ERROR("hci write adv params error 0x%x", status); @@ -1019,7 +1019,6 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; } case HCI_BLE_RC_PARAM_REQ_REPLY: { - uint8_t status; STREAM_TO_UINT8 (status, p); if(status != HCI_SUCCESS) { HCI_TRACE_ERROR("hci connection params reply command error 0x%x", status); @@ -1027,7 +1026,6 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; } case HCI_BLE_RC_PARAM_REQ_NEG_REPLY: { - uint8_t status; STREAM_TO_UINT8 (status, p); if(status != HCI_SUCCESS) { HCI_TRACE_ERROR("hci connection params neg reply command error %x", status); @@ -1084,21 +1082,27 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l break; case HCI_BLE_READ_RESOLVABLE_ADDR_LOCAL: + break; case HCI_BLE_SET_ADDR_RESOLUTION_ENABLE: + btm_ble_set_addr_resolution_enable_complete(p, evt_len); + break; case HCI_BLE_SET_RAND_PRIV_ADDR_TIMOUT: + btm_ble_set_rpa_timeout_complete(p, evt_len); break; + case HCI_BLE_SET_PRIVACY_MODE: + btm_ble_set_privacy_mode_complete(p, evt_len); + break; +#endif // #if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) #if (BLE_50_FEATURE_SUPPORT == TRUE) case HCI_BLE_SET_EXT_ADV_PARAM: case HCI_BLE_SET_EXT_ADV_DATA: case HCI_BLE_SET_EXT_SCAN_RSP_DATA: case HCI_BLE_SET_EXT_ADV_ENABLE: { - uint8_t status; STREAM_TO_UINT8 (status, p); HCI_TRACE_EVENT("%s opcode 0x%x status 0x%x", __func__, opcode, status); break; } case HCI_BLE_READ_PHY: { - uint8_t status; uint16_t conn_handle; uint8_t tx_phy; uint8_t rx_phy; @@ -1114,14 +1118,26 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l btm_ble_test_command_complete(p); break; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) -#endif +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + case HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE: + case HCI_BLE_SET_DEFAULT_PAST_PARAMS: + break; + case HCI_BLE_PERIOD_ADV_SYNC_TRANS: + case HCI_BLE_PERIOD_ADV_SET_INFO_TRANS: + case HCI_BLE_SET_PAST_PARAMS: { + UINT16 conn_handle; + STREAM_TO_UINT8(status, p); + STREAM_TO_UINT16(conn_handle, p); + btm_ble_periodic_adv_sync_trans_complete(opcode, status, conn_handle); + break; + } +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #endif /* (BLE_INCLUDED == TRUE) */ default: { if ((opcode & HCI_GRP_VENDOR_SPECIFIC) == HCI_GRP_VENDOR_SPECIFIC) { btm_vsc_complete (p, opcode, evt_len, (tBTM_CMPL_CB *)p_cplt_cback); } - uint8_t status; STREAM_TO_UINT8 (status, p); if(status != HCI_SUCCESS) { HCI_TRACE_ERROR("CC evt: op=0x%x, status=0x%x", opcode, status); @@ -1228,6 +1244,9 @@ static void btu_hcif_command_complete_evt(BT_HDR *response, void *context) static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_cmd, void *p_vsc_status_cback) { + if (status != HCI_SUCCESS){ + HCI_TRACE_WARNING("%s,opcode:0x%04x,status:0x%02x", __func__, opcode,status); + } BD_ADDR bd_addr; UINT16 handle; #if BTM_SCO_INCLUDED == TRUE @@ -1349,6 +1368,9 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c break; #if BLE_INCLUDED == TRUE +#if (BLE_50_FEATURE_SUPPORT == TRUE) + case HCI_BLE_EXT_CREATE_CONN: +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) case HCI_BLE_CREATE_LL_CONN: btm_ble_create_ll_conn_complete(status); break; @@ -1441,7 +1463,6 @@ static void btu_hcif_command_status_evt(uint8_t status, BT_HDR *command, void *c hack->context = context; event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK; - if (btu_task_post(SIG_BTU_HCI_MSG, event, OSI_THREAD_MAX_TIMEOUT) == false) { osi_free(event); } @@ -1746,8 +1767,19 @@ static void btu_hcif_read_clock_off_comp_evt (UINT8 *p) ** Returns void ** *******************************************************************************/ -static void btu_hcif_conn_pkt_type_change_evt (void) +static void btu_hcif_conn_pkt_type_change_evt (UINT8 *p) { + UINT8 status; + UINT16 handle; + UINT16 pkt_types; + + STREAM_TO_UINT8 (status, p); + STREAM_TO_UINT16 (handle, p); + STREAM_TO_UINT16 (pkt_types, p); + + handle = HCID_GET_HANDLE (handle); + + btm_acl_pkt_types_changed(status, handle, pkt_types); } @@ -2314,20 +2346,32 @@ static void btu_ble_scan_req_received_evt(UINT8 *p) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p) { - tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV recv = {0}; + UINT16 conn_handle; + tL2C_LCB *p_lcb = NULL; + tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV past_recv = {0}; - STREAM_TO_UINT8(recv.status, p); - STREAM_TO_UINT16(recv.conn_handle, p); - STREAM_TO_UINT16(recv.service_data, p); - STREAM_TO_UINT16(recv.sync_handle, p); - STREAM_TO_UINT8(recv.adv_sid, p); - STREAM_TO_UINT8(recv.adv_addr_type, p); - STREAM_TO_BDADDR(recv.adv_addr, p); - STREAM_TO_UINT8(recv.adv_phy, p); - STREAM_TO_UINT16(recv.period_adv_interval, p); - STREAM_TO_UINT8(recv.adv_clk_accuracy, p); + if (!p) { + HCI_TRACE_ERROR("%s, Invalid params.", __func__); + return; + } + + STREAM_TO_UINT8(past_recv.status, p); + STREAM_TO_UINT16(conn_handle, p); + STREAM_TO_UINT16(past_recv.service_data, p); + STREAM_TO_UINT16(past_recv.sync_handle, p); + STREAM_TO_UINT8(past_recv.adv_sid, p); + STREAM_TO_UINT8(past_recv.adv_addr_type, p); + STREAM_TO_BDADDR(past_recv.adv_addr, p); + STREAM_TO_UINT8(past_recv.adv_phy, p); + STREAM_TO_UINT16(past_recv.adv_interval, p); + STREAM_TO_UINT8(past_recv.adv_clk_accuracy, p); + + p_lcb = l2cu_find_lcb_by_handle(conn_handle); + if(p_lcb) { + memcpy(past_recv.addr, p_lcb->remote_bd_addr, BD_ADDR_LEN); + } - HCI_TRACE_DEBUG("%s status %x, conn handle %x, sync handle %x", recv.status, recv.conn_handle, recv.sync_handle); + btm_ble_periodic_adv_sync_trans_recv_evt(&past_recv); } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/stack/btu/btu_init.c b/components/bt/host/bluedroid/stack/btu/btu_init.c index 615fbf8019..9ede9c2da9 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_init.c +++ b/components/bt/host/bluedroid/stack/btu/btu_init.c @@ -98,11 +98,11 @@ void btu_init_core(void) #endif #if BLE_INCLUDED == TRUE -#if (defined(GATT_INCLUDED) && GATT_INCLUDED == true) - gatt_init(); -#endif #if (defined(SMP_INCLUDED) && SMP_INCLUDED == TRUE) SMP_Init(); +#endif +#if (defined(GATT_INCLUDED) && GATT_INCLUDED == true) + gatt_init(); #endif btm_ble_init(); #endif diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index 62707bbd2f..8d8056f6d0 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -122,6 +122,7 @@ BOOLEAN GATTS_NVRegister (const tGATT_APPL_INFO *p_cb_info) return status; } +#if GATTS_ROBUST_CACHING_ENABLED static void gatt_update_for_database_change(void) { UINT8 i; @@ -135,7 +136,7 @@ static void gatt_update_for_database_change(void) } } } - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ /******************************************************************************* ** ** Function GATTS_CreateService @@ -414,7 +415,9 @@ BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, UINT16 svc_ GATT_TRACE_DEBUG ("Delete a new service changed item - the service has not yet started"); osi_free(fixed_queue_try_remove_from_queue(gatt_cb.pending_new_srv_start_q, p_buf)); } else { +#if GATTS_ROBUST_CACHING_ENABLED gatt_update_for_database_change(); +#endif /* GATTS_ROBUST_CACHING_ENABLED */ if (gatt_cb.srv_chg_mode == GATTS_SEND_SERVICE_CHANGE_AUTO) { gatt_proc_srv_chg(); } @@ -527,7 +530,11 @@ tGATT_STATUS GATTS_StartService (tGATT_IF gatt_if, UINT16 service_handle, if ( (p_buf = gatt_sr_is_new_srv_chg(&p_list->asgn_range.app_uuid128, &p_list->asgn_range.svc_uuid, p_list->asgn_range.svc_inst)) != NULL) { + + #if GATTS_ROBUST_CACHING_ENABLED gatt_update_for_database_change(); + #endif /* GATTS_ROBUST_CACHING_ENABLED */ + if (gatt_cb.srv_chg_mode == GATTS_SEND_SERVICE_CHANGE_AUTO) { gatt_proc_srv_chg(); } @@ -781,7 +788,7 @@ tGATT_STATUS GATTS_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *v ** ** Function GATTS_GetAttributeValue ** -** Description This function sends to set the attribute value . +** Description This function sends to get the attribute value . ** ** Parameter attr_handle: the attribute handle ** length:the attribute value length in the database @@ -807,6 +814,26 @@ tGATT_STATUS GATTS_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 * status = gatts_get_attribute_value(&p_decl->svc_db, attr_handle, length, value); return status; } + +/******************************************************************************* +** +** Function GATTS_GetAttributeValueInternal +** +** Description This function sends to get the attribute value of internal gatt and gap service. +** +** Parameter attr_handle: the attribute handle +** length:the attribute value length in the database +** value: the attribute value out put +* +** +** Returns tGATT_STATUS - GATT status indicating success or failure in +** retrieving the attribute value. +** +*******************************************************************************/ +tGATT_STATUS GATTS_GetAttributeValueInternal(UINT16 attr_handle, UINT16 *length, UINT8 **value) +{ + return gatts_get_attr_value_internal(attr_handle, length, value); +} #endif ///GATTS_INCLUDED == TRUE @@ -1769,4 +1796,10 @@ tGATT_STATUS GATTS_HandleMultiValueNotification (UINT16 conn_id, tGATT_HLV *tupl return cmd_sent; } +tGATT_STATUS GATTS_ShowLocalDatabase(void) +{ + gatts_show_local_database(); + return GATT_SUCCESS; +} + #endif diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_attr.c b/components/bt/host/bluedroid/stack/gatt/gatt_attr.c index 441d0398e8..3ab573426a 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_attr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_attr.c @@ -40,7 +40,13 @@ #define BLE_GATT_CL_SUPP_FEAT_BITMASK 0x07 #define GATTP_MAX_NUM_INC_SVR 0 -#define GATTP_MAX_CHAR_NUM 4 + +#if GATTS_ROBUST_CACHING_ENABLED +#define GATTP_MAX_CHAR_NUM 5 +#else +#define GATTP_MAX_CHAR_NUM 2 +#endif /* GATTS_ROBUST_CACHING_ENABLED */ + #define GATTP_MAX_ATTR_NUM (GATTP_MAX_CHAR_NUM * 2 + GATTP_MAX_NUM_INC_SVR + 1) #define GATTP_MAX_CHAR_VALUE_SIZE 50 @@ -196,26 +202,15 @@ tGATT_STATUS gatt_proc_read (UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_READ_RE GATT_TRACE_DEBUG("%s handle %x", __func__, p_data->handle); - UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id); - tGATT_TCB *tcb = gatt_get_tcb_by_idx(tcb_idx); - if (p_data->is_long) { p_rsp->attr_value.offset = p_data->offset; } p_rsp->attr_value.handle = p_data->handle; +#if GATTS_ROBUST_CACHING_ENABLED - /* handle request for reading service changed */ - if (p_data->handle == gatt_cb.handle_of_h_r) { - status = GATTS_GetAttributeValue(p_data->handle, &len, &value); - if(status == GATT_SUCCESS && len > 0 && value) { - if(len > GATT_MAX_ATTR_LEN) { - len = GATT_MAX_ATTR_LEN; - } - p_rsp->attr_value.len = len; - memcpy(p_rsp->attr_value.value, value, len); - } - } + UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id); + tGATT_TCB *tcb = gatt_get_tcb_by_idx(tcb_idx); /* handle request for reading client supported features */ if (p_data->handle == gatt_cb.handle_of_cl_supported_feat) { @@ -224,7 +219,7 @@ tGATT_STATUS gatt_proc_read (UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_READ_RE } p_rsp->attr_value.len = 1; memcpy(p_rsp->attr_value.value, &tcb->cl_supp_feat, 1); - status = GATT_SUCCESS; + return GATT_SUCCESS; } /* handle request for reading database hash */ @@ -232,19 +227,28 @@ tGATT_STATUS gatt_proc_read (UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_READ_RE p_rsp->attr_value.len = BT_OCTET16_LEN; memcpy(p_rsp->attr_value.value, gatt_cb.database_hash, BT_OCTET16_LEN); gatt_sr_update_cl_status(tcb, true); - status = GATT_SUCCESS; + return GATT_SUCCESS; } /* handle request for reading server supported features */ if (p_data->handle == gatt_cb.handle_of_sr_supported_feat) { p_rsp->attr_value.len = 1; memcpy(p_rsp->attr_value.value, &gatt_cb.gatt_sr_supported_feat_mask, 1); - status = GATT_SUCCESS; + return GATT_SUCCESS; + } +#endif /* GATTS_ROBUST_CACHING_ENABLED */ + /* handle request for reading service changed des and the others */ + status = GATTS_GetAttributeValue(p_data->handle, &len, &value); + if(status == GATT_SUCCESS && len > 0 && value) { + if(len > GATT_MAX_ATTR_LEN) { + len = GATT_MAX_ATTR_LEN; + } + p_rsp->attr_value.len = len; + memcpy(p_rsp->attr_value.value, value, len); } - return status; } - +#if GATTS_ROBUST_CACHING_ENABLED static tGATT_STATUS gatt_sr_write_cl_supp_feat(UINT16 conn_id, tGATT_WRITE_REQ *p_data) { UINT8 val_new; @@ -289,7 +293,7 @@ static tGATT_STATUS gatt_sr_write_cl_supp_feat(UINT16 conn_id, tGATT_WRITE_REQ * #endif return GATT_SUCCESS; } - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ /****************************************************************************** ** ** Function gatt_proc_write_req @@ -304,7 +308,7 @@ tGATT_STATUS gatt_proc_write_req(UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_WRI if(p_data->len > GATT_MAX_ATTR_LEN) { p_data->len = GATT_MAX_ATTR_LEN; } - +#if GATTS_ROBUST_CACHING_ENABLED if (p_data->handle == gatt_cb.handle_of_h_r) { return GATT_WRITE_NOT_PERMIT; } @@ -320,7 +324,7 @@ tGATT_STATUS gatt_proc_write_req(UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_WRI if (p_data->handle == gatt_cb.handle_of_sr_supported_feat) { return GATT_WRITE_NOT_PERMIT; } - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ return GATTS_SetAttributeValue(p_data->handle, p_data->len, p_data->value); @@ -473,7 +477,7 @@ void gatt_profile_db_init (void) }; GATTS_AddCharDescriptor (service_handle, GATT_PERM_READ | GATT_PERM_WRITE , &descr_uuid, &attr_val, NULL); - +#if GATTS_ROBUST_CACHING_ENABLED /* add Client Supported Features characteristic */ uuid.uu.uuid16 = GATT_UUID_CLIENT_SUP_FEAT; gatt_cb.handle_of_cl_supported_feat = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ | GATT_PERM_WRITE, @@ -486,7 +490,7 @@ void gatt_profile_db_init (void) /* add Server Supported Features characteristic */ uuid.uu.uuid16 = GATT_UUID_SERVER_SUP_FEAT; gatt_cb.handle_of_sr_supported_feat = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ, NULL, NULL); - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ /* start service */ status = GATTS_StartService (gatt_cb.gatt_if, service_handle, GATTP_TRANSPORT_SUPPORTED ); @@ -692,6 +696,7 @@ void GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, tBT_TRANSP gatt_cl_start_config_ccc(p_clcb); } +#if GATTS_ROBUST_CACHING_ENABLED /******************************************************************************* ** ** Function gatt_sr_is_cl_robust_caching_supported @@ -703,14 +708,8 @@ void GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, tBT_TRANSP *******************************************************************************/ static BOOLEAN gatt_sr_is_cl_robust_caching_supported(tGATT_TCB *p_tcb) { - // Server robust caching not enabled - if (!GATTS_ROBUST_CACHING_ENABLED) { - return FALSE; - } - return (p_tcb->cl_supp_feat & BLE_GATT_CL_SUPP_FEAT_ROBUST_CACHING_BITMASK); } - /******************************************************************************* ** ** Function gatt_sr_is_cl_change_aware @@ -794,4 +793,5 @@ void gatt_sr_update_cl_status(tGATT_TCB *p_tcb, BOOLEAN chg_aware) GATT_TRACE_DEBUG("%s status %d", __func__, chg_aware); } +#endif /* GATTS_ROBUST_CACHING_ENABLED */ #endif /* BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_db.c b/components/bt/host/bluedroid/stack/gatt/gatt_db.c index ed03d0453b..e84580bc95 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_db.c @@ -780,7 +780,7 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, ** Returns Status of the operation. ** *******************************************************************************/ -static tGATT_STATUS gatts_get_attr_value_internal(UINT16 attr_handle, UINT16 *length, UINT8 **value) +tGATT_STATUS gatts_get_attr_value_internal(UINT16 attr_handle, UINT16 *length, UINT8 **value) { UINT8 i; tGATT_READ_REQ read_req; @@ -788,6 +788,17 @@ static tGATT_STATUS gatts_get_attr_value_internal(UINT16 attr_handle, UINT16 *le tGATT_SR_REG *p_rcb = gatt_cb.sr_reg; UINT8 service_uuid[LEN_UUID_128] = {0}; + if (length == NULL){ + GATT_TRACE_ERROR("gatts_get_attr_value_internal Fail:length is NULL.\n"); + return GATT_INVALID_PDU; + } + + if (value == NULL){ + GATT_TRACE_ERROR("gatts_get_attr_value_internal Fail:value is NULL.\n"); + *length = 0; + return GATT_INVALID_PDU; + } + // find the service by handle for (i = 0; i < GATT_MAX_SR_PROFILES; i++, p_rcb++) { if (p_rcb->in_use && p_rcb->s_hdl <= attr_handle && p_rcb->e_hdl >= attr_handle) { @@ -868,10 +879,6 @@ tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, return GATT_INVALID_PDU; } - if (gatts_get_attr_value_internal(attr_handle, length, value) == GATT_SUCCESS) { - return GATT_SUCCESS; - } - p_cur = (tGATT_ATTR16 *) p_db->p_attr_list; while (p_cur != NULL) { @@ -1166,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) { @@ -1234,15 +1241,18 @@ tGATT_STATUS gatts_write_attr_perm_check (tGATT_SVC_DB *p_db, UINT8 op_code, // btla-specific ++ else if ( (p_attr->uuid_type == GATT_ATTR_UUID_TYPE_16) && (p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG || - p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG) ) + p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG || + p_attr->uuid == GATT_UUID_CLIENT_SUP_FEAT || + p_attr->uuid == GATT_UUID_GAP_ICON + ) ) // btla-specific -- { - 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"); + if (op_code == GATT_REQ_PREPARE_WRITE) { /* does not allow write blob */ + status = GATT_REQ_NOT_SUPPORTED; + GATT_TRACE_ERROR( "gatts_write_attr_perm_check - GATT_REQ_NOT_SUPPORTED,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_ATTR_LEN,handle:0x%04x",handle); } else { status = GATT_SUCCESS; } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_main.c b/components/bt/host/bluedroid/stack/gatt/gatt_main.c index 9f437f94c8..d76aefe95b 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_main.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_main.c @@ -194,9 +194,7 @@ void gatt_free(void) #endif /* #if (GATTS_INCLUDED == TRUE) */ } list_free(gatt_cb.p_tcb_list); -#if (GATTC_INCLUDED == TRUE) list_free(gatt_cb.p_clcb_list); -#endif //(GATTC_INCLUDED == TRUE) #if (GATTS_INCLUDED == TRUE) for (int i = 0; i < GATT_MAX_SR_PROFILES; i++) { @@ -1233,4 +1231,20 @@ void gatt_set_local_mtu(uint16_t mtu) gatt_default.local_mtu = mtu; } +uint8_t gatt_tcb_active_count(void) +{ + tGATT_TCB *p_tcb = NULL; + list_node_t *p_node = NULL; + uint8_t count = 0; + + for(p_node = list_begin(gatt_cb.p_tcb_list); p_node; p_node = list_next(p_node)) { + p_tcb = list_node(p_node); + if (p_tcb && p_tcb->in_use && (p_tcb->ch_state != GATT_CH_CLOSE)) { + count++; + } + } + + return count; +} + #endif /* BLE_INCLUDED */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c index 1510f44871..79e161c1e3 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c @@ -1448,8 +1448,9 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand } if ((prepare_record->error_code_app == GATT_SUCCESS) - && ((status == GATT_INVALID_OFFSET) || (status == GATT_INVALID_ATTR_LEN))){ - prepare_record->error_code_app = status; + // update prepare write status for excute write request + && (status == GATT_INVALID_OFFSET || status == GATT_INVALID_ATTR_LEN || status == GATT_REQ_NOT_SUPPORTED)) { + prepare_record->error_code_app = status; } } @@ -1680,9 +1681,10 @@ static BOOLEAN gatts_proc_ind_ack(tGATT_TCB *p_tcb, UINT16 ack_handle) gatts_proc_srv_chg_ind_ack(p_tcb); /* there is no need to inform the application since srv chg is handled internally by GATT */ continue_processing = FALSE; - +#if GATTS_ROBUST_CACHING_ENABLED /* after receiving ack of svc_chg_ind, reset client status */ gatt_sr_update_cl_status(p_tcb, true); +#endif /* GATTS_ROBUST_CACHING_ENABLED */ } gatts_chk_pending_ind(p_tcb); @@ -1729,6 +1731,7 @@ void gatts_process_value_conf(tGATT_TCB *p_tcb, UINT8 op_code) } } +#if GATTS_ROBUST_CACHING_ENABLED static BOOLEAN gatts_handle_db_out_of_sync(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) { @@ -1808,6 +1811,7 @@ static BOOLEAN gatts_handle_db_out_of_sync(tGATT_TCB *p_tcb, UINT8 op_code, return should_ignore; } +#endif /* GATTS_ROBUST_CACHING_ENABLED */ /******************************************************************************* ** ** Function gatt_server_handle_client_req @@ -1839,11 +1843,12 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, } /* otherwise, ignore the pkt */ } else { +#if GATTS_ROBUST_CACHING_ENABLED // handle database out of sync if (gatts_handle_db_out_of_sync(p_tcb, op_code, len, p_data)) { return; } - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ switch (op_code) { case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */ case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c index f332292179..3e2974edb0 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr_hash.c @@ -8,6 +8,36 @@ #include "smp_int.h" #if (BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE) + +const char *const gatt_attr_name[] = { + "primary service", + "secondary service", + "included service", + "characteristic", +}; + +const char *const gatt_char_desc_name[] = { + "characteristic extended properties", + "characteristic user description", + "client characteristic configuration", + "server characteristic configuration", + "characteristic presentation format", + "characteristic aggregate format", +}; + +static const char *gatt_get_attr_name(UINT16 uuid) +{ + if (uuid >= GATT_UUID_PRI_SERVICE && uuid <= GATT_UUID_CHAR_DECLARE) { + return gatt_attr_name[uuid - GATT_UUID_PRI_SERVICE]; + } + + if (uuid >= GATT_UUID_CHAR_EXT_PROP && uuid <= GATT_UUID_CHAR_AGG_FORMAT) { + return gatt_char_desc_name[uuid - GATT_UUID_CHAR_EXT_PROP]; + } + + return "Unknown Attribute"; +} + static void attr_uuid_to_bt_uuid(void *p_attr, tBT_UUID *p_uuid) { tGATT_ATTR16 *p_attr16 = (tGATT_ATTR16 *)p_attr; @@ -46,7 +76,7 @@ static size_t calculate_database_info_size(void) // Included service declaration len += 8 + p_attr->p_value->incl_handle.service_type.len; } else if (p_attr->uuid == GATT_UUID_CHAR_DECLARE) { - tBT_UUID char_uuid; + tBT_UUID char_uuid = {0}; // Characteristic declaration p_attr = (tGATT_ATTR16 *)p_attr->p_next; attr_uuid_to_bt_uuid((void *)p_attr, &char_uuid); @@ -96,7 +126,7 @@ static void fill_database_info(UINT8 *p_data) UINT16_TO_STREAM(p_data, p_attr->p_value->incl_handle.e_handle); gatt_build_uuid_to_stream(&p_data, p_attr->p_value->incl_handle.service_type); } else if (p_attr->uuid == GATT_UUID_CHAR_DECLARE) { - tBT_UUID char_uuid; + tBT_UUID char_uuid = {0}; // Characteristic declaration UINT16_TO_STREAM(p_data, p_attr->handle); UINT16_TO_STREAM(p_data, GATT_UUID_CHAR_DECLARE); @@ -165,4 +195,62 @@ tGATT_STATUS gatts_calculate_datebase_hash(BT_OCTET16 hash) osi_free(data_buf); return GATT_SUCCESS; } + +void gatts_show_local_database(void) +{ + UINT8 i; + tGATT_SVC_DB *p_db; + tGATT_ATTR16 *p_attr; + + printf("\n================= GATTS DATABASE DUMP START =================\n"); + for (i = 0; i < GATT_MAX_SR_PROFILES; i++) { + p_db = gatt_cb.sr_reg[i].p_db; + if (p_db && p_db->p_attr_list) { + p_attr = (tGATT_ATTR16 *)p_db->p_attr_list; + while (p_attr) { + switch (p_attr->uuid) { + case GATT_UUID_PRI_SERVICE: + case GATT_UUID_SEC_SERVICE: + // Service declaration + printf("%s\n", gatt_get_attr_name(p_attr->uuid)); + printf("\tuuid %s\n", gatt_uuid_to_str(&p_attr->p_value->uuid)); + printf("\thandle %d\n", p_attr->handle); + printf("\tend_handle %d\n",p_db->end_handle-1); + break; + case GATT_UUID_INCLUDE_SERVICE: + // Included service declaration + printf("%s\n", gatt_get_attr_name(p_attr->uuid)); + printf("\tuuid %s\t", gatt_uuid_to_str(&p_attr->p_value->incl_handle.service_type)); + printf("\thandle %d\n", p_attr->p_value->incl_handle.s_handle); + printf("\tend_handle %d\n", p_attr->p_value->incl_handle.e_handle); + break; + case GATT_UUID_CHAR_DECLARE: { + tBT_UUID char_uuid; + tGATT_ATTR16 *p_char_val; + p_char_val = (tGATT_ATTR16 *)p_attr->p_next; + attr_uuid_to_bt_uuid((void *)p_char_val, &char_uuid); + + printf("%s\n", gatt_get_attr_name(p_attr->uuid)); + printf("\tuuid %s\n", gatt_uuid_to_str(&char_uuid)); + printf("\tdef_handle %d\n", p_attr->handle); + printf("\tval_handle %d\n", p_attr->p_value->char_decl.char_val_handle); + printf("\tperm 0x%04x, prop 0x%02x\n", p_char_val->permission, p_attr->p_value->char_decl.property); + break; + } + case GATT_UUID_CHAR_EXT_PROP: + case GATT_UUID_CHAR_DESCRIPTION: + case GATT_UUID_CHAR_CLIENT_CONFIG: + case GATT_UUID_CHAR_SRVR_CONFIG: + case GATT_UUID_CHAR_PRESENT_FORMAT: + case GATT_UUID_CHAR_AGG_FORMAT: + printf("%s\n", gatt_get_attr_name(p_attr->uuid)); + printf("\thandle %d\n", p_attr->handle); + break; + } + p_attr = (tGATT_ATTR16 *) p_attr->p_next; + } + } + } + printf("================= GATTS DATABASE DUMP END =================\n"); +} #endif /* BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index 2dbbcd8d8a..621b246888 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -1090,9 +1090,9 @@ tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) p_tcb->transport = transport; } memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN); -#if (GATTS_INCLUDED == TRUE) +#if GATTS_ROBUST_CACHING_ENABLED gatt_sr_init_cl_status(p_tcb); -#endif ///GATTS_INCLUDED == TRUE +#endif /* GATTS_ROBUST_CACHING_ENABLED */ } return p_tcb; } diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index a34e5d1eb4..1161da62b5 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -539,6 +539,7 @@ typedef struct { tGATT_PROFILE_CLCB profile_clcb[GATT_MAX_APPS]; #endif ///GATTS_INCLUDED == TRUE UINT16 handle_of_h_r; /* Handle of the handles reused characteristic value */ +#if GATTS_ROBUST_CACHING_ENABLED UINT16 handle_of_database_hash; UINT16 handle_of_cl_supported_feat; UINT16 handle_of_sr_supported_feat; @@ -546,6 +547,7 @@ typedef struct { UINT8 gatt_sr_supported_feat_mask; UINT8 gatt_cl_supported_feat_mask; +#endif tGATT_APPL_INFO cb_info; @@ -754,7 +756,7 @@ extern UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, extern tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, UINT16 length, UINT8 *value); - +extern tGATT_STATUS gatts_get_attr_value_internal(UINT16 attr_handle, UINT16 *length, UINT8 **value); extern tGATT_STATUS gatts_get_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, UINT16 *length, UINT8 **value); extern BOOLEAN gatts_is_auto_response(UINT16 attr_handle); @@ -778,6 +780,8 @@ extern uint16_t gatt_get_local_mtu(void); extern void gatt_set_local_mtu(uint16_t mtu); extern tGATT_STATUS gatts_calculate_datebase_hash(BT_OCTET16 hash); +extern void gatts_show_local_database(void); + extern BOOLEAN gatt_sr_is_cl_change_aware(tGATT_TCB *p_tcb); extern void gatt_sr_init_cl_status(tGATT_TCB *p_tcb); extern void gatt_sr_update_cl_status(tGATT_TCB *tcb, BOOLEAN chg_aware); diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 64e9a67a73..52a2b2dc09 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; \ @@ -1169,7 +1190,9 @@ UINT8 btsnd_hcic_ble_enhand_rx_test(UINT8 rx_channel, UINT8 phy, UINT8_TO_STREAM(pp, phy); UINT8_TO_STREAM(pp, modulation_idx); - return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + + return TRUE; } UINT8 btsnd_hcic_ble_enhand_tx_test(UINT8 tx_channel, UINT8 len, @@ -1191,7 +1214,9 @@ UINT8 btsnd_hcic_ble_enhand_tx_test(UINT8 tx_channel, UINT8 len, UINT8_TO_STREAM(pp, packect); UINT8_TO_STREAM(pp, phy); - return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + + return TRUE; } UINT8 btsnd_hcic_ble_set_extend_rand_address(UINT8 adv_handle, BD_ADDR rand_addr) @@ -1273,17 +1298,16 @@ UINT8 btsnd_hcic_ble_set_ext_adv_data(UINT8 adv_handle, UINT8_TO_STREAM(pp, operation); UINT8_TO_STREAM(pp, fragment_prefrence); - if (p_data != NULL && data_len > 0) { - if (data_len > HCIC_PARAM_SIZE_EXT_ADV_WRITE_DATA) { - data_len = HCIC_PARAM_SIZE_EXT_ADV_WRITE_DATA; - } + if (data_len > HCIC_PARAM_SIZE_EXT_ADV_WRITE_DATA) { + data_len = HCIC_PARAM_SIZE_EXT_ADV_WRITE_DATA; + } - UINT8_TO_STREAM (pp, data_len); + UINT8_TO_STREAM (pp, data_len); + if (p_data != NULL && data_len > 0){ ARRAY_TO_STREAM (pp, p_data, data_len); - } else { - return FALSE; } + uint8_t status = btu_hcif_send_cmd_sync (LOCAL_BR_EDR_CONTROLLER_ID, p); return status; @@ -1309,16 +1333,13 @@ UINT8 btsnd_hcic_ble_set_ext_adv_scan_rsp_data(UINT8 adv_handle, memset(pp, 0, data_len); - if (p_data != NULL && data_len > 0) { - if (data_len > HCIC_PARAM_SIZE_EXT_ADV_WRITE_DATA) { - data_len = HCIC_PARAM_SIZE_EXT_ADV_WRITE_DATA; - } - - UINT8_TO_STREAM (pp, data_len); + if (data_len > HCIC_PARAM_SIZE_EXT_ADV_WRITE_DATA) { + data_len = HCIC_PARAM_SIZE_EXT_ADV_WRITE_DATA; + } + UINT8_TO_STREAM (pp, data_len); + if (p_data != NULL && data_len > 0) { ARRAY_TO_STREAM (pp, p_data, data_len); - } else { - return FALSE; } return btu_hcif_send_cmd_sync (LOCAL_BR_EDR_CONTROLLER_ID, p); @@ -1455,16 +1476,14 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_data(UINT8 adv_handle, //memset(pp, 0, len); - if (p_data != NULL && len > 0) { - if (len > HCIC_PARAM_SIZE_WRITE_PERIODIC_ADV_DATA) { - len = HCIC_PARAM_SIZE_WRITE_PERIODIC_ADV_DATA; - } + if (len > HCIC_PARAM_SIZE_WRITE_PERIODIC_ADV_DATA) { + len = HCIC_PARAM_SIZE_WRITE_PERIODIC_ADV_DATA; + } - UINT8_TO_STREAM (pp, len); + UINT8_TO_STREAM (pp, len); + if (p_data != NULL && len > 0) { ARRAY_TO_STREAM (pp, p_data, len); - } else { - return FALSE; } return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); @@ -1608,14 +1627,14 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn(tHCI_CreatExtConn *p_conn) } -BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 filter_policy, UINT8 adv_sid, +BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 option, UINT8 adv_sid, UINT8 adv_addr_type, BD_ADDR adv_addr, UINT16 sync_timeout, UINT8 unused) { BT_HDR *p; UINT8 *pp; - HCI_TRACE_EVENT("%s, filter_policy = %d, adv_sid = %d, adv_addr_type = %d, sync_timeout = %d, unused = %d", - __func__, filter_policy, adv_sid, adv_addr_type, sync_timeout, unused); + HCI_TRACE_EVENT("%s, option = %d, adv_sid = %d, adv_addr_type = %d, sync_timeout = %d, unused = %d", + __func__, option, adv_sid, adv_addr_type, sync_timeout, unused); HCI_TRACE_EVENT("addr %02x %02x %02x %02x %02x %02x", adv_addr[0], adv_addr[1], adv_addr[2], adv_addr[3], adv_addr[4], adv_addr[5]); uint16_t skip = 0; @@ -1623,7 +1642,7 @@ BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 filter_policy, UINT8 adv_s UINT16_TO_STREAM(pp, HCI_BLE_PERIOD_ADV_CREATE_SYNC); UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PERIODIC_ADV_CREATE_SYNC + 2); - UINT8_TO_STREAM(pp, filter_policy); + UINT8_TO_STREAM(pp, option); UINT8_TO_STREAM(pp, adv_sid); UINT8_TO_STREAM(pp, adv_addr_type); BDADDR_TO_STREAM(pp, adv_addr); @@ -1789,12 +1808,12 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enab BT_HDR *p; UINT8 *pp; - HCIC_BLE_CMD_CREATED(p, pp, 3); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_PERIODIC_ADV_RECV_ENABLE); pp = (UINT8 *)(p + 1); UINT16_TO_STREAM(pp, HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE); - UINT8_TO_STREAM(pp, 3); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PERIODIC_ADV_RECV_ENABLE); UINT16_TO_STREAM(pp, sync_handle); UINT8_TO_STREAM(pp, enable); @@ -1802,59 +1821,61 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enab return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } -UINT8 btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle) +BOOLEAN btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle) { BT_HDR *p; UINT8 *pp; - HCIC_BLE_CMD_CREATED(p, pp, 6); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_PERIODIC_ADV_SYNC_TRANS); pp = (UINT8 *)(p + 1); UINT16_TO_STREAM(pp, HCI_BLE_PERIOD_ADV_SYNC_TRANS); - UINT8_TO_STREAM(pp, 6); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PERIODIC_ADV_SYNC_TRANS); UINT16_TO_STREAM(pp, conn_handle); UINT16_TO_STREAM(pp, service_data); UINT16_TO_STREAM(pp, sync_handle); - return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; } -UINT8 btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle) +BOOLEAN btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle) { BT_HDR *p; UINT8 *pp; HCI_TRACE_DEBUG("%s conn handle %x, adv handle %x", __func__, conn_handle, adv_handle); - HCIC_BLE_CMD_CREATED(p, pp, 5); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_PERIODIC_ADV_SET_INFO_TRANS); pp = (UINT8 *)(p + 1); UINT16_TO_STREAM(pp, HCI_BLE_PERIOD_ADV_SET_INFO_TRANS); - UINT8_TO_STREAM(pp, 5); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_PERIODIC_ADV_SET_INFO_TRANS); UINT16_TO_STREAM(pp, conn_handle); UINT16_TO_STREAM(pp, service_data); UINT8_TO_STREAM(pp, adv_handle); - return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; } -UINT8 btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) +BOOLEAN btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) { BT_HDR *p; UINT8 *pp; HCI_TRACE_DEBUG("%s conn handle %x, mode %x, sync timeout %x", __func__, conn_handle, mode, sync_timeout); - HCIC_BLE_CMD_CREATED(p, pp, 8); + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_PAST_PARAMS); pp = (UINT8 *)(p + 1); - UINT16_TO_STREAM(pp, HCI_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS); - UINT8_TO_STREAM(pp, 8); + UINT16_TO_STREAM(pp, HCI_BLE_SET_PAST_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PAST_PARAMS); UINT16_TO_STREAM(pp, conn_handle); UINT8_TO_STREAM(pp, mode); @@ -1862,7 +1883,54 @@ UINT8 btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT UINT16_TO_STREAM(pp, sync_timeout); UINT8_TO_STREAM(pp, cte_type); + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return TRUE; +} + +UINT8 btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type) +{ + BT_HDR *p; + UINT8 *pp; + + HCI_TRACE_DEBUG("%s mode %x, skip %x, sync timeout %x", __func__, mode, skip, sync_timeout); + + HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_SET_DEFAULT_PAST_PARAMS); + + pp = (UINT8 *)(p + 1); + + UINT16_TO_STREAM(pp, HCI_BLE_SET_DEFAULT_PAST_PARAMS); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_DEFAULT_PAST_PARAMS); + + UINT8_TO_STREAM(pp, mode); + UINT16_TO_STREAM(pp, skip); + UINT16_TO_STREAM(pp, sync_timeout); + UINT8_TO_STREAM(pp, cte_type); + return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); } #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + +UINT8 btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode) +{ + BT_HDR *p; + UINT8 *pp; + + if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_SET_PRIVACY_MODE)) == NULL) { + return (FALSE); + } + + pp = (UINT8 *)(p + 1); + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_PRIVACY_MODE; + p->offset = 0; + + UINT16_TO_STREAM(pp, HCI_BLE_SET_PRIVACY_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_PRIVACY_MODE); + + UINT8_TO_STREAM(pp, addr_type); + BDADDR_TO_STREAM(pp, addr); + UINT8_TO_STREAM(pp, privacy_mode); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + return (TRUE); +} #endif diff --git a/components/bt/host/bluedroid/stack/hid/hidd_conn.c b/components/bt/host/bluedroid/stack/hid/hidd_conn.c index 05a14799e0..5a8e36ee59 100644 --- a/components/bt/host/bluedroid/stack/hid/hidd_conn.c +++ b/components/bt/host/bluedroid/stack/hid/hidd_conn.c @@ -231,7 +231,7 @@ static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result) tHID_CONN *p_hcon = &hd_cb.device.conn; HIDD_TRACE_EVENT("%s: cid=%04x result=%d, conn_state=%d", __func__, cid, result, p_hcon->conn_state); if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } if (!(p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) || @@ -243,10 +243,12 @@ static void hidd_l2cif_connect_cfm(uint16_t cid, uint16_t result) } if (result != L2CAP_CONN_OK) { HIDD_TRACE_WARNING("%s: connection failed, now disconnect", __func__); - if (cid == p_hcon->ctrl_cid) + if (cid == p_hcon->ctrl_cid) { p_hcon->ctrl_cid = 0; - else + } else { p_hcon->intr_cid = 0; + } + hidd_conn_disconnect(); hd_cb.callback(hd_cb.device.addr, HID_DHOST_EVT_CLOSE, HID_L2CAP_CONN_FAIL | (uint32_t)result, NULL); return; @@ -278,7 +280,7 @@ static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO *p_cfg) HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid); p_hcon = &hd_cb.device.conn; if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } if ((!p_cfg->mtu_present) || (p_cfg->mtu > HID_DEV_MTU_SIZE)) @@ -297,7 +299,8 @@ static void hidd_l2cif_config_ind(uint16_t cid, tL2CAP_CFG_INFO *p_cfg) // update flags if (cid == p_hcon->ctrl_cid) { p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE; - if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE)) { + if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE) && + (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) { p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; if ((p_hcon->intr_cid = L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) { p_hcon->conn_state = HID_CONN_STATE_UNUSED; @@ -330,7 +333,7 @@ static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO *p_cfg) HIDD_TRACE_EVENT("%s: cid=%04x pcfg->result=%d", __func__, cid, p_cfg->result); p_hcon = &hd_cb.device.conn; if (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } if (p_hcon->intr_cid == cid && p_cfg->result == L2CAP_CFG_UNACCEPTABLE_PARAMS && p_cfg->qos_present) { @@ -357,7 +360,8 @@ static void hidd_l2cif_config_cfm(uint16_t cid, tL2CAP_CFG_INFO *p_cfg) // update flags if (cid == p_hcon->ctrl_cid) { p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE; - if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE)) { + if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE) && + (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) { p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; if ((p_hcon->intr_cid = L2CA_ConnectReq(HID_PSM_INTERRUPT, hd_cb.device.addr)) == 0) { p_hcon->conn_state = HID_CONN_STATE_UNUSED; @@ -389,11 +393,14 @@ static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed) HIDD_TRACE_EVENT("%s: cid=%04x ack_needed=%d", __func__, cid, ack_needed); p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } - if (ack_needed) + + if (ack_needed) { L2CA_DisconnectRsp(cid); + } + if (cid == p_hcon->ctrl_cid) { p_hcon->ctrl_cid = 0; p_hcon->conn_state = HID_CONN_STATE_DISCONNECTING_CTRL; @@ -417,7 +424,7 @@ static void hidd_l2cif_disconnect_ind(uint16_t cid, bool ack_needed) * * Function hidd_l2cif_disconnect_cfm * - * Description Handles L2CAP disconection response + * Description Handles L2CAP disconnection response * * Returns void * @@ -428,7 +435,7 @@ static void hidd_l2cif_disconnect_cfm(uint16_t cid, uint16_t result) HIDD_TRACE_EVENT("%s: cid=%04x result=%d", __func__, cid, result); p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } if (cid == p_hcon->ctrl_cid) { @@ -465,7 +472,7 @@ static void hidd_l2cif_cong_ind(uint16_t cid, bool congested) HIDD_TRACE_EVENT("%s: cid=%04x congested=%d", __func__, cid, congested); p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); return; } if (congested) { @@ -492,7 +499,7 @@ static void hidd_l2cif_data_ind(uint16_t cid, BT_HDR *p_msg) HIDD_TRACE_EVENT("%s: cid=%04x", __func__, cid); p_hcon = &hd_cb.device.conn; if (p_hcon->conn_state == HID_CONN_STATE_UNUSED || (p_hcon->ctrl_cid != cid && p_hcon->intr_cid != cid)) { - HIDD_TRACE_WARNING("%s: unknown cid", __func__); + HIDD_TRACE_WARNING("%s: unknown cid=%04x", __func__, cid); osi_free(p_msg); return; } @@ -645,7 +652,7 @@ tHID_STATUS hidd_conn_initiate(void) p_dev->conn.ctrl_cid = 0; p_dev->conn.intr_cid = 0; p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL; - p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG; + p_dev->conn.conn_flags |= HID_CONN_FLAGS_IS_ORIG; BTM_SetOutService(p_dev->addr, BTM_SEC_SERVICE_HIDD_SEC_CTRL, HIDD_SEC_CHN); /* Check if L2CAP started the connection process */ if ((p_dev->conn.ctrl_cid = L2CA_ConnectReq(HID_PSM_CONTROL, p_dev->addr)) == 0) { @@ -709,11 +716,14 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param uint8_t *p_out; uint16_t cid; uint16_t buf_size; + HIDD_TRACE_VERBOSE("%s: channel(%d), msg_type(%d), len(%d)", __func__, channel, msg_type, len); + p_hcon = &hd_cb.device.conn; if (p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) { return HID_ERR_CONGESTED; } + switch (msg_type) { case HID_TRANS_HANDSHAKE: case HID_TRANS_CONTROL: @@ -760,7 +770,8 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param } hd_cb.pending_data = p_buf; if (hd_cb.device.conn.conn_state == HID_CONN_STATE_UNUSED) { - hidd_conn_initiate(); + HIDD_TRACE_WARNING("%s: try to reconnect!", __func__); + return hidd_conn_initiate(); } return HID_SUCCESS; } @@ -772,7 +783,7 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param } #endif HIDD_TRACE_VERBOSE("%s: report sent", __func__); - if (!L2CA_DataWrite(cid, p_buf)) + if (L2CA_DataWrite(cid, p_buf) == L2CAP_DW_FAILED) return (HID_ERR_CONGESTED); return (HID_SUCCESS); } diff --git a/components/bt/host/bluedroid/stack/hid/hidh_api.c b/components/bt/host/bluedroid/stack/hid/hidh_api.c index ea8e73a75c..ec072845ea 100644 --- a/components/bt/host/bluedroid/stack/hid/hidh_api.c +++ b/components/bt/host/bluedroid/stack/hid/hidh_api.c @@ -651,4 +651,23 @@ BOOLEAN hid_known_hid_device (BD_ADDR bd_addr) return FALSE; } +BOOLEAN HID_HostConnectOrig(UINT8 dev_handle) +{ + BOOLEAN ret = FALSE; + + do { + if (!hh_cb.reg_flag) { + break; + } + + if ((dev_handle >= HID_HOST_MAX_DEVICES) || (!hh_cb.devices[dev_handle].in_use)) { + break; + } + + ret = hidh_conn_is_orig(dev_handle); + } while (0); + + return ret; +} + #endif //HID_HOST_INCLUDED diff --git a/components/bt/host/bluedroid/stack/hid/hidh_conn.c b/components/bt/host/bluedroid/stack/hid/hidh_conn.c index 42d170ddd0..f9d4a47b63 100644 --- a/components/bt/host/bluedroid/stack/hid/hidh_conn.c +++ b/components/bt/host/bluedroid/stack/hid/hidh_conn.c @@ -457,8 +457,8 @@ static void hidh_l2cif_config_ind (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) if (l2cap_cid == p_hcon->ctrl_cid) { p_hcon->conn_flags |= HID_CONN_FLAGS_HIS_CTRL_CFG_DONE; - if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && - (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE)) { + if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_MY_CTRL_CFG_DONE) && + (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) { /* Connect interrupt channel */ p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */ if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0) { @@ -528,8 +528,8 @@ static void hidh_l2cif_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) if (l2cap_cid == p_hcon->ctrl_cid) { p_hcon->conn_flags |= HID_CONN_FLAGS_MY_CTRL_CFG_DONE; - if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && - (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE)) { + if ((p_hcon->conn_flags & HID_CONN_FLAGS_IS_ORIG) && (p_hcon->conn_flags & HID_CONN_FLAGS_HIS_CTRL_CFG_DONE) && + (p_hcon->conn_state != HID_CONN_STATE_CONNECTING_INTR)) { /* Connect interrupt channel */ p_hcon->disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */ if ((p_hcon->intr_cid = L2CA_ConnectReq (HID_PSM_INTERRUPT, hh_cb.devices[dhandle].addr)) == 0) { @@ -928,7 +928,7 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param, data_size -= bytes_copied; /* Send the buffer through L2CAP */ - if ((p_hcon->conn_flags & HID_CONN_FLAGS_CONGESTED) || (!L2CA_DataWrite (cid, p_buf))) { + if (L2CA_DataWrite(cid, p_buf) == L2CAP_DW_FAILED) { return (HID_ERR_CONGESTED); } @@ -968,7 +968,7 @@ tHID_STATUS hidh_conn_initiate (UINT8 dhandle) p_dev->conn.disc_reason = HID_L2CAP_CONN_FAIL; /* Reset initial reason for CLOSE_EVT: Connection Attempt was made but failed */ /* We are the originator of this connection */ - p_dev->conn.conn_flags = HID_CONN_FLAGS_IS_ORIG; + p_dev->conn.conn_flags |= HID_CONN_FLAGS_IS_ORIG; if (p_dev->attr_mask & HID_SEC_REQUIRED) { service_id = BTM_SEC_SERVICE_HIDH_SEC_CTRL; @@ -989,6 +989,20 @@ tHID_STATUS hidh_conn_initiate (UINT8 dhandle) return ( HID_SUCCESS ); } +/******************************************************************************* +** +** Function hidh_conn_is_orig +** +** Description This function check if we are the originator of this connection +** +** Returns BOOLEAN +** +*******************************************************************************/ +BOOLEAN hidh_conn_is_orig(UINT8 dhandle) +{ + tHID_HOST_DEV_CTB *p_dev = &hh_cb.devices[dhandle]; + return (p_dev->conn.conn_flags & HID_CONN_FLAGS_IS_ORIG); +} /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/hid/include/hid_int.h b/components/bt/host/bluedroid/stack/hid/include/hid_int.h index b42089662d..beaca21e72 100644 --- a/components/bt/host/bluedroid/stack/hid/include/hid_int.h +++ b/components/bt/host/bluedroid/stack/hid/include/hid_int.h @@ -39,7 +39,6 @@ typedef struct per_device_ctb { UINT16 attr_mask; /* 0x01- virtual_cable; 0x02- normally_connectable; 0x03- reconn_initiate; 0x04- sdp_disable; */ UINT8 state; /* Device state if in HOST-KNOWN mode */ - UINT8 conn_substate; UINT8 conn_tries; /* Remembers to the number of connection attempts while CONNECTING */ tHID_CONN conn; /* L2CAP channel info */ @@ -66,6 +65,7 @@ extern tHID_STATUS hidh_conn_reg (void); extern void hidh_conn_dereg( void ); extern tHID_STATUS hidh_conn_disconnect (UINT8 dhandle); extern tHID_STATUS hidh_conn_initiate (UINT8 dhandle); +extern BOOLEAN hidh_conn_is_orig(UINT8 dhandle); extern void hidh_proc_repage_timeout (TIMER_LIST_ENT *p_tle); #ifdef __cplusplus extern "C" { diff --git a/components/bt/host/bluedroid/stack/include/stack/bt_types.h b/components/bt/host/bluedroid/stack/include/stack/bt_types.h index be803d50d2..d9fdaf2df8 100644 --- a/components/bt/host/bluedroid/stack/include/stack/bt_types.h +++ b/components/bt/host/bluedroid/stack/include/stack/bt_types.h @@ -676,6 +676,11 @@ typedef void (BT_LOG_FUNC) (int trace_type, const char *fmt_str, ...); typedef uint8_t BD_ADDR[BD_ADDR_LEN]; #endif +/* peer irk */ +#ifndef PEER_IRK_LEN +#define PEER_IRK_LEN 16 +typedef uint8_t PEER_IRK[PEER_IRK_LEN]; +#endif // From bd.c /***************************************************************************** diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_api.h index ff4fc233f8..1d4b059627 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -189,12 +189,17 @@ typedef void (tBTM_UPDATE_CONN_PARAM_CBACK) (UINT8 status, BD_ADDR bd_addr, tBTM typedef void (tBTM_SET_PKT_DATA_LENGTH_CBACK) (UINT8 status, tBTM_LE_SET_PKT_DATA_LENGTH_PARAMS *data_length_params); +typedef void (tBTM_DTM_CMD_CMPL_CBACK) (void *p1); + typedef void (tBTM_SET_RAND_ADDR_CBACK) (UINT8 status); typedef void (tBTM_UPDATE_WHITELIST_CBACK) (UINT8 status, tBTM_WL_OPERATION wl_opration); typedef void (tBTM_SET_LOCAL_PRIVACY_CBACK) (UINT8 status); +typedef void (tBTM_SET_RPA_TIMEOUT_CMPL_CBACK) (UINT8 status); + +typedef void (tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK) (UINT8 status); /***************************************************************************** ** DEVICE DISCOVERY - Inquiry, Remote Name, Discovery, Class of Device @@ -306,7 +311,7 @@ typedef void (tBTM_SET_LOCAL_PRIVACY_CBACK) (UINT8 status); #define BTM_COD_MINOR_CELLULAR 0x04 #define BTM_COD_MINOR_CORDLESS 0x08 #define BTM_COD_MINOR_SMART_PHONE 0x0C -#define BTM_COD_MINOR_WIRED_MDM_V_GTWY 0x10 /* wired modem or voice gatway */ +#define BTM_COD_MINOR_WIRED_MDM_V_GTWY 0x10 /* wired modem or voice gateway */ #define BTM_COD_MINOR_ISDN_ACCESS 0x14 /* minor device class field for LAN Access Point Major Class */ @@ -810,6 +815,15 @@ typedef struct { UINT8 hci_status; } tBTM_SET_AFH_CHANNELS_RESULTS; +/* Structure returned with set ACL packet types event (in tBTM_CMPL_CB callback function) +** in response to BTM_SetAclPktTypes call. +*/ +typedef struct { + tBTM_STATUS status; + BD_ADDR rem_bda; + UINT16 pkt_types; +} tBTM_SET_ACL_PKT_TYPES_RESULTS; + /* Structure returned with set BLE channels event (in tBTM_CMPL_CB callback function) ** in response to BTM_BleSetChannels call. */ @@ -1062,6 +1076,17 @@ enum { }; typedef UINT8 tBTM_SCO_DATA_FLAG; +/* Count the number of SCO Data Packet Status */ +typedef struct { + UINT32 rx_total; + UINT32 rx_correct; + UINT32 rx_err; + UINT32 rx_none; + UINT32 rx_lost; + UINT32 tx_total; + UINT32 tx_discarded; +} tBTM_SCO_PKT_STAT_NUMS; + /*************************** ** SCO Callback Functions ****************************/ @@ -1527,7 +1552,7 @@ typedef struct { tBTM_AUTH_REQ loc_auth_req; /* Authentication required for local device */ tBTM_AUTH_REQ rmt_auth_req; /* Authentication required for peer device */ tBTM_IO_CAP loc_io_caps; /* IO Capabilities of the local device */ - tBTM_IO_CAP rmt_io_caps; /* IO Capabilities of the remot device */ + tBTM_IO_CAP rmt_io_caps; /* IO Capabilities of the remote device */ } tBTM_SP_CFM_REQ; /* data type for BTM_SP_KEY_REQ_EVT */ @@ -2184,7 +2209,7 @@ UINT8 BTM_SetTraceLevel (UINT8 new_level); ** ** Function BTM_WritePageTimeout ** -** Description Send HCI Wite Page Timeout. +** Description Send HCI Write Page Timeout. ** ** Returns ** BTM_SUCCESS Command sent. @@ -2194,6 +2219,20 @@ UINT8 BTM_SetTraceLevel (UINT8 new_level); //extern tBTM_STATUS BTM_WritePageTimeout(UINT16 timeout); +/******************************************************************************* +** +** Function BTM_SetAclPktTypes +** +** Description Send HCI Change Connection Packet Type +** +** Returns +** BTM_SUCCESS Command sent. +** BTM_NO_RESOURCES If out of resources to send the command. +** +*******************************************************************************/ +//extern +tBTM_STATUS BTM_SetAclPktTypes(BD_ADDR remote_bda, UINT16 pkt_types, tBTM_CMPL_CB *p_cb); + /******************************************************************************* ** ** Function BTM_WriteVoiceSettings @@ -2348,7 +2387,7 @@ tBTM_STATUS BTM_StartInquiry (tBTM_INQ_PARMS *p_inqparms, ** Description This function returns a bit mask of the current inquiry state ** ** Returns BTM_INQUIRY_INACTIVE if inactive (0) -** BTM_LIMITED_INQUIRY_ACTIVE if a limted inquiry is active +** BTM_LIMITED_INQUIRY_ACTIVE if a limited inquiry is active ** BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active ** BTM_PERIODIC_INQUIRY_ACTIVE if a periodic inquiry is active ** @@ -3488,7 +3527,7 @@ BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, ** ** Description Free resources associated with the device. ** -** Returns TRUE if rmoved OK, FALSE if not found +** Returns TRUE if removed OK, FALSE if not found ** *******************************************************************************/ //extern @@ -3999,6 +4038,22 @@ BOOLEAN BTM_HasEirService( UINT32 *p_eir_uuid, UINT16 uuid16 ); tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService( tBTM_INQ_RESULTS *p_results, UINT16 uuid16 ); +/******************************************************************************* +** +** Function BTM_HasCustomEirService +** +** Description This function is called to know if UUID is already in custom +** UUID list. +** +** Parameters custom_uuid - pointer to custom_uuid array in tBTA_DM_CB +** uuid - UUID struct +** +** Returns TRUE - if found +** FALSE - if not found +** +*******************************************************************************/ +BOOLEAN BTM_HasCustomEirService( tBT_UUID *custom_uuid, tBT_UUID uuid ); + /******************************************************************************* ** ** Function BTM_AddEirService @@ -4014,6 +4069,20 @@ tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService( tBTM_INQ_RESULTS *p_results, //extern void BTM_AddEirService( UINT32 *p_eir_uuid, UINT16 uuid16 ); +/******************************************************************************* +** +** Function BTM_AddCustomEirService +** +** Description This function is called to add a custom UUID. +** +** Parameters custom_uuid - pointer to custom_uuid array in tBTA_DM_CB +** uuid - UUID struct +** +** Returns None +** +*******************************************************************************/ +void BTM_AddCustomEirService(tBT_UUID *custom_uuid, tBT_UUID uuid); + /******************************************************************************* ** ** Function BTM_RemoveEirService @@ -4029,6 +4098,20 @@ void BTM_AddEirService( UINT32 *p_eir_uuid, UINT16 uuid16 ); //extern void BTM_RemoveEirService( UINT32 *p_eir_uuid, UINT16 uuid16 ); +/******************************************************************************* +** +** Function BTM_RemoveCustomEirService +** +** Description This function is called to remove a a custom UUID. +** +** Parameters custom_uuid - pointer to custom_uuid array in tBTA_DM_CB + uuid - UUID struct +** +** Returns None +** +*******************************************************************************/ +void BTM_RemoveCustomEirService(tBT_UUID *custom_uuid, tBT_UUID uuid); + /******************************************************************************* ** ** Function BTM_GetEirSupportedServices @@ -4090,7 +4173,7 @@ UINT8 BTM_GetEirUuidList( UINT8 *p_eir, UINT8 uuid_size, UINT8 *p_num_uuid, ** pointer is used, PCM parameter maintained in ** the control block will be used; otherwise update ** control block value. -** err_data_rpt: Lisbon feature to enable the erronous data report +** err_data_rpt: Lisbon feature to enable the erroneous data report ** or not. ** ** Returns BTM_SUCCESS if the successful. @@ -4190,6 +4273,17 @@ tBTM_STATUS BTM_SetAfhChannels (AFH_CHANNELS channels, tBTM_CMPL_CB *p_afh_chann *******************************************************************************/ tBTM_STATUS BTM_BleSetChannels (BLE_CHANNELS channels, tBTM_CMPL_CB *p_ble_channels_cmpl_cback); +/******************************************************************************* +** +** Function BTM_PktStatNumsGet +** +** Description This function is called to get the number of packet status struct +** +** Returns void +** +*******************************************************************************/ +void BTM_PktStatNumsGet(UINT16 sync_conn_handle, tBTM_SCO_PKT_STAT_NUMS *pkt_nums); + #ifdef __cplusplus } #endif 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 16230bc7b5..1b30964284 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 @@ -105,8 +105,12 @@ typedef UINT8 tBTM_BLE_SFP; #endif /* adv parameter boundary values */ -#define BTM_BLE_ADV_INT_MIN 0x0020 -#define BTM_BLE_ADV_INT_MAX 0x4000 +#if BLE_HIGH_DUTY_ADV_INTERVAL +#define BTM_BLE_ADV_INT_MIN 0x0008 /* 5ms */ +#else +#define BTM_BLE_ADV_INT_MIN 0x0020 /* 20ms */ +#endif +#define BTM_BLE_ADV_INT_MAX 0x4000 /* 10240ms */ /* Full scan boundary values */ #define BTM_BLE_ADV_SCAN_FULL_MIN 0x00 @@ -140,12 +144,12 @@ typedef UINT8 tBTM_BLE_SFP; #ifndef BTM_BLE_SCAN_FAST_INT #define BTM_BLE_SCAN_FAST_INT 96 /* 30 ~ 60 ms (use 60) = 96 *0.625 */ #endif -/* default scan window for background connection, applicable for auto connection or selective conenction */ +/* default scan window for background connection, applicable for auto connection or selective connection */ #ifndef BTM_BLE_SCAN_FAST_WIN #define BTM_BLE_SCAN_FAST_WIN 48 /* 30 ms = 48 *0.625 */ #endif -/* default scan paramter used in reduced power cycle (background scanning) */ +/* default scan parameter used in reduced power cycle (background scanning) */ #ifndef BTM_BLE_SCAN_SLOW_INT_1 #define BTM_BLE_SCAN_SLOW_INT_1 2048 /* 1.28 s = 2048 *0.625 */ #endif @@ -153,7 +157,7 @@ typedef UINT8 tBTM_BLE_SFP; #define BTM_BLE_SCAN_SLOW_WIN_1 48 /* 30 ms = 48 *0.625 */ #endif -/* default scan paramter used in reduced power cycle (background scanning) */ +/* default scan parameter used in reduced power cycle (background scanning) */ #ifndef BTM_BLE_SCAN_SLOW_INT_2 #define BTM_BLE_SCAN_SLOW_INT_2 4096 /* 2.56 s = 4096 *0.625 */ #endif @@ -250,6 +254,7 @@ typedef UINT8 BLE_SIGNATURE[BTM_BLE_AUTH_SIGN_LEN]; /* Device address */ #define BTM_BLE_APPEARANCE_CYCLING_CADENCE 0x0483 #define BTM_BLE_APPEARANCE_CYCLING_POWER 0x0484 #define BTM_BLE_APPEARANCE_CYCLING_SPEED_CADENCE 0x0485 +#define BTM_BLE_APPEARANCE_STANDALONE_SPEAKER 0x0841 #define BTM_BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 0x0C40 #define BTM_BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 0x0C41 #define BTM_BLE_APPEARANCE_PULSE_OXIMETER_WRIST 0x0C42 @@ -455,7 +460,7 @@ typedef struct { } tBTM_BLE_PROPRIETARY; typedef struct { - tBTM_BLE_INT_RANGE int_range; /* slave prefered conn interval range */ + tBTM_BLE_INT_RANGE int_range; /* slave preferred conn interval range */ tBTM_BLE_MANU *p_manu; /* manufacturer data */ tBTM_BLE_SERVICE *p_services; /* services */ tBTM_BLE_128SERVICE *p_services_128b; /* 128 bits service */ @@ -805,6 +810,10 @@ typedef struct { typedef struct { UINT8 filter_policy; + #if (CONFIG_BT_BLE_FEAT_CREATE_SYNC_ENH) + UINT8 reports_disabled; + UINT8 filter_duplicates; + #endif UINT8 sid; tBLE_ADDR_TYPE addr_type; BD_ADDR addr; @@ -996,6 +1005,9 @@ 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); +typedef void (tBTM_SET_PRIVACY_MODE_CMPL_CBACK) (tBTM_STATUS 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 @@ -1031,7 +1043,15 @@ typedef void (tBTM_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTM_STATUS st #define BTM_BLE_5_GAP_PERIODIC_ADV_REPORT_EVT 32 #define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_LOST_EVT 33 #define BTM_BLE_5_GAP_PERIODIC_ADV_SYNC_ESTAB_EVT 34 -#define BTM_BLE_5_GAP_UNKNOWN_EVT 35 +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define BTM_BLE_GAP_PERIODIC_ADV_RECV_ENABLE_COMPLETE_EVT 35 +#define BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_COMPLETE_EVT 36 +#define BTM_BLE_GAP_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT 37 +#define BTM_BLE_GAP_SET_PAST_PARAMS_COMPLETE_EVT 38 +#define BTM_BLE_GAP_PERIODIC_ADV_SYNC_TRANS_RECV_EVT 39 +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define BTM_BLE_GAP_SET_PRIVACY_MODE_COMPLETE_EVT 40 +#define BTM_BLE_5_GAP_UNKNOWN_EVT 41 typedef UINT8 tBTM_BLE_5_GAP_EVENT; #define BTM_BLE_EXT_ADV_DATA_COMPLETE 0x00 @@ -1080,46 +1100,58 @@ typedef struct { typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_SET_PERF_PHY_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_SET_RAND_ADDR_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_SET_PARAMS_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_DATA_SET_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_SCAN_RSP_DATA_SET_CMPL; typedef struct { UINT8 status; + UINT8 instance_num; + UINT8 instance[10]; } tBTM_BLE_EXT_ADV_START_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_EXT_ADV_STOP_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_SET_PARAMS_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_DATA_SET_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_START_CMPL; typedef struct { UINT8 status; + UINT8 instance; } tBTM_BLE_PERIOD_ADV_STOP_CMPL; typedef struct { @@ -1241,6 +1273,39 @@ typedef struct { UINT16 max_ce_len; } tBTM_BLE_CONN_PARAMS; +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +typedef struct { + UINT8 status; +} tBTM_BLE_PERIOD_ADV_RECV_ENABLE_CMPL; + +typedef struct { + UINT8 status; + BD_ADDR addr; +} tBTM_BLE_PERIOD_ADV_SYNC_TRANS_CMPL; + +typedef struct { + UINT8 status; + BD_ADDR addr; +} tBTM_BLE_PERIOD_ADV_SET_INFO_TRANS_CMPL; + +typedef struct { + UINT8 status; + BD_ADDR addr; +} tBTM_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS_CMPL; + +typedef struct { + UINT8 status; + BD_ADDR addr; + UINT16 service_data; + UINT16 sync_handle; + UINT8 adv_sid; + UINT8 adv_addr_type; + BD_ADDR adv_addr; + UINT8 adv_phy; + UINT16 adv_interval; + UINT8 adv_clk_accuracy; +} tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV; +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) typedef union { UINT8 status; @@ -1275,6 +1340,13 @@ typedef union { tBTM_PERIOD_ADV_REPORT period_adv_report; tBTM_BLE_PERIOD_ADV_SYNC_LOST sync_lost; tBTM_BLE_PERIOD_ADV_SYNC_ESTAB sync_estab; +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + tBTM_BLE_PERIOD_ADV_RECV_ENABLE_CMPL per_adv_recv_enable; + tBTM_BLE_PERIOD_ADV_SYNC_TRANS_CMPL per_adv_sync_trans; + tBTM_BLE_PERIOD_ADV_SET_INFO_TRANS_CMPL per_adv_set_info_trans; + tBTM_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS_CMPL set_past_params; + tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV past_recv; +#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) } tBTM_BLE_5_GAP_CB_PARAMS; typedef struct { @@ -1288,21 +1360,6 @@ typedef void (*tBTM_BLE_5_HCI_CBACK)(tBTM_BLE_5_GAP_EVENT event, tBTM_BLE_5_GAP_ #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) -#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) -typedef struct { - UINT8 status; - UINT16 conn_handle; - UINT16 service_data; - UINT16 sync_handle; - UINT8 adv_sid; - UINT8 adv_addr_type; - BD_ADDR adv_addr; - UINT8 adv_phy; - UINT16 period_adv_interval; - UINT8 adv_clk_accuracy; -} tBTM_BLE_PERIOD_ADV_SYNC_TRANS_RECV; -#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) - /***************************************************************************** ** EXTERNAL FUNCTION DECLARATIONS *****************************************************************************/ @@ -1324,6 +1381,7 @@ extern "C" { ** *******************************************************************************/ void BTM_BleRegiseterConnParamCallback(tBTM_UPDATE_CONN_PARAM_CBACK *update_conn_param_cb); +void BTM_BleRegiseterPktLengthChangeCallback(tBTM_SET_PKT_DATA_LENGTH_CBACK *ptk_len_chane_cb); /******************************************************************************* ** @@ -1853,7 +1911,7 @@ void BTM_BleSecureConnectionCreateOobData(void); ** Function BTM_BleDataSignature ** ** Description This function is called to sign the data using AES128 CMAC -** algorith. +** algorithm. ** ** Parameter bd_addr: target device the data to be signed for. ** p_text: singing data @@ -1861,7 +1919,7 @@ void BTM_BleSecureConnectionCreateOobData(void); ** signature: output parameter where data signature is going to ** be stored. ** -** Returns TRUE if signing sucessul, otherwise FALSE. +** Returns TRUE if signing successful, otherwise FALSE. ** *******************************************************************************/ //extern @@ -2351,7 +2409,7 @@ BOOLEAN BTM_UseLeLink (BD_ADDR bd_addr); ** ** Function BTM_BleStackEnable ** -** Description Enable/Disable BLE functionality on stack regarless controller +** Description Enable/Disable BLE functionality on stack regardless controller ** capability. ** ** Parameters: enable: TRUE to enable, FALSE to disable. @@ -2395,7 +2453,7 @@ BOOLEAN BTM_BleSecurityProcedureIsRunning (BD_ADDR bd_addr); ** Function BTM_BleGetSupportedKeySize ** ** Description This function gets the maximum encryption key size in bytes -** the local device can suport. +** the local device can support. ** record. ** ** Returns the key size or 0 if the size can't be retrieved. @@ -2430,7 +2488,7 @@ tBTM_STATUS BTM_BleEnableAdvInstance (tBTM_BLE_ADV_PARAMS *p_params, ** ** Function BTM_BleUpdateAdvInstParam ** -** Description This function update a Multi-ADV instance with the specififed +** Description This function update a Multi-ADV instance with the specified ** adv parameters. ** ** Parameters inst_id: adv instance ID @@ -2506,7 +2564,7 @@ tBTM_STATUS BTM_BleAdvFilterParamSetup(int action, ** ** Parameters action: to read/write/clear ** cond_type: filter condition type. -** p_cond: filter condition paramter +** p_cond: filter condition parameter ** ** Returns tBTM_STATUS ** @@ -2602,6 +2660,70 @@ 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); + +/******************************************************************************* +** +** Function BTM_BleSetRpaTimeout +** +** Description This function is called to set the Resolvable Private Address +** (RPA) timeout. +** +** Parameter rpa_timeout - The timeout value for RPA, typically in seconds. +** +*******************************************************************************/ +BOOLEAN BTM_BleSetRpaTimeout(uint16_t rpa_timeout, tBTM_SET_RPA_TIMEOUT_CMPL_CBACK *p_set_rpa_timeout_cback); + +/******************************************************************************* +** +** Function BTM_BleAddDevToResolvingList +** +** Description This function is called to add a device to the resolving list +** used to generate and resolve Resolvable Private Addresses (RPAs) +** in the Bluetooth Controller. +** +** Parameters addr - The address of the device to be added to the resolving list. +** addr_type - The address type of the device (public or random). +** irk - The Identity Resolving Key (IRK) of the device. +** p_add_dev_to_resolving_list_callback - Callback function to be called when the operation is completed. +** +** Returns TRUE if the operation was successful, otherwise FALSE. +** +*******************************************************************************/ +BOOLEAN BTM_BleAddDevToResolvingList(BD_ADDR addr, + uint8_t addr_type, + uint8_t irk[], + tBTM_ADD_DEV_TO_RESOLVING_LIST_CMPL_CBACK *p_add_dev_to_resolving_list_callback); + +/******************************************************************************* +** +** Function BTM_BleSetPrivacyMode +** +** Description This function is called to set the privacy mode of device in resolving list +** +** Parameters addr_type - The address type of the device in resolving list (public or random). +** addr - The address of the device in resolving list. +** privacy_mode - The privacy mode (network or device) of the device. +** p_callback - Callback function to be called when the operation is completed. +** +** Returns TRUE if the operation was successful, otherwise FALSE. +** +*******************************************************************************/ +BOOLEAN BTM_BleSetPrivacyMode(UINT8 addr_type, + BD_ADDR bd_addr, + UINT8 privacy_mode, + tBTM_SET_PRIVACY_MODE_CMPL_CBACK *p_callback); + /* #ifdef __cplusplus } @@ -2631,9 +2753,9 @@ tBTM_STATUS BTM_BleExtAdvSetClear(void); tBTM_STATUS BTM_BlePeriodicAdvSetParams(UINT8 instance, tBTM_BLE_Periodic_Adv_Params *params); -tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data); +tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data, BOOLEAN only_update_did); -tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, BOOLEAN enable); +tBTM_STATUS BTM_BlePeriodicAdvEnable(UINT8 instance, UINT8 enable); tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params); @@ -2652,9 +2774,18 @@ tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params); tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period); void BTM_BleSetPreferExtenedConnParams(BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *params); + +void BTM_BleEnhancedReceiverTest(UINT8 rx_freq, UINT8 phy, UINT8 modulation_index, tBTM_CMPL_CB *p_cmd_cmpl_cback); + +void BTM_BleEnhancedTransmitterTest(UINT8 tx_freq, UINT8 test_data_len, UINT8 packet_payload, UINT8 phy, tBTM_CMPL_CB *p_cmd_cmpl_cback); + #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +void BTM_BlePeriodicAdvRecvEnable(UINT16 sync_handle, UINT8 enable); + +void BTM_BlePeriodicAdvSyncTrans(BD_ADDR bd_addr, UINT16 service_data, UINT16 sync_handle); + void BTM_BlePeriodicAdvSetInfoTrans(BD_ADDR bd_addr, UINT16 service_data, UINT8 adv_handle); void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); diff --git a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h index 441bb12250..fed2ea9a4e 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gatt_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/gatt_api.h @@ -139,7 +139,7 @@ typedef UINT16 tGATT_DISCONN_REASON; /* max length of an attribute value */ #ifndef GATT_MAX_ATTR_LEN -#define GATT_MAX_ATTR_LEN 600 +#define GATT_MAX_ATTR_LEN 512 #endif /* default GATT MTU size over LE link @@ -701,7 +701,7 @@ extern UINT8 GATT_SetTraceLevel (UINT8 new_level); ** ** Function GATTS_AddHandleRange ** -** Description This function add the allocated handles range for the specifed +** Description This function add the allocated handles range for the specified ** application UUID, service UUID and service instance ** ** Parameter p_hndl_range: pointer to allocated handles information @@ -720,7 +720,7 @@ extern BOOLEAN GATTS_AddHandleRange(tGATTS_HNDL_RANGE *p_hndl_range); ** NV save callback function. There can be one and only one ** NV save callback function. ** -** Parameter p_cb_info : callback informaiton +** Parameter p_cb_info : callback information ** ** Returns TRUE if registered OK, else FALSE ** @@ -943,7 +943,7 @@ tGATT_STATUS GATTS_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *v *******************************************************************************/ tGATT_STATUS GATTS_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value); - +tGATT_STATUS GATTS_GetAttributeValueInternal(UINT16 attr_handle, UINT16 *length, UINT8 **value); /*******************************************************************************/ /* GATT Profile Client Functions */ @@ -1143,7 +1143,7 @@ extern BOOLEAN GATT_Connect (tGATT_IF gatt_if, BD_ADDR bd_addr, tBLE_ADDR_TYPE b ** ** Function GATT_CancelConnect ** -** Description This function terminate the connection initaition to a remote +** Description This function terminate the connection initiation to a remote ** device on GATT channel. ** ** Parameters gatt_if: client interface. If 0 used as unconditionally disconnect, @@ -1279,6 +1279,17 @@ extern tGATT_STATUS GATTS_SetServiceChangeMode(UINT8 mode); *******************************************************************************/ extern tGATT_STATUS GATTS_HandleMultiValueNotification (UINT16 conn_id, tGATT_HLV *tuples, UINT16 num_tuples); +/******************************************************************************* +** +** Function GATTS_ShowLocalDatabase +** +** Description This function print local service database. +** +** Returns GATT_SUCCESS if successfully sent; otherwise error code. +** +*******************************************************************************/ +extern tGATT_STATUS GATTS_ShowLocalDatabase(void); + #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 7dba073ec6..2caedaf9e2 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -383,13 +383,14 @@ #define HCI_BLE_RD_TRANSMIT_POWER (0x004B | HCI_GRP_BLE_CMDS) #define HCI_BLE_RD_RF_PATH_COMPENSATION (0x004C | HCI_GRP_BLE_CMDS) #define HCI_BLE_WR_RF_PATH_COMPENSATION (0x004D | HCI_GRP_BLE_CMDS) -#define HCI_BLE_SET_PRIVACY_MODE (0x004E | HCI_GRP_BLE_CMDS) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) +#define HCI_BLE_SET_PRIVACY_MODE (0x004E | HCI_GRP_BLE_CMDS) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #define HCI_BLE_SET_PERIOD_ADV_RECV_ENABLE (0x0059 | HCI_GRP_BLE_CMDS) #define HCI_BLE_PERIOD_ADV_SYNC_TRANS (0x005A | HCI_GRP_BLE_CMDS) #define HCI_BLE_PERIOD_ADV_SET_INFO_TRANS (0x005B | HCI_GRP_BLE_CMDS) -#define HCI_BLE_SET_PERIOD_ADV_SYNC_TRANS_PARAMS (0x005C | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_PAST_PARAMS (0x005C | HCI_GRP_BLE_CMDS) +#define HCI_BLE_SET_DEFAULT_PAST_PARAMS (0x005D | HCI_GRP_BLE_CMDS) #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) // Vendor OGF define #define HCI_VENDOR_OGF 0x3F @@ -418,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 @@ -461,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 */ @@ -824,7 +829,6 @@ ** Defentions for HCI Error Codes that are past in the events */ #define HCI_SUCCESS 0x00 -#define HCI_PENDING 0x00 #define HCI_ERR_ILLEGAL_COMMAND 0x01 #define HCI_ERR_NO_CONNECTION 0x02 #define HCI_ERR_HW_FAILURE 0x03 @@ -1127,18 +1131,18 @@ typedef UINT8 tHCI_STATUS; #define HCI_MIN_INQ_LAP 0x9E8B00 #define HCI_MAX_INQ_LAP 0x9E8B3F -/* HCI role defenitions */ +/* HCI role definitions */ #define HCI_ROLE_MASTER 0x00 #define HCI_ROLE_SLAVE 0x01 #define HCI_ROLE_UNKNOWN 0xff -/* HCI mode defenitions */ +/* HCI mode definitions */ #define HCI_MODE_ACTIVE 0x00 #define HCI_MODE_HOLD 0x01 #define HCI_MODE_SNIFF 0x02 #define HCI_MODE_PARK 0x03 -/* HCI Flow Control Mode defenitions */ +/* HCI Flow Control Mode definitions */ #define HCI_PACKET_BASED_FC_MODE 0x00 #define HCI_BLOCK_BASED_FC_MODE 0x01 @@ -1406,7 +1410,7 @@ typedef UINT8 tHCI_STATUS; /* Define an invalid value for a handle */ #define HCI_INVALID_HANDLE 0xFFFF -/* Define max ammount of data in the HCI command */ +/* Define max amount of data in the HCI command */ #define HCI_COMMAND_SIZE 255 /* Define the preamble length for all HCI Commands. diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index e50b6510b5..ed98f8f63d 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -621,7 +621,7 @@ BOOLEAN btsnd_hcic_write_voice_settings(UINT16 flags); /* Write Voice BOOLEAN btsnd_hcic_write_auto_flush_tout(UINT16 handle, - UINT16 timeout); /* Write Retransmit Timout */ + UINT16 timeout); /* Write Retransmit Timeout */ #define HCIC_PARAM_SIZE_WRITE_AUTO_FLUSH_TOUT 4 @@ -751,8 +751,10 @@ 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 +#define HCIC_PARAM_SIZE_SET_PRIVACY_MODE 8 #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 +908,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 { @@ -1033,18 +1037,32 @@ UINT8 btsnd_hcic_ble_read_rf_path_compensation(void); UINT8 btsnd_hcic_ble_write_rf_path_compensation(UINT16 rf_tx_path, UINT16 rf_rx_path); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) -#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) -UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enable); - -UINT8 btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle); -UINT8 btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle); +UINT8 btsnd_hcic_ble_set_privacy_mode(UINT8 addr_type, BD_ADDR addr, UINT8 privacy_mode); -UINT8 btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); -#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #define HCIC_PARAM_SIZE_WRITE_AUTHENT_PAYLOAD_TOUT 4 #define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_HANDLE_OFF 0 #define HCI__WRITE_AUTHENT_PAYLOAD_TOUT_TOUT_OFF 2 +#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#define HCIC_PARAM_SIZE_PERIODIC_ADV_RECV_ENABLE 3 +#define HCI_PERIODIC_ADV_RECV_REPORT_EN 1 +#define HCI_PERIODIC_ADV_RECV_DUP_FILTER_EN 2 +#define HCIC_PARAM_SIZE_PERIODIC_ADV_SYNC_TRANS 6 +#define HCIC_PARAM_SIZE_PERIODIC_ADV_SET_INFO_TRANS 5 +#define HCIC_PARAM_SIZE_SET_PAST_PARAMS 8 +#define HCIC_PARAM_SIZE_SET_DEFAULT_PAST_PARAMS 6 + +UINT8 btsnd_hcic_ble_set_periodic_adv_recv_enable(UINT16 sync_handle, UINT8 enable); + +BOOLEAN btsnd_hcic_ble_periodic_adv_sync_trans(UINT16 conn_handle, UINT16 service_data, UINT16 sync_handle); + +BOOLEAN btsnd_hcic_ble_periodic_adv_set_info_trans(UINT16 conn_handle, UINT16 service_data, UINT8 adv_handle); + +BOOLEAN btsnd_hcic_ble_set_periodic_adv_sync_trans_params(UINT16 conn_handle, UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); + +UINT8 btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(UINT8 mode, UINT16 skip, UINT16 sync_timeout, UINT8 cte_type); +#endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/hidh_api.h b/components/bt/host/bluedroid/stack/include/stack/hidh_api.h index 2ddaf1c51a..2445163db5 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hidh_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/hidh_api.h @@ -249,6 +249,17 @@ BOOLEAN hid_known_hid_device (BD_ADDR bd_addr); *******************************************************************************/ extern UINT8 HID_HostSetTraceLevel (UINT8 new_level); +/******************************************************************************* +** +** Function HID_HostConnectOrig +** +** Description Check if the HID Host initiates the connection +** +** Returns TRUE if the HID Host initiates the connection else FALSE +** +*******************************************************************************/ +extern BOOLEAN HID_HostConnectOrig(UINT8 dev_handle); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/stack/include/stack/l2c_api.h b/components/bt/host/bluedroid/stack/include/stack/l2c_api.h index 03d185e7bc..b985b641e8 100644 --- a/components/bt/host/bluedroid/stack/include/stack/l2c_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/l2c_api.h @@ -1215,6 +1215,19 @@ extern BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable); ** *******************************************************************************/ extern UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr); + +/******************************************************************************* +** +** Function L2CA_BleDisconnect +** +** Description This function use to disconnect LE connection. +** +** Parameters BD Address of remote +** +** Returns TRUE if disconnect successfully. +** +*******************************************************************************/ +extern BOOLEAN L2CA_BleDisconnect (BD_ADDR rem_bda); #endif /* (BLE_INCLUDED == TRUE) */ /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c index 7c282db09e..fa01790d5f 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c @@ -1949,6 +1949,36 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda) return (TRUE); } +#if BLE_INCLUDED == TRUE +BOOLEAN L2CA_BleDisconnect (BD_ADDR rem_bda) +{ + tL2C_LCB *p_lcb; + tGATT_TCB *p_tcb; + + p_lcb = l2cu_find_lcb_by_bd_addr (rem_bda, BT_TRANSPORT_LE); + if (p_lcb == NULL) { + return FALSE; + } + + if (p_lcb->link_state != LST_CONNECTED) { + return FALSE; + } + + p_lcb->disc_reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST; + p_lcb->link_state = LST_DISCONNECTING; + btsnd_hcic_disconnect (p_lcb->handle, HCI_ERR_PEER_USER); + + p_tcb = gatt_find_tcb_by_addr(rem_bda, BT_TRANSPORT_LE); + if (p_tcb == NULL) { + return FALSE; + } + + gatt_set_ch_state(p_tcb, GATT_CH_CLOSING); + + return TRUE; +} +#endif + /******************************************************************************* ** ** Function L2CA_SetFixedChannelTout @@ -2107,6 +2137,33 @@ UINT8 L2CA_DataWrite (UINT16 cid, BT_HDR *p_data) } #endif ///CLASSIC_BT_INCLUDED == TRUE +/******************************************************************************* +** +** Function l2cap_bqb_write_data +** +** Description Call L2CA_DataWrite and write I-Frame data for BQB test. +** +** Returns None +** +*******************************************************************************/ +#if (BT_CLASSIC_BQB_INCLUDED == TRUE) +void l2cap_bqb_write_data(UINT16 cid) +{ + BT_HDR *p_buf; + uint8_t *p; + + if ((p_buf = (BT_HDR *)osi_malloc(SDP_DATA_BUF_SIZE)) != NULL) { + p_buf->len = 30; + p_buf->offset = L2CAP_MIN_OFFSET; + p = (UINT8 *)(p_buf + 1) + p_buf->offset; + for(int i = 0 ; i < 10; i++) { + UINT8_TO_BE_STREAM(p, 0) + } + L2CA_DataWrite(cid, p_buf); + } +} +#endif /* BT_CLASSIC_BQB_INCLUDED */ + /******************************************************************************* ** ** Function L2CA_SetChnlFlushability diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c index 8d9f510f55..956a4b7fb2 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ble.c @@ -175,14 +175,14 @@ BOOLEAN L2CA_UpdateBleConnParams (BD_ADDR rem_bda, UINT16 min_int, UINT16 max_in L2CAP_TRACE_ERROR("There are two connection parameter requests that are being updated, please try later "); } - if ((need_cb == TRUE) && (conn_param_update_cb.update_conn_param_cb != NULL)) { + if ((need_cb == TRUE) && (conn_callback_func.update_conn_param_cb != NULL)) { tBTM_LE_UPDATE_CONN_PRAMS update_param; update_param.max_conn_int = max_int; update_param.min_conn_int = min_int; update_param.conn_int = p_lcb->current_used_conn_interval; update_param.slave_latency = p_lcb->current_used_conn_latency; update_param.supervision_tout = p_lcb->current_used_conn_timeout; - (conn_param_update_cb.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param); + (conn_callback_func.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param); return (status == HCI_SUCCESS); } @@ -287,7 +287,7 @@ UINT8 L2CA_GetBleConnRole (BD_ADDR bd_addr) ** ** Function l2cble_notify_le_connection ** -** Description This function notifiy the l2cap connection to the app layer +** Description This function notify the l2cap connection to the app layer ** ** Returns none ** @@ -647,7 +647,7 @@ void l2cble_process_conn_update_evt (UINT16 handle, UINT8 status, UINT16 conn_in p_lcb->conn_update_mask &= ~L2C_BLE_UPDATE_PARAM_FULL; btu_stop_timer(&p_lcb->upda_con_timer); - if (conn_param_update_cb.update_conn_param_cb != NULL) { + if (conn_callback_func.update_conn_param_cb != NULL) { l2c_send_update_conn_params_cb(p_lcb, status); } @@ -686,7 +686,7 @@ void l2cble_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handl btu_stop_timer (&p_lcb->upda_con_timer); - if (conn_param_update_cb.update_conn_param_cb != NULL) { + if (conn_callback_func.update_conn_param_cb != NULL) { l2c_send_update_conn_params_cb(p_lcb, status); } if ((p_lcb->conn_update_mask & L2C_BLE_UPDATE_PARAM_FULL) != 0){ @@ -807,6 +807,7 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) STREAM_TO_UINT16(mps, p); STREAM_TO_UINT16(credits, p); L2CAP_TRACE_DEBUG("%s spsm %x, scid %x", __func__, spsm, scid); + UNUSED(spsm); p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, scid); if (p_ccb) { @@ -867,7 +868,7 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) ** ** Function l2cble_init_direct_conn ** -** Description This function is to initate a direct connection +** Description This function is to initiate a direct connection ** ** Returns TRUE connection initiated, FALSE otherwise. ** @@ -893,7 +894,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) /* There can be only one BLE connection request outstanding at a time */ if (p_dev_rec == NULL) { - L2CAP_TRACE_WARNING ("unknown device, can not initate connection"); + L2CAP_TRACE_WARNING ("unknown device, can not initiate connection"); return (FALSE); } @@ -946,7 +947,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) if (!btm_ble_topology_check(BTM_BLE_STATE_INIT)) { l2cu_release_lcb (p_lcb); - L2CAP_TRACE_ERROR("initate direct connection fail, topology limitation"); + L2CAP_TRACE_ERROR("initiate direct connection fail, topology limitation"); return FALSE; } uint32_t link_timeout = L2CAP_BLE_LINK_CONNECT_TOUT; @@ -980,7 +981,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) BLE_CE_LEN_MIN, /* UINT16 min_len */ BLE_CE_LEN_MIN)) { /* UINT16 max_len */ l2cu_release_lcb (p_lcb); - L2CAP_TRACE_ERROR("initate direct connection fail, no resources"); + L2CAP_TRACE_ERROR("initiate direct connection fail, no resources"); return (FALSE); } else { p_lcb->link_state = LST_CONNECTING; @@ -1032,7 +1033,7 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb) btm_ble_set_conn_st (BLE_DIR_CONN); if(!btsnd_hcic_ble_create_ext_conn(&aux_conn)) { l2cu_release_lcb (p_lcb); - L2CAP_TRACE_ERROR("initate Aux connection failed, no resources"); + L2CAP_TRACE_ERROR("initiate Aux connection failed, no resources"); } #else L2CAP_TRACE_ERROR("BLE 5.0 not support!\n"); @@ -1323,15 +1324,18 @@ void l2cble_process_data_length_change_event(UINT16 handle, UINT16 tx_data_len, if(p_acl) { p_acl->data_length_params = data_length_params; if (p_acl->p_set_pkt_data_cback) { + // Only when the corresponding API is called will the callback be registered (*p_acl->p_set_pkt_data_cback)(BTM_SUCCESS, &data_length_params); + } else { + // If the callback is not registered,using global callback + (*conn_callback_func.set_pkt_data_length_cb)(BTM_SUCCESS, &data_length_params); } - p_acl->data_len_updating = false; if(p_acl->data_len_waiting) { p_acl->data_len_waiting = false; p_acl->p_set_pkt_data_cback = p_acl->p_set_data_len_cback_waiting; p_acl->p_set_data_len_cback_waiting = NULL; - // if value is same, triger callback directly + // if value is same, trigger callback directly if(p_acl->tx_len_waiting == p_acl->data_length_params.tx_len) { if(p_acl->p_set_pkt_data_cback) { (*p_acl->p_set_pkt_data_cback)(BTM_SUCCESS, &p_acl->data_length_params); @@ -1395,7 +1399,7 @@ void l2cble_set_fixed_channel_tx_data_length(BD_ADDR remote_bda, UINT16 fix_cid, *******************************************************************************/ void l2c_send_update_conn_params_cb(tL2C_LCB *p_lcb, UINT8 status) { - if(conn_param_update_cb.update_conn_param_cb != NULL){ + if(conn_callback_func.update_conn_param_cb != NULL){ tBTM_LE_UPDATE_CONN_PRAMS update_param; //if myself update the connection parameters if (p_lcb->updating_param_flag){ @@ -1411,7 +1415,7 @@ void l2c_send_update_conn_params_cb(tL2C_LCB *p_lcb, UINT8 status) update_param.slave_latency = p_lcb->current_used_conn_latency; update_param.supervision_tout = p_lcb->current_used_conn_timeout; - (conn_param_update_cb.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param); + (conn_callback_func.update_conn_param_cb)(status, p_lcb->remote_bd_addr, &update_param); } } @@ -1429,7 +1433,7 @@ UINT32 CalConnectParamTimeout(tL2C_LCB *p_lcb) UINT32 timeout = 6; if (p_lcb != NULL){ //1.25 * conn_int *(1+ latency) *32 - timeout = (40 * ( 1 + p_lcb->current_used_conn_latency) * p_lcb->current_used_conn_interval + 1000) / 1000; + timeout = (40 * ( 1 + p_lcb->current_used_conn_latency) * p_lcb->current_used_conn_interval + 1.25 * p_lcb->waiting_update_conn_max_interval + 1000) / 1000; if (timeout < 1){ timeout = 1; }else if (timeout > 120){ diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c index 4b81b4b3b2..c3118fdd5c 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c @@ -367,6 +367,11 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) if (reason != HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT) { BTM_Recovery_Pre_State(); } + #if (BLE_50_FEATURE_SUPPORT == TRUE) + if(btm_ble_inter_get() && reason == HCI_ERR_CONN_FAILED_ESTABLISHMENT) { + BTM_BleStartExtAdvRestart(handle); + } + #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #endif ///BLE_INCLUDED == TRUE status = FALSE; } else { @@ -438,7 +443,7 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) #endif { #if (L2CAP_NUM_FIXED_CHNLS > 0) - /* If we are going to re-use the LCB without dropping it, release all fixed channels + /* If we are going to reuse the LCB without dropping it, release all fixed channels here */ int xx; for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { @@ -463,9 +468,9 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) } p_lcb->p_pending_ccb = NULL; -#if (BLE_INCLUDED == TRUE && GATTC_CONNECT_RETRY_EN == TRUE) +#if (BLE_INCLUDED == TRUE) if(reason == HCI_ERR_CONN_FAILED_ESTABLISHMENT && p_lcb->transport == BT_TRANSPORT_LE) { - + #if (GATTC_CONNECT_RETRY_EN == TRUE) if(p_lcb->link_role == HCI_ROLE_MASTER && p_lcb->retry_create_con < GATTC_CONNECT_RETRY_COUNT) { L2CAP_TRACE_DEBUG("master retry connect, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason); p_lcb->retry_create_con ++; @@ -475,9 +480,10 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) lcb_is_free = FALSE; /* still using this lcb */ } } + #endif // (GATTC_CONNECT_RETRY_EN == TRUE) #if (BLE_50_FEATURE_SUPPORT == TRUE) - if(btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE && p_lcb->retry_create_con < GATTC_CONNECT_RETRY_COUNT) { + if(btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE) { p_lcb->retry_create_con ++; L2CAP_TRACE_DEBUG("slave restart extend adv, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason); BTM_BleStartExtAdvRestart(handle); @@ -485,7 +491,7 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_42_FEATURE_SUPPORT == TRUE) - if(!btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE && p_lcb->retry_create_con < GATTC_CONNECT_RETRY_COUNT) { + if(!btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE) { p_lcb->retry_create_con ++; L2CAP_TRACE_DEBUG("slave resatrt adv, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason); btm_ble_start_adv(); @@ -909,7 +915,7 @@ UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles) ** ** Function l2c_link_role_changed ** -** Description This function is called whan a link's master/slave role change +** Description This function is called when a link's master/slave role change ** event is received. It simply updates the link control block. ** ** Returns void @@ -947,7 +953,7 @@ void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status) ** ** Function l2c_pin_code_request ** -** Description This function is called whan a pin-code request is received +** Description This function is called when a pin-code request is received ** on a connection. If there are no channels active yet on the ** link, it extends the link first connection timer. Make sure ** that inactivity timer is not extended if PIN code happens diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c index 364aac8467..dfdef99bef 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c @@ -52,6 +52,10 @@ tL2C_CB l2cb; tL2C_CB *l2c_cb_ptr; #endif +#if BT_CLASSIC_BQB_INCLUDED +static BOOLEAN s_l2cap_bqb_bad_cmd_len_rej_flag = FALSE; +#endif /* BT_CLASSIC_BQB_INCLUDED */ + #if 0 //Unused /******************************************************************************* ** @@ -107,6 +111,24 @@ void l2c_bcst_msg( BT_HDR *p_buf, UINT16 psm ) } #endif +/******************************************************************************* +** +** Function l2cap_bqb_bad_cmd_len_rej_ctrl +** +** Description Control rejecting L2CAP signaling PDUs with incorrect length +** for BQB test. +** +** Returns void +** +*******************************************************************************/ +#if BT_CLASSIC_BQB_INCLUDED +void l2cap_bqb_bad_cmd_len_rej_ctrl(BOOLEAN enable) +{ + s_l2cap_bqb_bad_cmd_len_rej_flag = enable; +} +#endif /* BT_CLASSIC_BQB_INCLUDED */ + + /******************************************************************************* ** ** Function l2c_rcv_acl_data @@ -461,6 +483,12 @@ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) p_ccb->remote_cid = rcid; l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_REQ, &con_info); +#if BT_CLASSIC_BQB_INCLUDED + // L2CAP/COS/CED/BI-02-C + if (s_l2cap_bqb_bad_cmd_len_rej_flag) { + l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); + } +#endif /* BT_CLASSIC_BQB_INCLUDED */ break; case L2CAP_CMD_CONN_RSP: diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index c70cd9c816..992d4b68eb 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -39,6 +39,10 @@ #include "osi/allocator.h" #include "osi/list.h" +#if BT_SDP_BQB_INCLUDED +extern BOOLEAN l2cap_bqb_ertm_mode_included_flag; +#endif /* BT_SDP_BQB_INCLUDED */ + /******************************************************************************* ** ** Function l2cu_allocate_lcb @@ -1558,8 +1562,17 @@ tL2C_CCB *l2cu_allocate_ccb (tL2C_LCB *p_lcb, UINT16 cid) #if (CLASSIC_BT_INCLUDED == TRUE) l2c_fcr_free_timer (p_ccb); #endif ///CLASSIC_BT_INCLUDED == TRUE - p_ccb->ertm_info.preferred_mode = L2CAP_FCR_BASIC_MODE; /* Default mode for channel is basic mode */ - p_ccb->ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_BASIC|L2CAP_FCR_CHAN_OPT_ERTM; + +#if BT_SDP_BQB_INCLUDED + if (l2cap_bqb_ertm_mode_included_flag) { + p_ccb->ertm_info.preferred_mode = L2CAP_FCR_ERTM_MODE; + p_ccb->ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_ERTM; + } else +#endif /* BT_SDP_BQB_INCLUDED */ + { + p_ccb->ertm_info.preferred_mode = L2CAP_FCR_BASIC_MODE; /* Default mode for channel is basic mode */ + p_ccb->ertm_info.allowed_modes = L2CAP_FCR_CHAN_OPT_BASIC|L2CAP_FCR_CHAN_OPT_ERTM; + } p_ccb->ertm_info.fcr_rx_buf_size = L2CAP_FCR_RX_BUF_SIZE; p_ccb->ertm_info.fcr_tx_buf_size = L2CAP_FCR_TX_BUF_SIZE; p_ccb->ertm_info.user_rx_buf_size = L2CAP_USER_RX_BUF_SIZE; diff --git a/components/bt/host/bluedroid/stack/rfcomm/rfc_ts_frames.c b/components/bt/host/bluedroid/stack/rfcomm/rfc_ts_frames.c index 0640c67fc9..86ba2550a5 100644 --- a/components/bt/host/bluedroid/stack/rfcomm/rfc_ts_frames.c +++ b/components/bt/host/bluedroid/stack/rfcomm/rfc_ts_frames.c @@ -500,6 +500,50 @@ void rfc_send_rpn (tRFC_MCB *p_mcb, UINT8 dlci, BOOLEAN is_command, rfc_send_buf_uih (p_mcb, RFCOMM_MX_DLCI, p_buf); } +#if BT_RFCOMM_BQB_INCLUDED +/******************************************************************************* +** +** Function rfc_bqb_send_msc_cmd +** +** Description This function sends msc command for BQB test. +** +*******************************************************************************/ +void rfc_bqb_send_msc_cmd(BD_ADDR cert_pts_addr) +{ + UINT8 i; + UINT8 dlci; + BOOLEAN get_dlci = FALSE; + tPORT *p_port; + tPORT_CTRL *p_pars; + tRFC_MCB *p_mcb; + + if ((p_pars = (tPORT_CTRL *)osi_malloc(sizeof(tPORT_CTRL))) == NULL) { + return; + } + + p_pars->modem_signal = 0; + p_pars->break_signal = 0; + p_pars->fc = TRUE; + + p_mcb = port_find_mcb (cert_pts_addr); + + for (i = 0; i < MAX_RFC_PORTS; i++) { + p_port = &rfc_cb.port.port[i]; + if (p_port->in_use && !memcmp (p_port->bd_addr, cert_pts_addr, BD_ADDR_LEN)) { + dlci = p_port->dlci; + get_dlci = TRUE; + break; + } + } + + if (get_dlci) { + rfc_send_msc(p_mcb, dlci, TRUE, p_pars); + } else { + RFCOMM_TRACE_ERROR ("Get dlci fail"); + } + osi_free(p_pars); +} +#endif /* BT_RFCOMM_BQB_INCLUDED */ /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/sdp/include/sdpint.h b/components/bt/host/bluedroid/stack/sdp/include/sdpint.h index 9c0e6047d0..ab97b70276 100644 --- a/components/bt/host/bluedroid/stack/sdp/include/sdpint.h +++ b/components/bt/host/bluedroid/stack/sdp/include/sdpint.h @@ -37,8 +37,10 @@ #define SDP_MAX_CONTINUATION_LEN 16 /* As per the spec */ /* Timeout definitions. */ -#define SDP_INACT_TIMEOUT 30 /* Inactivity timeout */ - +#define SDP_INACT_TIMEOUT 30 /* Inactivity timeout */ +#if BT_SDP_BQB_INCLUDED +#define SDP_BQB_INACT_TIMEOUT 90 /* Inactivity timeout for BQB test */ +#endif /* BT_SDP_BQB_INCLUDED */ /* Define the Out-Flow default values. */ #define SDP_OFLOW_QOS_FLAG 0 diff --git a/components/bt/host/bluedroid/stack/sdp/sdp_main.c b/components/bt/host/bluedroid/stack/sdp/sdp_main.c index 3e73337191..e945314b83 100644 --- a/components/bt/host/bluedroid/stack/sdp/sdp_main.c +++ b/components/bt/host/bluedroid/stack/sdp/sdp_main.c @@ -71,6 +71,59 @@ static void sdp_disconnect_cfm (UINT16 l2cap_cid, UINT16 result); #define sdp_disconnect_cfm NULL #endif +#if BT_SDP_BQB_INCLUDED +static BOOLEAN s_sdp_bqb_disable_flag = FALSE; +static BOOLEAN s_sdp_bqb_inact_timeout_flag = FALSE; +BOOLEAN l2cap_bqb_ertm_mode_included_flag = FALSE; +#endif /* BT_SDP_BQB_INCLUDED */ + +/******************************************************************************* +** +** Function sdp_bqb_disable_ctrl +** +** Description Control the disable of bqb for SDP BQB test +** +** Returns void +** +*******************************************************************************/ +#if BT_SDP_BQB_INCLUDED +void sdp_bqb_disable_ctrl(BOOLEAN enable) +{ + s_sdp_bqb_disable_flag = enable; +} +#endif /* BT_SDP_BQB_INCLUDED */ + +/******************************************************************************* +** +** Function sdp_bqb_inact_timeout_ctrl +** +** Description Control the inactivity timeout for SDP BQB test +** +** Returns void +** +*******************************************************************************/ +#if BT_SDP_BQB_INCLUDED +void sdp_bqb_inact_timeout_ctrl(BOOLEAN enable) +{ + s_sdp_bqb_inact_timeout_flag = enable; +} +#endif /* BT_SDP_BQB_INCLUDED */ + +/******************************************************************************* +** +** Function l2cap_bqb_ertm_mode_included_ctrl +** +** Description Control the L2CAP flow control and retransmissions mode for SDP BQB test +** +** Returns void +** +*******************************************************************************/ +#if BT_SDP_BQB_INCLUDED +void l2cap_bqb_ertm_mode_included_ctrl(BOOLEAN enable) +{ + l2cap_bqb_ertm_mode_included_flag = enable; +} +#endif /* BT_SDP_BQB_INCLUDED */ /******************************************************************************* ** @@ -95,7 +148,17 @@ void sdp_init (void) sdp_cb.l2cap_my_cfg.mtu = SDP_MTU_SIZE; sdp_cb.l2cap_my_cfg.flush_to_present = TRUE; sdp_cb.l2cap_my_cfg.flush_to = SDP_FLUSH_TO; - +#if BT_SDP_BQB_INCLUDED + if (l2cap_bqb_ertm_mode_included_flag) { + sdp_cb.l2cap_my_cfg.fcr_present = TRUE; + sdp_cb.l2cap_my_cfg.fcr.mode = L2CAP_FCR_ERTM_MODE; + sdp_cb.l2cap_my_cfg.fcr.tx_win_sz = 8; + sdp_cb.l2cap_my_cfg.fcr.max_transmit = 0xff; + sdp_cb.l2cap_my_cfg.fcr.rtrans_tout = 2000; + sdp_cb.l2cap_my_cfg.fcr.mon_tout = 12000; + sdp_cb.l2cap_my_cfg.fcr.mps = 672; + } +#endif /* BT_SDP_BQB_INCLUDED */ sdp_cb.max_attr_list_size = SDP_MTU_SIZE - 16; sdp_cb.max_recs_per_search = SDP_MAX_DISC_SERVER_RECS; @@ -424,7 +487,15 @@ static void sdp_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg) } else /* Start inactivity timer */ { - btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_SDP, SDP_INACT_TIMEOUT); +#if BT_SDP_BQB_INCLUDED + /* Change the timeout from 30s to 90s for BQB test */ + if (s_sdp_bqb_inact_timeout_flag) { + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_SDP, SDP_BQB_INACT_TIMEOUT); + } else +#endif /* BT_SDP_BQB_INCLUDED */ + { + btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_SDP, SDP_INACT_TIMEOUT); + } } } } else { @@ -505,10 +576,17 @@ static void sdp_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg) /* Find CCB based on CID */ if ((p_ccb = sdpu_find_ccb_by_cid (l2cap_cid)) != NULL) { if (p_ccb->con_state == SDP_STATE_CONNECTED) { - if (p_ccb->con_flags & SDP_FLAGS_IS_ORIG) { - sdp_disc_server_rsp (p_ccb, p_msg); - } else { - sdp_server_handle_client_req (p_ccb, p_msg); +#if BT_SDP_BQB_INCLUDED + /* Skip the following code in BQB test when the flag is true, since the PDU is reserved and + function sdp_server_handle_client_req will return error (sdpu_build_n_send_error) */ + if (!s_sdp_bqb_disable_flag) +#endif /* BT_SDP_BQB_INCLUDED */ + { + if (p_ccb->con_flags & SDP_FLAGS_IS_ORIG) { + sdp_disc_server_rsp(p_ccb, p_msg); + } else { + sdp_server_handle_client_req(p_ccb, p_msg); + } } } else { SDP_TRACE_WARNING ("SDP - Ignored L2CAP data while in state: %d, CID: 0x%x\n", diff --git a/components/bt/host/bluedroid/stack/smp/smp_api.c b/components/bt/host/bluedroid/stack/smp/smp_api.c index df8f4cea21..78e295f4f1 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_api.c +++ b/components/bt/host/bluedroid/stack/smp/smp_api.c @@ -125,7 +125,7 @@ BOOLEAN SMP_Register (tSMP_CALLBACK *p_cback) SMP_TRACE_EVENT ("SMP_Register state=%d", smp_cb.state); if (smp_cb.p_callback != NULL) { - SMP_TRACE_ERROR ("SMP_Register: duplicate registration, overwrite it"); + SMP_TRACE_WARNING ("SMP_Register: duplicate registration, overwrite it"); } smp_cb.p_callback = p_cback; diff --git a/components/bt/host/bluedroid/stack/smp/smp_cmac.c b/components/bt/host/bluedroid/stack/smp/smp_cmac.c index 391f538353..e47c56b71f 100644 --- a/components/bt/host/bluedroid/stack/smp/smp_cmac.c +++ b/components/bt/host/bluedroid/stack/smp/smp_cmac.c @@ -133,7 +133,7 @@ static void cmac_aes_cleanup(void) static BOOLEAN cmac_aes_k_calculate(BT_OCTET16 key, UINT8 *p_signature, UINT16 tlen) { tSMP_ENC output; - UINT8 i = 1, err = 0; + UINT16 i = 1, err = 0; UINT8 x[16] = {0}; UINT8 *p_mac; diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index 869ccad1f1..d352fe1342 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -65,6 +65,8 @@ config BT_NIMBLE_LOG_LEVEL config BT_NIMBLE_MAX_CONNECTIONS int "Maximum number of concurrent connections" range 1 2 if IDF_TARGET_ESP32C2 + range 1 70 if IDF_TARGET_ESP32C6 + range 1 35 if IDF_TARGET_ESP32H2 range 1 9 default 2 if IDF_TARGET_ESP32C2 default 3 @@ -162,6 +164,16 @@ config BT_NIMBLE_NVS_PERSIST help Enable this flag to make bonding persistent across device reboots +config BT_NIMBLE_SMP_ID_RESET + bool "Reset device identity when all bonding records are deleted" + default n + help + There are tracking risks associated with using a fixed or static IRK. + If enabled this option, Bluedroid will assign a new randomly-generated IRK + when all pairing and bonding records are deleted. This would decrease the ability + of a previously paired peer to be used to determine whether a device + with which it previously shared an IRK is within range. + menuconfig BT_NIMBLE_SECURITY_ENABLE bool "Enable BLE SM feature" depends on BT_NIMBLE_ENABLED @@ -199,6 +211,17 @@ config BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION help Enable encryption connection +config BT_NIMBLE_SM_SC_LVL + int "Security level" + depends on BT_NIMBLE_SECURITY_ENABLE + default 0 + help + LE Security Mode 1 Levels: + 1. No Security + 2. Unauthenticated pairing with encryption + 3. Authenticated pairing with encryption + 4. Authenticated LE Secure Connections pairing with encryption using a 128-bit strength encryption key. + config BT_NIMBLE_DEBUG bool "Enable extra runtime asserts and host debugging" default n @@ -206,6 +229,12 @@ config BT_NIMBLE_DEBUG help This enables extra runtime asserts and host debugging +config BT_NIMBLE_DYNAMIC_SERVICE + bool "Enable dynamic services" + depends on BT_NIMBLE_ENABLED + help + This enables user to add/remove Gatt services at runtime + config BT_NIMBLE_SVC_GAP_DEVICE_NAME string "BLE GAP default device name" depends on BT_NIMBLE_ENABLED @@ -267,6 +296,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 @@ -359,8 +397,7 @@ config BT_NIMBLE_RPA_TIMEOUT depends on BT_NIMBLE_ENABLED default 900 help - Time interval between RPA address change. This is applicable in case of - Host based RPA + Time interval between RPA address change. menuconfig BT_NIMBLE_MESH bool "Enable BLE mesh functionality" @@ -463,7 +500,6 @@ config BT_NIMBLE_CRYPTO_STACK_MBEDTLS bool "Override TinyCrypt with mbedTLS for crypto computations" default y depends on BT_NIMBLE_ENABLED - select MBEDTLS_ECP_RESTARTABLE select MBEDTLS_CMAC_C help Enable this option to choose mbedTLS instead of TinyCrypt for crypto @@ -494,7 +530,7 @@ config BT_NIMBLE_ENABLE_CONN_REATTEMPT config BT_NIMBLE_MAX_CONN_REATTEMPT int "Maximum number connection reattempts" - range 1 7 + range 1 255 default 3 depends on BT_NIMBLE_ENABLED && BT_NIMBLE_ENABLE_CONN_REATTEMPT help @@ -562,7 +598,7 @@ if BT_NIMBLE_EXT_ADV Enable this option to start periodic advertisement. config BT_NIMBLE_PERIODIC_ADV_SYNC_TRANSFER - bool "Enable Transer Sync Events" + bool "Enable Transfer Sync Events" depends on BT_NIMBLE_ENABLE_PERIODIC_ADV default y help @@ -596,31 +632,42 @@ config BT_NIMBLE_BLE_POWER_CONTROL help Set this option to enable the Power Control feature -choice BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM - prompt "Coexistence: limit on MAX Tx/Rx time for coded-PHY connection" - default BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_DIS - depends on ESP_WIFI_SW_COEXIST_ENABLE && BT_NIMBLE_ENABLED +config BT_NIMBLE_PERIODIC_ADV_ENH + bool "Periodic adv enhancements(adi support)" + depends on BT_NIMBLE_ENABLE_PERIODIC_ADV && BT_NIMBLE_50_FEATURE_SUPPORT && SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED help - When using PHY-Coded in BLE connection, limitation on max tx/rx time can be applied to - better avoid dramatic performance deterioration of Wi-Fi. - - config BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EN - bool "Force Enable" - help - Always enable the limitation on max tx/rx time for Coded-PHY connection - - config BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_DIS - bool "Force Disable" - help - Disable the limitation on max tx/rx time for Coded-PHY connection -endchoice - -config BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EFF - int - default 0 if !(ESP_WIFI_SW_COEXIST_ENABLE && BT_NIMBLE_ENABLED) - default 1 if BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EN - default 0 if BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_DIS + Enable the periodic advertising enhancements +menuconfig BT_NIMBLE_GATT_CACHING + bool "Enable GATT caching" + depends on BT_NIMBLE_ENABLED && BT_NIMBLE_50_FEATURE_SUPPORT + select BT_NIMBLE_DYNAMIC_SERVICE + help + Enable GATT caching +config BT_NIMBLE_GATT_CACHING_MAX_CONNS + int "Maximum connections to be cached" + depends on BT_NIMBLE_GATT_CACHING + default 1 + help + Set this option to set the upper limit on number of connections to be cached. +config BT_NIMBLE_GATT_CACHING_MAX_SVCS + int "Maximum number of services per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of services per connection to be cached. +config BT_NIMBLE_GATT_CACHING_MAX_CHRS + int "Maximum number of characteristics per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of characteristics per connection to be cached. +config BT_NIMBLE_GATT_CACHING_MAX_DSCS + int "Maximum number of descriptors per connection" + depends on BT_NIMBLE_GATT_CACHING + default 64 + help + Set this option to set the upper limit on number of descriptors per connection to be cached. config BT_NIMBLE_WHITELIST_SIZE int "BLE white list size" @@ -662,8 +709,350 @@ config BT_NIMBLE_BLE_GATT_BLOB_TRANSFER This option is used when data to be sent is more than 512 bytes. For peripheral role, BT_NIMBLE_MSYS_1_BLOCK_COUNT needs to be increased according to the need. +menu "GAP Service" + menu "GAP Appearance write permissions" + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE + bool "Write" + default n + help + Enable write permission (BLE_GATT_CHR_F_WRITE) + + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_ENC + depends on BT_NIMBLE_SVC_GAP_APPEAR_WRITE + bool "Write with encryption" + default n + help + Enable write with encryption permission (BLE_GATT_CHR_F_WRITE_ENC) + + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHEN + depends on BT_NIMBLE_SVC_GAP_APPEAR_WRITE + bool "Write with authentication" + default n + help + Enable write with authentication permission (BLE_GATT_CHR_F_WRITE_AUTHEN) + + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHOR + depends on BT_NIMBLE_SVC_GAP_APPEAR_WRITE + bool "Write with authorisation" + default n + help + Enable write with authorisation permission (BLE_GATT_CHR_F_WRITE_AUTHOR) + endmenu + + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM + int + default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE + default 8 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE + + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC + int + default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE_ENC + default 4096 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE_ENC + + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN + int + default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHEN + default 8192 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHEN + + config BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR + int + default 0 if !BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHOR + default 16384 if BT_NIMBLE_SVC_GAP_APPEAR_WRITE_AUTHOR + + choice BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION + prompt "GAP Characteristic - Central Address Resolution" + default BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP + help + Weather or not Central Address Resolution characteristic is supported on + the device, and if supported, weather or not Central Address Resolution + is supported. + + - Central Address Resolution characteristic not supported + - Central Address Resolution not supported + - Central Address Resolution supported + + config BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP + bool "Characteristic not supported" + + config BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP + bool "Central Address Resolution not supported" + + config BT_NIMBLE_SVC_GAP_CAR_SUPP + bool "Central Address Resolution supported" + endchoice + + config BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION + int + default -1 if BT_NIMBLE_SVC_GAP_CAR_CHAR_NOT_SUPP + default 0 if BT_NIMBLE_SVC_GAP_CAR_NOT_SUPP + default 1 if BT_NIMBLE_SVC_GAP_CAR_SUPP + + menu "GAP device name write permissions" + config BT_NIMBLE_SVC_GAP_NAME_WRITE + bool "Write" + default n + help + Enable write permission (BLE_GATT_CHR_F_WRITE) + + config BT_NIMBLE_SVC_GAP_NAME_WRITE_ENC + depends on BT_NIMBLE_SVC_GAP_NAME_WRITE + bool "Write with encryption" + default n + help + Enable write with encryption permission (BLE_GATT_CHR_F_WRITE_ENC) + + config BT_NIMBLE_SVC_GAP_NAME_WRITE_AUTHEN + depends on BT_NIMBLE_SVC_GAP_NAME_WRITE + bool "Write with authentication" + default n + help + Enable write with authentication permission (BLE_GATT_CHR_F_WRITE_AUTHEN) + + config BT_NIMBLE_SVC_GAP_NAME_WRITE_AUTHOR + depends on BT_NIMBLE_SVC_GAP_NAME_WRITE + bool "Write with authorisation" + default n + help + Enable write with authorisation permission (BLE_GATT_CHR_F_WRITE_AUTHOR) + endmenu + + config BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM + int + default 0 if !BT_NIMBLE_SVC_GAP_NAME_WRITE + default 8 if BT_NIMBLE_SVC_GAP_NAME_WRITE + + config BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC + int + default 0 if !BT_NIMBLE_SVC_GAP_NAME_WRITE_ENC + default 4096 if BT_NIMBLE_SVC_GAP_NAME_WRITE_ENC + + config BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN + int + default 0 if !BT_NIMBLE_SVC_GAP_NAME_WRITE_AUTHEN + default 8192 if BT_NIMBLE_SVC_GAP_NAME_WRITE_AUTHEN + + config BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR + int + default 0 if !BT_NIMBLE_SVC_GAP_NAME_WRITE_AUTHOR + default 16384 if BT_NIMBLE_SVC_GAP_NAME_WRITE_AUTHOR + + config BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL + int "PPCP Connection Interval Max (Unit: 1.25 ms)" + depends on BT_NIMBLE_ROLE_PERIPHERAL + default 0 + help + Peripheral Preferred Connection Parameter: Connection Interval maximum value + Interval Max = value * 1.25 ms + + config BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL + int "PPCP Connection Interval Min (Unit: 1.25 ms)" + depends on BT_NIMBLE_ROLE_PERIPHERAL + default 0 + help + Peripheral Preferred Connection Parameter: Connection Interval minimum value + Interval Min = value * 1.25 ms + + config BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY + int "PPCP Slave Latency" + default 0 + help + Peripheral Preferred Connection Parameter: Slave Latency + + config BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO + int "PPCP Supervision Timeout (Uint: 10 ms)" + default 0 + help + Peripheral Preferred Connection Parameter: Supervision Timeout + Timeout = Value * 10 ms + +endmenu + +menu "BLE Services" + menuconfig BT_NIMBLE_HID_SERVICE + bool "HID service" + depends on BT_NIMBLE_ENABLED + default n + help + Enable HID service support + + config BT_NIMBLE_SVC_HID_MAX_INSTANCES + depends on BT_NIMBLE_HID_SERVICE + int "Maximum HID service instances" + default 2 + help + Defines maximum number of HID service instances + + config BT_NIMBLE_SVC_HID_MAX_RPTS + depends on BT_NIMBLE_HID_SERVICE + int "Maximum HID Report characteristics per service instance" + default 3 + help + Defines maximum number of report characteristics per service instance +endmenu + config BT_NIMBLE_VS_SUPPORT bool "Enable support for VSC and VSE" help This option is used to enable support for sending Vendor Specific HCI commands and handling Vendor Specific HCI Events. + +config BT_NIMBLE_OPTIMIZE_MULTI_CONN + bool "Enable the optimization of multi-connection" + depends on SOC_BLE_MULTI_CONN_OPTIMIZATION + select BT_NIMBLE_VS_SUPPORT + default n + help + This option enables the use of vendor-specific APIs for multi-connections, which can + greatly enhance the stability of coexistence between numerous central and peripheral + devices. It will prohibit the usage of standard APIs. + +config BT_NIMBLE_ENC_ADV_DATA + bool "Encrypted Advertising Data" + select BT_NIMBLE_EXT_ADV + help + This option is used to enable encrypted advertising data. + +config BT_NIMBLE_MAX_EADS + int "Maximum number of EAD devices to save across reboots" + default 10 + depends on BT_NIMBLE_ENABLED && BT_NIMBLE_ENC_ADV_DATA + help + Defines maximum number of encrypted advertising data key material to save + +config BT_NIMBLE_HIGH_DUTY_ADV_ITVL + bool "Enable BLE high duty advertising interval feature" + depends on BT_NIMBLE_ENABLED + help + This enable BLE high duty advertising interval feature + +config BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN + bool "Allow Connections with scanning in progress" + depends on BT_NIMBLE_ENABLED && (IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3) + help + This enables support for user to initiate a new connection with scan in progress + +config BT_NIMBLE_HOST_QUEUE_CONG_CHECK + bool "BLE queue congestion check" + depends on BT_NIMBLE_ENABLED + default n + help + When scanning and scan duplicate is not enabled, if there are a lot of adv packets around + or application layer handling adv packets is slow, it will cause the controller memory + to run out. if enabled, adv packets will be lost when host queue is congested. + +menu "Host-controller Transport" + config BT_NIMBLE_TRANSPORT_UART + bool "Enable Uart Transport" + default y + depends on BT_CONTROLLER_DISABLED + help + Use UART transport + + config BT_NIMBLE_TRANSPORT_UART_PORT + int "Uart port" + depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART + default 1 + help + Uart port + + choice BT_NIMBLE_HCI_USE_UART_BAUDRATE + prompt "Uart Hci Baud Rate" + default UART_BAUDRATE_921600 + depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART + help + Uart Baud Rate + + config UART_BAUDRATE_115200 + bool "115200" + config UART_BAUDRATE_230400 + bool "230400" + config UART_BAUDRATE_460800 + bool "460800" + config UART_BAUDRATE_921600 + bool "921600" + endchoice + + config BT_NIMBLE_HCI_UART_BAUDRATE + depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART + int + default 115200 if UART_BAUDRATE_115200 + default 230400 if UART_BAUDRATE_230400 + default 460800 if UART_BAUDRATE_460800 + default 921600 if UART_BAUDRATE_921600 + + choice BT_NIMBLE_USE_HCI_UART_PARITY + prompt "Uart PARITY" + default UART_PARITY_NONE + depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART + help + Uart Parity + + config UART_PARITY_NONE + bool "None" + config UART_PARITY_ODD + bool "Odd" + config UART_PARITY_EVEN + bool "Even" + endchoice + + config BT_NIMBLE_TRANSPORT_UART_PARITY_NONE + int + default 0 if !UART_PARITY_NONE + default 1 if UART_PARITY_NONE + depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART + + config BT_NIMBLE_TRANSPORT_UART_PARITY_ODD + int + default 0 if !UART_PARITY_ODD + default 1 if UART_PARITY_ODD + depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART + + config BT_NIMBLE_TRANSPORT_UART_PARITY_EVEN + int + default 0 if !UART_PARITY_EVEN + default 1 if UART_PARITY_EVEN + depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART + + config BT_NIMBLE_UART_RX_PIN + int "UART Rx pin" + depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART + default 5 + help + Rx pin for Nimble Transport + + config BT_NIMBLE_UART_TX_PIN + int "UART Tx pin" + depends on BT_CONTROLLER_DISABLED && BT_NIMBLE_TRANSPORT_UART + default 4 + help + Tx pin for Nimble Transport + + choice BT_NIMBLE_USE_HCI_UART_FLOW_CTRL + prompt "Uart Flow Control" + default UART_HW_FLOWCTRL_DISABLE + help + Uart Flow Control + + config UART_HW_FLOWCTRL_DISABLE + bool "Disable" + config UART_HW_FLOWCTRL_CTS_RTS + bool "Enable hardware flow control" + endchoice + + config BT_NIMBLE_HCI_UART_FLOW_CTRL + int + default 0 if UART_HW_FLOWCTRL_DISABLE + default 1 if UART_HW_FLOWCTRL_CTS_RTS + + config BT_NIMBLE_HCI_UART_RTS_PIN + int "UART Rts Pin" + default 19 + help + UART HCI RTS pin + + config BT_NIMBLE_HCI_UART_CTS_PIN + int "UART Cts Pin" + default 23 + help + UART HCI CTS pin +endmenu diff --git a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c index 90ceea94b5..ed4b7adfeb 100644 --- a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c +++ b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,10 +15,14 @@ #include "esp_nimble_hci.h" #include "esp_nimble_mem.h" #include "bt_osi_mem.h" +#if CONFIG_BT_CONTROLLER_ENABLED #include "esp_bt.h" +#endif #include "freertos/semphr.h" #include "esp_compiler.h" #include "soc/soc_caps.h" +#include "bt_common.h" +#include "hci_log/bt_hci_log.h" #define NIMBLE_VHCI_TIMEOUT_MS 2000 #define BLE_HCI_EVENT_HDR_LEN (2) @@ -59,6 +63,13 @@ void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb, ble_hci_rx_acl_hs_arg = acl_arg; } +void esp_vhci_host_send_packet_wrapper(uint8_t *data, uint16_t len) +{ +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_record_hci_data(data[0], &data[1], len - 1); +#endif + esp_vhci_host_send_packet(data, len); +} int ble_hci_trans_hs_cmd_tx(uint8_t *cmd) { @@ -73,7 +84,7 @@ int ble_hci_trans_hs_cmd_tx(uint8_t *cmd) } if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { - esp_vhci_host_send_packet(cmd, len); + esp_vhci_host_send_packet_wrapper(cmd, len); } else { rc = BLE_HS_ETIMEOUT_HCI; } @@ -110,7 +121,7 @@ int ble_hci_trans_hs_acl_tx(struct os_mbuf *om) len += OS_MBUF_PKTLEN(om); if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { - esp_vhci_host_send_packet(data, len); + esp_vhci_host_send_packet_wrapper(data, len); } else { rc = BLE_HS_ETIMEOUT_HCI; } @@ -168,7 +179,6 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len) OS_EXIT_CRITICAL(sr); } - /* * @brief: BT controller callback function, used to notify the upper layer that * controller is ready to receive command @@ -180,11 +190,26 @@ static void controller_rcv_pkt_ready(void) } } +void bt_record_hci_data(uint8_t *data, uint16_t len) +{ +#if (BT_HCI_LOG_INCLUDED == TRUE) + if ((data[0] == BLE_HCI_UART_H4_EVT) && (data[1] == BLE_HCI_EVCODE_LE_META) && ((data[3] == BLE_HCI_LE_SUBEV_ADV_RPT) || (data[3] == BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT) + || (data[3] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT) || (data[3] == BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT))) { + bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2); + } else { + uint8_t data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]); + bt_hci_log_record_hci_data(data_type, &data[1], len - 1); + } +#endif // (BT_HCI_LOG_INCLUDED == TRUE) +} + /* * @brief: BT controller callback function, to transfer data packet to the host */ static int host_rcv_pkt(uint8_t *data, uint16_t len) { + bt_record_hci_data(data, len); + if(!ble_hs_enabled_state) { /* If host is not enabled, drop the packet */ ESP_LOGE(TAG, "Host not enabled. Dropping the packet!"); @@ -265,6 +290,10 @@ esp_err_t esp_nimble_hci_init(void) xSemaphoreGive(vhci_send_sem); +#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) + ble_adv_list_init(); +#endif + return ret; err: ble_buf_free(); @@ -286,5 +315,9 @@ esp_err_t esp_nimble_hci_deinit(void) ble_buf_free(); +#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) + ble_adv_list_deinit(); +#endif + return ESP_OK; } diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index ec23739a74..1fa7edc41d 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit ec23739a744aff94762d5013fc60d50275ca797a +Subproject commit 1fa7edc41d7ee415699b7abe8fa1f7375d344c83 diff --git a/components/bt/host/nimble/port/include/esp_nimble_cfg.h b/components/bt/host/nimble/port/include/esp_nimble_cfg.h index 66d85102c4..06aa199add 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/components/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -104,6 +104,12 @@ #define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (CONFIG_BT_NIMBLE_EXT_ADV_MAX_SIZE) #endif +#ifndef CONFIG_BT_NIMBLE_ENC_ADV_DATA +#define MYNEWT_VAL_ENC_ADV_DATA (0) +#else +#define MYNEWT_VAL_ENC_ADV_DATA (CONFIG_BT_NIMBLE_ENC_ADV_DATA) +#endif + #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) #define BLE_SCAN_RSP_DATA_MAX_LEN_N (1650) #else @@ -123,6 +129,37 @@ #define MYNEWT_VAL_BLE_MAX_PERIODIC_ADVERTISER_LIST (CONFIG_BT_NIMBLE_MAX_PERIODIC_ADVERTISER_LIST) #endif +#ifndef CONFIG_BT_NIMBLE_GATT_CACHING +#define MYNEWT_VAL_BLE_GATT_CACHING (0) +#else +#define MYNEWT_VAL_BLE_GATT_CACHING (CONFIG_BT_NIMBLE_GATT_CACHING) + +#ifdef CONFIG_BT_NIMBLE_GATT_CACHING_MAX_CONNS +#define MYNEWT_VAL_BLE_GATT_CACHING_MAX_CONNS (CONFIG_BT_NIMBLE_GATT_CACHING_MAX_CONNS) +#else +#define MYNEWT_VAL_BLE_GATT_CACHING_MAX_CONNS (0) +#endif + +#ifdef CONFIG_BT_NIMBLE_GATT_CACHING_MAX_SVCS +#define MYNEWT_VAL_BLE_GATT_CACHING_MAX_SVCS (CONFIG_BT_NIMBLE_GATT_CACHING_MAX_SVCS) +#else +#define MYNEWT_VAL_BLE_GATT_CACHING_MAX_SVCS (0) +#endif + +#ifdef CONFIG_BT_NIMBLE_GATT_CACHING_MAX_CHRS +#define MYNEWT_VAL_BLE_GATT_CACHING_MAX_CHRS (CONFIG_BT_NIMBLE_GATT_CACHING_MAX_CHRS) +#else +#define MYNEWT_VAL_BLE_GATT_CACHING_MAX_CHRS (0) +#endif + +#ifdef CONFIG_BT_NIMBLE_GATT_CACHING_MAX_DSCS +#define MYNEWT_VAL_BLE_GATT_CACHING_MAX_DSCS (CONFIG_BT_NIMBLE_GATT_CACHING_MAX_DSCS) +#else +#define MYNEWT_VAL_BLE_GATT_CACHING_MAX_DSCS (0) +#endif + +#endif + #ifndef CONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES #define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (1) #else @@ -180,6 +217,11 @@ #else #define MYNEWT_VAL_BLE_CONN_SUBRATING (CONFIG_BT_NIMBLE_SUBRATE) #endif +#ifndef CONFIG_BT_NIMBLE_PERIODIC_ADV_ENH +#define MYNEWT_VAL_BLE_PERIODIC_ADV_ENH (0) +#else +#define MYNEWT_VAL_BLE_PERIODIC_ADV_ENH (CONFIG_BT_NIMBLE_PERIODIC_ADV_ENH) +#endif /*** @apache-mynewt-nimble/nimble/controller */ /*** @apache-mynewt-nimble/nimble/controller */ @@ -192,7 +234,7 @@ #endif #ifndef MYNEWT_VAL_BLE_VERSION -#define MYNEWT_VAL_BLE_VERSION (50) +#define MYNEWT_VAL_BLE_VERSION (54) #endif #ifndef MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS @@ -464,6 +506,15 @@ #endif /*** @apache-mynewt-nimble/nimble/host */ + +#ifndef MYNEWT_VAL_BLE_DYNAMIC_SERVICE +#ifdef CONFIG_BT_NIMBLE_DYNAMIC_SERVICE +#define MYNEWT_VAL_BLE_DYNAMIC_SERVICE CONFIG_BT_NIMBLE_DYNAMIC_SERVICE +#else +#define MYNEWT_VAL_BLE_DYNAMIC_SERVICE (0) +#endif +#endif + #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU #endif @@ -584,6 +635,10 @@ #define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif +#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT_VAR +#define MYNEWT_VAL_BLE_GATT_READ_MULT_VAR (MYNEWT_VAL_BLE_ROLE_CENTRAL) +#endif + #ifndef MYNEWT_VAL_BLE_GATT_READ_UUID #define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL) #endif @@ -818,8 +873,12 @@ #ifndef MYNEWT_VAL_BLE_SM_SC_LVL +#ifdef CONFIG_BT_NIMBLE_SM_SC_LVL +#define MYNEWT_VAL_BLE_SM_SC_LVL CONFIG_BT_NIMBLE_SM_SC_LVL +#else #define MYNEWT_VAL_BLE_SM_SC_LVL (0) #endif +#endif #ifndef MYNEWT_VAL_BLE_SM_SC_ONLY #define MYNEWT_VAL_BLE_SM_SC_ONLY (0) @@ -830,6 +889,14 @@ #define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0) #endif +#ifndef MYNEWT_VAL_BLE_SMP_ID_RESET +#ifdef CONFIG_BT_NIMBLE_SMP_ID_RESET +#define MYNEWT_VAL_BLE_SMP_ID_RESET CONFIG_BT_NIMBLE_SMP_ID_RESET +#else +#define MYNEWT_VAL_BLE_SMP_ID_RESET (0) +#endif +#endif + #ifndef MYNEWT_VAL_BLE_CRYPTO_STACK_MBEDTLS #define MYNEWT_VAL_BLE_CRYPTO_STACK_MBEDTLS (CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS) #endif @@ -842,6 +909,10 @@ #define MYNEWT_VAL_BLE_STORE_MAX_CCCDS CONFIG_BT_NIMBLE_MAX_CCCDS #endif +#ifdef CONFIG_BT_NIMBLE_MAX_EADS +#define MYNEWT_VAL_BLE_STORE_MAX_EADS CONFIG_BT_NIMBLE_MAX_EADS +#endif + #ifndef MYNEWT_VAL_BLE_STORE_CONFIG_PERSIST #ifdef CONFIG_BT_NIMBLE_NVS_PERSIST #define MYNEWT_VAL_BLE_STORE_CONFIG_PERSIST (1) @@ -888,6 +959,20 @@ #ifndef MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM #define MYNEWT_VAL_BLE_SVC_BAS_BATTERY_LEVEL_READ_PERM (0) #endif + +/*** nimble/host/services/hid */ +#ifndef MYNEWT_VAL_BLE_SVC_HID_SERVICE +#define MYNEWT_VAL_BLE_SVC_HID_SERVICE CONFIG_BT_NIMBLE_HID_SERVICE +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_HID_MAX_RPTS +#define MYNEWT_VAL_BLE_SVC_HID_MAX_RPTS CONFIG_BT_NIMBLE_SVC_HID_MAX_RPTS +#endif + +#ifndef MYNEWT_VAL_BLE_SVC_HID_MAX_SVC_INSTANCES +#define MYNEWT_VAL_BLE_SVC_HID_MAX_SVC_INSTANCES CONFIG_BT_NIMBLE_SVC_HID_MAX_INSTANCES +#endif + #ifndef MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO #define MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO (9) #endif @@ -1550,17 +1635,34 @@ #define MYNEWT_VAL_BLE_SVC_DIS_SYSTEM_ID_READ_PERM (-1) #endif +#ifndef MYNEWT_VAL_BLE_SVC_DIS_PNP_ID_DEFAULT +#define MYNEWT_VAL_BLE_SVC_DIS_PNP_ID_DEFAULT (NULL) +#endif + +/* Value copied from BLE_SVC_DIS_DEFAULT_READ_PERM */ +#ifndef MYNEWT_VAL_BLE_SVC_DIS_PNP_ID_READ_PERM +#define MYNEWT_VAL_BLE_SVC_DIS_PNP_ID_READ_PERM (-1) +#endif + /*** @apache-mynewt-nimble/nimble/host/services/gap */ #ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE #define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM +#if CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM +#define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM ( \ + CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ENC | \ + CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHN | \ + CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM_ATHR) +#else #define MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM (-1) -#endif +#endif //CONFIG_BT_NIMBLE_SVC_GAP_APPEAR_WRITE_PERM +#endif //MYNEWT_VAL_BLE_SVC_GAP_APPEARANCE_WRITE_PERM #ifndef MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION -#define MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION (-1) +#define MYNEWT_VAL_BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION \ + CONFIG_BT_NIMBLE_SVC_GAP_CENT_ADDR_RESOLUTION #endif #ifndef CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME @@ -1574,23 +1676,34 @@ #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM +#if CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM +#define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM ( \ + CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_ENC | \ + CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHEN | \ + CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM_AUTHOR) +#else #define MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM (-1) -#endif +#endif //CONFIG_BT_NIMBLE_SVC_GAP_NAME_WRITE_PERM +#endif //MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM #ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL -#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL (0) +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL \ + CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL -#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL (0) +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL \ + CONFIG_BT_NIMBLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY -#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY (0) +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SLAVE_LATENCY \ + CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SLAVE_LATENCY #endif #ifndef MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO -#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO (0) +#define MYNEWT_VAL_BLE_SVC_GAP_PPCP_SUPERVISION_TMO \ + CONFIG_BT_NIMBLE_SVC_GAP_PPCP_SUPERVISION_TMO #endif /*** nimble/transport */ @@ -1688,4 +1801,78 @@ #define MYNEWT_VAL_BLE_HCI_VS (0) #endif +#ifndef MYNEWT_VAL_OPTIMIZE_MULTI_CONN +#ifdef CONFIG_BT_NIMBLE_OPTIMIZE_MULTI_CONN +#define MYNEWT_VAL_OPTIMIZE_MULTI_CONN CONFIG_BT_NIMBLE_OPTIMIZE_MULTI_CONN +#else +#define MYNEWT_VAL_OPTIMIZE_MULTI_CONN (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_HIGH_DUTY_ADV_ITVL +#ifdef CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL +#define MYNEWT_VAL_BLE_HIGH_DUTY_ADV_ITVL CONFIG_BT_NIMBLE_HIGH_DUTY_ADV_ITVL +#else +#define MYNEWT_VAL_BLE_HIGH_DUTY_ADV_ITVL (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_QUEUE_CONG_CHECK +#ifdef CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK +#define MYNEWT_VAL_BLE_QUEUE_CONG_CHECK CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK +#else +#define MYNEWT_VAL_BLE_QUEUE_CONG_CHECK FALSE +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_ENABLE_CONN_REATTEMPT +#ifdef CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT +#define MYNEWT_VAL_BLE_ENABLE_CONN_REATTEMPT CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT +#else +#define MYNEWT_VAL_BLE_ENABLE_CONN_REATTEMPT (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN +#ifdef CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN +#define MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN +#else +#define MYNEWT_VAL_BLE_HOST_ALLOW_CONNECT_WITH_SCAN (0) +#endif +#endif + +#if CONFIG_BT_CONTROLLER_DISABLED && CONFIG_BT_NIMBLE_TRANSPORT_UART +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_PORT +#define MYNEWT_VAL_BLE_TRANSPORT_UART_PORT CONFIG_BT_NIMBLE_TRANSPORT_UART_PORT +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_PARITY__none +#define MYNEWT_VAL_BLE_TRANSPORT_UART_PARITY__none CONFIG_BT_NIMBLE_TRANSPORT_UART_PARITY_NONE +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_PARITY__odd +#define MYNEWT_VAL_BLE_TRANSPORT_UART_PARITY__odd CONFIG_BT_NIMBLE_TRANSPORT_UART_PARITY_ODD +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_PARITY__even +#define MYNEWT_VAL_BLE_TRANSPORT_UART_PARITY__even CONFIG_BT_NIMBLE_TRANSPORT_UART_PARITY_EVEN +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_FLOW_CONTROL__rtscts +#define MYNEWT_VAL_BLE_TRANSPORT_UART_FLOW_CONTROL__rtscts CONFIG_BT_NIMBLE_HCI_UART_FLOW_CTRL +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_BAUDRATE +#define MYNEWT_VAL_BLE_TRANSPORT_UART_BAUDRATE CONFIG_BT_NIMBLE_HCI_UART_BAUDRATE +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_DATA_BITS +#define MYNEWT_VAL_BLE_TRANSPORT_UART_DATA_BITS (3) +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_STOP_BITS +#define MYNEWT_VAL_BLE_TRANSPORT_UART_STOP_BITS (1) +#endif +#endif + #endif diff --git a/components/bt/host/nimble/port/src/nvs_port.c b/components/bt/host/nimble/port/src/nvs_port.c new file mode 100644 index 0000000000..19d89a063c --- /dev/null +++ b/components/bt/host/nimble/port/src/nvs_port.c @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _NVS_H +#define _NVS_H + +#include +#include "nvs.h" +#include "nimble/storage_port.h" + +static int +nvs_open_custom(const char* namespace_name, open_mode_t open_mode, cache_handle_t *out_handle) +{ + switch (open_mode) { + case READONLY: + return nvs_open(namespace_name, NVS_READONLY, out_handle); + + case READWRITE: + return nvs_open(namespace_name, NVS_READWRITE, out_handle); + + default: + return -1; + } +} + +struct cache_fn_mapping +link_storage_fn(void *storage_cb) +{ + struct cache_fn_mapping cache_fn; + cache_fn.open = nvs_open_custom; + cache_fn.close = nvs_close; + cache_fn.erase_all = nvs_erase_all; + cache_fn.write = nvs_set_blob; + cache_fn.read = nvs_get_blob; + return cache_fn; +} +#endif diff --git a/components/bt/include/esp32/include/esp_bt.h b/components/bt/include/esp32/include/esp_bt.h index f048ff37e6..cf442169a8 100644 --- a/components/bt/include/esp32/include/esp_bt.h +++ b/components/bt/include/esp32/include/esp_bt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -50,32 +50,38 @@ extern "C" { #endif //CONFIG_BT_ENABLED -#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x20221207 +/** +* @brief Internal use only +* +* @note Please do not modify this value. +*/ +#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x20240722 /** - * @brief Bluetooth mode for controller enable/disable + * @brief Bluetooth Controller mode */ typedef enum { - ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not running */ - ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */ - ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Run Classic BT mode */ - ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */ + ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not operating. */ + ESP_BT_MODE_BLE = 0x01, /*!< Bluetooth is operating in BLE mode. */ + ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Bluetooth is operating in Classic Bluetooth mode. */ + ESP_BT_MODE_BTDM = 0x03, /*!< Bluetooth is operating in Dual mode. */ } esp_bt_mode_t; /** - * @brief BLE sleep clock accuracy(SCA), values for ble_sca field in esp_bt_controller_config_t, - * currently only ESP_BLE_SCA_500PPM and ESP_BLE_SCA_250PPM are supported + * @brief BLE sleep clock accuracy (SCA) + * + * @note Currently only ESP_BLE_SCA_500PPM and ESP_BLE_SCA_250PPM are supported. */ -enum { - ESP_BLE_SCA_500PPM = 0, /*!< BLE SCA at 500ppm */ - ESP_BLE_SCA_250PPM, /*!< BLE SCA at 250ppm */ - ESP_BLE_SCA_150PPM, /*!< BLE SCA at 150ppm */ - ESP_BLE_SCA_100PPM, /*!< BLE SCA at 100ppm */ - ESP_BLE_SCA_75PPM, /*!< BLE SCA at 75ppm */ - ESP_BLE_SCA_50PPM, /*!< BLE SCA at 50ppm */ - ESP_BLE_SCA_30PPM, /*!< BLE SCA at 30ppm */ - ESP_BLE_SCA_20PPM, /*!< BLE SCA at 20ppm */ -}; +typedef enum { + ESP_BLE_SCA_500PPM = 0, /*!< BLE SCA at 500 ppm */ + ESP_BLE_SCA_250PPM, /*!< BLE SCA at 250 ppm */ + ESP_BLE_SCA_150PPM, /*!< BLE SCA at 150 ppm */ + ESP_BLE_SCA_100PPM, /*!< BLE SCA at 100 ppm */ + ESP_BLE_SCA_75PPM, /*!< BLE SCA at 75 ppm */ + ESP_BLE_SCA_50PPM, /*!< BLE SCA at 50 ppm */ + ESP_BLE_SCA_30PPM, /*!< BLE SCA at 30 ppm */ + ESP_BLE_SCA_20PPM, /*!< BLE SCA at 20 ppm */ +} esp_ble_sca_t; #ifdef CONFIG_BT_ENABLED /* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE, @@ -167,6 +173,14 @@ the adv packet will be discarded until the memory is restored. */ #define BTDM_CONTROLLER_SCO_DATA_PATH_HCI 0 // SCO data is routed to HCI #define BTDM_CONTROLLER_SCO_DATA_PATH_PCM 1 // SCO data path is PCM +#ifdef CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX +#define BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX +#else +#define BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX 0 +#endif +/** +* @brief Default Bluetooth Controller configuration +*/ #define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \ .controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \ .controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \ @@ -188,110 +202,120 @@ the adv packet will be discarded until the memory is restored. */ .ble_sca = CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF, \ .pcm_role = CONFIG_BTDM_CTRL_PCM_ROLE_EFF, \ .pcm_polar = CONFIG_BTDM_CTRL_PCM_POLAR_EFF, \ + .pcm_fsyncshp = 0, \ .hli = BTDM_CTRL_HLI, \ .dup_list_refresh_period = SCAN_DUPL_CACHE_REFRESH_PERIOD, \ + .ble_scan_backoff = BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX, \ .magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL, \ } #else +/** +* @brief Default Bluetooth Controller configuration +*/ #define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; ESP_STATIC_ASSERT(0, "please enable bluetooth in menuconfig to use esp_bt.h"); #endif /** - * @brief Controller config options, depend on config mask. - * Config mask indicate which functions enabled, this means - * some options or parameters of some functions enabled by config mask. + * @brief Bluetooth Controller config options + * @note + * 1. For parameters configurable in menuconfig, please refer to menuconfig for details on range and default values. + * 2. It is not recommended to modify the default values of `controller_task_stack_size`, `controller_task_prio`. */ typedef struct { - /* - * Following parameters can be configured runtime, when call esp_bt_controller_init() - */ - uint16_t controller_task_stack_size; /*!< Bluetooth controller task stack size */ - uint8_t controller_task_prio; /*!< Bluetooth controller task priority */ - uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */ - uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */ - uint8_t scan_duplicate_mode; /*!< scan duplicate mode */ - uint8_t scan_duplicate_type; /*!< scan duplicate type */ - uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */ - uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */ - uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */ - uint32_t controller_debug_flag; /*!< Controller debug log flag */ - uint8_t mode; /*!< Controller mode: BR/EDR, BLE or Dual Mode */ - uint8_t ble_max_conn; /*!< BLE maximum connection numbers */ - uint8_t bt_max_acl_conn; /*!< BR/EDR maximum ACL connection numbers */ - uint8_t bt_sco_datapath; /*!< SCO data path, i.e. HCI or PCM module */ - bool auto_latency; /*!< BLE auto latency, used to enhance classic BT performance */ - bool bt_legacy_auth_vs_evt; /*!< BR/EDR Legacy auth complete event required to protect from BIAS attack */ - /* - * Following parameters can not be configured runtime when call esp_bt_controller_init() - * It will be overwrite with a constant value which in menuconfig or from a macro. - * So, do not modify the value when esp_bt_controller_init() - */ - uint8_t bt_max_sync_conn; /*!< BR/EDR maximum ACL connection numbers. Effective in menuconfig */ - uint8_t ble_sca; /*!< BLE low power crystal accuracy index */ - uint8_t pcm_role; /*!< PCM role (master & slave)*/ - uint8_t pcm_polar; /*!< PCM polar trig (falling clk edge & rising clk edge) */ - bool hli; /*!< Using high level interrupt or not */ - uint16_t dup_list_refresh_period; /*!< Duplicate scan list refresh period */ + uint16_t controller_task_stack_size; /*!< Bluetooth Controller task stack size in bytes */ + uint8_t controller_task_prio; /*!< Bluetooth Controller task priority */ + uint8_t hci_uart_no; /*!< Indicates UART number if using UART1/2 as HCI I/O interface. Configurable in menuconfig. */ + uint32_t hci_uart_baudrate; /*!< Indicates UART baudrate if using UART1/2 as HCI I/O interface. Configurable in menuconfig. */ + uint8_t scan_duplicate_mode; /*!< Scan duplicate filtering mode. Configurable in menuconfig. */ + uint8_t scan_duplicate_type; /*!< Scan duplicate filtering type. Configurable in menuconfig. */ + uint16_t normal_adv_size; /*!< Maximum number of devices in scan duplicate filtering list. Configurable in menuconfig. */ + uint16_t mesh_adv_size; /*!< Maximum number of Mesh ADV packets in scan duplicate filtering list. Configurable in menuconfig. */ + uint16_t send_adv_reserved_size; /*!< Controller minimum memory value in bytes. Internal use only */ + uint32_t controller_debug_flag; /*!< Controller debug log flag. Internal use only */ + uint8_t mode; /*!< Controller mode: + + 1: BLE mode + + 2: Classic Bluetooth mode + + 3: Dual mode + + Others: Invalid + C + onfigurable in menuconfig + */ + uint8_t ble_max_conn; /*!< Maximum number of BLE connections. Configurable in menuconfig. */ + uint8_t bt_max_acl_conn; /*!< Maximum number of BR/EDR ACL connections. Configurable in menuconfig. */ + uint8_t bt_sco_datapath; /*!< SCO data path, i.e. HCI or PCM module. Configurable in menuconfig. */ + bool auto_latency; /*!< True if BLE auto latency is enabled, used to enhance Classic Bluetooth performance; false otherwise. Configurable in menuconfig.*/ + bool bt_legacy_auth_vs_evt; /*!< True if BR/EDR Legacy Authentication Vendor Specific Event is enabled, which is required to protect from BIAS attack; false otherwise. Configurable in menuconfig. */ + uint8_t bt_max_sync_conn; /*!< Maximum number of BR/EDR synchronous connections. Configurable in menuconfig. */ + uint8_t ble_sca; /*!< BLE low power crystal accuracy index. Configurable in menuconfig. */ + uint8_t pcm_role; /*!< PCM role (master & slave). Configurable in menuconfig.*/ + uint8_t pcm_polar; /*!< PCM polar trig (falling clk edge & rising clk edge). Configurable in menuconfig. */ + uint8_t pcm_fsyncshp; /*!< Physical shape of the PCM Frame Synchronization signal (stereo mode & mono mode). Configurable in menuconfig */ + bool hli; /*!< True if using high level interrupt; false otherwise. Configurable in menuconfig. */ + uint16_t dup_list_refresh_period; /*!< Scan duplicate filtering list refresh period in seconds. Configurable in menuconfig.*/ + bool ble_scan_backoff; /*!< True if BLE scan backoff is enabled; false otherwise. Configurable in menuconfig.*/ uint32_t magic; /*!< Magic number */ } esp_bt_controller_config_t; /** - * @brief Bluetooth controller enable/disable/initialised/de-initialised status + * @brief Bluetooth Controller status */ typedef enum { - ESP_BT_CONTROLLER_STATUS_IDLE = 0, - ESP_BT_CONTROLLER_STATUS_INITED, - ESP_BT_CONTROLLER_STATUS_ENABLED, - ESP_BT_CONTROLLER_STATUS_NUM, + ESP_BT_CONTROLLER_STATUS_IDLE = 0, /*!< The Controller is not initialized or has been de-initialized.*/ + ESP_BT_CONTROLLER_STATUS_INITED, /*!< The Controller has been initialized, but not enabled or has been disabled. */ + ESP_BT_CONTROLLER_STATUS_ENABLED, /*!< The Controller has been initialized and enabled. */ + ESP_BT_CONTROLLER_STATUS_NUM, /*!< Number of Controller statuses */ } esp_bt_controller_status_t; /** - * @brief BLE tx power type - * ESP_BLE_PWR_TYPE_CONN_HDL0-8: for each connection, and only be set after connection completed. - * when disconnect, the correspond TX power is not effected. - * ESP_BLE_PWR_TYPE_ADV : for advertising/scan response. - * ESP_BLE_PWR_TYPE_SCAN : for scan. - * ESP_BLE_PWR_TYPE_DEFAULT : if each connection's TX power is not set, it will use this default value. - * if neither in scan mode nor in adv mode, it will use this default value. - * If none of power type is set, system will use ESP_PWR_LVL_P3 as default for ADV/SCAN/CONN0-9. + * @brief BLE TX power type + * @note + * 1. The connection TX power can only be set after the connection is established. + * After disconnecting, the corresponding TX power will not be affected. + * 2. `ESP_BLE_PWR_TYPE_DEFAULT` can be used to set the TX power for power types that have not been set before. + * It will not affect the TX power values which have been set for the following CONN0-8/ADV/SCAN power types. + * 3. If none of power type is set, the system will use `ESP_PWR_LVL_P3` as default for all power types. */ typedef enum { - ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, /*!< For connection handle 0 */ - ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, /*!< For connection handle 1 */ - ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, /*!< For connection handle 2 */ - ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, /*!< For connection handle 3 */ - ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, /*!< For connection handle 4 */ - ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, /*!< For connection handle 5 */ - ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, /*!< For connection handle 6 */ - ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, /*!< For connection handle 7 */ - ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, /*!< For connection handle 8 */ - ESP_BLE_PWR_TYPE_ADV = 9, /*!< For advertising */ - ESP_BLE_PWR_TYPE_SCAN = 10, /*!< For scan */ - ESP_BLE_PWR_TYPE_DEFAULT = 11, /*!< For default, if not set other, it will use default value */ - ESP_BLE_PWR_TYPE_NUM = 12, /*!< TYPE numbers */ + ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, /*!< TX power for connection handle 0 */ + ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, /*!< TX power for connection handle 1 */ + ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, /*!< TX power for connection handle 2 */ + ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, /*!< TX power for connection handle 3 */ + ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, /*!< TX power for connection handle 4 */ + ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, /*!< TX power for connection handle 5 */ + ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, /*!< TX power for connection handle 6 */ + ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, /*!< TX power for connection handle 7 */ + ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, /*!< TX power for connection handle 8 */ + ESP_BLE_PWR_TYPE_ADV = 9, /*!< TX power for advertising */ + ESP_BLE_PWR_TYPE_SCAN = 10, /*!< TX power for scan */ + ESP_BLE_PWR_TYPE_DEFAULT = 11, /*!< Default TX power type, which can be used to set the TX power for power types that have not been set before.*/ + ESP_BLE_PWR_TYPE_NUM = 12, /*!< Number of types */ } esp_ble_power_type_t; /** - * @brief Bluetooth TX power level(index), it's just a index corresponding to power(dbm). + * @brief Bluetooth TX power level (index). Each index corresponds to a specific power value in dBm. */ typedef enum { - ESP_PWR_LVL_N12 = 0, /*!< Corresponding to -12dbm */ - ESP_PWR_LVL_N9 = 1, /*!< Corresponding to -9dbm */ - ESP_PWR_LVL_N6 = 2, /*!< Corresponding to -6dbm */ - ESP_PWR_LVL_N3 = 3, /*!< Corresponding to -3dbm */ - ESP_PWR_LVL_N0 = 4, /*!< Corresponding to 0dbm */ - ESP_PWR_LVL_P3 = 5, /*!< Corresponding to +3dbm */ - ESP_PWR_LVL_P6 = 6, /*!< Corresponding to +6dbm */ - ESP_PWR_LVL_P9 = 7, /*!< Corresponding to +9dbm */ - ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12, /*!< Backward compatibility! Setting to -14dbm will actually result to -12dbm */ - ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9, /*!< Backward compatibility! Setting to -11dbm will actually result to -9dbm */ - ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6, /*!< Backward compatibility! Setting to -8dbm will actually result to -6dbm */ - ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3, /*!< Backward compatibility! Setting to -5dbm will actually result to -3dbm */ - ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0, /*!< Backward compatibility! Setting to -2dbm will actually result to 0dbm */ - ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3, /*!< Backward compatibility! Setting to +1dbm will actually result to +3dbm */ - ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6, /*!< Backward compatibility! Setting to +4dbm will actually result to +6dbm */ - ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9, /*!< Backward compatibility! Setting to +7dbm will actually result to +9dbm */ + ESP_PWR_LVL_N12 = 0, /*!< Corresponding to -12 dBm */ + ESP_PWR_LVL_N9 = 1, /*!< Corresponding to -9 dBm */ + ESP_PWR_LVL_N6 = 2, /*!< Corresponding to -6 dBm */ + ESP_PWR_LVL_N3 = 3, /*!< Corresponding to -3 dBm */ + ESP_PWR_LVL_N0 = 4, /*!< Corresponding to 0 dBm */ + ESP_PWR_LVL_P3 = 5, /*!< Corresponding to +3 dBm */ + ESP_PWR_LVL_P6 = 6, /*!< Corresponding to +6 dBm */ + ESP_PWR_LVL_P9 = 7, /*!< Corresponding to +9 dBm */ + ESP_PWR_LVL_N14 = ESP_PWR_LVL_N12, /*!< Backward compatibility! Setting to -14 dBm will actually result in -12 dBm */ + ESP_PWR_LVL_N11 = ESP_PWR_LVL_N9, /*!< Backward compatibility! Setting to -11 dBm will actually result in -9 dBm */ + ESP_PWR_LVL_N8 = ESP_PWR_LVL_N6, /*!< Backward compatibility! Setting to -8 dBm will actually result in -6 dBm */ + ESP_PWR_LVL_N5 = ESP_PWR_LVL_N3, /*!< Backward compatibility! Setting to -5 dBm will actually result in -3 dBm */ + ESP_PWR_LVL_N2 = ESP_PWR_LVL_N0, /*!< Backward compatibility! Setting to -2 dBm will actually result in 0 dBm */ + ESP_PWR_LVL_P1 = ESP_PWR_LVL_P3, /*!< Backward compatibility! Setting to +1 dBm will actually result in +3 dBm */ + ESP_PWR_LVL_P4 = ESP_PWR_LVL_P6, /*!< Backward compatibility! Setting to +4 dBm will actually result in +6 dBm */ + ESP_PWR_LVL_P7 = ESP_PWR_LVL_P9, /*!< Backward compatibility! Setting to +7 dBm will actually result in +9 dBm */ } esp_power_level_t; /** @@ -304,243 +328,312 @@ typedef enum { /** * @brief Set BLE TX power - * Connection Tx power should only be set after connection created. - * @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc - * @param power_level: Power level(index) corresponding to absolute value(dbm) - * @return ESP_OK - success, other - failed + * + * @note Connection TX power should only be set after the connection is established. + * + * @param[in] power_type The type of TX power. It could be Advertising, Connection, Default, etc. + * @param[in] power_level Power level (index) corresponding to the absolute value (dBm) + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_ARG: Invalid argument */ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level); /** * @brief Get BLE TX power - * Connection Tx power should only be get after connection created. - * @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc - * @return >= 0 - Power level, < 0 - Invalid + * + * @note Connection TX power should only be retrieved after the connection is established. + * + * @param[in] power_type The type of TX power. It could be Advertising/Connection/Default and etc. + * + * @return + * - Power level + * */ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type); /** * @brief Set BR/EDR TX power - * BR/EDR power control will use the power in range of minimum value and maximum value. - * The power level will effect the global BR/EDR TX power, such inquire, page, connection and so on. - * Please call the function after esp_bt_controller_enable and before any function which cause RF do TX. - * So you can call the function before doing discovery, profile init and so on. - * For example, if you want BR/EDR use the new TX power to do inquire, you should call - * this function before inquire. Another word, If call this function when BR/EDR is in inquire(ING), - * please do inquire again after call this function. - * Default minimum power level is ESP_PWR_LVL_N0, and maximum power level is ESP_PWR_LVL_P3. - * @param min_power_level: The minimum power level - * @param max_power_level: The maximum power level - * @return ESP_OK - success, other - failed + * + * BR/EDR power control will use the power within the range of minimum value and maximum value. + * The power level will affect the global BR/EDR TX power for operations such as inquiry, page, and connection. + * + * @note + * 1. Please call this function after `esp_bt_controller_enable()` and before any functions that cause RF transmission, + * such as performing discovery, profile initialization, and so on. + * 2. For BR/EDR to use the new TX power for inquiry, call this function before starting an inquiry. + * If BR/EDR is already inquiring, restart the inquiry after calling this function. + * + * @param[in] min_power_level The minimum power level. The default value is `ESP_PWR_LVL_N0`. + * @param[in] max_power_level The maximum power level. The default value is `ESP_PWR_LVL_P3`. + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_ARG: Invalid argument + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_bredr_tx_power_set(esp_power_level_t min_power_level, esp_power_level_t max_power_level); /** * @brief Get BR/EDR TX power - * If the argument is not NULL, then store the corresponding value. - * @param min_power_level: The minimum power level - * @param max_power_level: The maximum power level - * @return ESP_OK - success, other - failed + * + * The corresponding power levels will be stored into the arguments. + * + * @param[out] min_power_level Pointer to store the minimum power level + * @param[out] max_power_level The maximum power level + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_ARG: Invalid argument */ esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_level_t *max_power_level); /** * @brief Set default SCO data path - * Should be called after controller is enabled, and before (e)SCO link is established - * @param data_path: SCO data path - * @return ESP_OK - success, other - failed + * + * @note This function should be called after the Controller is enabled, and before (e)SCO link is established. + * + * @param[in] data_path SCO data path + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path); /** - * @brief Initialize BT controller to allocate task and other resource. - * This function should be called only once, before any other BT functions are called. - * @param cfg: Initial configuration of BT controller. Different from previous version, there's a mode and some - * connection configuration in "cfg" to configure controller work mode and allocate the resource which is needed. - * @return ESP_OK - success, other - failed + * @brief Initialize the Bluetooth Controller to allocate tasks and other resources + * + * @note This function should be called only once, before any other Bluetooth functions. + * + * @param[in] cfg Initial Bluetooth Controller configuration + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); /** - * @brief De-initialize BT controller to free resource and delete task. - * You should stop advertising and scanning, as well as - * disconnect all existing connections before de-initializing BT controller. + * @brief De-initialize Bluetooth Controller to free resources and delete tasks + * + * @note + * 1. You should stop advertising and scanning, and disconnect all existing connections before de-initializing Bluetooth Controller. + * 2. This function should be called only once, after any other Bluetooth functions. * - * This function should be called only once, after any other BT functions are called. - * @return ESP_OK - success, other - failed + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_ARG: Invalid argument + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state + * - ESP_ERR_NO_MEM: Out of memory */ esp_err_t esp_bt_controller_deinit(void); /** - * @brief Enable BT controller. - * Due to a known issue, you cannot call esp_bt_controller_enable() a second time - * to change the controller mode dynamically. To change controller mode, call - * esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode. - * @param mode : the mode(BLE/BT/BTDM) to enable. For compatible of API, retain this argument. This mode must be - * equal as the mode in "cfg" of esp_bt_controller_init(). - * @return ESP_OK - success, other - failed + * @brief Enable Bluetooth Controller + * + * @note + * 1. Bluetooth Controller cannot be enabled in `ESP_BT_CONTROLLER_STATUS_IDLE` status. It has to be initialized first. + * 2. Due to a known issue, you cannot call `esp_bt_controller_enable()` for the second time + * to change the Controller mode dynamically. To change the Controller mode, call + * `esp_bt_controller_disable()` and then call `esp_bt_controller_enable()` with the new mode. + * + * @param[in] mode The Bluetooth Controller mode (BLE/Classic Bluetooth/BTDM) to enable + * + * For API compatibility, retain this argument. This mode must match the mode specified in the `cfg` of `esp_bt_controller_init()`. + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); /** - * @brief Disable BT controller - * @return ESP_OK - success, other - failed + * @brief Disable Bluetooth Controller + * + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_bt_controller_disable(void); /** - * @brief Get BT controller is initialised/de-initialised/enabled/disabled - * @return status value + * @brief Get Bluetooth Controller status + * + * @return + * - ESP_BT_CONTROLLER_STATUS_IDLE: The Controller is not initialized or has been de-initialized. + * - ESP_BT_CONTROLLER_STATUS_INITED: The Controller has been initialized, but not enabled or has been disabled. + * - ESP_BT_CONTROLLER_STATUS_ENABLED: The Controller has been initialized and enabled. */ esp_bt_controller_status_t esp_bt_controller_get_status(void); -/** @brief esp_vhci_host_callback - * used for vhci call host function to notify what host need to do +/** + * @brief Vendor HCI (VHCI) callback functions to notify the Host on the next operation */ typedef struct esp_vhci_host_callback { - void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */ - int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/ + void (*notify_host_send_available)(void); /*!< Callback to notify the Host that the Controller is ready to receive the packet */ + int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< Callback to notify the Host that the Controller has a packet to send */ } esp_vhci_host_callback_t; -/** @brief esp_vhci_host_check_send_available - * used for check actively if the host can send packet to controller or not. - * @return true for ready to send, false means cannot send packet +/** + * @brief Check whether the Controller is ready to receive the packet + * + * If the return value is True, the Host can send the packet to the Controller. + * + * @note This function should be called before each `esp_vhci_host_send_packet()`. + * + * @return + * True if the Controller is ready to receive packets; false otherwise */ bool esp_vhci_host_check_send_available(void); -/** @brief esp_vhci_host_send_packet - * host send packet to controller +/** + * @brief Send the packet to the Controller * - * Should not call this function from within a critical section - * or when the scheduler is suspended. + * @note + * 1. This function shall not be called within a critical section or when the scheduler is suspended. + * 2. This function should be called only if `esp_vhci_host_check_send_available()` returns True. * - * @param data the packet point - * @param len the packet length + * @param[in] data Pointer to the packet data + * @param[in] len The packet length */ void esp_vhci_host_send_packet(uint8_t *data, uint16_t len); -/** @brief esp_vhci_host_register_callback - * register the vhci reference callback - * struct defined by vhci_host_callback structure. - * @param callback esp_vhci_host_callback type variable - * @return ESP_OK - success, ESP_FAIL - failed +/** + * @brief Register the VHCI callback funations defined in `esp_vhci_host_callback` structure. + * + * @param[in] callback `esp_vhci_host_callback` type variable + * + * @return + * - ESP_OK: Success + * - ESP_FAIL: Failure */ esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback); -/** @brief esp_bt_controller_mem_release - * release the controller memory as per the mode +/** + * @brief Release the Controller memory as per the mode * - * This function releases the BSS, data and other sections of the controller to heap. The total size is about 70k bytes. + * This function releases the BSS, data and other sections of the Controller to heap. The total size is about 70 KB. * - * esp_bt_controller_mem_release(mode) should be called only before esp_bt_controller_init() - * or after esp_bt_controller_deinit(). + * @note + * 1. This function is optional and should be called only if you want to free up memory for other components. + * 2. This function should only be called when the controller is in `ESP_BT_CONTROLLER_STATUS_IDLE` status. + * 3. Once Bluetooth Controller memory is released, the process cannot be reversed. This means you cannot use the Bluetooth Controller mode that you have released using this function. + * 4. If your firmware will upgrade the Bluetooth Controller mode later (such as switching from BLE to Classic Bluetooth or from disabled to enabled), then do not call this function. * - * Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth - * mode which you have released by this function. + * If you never intend to use Bluetooth in a current boot-up cycle, calling `esp_bt_controller_mem_release(ESP_BT_MODE_BTDM)` could release the BSS and data consumed by both Classic Bluetooth and BLE Controller to heap. * - * If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled) - * then do not call this function. + * If you intend to use BLE only, calling `esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT)` could release the BSS and data consumed by Classic Bluetooth Controller. You can then continue using BLE. * - * If the app calls esp_bt_controller_enable(ESP_BT_MODE_BLE) to use BLE only then it is safe to call - * esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialization time to free unused BT Classic memory. + * If you intend to use Classic Bluetooth only, calling `esp_bt_controller_mem_release(ESP_BT_MODE_BLE)` could release the BSS and data consumed by BLE Controller. You can then continue using Classic Bluetooth. * - * If the mode is ESP_BT_MODE_BTDM, then it may be useful to call API esp_bt_mem_release(ESP_BT_MODE_BTDM) instead, - * which internally calls esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) and additionally releases the BSS and data - * consumed by the BT/BLE host stack to heap. For more details about usage please refer to the documentation of - * esp_bt_mem_release() function + * @param[in] mode The Bluetooth Controller mode * - * @param mode : the mode want to release memory - * @return ESP_OK - success, other - failed + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state + * - ESP_ERR_NOT_FOUND: Requested resource not found */ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode); -/** @brief esp_bt_mem_release - * release controller memory and BSS and data section of the BT/BLE host stack as per the mode +/** + * @brief Release the Controller memory, BSS and data section of the Classic Bluetooth/BLE Host stack as per the mode * - * This function first releases controller memory by internally calling esp_bt_controller_mem_release(). - * Additionally, if the mode is set to ESP_BT_MODE_BTDM, it also releases the BSS and data consumed by the BT/BLE host stack to heap + * @note + * 1. This function is optional and should be called only if you want to free up memory for other components. + * 2. This function should only be called when the controller is in `ESP_BT_CONTROLLER_STATUS_IDLE` status. + * 3. Once Bluetooth Controller memory is released, the process cannot be reversed. This means you cannot use the Bluetooth Controller mode that you have released using this function. + * 4. If your firmware will upgrade the Bluetooth Controller mode later (such as switching from BLE to Classic Bluetooth or from disabled to enabled), then do not call this function. * - * Note that once BT memory is released, the process cannot be reversed. It means you cannot use the bluetooth - * mode which you have released by this function. + * This function first releases Controller memory by internally calling `esp_bt_controller_mem_release()`, then releases Host memory. * - * If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled) - * then do not call this function. + * If you never intend to use Bluetooth in a current boot-up cycle, calling `esp_bt_mem_release(ESP_BT_MODE_BTDM)` could release the BSS and data consumed by both Classic Bluetooth and BLE stack to heap. * - * If you never intend to use bluetooth in a current boot-up cycle, you can call esp_bt_mem_release(ESP_BT_MODE_BTDM) - * before esp_bt_controller_init or after esp_bt_controller_deinit. + * If you intend to use BLE only, calling `esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT)` could release the BSS and data consumed by Classic Bluetooth. You can then continue using BLE. * - * For example, if a user only uses bluetooth for setting the WiFi configuration, and does not use bluetooth in the rest of the product operation". - * In such cases, after receiving the WiFi configuration, you can disable/deinit bluetooth and release its memory. + * If you intend to use Classic Bluetooth only, calling `esp_bt_mem_release(ESP_BT_MODE_BLE)` could release the BSS and data consumed by BLE. You can then continue using Classic Bluetooth. + * + * For example, if you only use Bluetooth for setting the Wi-Fi configuration, and do not use Bluetooth in the rest of the product operation, + * after receiving the Wi-Fi configuration, you can disable/de-init Bluetooth and release its memory. * Below is the sequence of APIs to be called for such scenarios: * - * esp_bluedroid_disable(); - * esp_bluedroid_deinit(); - * esp_bt_controller_disable(); - * esp_bt_controller_deinit(); - * esp_bt_mem_release(ESP_BT_MODE_BTDM); + * esp_bluedroid_disable(); + * esp_bluedroid_deinit(); + * esp_bt_controller_disable(); + * esp_bt_controller_deinit(); + * esp_bt_mem_release(ESP_BT_MODE_BTDM); + * + * @param[in] mode The Bluetooth Controller mode * - * @note In case of NimBLE host, to release BSS and data memory to heap, the mode needs to be - * set to ESP_BT_MODE_BTDM as controller is dual mode. - * @param mode : the mode whose memory is to be released - * @return ESP_OK - success, other - failed + * @return + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state + * - ESP_ERR_NOT_FOUND: Requested resource not found */ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode); /** - * @brief enable bluetooth to enter modem sleep + * @brief Enable Bluetooth modem sleep * - * Note that this function shall not be invoked before esp_bt_controller_enable() + * There are currently two options for Bluetooth modem sleep: ORIG mode and EVED mode. The latter is intended for BLE only. + * The modem sleep mode could be configured in menuconfig. * - * There are currently two options for bluetooth modem sleep, one is ORIG mode, and another is EVED Mode. EVED Mode is intended for BLE only. + * In ORIG mode, if there is no event to process, the Bluetooth Controller will periodically switch off some components and pause operation, then wake up according to the scheduled interval and resume work. + * It can also wakeup earlier upon external request using function `esp_bt_controller_wakeup_request()`. * - * For ORIG mode: - * Bluetooth modem sleep is enabled in controller start up by default if CONFIG_CTRL_BTDM_MODEM_SLEEP is set and "ORIG mode" is selected. In ORIG modem sleep mode, bluetooth controller will switch off some components and pause to work every now and then, if there is no event to process; and wakeup according to the scheduled interval and resume the work. It can also wakeup earlier upon external request using function "esp_bt_controller_wakeup_request". + * @note This function shall not be invoked before `esp_bt_controller_enable()`. * * @return - * - ESP_OK : success - * - other : failed + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state + * - ESP_ERR_NOT_SUPPORTED: Operation or feature not supported */ esp_err_t esp_bt_sleep_enable(void); /** - * @brief disable bluetooth modem sleep - * - * Note that this function shall not be invoked before esp_bt_controller_enable() + * @brief Disable Bluetooth modem sleep * - * If esp_bt_sleep_disable() is called, bluetooth controller will not be allowed to enter modem sleep; - * - * If ORIG modem sleep mode is in use, if this function is called, bluetooth controller may not immediately wake up if it is dormant then. - * In this case, esp_bt_controller_wakeup_request() can be used to shorten the time for wakeup. + * @note + * 1. Bluetooth Controller will not be allowed to enter modem sleep after calling this function. + * 2. In ORIG modem sleep mode, calling this function may not immediately wake up the Controller if it is currently dormant. + * In this case, `esp_bt_controller_wakeup_request()` can be used to shorten the wake-up time. + * 3. This function shall not be invoked before `esp_bt_controller_enable()`. * * @return - * - ESP_OK : success - * - other : failed + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state + * - ESP_ERR_NOT_SUPPORTED: Operation or feature not supported */ esp_err_t esp_bt_sleep_disable(void); /** - * @brief Manually clear scan duplicate list - * - * Note that scan duplicate list will be automatically cleared when the maximum amount of device in the filter is reached - * the amount of device in the filter can be configured in menuconfig. + * @brief Manually clear the scan duplicate list * - * @note This function name is incorrectly spelled, it will be fixed in release 5.x version. + * @note + * 1. This function name is incorrectly spelled, it will be fixed in release 5.x version. + * 2. The scan duplicate list will be automatically cleared when the maximum amount of devices in the filter is reached. + * The amount of devices in the filter can be configured in menuconfig. * * @return - * - ESP_OK : success - * - other : failed + * - ESP_OK: Success + * - ESP_ERR_INVALID_STATE: Invalid Bluetooth Controller state */ esp_err_t esp_ble_scan_dupilcate_list_flush(void); /** - * @brief bt Wi-Fi power domain power on - */ + * @brief Power on Bluetooth Wi-Fi power domain + * + * @note This function is not recommended to use due to potential risk. +*/ void esp_wifi_bt_power_domain_on(void); /** - * @brief bt Wi-Fi power domain power off - */ + * @brief Power off Bluetooth Wi-Fi power domain + * + * @note This function is not recommended to use due to potential risk. +*/ void esp_wifi_bt_power_domain_off(void); #ifdef __cplusplus diff --git a/components/bt/include/esp32c2/include/esp_bt.h b/components/bt/include/esp32c2/include/esp_bt.h index 7f15dc1080..c73d4cb924 100644 --- a/components/bt/include/esp32c2/include/esp_bt.h +++ b/components/bt/include/esp32c2/include/esp_bt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,8 @@ #include "esp_task.h" #include "nimble/nimble_npl.h" -#include "esp_bt_cfg.h" +#include "../../../../controller/esp32c2/esp_bt_cfg.h" +#include "hal/efuse_hal.h" #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #include "driver/uart.h" @@ -25,9 +26,8 @@ extern "C" { #endif /** - * @brief Bluetooth mode for controller enable/disable + * @brief Bluetooth mode for controller enable/disable. */ - typedef enum { ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not running */ ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */ @@ -36,9 +36,8 @@ typedef enum { } esp_bt_mode_t; /** - * @brief Bluetooth controller enable/disable/initialised/de-initialised status + * @brief Bluetooth controller enable/disable/initialised/de-initialised status. */ - typedef enum { ESP_BT_CONTROLLER_STATUS_IDLE = 0, /*!< Controller is in idle state */ ESP_BT_CONTROLLER_STATUS_INITED, /*!< Controller is in initialising state */ @@ -91,10 +90,14 @@ typedef enum { ESP_PWR_LVL_P12 = 12, /*!< Corresponding to +12dbm */ ESP_PWR_LVL_P15 = 13, /*!< Corresponding to +15dbm */ ESP_PWR_LVL_P18 = 14, /*!< Corresponding to +18dbm */ - ESP_PWR_LVL_P21 = 15, /*!< Corresponding to +21dbm */ + ESP_PWR_LVL_P20 = 15, /*!< Corresponding to +20dbm */ + ESP_PWR_LVL_P21 = 15, /*!< Corresponding to +20dbm, this enum variable has been deprecated */ ESP_PWR_LVL_INVALID = 0xFF, /*!< Indicates an invalid value */ } esp_power_level_t; +/** + * @brief The enhanced type of which tx power, could set Advertising/Connection/Default and etc. + */ typedef enum { ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT = 0, ESP_BLE_ENHANCED_PWR_TYPE_ADV, @@ -104,9 +107,20 @@ typedef enum { ESP_BLE_ENHANCED_PWR_TYPE_MAX, } esp_ble_enhanced_power_type_t; +/** + * @brief Select buffers +*/ +typedef enum { + ESP_BLE_LOG_BUF_HCI = 0x02, + ESP_BLE_LOG_BUF_CONTROLLER = 0x05, +} esp_ble_log_buf_t; + +/** + * @brief Address type and address value. + */ typedef struct { - uint8_t type; - uint8_t val[6]; + uint8_t type; /*!< Type of the Bluetooth address (public, random, etc.) */ + uint8_t val[6]; /*!< Array containing the 6-byte Bluetooth address value */ } esp_ble_addr_t; /** @@ -152,7 +166,7 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po */ uint8_t esp_ble_get_chip_rev_version(void); -#define CONFIG_VERSION 0x20230629 +#define CONFIG_VERSION 0x20231124 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -160,59 +174,59 @@ uint8_t esp_ble_get_chip_rev_version(void); * Config mask indicate which functions enabled, this means * some options or parameters of some functions enabled by config mask. */ - typedef struct { - uint32_t config_version; - uint16_t ble_ll_resolv_list_size; - uint16_t ble_hci_evt_hi_buf_count; - uint16_t ble_hci_evt_lo_buf_count; - uint8_t ble_ll_sync_list_cnt; - uint8_t ble_ll_sync_cnt; - uint16_t ble_ll_rsp_dup_list_count; - uint16_t ble_ll_adv_dup_list_count; - uint8_t ble_ll_tx_pwr_dbm; - uint64_t rtc_freq; - uint16_t ble_ll_sca; - uint8_t ble_ll_scan_phy_number; - uint16_t ble_ll_conn_def_auth_pyld_tmo; - uint8_t ble_ll_jitter_usecs; - uint16_t ble_ll_sched_max_adv_pdu_usecs; - uint16_t ble_ll_sched_direct_adv_max_usecs; - uint16_t ble_ll_sched_adv_max_usecs; - uint16_t ble_scan_rsp_data_max_len; - uint8_t ble_ll_cfg_num_hci_cmd_pkts; - uint32_t ble_ll_ctrl_proc_timeout_ms; - uint16_t nimble_max_connections; - uint8_t ble_whitelist_size; - uint16_t ble_acl_buf_size; - uint16_t ble_acl_buf_count; - uint16_t ble_hci_evt_buf_size; - uint16_t ble_multi_adv_instances; - uint16_t ble_ext_adv_max_size; - uint16_t controller_task_stack_size; - uint8_t controller_task_prio; - uint8_t controller_run_cpu; - uint8_t enable_qa_test; - uint8_t enable_bqb_test; - uint8_t enable_uart_hci; - uint8_t ble_hci_uart_port; - uint32_t ble_hci_uart_baud; - uint8_t ble_hci_uart_data_bits; - uint8_t ble_hci_uart_stop_bits; - uint8_t ble_hci_uart_flow_ctrl; - uint8_t ble_hci_uart_uart_parity; - uint8_t enable_tx_cca; - uint8_t cca_rssi_thresh; - uint8_t sleep_en; - uint8_t coex_phy_coded_tx_rx_time_limit; - uint8_t dis_scan_backoff; - uint8_t ble_scan_classify_filter_enable; - uint8_t cca_drop_mode; - int8_t cca_low_tx_pwr; - uint8_t main_xtal_freq; - uint8_t version_num; - uint8_t ignore_wl_for_direct_adv; - uint32_t config_magic; + uint32_t config_version; /*!< Version number of the defined structure */ + uint16_t ble_ll_resolv_list_size; /*!< Size of the resolvable private address list */ + uint16_t ble_hci_evt_hi_buf_count; /*!< Count of high buffers for HCI events */ + uint16_t ble_hci_evt_lo_buf_count; /*!< Count of low buffers for HCI events */ + uint8_t ble_ll_sync_list_cnt; /*!< Number of synchronization lists */ + uint8_t ble_ll_sync_cnt; /*!< Number of synchronizations */ + uint16_t ble_ll_rsp_dup_list_count; /*!< Count of duplicated lists for scan response packets */ + uint16_t ble_ll_adv_dup_list_count; /*!< Count of duplicated lists for advertising packets */ + uint8_t ble_ll_tx_pwr_dbm; /*!< Tx power (transmit power) in dBm */ + uint64_t rtc_freq; /*!< Frequency of RTC (Real-Time Clock) */ + uint16_t ble_ll_sca; /*!< Sleep Clock Accuracy (SCA) parameter */ + uint8_t ble_ll_scan_phy_number; /*!< Number of PHYs supported for scanning */ + uint16_t ble_ll_conn_def_auth_pyld_tmo; /*!< Connection default authentication payload timeout */ + uint8_t ble_ll_jitter_usecs; /*!< Jitter time in microseconds */ + uint16_t ble_ll_sched_max_adv_pdu_usecs; /*!< Maximum time in microseconds for advertising PDU scheduling */ + uint16_t ble_ll_sched_direct_adv_max_usecs; /*!< Maximum time in microseconds for directed advertising scheduling */ + uint16_t ble_ll_sched_adv_max_usecs; /*!< Maximum time in microseconds for advertising scheduling */ + uint16_t ble_scan_rsp_data_max_len; /*!< Maximum length of scan response data */ + uint8_t ble_ll_cfg_num_hci_cmd_pkts; /*!< Number of HCI command packets that can be queued */ + uint32_t ble_ll_ctrl_proc_timeout_ms; /*!< Control processing timeout in milliseconds */ + uint16_t nimble_max_connections; /*!< Maximum number of connections supported */ + uint8_t ble_whitelist_size; /*!< Size of the white list */ + uint16_t ble_acl_buf_size; /*!< Buffer size of ACL (Asynchronous Connection-Less) data */ + uint16_t ble_acl_buf_count; /*!< Buffer count of ACL data */ + uint16_t ble_hci_evt_buf_size; /*!< Buffer size for HCI event data */ + uint16_t ble_multi_adv_instances; /*!< Number of advertising instances */ + uint16_t ble_ext_adv_max_size; /*!< Maximum size of extended advertising data */ + uint16_t controller_task_stack_size; /*!< Size of Bluetooth controller task stack */ + uint8_t controller_task_prio; /*!< Priority of the Bluetooth task */ + uint8_t controller_run_cpu; /*!< CPU number on which the Bluetooth controller task runs */ + uint8_t enable_qa_test; /*!< Enable for QA test */ + uint8_t enable_bqb_test; /*!< Enable for BQB test */ + uint8_t enable_uart_hci; /*!< Enable UART for HCI (Host Controller Interface) */ + uint8_t ble_hci_uart_port; /*!< Port of UART for HCI */ + uint32_t ble_hci_uart_baud; /*!< Baudrate of UART for HCI */ + uint8_t ble_hci_uart_data_bits; /*!< Data bits of UART for HCI */ + uint8_t ble_hci_uart_stop_bits; /*!< Stop bits of UART for HCI */ + uint8_t ble_hci_uart_flow_ctrl; /*!< Flow control of UART for HCI */ + uint8_t ble_hci_uart_uart_parity; /*!< UART parity */ + uint8_t enable_tx_cca; /*!< Enable Clear Channel Assessment (CCA) when transmitting */ + uint8_t cca_rssi_thresh; /*!< RSSI threshold for CCA */ + uint8_t sleep_en; /*!< Enable sleep functionality */ + uint8_t coex_phy_coded_tx_rx_time_limit; /*!< Coexistence PHY coded TX and RX time limit */ + uint8_t dis_scan_backoff; /*!< Disable scan backoff */ + uint8_t ble_scan_classify_filter_enable; /*!< Enable classification filter for BLE scan */ + uint8_t cca_drop_mode; /*!< CCA drop mode */ + int8_t cca_low_tx_pwr; /*!< Low TX power setting for CCA */ + uint8_t main_xtal_freq; /*!< Main crystal frequency */ + uint8_t version_num; /*!< Version number */ + uint8_t ignore_wl_for_direct_adv; /*!< Ignore the white list for directed advertising */ + uint8_t csa2_select; /*!< Select CSA#2 */ + uint32_t config_magic; /*!< Configuration magic value */ } esp_bt_controller_config_t; #define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \ @@ -248,13 +262,6 @@ typedef struct { .controller_run_cpu = 0, \ .enable_qa_test = RUN_QA_TEST, \ .enable_bqb_test = RUN_BQB_TEST, \ - .enable_uart_hci = HCI_UART_EN, \ - .ble_hci_uart_port = DEFAULT_BT_LE_HCI_UART_PORT, \ - .ble_hci_uart_baud = DEFAULT_BT_LE_HCI_UART_BAUD, \ - .ble_hci_uart_data_bits = DEFAULT_BT_LE_HCI_UART_DATA_BITS, \ - .ble_hci_uart_stop_bits = DEFAULT_BT_LE_HCI_UART_STOP_BITS, \ - .ble_hci_uart_flow_ctrl = DEFAULT_BT_LE_HCI_UART_FLOW_CTRL, \ - .ble_hci_uart_uart_parity = DEFAULT_BT_LE_HCI_UART_PARITY, \ .enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \ .cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \ .sleep_en = NIMBLE_SLEEP_ENABLE, \ @@ -264,9 +271,16 @@ typedef struct { .main_xtal_freq = CONFIG_XTAL_FREQ, \ .version_num = esp_ble_get_chip_rev_version(), \ .ignore_wl_for_direct_adv = 0, \ + .csa2_select = DEFAULT_BT_LE_50_FEATURE_SUPPORT, \ .config_magic = CONFIG_MAGIC, \ } +/** + * @brief Initialize BT controller to allocate task and other resource. + * This function should be called only once, before any other BT functions are called. + * @param cfg: Initial configuration of BT controller. + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); /** @@ -274,11 +288,45 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); * @return status value */ esp_bt_controller_status_t esp_bt_controller_get_status(void); + +/** + * @brief Get BLE TX power + * Connection Tx power should only be get after connection created. + * @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc + * @return >= 0 - Power level, < 0 - Invalid + */ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type); + +/** + * @brief De-initialize BT controller to free resource and delete task. + * You should stop advertising and scanning, as well as + * disconnect all existing connections before de-initializing BT controller. + * + * This function should be called only once, after any other BT functions are called. + * This function is not whole completed, esp_bt_controller_init cannot called after this function. + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_deinit(void); + +/** + * @brief Enable BT controller. + * Due to a known issue, you cannot call esp_bt_controller_enable() a second time + * to change the controller mode dynamically. To change controller mode, call + * esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode. + * @param mode : the mode(BLE/BT/BTDM) to enable. For compatible of API, retain this argument. + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); + +/** + * @brief Disable BT controller + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_disable(void); +/** @brief esp_vhci_host_callback + * used for vhci call host function to notify what host need to do + */ typedef struct esp_vhci_host_callback { void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */ int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/ @@ -366,9 +414,20 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode); */ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode); -/* Returns random static address or -1 if not present */ +/** + * @brief Returns random static address or -1 if not present. + * @return ESP_OK - success, other - failed + */ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr); +#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +/** + * @brief dump all controller log information cached in buffer + * @param output : true for log dump, false will take no effect + */ +void esp_ble_controller_log_dump_all(bool output); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED + #ifdef __cplusplus } #endif diff --git a/components/bt/include/esp32c3/include/esp_bt.h b/components/bt/include/esp32c3/include/esp_bt.h index 3b62cf0215..7221e720a3 100644 --- a/components/bt/include/esp32c3/include/esp_bt.h +++ b/components/bt/include/esp32c3/include/esp_bt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,7 @@ extern "C" { #endif #define ESP_BT_CTRL_CONFIG_MAGIC_VAL 0x5A5AA5A5 -#define ESP_BT_CTRL_CONFIG_VERSION 0x02302140 +#define ESP_BT_CTRL_CONFIG_VERSION 0x02404010 #define ESP_BT_HCI_TL_MAGIC_VALUE 0xfadebead #define ESP_BT_HCI_TL_VERSION 0x00010000 @@ -43,7 +43,7 @@ typedef enum { } esp_bt_ctrl_hci_tl_t; /** - * @breif type of BLE connection event length computation + * @brief type of BLE connection event length computation */ typedef enum { ESP_BLE_CE_LEN_TYPE_ORIG = 0, /*!< original */ @@ -144,8 +144,21 @@ typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status); #ifdef CONFIG_BT_CTRL_AGC_RECORRECT_EN #define BT_CTRL_AGC_RECORRECT_EN CONFIG_BT_CTRL_AGC_RECORRECT_EN +// ESP32-S3 +#if CONFIG_IDF_TARGET_ESP32S3 +#define BT_CTRL_AGC_RECORRECT_NEW 1 +#else +//Check if chip target is ESP32-C3 101 +#if CONFIG_ESP32C3_REV_MIN_101 +#define BT_CTRL_AGC_RECORRECT_NEW 1 +#else +#define BT_CTRL_AGC_RECORRECT_NEW 0 +#endif // CONFIG_ESP32C3_REV_MIN_101 +#endif // CONFIG_IDF_TARGET_ESP32S3 + #else #define BT_CTRL_AGC_RECORRECT_EN 0 +#define BT_CTRL_AGC_RECORRECT_NEW 0 #endif #ifdef CONFIG_BT_CTRL_CODED_AGC_RECORRECT_EN @@ -169,7 +182,31 @@ typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status); #endif // (CONFIG_BT_BLUEDROID_ENABLED) || (CONFIG_BT_NIMBLE_ENABLED) #endif // (CONFIG_BT_BLE_50_FEATURES_SUPPORTED) || (CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT) -#define AGC_RECORRECT_EN ((BT_CTRL_AGC_RECORRECT_EN << 0) | (BT_CTRL_CODED_AGC_RECORRECT <<1)) +#if defined(CONFIG_BT_BLE_CCA_MODE) +#define BT_BLE_CCA_MODE (CONFIG_BT_BLE_CCA_MODE) +#else +#define BT_BLE_CCA_MODE (0) +#endif + +#if defined(CONFIG_BT_BLE_ADV_DATA_LENGTH_ZERO_AUX) +#define BT_BLE_ADV_DATA_LENGTH_ZERO_AUX (CONFIG_BT_BLE_ADV_DATA_LENGTH_ZERO_AUX) +#else +#define BT_BLE_ADV_DATA_LENGTH_ZERO_AUX (0) +#endif + +#if defined(CONFIG_BT_CTRL_CHAN_ASS_EN) +#define BT_CTRL_CHAN_ASS_EN (CONFIG_BT_CTRL_CHAN_ASS_EN) +#else +#define BT_CTRL_CHAN_ASS_EN (0) +#endif + +#if defined(CONFIG_BT_CTRL_LE_PING_EN) +#define BT_CTRL_LE_PING_EN (CONFIG_BT_CTRL_LE_PING_EN) +#else +#define BT_CTRL_LE_PING_EN (0) +#endif + +#define AGC_RECORRECT_EN ((BT_CTRL_AGC_RECORRECT_EN << 0) | (BT_CTRL_CODED_AGC_RECORRECT <<1) | (BT_CTRL_AGC_RECORRECT_NEW << 2)) #define CFG_MASK_BIT_SCAN_DUPLICATE_OPTION (1<<0) @@ -214,6 +251,10 @@ typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status); .scan_backoff_upperlimitmax = BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX, \ .dup_list_refresh_period = DUPL_SCAN_CACHE_REFRESH_PERIOD, \ .ble_50_feat_supp = BT_CTRL_50_FEATURE_SUPPORT, \ + .ble_cca_mode = BT_BLE_CCA_MODE, \ + .ble_data_lenth_zero_aux = BT_BLE_ADV_DATA_LENGTH_ZERO_AUX, \ + .ble_chan_ass_en = BT_CTRL_CHAN_ASS_EN, \ + .ble_ping_en = BT_CTRL_LE_PING_EN, \ } #else @@ -225,16 +266,16 @@ typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status); * This structure shall be registered when HCI transport layer is UART */ typedef struct { - uint32_t _magic; /* Magic number */ - uint32_t _version; /* version number of the defined structure */ - uint32_t _reserved; /* reserved for future use */ - int (* _open)(void); /* hci tl open */ - void (* _close)(void); /* hci tl close */ - void (* _finish_transfers)(void); /* hci tl finish trasnfers */ - void (* _recv)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /* hci tl recv */ - void (* _send)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /* hci tl send */ - bool (* _flow_off)(void); /* hci tl flow off */ - void (* _flow_on)(void); /* hci tl flow on */ + uint32_t _magic; /*!< Magic number */ + uint32_t _version; /*!< Version number of the defined structure */ + uint32_t _reserved; /*!< Reserved for future use */ + int (* _open)(void); /*!< HCI transport layer open function */ + void (* _close)(void); /*!< HCI transport layer close function */ + void (* _finish_transfers)(void); /*!< HCI transport layer finish transfers function */ + void (* _recv)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /*!< HCI transport layer receive function */ + void (* _send)(uint8_t *buf, uint32_t len, esp_bt_hci_tl_callback_t callback, void* arg); /*!< HCI transport layer send function */ + bool (* _flow_off)(void); /*!< HCI transport layer flow off function */ + void (* _flow_on)(void); /*!< HCI transport layer flow on function */ } esp_bt_hci_tl_t; /** @@ -262,7 +303,7 @@ typedef struct { uint8_t sleep_clock; /*!< controller sleep clock */ uint8_t ble_st_acl_tx_buf_nb; /*!< controller static ACL TX BUFFER number */ uint8_t ble_hw_cca_check; /*!< controller hardware triggered CCA check */ - uint16_t ble_adv_dup_filt_max; /*!< maxinum number of duplicate scan filter */ + uint16_t ble_adv_dup_filt_max; /*!< maximum number of duplicate scan filter */ bool coex_param_en; /*!< deprecated */ uint8_t ce_len_type; /*!< connection event length computation method */ bool coex_use_hooks; /*!< deprecated */ @@ -271,7 +312,7 @@ typedef struct { uint8_t txant_dft; /*!< default Tx antenna */ uint8_t rxant_dft; /*!< default Rx antenna */ uint8_t txpwr_dft; /*!< default Tx power */ - uint32_t cfg_mask; + uint32_t cfg_mask; /*!< Configuration mask to set specific options */ uint8_t scan_duplicate_mode; /*!< scan duplicate mode */ uint8_t scan_duplicate_type; /*!< scan duplicate type */ uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */ @@ -279,11 +320,15 @@ typedef struct { uint8_t coex_phy_coded_tx_rx_time_limit; /*!< limit on max tx/rx time in case of connection using CODED-PHY with Wi-Fi coexistence */ uint32_t hw_target_code; /*!< hardware target */ uint8_t slave_ce_len_min; /*!< slave minimum ce length*/ - uint8_t hw_recorrect_en; + uint8_t hw_recorrect_en; /*!< Hardware re-correction enabled */ uint8_t cca_thresh; /*!< cca threshold*/ uint16_t scan_backoff_upperlimitmax; /*!< scan backoff upperlimitmax value */ uint16_t dup_list_refresh_period; /*!< duplicate scan list refresh time */ bool ble_50_feat_supp; /*!< BLE 5.0 feature support */ + uint8_t ble_cca_mode; /*!< BLE CCA mode */ + uint8_t ble_data_lenth_zero_aux; /*!< Config ext adv aux option */ + uint8_t ble_chan_ass_en; /*!< BLE channel assessment enable */ + uint8_t ble_ping_en; /*!< BLE ping procedure enable */ } esp_bt_controller_config_t; /** @@ -345,6 +390,18 @@ typedef enum { ESP_PWR_LVL_INVALID = 0xFF, /*!< Indicates an invalid value */ } esp_power_level_t; +/** + * @brief The enhanced type of which tx power, could set Advertising/Connection/Default and etc. + */ +typedef enum { + ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT = 0, + ESP_BLE_ENHANCED_PWR_TYPE_ADV, + ESP_BLE_ENHANCED_PWR_TYPE_SCAN, + ESP_BLE_ENHANCED_PWR_TYPE_INIT, + ESP_BLE_ENHANCED_PWR_TYPE_CONN, + ESP_BLE_ENHANCED_PWR_TYPE_MAX, +} esp_ble_enhanced_power_type_t; + /** * @brief Set BLE TX power * Connection Tx power should only be set after connection created. @@ -362,6 +419,25 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ */ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type); +/** + * @brief ENHANCED API for Setting BLE TX power + * Connection Tx power should only be set after connection created. + * @param power_type : The enhanced type of which tx power, could set Advertising/Connection/Default and etc. + * @param handle : The handle of Advertising or Connection and the value 0 for other enhanced power types. + * @param power_level: Power level(index) corresponding to absolute value(dbm) + * @return ESP_OK - success, other - failed + */ +esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle, esp_power_level_t power_level); + +/** + * @brief ENHANCED API of Getting BLE TX power + * Connection Tx power should only be get after connection created. + * @param power_type : The enhanced type of which tx power, could set Advertising/Connection/Default and etc + * @param handle : The handle of Advertising or Connection and the value 0 for other enhanced power types. + * @return >= 0 - Power level, < 0 - Invalid + */ +esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); + /** * @brief Initialize BT controller to allocate task and other resource. * This function should be called only once, before any other BT functions are called. @@ -571,6 +647,15 @@ void esp_wifi_bt_power_domain_on(void); */ void esp_wifi_bt_power_domain_off(void); +/** + * @brief Get the Bluetooth module sleep clock source. + * + * Note that this function shall not be invoked before esp_bt_controller_init() + * + * @return clock source used in Bluetooth low power mode + */ +esp_bt_sleep_clock_t esp_bt_get_lpclk_src(void); + #ifdef __cplusplus } #endif diff --git a/components/bt/include/esp32c6/include/esp_bt.h b/components/bt/include/esp32c6/include/esp_bt.h index 25a3f7bb5e..ea27228722 100644 --- a/components/bt/include/esp32c6/include/esp_bt.h +++ b/components/bt/include/esp32c6/include/esp_bt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,7 @@ #include "esp_task.h" #include "nimble/nimble_npl.h" -#include "esp_bt_cfg.h" +#include "../../../../controller/esp32c6/esp_bt_cfg.h" #include "hal/efuse_hal.h" #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART @@ -24,10 +24,10 @@ #ifdef __cplusplus extern "C" { #endif + /** - * @brief Bluetooth mode for controller enable/disable + * @brief Bluetooth mode for controller enable/disable. */ - typedef enum { ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not running */ ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */ @@ -36,9 +36,8 @@ typedef enum { } esp_bt_mode_t; /** - * @brief Bluetooth controller enable/disable/initialised/de-initialised status + * @brief Bluetooth controller enable/disable/initialised/de-initialised status. */ - typedef enum { ESP_BT_CONTROLLER_STATUS_IDLE = 0, /*!< Controller is in idle state */ ESP_BT_CONTROLLER_STATUS_INITED, /*!< Controller is in initialising state */ @@ -92,6 +91,9 @@ typedef enum { ESP_PWR_LVL_INVALID = 0xFF, /*!< Indicates an invalid value */ } esp_power_level_t; +/** + * @brief The enhanced type of which tx power, could set Advertising/Connection/Default and etc. + */ typedef enum { ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT = 0, ESP_BLE_ENHANCED_PWR_TYPE_ADV, @@ -101,9 +103,20 @@ typedef enum { ESP_BLE_ENHANCED_PWR_TYPE_MAX, } esp_ble_enhanced_power_type_t; +/** + * @brief Select buffers +*/ +typedef enum { + ESP_BLE_LOG_BUF_HCI = 0x02, + ESP_BLE_LOG_BUF_CONTROLLER = 0x05, +} esp_ble_log_buf_t; + +/** + * @brief Address type and address value. + */ typedef struct { - uint8_t type; - uint8_t val[6]; + uint8_t type; /*!< Type of the Bluetooth address (public, random, etc.) */ + uint8_t val[6]; /*!< Array containing the 6-byte Bluetooth address value */ } esp_ble_addr_t; /** @@ -126,7 +139,7 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type); /** * @brief ENHANCED API for Setting BLE TX power * Connection Tx power should only be set after connection created. - * @param power_type : The enhanced type of which tx power, could set Advertising/Connection/Default and etc + * @param power_type : The enhanced type of which tx power, could set Advertising/Connection/Default and etc. * @param handle : The handle of Advertising or Connection and the value 0 for other enhanced power types. * @param power_level: Power level(index) corresponding to absolute value(dbm) * @return ESP_OK - success, other - failed @@ -142,7 +155,7 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type */ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -#define CONFIG_VERSION 0x20230113 +#define CONFIG_VERSION 0x20240422 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -150,64 +163,56 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po * Config mask indicate which functions enabled, this means * some options or parameters of some functions enabled by config mask. */ - typedef struct { - uint32_t config_version; - uint16_t ble_ll_resolv_list_size; - uint16_t ble_hci_evt_hi_buf_count; - uint16_t ble_hci_evt_lo_buf_count; - uint8_t ble_ll_sync_list_cnt; - uint8_t ble_ll_sync_cnt; - uint16_t ble_ll_rsp_dup_list_count; - uint16_t ble_ll_adv_dup_list_count; - uint8_t ble_ll_tx_pwr_dbm; - uint64_t rtc_freq; - uint16_t ble_ll_sca; - uint8_t ble_ll_scan_phy_number; - uint16_t ble_ll_conn_def_auth_pyld_tmo; - uint8_t ble_ll_jitter_usecs; - uint16_t ble_ll_sched_max_adv_pdu_usecs; - uint16_t ble_ll_sched_direct_adv_max_usecs; - uint16_t ble_ll_sched_adv_max_usecs; - uint16_t ble_scan_rsp_data_max_len; - uint8_t ble_ll_cfg_num_hci_cmd_pkts; - uint32_t ble_ll_ctrl_proc_timeout_ms; - uint16_t nimble_max_connections; - uint8_t ble_whitelist_size; - uint16_t ble_acl_buf_size; - uint16_t ble_acl_buf_count; - uint16_t ble_hci_evt_buf_size; - uint16_t ble_multi_adv_instances; - uint16_t ble_ext_adv_max_size; - uint16_t controller_task_stack_size; - uint8_t controller_task_prio; - uint8_t controller_run_cpu; - uint8_t enable_qa_test; - uint8_t enable_bqb_test; - uint8_t enable_uart_hci; - uint8_t ble_hci_uart_port; - uint32_t ble_hci_uart_baud; - uint8_t ble_hci_uart_data_bits; - uint8_t ble_hci_uart_stop_bits; - uint8_t ble_hci_uart_flow_ctrl; - uint8_t ble_hci_uart_uart_parity; - uint8_t enable_tx_cca; - uint8_t cca_rssi_thresh; - uint8_t sleep_en; - uint8_t coex_phy_coded_tx_rx_time_limit; - uint8_t dis_scan_backoff; - uint8_t ble_scan_classify_filter_enable; - uint8_t cca_drop_mode; - int8_t cca_low_tx_pwr; - uint8_t main_xtal_freq; - uint8_t version_num; - uint8_t cpu_freq_mhz; - uint8_t ignore_wl_for_direct_adv; - uint8_t enable_pcl; - uint32_t config_magic; + uint32_t config_version; /*!< Configuration version */ + uint16_t ble_ll_resolv_list_size; /*!< Size of the BLE resolving list */ + uint16_t ble_hci_evt_hi_buf_count; /*!< Number of high priority HCI event buffers */ + uint16_t ble_hci_evt_lo_buf_count; /*!< Number of low priority HCI event buffers */ + uint8_t ble_ll_sync_list_cnt; /*!< Number of entries in the BLE sync list */ + uint8_t ble_ll_sync_cnt; /*!< Number of BLE sync instances */ + uint16_t ble_ll_rsp_dup_list_count; /*!< Size of the BLE response duplicate list */ + uint16_t ble_ll_adv_dup_list_count; /*!< Size of the BLE advertising duplicate list */ + uint8_t ble_ll_tx_pwr_dbm; /*!< BLE transmit power in dBm */ + uint64_t rtc_freq; /*!< RTC (Real-Time Clock) frequency */ + uint16_t ble_ll_sca; /*!< BLE sleep clock accuracy in ppm */ + uint8_t ble_ll_scan_phy_number; /*!< Number of BLE scanning physical layers */ + uint16_t ble_ll_conn_def_auth_pyld_tmo; /*!< BLE connection default authentication payload timeout */ + uint8_t ble_ll_jitter_usecs; /*!< BLE link layer jitter in microseconds */ + uint16_t ble_ll_sched_max_adv_pdu_usecs; /*!< BLE scheduler maximum advertising PDU duration in microseconds */ + uint16_t ble_ll_sched_direct_adv_max_usecs; /*!< BLE scheduler maximum direct advertising duration in microseconds */ + uint16_t ble_ll_sched_adv_max_usecs; /*!< BLE scheduler maximum advertising duration in microseconds */ + uint16_t ble_scan_rsp_data_max_len; /*!< Maximum length of BLE scan response data */ + uint8_t ble_ll_cfg_num_hci_cmd_pkts; /*!< Number of BLE LL configuration HCI command packets */ + uint32_t ble_ll_ctrl_proc_timeout_ms; /*!< BLE link layer controller process timeout in milliseconds */ + uint16_t nimble_max_connections; /*!< Maximum number of concurrent BLE connections */ + uint8_t ble_whitelist_size; /*!< Size of the BLE whitelist */ + uint16_t ble_acl_buf_size; /*!< Size of the BLE ACL data buffer */ + uint16_t ble_acl_buf_count; /*!< Number of BLE ACL data buffers */ + uint16_t ble_hci_evt_buf_size; /*!< Size of the BLE HCI event buffer */ + uint16_t ble_multi_adv_instances; /*!< Number of BLE multi-advertising instances */ + uint16_t ble_ext_adv_max_size; /*!< Maximum size of BLE extended advertising data */ + uint16_t controller_task_stack_size; /*!< Controller task stack size */ + uint8_t controller_task_prio; /*!< Controller task priority */ + uint8_t controller_run_cpu; /*!< CPU core on which the controller runs */ + uint8_t enable_qa_test; /*!< Enable quality assurance (QA) testing */ + uint8_t enable_bqb_test; /*!< Enable Bluetooth Qualification Test (BQB) testing */ + uint8_t enable_tx_cca; /*!< Enable Transmit Clear Channel Assessment (TX CCA) */ + uint8_t cca_rssi_thresh; /*!< RSSI threshold for Transmit Clear Channel Assessment (CCA) */ + uint8_t sleep_en; /*!< Enable sleep mode */ + uint8_t coex_phy_coded_tx_rx_time_limit; /*!< PHY coded transmission and reception time limit for coexistence */ + uint8_t dis_scan_backoff; /*!< Disable scan backoff */ + uint8_t ble_scan_classify_filter_enable; /*!< Enable BLE scan classify filter */ + uint8_t cca_drop_mode; /*!< CCA drop mode */ + int8_t cca_low_tx_pwr; /*!< CCA low transmit power */ + uint8_t main_xtal_freq; /*!< Main crystal frequency */ + uint32_t version_num; /*!< Controller configuration version number */ + uint8_t cpu_freq_mhz; /*!< CPU frequency in megahertz (MHz) */ + uint8_t ignore_wl_for_direct_adv; /*!< Ignore the whitelist for direct advertising */ + uint8_t enable_pcl; /*!< Enable power control */ + uint8_t csa2_select; /*!< Select CSA#2*/ + uint32_t config_magic; /*!< Magic number for configuration validation */ } esp_bt_controller_config_t; - #define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \ .config_version = CONFIG_VERSION, \ .ble_ll_resolv_list_size = CONFIG_BT_LE_LL_RESOLV_LIST_SIZE, \ @@ -241,13 +246,6 @@ typedef struct { .controller_run_cpu = 0, \ .enable_qa_test = RUN_QA_TEST, \ .enable_bqb_test = RUN_BQB_TEST, \ - .enable_uart_hci = HCI_UART_EN, \ - .ble_hci_uart_port = DEFAULT_BT_LE_HCI_UART_PORT, \ - .ble_hci_uart_baud = DEFAULT_BT_LE_HCI_UART_BAUD, \ - .ble_hci_uart_data_bits = DEFAULT_BT_LE_HCI_UART_DATA_BITS, \ - .ble_hci_uart_stop_bits = DEFAULT_BT_LE_HCI_UART_STOP_BITS, \ - .ble_hci_uart_flow_ctrl = DEFAULT_BT_LE_HCI_UART_FLOW_CTRL, \ - .ble_hci_uart_uart_parity = DEFAULT_BT_LE_HCI_UART_PARITY, \ .enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \ .cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \ .sleep_en = NIMBLE_SLEEP_ENABLE, \ @@ -259,9 +257,16 @@ typedef struct { .cpu_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, \ .ignore_wl_for_direct_adv = 0, \ .enable_pcl = DEFAULT_BT_LE_POWER_CONTROL_ENABLED, \ + .csa2_select = DEFAULT_BT_LE_50_FEATURE_SUPPORT, \ .config_magic = CONFIG_MAGIC, \ } +/** + * @brief Initialize BT controller to allocate task and other resource. + * This function should be called only once, before any other BT functions are called. + * @param cfg: Initial configuration of BT controller. + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); /** @@ -269,11 +274,45 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); * @return status value */ esp_bt_controller_status_t esp_bt_controller_get_status(void); + +/** + * @brief Get BLE TX power + * Connection Tx power should only be get after connection created. + * @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc + * @return >= 0 - Power level, < 0 - Invalid + */ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type); + +/** + * @brief De-initialize BT controller to free resource and delete task. + * You should stop advertising and scanning, as well as + * disconnect all existing connections before de-initializing BT controller. + * + * This function should be called only once, after any other BT functions are called. + * This function is not whole completed, esp_bt_controller_init cannot called after this function. + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_deinit(void); + +/** + * @brief Enable BT controller. + * Due to a known issue, you cannot call esp_bt_controller_enable() a second time + * to change the controller mode dynamically. To change controller mode, call + * esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode. + * @param mode : the mode(BLE/BT/BTDM) to enable. For compatible of API, retain this argument. + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); + +/** + * @brief Disable BT controller + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_disable(void); +/** @brief esp_vhci_host_callback + * used for vhci call host function to notify what host need to do + */ typedef struct esp_vhci_host_callback { void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */ int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/ @@ -361,13 +400,16 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode); */ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode); -/* Returns random static address or -1 if not present */ +/** + * @brief Returns random static address or -1 if not present. + * @return ESP_OK - success, other - failed + */ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -/** @brief esp_ble_controller_log_dump_all - * dump all controller log information cached in buffer - * @param output : true for log dump, false will be no effect +/** + * @brief dump all log information cached in buffers. + * @param output : true for log dump, false will take no effect */ void esp_ble_controller_log_dump_all(bool output); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED diff --git a/components/bt/include/esp32h2/include/esp_bt.h b/components/bt/include/esp32h2/include/esp_bt.h index 67909c9a42..bbecb64072 100644 --- a/components/bt/include/esp32h2/include/esp_bt.h +++ b/components/bt/include/esp32h2/include/esp_bt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,7 @@ #include "esp_task.h" #include "nimble/nimble_npl.h" -#include "esp_bt_cfg.h" +#include "../../../../controller/esp32h2/esp_bt_cfg.h" #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #include "driver/uart.h" @@ -25,9 +25,8 @@ extern "C" { #endif /** - * @brief Bluetooth mode for controller enable/disable + * @brief Bluetooth mode for controller enable/disable. */ - typedef enum { ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not running */ ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */ @@ -36,9 +35,8 @@ typedef enum { } esp_bt_mode_t; /** - * @brief Bluetooth controller enable/disable/initialised/de-initialised status + * @brief Bluetooth controller enable/disable/initialised/de-initialised status. */ - typedef enum { ESP_BT_CONTROLLER_STATUS_IDLE = 0, /*!< Controller is in idle state */ ESP_BT_CONTROLLER_STATUS_INITED, /*!< Controller is in initialising state */ @@ -90,14 +88,17 @@ typedef enum { ESP_PWR_LVL_P9 = 11, /*!< Corresponding to +9dbm */ ESP_PWR_LVL_P12 = 12, /*!< Corresponding to +12dbm */ ESP_PWR_LVL_P15 = 13, /*!< Corresponding to +15dbm */ - ESP_PWR_LVL_P16 = 14, /*!< Corresponding to +16dbm */ - ESP_PWR_LVL_P17 = 15, /*!< Corresponding to +17dbm */ - ESP_PWR_LVL_P18 = 16, /*!< Corresponding to +18dbm */ - ESP_PWR_LVL_P19 = 17, /*!< Corresponding to +19dbm */ - ESP_PWR_LVL_P20 = 18, /*!< Corresponding to +20dbm */ + ESP_PWR_LVL_P16 = 14, /*!< Corresponding to +18dbm, this enum variable has been deprecated */ + ESP_PWR_LVL_P17 = 14, /*!< Corresponding to +18dbm, this enum variable has been deprecated */ + ESP_PWR_LVL_P18 = 14, /*!< Corresponding to +18dbm */ + ESP_PWR_LVL_P19 = 15, /*!< Corresponding to +20dbm, this enum variable has been deprecated */ + ESP_PWR_LVL_P20 = 15, /*!< Corresponding to +20dbm */ ESP_PWR_LVL_INVALID = 0xFF, /*!< Indicates an invalid value */ } esp_power_level_t; +/** + * @brief The enhanced type of which tx power, could set Advertising/Connection/Default and etc. + */ typedef enum { ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT = 0, ESP_BLE_ENHANCED_PWR_TYPE_ADV, @@ -107,11 +108,22 @@ typedef enum { ESP_BLE_ENHANCED_PWR_TYPE_MAX, } esp_ble_enhanced_power_type_t; +/** + * @brief Address type and address value. + */ typedef struct { - uint8_t type; - uint8_t val[6]; + uint8_t type; /*!< Type of the Bluetooth address (public, random, etc.) */ + uint8_t val[6]; /*!< Array containing the 6-byte Bluetooth address value */ } esp_ble_addr_t; +/** + * @brief Select buffers +*/ +typedef enum { + ESP_BLE_LOG_BUF_HCI = 0x02, + ESP_BLE_LOG_BUF_CONTROLLER = 0x05, +} esp_ble_log_buf_t; + /** * @brief Set BLE TX power * Connection Tx power should only be set after connection created. @@ -148,7 +160,7 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type */ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle); -#define CONFIG_VERSION 0x20230113 +#define CONFIG_VERSION 0x20240422 #define CONFIG_MAGIC 0x5A5AA5A5 /** @@ -156,60 +168,53 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po * Config mask indicate which functions enabled, this means * some options or parameters of some functions enabled by config mask. */ - typedef struct { - uint32_t config_version; - uint16_t ble_ll_resolv_list_size; - uint16_t ble_hci_evt_hi_buf_count; - uint16_t ble_hci_evt_lo_buf_count; - uint8_t ble_ll_sync_list_cnt; - uint8_t ble_ll_sync_cnt; - uint16_t ble_ll_rsp_dup_list_count; - uint16_t ble_ll_adv_dup_list_count; - uint8_t ble_ll_tx_pwr_dbm; - uint64_t rtc_freq; - uint16_t ble_ll_sca; - uint8_t ble_ll_scan_phy_number; - uint16_t ble_ll_conn_def_auth_pyld_tmo; - uint8_t ble_ll_jitter_usecs; - uint16_t ble_ll_sched_max_adv_pdu_usecs; - uint16_t ble_ll_sched_direct_adv_max_usecs; - uint16_t ble_ll_sched_adv_max_usecs; - uint16_t ble_scan_rsp_data_max_len; - uint8_t ble_ll_cfg_num_hci_cmd_pkts; - uint32_t ble_ll_ctrl_proc_timeout_ms; - uint16_t nimble_max_connections; - uint8_t ble_whitelist_size; - uint16_t ble_acl_buf_size; - uint16_t ble_acl_buf_count; - uint16_t ble_hci_evt_buf_size; - uint16_t ble_multi_adv_instances; - uint16_t ble_ext_adv_max_size; - uint16_t controller_task_stack_size; - uint8_t controller_task_prio; - uint8_t controller_run_cpu; - uint8_t enable_qa_test; - uint8_t enable_bqb_test; - uint8_t enable_uart_hci; - uint8_t ble_hci_uart_port; - uint32_t ble_hci_uart_baud; - uint8_t ble_hci_uart_data_bits; - uint8_t ble_hci_uart_stop_bits; - uint8_t ble_hci_uart_flow_ctrl; - uint8_t ble_hci_uart_uart_parity; - uint8_t enable_tx_cca; - uint8_t cca_rssi_thresh; - uint8_t sleep_en; - uint8_t coex_phy_coded_tx_rx_time_limit; - uint8_t dis_scan_backoff; - uint8_t ble_scan_classify_filter_enable; - uint8_t cca_drop_mode; - int8_t cca_low_tx_pwr; - uint8_t main_xtal_freq; - uint8_t cpu_freq_mhz; - uint8_t ignore_wl_for_direct_adv; - uint8_t enable_pcl; - uint32_t config_magic; + uint32_t config_version; /*!< Version number of the defined structure */ + uint16_t ble_ll_resolv_list_size; /*!< Size of the resolvable private address list */ + uint16_t ble_hci_evt_hi_buf_count; /*!< Count of high buffers for HCI events */ + uint16_t ble_hci_evt_lo_buf_count; /*!< Count of low buffers for HCI events */ + uint8_t ble_ll_sync_list_cnt; /*!< Number of synchronization lists */ + uint8_t ble_ll_sync_cnt; /*!< Number of synchronizations */ + uint16_t ble_ll_rsp_dup_list_count; /*!< Count of duplicated lists for scan response packets */ + uint16_t ble_ll_adv_dup_list_count; /*!< Count of duplicated lists for advertising packets */ + uint8_t ble_ll_tx_pwr_dbm; /*!< Tx power (transmit power) in dBm */ + uint64_t rtc_freq; /*!< Frequency of RTC (Real-Time Clock) */ + uint16_t ble_ll_sca; /*!< Sleep Clock Accuracy (SCA) parameter */ + uint8_t ble_ll_scan_phy_number; /*!< Number of PHYs supported for scanning */ + uint16_t ble_ll_conn_def_auth_pyld_tmo; /*!< Connection default authentication payload timeout */ + uint8_t ble_ll_jitter_usecs; /*!< Jitter time in microseconds */ + uint16_t ble_ll_sched_max_adv_pdu_usecs; /*!< Maximum time in microseconds for advertising PDU scheduling */ + uint16_t ble_ll_sched_direct_adv_max_usecs; /*!< Maximum time in microseconds for directed advertising scheduling */ + uint16_t ble_ll_sched_adv_max_usecs; /*!< Maximum time in microseconds for advertising scheduling */ + uint16_t ble_scan_rsp_data_max_len; /*!< Maximum length of scan response data */ + uint8_t ble_ll_cfg_num_hci_cmd_pkts; /*!< Number of HCI command packets that can be queued */ + uint32_t ble_ll_ctrl_proc_timeout_ms; /*!< Control processing timeout in milliseconds */ + uint16_t nimble_max_connections; /*!< Maximum number of connections supported */ + uint8_t ble_whitelist_size; /*!< Size of the white list */ + uint16_t ble_acl_buf_size; /*!< Buffer size of ACL (Asynchronous Connection-Less) data */ + uint16_t ble_acl_buf_count; /*!< Buffer count of ACL data */ + uint16_t ble_hci_evt_buf_size; /*!< Buffer size for HCI event data */ + uint16_t ble_multi_adv_instances; /*!< Number of advertising instances */ + uint16_t ble_ext_adv_max_size; /*!< Maximum size of extended advertising data */ + uint16_t controller_task_stack_size; /*!< Size of Bluetooth controller task stack */ + uint8_t controller_task_prio; /*!< Priority of the Bluetooth task */ + uint8_t controller_run_cpu; /*!< CPU number on which the Bluetooth controller task runs */ + uint8_t enable_qa_test; /*!< Enable for QA test */ + uint8_t enable_bqb_test; /*!< Enable for BQB test */ + uint8_t enable_tx_cca; /*!< Enable Clear Channel Assessment (CCA) when transmitting */ + uint8_t cca_rssi_thresh; /*!< RSSI threshold for CCA */ + uint8_t sleep_en; /*!< Enable sleep functionality */ + uint8_t coex_phy_coded_tx_rx_time_limit; /*!< Coexistence PHY coded TX and RX time limit */ + uint8_t dis_scan_backoff; /*!< Disable scan backoff */ + uint8_t ble_scan_classify_filter_enable; /*!< Enable classification filter for BLE scan */ + uint8_t cca_drop_mode; /*!< CCA drop mode */ + int8_t cca_low_tx_pwr; /*!< Low TX power setting for CCA */ + uint8_t main_xtal_freq; /*!< Main crystal frequency */ + uint8_t cpu_freq_mhz; /*!< CPU frequency in megahertz */ + uint8_t ignore_wl_for_direct_adv; /*!< Ignore the white list for directed advertising */ + uint8_t enable_pcl; /*!< Enable power control */ + uint8_t csa2_select; /*!< Select CSA#2*/ + uint32_t config_magic; /*!< Configuration magic value */ } esp_bt_controller_config_t; @@ -246,13 +251,6 @@ typedef struct { .controller_run_cpu = 0, \ .enable_qa_test = RUN_QA_TEST, \ .enable_bqb_test = RUN_BQB_TEST, \ - .enable_uart_hci = HCI_UART_EN, \ - .ble_hci_uart_port = DEFAULT_BT_LE_HCI_UART_PORT, \ - .ble_hci_uart_baud = DEFAULT_BT_LE_HCI_UART_BAUD, \ - .ble_hci_uart_data_bits = DEFAULT_BT_LE_HCI_UART_DATA_BITS, \ - .ble_hci_uart_stop_bits = DEFAULT_BT_LE_HCI_UART_STOP_BITS, \ - .ble_hci_uart_flow_ctrl = DEFAULT_BT_LE_HCI_UART_FLOW_CTRL, \ - .ble_hci_uart_uart_parity = DEFAULT_BT_LE_HCI_UART_PARITY, \ .enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \ .cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \ .sleep_en = NIMBLE_SLEEP_ENABLE, \ @@ -263,9 +261,16 @@ typedef struct { .cpu_freq_mhz = CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, \ .ignore_wl_for_direct_adv = 0, \ .enable_pcl = 0, \ + .csa2_select = DEFAULT_BT_LE_50_FEATURE_SUPPORT, \ .config_magic = CONFIG_MAGIC, \ } +/** + * @brief Initialize BT controller to allocate task and other resource. + * This function should be called only once, before any other BT functions are called. + * @param cfg: Initial configuration of BT controller. + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); /** @@ -273,11 +278,45 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); * @return status value */ esp_bt_controller_status_t esp_bt_controller_get_status(void); + +/** + * @brief Get BLE TX power + * Connection Tx power should only be get after connection created. + * @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc + * @return >= 0 - Power level, < 0 - Invalid + */ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type); + +/** + * @brief De-initialize BT controller to free resource and delete task. + * You should stop advertising and scanning, as well as + * disconnect all existing connections before de-initializing BT controller. + * + * This function should be called only once, after any other BT functions are called. + * This function is not whole completed, esp_bt_controller_init cannot called after this function. + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_deinit(void); + +/** + * @brief Enable BT controller. + * Due to a known issue, you cannot call esp_bt_controller_enable() a second time + * to change the controller mode dynamically. To change controller mode, call + * esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode. + * @param mode : the mode(BLE/BT/BTDM) to enable. For compatible of API, retain this argument. + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode); + +/** + * @brief Disable BT controller + * @return ESP_OK - success, other - failed + */ esp_err_t esp_bt_controller_disable(void); +/** @brief esp_vhci_host_callback + * used for vhci call host function to notify what host need to do + */ typedef struct esp_vhci_host_callback { void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */ int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/ @@ -365,13 +404,16 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode); */ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode); -/* Returns random static address or -1 if not present */ +/** + * @brief Returns random static address or -1 if not present. + * @return ESP_OK - success, other - failed + */ extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -/** @brief esp_ble_controller_log_dump_all - * dump all controller log information cached in buffer - * @param output : true for log dump, false will be no effect +/** + * @brief dump all log information cached in buffers. + * @param output : true for log dump, false will take no effect */ void esp_ble_controller_log_dump_all(bool output); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED diff --git a/components/bt/include/esp32h4/include/esp_bt_cfg.h b/components/bt/include/esp32h4/include/esp_bt_cfg.h index 28d1854d83..1f8caaeca8 100644 --- a/components/bt/include/esp32h4/include/esp_bt_cfg.h +++ b/components/bt/include/esp32h4/include/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -41,7 +41,6 @@ extern "C" { #define DEFAULT_BT_NIMBLE_WHITELIST_SIZE MYNEWT_VAL(BLE_LL_WHITELIST_SIZE) #define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT) - #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EFF #else @@ -117,11 +116,23 @@ extern "C" { #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8) #endif - #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF - + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif #endif - +#define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART @@ -159,8 +170,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -169,8 +178,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ diff --git a/components/bt/linker.lf b/components/bt/linker.lf deleted file mode 100644 index 72afd4d2e0..0000000000 --- a/components/bt/linker.lf +++ /dev/null @@ -1,56 +0,0 @@ -[sections:bt_bss] -entries: - .bss+ - -[sections:bt_common] -entries: - COMMON - -[scheme:bt_start_end] -entries: - bt_bss -> dram0_bss - bt_common -> dram0_bss - data -> dram0_data - -# For the following fragments, order matters for -# 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates: -# -# . = ALIGN(4) -# _sym_start -# ... -# . = ALIGN(4) -# _sym_end - -[mapping:bt] -archive: libbt.a -entries: - * (bt_start_end); - bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss), - bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common), - data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data) - if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: - * (extram_bss) - -[mapping:btdm] -archive: libbtdm_app.a -entries: - * (bt_start_end); - bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_bss), - bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(btdm_common), - data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(btdm_data) - -[mapping:bt_controller] -archive: libble_app.a -entries: - * (bt_start_end); - bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss), - bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common), - data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data) - -[mapping:nimble] -archive: libnimble.a -entries: - * (bt_start_end); - bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(nimble_bss), - bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(nimble_common), - data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(nimble_data) diff --git a/components/bt/linker_common.lf b/components/bt/linker_common.lf new file mode 100644 index 0000000000..501acd9505 --- /dev/null +++ b/components/bt/linker_common.lf @@ -0,0 +1,42 @@ +[sections:bt_bss] +entries: + .bss+ + +[sections:bt_common] +entries: + COMMON + +[scheme:bt_default] +entries: + bt_bss -> dram0_bss + bt_common -> dram0_bss + data -> dram0_data + +[scheme:bt_extram_bss] +entries: + bt_bss -> extern_ram + bt_common -> extern_ram + data -> dram0_data + +# For the following fragments, order matters for +# 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates: +# +# . = ALIGN(4) +# _sym_start +# ... +# . = ALIGN(4) +# _sym_end + +[mapping:bt] +archive: libbt.a +entries: + if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (bt_extram_bss); + bt_bss -> extern_ram ALIGN(4) ALIGN(4, post) SURROUND(bt_bss), + bt_common -> extern_ram ALIGN(4) ALIGN(4, post) SURROUND(bt_common), + data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data) + else: + * (bt_default); + bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss), + bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common), + data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data) diff --git a/components/bt/linker_esp32c2.lf b/components/bt/linker_esp32c2.lf new file mode 100644 index 0000000000..7178420a00 --- /dev/null +++ b/components/bt/linker_esp32c2.lf @@ -0,0 +1,50 @@ +[sections:bt_iram_text] +entries: + .iram1+ + +[sections:bt_bss] +entries: + .bss+ + .sbss+ + +[sections:bt_data] +entries: + .data+ + .sdata+ + .dram1+ + +[sections:bt_common] +entries: + COMMON + +[scheme:bt_default] +entries: + bt_iram_text -> iram0_bt_text + bt_bss -> dram0_bt_bss + bt_common -> dram0_bt_bss + bt_data -> dram0_bt_data + +# For the following fragments, order matters for +# 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates: +# +# . = ALIGN(4) +# _sym_start +# ... +# . = ALIGN(4) +# _sym_end + +[mapping:bt] +archive: libbt.a +entries: + * (bt_default); + bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss), + bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common), + bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data) + +[mapping:ble_app] +archive: libble_app.a +entries: + * (bt_default); + bt_bss -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss), + bt_common -> dram0_bt_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common), + bt_data -> dram0_bt_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data) diff --git a/components/bt/linker_esp_ble_controller.lf b/components/bt/linker_esp_ble_controller.lf new file mode 100644 index 0000000000..fe8598112b --- /dev/null +++ b/components/bt/linker_esp_ble_controller.lf @@ -0,0 +1,7 @@ +[mapping:ble_app] +archive: libble_app.a +entries: + * (bt_default); + bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss), + bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common), + data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data) diff --git a/components/bt/linker_rw_bt_controller.lf b/components/bt/linker_rw_bt_controller.lf new file mode 100644 index 0000000000..083d6e90b7 --- /dev/null +++ b/components/bt/linker_rw_bt_controller.lf @@ -0,0 +1,7 @@ +[mapping:btdm] +archive: libbtdm_app.a +entries: + * (bt_default); + bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss), + bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common), + data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data) diff --git a/components/bt/porting/nimble/include/nimble/ble_hci_trans.h b/components/bt/porting/include/ble_hci_trans.h similarity index 93% rename from components/bt/porting/nimble/include/nimble/ble_hci_trans.h rename to components/bt/porting/include/ble_hci_trans.h index 60281c676d..05267b6be7 100644 --- a/components/bt/porting/nimble/include/nimble/ble_hci_trans.h +++ b/components/bt/porting/include/ble_hci_trans.h @@ -1,20 +1,7 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 */ #ifndef H_HCI_TRANSPORT_ @@ -63,7 +50,7 @@ extern "C" { typedef int ble_hci_trans_rx_cmd_fn(uint8_t *cmd, void *arg); typedef int ble_hci_trans_rx_acl_fn(struct os_mbuf *om, void *arg); -#if SOC_ESP_NIMBLE_CONTROLLER +#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED #define ble_transport_alloc_cmd() ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD) #define ble_transport_alloc_event(X) ble_hci_trans_buf_alloc(X ? BLE_HCI_TRANS_BUF_EVT_LO : BLE_HCI_TRANS_BUF_EVT_HI) #define ble_transport_free ble_hci_trans_buf_free diff --git a/components/bt/porting/mem/bt_osi_mem.h b/components/bt/porting/include/bt_osi_mem.h similarity index 100% rename from components/bt/porting/mem/bt_osi_mem.h rename to components/bt/porting/include/bt_osi_mem.h diff --git a/components/bt/porting/include/mem_api.h b/components/bt/porting/include/mem_api.h index ea19f2cff4..854074613a 100644 --- a/components/bt/porting/include/mem_api.h +++ b/components/bt/porting/include/mem_api.h @@ -11,7 +11,7 @@ extern "C" { #endif -#if SOC_ESP_NIMBLE_CONTROLLER +#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED struct os_mempool; struct os_mbuf_pool; diff --git a/components/bt/porting/nimble/include/os/endian.h b/components/bt/porting/include/os/endian.h similarity index 99% rename from components/bt/porting/nimble/include/os/endian.h rename to components/bt/porting/include/os/endian.h index af474acc05..2e06a8b566 100644 --- a/components/bt/porting/nimble/include/os/endian.h +++ b/components/bt/porting/include/os/endian.h @@ -213,7 +213,7 @@ extern "C" { #endif -#if SOC_ESP_NIMBLE_CONTROLLER +#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED void r_put_le16(void *buf, uint16_t x); #define put_le16 r_put_le16 diff --git a/components/bt/porting/nimble/include/os/os.h b/components/bt/porting/include/os/os.h similarity index 100% rename from components/bt/porting/nimble/include/os/os.h rename to components/bt/porting/include/os/os.h diff --git a/components/bt/porting/nimble/include/os/os_error.h b/components/bt/porting/include/os/os_error.h similarity index 100% rename from components/bt/porting/nimble/include/os/os_error.h rename to components/bt/porting/include/os/os_error.h diff --git a/components/bt/porting/nimble/include/os/os_mbuf.h b/components/bt/porting/include/os/os_mbuf.h similarity index 99% rename from components/bt/porting/nimble/include/os/os_mbuf.h rename to components/bt/porting/include/os/os_mbuf.h index bd2df864b4..c6ea6b6e85 100644 --- a/components/bt/porting/nimble/include/os/os_mbuf.h +++ b/components/bt/porting/include/os/os_mbuf.h @@ -65,7 +65,7 @@ struct os_mbuf_pool { /** - * A packet header structure that preceeds the mbuf packet headers. + * A packet header structure that proceeds the mbuf packet headers. */ struct os_mbuf_pkthdr { /** @@ -89,7 +89,7 @@ struct os_mbuf { */ uint8_t *om_data; /** - * Flags associated with this buffer, see OS_MBUF_F_* defintions + * Flags associated with this buffer, see OS_MBUF_F_* definitions */ uint8_t om_flags; /** @@ -244,7 +244,7 @@ _os_mbuf_trailingspace(struct os_mbuf *om) #define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om) -#if SOC_ESP_NIMBLE_CONTROLLER +#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED /** * Initializes an mqueue. An mqueue is a queue of mbufs that ties to a * particular task's event queue. Mqueues form a helper API around a common diff --git a/components/bt/porting/nimble/include/os/os_mempool.h b/components/bt/porting/include/os/os_mempool.h similarity index 99% rename from components/bt/porting/nimble/include/os/os_mempool.h rename to components/bt/porting/include/os/os_mempool.h index 4daead13a6..3ef8e6d579 100644 --- a/components/bt/porting/nimble/include/os/os_mempool.h +++ b/components/bt/porting/include/os/os_mempool.h @@ -163,7 +163,7 @@ typedef __uint128_t os_membuf_t; #define OS_MEMPOOL_BYTES(n,blksize) \ (sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize))) -#if SOC_ESP_NIMBLE_CONTROLLER +#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED /** * Initialize a memory pool. * diff --git a/components/bt/porting/nimble/include/os/queue.h b/components/bt/porting/include/os/queue.h similarity index 81% rename from components/bt/porting/nimble/include/os/queue.h rename to components/bt/porting/include/os/queue.h index c184a394ed..868f9abfa4 100644 --- a/components/bt/porting/nimble/include/os/queue.h +++ b/components/bt/porting/include/os/queue.h @@ -1,33 +1,27 @@ /* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. + * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF) * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * SPDX-License-Identifier: Apache-2.0 * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.7 2002/04/17 14:21:02 des Exp $ + * 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. */ #ifndef _QUEUE_H_ diff --git a/components/bt/porting/nimble/include/os/util.h b/components/bt/porting/include/os/util.h similarity index 100% rename from components/bt/porting/nimble/include/os/util.h rename to components/bt/porting/include/os/util.h diff --git a/components/bt/porting/nimble/src/os_msys_init.c b/components/bt/porting/mem/os_msys_init.c similarity index 81% rename from components/bt/porting/nimble/src/os_msys_init.c rename to components/bt/porting/mem/os_msys_init.c index 523566cbf4..1a121e6d0b 100644 --- a/components/bt/porting/nimble/src/os_msys_init.c +++ b/components/bt/porting/mem/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 @@ -48,9 +59,12 @@ static STAILQ_HEAD(, os_mbuf_pool) g_msys_pool_list = #define SYSINIT_MSYS_1_MEMPOOL_SIZE \ OS_MEMPOOL_SIZE(OS_MSYS_1_BLOCK_COUNT, \ SYSINIT_MSYS_1_MEMBLOCK_SIZE) + +#if !CONFIG_BT_LE_MSYS_INIT_IN_CONTROLLER static os_membuf_t *os_msys_init_1_data; static struct os_mbuf_pool os_msys_init_1_mbuf_pool; static struct os_mempool os_msys_init_1_mempool; +#endif // !CONFIG_BT_LE_MSYS_INIT_IN_CONTROLLER #endif #if OS_MSYS_2_BLOCK_COUNT > 0 @@ -59,18 +73,33 @@ static struct os_mempool os_msys_init_1_mempool; #define SYSINIT_MSYS_2_MEMPOOL_SIZE \ OS_MEMPOOL_SIZE(OS_MSYS_2_BLOCK_COUNT, \ SYSINIT_MSYS_2_MEMBLOCK_SIZE) + +#if !CONFIG_BT_LE_MSYS_INIT_IN_CONTROLLER static os_membuf_t *os_msys_init_2_data; static struct os_mbuf_pool os_msys_init_2_mbuf_pool; static struct os_mempool os_msys_init_2_mempool; +#endif // !CONFIG_BT_LE_MSYS_INIT_IN_CONTROLLER #endif -#define OS_MSYS_SANITY_ENABLED \ - (OS_MSYS_1_SANITY_MIN_COUNT > 0 || \ - OS_MSYS_2_SANITY_MIN_COUNT > 0) +#if CONFIG_BT_LE_MSYS_INIT_IN_CONTROLLER +extern int r_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 r_esp_ble_msys_deinit(void); -#if OS_MSYS_SANITY_ENABLED -static struct os_sanity_check os_msys_sc; -#endif +int os_msys_init(void) +{ + return r_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_BLOCK_FROM_HEAP); +} + +void os_msys_deinit(void) +{ + r_esp_ble_msys_deinit(); +} + +#else // CONFIG_BT_LE_MSYS_INIT_IN_CONTROLLER #if OS_MSYS_SANITY_ENABLED @@ -208,3 +237,4 @@ void os_msys_init(void) SYSINIT_PANIC_ASSERT(rc == 0); #endif } +#endif // CONFIG_BT_LE_MSYS_INIT_IN_CONTROLLER diff --git a/components/bt/porting/nimble/include/nimble/ble.h b/components/bt/porting/nimble/include/nimble/ble.h deleted file mode 100644 index f037d3565b..0000000000 --- a/components/bt/porting/nimble/include/nimble/ble.h +++ /dev/null @@ -1,319 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF) - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -#ifndef H_BLE_ -#define H_BLE_ - -#include -#include -#include "syscfg/syscfg.h" -#include "os/os.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* The number of advertising instances */ -#define BLE_ADV_INSTANCES (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) + 1) - -/* BLE encryption block definitions */ -#define BLE_ENC_BLOCK_SIZE (16) - -/* 4 byte header + 251 byte payload. */ -#define BLE_ACL_MAX_PKT_SIZE 255 - -struct ble_encryption_block -{ - uint8_t key[BLE_ENC_BLOCK_SIZE]; - uint8_t plain_text[BLE_ENC_BLOCK_SIZE]; - uint8_t cipher_text[BLE_ENC_BLOCK_SIZE]; -}; - -/* - * BLE MBUF structure: - * - * The BLE mbuf structure is as follows. Note that this structure applies to - * the packet header mbuf (not mbufs that are part of a "packet chain"): - * struct os_mbuf (16) - * struct os_mbuf_pkthdr (8) - * struct ble_mbuf_hdr (8) - * Data buffer (payload size, in bytes) - * - * The BLE mbuf header contains the following: - * flags: bitfield with the following values - * 0x01: Set if there was a match on the whitelist - * 0x02: Set if a connect request was transmitted upon receiving pdu - * 0x04: Set the first time we transmit the PDU (used to detect retry). - * channel: The logical BLE channel PHY channel # (0 - 39) - * crcok: flag denoting CRC check passed (1) or failed (0). - * rssi: RSSI, in dBm. - */ -struct ble_mbuf_hdr_rxinfo -{ - uint16_t flags; - uint8_t channel; - uint8_t handle; - int8_t rssi; - /* XXX: we could just use single phy_mode field */ - int8_t phy; - uint8_t phy_mode; -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) - int8_t rpa_index; -#endif -#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) - void *user_data; -#endif -}; - -/* - * Flag definitions for rxinfo - * - * Note: it's ok to have symbols with the same values as long as they cannot be - * set for the same PDU (e.g. one use by scanner, other one used by - * connection) - */ -#define BLE_MBUF_HDR_F_CONN_CREDIT (0x8000) -#define BLE_MBUF_HDR_F_IGNORED (0x8000) -#define BLE_MBUF_HDR_F_SCAN_REQ_TXD (0x4000) -#define BLE_MBUF_HDR_F_INITA_RESOLVED (0x2000) -#define BLE_MBUF_HDR_F_TARGETA_RESOLVED (0x2000) -#define BLE_MBUF_HDR_F_EXT_ADV_SEC (0x1000) -#define BLE_MBUF_HDR_F_EXT_ADV (0x0800) -#define BLE_MBUF_HDR_F_RESOLVED (0x0400) -#define BLE_MBUF_HDR_F_AUX_PTR_WAIT (0x0200) -#define BLE_MBUF_HDR_F_AUX_INVALID (0x0100) -#define BLE_MBUF_HDR_F_CRC_OK (0x0080) -#define BLE_MBUF_HDR_F_DEVMATCH (0x0040) -#define BLE_MBUF_HDR_F_MIC_FAILURE (0x0020) -#define BLE_MBUF_HDR_F_SCAN_RSP_TXD (0x0010) -#define BLE_MBUF_HDR_F_SCAN_RSP_RXD (0x0008) -#define BLE_MBUF_HDR_F_RXSTATE_MASK (0x0007) - -/* Transmit info. NOTE: no flags defined */ -struct ble_mbuf_hdr_txinfo -{ - uint8_t flags; - uint8_t reserve0; - uint8_t pyld_len; - uint8_t hdr_byte; - uint16_t offset; -}; - -struct ble_mbuf_hdr -{ - union { - struct ble_mbuf_hdr_rxinfo rxinfo; - struct ble_mbuf_hdr_txinfo txinfo; - }; - uint32_t beg_cputime; - uint32_t rem_usecs; -}; - -#define BLE_MBUF_HDR_IGNORED(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_IGNORED)) - -#define BLE_MBUF_HDR_SCAN_REQ_TXD(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_REQ_TXD)) - -#define BLE_MBUF_HDR_EXT_ADV_SEC(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_EXT_ADV_SEC)) - -#define BLE_MBUF_HDR_EXT_ADV(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_EXT_ADV)) - -#define BLE_MBUF_HDR_DEVMATCH(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_DEVMATCH)) - -#define BLE_MBUF_HDR_SCAN_RSP_RXD(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_SCAN_RSP_RXD)) - -#define BLE_MBUF_HDR_AUX_INVALID(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_AUX_INVALID)) - -#define BLE_MBUF_HDR_WAIT_AUX(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_AUX_PTR_WAIT)) - -#define BLE_MBUF_HDR_CRC_OK(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_CRC_OK)) - -#define BLE_MBUF_HDR_MIC_FAILURE(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_MIC_FAILURE)) - -#define BLE_MBUF_HDR_RESOLVED(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_RESOLVED)) - -#define BLE_MBUF_HDR_INITA_RESOLVED(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_INITA_RESOLVED)) - -#define BLE_MBUF_HDR_TARGETA_RESOLVED(hdr) \ - (!!((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_TARGETA_RESOLVED)) - -#define BLE_MBUF_HDR_RX_STATE(hdr) \ - ((uint8_t)((hdr)->rxinfo.flags & BLE_MBUF_HDR_F_RXSTATE_MASK)) - -#define BLE_MBUF_HDR_PTR(om) \ - (struct ble_mbuf_hdr *)((uint8_t *)om + sizeof(struct os_mbuf) + \ - sizeof(struct os_mbuf_pkthdr)) - -/* BLE mbuf overhead per packet header mbuf */ -#define BLE_MBUF_PKTHDR_OVERHEAD \ - (sizeof(struct os_mbuf_pkthdr) + sizeof(struct ble_mbuf_hdr)) - -#define BLE_MBUF_MEMBLOCK_OVERHEAD \ - (sizeof(struct os_mbuf) + BLE_MBUF_PKTHDR_OVERHEAD) - -/* Length of host user header. Only contains the peer's connection handle. */ -#define BLE_MBUF_HS_HDR_LEN (2) - -#define BLE_DEV_ADDR_LEN (6) -extern uint8_t g_dev_addr[BLE_DEV_ADDR_LEN]; -extern uint8_t g_random_addr[BLE_DEV_ADDR_LEN]; - -/* BLE Error Codes (Core v4.2 Vol 2 part D) */ -enum ble_error_codes -{ - /* An "error" code of 0x0 means success */ - BLE_ERR_SUCCESS = 0x00, - BLE_ERR_UNKNOWN_HCI_CMD = 0x01, - BLE_ERR_UNK_CONN_ID = 0x02, - BLE_ERR_HW_FAIL = 0x03, - BLE_ERR_PAGE_TMO = 0x04, - BLE_ERR_AUTH_FAIL = 0x05, - BLE_ERR_PINKEY_MISSING = 0x06, - BLE_ERR_MEM_CAPACITY = 0x07, - BLE_ERR_CONN_SPVN_TMO = 0x08, - BLE_ERR_CONN_LIMIT = 0x09, - BLE_ERR_SYNCH_CONN_LIMIT = 0x0a, - BLE_ERR_ACL_CONN_EXISTS = 0x0b, - BLE_ERR_CMD_DISALLOWED = 0x0c, - BLE_ERR_CONN_REJ_RESOURCES = 0x0d, - BLE_ERR_CONN_REJ_SECURITY = 0x0e, - BLE_ERR_CONN_REJ_BD_ADDR = 0x0f, - BLE_ERR_CONN_ACCEPT_TMO = 0x10, - BLE_ERR_UNSUPPORTED = 0x11, - BLE_ERR_INV_HCI_CMD_PARMS = 0x12, - BLE_ERR_REM_USER_CONN_TERM = 0x13, - BLE_ERR_RD_CONN_TERM_RESRCS = 0x14, - BLE_ERR_RD_CONN_TERM_PWROFF = 0x15, - BLE_ERR_CONN_TERM_LOCAL = 0x16, - BLE_ERR_REPEATED_ATTEMPTS = 0x17, - BLE_ERR_NO_PAIRING = 0x18, - BLE_ERR_UNK_LMP = 0x19, - BLE_ERR_UNSUPP_REM_FEATURE = 0x1a, - BLE_ERR_SCO_OFFSET = 0x1b, - BLE_ERR_SCO_ITVL = 0x1c, - BLE_ERR_SCO_AIR_MODE = 0x1d, - BLE_ERR_INV_LMP_LL_PARM = 0x1e, - BLE_ERR_UNSPECIFIED = 0x1f, - BLE_ERR_UNSUPP_LMP_LL_PARM = 0x20, - BLE_ERR_NO_ROLE_CHANGE = 0x21, - BLE_ERR_LMP_LL_RSP_TMO = 0x22, - BLE_ERR_LMP_COLLISION = 0x23, - BLE_ERR_LMP_PDU = 0x24, - BLE_ERR_ENCRYPTION_MODE = 0x25, - BLE_ERR_LINK_KEY_CHANGE = 0x26, - BLE_ERR_UNSUPP_QOS = 0x27, - BLE_ERR_INSTANT_PASSED = 0x28, - BLE_ERR_UNIT_KEY_PAIRING = 0x29, - BLE_ERR_DIFF_TRANS_COLL = 0x2a, - /* BLE_ERR_RESERVED = 0x2b */ - BLE_ERR_QOS_PARM = 0x2c, - BLE_ERR_QOS_REJECTED = 0x2d, - BLE_ERR_CHAN_CLASS = 0x2e, - BLE_ERR_INSUFFICIENT_SEC = 0x2f, - BLE_ERR_PARM_OUT_OF_RANGE = 0x30, - /* BLE_ERR_RESERVED = 0x31 */ - BLE_ERR_PENDING_ROLE_SW = 0x32, - /* BLE_ERR_RESERVED = 0x33 */ - BLE_ERR_RESERVED_SLOT = 0x34, - BLE_ERR_ROLE_SW_FAIL = 0x35, - BLE_ERR_INQ_RSP_TOO_BIG = 0x36, - BLE_ERR_SEC_SIMPLE_PAIR = 0x37, - BLE_ERR_HOST_BUSY_PAIR = 0x38, - BLE_ERR_CONN_REJ_CHANNEL = 0x39, - BLE_ERR_CTLR_BUSY = 0x3a, - BLE_ERR_CONN_PARMS = 0x3b, - BLE_ERR_DIR_ADV_TMO = 0x3c, - BLE_ERR_CONN_TERM_MIC = 0x3d, - BLE_ERR_CONN_ESTABLISHMENT = 0x3e, - BLE_ERR_MAC_CONN_FAIL = 0x3f, - BLE_ERR_COARSE_CLK_ADJ = 0x40, - BLE_ERR_TYPE0_SUBMAP_NDEF = 0x41, - BLE_ERR_UNK_ADV_INDENT = 0x42, - BLE_ERR_LIMIT_REACHED = 0x43, - BLE_ERR_OPERATION_CANCELLED = 0x44, - BLE_ERR_PACKET_TOO_LONG = 0x45, - BLE_ERR_MAX = 0xff -}; - -/* HW error codes */ -#define BLE_HW_ERR_DO_NOT_USE (0) /* XXX: reserve this one for now */ -#define BLE_HW_ERR_HCI_SYNC_LOSS (1) - -/* Own Bluetooth Device address type */ -#define BLE_OWN_ADDR_PUBLIC (0x00) -#define BLE_OWN_ADDR_RANDOM (0x01) -#define BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT (0x02) -#define BLE_OWN_ADDR_RPA_RANDOM_DEFAULT (0x03) - -/* Bluetooth Device address type */ -#define BLE_ADDR_PUBLIC (0x00) -#define BLE_ADDR_RANDOM (0x01) -#define BLE_ADDR_PUBLIC_ID (0x02) -#define BLE_ADDR_RANDOM_ID (0x03) - -#define BLE_ADDR_ANY (&(ble_addr_t) { 0, {0, 0, 0, 0, 0, 0} }) - -#define BLE_ADDR_IS_RPA(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ - ((addr)->val[5] & 0xc0) == 0x40) -#define BLE_ADDR_IS_NRPA(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ - ((addr)->val[5] & 0xc0) == 0x00) -#define BLE_ADDR_IS_STATIC(addr) (((addr)->type == BLE_ADDR_RANDOM) && \ - ((addr)->val[5] & 0xc0) == 0xc0) - -typedef struct { - uint8_t type; - uint8_t val[6]; -} ble_addr_t; - - -static inline int ble_addr_cmp(const ble_addr_t *a, const ble_addr_t *b) -{ - int type_diff; - - type_diff = a->type - b->type; - if (type_diff != 0) { - return type_diff; - } - - return memcmp(a->val, b->val, sizeof(a->val)); -} - -#ifdef __cplusplus -} -#endif - -#endif /* H_BLE_ */ diff --git a/components/bt/porting/nimble/include/nimble/hci_common.h b/components/bt/porting/nimble/include/nimble/hci_common.h deleted file mode 100644 index cb743efac1..0000000000 --- a/components/bt/porting/nimble/include/nimble/hci_common.h +++ /dev/null @@ -1,1993 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF) - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -#ifndef H_BLE_HCI_COMMON_ -#define H_BLE_HCI_COMMON_ - -#include "ble.h" -#include "nimble/transport.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define BLE_HCI_MAX_DATA_LEN (MYNEWT_VAL(BLE_TRANSPORT_EVT_SIZE) - \ - sizeof(struct ble_hci_ev)) - -/* Generic command header */ -struct ble_hci_cmd { - uint16_t opcode; - uint8_t length; - uint8_t data[0]; -} __attribute__((packed)); - -/* Generic event header */ -struct ble_hci_ev { - uint8_t opcode; - uint8_t length; - uint8_t data[0]; -} __attribute__((packed)); - -#define BLE_HCI_OPCODE_NOP (0) - -/* Set opcode based on OCF and OGF */ -#define BLE_HCI_OP(ogf, ocf) ((ocf) | ((ogf) << 10)) - -/* Get the OGF and OCF from the opcode in the command */ -#define BLE_HCI_OGF(opcode) (((opcode) >> 10) & 0x003F) -#define BLE_HCI_OCF(opcode) ((opcode) & 0x03FF) - -/* Opcode Group definitions (note: 0x07 not defined in spec) */ -#define BLE_HCI_OGF_LINK_CTRL (0x01) -#define BLE_HCI_OGF_LINK_POLICY (0x02) -#define BLE_HCI_OGF_CTLR_BASEBAND (0x03) -#define BLE_HCI_OGF_INFO_PARAMS (0x04) -#define BLE_HCI_OGF_STATUS_PARAMS (0x05) -#define BLE_HCI_OGF_TESTING (0x06) -#define BLE_HCI_OGF_LE (0x08) -#define BLE_HCI_OGF_VENDOR (0x3F) - -/* - * Number of LE commands. NOTE: this is really just used to size the array - * containing the lengths of the LE commands. - */ -#define BLE_HCI_NUM_LE_CMDS (79) - -/* List of OCF for Link Control commands (OGF=0x01) */ -#define BLE_HCI_OCF_DISCONNECT_CMD (0x0006) -struct ble_hci_lc_disconnect_cp { - uint16_t conn_handle; - uint8_t reason; -} __attribute__((packed)); - -#define BLE_HCI_OCF_RD_REM_VER_INFO (0x001D) -struct ble_hci_rd_rem_ver_info_cp { - uint16_t conn_handle; -} __attribute__((packed)); - -/* List of OCF for Controller and Baseband commands (OGF=0x03) */ -#define BLE_HCI_OCF_CB_SET_EVENT_MASK (0x0001) -struct ble_hci_cb_set_event_mask_cp { - uint64_t event_mask; -} __attribute__((packed)); - -#define BLE_HCI_OCF_CB_RESET (0x0003) - -#define BLE_HCI_OCF_CB_READ_TX_PWR (0x002D) -struct ble_hci_cb_read_tx_pwr_cp { - uint16_t conn_handle; - uint8_t type; -} __attribute__((packed)); - -struct ble_hci_cb_read_tx_pwr_rp { - uint16_t conn_handle; - int8_t tx_level; -} __attribute__((packed)); - - -#define BLE_HCI_OCF_CB_SET_CTLR_TO_HOST_FC (0x0031) -struct ble_hci_cb_ctlr_to_host_fc_cp { - uint8_t enable; -} __attribute__((packed)); - -#define BLE_HCI_OCF_CB_HOST_BUF_SIZE (0x0033) -struct ble_hci_cb_host_buf_size_cp { - uint16_t acl_data_len; - uint8_t sco_data_len; - uint16_t acl_num; - uint16_t sco_num; -} __attribute__((packed)); - -#define BLE_HCI_OCF_CB_HOST_NUM_COMP_PKTS (0x0035) -struct ble_hci_cb_host_num_comp_pkts_entry { - uint16_t handle; - uint16_t count; -} __attribute__((packed)); -struct ble_hci_cb_host_num_comp_pkts_cp { - uint8_t handles; - struct ble_hci_cb_host_num_comp_pkts_entry h[0]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_CB_SET_EVENT_MASK2 (0x0063) -struct ble_hci_cb_set_event_mask2_cp { - uint64_t event_mask2; -} __attribute__((packed)); - -#define BLE_HCI_OCF_CB_RD_AUTH_PYLD_TMO (0x007B) -struct ble_hci_cb_rd_auth_pyld_tmo_cp { - uint16_t conn_handle; -} __attribute__((packed)); -struct ble_hci_cb_rd_auth_pyld_tmo_rp { - uint16_t conn_handle; - uint16_t tmo; -} __attribute__((packed)); - -#define BLE_HCI_OCF_CB_WR_AUTH_PYLD_TMO (0x007C) -struct ble_hci_cb_wr_auth_pyld_tmo_cp { - uint16_t conn_handle; - uint16_t tmo; -} __attribute__((packed)); -struct ble_hci_cb_wr_auth_pyld_tmo_rp { - uint16_t conn_handle; -} __attribute__((packed)); - -/* List of OCF for Info Param commands (OGF=0x04) */ -#define BLE_HCI_OCF_IP_RD_LOCAL_VER (0x0001) -struct ble_hci_ip_rd_local_ver_rp { - uint8_t hci_ver; - uint16_t hci_rev; - uint8_t lmp_ver; - uint16_t manufacturer; - uint16_t lmp_subver; -} __attribute__((packed)); - -#define BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD (0x0002) -struct ble_hci_ip_rd_loc_supp_cmd_rp { - uint8_t commands[64]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT (0x0003) -struct ble_hci_ip_rd_loc_supp_feat_rp { - uint64_t features; -} __attribute__((packed)); - -#define BLE_HCI_OCF_IP_RD_BUF_SIZE (0x0005) -struct ble_hci_ip_rd_buf_size_rp { - uint16_t acl_data_len; - uint8_t sco_data_len; - uint16_t acl_num; - uint16_t sco_num; -} __attribute__((packed)); - -#define BLE_HCI_OCF_IP_RD_BD_ADDR (0x0009) -struct ble_hci_ip_rd_bd_addr_rp { - uint8_t addr[6]; -} __attribute__((packed)); - -/* List of OCF for Status parameters commands (OGF = 0x05) */ -#define BLE_HCI_OCF_RD_RSSI (0x0005) -struct ble_hci_rd_rssi_cp { - uint16_t handle; -} __attribute__((packed)); -struct ble_hci_rd_rssi_rp { - uint16_t handle; - int8_t rssi; -} __attribute__((packed)); - -/* List of OCF for LE commands (OGF = 0x08) */ -#define BLE_HCI_OCF_LE_SET_EVENT_MASK (0x0001) -struct ble_hci_le_set_event_mask_cp { - uint64_t event_mask; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_BUF_SIZE (0x0002) -struct ble_hci_le_rd_buf_size_rp { - uint16_t data_len; - uint8_t data_packets; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_BUF_SIZE_V2 (0x0060) -struct ble_hci_le_rd_buf_size_v2_rp { - uint16_t data_len; - uint8_t data_packets; - uint16_t iso_data_len; - uint8_t iso_data_packets; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT (0x0003) -struct ble_hci_le_rd_loc_supp_feat_rp { - uint64_t features; -} __attribute__((packed)); - -/* NOTE: 0x0004 is intentionally left undefined */ -#define BLE_HCI_OCF_LE_SET_RAND_ADDR (0x0005) -struct ble_hci_le_set_rand_addr_cp { - uint8_t addr[6]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_ADV_PARAMS (0x0006) -struct ble_hci_le_set_adv_params_cp { - uint16_t min_interval; - uint16_t max_interval; - uint8_t type; - uint8_t own_addr_type; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint8_t chan_map; - uint8_t filter_policy; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR (0x0007) -struct ble_hci_le_rd_adv_chan_txpwr_rp { - int8_t power_level; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_ADV_DATA (0x0008) -#define BLE_HCI_MAX_ADV_DATA_LEN (31) -struct ble_hci_le_set_adv_data_cp { - uint8_t adv_data_len; - uint8_t adv_data[BLE_HCI_MAX_ADV_DATA_LEN]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA (0x0009) -#define BLE_HCI_MAX_SCAN_RSP_DATA_LEN (31) -struct ble_hci_le_set_scan_rsp_data_cp { - uint8_t scan_rsp_len; - uint8_t scan_rsp[BLE_HCI_MAX_SCAN_RSP_DATA_LEN]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_ADV_ENABLE (0x000A) -struct ble_hci_le_set_adv_enable_cp { - uint8_t enable; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_SCAN_PARAMS (0x000B) -struct ble_hci_le_set_scan_params_cp { - uint8_t scan_type; - uint16_t scan_itvl; - uint16_t scan_window; - uint8_t own_addr_type; - uint8_t filter_policy; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_SCAN_ENABLE (0x000C) -struct ble_hci_le_set_scan_enable_cp { - uint8_t enable; - uint8_t filter_duplicates; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_CREATE_CONN (0x000D) -struct ble_hci_le_create_conn_cp { - uint16_t scan_itvl; - uint16_t scan_window; - uint8_t filter_policy; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint8_t own_addr_type; - uint16_t min_conn_itvl; - uint16_t max_conn_itvl; - uint16_t conn_latency; - uint16_t tmo; - uint16_t min_ce; - uint16_t max_ce; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_CREATE_CONN_CANCEL (0x000E) - -#define BLE_HCI_OCF_LE_RD_WHITE_LIST_SIZE (0x000F) -struct ble_hci_le_rd_white_list_rp { - uint8_t size; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_CLEAR_WHITE_LIST (0x0010) - -#define BLE_HCI_OCF_LE_ADD_WHITE_LIST (0x0011) -struct ble_hci_le_add_whte_list_cp { - uint8_t addr_type; - uint8_t addr[6]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RMV_WHITE_LIST (0x0012) -struct ble_hci_le_rmv_white_list_cp { - uint8_t addr_type; - uint8_t addr[6]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_CONN_UPDATE (0x0013) -struct ble_hci_le_conn_update_cp { - uint16_t conn_handle; - uint16_t conn_itvl_min; - uint16_t conn_itvl_max; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_ce_len; - uint16_t max_ce_len; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS (0x0014) -struct ble_hci_le_set_host_chan_class_cp { - uint8_t chan_map[5]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_CHAN_MAP (0x0015) -struct ble_hci_le_rd_chan_map_cp { - uint16_t conn_handle; -} __attribute__((packed)); -struct ble_hci_le_rd_chan_map_rp { - uint16_t conn_handle; - uint8_t chan_map[5]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_REM_FEAT (0x0016) -struct ble_hci_le_rd_rem_feat_cp { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_ENCRYPT (0x0017) -struct ble_hci_le_encrypt_cp { - uint8_t key[16]; - uint8_t data[16]; -} __attribute__((packed)); -struct ble_hci_le_encrypt_rp { - uint8_t data[16]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RAND (0x0018) -struct ble_hci_le_rand_rp { - uint64_t random_number; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_START_ENCRYPT (0x0019) -struct ble_hci_le_start_encrypt_cp { - uint16_t conn_handle; - uint64_t rand; - uint16_t div; - uint8_t ltk[16]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY (0x001A) -struct ble_hci_le_lt_key_req_reply_cp { - uint16_t conn_handle; - uint8_t ltk[16]; -} __attribute__((packed)); -struct ble_hci_le_lt_key_req_reply_rp { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY (0x001B) -struct ble_hci_le_lt_key_req_neg_reply_cp { - uint16_t conn_handle; -} __attribute__((packed)); -struct ble_hci_le_lt_key_req_neg_reply_rp { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_SUPP_STATES (0x001C) -struct ble_hci_le_rd_supp_states_rp { - uint64_t states; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RX_TEST (0x001D) -struct ble_hci_le_rx_test_cp { - uint8_t rx_chan; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_TX_TEST (0x001E) -struct ble_hci_le_tx_test_cp { - uint8_t tx_chan; - uint8_t test_data_len; - uint8_t payload; -} __attribute__((packed)); -#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) -struct ble_hci_le_tx_test_ext_cp { - uint8_t tx_chan; - uint8_t test_data_len; - uint8_t payload; - uint16_t interval; - uint16_t pkt_count; -} __attribute__((packed)); -#endif - -#define BLE_HCI_OCF_LE_TEST_END (0x001F) -struct ble_hci_le_test_end_rp { - uint16_t num_packets; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_REM_CONN_PARAM_RR (0x0020) -struct ble_hci_le_rem_conn_param_rr_cp { - uint16_t conn_handle; - uint16_t conn_itvl_min; - uint16_t conn_itvl_max; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_ce; - uint16_t max_ce; -} __attribute__((packed)); -struct ble_hci_le_rem_conn_param_rr_rp { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR (0x0021) -struct ble_hci_le_rem_conn_params_nrr_cp { - uint16_t conn_handle; - uint8_t reason; -} __attribute__((packed)); -struct ble_hci_le_rem_conn_params_nrr_rp { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_DATA_LEN (0x0022) -struct ble_hci_le_set_data_len_cp { - uint16_t conn_handle; - uint16_t tx_octets; - uint16_t tx_time; -} __attribute__((packed)); -struct ble_hci_le_set_data_len_rp { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_SUGG_DEF_DATA_LEN (0x0023) -struct ble_hci_le_rd_sugg_def_data_len_rp { - uint16_t max_tx_octets; - uint16_t max_tx_time; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_WR_SUGG_DEF_DATA_LEN (0x0024) -struct ble_hci_le_wr_sugg_def_data_len_cp { - uint16_t max_tx_octets; - uint16_t max_tx_time; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_P256_PUBKEY (0x0025) - -#define BLE_HCI_OCF_LE_GEN_DHKEY (0x0026) -struct ble_hci_le_gen_dhkey_cp { - uint8_t pkey[64]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_ADD_RESOLV_LIST (0x0027) -struct ble_hci_le_add_resolv_list_cp { - uint8_t peer_addr_type; - uint8_t peer_id_addr[6]; - uint8_t peer_irk[16]; - uint8_t local_irk[16]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RMV_RESOLV_LIST (0x0028) -struct ble_hci_le_rmv_resolve_list_cp { - uint8_t peer_addr_type; - uint8_t peer_id_addr[6]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_CLR_RESOLV_LIST (0x0029) - -#define BLE_HCI_OCF_LE_RD_RESOLV_LIST_SIZE (0x002A) -struct ble_hci_le_rd_resolv_list_size_rp { - uint8_t size; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_PEER_RESOLV_ADDR (0x002B) -struct ble_hci_le_rd_peer_resolv_addr_cp { - uint8_t peer_addr_type; - uint8_t peer_id_addr[6]; -} __attribute__((packed)); -struct ble_hci_le_rd_peer_resolv_addr_rp { - uint8_t rpa[6]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_LOCAL_RESOLV_ADDR (0x002C) -struct ble_hci_le_rd_local_resolv_addr_cp { - uint8_t peer_addr_type; - uint8_t peer_id_addr[6]; -} __attribute__((packed)); -struct ble_hci_le_rd_local_resolv_addr_rp { - uint8_t rpa[6]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_ADDR_RES_EN (0x002D) -struct ble_hci_le_set_addr_res_en_cp { - uint8_t enable; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_RPA_TMO (0x002E) -struct ble_hci_le_set_rpa_tmo_cp { - uint16_t rpa_timeout; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_MAX_DATA_LEN (0x002F) -struct ble_hci_le_rd_max_data_len_rp { - uint16_t max_tx_octests; - uint16_t max_tx_time; - uint16_t max_rx_octests; - uint16_t max_rx_time; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_PHY (0x0030) -struct ble_hci_le_rd_phy_cp { - uint16_t conn_handle; -} __attribute__((packed)); -struct ble_hci_le_rd_phy_rp { - uint16_t conn_handle; - uint8_t tx_phy; - uint8_t rx_phy; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_DEFAULT_PHY (0x0031) -struct ble_hci_le_set_default_phy_cp { - uint8_t all_phys; - uint8_t tx_phys; - uint8_t rx_phys; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_PHY (0x0032) -struct ble_hci_le_set_phy_cp { - uint16_t conn_handle; - uint8_t all_phys; - uint8_t tx_phys; - uint8_t rx_phys; - uint16_t phy_options; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RX_TEST_V2 (0x0033) -struct ble_hci_le_rx_test_v2_cp { - uint8_t rx_chan; - uint8_t phy; - uint8_t index; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_TX_TEST_V2 (0x0034) -struct ble_hci_le_tx_test_v2_cp { - uint8_t tx_chan; - uint8_t test_data_len; - uint8_t payload; - uint8_t phy; -} __attribute__((packed)); -#if MYNEWT_VAL(BLE_LL_DTM_EXTENSIONS) -struct ble_hci_le_tx_test_v2_ext_cp { - uint8_t tx_chan; - uint8_t test_data_len; - uint8_t payload; - uint8_t phy; - uint16_t interval; - uint16_t pkt_count; -} __attribute__((packed)); -#endif - -#define BLE_HCI_OCF_LE_SET_ADV_SET_RND_ADDR (0x0035) -struct ble_hci_le_set_adv_set_rnd_addr_cp { - uint8_t adv_handle; - uint8_t addr[6]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM (0x0036) -struct ble_hci_le_set_ext_adv_params_cp { - uint8_t adv_handle; - uint16_t props; - uint8_t pri_itvl_min[3]; - uint8_t pri_itvl_max[3]; - uint8_t pri_chan_map; - uint8_t own_addr_type; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint8_t filter_policy; - int8_t tx_power; - uint8_t pri_phy; - uint8_t sec_max_skip; - uint8_t sec_phy; - uint8_t sid; - uint8_t scan_req_notif; -} __attribute__((packed)); -struct ble_hci_le_set_ext_adv_params_rp { - int8_t tx_power; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_EXT_ADV_DATA (0x0037) -struct ble_hci_le_set_ext_adv_data_cp { - uint8_t adv_handle; - uint8_t operation; - uint8_t fragment_pref; - uint8_t adv_data_len; - uint8_t adv_data[0]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_EXT_SCAN_RSP_DATA (0x0038) -struct ble_hci_le_set_ext_scan_rsp_data_cp { - uint8_t adv_handle; - uint8_t operation; - uint8_t fragment_pref; - uint8_t scan_rsp_len; - uint8_t scan_rsp[0]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_EXT_ADV_ENABLE (0x0039) -struct adv_set { - uint8_t adv_handle; - uint16_t duration; - uint8_t max_events; -} __attribute__((packed)); -struct ble_hci_le_set_ext_adv_enable_cp { - uint8_t enable; - uint8_t num_sets; - struct adv_set sets[0]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_MAX_ADV_DATA_LEN (0x003A) -struct ble_hci_le_rd_max_adv_data_len_rp { - uint16_t max_adv_data_len; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_NUM_OF_ADV_SETS (0x003B) -struct ble_hci_le_rd_num_of_adv_sets_rp { - uint8_t num_sets; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_REMOVE_ADV_SET (0x003C) -struct ble_hci_le_remove_adv_set_cp { - uint8_t adv_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_CLEAR_ADV_SETS (0x003D) - -#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_PARAMS (0x003E) -struct ble_hci_le_set_periodic_adv_params_cp { - uint8_t adv_handle; - uint16_t min_itvl; - uint16_t max_itvl; - uint16_t props; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_DATA (0x003F) -struct ble_hci_le_set_periodic_adv_data_cp { - uint8_t adv_handle; - uint8_t operation; - uint8_t adv_data_len; - uint8_t adv_data[0]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_PERIODIC_ADV_ENABLE (0x0040) -struct ble_hci_le_set_periodic_adv_enable_cp { - uint8_t enable; - uint8_t adv_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM (0x0041) -struct scan_params { - uint8_t type; - uint16_t itvl; - uint16_t window; -} __attribute__((packed)); -struct ble_hci_le_set_ext_scan_params_cp { - uint8_t own_addr_type; - uint8_t filter_policy; - uint8_t phys; - struct scan_params scans[0]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE (0x0042) -struct ble_hci_le_set_ext_scan_enable_cp { - uint8_t enable; - uint8_t filter_dup; - uint16_t duration; - uint16_t period; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_EXT_CREATE_CONN (0x0043) -struct conn_params { - uint16_t scan_itvl; - uint16_t scan_window; - uint16_t conn_min_itvl; - uint16_t conn_max_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_ce; - uint16_t max_ce; -} __attribute__((packed)); -struct ble_hci_le_ext_create_conn_cp { - uint8_t filter_policy; - uint8_t own_addr_type; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint8_t init_phy_mask; - struct conn_params conn_params[0]; -} __attribute__((packed)); - -#define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_FILTER 0x01 -#define BLE_HCI_LE_PERIODIC_ADV_CREATE_SYNC_OPT_DISABLED 0x02 - -#define BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC (0x0044) -struct ble_hci_le_periodic_adv_create_sync_cp { - uint8_t options; - uint8_t sid; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint16_t skip; - uint16_t sync_timeout; - uint8_t sync_cte_type; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL (0x0045) - -#define BLE_HCI_OCF_LE_PERIODIC_ADV_TERM_SYNC (0x0046) -struct ble_hci_le_periodic_adv_term_sync_cp { - uint16_t sync_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_ADD_DEV_TO_PERIODIC_ADV_LIST (0x0047) -struct ble_hci_le_add_dev_to_periodic_adv_list_cp { - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint8_t sid; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_REM_DEV_FROM_PERIODIC_ADV_LIST (0x0048) -struct ble_hci_le_rem_dev_from_periodic_adv_list_cp { - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint8_t sid; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_CLEAR_PERIODIC_ADV_LIST (0x0049) - -#define BLE_HCI_OCF_LE_RD_PERIODIC_ADV_LIST_SIZE (0x004A) -struct ble_hci_le_rd_periodic_adv_list_size_rp { - uint8_t list_size; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_TRANSMIT_POWER (0x004B) -struct ble_hci_le_rd_transmit_power_rp { - int8_t min_tx_power; - int8_t max_tx_power; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RD_RF_PATH_COMPENSATION (0x004C) -struct ble_hci_le_rd_rf_path_compensation_rp { - int16_t tx_path_compensation; - int16_t rx_path_compensation; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_WR_RF_PATH_COMPENSATION (0x004D) -struct ble_hci_le_wr_rf_path_compensation_cp { - int16_t tx_path_compensation; - int16_t rx_path_compensation; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_PRIVACY_MODE (0x004E) -struct ble_hci_le_set_privacy_mode_cp { - uint8_t peer_id_addr_type; - uint8_t peer_id_addr[6]; - uint8_t mode; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_RX_TEST_V3 (0x004F) -#define BLE_HCI_OCF_LE_TX_TEST_V3 (0x0050) -#define BLE_HCI_OCF_LE_SET_CONNLESS_CTE_TX_PARAMS (0x0051) -#define BLE_HCI_OCF_LE_SET_CONNLESS_CTE_TX_ENABLE (0x0052) -#define BLE_HCI_OCF_LE_SET_CONNLESS_IQ_SAMPLING_ENABLE (0x0053) -#define BLE_HCI_OCF_LE_SET_CONN_CTE_RX_PARAMS (0x0054) -#define BLE_HCI_OCF_LE_SET_CONN_CTE_TX_PARAMS (0x0055) -#define BLE_HCI_OCF_LE_SET_CONN_CTE_REQ_ENABLE (0x0056) -#define BLE_HCI_OCF_LE_SET_CONN_CTE_RESP_ENABLE (0x0057) -#define BLE_HCI_OCF_LE_RD_ANTENNA_INFO (0x0058) - -#define BLE_HCI_OCF_LE_PERIODIC_ADV_RECEIVE_ENABLE (0x0059) -struct ble_hci_le_periodic_adv_receive_enable_cp { - uint16_t sync_handle; - uint8_t enable; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER (0x005A) -struct ble_hci_le_periodic_adv_sync_transfer_cp { - uint16_t conn_handle; - uint16_t service_data; - uint16_t sync_handle; -} __attribute__((packed)); -struct ble_hci_le_periodic_adv_sync_transfer_rp { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_PERIODIC_ADV_SET_INFO_TRANSFER (0x005B) -struct ble_hci_le_periodic_adv_set_info_transfer_cp { - uint16_t conn_handle; - uint16_t service_data; - uint8_t adv_handle; -} __attribute__((packed)); -struct ble_hci_le_periodic_adv_set_info_transfer_rp { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_PERIODIC_ADV_SYNC_TRANSFER_PARAMS (0x005C) -struct ble_hci_le_periodic_adv_sync_transfer_params_cp { - uint16_t conn_handle; - uint8_t mode; - uint16_t skip; - uint16_t sync_timeout; - uint8_t sync_cte_type; -} __attribute__((packed)); -struct ble_hci_le_periodic_adv_sync_transfer_params_rp { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_DEFAULT_SYNC_TRANSFER_PARAMS (0x005D) -struct ble_hci_le_set_default_periodic_sync_transfer_params_cp { - uint8_t mode; - uint16_t skip; - uint16_t sync_timeout; - uint8_t sync_cte_type; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_GENERATE_DHKEY_V2 (0x005E) -#define BLE_HCI_OCF_LE_MODIFY_SCA (0x005F) - -#if MYNEWT_VAL(BLE_ISO) -#define BLE_HCI_OCF_LE_READ_ISO_TX_SYNC (0x0061) -struct ble_hci_le_read_iso_tx_sync_cp { - uint16_t conn_handle; -} __attribute__((packed)); - -struct ble_hci_le_read_iso_tx_sync_rp { - uint16_t conn_handle; - uint16_t packet_seq_num; - uint32_t timestamp; - uint8_t timeoffset[3]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SET_CIG_CIS_MAX_NUM (0x1F) -#define BLE_HCI_OCF_LE_SET_CIG_PARAM (0x0062) -struct ble_hci_le_cis_params { - uint8_t cis_id; - uint16_t max_sdu_mtos; - uint16_t max_sdu_stom; - uint8_t phy_mtos; - uint8_t phy_stom; - uint8_t rnt_mtos; - uint8_t rnt_stom; -} __attribute__((packed)); - -struct ble_hci_le_set_cig_params_cp { - uint8_t cig_id; - uint8_t sdu_interval_mtos[3]; - uint8_t sdu_interval_stom[3]; - uint8_t sca; - uint8_t packing; - uint8_t framing; - uint16_t max_latency_mtos; - uint16_t max_latency_stom; - uint8_t cis_cnt; - struct ble_hci_le_cis_params cis_params[0]; -} __attribute__((packed)); - -struct ble_hci_le_set_cig_params_rp { - uint8_t cig_id; - uint8_t cis_cnt; - uint16_t cis_handle[0]; -} __attribute__((packed)); - -#if MYNEWT_VAL(BLE_ISO_TEST) -#define BLE_HCI_OCF_LE_SET_CIG_PARAM_TEST (0x0063) -struct ble_hci_le_cis_params_test { - uint8_t cis_id; - uint8_t nse; - uint16_t max_sdu_mtos; - uint16_t max_sdu_stom; - uint16_t max_pdu_mtos; - uint16_t max_pdu_stom; - uint8_t phy_mtos; - uint8_t phy_stom; - uint8_t bn_mtos; - uint8_t bn_stom; -} __attribute__((packed)); - -struct ble_hci_le_set_cig_params_test_cp { - uint8_t cig_id; - uint8_t sdu_interval_mtos[3]; - uint8_t sdu_interval_stom[3]; - uint8_t ft_mtos; - uint8_t ft_stom; - uint16_t iso_interval; - uint8_t sca; - uint8_t packing; - uint8_t framing; - uint8_t cis_cnt; - struct ble_hci_le_cis_params_test cis_params[0]; -} __attribute__((packed)); -#endif - -#define BLE_HCI_LE_CREATE_CIS_MAX_CIS_NUM (0x1F) -#define BLE_HCI_OCF_LE_CREATE_CIS (0x0064) -struct ble_hci_le_create_cis_params { - uint16_t cis_handle; - uint16_t conn_handle; -} __attribute__((packed)); - -struct ble_hci_le_create_cis_cp { - uint8_t cis_cnt; - struct ble_hci_le_create_cis_params params[0]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_REMOVE_CIG (0x0065) -struct ble_hci_le_remove_cig_cp { - uint8_t cig_id; -} __attribute__((packed)); - -struct ble_hci_le_remove_cig_rp { - uint8_t cig_id; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_ACCEPT_CIS_REQ (0x0066) -struct ble_hci_le_accept_cis_request_cp { - uint16_t cis_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_REJECT_CIS_REQ (0x0067) -struct ble_hci_le_reject_cis_request_cp { - uint16_t cis_handle; - uint8_t reason; -} __attribute__((packed)); - -struct ble_hci_le_reject_cis_request_rp { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_CREATE_BIG (0x0068) -struct ble_hci_le_create_big_cp { - uint8_t big_handle; - uint8_t adv_handle; - uint8_t bis_cnt; - uint8_t sdu_interval[3]; - uint16_t max_sdu; - uint16_t max_transport_latency; - uint8_t rnt; - uint8_t phy; - uint8_t packing; - uint8_t framing; - uint8_t encryption; - uint8_t broadcast_code[16]; -} __attribute__((packed)); - -#if MYNEWT_VAL(BLE_ISO_TEST) -#define BLE_HCI_OCF_LE_CREATE_BIG_TEST (0x0069) -struct ble_hci_le_create_big_test_cp { - uint8_t big_handle; - uint8_t adv_handle; - uint8_t bis_cnt; - uint8_t sdu_interval[3]; - uint16_t iso_interval; - uint8_t nse; - uint16_t max_sdu; - uint16_t max_pdu; - uint8_t phy; - uint8_t packing; - uint8_t framing; - uint8_t bn; - uint8_t irc; - uint8_t pto; - uint8_t encryption; - uint8_t broadcast_code[16]; -} __attribute__((packed)); -#endif - -#define BLE_HCI_OCF_LE_TERMINATE_BIG (0x006a) -struct ble_hci_le_terminate_big_cp { - uint8_t big_handle; - uint8_t reason; -} __attribute__((packed)); - -#define BLE_HCI_LE_BIG_CREATE_SYNC_LEN_MIN (25) -#define BLE_HCI_OCF_LE_BIG_CREATE_SYNC (0x006b) -struct ble_hci_le_big_create_sync_cp { - uint8_t big_handle; - uint16_t sync_handle; - uint8_t big_cnt; - uint8_t encryption; - uint8_t broadcast_code[16]; - uint8_t mse; - uint16_t timeout; - uint8_t bis[0]; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_BIG_TERMINATE_SYNC (0x006c) -struct ble_hci_le_terminate_big_sync_cp { - uint8_t big_handle; -} __attribute__((packed)); -#endif - -#define BLE_HCI_OCF_LE_REQ_PEER_SCA (0x006d) -struct ble_hci_le_request_peer_sca_cp { - uint16_t conn_handle; -} __attribute__((packed)); - -#if MYNEWT_VAL(BLE_ISO) -#define BLE_HCI_OCF_LE_SETUP_ISO_DATA_PATH (0x006e) -struct ble_hci_le_iso_setup_data_path_cp { - uint16_t iso_handle; - uint8_t direction; - uint8_t id; - uint8_t codec_id[5]; - uint8_t controller_delay[3]; - uint8_t codec_conf_len; - uint8_t codec_conf[0]; -} __attribute__((packed)); - -#define BLE_HCI_LE_REMOVE_INPUT_DATA_PATH_BIT (0x01) -#define BLE_HCI_LE_REMOVE_OUTPUT_DATA_PATH_BIT (0x02) -#define BLE_HCI_OCF_LE_REMOVE_ISO_DATA_PATH (0x006f) -struct ble_hci_le_iso_remove_data_path_cp { - uint16_t iso_handle; - uint8_t direction; -} __attribute__((packed)); - -#if MYNEWT_VAL(BLE_ISO_TEST) -#define BLE_HCI_OCF_LE_ISO_TRANSMIT_TEST (0x0070) -struct ble_hci_le_iso_transmit_test_cp { - uint16_t iso_handle; - uint8_t payload_type; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_ISO_RECEIVE_TEST (0x0071) -struct ble_hci_le_iso_receive_test_cp { - uint16_t iso_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_ISO_READ_TEST_COUNTERS (0x0072) -struct ble_hci_le_iso_read_test_counters_cp { - uint16_t iso_handle; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_ISO_TEST_END (0x0073) -struct ble_hci_le_iso_test_end_cp { - uint16_t iso_handle; -} __attribute__((packed)); -#endif -#endif - -#define BLE_HCI_OCF_LE_SET_HOST_FEAT (0x0074) -struct ble_hci_le_set_host_feat_cp { - uint8_t bit_num; - uint8_t val; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_ENH_READ_TRANSMIT_POWER_LEVEL (0x0076) -struct ble_hci_le_enh_read_transmit_power_level_cp { - uint16_t conn_handle; - uint8_t phy; -} __attribute__((packed)); -struct ble_hci_le_enh_read_transmit_power_level_rp { - uint16_t conn_handle; - uint8_t phy; - uint8_t curr_tx_power_level; - uint8_t max_tx_power_level; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_READ_REMOTE_TRANSMIT_POWER_LEVEL (0x0077) -struct ble_hci_le_read_remote_transmit_power_level_cp { - uint16_t conn_handle; - uint8_t phy; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_PATH_LOSS_REPORT_PARAM (0x0078) -struct ble_hci_le_set_path_loss_report_param_cp { - uint16_t conn_handle; - uint8_t high_threshold; - uint8_t high_hysteresis; - uint8_t low_threshold; - uint8_t low_hysteresis; - uint16_t min_time_spent; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_PATH_LOSS_REPORT_ENABLE (0x0079) -struct ble_hci_le_set_path_loss_report_enable_cp { - uint16_t conn_handle; - uint8_t enable; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_TRANS_PWR_REPORT_ENABLE (0x007A) -struct ble_hci_le_set_transmit_power_report_enable_cp { - uint16_t conn_handle; - uint8_t local_enable; - uint8_t remote_enable; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SET_DEFAULT_SUBRATE (0x007D) -struct ble_hci_le_set_default_subrate_cp { - uint16_t subrate_min; - uint16_t subrate_max; - uint16_t max_latency; - uint16_t cont_num; - uint16_t supervision_tmo; -} __attribute__((packed)); - -#define BLE_HCI_OCF_LE_SUBRATE_REQ (0x007E) -struct ble_hci_le_subrate_req_cp { - uint16_t conn_handle; - uint16_t subrate_min; - uint16_t subrate_max; - uint16_t max_latency; - uint16_t cont_num; - uint16_t supervision_tmo; -} __attribute__((packed)); - -/* --- Vendor specific commands (OGF 0x003F) */ -/* Read Random Static Address */ -#define BLE_HCI_OCF_VS_RD_STATIC_ADDR (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0001)) -struct ble_hci_vs_rd_static_addr_rp { - uint8_t addr[6]; -} __attribute__((packed)); - - -#if SOC_BLE_POWER_CONTROL_SUPPORTED && MYNEWT_VAL(BLE_HCI_VS) -#define BLE_HCI_OCF_VS_PCL_SET_RSSI (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0111)) -#endif - -/* Command Specific Definitions */ -/* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */ -#define BLE_HCI_CTLR_TO_HOST_FC_OFF (0) -#define BLE_HCI_CTLR_TO_HOST_FC_ACL (1) -#define BLE_HCI_CTLR_TO_HOST_FC_SYNC (2) -#define BLE_HCI_CTLR_TO_HOST_FC_BOTH (3) - -/* --- LE set advertising parameters (OCF 0x0006) */ -/* Advertising types */ -#define BLE_HCI_ADV_TYPE_ADV_IND (0) -#define BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD (1) -#define BLE_HCI_ADV_TYPE_ADV_SCAN_IND (2) -#define BLE_HCI_ADV_TYPE_ADV_NONCONN_IND (3) -#define BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD (4) -#define BLE_HCI_ADV_TYPE_MAX (4) - -#define BLE_HCI_ADV_CONN_MASK (0x0001) -#define BLE_HCI_ADV_SCAN_MASK (0x0002) -#define BLE_HCI_ADV_DIRECT_MASK (0x0004) -#define BLE_HCI_ADV_SCAN_RSP_MASK (0x0008) -#define BLE_HCI_ADV_LEGACY_MASK (0x0010) - -#define BLE_HCI_ADV_DATA_STATUS_COMPLETE (0x0000) -#define BLE_HCI_ADV_DATA_STATUS_INCOMPLETE (0x0020) -#define BLE_HCI_ADV_DATA_STATUS_TRUNCATED (0x0040) -#define BLE_HCI_ADV_DATA_STATUS_MASK (0x0060) - -/* Own address types */ -#define BLE_HCI_ADV_OWN_ADDR_PUBLIC (0) -#define BLE_HCI_ADV_OWN_ADDR_RANDOM (1) -#define BLE_HCI_ADV_OWN_ADDR_PRIV_PUB (2) -#define BLE_HCI_ADV_OWN_ADDR_PRIV_RAND (3) -#define BLE_HCI_ADV_OWN_ADDR_MAX (3) - -/* Advertisement peer address Type */ -#define BLE_HCI_ADV_PEER_ADDR_PUBLIC (0) -#define BLE_HCI_ADV_PEER_ADDR_RANDOM (1) -#define BLE_HCI_ADV_PEER_ADDR_MAX (1) - -/* --- LE advertising channel tx power (OCF 0x0007) */ -#define BLE_HCI_ADV_CHAN_TXPWR_MIN (-20) -#define BLE_HCI_ADV_CHAN_TXPWR_MAX (10) - -/* --- LE set scan enable (OCF 0x000c) */ - -/* Connect peer address type */ -#define BLE_HCI_CONN_PEER_ADDR_PUBLIC (0) -#define BLE_HCI_CONN_PEER_ADDR_RANDOM (1) -#define BLE_HCI_CONN_PEER_ADDR_PUBLIC_IDENT (2) -#define BLE_HCI_CONN_PEER_ADDR_RANDOM_IDENT (3) -#define BLE_HCI_CONN_PEER_ADDR_MAX (3) - -/* - * Advertising filter policy - * - * Determines how an advertiser filters scan and connection requests. - * - * NONE: no filtering (default value). No whitelist used. - * SCAN: process all connection requests but only scans from white list. - * CONN: process all scan request but only connection requests from white list - * BOTH: ignore all scan and connection requests unless in white list. - */ -#define BLE_HCI_ADV_FILT_NONE (0) -#define BLE_HCI_ADV_FILT_SCAN (1) -#define BLE_HCI_ADV_FILT_CONN (2) -#define BLE_HCI_ADV_FILT_BOTH (3) -#define BLE_HCI_ADV_FILT_MAX (3) - -#define BLE_HCI_ADV_FILT_DEF (BLE_HCI_ADV_FILT_NONE) - -/* Advertising interval */ -#define BLE_HCI_ADV_ITVL (625) /* usecs */ -#define BLE_HCI_ADV_ITVL_MIN (32) /* units */ -#define BLE_HCI_ADV_ITVL_MAX (16384) /* units */ -#define BLE_HCI_ADV_ITVL_NONCONN_MIN (160) /* units */ - -#define BLE_HCI_ADV_ITVL_DEF (0x800) /* 1.28 seconds */ -#define BLE_HCI_ADV_CHANMASK_DEF (0x7) /* all channels */ - -#define BLE_HCI_PERIODIC_ADV_ITVL (1250) /* usecs */ - -/* Set scan parameters */ -#define BLE_HCI_SCAN_TYPE_PASSIVE (0) -#define BLE_HCI_SCAN_TYPE_ACTIVE (1) - -/* Scan interval and scan window timing */ -#define BLE_HCI_SCAN_ITVL (625) /* usecs */ -#define BLE_HCI_SCAN_ITVL_MIN (4) /* units */ -#define BLE_HCI_SCAN_ITVL_MAX (16384) /* units */ -#define BLE_HCI_SCAN_ITVL_DEF (16) /* units */ -#define BLE_HCI_SCAN_WINDOW_MIN (4) /* units */ -#define BLE_HCI_SCAN_WINDOW_MAX (16384) /* units */ -#define BLE_HCI_SCAN_WINDOW_DEF (16) /* units */ - -/* - * Scanning filter policy - * NO_WL: - * Scanner processes all advertising packets (white list not used) except - * directed, connectable advertising packets not sent to the scanner. - * USE_WL: - * Scanner processes advertisements from white list only. A connectable, - * directed advertisment is ignored unless it contains scanners address. - * NO_WL_INITA: - * Scanner process all advertising packets (white list not used). A - * connectable, directed advertisement shall not be ignored if the InitA - * is a resolvable private address. - * USE_WL_INITA: - * Scanner process advertisements from white list only. A connectable, - * directed advertisement shall not be ignored if the InitA is a - * resolvable private address. - */ -#define BLE_HCI_SCAN_FILT_NO_WL (0) -#define BLE_HCI_SCAN_FILT_USE_WL (1) -#define BLE_HCI_SCAN_FILT_NO_WL_INITA (2) -#define BLE_HCI_SCAN_FILT_USE_WL_INITA (3) -#define BLE_HCI_SCAN_FILT_MAX (3) - -/* Whitelist commands */ -#define BLE_HCI_ADD_WHITE_LIST_LEN (7) -#define BLE_HCI_RMV_WHITE_LIST_LEN (7) - -/* Create Connection */ -#define BLE_HCI_CREATE_CONN_LEN (25) -#define BLE_HCI_CONN_ITVL (1250) /* usecs */ -#define BLE_HCI_CONN_FILT_NO_WL (0) -#define BLE_HCI_CONN_FILT_USE_WL (1) -#define BLE_HCI_CONN_FILT_MAX (1) -#define BLE_HCI_CONN_ITVL_MIN (0x0006) -#define BLE_HCI_CONN_ITVL_MAX (0x0c80) -#define BLE_HCI_CONN_LATENCY_MIN (0x0000) -#define BLE_HCI_CONN_LATENCY_MAX (0x01f3) -#define BLE_HCI_CONN_SPVN_TIMEOUT_MIN (0x000a) -#define BLE_HCI_CONN_SPVN_TIMEOUT_MAX (0x0c80) -#define BLE_HCI_CONN_SPVN_TMO_UNITS (10) /* msecs */ -#define BLE_HCI_INITIATOR_FILT_POLICY_MAX (1) - -/* Peer Address Type */ -#define BLE_HCI_CONN_PEER_ADDR_PUBLIC (0) -#define BLE_HCI_CONN_PEER_ADDR_RANDOM (1) -#define BLE_HCI_CONN_PEER_ADDR_PUB_ID (2) -#define BLE_HCI_CONN_PEER_ADDR_RAND_ID (3) -#define BLE_HCI_CONN_PEER_ADDR_MAX (3) - - -/* --- LE set data length (OCF 0x0022) */ -#define BLE_HCI_SET_DATALEN_TX_OCTETS_MIN (0x001b) -#define BLE_HCI_SET_DATALEN_TX_OCTETS_MAX (0x00fb) -#define BLE_HCI_SET_DATALEN_TX_TIME_MIN (0x0148) -#define BLE_HCI_SET_DATALEN_TX_TIME_MAX (0x4290) - -/* --- LE read/write suggested default data length (OCF 0x0023 and 0x0024) */ -#define BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MIN (0x001b) -#define BLE_HCI_SUGG_DEF_DATALEN_TX_OCTETS_MAX (0x00fb) -#define BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MIN (0x0148) -#define BLE_HCI_SUGG_DEF_DATALEN_TX_TIME_MAX (0x4290) - -/* --- LE read maximum default PHY (OCF 0x0030) */ -#define BLE_HCI_LE_PHY_1M (1) -#define BLE_HCI_LE_PHY_2M (2) -#define BLE_HCI_LE_PHY_CODED (3) - -/* --- LE set default PHY (OCF 0x0031) */ -#define BLE_HCI_LE_PHY_NO_TX_PREF_MASK (0x01) -#define BLE_HCI_LE_PHY_NO_RX_PREF_MASK (0x02) -#define BLE_HCI_LE_PHY_1M_PREF_MASK (0x01) -#define BLE_HCI_LE_PHY_2M_PREF_MASK (0x02) -#define BLE_HCI_LE_PHY_CODED_PREF_MASK (0x04) - -#define BLE_HCI_LE_PHY_PREF_MASK_ALL \ - (BLE_HCI_LE_PHY_1M_PREF_MASK | BLE_HCI_LE_PHY_2M_PREF_MASK | \ - BLE_HCI_LE_PHY_CODED_PREF_MASK) - -/* --- LE set PHY (OCF 0x0032) */ -#define BLE_HCI_LE_PHY_CODED_ANY (0x0000) -#define BLE_HCI_LE_PHY_CODED_S2_PREF (0x0001) -#define BLE_HCI_LE_PHY_CODED_S8_PREF (0x0002) - -/* --- LE enhanced receiver test (OCF 0x0033) */ -#define BLE_HCI_LE_PHY_1M (1) -#define BLE_HCI_LE_PHY_2M (2) -#define BLE_HCI_LE_PHY_CODED (3) - -/* --- LE enhanced transmitter test (OCF 0x0034) */ -#define BLE_HCI_LE_PHY_CODED_S8 (3) -#define BLE_HCI_LE_PHY_CODED_S2 (4) - -/* --- LE set extended advertising parameters (OCF 0x0036) */ -#define BLE_HCI_LE_SET_EXT_ADV_PROP_CONNECTABLE (0x0001) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_SCANNABLE (0x0002) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_DIRECTED (0x0004) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED (0x0008) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY (0x0010) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_ANON_ADV (0x0020) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_INC_TX_PWR (0x0040) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_MASK (0x7F) - -#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_IND (0x0013) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_LD_DIR (0x0015) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_HD_DIR (0x001d) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_SCAN (0x0012) -#define BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY_NONCONN (0x0010) - -/* --- LE set extended advertising data (OCF 0x0037) */ -#define BLE_HCI_MAX_EXT_ADV_DATA_LEN (251) - -#define BLE_HCI_LE_SET_DATA_OPER_INT (0) -#define BLE_HCI_LE_SET_DATA_OPER_FIRST (1) -#define BLE_HCI_LE_SET_DATA_OPER_LAST (2) -#define BLE_HCI_LE_SET_DATA_OPER_COMPLETE (3) -#define BLE_HCI_LE_SET_DATA_OPER_UNCHANGED (4) - -/* --- LE set extended scan response data (OCF 0x0038) */ -#define BLE_HCI_MAX_EXT_SCAN_RSP_DATA_LEN (251) - -/* --- LE set periodic advertising parameters (OCF 0x003E) */ -#define BLE_HCI_LE_SET_PERIODIC_ADV_PROP_INC_TX_PWR (0x0040) -#define BLE_HCI_LE_SET_PERIODIC_ADV_PROP_MASK (0x0040) - -/* --- LE set periodic advertising data (OCF 0x003F) */ -#define BLE_HCI_MAX_PERIODIC_ADV_DATA_LEN (252) - -/* --- LE remove device from periodic advertising list (OCF 0x0048) */ -#define BLE_HCI_PERIODIC_DATA_STATUS_COMPLETE 0x00 -#define BLE_HCI_PERIODIC_DATA_STATUS_INCOMPLETE 0x01 -#define BLE_HCI_PERIODIC_DATA_STATUS_TRUNCATED 0x02 - -/* --- LE set privacy mode (OCF 0x004E) */ -#define BLE_HCI_PRIVACY_NETWORK (0) -#define BLE_HCI_PRIVACY_DEVICE (1) - -/* Event Codes */ -#define BLE_HCI_EVCODE_INQUIRY_CMP (0x01) -#define BLE_HCI_EVCODE_INQUIRY_RESULT (0x02) -#define BLE_HCI_EVCODE_CONN_DONE (0x03) -#define BLE_HCI_EVCODE_CONN_REQUEST (0x04) -#define BLE_HCI_EVCODE_DISCONN_CMP (0x05) -struct ble_hci_ev_disconn_cmp { - uint8_t status; - uint16_t conn_handle; - uint8_t reason; -} __attribute__((packed)); - -#define BLE_HCI_EVCODE_AUTH_CMP (0x06) -#define BLE_HCI_EVCODE_REM_NAME_REQ_CMP (0x07) - -#define BLE_HCI_EVCODE_ENCRYPT_CHG (0x08) -struct ble_hci_ev_enrypt_chg { - uint8_t status; - uint16_t connection_handle; - uint8_t enabled; -} __attribute__((packed)); - -#define BLE_HCI_EVCODE_CHG_LINK_KEY_CMP (0x09) -#define BLE_HCI_EVCODE_MASTER_LINK_KEY_CMP (0x0A) -#define BLE_HCI_EVCODE_RD_REM_SUPP_FEAT_CMP (0x0B) -#define BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP (0x0C) -struct ble_hci_ev_rd_rem_ver_info_cmp { - uint8_t status; - uint16_t conn_handle; - uint8_t version; - uint16_t manufacturer; - uint16_t subversion; -} __attribute__((packed)); - -#define BLE_HCI_EVCODE_QOS_SETUP_CMP (0x0D) - -#define BLE_HCI_EVCODE_COMMAND_COMPLETE (0x0E) -struct ble_hci_ev_command_complete { - uint8_t num_packets; - uint16_t opcode; - uint8_t status; - uint8_t return_params[0]; -} __attribute__((packed)); -/* NOP is exception and has no return parameters */ -struct ble_hci_ev_command_complete_nop { - uint8_t num_packets; - uint16_t opcode; -} __attribute__((packed)); - -#define BLE_HCI_EVCODE_COMMAND_STATUS (0x0F) -struct ble_hci_ev_command_status { - uint8_t status; - uint8_t num_packets; - uint16_t opcode; -} __attribute__((packed)); - -#define BLE_HCI_EVCODE_HW_ERROR (0x10) -struct ble_hci_ev_hw_error { - uint8_t hw_code; -} __attribute__((packed)); - -#define BLE_HCI_EVCODE_NUM_COMP_PKTS (0x13) -struct comp_pkt { - uint16_t handle; - uint16_t packets; -} __attribute__((packed));; -struct ble_hci_ev_num_comp_pkts { - uint8_t count; - struct comp_pkt completed[0]; -} __attribute__((packed)); - -#define BLE_HCI_EVCODE_MODE_CHANGE (0x14) -#define BLE_HCI_EVCODE_RETURN_LINK_KEYS (0x15) -#define BLE_HCI_EVCODE_PIN_CODE_REQ (0x16) -#define BLE_HCI_EVCODE_LINK_KEY_REQ (0x17) -#define BLE_HCI_EVCODE_LINK_KEY_NOTIFY (0x18) -#define BLE_HCI_EVCODE_LOOPBACK_CMD (0x19) - -#define BLE_HCI_EVCODE_DATA_BUF_OVERFLOW (0x1A) -struct ble_hci_ev_data_buf_overflow { - uint8_t link_type; -} __attribute__((packed)); - -#define BLE_HCI_EVCODE_MAX_SLOTS_CHG (0x1B) -#define BLE_HCI_EVCODE_READ_CLK_OFF_COMP (0x1C) -#define BLE_HCI_EVCODE_CONN_PKT_TYPE_CHG (0x1D) -#define BLE_HCI_EVCODE_QOS_VIOLATION (0x1E) -/* NOTE: 0x1F not defined */ -#define BLE_HCI_EVCODE_PSR_MODE_CHG (0x20) -#define BLE_HCI_EVCODE_FLOW_SPEC_COMP (0x21) -#define BLE_HCI_EVCODE_INQ_RESULT_RSSI (0x22) -#define BLE_HCI_EVCODE_READ_REM_EXT_FEAT (0x23) -/* NOTE: 0x24 - 0x2B not defined */ -#define BLE_HCI_EVCODE_SYNCH_CONN_COMP (0x2C) -#define BLE_HCI_EVCODE_SYNCH_CONN_CHG (0x2D) -#define BLE_HCI_EVCODE_SNIFF_SUBRATING (0x2E) -#define BLE_HCI_EVCODE_EXT_INQ_RESULT (0x2F) - -#define BLE_HCI_EVCODE_ENC_KEY_REFRESH (0x30) -struct ble_hci_ev_enc_key_refresh { - uint8_t status; - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_EVOCDE_IO_CAP_REQ (0x31) -#define BLE_HCI_EVCODE_IO_CAP_RSP (0x32) -#define BLE_HCI_EVCODE_USER_CONFIRM_REQ (0x33) -#define BLE_HCI_EVCODE_PASSKEY_REQ (0x34) -#define BLE_HCI_EVCODE_REM_OOB_DATA_REQ (0x35) -#define BLE_HCI_EVCODE_SIMPLE_PAIR_COMP (0x36) -/* NOTE: 0x37 not defined */ -#define BLE_HCI_EVCODE_LNK_SPVN_TMO_CHG (0x38) -#define BLE_HCI_EVCODE_ENH_FLUSH_COMP (0x39) -#define BLE_HCI_EVCODE_USER_PASSKEY_NOTIFY (0x3B) -#define BLE_HCI_EVCODE_KEYPRESS_NOTIFY (0x3C) -#define BLE_HCI_EVCODE_REM_HOST_SUPP_FEAT (0x3D) - -#define BLE_HCI_EVCODE_LE_META (0x3E) -struct ble_hci_ev_le_meta { - uint8_t subevent; - uint8_t data[0]; -} __attribute__((packed)); - -/* NOTE: 0x3F not defined */ -#define BLE_HCI_EVCODE_PHYS_LINK_COMP (0x40) -#define BLE_HCI_EVCODE_CHAN_SELECTED (0x41) -#define BLE_HCI_EVCODE_DISCONN_PHYS_LINK (0x42) -#define BLE_HCI_EVCODE_PHYS_LINK_LOSS_EARLY (0x43) -#define BLE_HCI_EVCODE_PHYS_LINK_RECOVERY (0x44) -#define BLE_HCI_EVCODE_LOGICAL_LINK_COMP (0x45) -#define BLE_HCI_EVCODE_DISCONN_LOGICAL_LINK (0x46) -#define BLE_HCI_EVCODE_FLOW_SPEC_MODE_COMP (0x47) -#define BLE_HCI_EVCODE_NUM_COMP_DATA_BLKS (0x48) -#define BLE_HCI_EVCODE_AMP_START_TEST (0x49) -#define BLE_HCI_EVOCDE_AMP_TEST_END (0x4A) -#define BLE_HCI_EVOCDE_AMP_RCVR_REPORT (0x4B) -#define BLE_HCI_EVCODE_SHORT_RANGE_MODE_CHG (0x4C) -#define BLE_HCI_EVCODE_AMP_STATUS_CHG (0x4D) -#define BLE_HCI_EVCODE_TRIG_CLK_CAPTURE (0x4E) -#define BLE_HCI_EVCODE_SYNCH_TRAIN_COMP (0x4F) -#define BLE_HCI_EVCODE_SYNCH_TRAIN_RCVD (0x50) -#define BLE_HCI_EVCODE_SLAVE_BCAST_RX (0x51) -#define BLE_HCI_EVCODE_SLAVE_BCAST_TMO (0x52) -#define BLE_HCI_EVCODE_TRUNC_PAGE_COMP (0x53) -#define BLE_HCI_EVCODE_SLAVE_PAGE_RSP_TMO (0x54) -#define BLE_HCI_EVCODE_SLAVE_BCAST_CHAN_MAP (0x55) -#define BLE_HCI_EVCODE_INQ_RSP_NOTIFY (0x56) - -#define BLE_HCI_EVCODE_AUTH_PYLD_TMO (0x57) -struct ble_hci_ev_auth_pyld_tmo { - uint16_t conn_handle; -} __attribute__((packed)); - -#define BLE_HCI_EVCODE_SAM_STATUS_CHG (0x58) - -#define BLE_HCI_EVCODE_VS_DEBUG (0xFF) -struct ble_hci_ev_vs_debug { - uint8_t id; - uint8_t data[0]; -} __attribute__((packed)); - -/* LE sub-event codes */ -#define BLE_HCI_LE_SUBEV_CONN_COMPLETE (0x01) -struct ble_hci_ev_le_subev_conn_complete { - uint8_t subev_code; - uint8_t status; - uint16_t conn_handle; - uint8_t role; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint16_t conn_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint8_t mca; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_ADV_RPT (0x02) -struct adv_report { - uint8_t type; - uint8_t addr_type; - uint8_t addr[6]; - uint8_t data_len; - uint8_t data[0]; -} __attribute__((packed)); -struct ble_hci_ev_le_subev_adv_rpt { - uint8_t subev_code; - uint8_t num_reports; - struct adv_report reports[0]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE (0x03) -struct ble_hci_ev_le_subev_conn_upd_complete { - uint8_t subev_code; - uint8_t status; - uint16_t conn_handle; - uint16_t conn_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT (0x04) -struct ble_hci_ev_le_subev_rd_rem_used_feat { - uint8_t subev_code; - uint8_t status; - uint16_t conn_handle; - uint8_t features[8]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_LT_KEY_REQ (0x05) -struct ble_hci_ev_le_subev_lt_key_req { - uint8_t subev_code; - uint16_t conn_handle; - uint64_t rand; - uint16_t div; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ (0x06) -struct ble_hci_ev_le_subev_rem_conn_param_req { - uint8_t subev_code; - uint16_t conn_handle; - uint16_t min_interval; - uint16_t max_interval; - uint16_t latency; - uint16_t timeout; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_DATA_LEN_CHG (0x07) -struct ble_hci_ev_le_subev_data_len_chg { - uint8_t subev_code; - uint16_t conn_handle; - uint16_t max_tx_octets; - uint16_t max_tx_time; - uint16_t max_rx_octets; - uint16_t max_rx_time; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_RD_LOC_P256_PUBKEY (0x08) -struct ble_hci_ev_le_subev_rd_loc_p256_pubkey { - uint8_t subev_code; - uint8_t status; - uint8_t public_key[64]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_GEN_DHKEY_COMPLETE (0x09) -struct ble_hci_ev_le_subev_gen_dhkey_complete { - uint8_t subev_code; - uint8_t status; - uint8_t dh_key[32]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_ENH_CONN_COMPLETE (0x0A) -struct ble_hci_ev_le_subev_enh_conn_complete { - uint8_t subev_code; - uint8_t status; - uint16_t conn_handle; - uint8_t role; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint8_t local_rpa[6]; - uint8_t peer_rpa[6]; - uint16_t conn_itvl; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint8_t mca; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT (0x0B) -struct dir_adv_report { - uint8_t type; - uint8_t addr_type; - uint8_t addr[6]; - uint8_t dir_addr_type; - uint8_t dir_addr[6]; - int8_t rssi; -} __attribute__((packed)); -struct ble_hci_ev_le_subev_direct_adv_rpt { - uint8_t subev_code; - uint8_t num_reports; - struct dir_adv_report reports[0]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE (0x0C) -struct ble_hci_ev_le_subev_phy_update_complete { - uint8_t subev_code; - uint8_t status; - uint16_t conn_handle; - uint8_t tx_phy; - uint8_t rx_phy; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_EXT_ADV_RPT (0x0D) -struct ext_adv_report { - uint16_t evt_type; - uint8_t addr_type; - uint8_t addr[6]; - uint8_t pri_phy; - uint8_t sec_phy; - uint8_t sid; - int8_t tx_power; - int8_t rssi; - uint16_t periodic_itvl; - uint8_t dir_addr_type; - uint8_t dir_addr[6]; - uint8_t data_len; - uint8_t data[0]; -} __attribute__((packed)); -struct ble_hci_ev_le_subev_ext_adv_rpt { - uint8_t subev_code; - uint8_t num_reports; - struct ext_adv_report reports[0]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_ESTAB (0x0E) -struct ble_hci_ev_le_subev_periodic_adv_sync_estab { - uint8_t subev_code; - uint8_t status; - uint16_t sync_handle; - uint8_t sid; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint8_t phy; - uint16_t interval; - uint8_t aca; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT (0x0F) -struct ble_hci_ev_le_subev_periodic_adv_rpt { - uint8_t subev_code; - uint16_t sync_handle; - int8_t tx_power; - int8_t rssi; - uint8_t cte_type; - uint8_t data_status; - uint8_t data_len; - uint8_t data[0]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_LOST (0x10) -struct ble_hci_ev_le_subev_periodic_adv_sync_lost { - uint8_t subev_code; - uint16_t sync_handle; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_SCAN_TIMEOUT (0x11) -struct ble_hci_ev_le_subev_scan_timeout { - uint8_t subev_code; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED (0x12) -struct ble_hci_ev_le_subev_adv_set_terminated { - uint8_t subev_code; - uint8_t status; - uint8_t adv_handle; - uint16_t conn_handle; - uint8_t num_events; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD (0x13) -struct ble_hci_ev_le_subev_scan_req_rcvd { - uint8_t subev_code; - uint8_t adv_handle; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_CHAN_SEL_ALG (0x14) -struct ble_hci_ev_le_subev_chan_sel_alg { - uint8_t subev_code; - uint16_t conn_handle; - uint8_t csa; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_CONNLESS_IQ_RPT (0x15) -#define BLE_HCI_LE_SUBEV_CONN_IQ_RPT (0x16) -#define BLE_HCI_LE_SUBEV_CTE_REQ_FAILED (0x17) - -#define BLE_HCI_LE_SUBEV_PERIODIC_ADV_SYNC_TRANSFER (0x18) -struct ble_hci_ev_le_subev_periodic_adv_sync_transfer { - uint8_t subev_code; - uint8_t status; - uint16_t conn_handle; - uint16_t service_data; - uint16_t sync_handle; - uint8_t sid; - uint8_t peer_addr_type; - uint8_t peer_addr[6]; - uint8_t phy; - uint16_t interval; - uint8_t aca; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_CIS_ESTAB (0x19) -struct ble_hci_ev_le_subev_cis_established { - uint8_t subev_code; - uint8_t status; - uint16_t cis_handle; - uint8_t cig_sync_delay[3]; - uint8_t cis_sync_delay[3]; - uint8_t trans_latency_mtos[3]; - uint8_t trans_latency_stom[3]; - uint8_t phy_mtos; - uint8_t phy_stom; - uint8_t nse; - uint8_t bn_mtos; - uint8_t bn_stom; - uint8_t ft_mtos; - uint8_t ft_stom; - uint16_t max_pdu_mtos; - uint16_t max_pdu_stom; - uint16_t iso_interval; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_CIS_REQUEST (0x1A) -struct ble_hci_ev_le_subev_cis_request { - uint8_t subev_code; - uint16_t conn_handle; - uint16_t cis_handle; - uint8_t cig_id; - uint8_t cis_id; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_BIG_COMP (0x1B) -struct ble_hci_ev_le_subev_big_complete { - uint8_t subev_code; - uint8_t status; - uint8_t big_handle; - uint8_t big_sync_delay[3]; - uint8_t transport_latency[3]; - uint8_t phy; - uint8_t nse; - uint8_t bn; - uint8_t pto; - uint8_t irc; - uint16_t max_pdu; - uint16_t iso_interval; - uint8_t bis_cnt; - uint16_t bis[0]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_BIG_TERMINATE_COMP (0x1C) -struct ble_hci_ev_le_subev_big_terminate_complete { - uint8_t subev_code; - uint8_t big_handle; - uint8_t reason; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_BIG_SYNC_ESTAB (0x1D) -struct ble_hci_ev_le_subev_big_sync_established { - uint8_t subev_code; - uint8_t status; - uint8_t big_handle; - uint8_t transport_latency[3]; - uint8_t nse; - uint8_t bn; - uint8_t pto; - uint8_t irc; - uint16_t max_pdu; - uint16_t iso_interval; - uint8_t bis_cnt; - uint16_t bis_handles[0]; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_BIG_SYNC_LOST (0x1E) -struct ble_hci_ev_le_subev_big_sync_lost { - uint8_t subev_code; - uint8_t big_handle; - uint8_t reason; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_REQ_PEER_SCA_COMP (0x1F) -struct ble_hci_ev_le_subev_peer_sca_complete { - uint8_t subev_code; - uint8_t status; - uint16_t conn_handle; - uint8_t sca; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_PATH_LOSS_THRESHOLD (0x20) -struct ble_hci_ev_le_subev_path_loss_threshold { - uint8_t subev_code; - uint16_t conn_handle; - uint8_t current_path_loss; - uint8_t zone_entered; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_TRANSMIT_POWER_REPORT (0x21) -struct ble_hci_ev_le_subev_transmit_power_report { - uint8_t subev_code; - uint8_t status; - uint16_t conn_handle; - uint8_t reason; - uint8_t phy; - int8_t transmit_power_level; - uint8_t transmit_power_level_flag; - int8_t delta; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_BIGINFO_ADV_REPORT (0x22) -struct ble_hci_ev_le_subev_biginfo_adv_report { - uint8_t subev_code; - uint16_t sync_handle; - uint8_t bis_cnt; - uint8_t nse; - uint16_t iso_interval; - uint8_t bn; - uint8_t pto; - uint8_t irc; - uint16_t max_pdu; - uint8_t sdu_interval[3]; - uint16_t max_sdu; - uint8_t phy; - uint8_t framing; - uint8_t encryption; -} __attribute__((packed)); - -#define BLE_HCI_LE_SUBEV_SUBRATE_CHANGE (0x23) -struct ble_hci_ev_le_subev_subrate_change { - uint8_t subev_code; - uint8_t status; - uint16_t conn_handle; - uint16_t subrate_factor; - uint16_t periph_latency; - uint16_t cont_num; - uint16_t supervision_tmo; -} __attribute__((packed)); - -/* Data buffer overflow event */ -#define BLE_HCI_EVENT_ACL_BUF_OVERFLOW (0x01) - -/* Advertising report */ -#define BLE_HCI_ADV_RPT_EVTYPE_ADV_IND (0) -#define BLE_HCI_ADV_RPT_EVTYPE_DIR_IND (1) -#define BLE_HCI_ADV_RPT_EVTYPE_SCAN_IND (2) -#define BLE_HCI_ADV_RPT_EVTYPE_NONCONN_IND (3) -#define BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP (4) - -/* Bluetooth 5, Vol 2, Part E, 7.7.65.13 */ -#define BLE_HCI_LEGACY_ADV_EVTYPE_ADV_IND (0x13) -#define BLE_HCI_LEGACY_ADV_EVTYPE_ADV_DIRECT_IND (0x15) -#define BLE_HCI_LEGACY_ADV_EVTYPE_ADV_SCAN_IND (0x12) -#define BLE_HCI_LEGACY_ADV_EVTYPE_ADV_NONCON_IND (0x10) -#define BLE_HCI_LEGACY_ADV_EVTYPE_SCAN_RSP_ADV_IND (0x1b) -#define BLE_HCI_LEGACY_ADV_EVTYPE_SCAN_RSP_ADV_SCAN_IND (0x1a) - -/* LE connection complete event (sub event 0x01) */ -#define BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER (0x00) -#define BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE (0x01) - -/* Maximum valid connection handle value */ -#define BLE_HCI_LE_CONN_HANDLE_MAX (0x0eff) - -/* LE advertising report event. (sub event 0x02) */ -#define BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN (1) -#define BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX (0x19) - -/* Bluetooth Assigned numbers for version information.*/ -#define BLE_HCI_VER_BCS_1_0b (0) -#define BLE_HCI_VER_BCS_1_1 (1) -#define BLE_HCI_VER_BCS_1_2 (2) -#define BLE_HCI_VER_BCS_2_0_EDR (3) -#define BLE_HCI_VER_BCS_2_1_EDR (4) -#define BLE_HCI_VER_BCS_3_0_HCS (5) -#define BLE_HCI_VER_BCS_4_0 (6) -#define BLE_HCI_VER_BCS_4_1 (7) -#define BLE_HCI_VER_BCS_4_2 (8) -#define BLE_HCI_VER_BCS_5_0 (9) -#define BLE_HCI_VER_BCS_5_1 (10) -#define BLE_HCI_VER_BCS_5_2 (11) -#define BLE_HCI_VER_BCS_5_3 (12) - -#define BLE_LMP_VER_BCS_1_0b (0) -#define BLE_LMP_VER_BCS_1_1 (1) -#define BLE_LMP_VER_BCS_1_2 (2) -#define BLE_LMP_VER_BCS_2_0_EDR (3) -#define BLE_LMP_VER_BCS_2_1_EDR (4) -#define BLE_LMP_VER_BCS_3_0_HCS (5) -#define BLE_LMP_VER_BCS_4_0 (6) -#define BLE_LMP_VER_BCS_4_1 (7) -#define BLE_LMP_VER_BCS_4_2 (8) -#define BLE_LMP_VER_BCS_5_0 (9) -#define BLE_LMP_VER_BCS_5_1 (10) -#define BLE_LMP_VER_BCS_5_2 (11) -#define BLE_LMP_VER_BCS_5_3 (12) - -/* selected HCI and LMP version */ -#if MYNEWT_VAL(BLE_VERSION) == 50 -#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_0 -#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_0 -#elif MYNEWT_VAL(BLE_VERSION) == 51 -#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_1 -#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_1 -#elif MYNEWT_VAL(BLE_VERSION) == 52 -#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_2 -#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_2 -#elif MYNEWT_VAL(BLE_VERSION) == 53 -#define BLE_HCI_VER_BCS BLE_HCI_VER_BCS_5_3 -#define BLE_LMP_VER_BCS BLE_LMP_VER_BCS_5_3 -#endif - -#define BLE_HCI_DATA_HDR_SZ 4 -#define BLE_HCI_DATA_HANDLE(handle_pb_bc) (((handle_pb_bc) & 0x0fff) >> 0) -#define BLE_HCI_DATA_PB(handle_pb_bc) (((handle_pb_bc) & 0x3000) >> 12) -#define BLE_HCI_DATA_BC(handle_pb_bc) (((handle_pb_bc) & 0xc000) >> 14) - -struct hci_data_hdr -{ - uint16_t hdh_handle_pb_bc; - uint16_t hdh_len; -}; - -#define BLE_HCI_PB_FIRST_NON_FLUSH 0 -#define BLE_HCI_PB_MIDDLE 1 -#define BLE_HCI_PB_FIRST_FLUSH 2 -#define BLE_HCI_PB_FULL 3 - -#ifdef __cplusplus -} -#endif - -#endif /* H_BLE_HCI_COMMON_ */ diff --git a/components/bt/porting/nimble/include/nimble/nimble_opt.h b/components/bt/porting/nimble/include/nimble/nimble_opt.h deleted file mode 100644 index f0e988b27b..0000000000 --- a/components/bt/porting/nimble/include/nimble/nimble_opt.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -#ifndef H_NIMBLE_OPT_ -#define H_NIMBLE_OPT_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Include automatically-generated settings. */ -#include "nimble/nimble_opt_auto.h" - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/components/bt/porting/nimble/include/nimble/nimble_opt_auto.h b/components/bt/porting/nimble/include/nimble/nimble_opt_auto.h deleted file mode 100644 index 7aeafcc321..0000000000 --- a/components/bt/porting/nimble/include/nimble/nimble_opt_auto.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF) - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD - */ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -#ifndef H_NIMBLE_OPT_AUTO_ -#define H_NIMBLE_OPT_AUTO_ - -#include "syscfg/syscfg.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*** - * Automatic options. - * - * These settings are generated automatically from the user-specified syscfg - * settings. - */ - -#undef NIMBLE_BLE_ADVERTISE -#define NIMBLE_BLE_ADVERTISE \ - (MYNEWT_VAL(BLE_ROLE_BROADCASTER) || MYNEWT_VAL(BLE_ROLE_PERIPHERAL)) - -#undef NIMBLE_BLE_SCAN -#define NIMBLE_BLE_SCAN \ - (MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_OBSERVER)) - -#undef NIMBLE_BLE_CONNECT -#define NIMBLE_BLE_CONNECT \ - (MYNEWT_VAL(BLE_ROLE_CENTRAL) || MYNEWT_VAL(BLE_ROLE_PERIPHERAL)) - - -/** Supported client ATT commands. */ - -#undef NIMBLE_BLE_ATT_CLT_FIND_INFO -#define NIMBLE_BLE_ATT_CLT_FIND_INFO \ - (MYNEWT_VAL(BLE_GATT_DISC_ALL_DSCS)) - -#undef NIMBLE_BLE_ATT_CLT_FIND_TYPE -#define NIMBLE_BLE_ATT_CLT_FIND_TYPE \ - (MYNEWT_VAL(BLE_GATT_DISC_SVC_UUID)) - -#undef NIMBLE_BLE_ATT_CLT_READ_TYPE -#define NIMBLE_BLE_ATT_CLT_READ_TYPE \ - (MYNEWT_VAL(BLE_GATT_FIND_INC_SVCS) || \ - MYNEWT_VAL(BLE_GATT_DISC_ALL_CHRS) || \ - MYNEWT_VAL(BLE_GATT_DISC_CHRS_UUID) || \ - MYNEWT_VAL(BLE_GATT_READ_UUID)) - -#undef NIMBLE_BLE_ATT_CLT_READ -#define NIMBLE_BLE_ATT_CLT_READ \ - (MYNEWT_VAL(BLE_GATT_READ) || \ - MYNEWT_VAL(BLE_GATT_READ_LONG) || \ - MYNEWT_VAL(BLE_GATT_FIND_INC_SVCS)) - -#undef NIMBLE_BLE_ATT_CLT_READ_BLOB -#define NIMBLE_BLE_ATT_CLT_READ_BLOB \ - (MYNEWT_VAL(BLE_GATT_READ_LONG)) - -#undef NIMBLE_BLE_ATT_CLT_READ_MULT -#define NIMBLE_BLE_ATT_CLT_READ_MULT \ - (MYNEWT_VAL(BLE_GATT_READ_MULT)) - -#undef NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE -#define NIMBLE_BLE_ATT_CLT_READ_GROUP_TYPE \ - (MYNEWT_VAL(BLE_GATT_DISC_ALL_SVCS)) - -#undef NIMBLE_BLE_ATT_CLT_WRITE -#define NIMBLE_BLE_ATT_CLT_WRITE \ - (MYNEWT_VAL(BLE_GATT_WRITE)) - -#undef NIMBLE_BLE_ATT_CLT_WRITE_NO_RSP -#define NIMBLE_BLE_ATT_CLT_WRITE_NO_RSP \ - (MYNEWT_VAL(BLE_GATT_WRITE_NO_RSP)) - -#undef NIMBLE_BLE_ATT_CLT_PREP_WRITE -#define NIMBLE_BLE_ATT_CLT_PREP_WRITE \ - (MYNEWT_VAL(BLE_GATT_WRITE_LONG)) - -#undef NIMBLE_BLE_ATT_CLT_EXEC_WRITE -#define NIMBLE_BLE_ATT_CLT_EXEC_WRITE \ - (MYNEWT_VAL(BLE_GATT_WRITE_LONG)) - -#undef NIMBLE_BLE_ATT_CLT_NOTIFY -#define NIMBLE_BLE_ATT_CLT_NOTIFY \ - (MYNEWT_VAL(BLE_GATT_NOTIFY)) - -#undef NIMBLE_BLE_ATT_CLT_INDICATE -#define NIMBLE_BLE_ATT_CLT_INDICATE \ - (MYNEWT_VAL(BLE_GATT_INDICATE)) - -/** Security manager settings. */ - -#undef NIMBLE_BLE_SM -#define NIMBLE_BLE_SM (MYNEWT_VAL(BLE_SM_LEGACY) || MYNEWT_VAL(BLE_SM_SC)) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/components/bt/porting/nimble/include/nimble/nimble_port.h b/components/bt/porting/nimble/include/nimble/nimble_port.h index 2b000081ea..f4a9854378 100644 --- a/components/bt/porting/nimble/include/nimble/nimble_port.h +++ b/components/bt/porting/nimble/include/nimble/nimble_port.h @@ -27,7 +27,7 @@ #define NIMBLE_HS_STACK_SIZE CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE -#if SOC_ESP_NIMBLE_CONTROLLER +#if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED #define NIMBLE_LL_STACK_SIZE CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE #endif diff --git a/components/bt/porting/nimble/include/nimble/nimble_npl.h b/components/bt/porting/npl/freertos/include/nimble/nimble_npl.h similarity index 83% rename from components/bt/porting/nimble/include/nimble/nimble_npl.h rename to components/bt/porting/npl/freertos/include/nimble/nimble_npl.h index c11a2972df..c9482044b7 100644 --- a/components/bt/porting/nimble/include/nimble/nimble_npl.h +++ b/components/bt/porting/npl/freertos/include/nimble/nimble_npl.h @@ -1,20 +1,7 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * - * 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 _NIMBLE_NPL_H_ diff --git a/components/bt/porting/npl/freertos/include/nimble/nimble_npl_os.h b/components/bt/porting/npl/freertos/include/nimble/nimble_npl_os.h index 742e1446cc..6c8d23c091 100644 --- a/components/bt/porting/npl/freertos/include/nimble/nimble_npl_os.h +++ b/components/bt/porting/npl/freertos/include/nimble/nimble_npl_os.h @@ -122,6 +122,7 @@ struct npl_funcs_t { void (*p_ble_npl_hw_exit_critical)(uint32_t); uint32_t (*p_ble_npl_get_time_forever)(void); uint8_t (*p_ble_npl_hw_is_in_critical)(void); + void (*p_ble_npl_eventq_put_to_front)(struct ble_npl_eventq *, struct ble_npl_event *); }; extern struct npl_funcs_t *npl_funcs; diff --git a/components/bt/porting/npl/freertos/src/npl_os_freertos.c b/components/bt/porting/npl/freertos/src/npl_os_freertos.c index 930889dd35..29e2567d55 100644 --- a/components/bt/porting/npl/freertos/src/npl_os_freertos.c +++ b/components/bt/porting/npl/freertos/src/npl_os_freertos.c @@ -1,9 +1,7 @@ /* - * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF) + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD */ #include @@ -18,7 +16,6 @@ #include "freertos/timers.h" #include "freertos/portable.h" #include "nimble/npl_freertos.h" -#include "nimble/nimble_port.h" #include "os/os_mempool.h" #include "esp_log.h" @@ -37,11 +34,19 @@ static const char *TAG = "Timer"; #error "not defined SOC_ESP_NIMBLE_CONTROLLER or SOC_ESP_NIMBLE_CONTROLLER is zero" #endif +#if CONFIG_BT_NIMBLE_ENABLED #define BLE_HOST_CO_COUNT (8) #define BLE_HOST_EV_COUNT (11 + BLE_HOST_CO_COUNT) #define BLE_HOST_EVQ_COUNT (3) #define BLE_HOST_SEM_COUNT (10) #define BLE_HOST_MUTEX_COUNT (4) +#else +#define BLE_HOST_CO_COUNT (0) +#define BLE_HOST_EV_COUNT (0) +#define BLE_HOST_EVQ_COUNT (0) +#define BLE_HOST_SEM_COUNT (0) +#define BLE_HOST_MUTEX_COUNT (0) +#endif struct os_mempool ble_freertos_ev_pool; static os_membuf_t *ble_freertos_ev_buf = NULL; @@ -133,6 +138,9 @@ npl_freertos_eventq_init(struct ble_npl_eventq *evq) memset(eventq, 0, sizeof(*eventq)); eventq->q = xQueueCreate(ble_freertos_total_event_cnt, sizeof(struct ble_npl_eventq *)); BLE_LL_ASSERT(eventq->q); + } else { + eventq = (struct ble_npl_eventq_freertos*)evq->eventq; + xQueueReset(eventq->q); } #else if(!evq->eventq) { @@ -142,6 +150,9 @@ npl_freertos_eventq_init(struct ble_npl_eventq *evq) memset(eventq, 0, sizeof(*eventq)); eventq->q = xQueueCreate(ble_freertos_total_event_cnt, sizeof(struct ble_npl_eventq *)); BLE_LL_ASSERT(eventq->q); + } else { + eventq = (struct ble_npl_eventq_freertos*)evq->eventq; + xQueueReset(eventq->q); } #endif } @@ -234,6 +245,32 @@ IRAM_ATTR npl_freertos_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_eve BLE_LL_ASSERT(ret == pdPASS); } +void +IRAM_ATTR npl_freertos_eventq_put_to_front(struct ble_npl_eventq *evq, struct ble_npl_event *ev) +{ + BaseType_t woken; + BaseType_t ret; + struct ble_npl_eventq_freertos *eventq = (struct ble_npl_eventq_freertos *)evq->eventq; + struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event; + + if (event->queued) { + return; + } + + event->queued = true; + + if (in_isr()) { + ret = xQueueSendToFrontFromISR(eventq->q, &ev, &woken); + if( woken == pdTRUE ) { + portYIELD_FROM_ISR(); + } + } else { + ret = xQueueSendToFront(eventq->q, &ev, portMAX_DELAY); + } + + BLE_LL_ASSERT(ret == pdPASS); +} + void IRAM_ATTR npl_freertos_eventq_remove(struct ble_npl_eventq *evq, struct ble_npl_event *ev) @@ -441,32 +478,32 @@ IRAM_ATTR npl_freertos_mutex_release(struct ble_npl_mutex *mu) ble_npl_error_t npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens) { - struct ble_npl_sem_freertos *semaphor = NULL; + struct ble_npl_sem_freertos *semaphore = NULL; #if OS_MEM_ALLOC if (!os_memblock_from(&ble_freertos_sem_pool,sem->sem)) { sem->sem = os_memblock_get(&ble_freertos_sem_pool); - semaphor = (struct ble_npl_sem_freertos *)sem->sem; + semaphore = (struct ble_npl_sem_freertos *)sem->sem; - if (!semaphor) { + if (!semaphore) { return BLE_NPL_INVALID_PARAM; } - memset(semaphor, 0, sizeof(*semaphor)); - semaphor->handle = xSemaphoreCreateCounting(128, tokens); - BLE_LL_ASSERT(semaphor->handle); + memset(semaphore, 0, sizeof(*semaphore)); + semaphore->handle = xSemaphoreCreateCounting(128, tokens); + BLE_LL_ASSERT(semaphore->handle); } #else if(!sem->sem) { sem->sem = malloc(sizeof(struct ble_npl_sem_freertos)); - semaphor = (struct ble_npl_sem_freertos *)sem->sem; + semaphore = (struct ble_npl_sem_freertos *)sem->sem; - if (!semaphor) { + if (!semaphore) { return BLE_NPL_INVALID_PARAM; } - memset(semaphor, 0, sizeof(*semaphor)); - semaphor->handle = xSemaphoreCreateCounting(128, tokens); - BLE_LL_ASSERT(semaphor->handle); + memset(semaphore, 0, sizeof(*semaphore)); + semaphore->handle = xSemaphoreCreateCounting(128, tokens); + BLE_LL_ASSERT(semaphore->handle); } #endif @@ -476,19 +513,19 @@ npl_freertos_sem_init(struct ble_npl_sem *sem, uint16_t tokens) ble_npl_error_t npl_freertos_sem_deinit(struct ble_npl_sem *sem) { - struct ble_npl_sem_freertos *semaphor = (struct ble_npl_sem_freertos *)sem->sem; + struct ble_npl_sem_freertos *semaphore = (struct ble_npl_sem_freertos *)sem->sem; - if (!semaphor) { + if (!semaphore) { return BLE_NPL_INVALID_PARAM; } - BLE_LL_ASSERT(semaphor->handle); - vSemaphoreDelete(semaphor->handle); + BLE_LL_ASSERT(semaphore->handle); + vSemaphoreDelete(semaphore->handle); #if OS_MEM_ALLOC - os_memblock_put(&ble_freertos_sem_pool,semaphor); + os_memblock_put(&ble_freertos_sem_pool,semaphore); #else - free((void *)semaphor); + free((void *)semaphore); #endif sem->sem = NULL; @@ -500,22 +537,22 @@ IRAM_ATTR npl_freertos_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout) { BaseType_t woken; BaseType_t ret; - struct ble_npl_sem_freertos *semaphor = (struct ble_npl_sem_freertos *)sem->sem; + struct ble_npl_sem_freertos *semaphore = (struct ble_npl_sem_freertos *)sem->sem; - if (!semaphor) { + if (!semaphore) { return BLE_NPL_INVALID_PARAM; } - BLE_LL_ASSERT(semaphor->handle); + BLE_LL_ASSERT(semaphore->handle); if (in_isr()) { BLE_LL_ASSERT(timeout == 0); - ret = xSemaphoreTakeFromISR(semaphor->handle, &woken); + ret = xSemaphoreTakeFromISR(semaphore->handle, &woken); if( woken == pdTRUE ) { portYIELD_FROM_ISR(); } } else { - ret = xSemaphoreTake(semaphor->handle, timeout); + ret = xSemaphoreTake(semaphore->handle, timeout); } return ret == pdPASS ? BLE_NPL_OK : BLE_NPL_TIMEOUT; @@ -526,21 +563,21 @@ IRAM_ATTR npl_freertos_sem_release(struct ble_npl_sem *sem) { BaseType_t ret; BaseType_t woken; - struct ble_npl_sem_freertos *semaphor = (struct ble_npl_sem_freertos *)sem->sem; + struct ble_npl_sem_freertos *semaphore = (struct ble_npl_sem_freertos *)sem->sem; - if (!semaphor) { + if (!semaphore) { return BLE_NPL_INVALID_PARAM; } - BLE_LL_ASSERT(semaphor->handle); + BLE_LL_ASSERT(semaphore->handle); if (in_isr()) { - ret = xSemaphoreGiveFromISR(semaphor->handle, &woken); + ret = xSemaphoreGiveFromISR(semaphore->handle, &woken); if( woken == pdTRUE ) { portYIELD_FROM_ISR(); } } else { - ret = xSemaphoreGive(semaphor->handle); + ret = xSemaphoreGive(semaphore->handle); } BLE_LL_ASSERT(ret == pdPASS); @@ -720,12 +757,12 @@ npl_freertos_callout_deinit(struct ble_npl_callout *co) } #else xTimerDelete(callout->handle, portMAX_DELAY); +#endif // BLE_NPL_USE_ESP_TIMER #if OS_MEM_ALLOC os_memblock_put(&ble_freertos_co_pool,callout); #else free((void *)callout); #endif // OS_MEM_ALLOC -#endif // BLE_NPL_USE_ESP_TIMER co->co = NULL; memset(co, 0, sizeof(struct ble_npl_callout)); } @@ -733,8 +770,8 @@ npl_freertos_callout_deinit(struct ble_npl_callout *co) uint16_t IRAM_ATTR npl_freertos_sem_get_count(struct ble_npl_sem *sem) { - struct ble_npl_sem_freertos *semaphor = (struct ble_npl_sem_freertos *)sem->sem; - return uxSemaphoreGetCount(semaphor->handle); + struct ble_npl_sem_freertos *semaphore = (struct ble_npl_sem_freertos *)sem->sem; + return uxSemaphoreGetCount(semaphore->handle); } @@ -802,15 +839,35 @@ ble_npl_time_t IRAM_ATTR npl_freertos_callout_get_ticks(struct ble_npl_callout *co) { #if BLE_NPL_USE_ESP_TIMER - /* Currently, esp_timer does not support an API which gets the expiry time for - * current timer. - * Returning 0 from here should not cause any effect. + + uint32_t exp = 0; + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + uint64_t expiry = 0; + esp_err_t err; + + struct ble_npl_callout_freertos *callout = (struct ble_npl_callout_freertos *)co->co; + + //Fetch expiry time in microseconds + err = esp_timer_get_expiry_time((esp_timer_handle_t)(callout->handle), &expiry); + if (err != ESP_OK) { + //Error. Could not fetch the expiry time + return 0; + } + + //Convert microseconds to ticks + npl_freertos_time_ms_to_ticks((uint32_t)(expiry / 1000), &exp); +#else + //esp_timer_get_expiry_time() is only available from IDF 5.0 onwards + /* Returning 0 from here should not cause any effect. * Drawback of this approach is that existing code to reset timer would be called * more often (since the if condition to invoke reset timer would always succeed if * timer is active). */ + exp = 0; +#endif //ESP_IDF_VERSION - return 0; + return exp; #else struct ble_npl_callout_freertos *callout = (struct ble_npl_callout_freertos *)co->co; return xTimerGetExpiryTime(callout->handle); @@ -980,6 +1037,7 @@ const struct npl_funcs_t npl_funcs_ro = { .p_ble_npl_eventq_deinit = npl_freertos_eventq_deinit, .p_ble_npl_eventq_get = npl_freertos_eventq_get, .p_ble_npl_eventq_put = npl_freertos_eventq_put, + .p_ble_npl_eventq_put_to_front = npl_freertos_eventq_put_to_front, .p_ble_npl_eventq_remove = npl_freertos_eventq_remove, .p_ble_npl_event_run = npl_freertos_event_run, .p_ble_npl_eventq_is_empty = npl_freertos_eventq_is_empty, diff --git a/components/bt/porting/transport/driver/common/hci_driver_h4.c b/components/bt/porting/transport/driver/common/hci_driver_h4.c new file mode 100644 index 0000000000..c31b71164e --- /dev/null +++ b/components/bt/porting/transport/driver/common/hci_driver_h4.c @@ -0,0 +1,356 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +#include +#include +#include +#include +#include +#include "common/hci_driver_h4.h" + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#define HCI_H4_SM_W4_PKT_TYPE 0 +#define HCI_H4_SM_W4_HEADER 1 +#define HCI_H4_SM_W4_PAYLOAD 2 +#define HCI_H4_SM_COMPLETED 3 + +struct hci_h4_input_buffer { + const uint8_t *buf; + uint16_t len; +}; + +static int +hci_h4_frame_start(struct hci_h4_sm *rxs, uint8_t pkt_type) +{ + rxs->pkt_type = pkt_type; + rxs->len = 0; + rxs->exp_len = 0; + + switch (rxs->pkt_type) { + case HCI_H4_CMD: + rxs->min_len = 3; + break; + case HCI_H4_ACL: + case HCI_H4_ISO: + rxs->min_len = 4; + break; + case HCI_H4_EVT: + rxs->min_len = 2; + break; + default: + /* !TODO: Sync loss. Need to wait for reset. */ + return -1; + } + + return 0; +} + +static int +hci_h4_ib_consume(struct hci_h4_input_buffer *ib, uint16_t len) +{ + assert(ib->len >= len); + + ib->buf += len; + ib->len -= len; + + return len; +} + +static int +hci_h4_ib_pull_min_len(struct hci_h4_sm *rxs, + struct hci_h4_input_buffer *ib) +{ + uint16_t len; + + len = min(ib->len, rxs->min_len - rxs->len); + memcpy(&rxs->hdr[rxs->len], ib->buf, len); + + rxs->len += len; + hci_h4_ib_consume(ib, len); + + + return rxs->len != rxs->min_len; +} + +static int +hci_h4_sm_w4_header(struct hci_h4_sm *h4sm, struct hci_h4_input_buffer *ib) +{ + int rc; + + rc = hci_h4_ib_pull_min_len(h4sm, ib); + if (rc) { + /* need more data */ + return 1; + } + + switch (h4sm->pkt_type) { + case HCI_H4_CMD: + assert(h4sm->allocs && h4sm->allocs->cmd); + h4sm->buf = h4sm->allocs->cmd(); + if (!h4sm->buf) { + return -1; + } + + memcpy(h4sm->buf, h4sm->hdr, h4sm->len); + h4sm->exp_len = h4sm->hdr[2] + 3; + + break; + case HCI_H4_ACL: + assert(h4sm->allocs && h4sm->allocs->acl); + h4sm->om = h4sm->allocs->acl(); + if (!h4sm->om) { + return -1; + } + + os_mbuf_append(h4sm->om, h4sm->hdr, h4sm->len); + h4sm->exp_len = get_le16(&h4sm->hdr[2]) + 4; + break; +#if !CONFIG_BT_CONTROLLER_ENABLED + case HCI_H4_EVT: + if (h4sm->hdr[0] == BLE_HCI_EVCODE_LE_META) { + /* For LE Meta event we need 3 bytes to parse header */ + h4sm->min_len = 3; + rc = hci_h4_ib_pull_min_len(h4sm, ib); + if (rc) { + /* need more data */ + return 1; + } + } + + assert(h4sm->allocs && h4sm->allocs->evt); + + /* We can drop legacy advertising events if there's no free buffer in + * discardable pool. + */ + if (h4sm->hdr[2] == BLE_HCI_LE_SUBEV_ADV_RPT) { + h4sm->buf = h4sm->allocs->evt(1); + } else { + h4sm->buf = h4sm->allocs->evt(0); + if (!h4sm->buf) { + return -1; + } + } + + if (h4sm->buf) { + memcpy(h4sm->buf, h4sm->hdr, h4sm->len); + } + + h4sm->exp_len = h4sm->hdr[1] + 2; + break; +#endif // !CONFIG_BT_CONTROLLER_ENABLED + case HCI_H4_ISO: + assert(h4sm->allocs && h4sm->allocs->iso); + h4sm->om = h4sm->allocs->iso(); + if (!h4sm->om) { + return -1; + } + + os_mbuf_append(h4sm->om, h4sm->hdr, h4sm->len); + h4sm->exp_len = (get_le16(&h4sm->hdr[2]) & 0x7fff) + 4; + break; + default: + assert(0); + break; + } + + return 0; +} + +static int +hci_h4_sm_w4_payload(struct hci_h4_sm *h4sm, + struct hci_h4_input_buffer *ib) +{ + uint16_t mbuf_len; + uint16_t len; + int rc; + + len = min(ib->len, h4sm->exp_len - h4sm->len); + + + switch (h4sm->pkt_type) { + case HCI_H4_CMD: + case HCI_H4_EVT: + if (h4sm->buf) { + memcpy(&h4sm->buf[h4sm->len], ib->buf, len); + } + break; + case HCI_H4_ACL: + case HCI_H4_ISO: + assert(h4sm->om); + + mbuf_len = OS_MBUF_PKTLEN(h4sm->om); + rc = os_mbuf_append(h4sm->om, ib->buf, len); + if (rc) { + /* Some data may already be appended so need to adjust h4sm only by + * the size of appended data. + */ + len = OS_MBUF_PKTLEN(h4sm->om) - mbuf_len; + h4sm->len += len; + hci_h4_ib_consume(ib, len); + + return -1; + } + break; + default: + assert(0); + break; + } + + h4sm->len += len; + hci_h4_ib_consume(ib, len); + + /* return 1 if need more data */ + return h4sm->len != h4sm->exp_len; +} + +static void +hci_h4_sm_completed(struct hci_h4_sm *h4sm) +{ + int rc; + + switch (h4sm->pkt_type) { +#if CONFIG_BT_CONTROLLER_ENABLED + case HCI_H4_CMD: + if (h4sm->buf) { + assert(h4sm->frame_cb); + rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->buf); + assert(rc == 0); + h4sm->buf = NULL; + } + break; + case HCI_H4_ACL: + case HCI_H4_ISO: + if (h4sm->om) { + assert(h4sm->frame_cb); + rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->om); + assert(rc == 0); + h4sm->om = NULL; + } + break; +#else + case HCI_H4_CMD: + case HCI_H4_EVT: + if (h4sm->buf) { + assert(h4sm->frame_cb); + rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->buf); + if (rc != 0) { + ble_transport_free(h4sm->buf); + } + h4sm->buf = NULL; + } + break; + case HCI_H4_ACL: + case HCI_H4_ISO: + if (h4sm->om) { + assert(h4sm->frame_cb); + rc = h4sm->frame_cb(h4sm->pkt_type, h4sm->om); + if (rc != 0) { + os_mbuf_free_chain(h4sm->om); + } + h4sm->om = NULL; + } + break; +#endif // CONFIG_BT_CONTROLLER_ENABLED + default: + assert(0); + break; + } +} + +int +hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len) +{ + struct hci_h4_input_buffer ib = { + .buf = buf, + .len = len, + }; + + int rc = 0; + while (ib.len && (rc >= 0)) { + rc = 0; + switch (h4sm->state) { + case HCI_H4_SM_W4_PKT_TYPE: + if (hci_h4_frame_start(h4sm, ib.buf[0]) < 0) { + return -1; + } + + hci_h4_ib_consume(&ib, 1); + h4sm->state = HCI_H4_SM_W4_HEADER; + /* no break */ + case HCI_H4_SM_W4_HEADER: + rc = hci_h4_sm_w4_header(h4sm, &ib); + assert(rc >= 0); + if (rc) { + break; + } + h4sm->state = HCI_H4_SM_W4_PAYLOAD; + /* no break */ + case HCI_H4_SM_W4_PAYLOAD: + rc = hci_h4_sm_w4_payload(h4sm, &ib); + assert(rc >= 0); + if (rc) { + break; + } + h4sm->state = HCI_H4_SM_COMPLETED; + /* no break */ + case HCI_H4_SM_COMPLETED: + hci_h4_sm_completed(h4sm); + h4sm->state = HCI_H4_SM_W4_PKT_TYPE; + break; + default: + return -1; + } + } + + /* Calculate consumed bytes + * + * Note: we should always consume some bytes unless there is an oom error. + * It's also possible that we have an oom error but already consumed some + * data, in such case just return success and error will be returned on next + * pass. + */ + len = len - ib.len; + if (len == 0) { + assert(rc < 0); + return -1; + } + + return len; +} + +void +hci_h4_sm_init(struct hci_h4_sm *h4sm, const struct hci_h4_allocators *allocs, + hci_h4_frame_cb *frame_cb) +{ + memset(h4sm, 0, sizeof(*h4sm)); + h4sm->allocs = allocs; + h4sm->frame_cb = frame_cb; +} diff --git a/components/bt/porting/transport/driver/common/hci_driver_mem.c b/components/bt/porting/transport/driver/common/hci_driver_mem.c new file mode 100644 index 0000000000..acfdf793f6 --- /dev/null +++ b/components/bt/porting/transport/driver/common/hci_driver_mem.c @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "common/hci_driver_mem.h" +#include "common/hci_driver_h4.h" +#include "esp_hci_internal.h" + +void * +hci_driver_mem_cmd_alloc(void) +{ + return r_ble_hci_trans_buf_alloc(ESP_HCI_INTERNAL_BUF_CMD); +} + +void * +hci_driver_mem_evt_alloc(int discardable) +{ + /* The controller shouldn't invoke this. */ + assert(0); + return NULL; +} + +struct os_mbuf * +hci_driver_mem_acl_alloc(void) +{ + return os_msys_get_pkthdr(0, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); +} + +struct os_mbuf * +hci_driver_mem_acl_len_alloc(uint32_t len) +{ + return os_msys_get_pkthdr(len, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); +} + +struct os_mbuf * +hci_driver_mem_iso_alloc(void) +{ + return os_msys_get_pkthdr(0, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); +} + +struct os_mbuf * +hci_driver_mem_iso_len_alloc(uint32_t len) +{ + return os_msys_get_pkthdr(len, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); +} + +const struct hci_h4_allocators s_hci_driver_mem_alloc = { + .cmd = hci_driver_mem_cmd_alloc, + .evt = hci_driver_mem_evt_alloc, + .acl = hci_driver_mem_acl_alloc, + .iso = hci_driver_mem_iso_alloc, +}; diff --git a/components/bt/porting/transport/driver/common/hci_driver_util.c b/components/bt/porting/transport/driver/common/hci_driver_util.c new file mode 100644 index 0000000000..30fe8d13c4 --- /dev/null +++ b/components/bt/porting/transport/driver/common/hci_driver_util.c @@ -0,0 +1,225 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "esp_log.h" +#include "os/os.h" +#include "os/os_mempool.h" +#include "esp_hci_driver.h" +#include "esp_hci_internal.h" +#include "common/hci_driver_util.h" + +#define TAG "HCI_UTIL" +#define HCI_DRIVER_UTIL_TX_POOL_NUM \ + (CONFIG_BT_LE_ACL_BUF_COUNT + CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT + CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT) + +#ifndef min +#define min(a, b) ((a) < (b) ? (a) : (b)) +#endif + +/** + * @brief Structure representing HCI TX data. + */ +typedef struct hci_driver_util_tx_entry { + hci_driver_data_type_t data_type; ///< Type of the HCI TX data. + uint8_t *data; ///< Pointer to the TX data. + uint32_t length; ///< Length of the TX data. + STAILQ_ENTRY(hci_driver_util_tx_entry) next; ///< Next element in the linked list. +} hci_driver_util_tx_entry_t; + +/* The list for hci_driver_util_tx_entry */ +STAILQ_HEAD(hci_driver_util_tx_list, hci_driver_util_tx_entry); + +typedef struct { + struct hci_driver_util_tx_list tx_head; + struct hci_driver_util_tx_entry *cur_tx_entry; + uint32_t cur_tx_off; + struct os_mempool *tx_entry_pool; + uint8_t *tx_entry_mem; +} hci_driver_util_env_t; + +static hci_driver_util_env_t s_hci_driver_util_env; + +static void +hci_driver_util_memory_deinit(void) +{ + if (s_hci_driver_util_env.tx_entry_pool) { + free(s_hci_driver_util_env.tx_entry_pool); + s_hci_driver_util_env.tx_entry_pool = NULL; + } + if (s_hci_driver_util_env.tx_entry_mem) { + free(s_hci_driver_util_env.tx_entry_mem); + s_hci_driver_util_env.tx_entry_mem = NULL; + } +} + +static int +hci_driver_util_memory_init(void) +{ + int rc; + + s_hci_driver_util_env.tx_entry_pool = (struct os_mempool *)malloc(sizeof(struct os_mempool)); + if (!s_hci_driver_util_env.tx_entry_pool) { + ESP_LOGE(TAG, "No memory for tx pool"); + goto init_err; + } + + s_hci_driver_util_env.tx_entry_mem = malloc(OS_MEMPOOL_SIZE(HCI_DRIVER_UTIL_TX_POOL_NUM, + sizeof(hci_driver_util_tx_entry_t)) * sizeof(os_membuf_t)); + if (!s_hci_driver_util_env.tx_entry_mem) { + ESP_LOGE(TAG, "No memory for tx pool buffer"); + goto init_err; + } + + rc = os_mempool_init(s_hci_driver_util_env.tx_entry_pool, HCI_DRIVER_UTIL_TX_POOL_NUM, + sizeof(hci_driver_util_tx_entry_t), s_hci_driver_util_env.tx_entry_mem, + "hci_tx_entry_pool"); + if (rc) { + ESP_LOGE(TAG, "Failed to initialize tx pool"); + goto init_err; + } + + return 0; + +init_err: + hci_driver_util_memory_deinit(); + return -1; +} + +void +hci_driver_util_tx_list_enqueue(hci_driver_data_type_t type, uint8_t *data, uint32_t len) +{ + os_sr_t sr; + hci_driver_util_tx_entry_t *tx_entry; + + tx_entry = os_memblock_get(s_hci_driver_util_env.tx_entry_pool); + assert(tx_entry != NULL); + tx_entry->data_type = type; + tx_entry->data = data; + tx_entry->length = len; + /* If the txbuf is command status event or command complete event, we should send firstly. + * The tx list maybe used in the controller task and hci task. Therefore, enter critical area. + */ + if ((type == HCI_DRIVER_TYPE_EVT) && ((data[0] == 0x0E) || (data[0] == 0x0F))) { + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_HEAD(&s_hci_driver_util_env.tx_head, tx_entry, next); + OS_EXIT_CRITICAL(sr); + } else { + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&s_hci_driver_util_env.tx_head, tx_entry, next); + OS_EXIT_CRITICAL(sr); + } +} + +uint32_t +hci_driver_util_tx_list_dequeue(uint32_t max_tx_len, void **tx_data, bool *last_frame) +{ + os_sr_t sr; + uint32_t tx_len; + uint32_t data_len; + uint16_t out_off; + struct os_mbuf *om; + hci_driver_util_tx_entry_t *tx_entry; + + /* Check if there is any remaining data that hasn't been sent completely. If it has been completed, + * free the corresponding memory. Therefore, the HCI TX entry needs to be sent one by one; multiple + * entries cannot be sent together. + */ + tx_len = 0; + tx_entry = s_hci_driver_util_env.cur_tx_entry; + if (tx_entry) { + data_len = tx_entry->length; + if (tx_entry->data_type == HCI_DRIVER_TYPE_ACL) { + om = (struct os_mbuf *)tx_entry->data; + if (s_hci_driver_util_env.cur_tx_off >= data_len) { + os_mbuf_free_chain(om); + } else { + om = os_mbuf_off(om, s_hci_driver_util_env.cur_tx_off, &out_off); + tx_len = min(max_tx_len, om->om_len - out_off); + *tx_data = (void *)&om->om_data[out_off]; + } + } else if (tx_entry->data_type == HCI_DRIVER_TYPE_EVT) { + if (s_hci_driver_util_env.cur_tx_off >= data_len) { + r_ble_hci_trans_buf_free(tx_entry->data); + } else { + tx_len = min(max_tx_len, data_len - s_hci_driver_util_env.cur_tx_off); + *tx_data = &tx_entry->data[s_hci_driver_util_env.cur_tx_off]; + } + } else { + assert(0); + } + /* If this is the last frame, inform the invoker not to call this API until the current data + * has been completely sent. + */ + if (tx_len) { + s_hci_driver_util_env.cur_tx_off += tx_len; + + if (s_hci_driver_util_env.cur_tx_off >= data_len) { + *last_frame = true; + } else { + *last_frame = false; + } + } else { + os_memblock_put(s_hci_driver_util_env.tx_entry_pool, (void *)tx_entry); + s_hci_driver_util_env.cur_tx_entry = NULL; + } + } + + /* Find a new entry. */ + if (!tx_len && !STAILQ_EMPTY(&s_hci_driver_util_env.tx_head)) { + OS_ENTER_CRITICAL(sr); + tx_entry = STAILQ_FIRST(&s_hci_driver_util_env.tx_head); + STAILQ_REMOVE_HEAD(&s_hci_driver_util_env.tx_head, next); + OS_EXIT_CRITICAL(sr); + + *tx_data = &tx_entry->data_type; + s_hci_driver_util_env.cur_tx_entry = tx_entry; + s_hci_driver_util_env.cur_tx_off = 0; + tx_len = 1; + *last_frame = false; + } + + return tx_len; +} + +int +hci_driver_util_init(void) +{ + memset(&s_hci_driver_util_env, 0, sizeof(hci_driver_util_env_t)); + + if (hci_driver_util_memory_init()) { + return -1; + } + + STAILQ_INIT(&s_hci_driver_util_env.tx_head); + + return 0; +} + +void +hci_driver_util_deinit(void) +{ + hci_driver_util_tx_entry_t *tx_entry; + hci_driver_util_tx_entry_t *next_entry; + + /* Free all of controller buffers which haven't been sent yet. The whole mempool will be freed. + * Therefore, it's unnecessary to put the tx_entry into mempool. + */ + tx_entry = STAILQ_FIRST(&s_hci_driver_util_env.tx_head); + while (tx_entry) { + next_entry = STAILQ_NEXT(tx_entry, next); + if (tx_entry->data_type == HCI_DRIVER_TYPE_ACL) { + os_mbuf_free_chain((struct os_mbuf *)tx_entry->data); + } else if (tx_entry->data_type == HCI_DRIVER_TYPE_EVT) { + r_ble_hci_trans_buf_free(tx_entry->data); + } + tx_entry = next_entry; + } + + hci_driver_util_memory_deinit(); + + memset(&s_hci_driver_util_env, 0, sizeof(hci_driver_util_env_t)); +} diff --git a/components/bt/porting/transport/driver/uart/hci_driver_uart.c b/components/bt/porting/transport/driver/uart/hci_driver_uart.c new file mode 100644 index 0000000000..6ac2a462fa --- /dev/null +++ b/components/bt/porting/transport/driver/uart/hci_driver_uart.c @@ -0,0 +1,222 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "esp_log.h" +#include "driver/uart.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" +#include "common/hci_driver_h4.h" +#include "common/hci_driver_util.h" +#include "common/hci_driver_mem.h" +#include "hci_driver_uart.h" + +static const char *TAG = "hci_uart"; + +#define CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN (256) + +typedef struct { + TaskHandle_t tx_task_handler; + TaskHandle_t rx_task_handler; + hci_driver_uart_params_config_t *hci_uart_params; + SemaphoreHandle_t tx_sem; + QueueHandle_t rx_event_queue; + uint8_t *rx_data; + struct hci_h4_sm *h4_sm; + hci_driver_forward_fn *forward_cb; +} hci_driver_uart_env_t; + +static hci_driver_uart_env_t s_hci_driver_uart_env; +static struct hci_h4_sm s_hci_driver_uart_h4_sm; +static uint8_t s_hci_driver_uart_rx_data[CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN]; +static hci_driver_uart_params_config_t hci_driver_uart_params = BT_HCI_DRIVER_UART_CONFIG_DEFAULT(); + +static int +hci_driver_uart_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + /* By now, this layer is only used by controller. */ + assert(dir == HCI_DRIVER_DIR_C2H); + ESP_LOGD(TAG, "controller tx len:%d\n", length); + + hci_driver_util_tx_list_enqueue(data_type, data, length); + xSemaphoreGive(s_hci_driver_uart_env.tx_sem); + + return 0; +} + +static int +hci_driver_uart_h4_frame_cb(uint8_t pkt_type, void *data) +{ + hci_driver_forward_fn *forward_cb; + + forward_cb = s_hci_driver_uart_env.forward_cb; + if (!forward_cb) { + return -1; + } + ESP_LOGD(TAG, "h4 frame\n"); + return forward_cb(pkt_type, data, 0, HCI_DRIVER_DIR_H2C); +} + +static void +hci_driver_uart_tx_task(void *p) +{ + void *data; + bool last_frame; + uint32_t tx_len; + uart_port_t port; + + port = s_hci_driver_uart_env.hci_uart_params->hci_uart_port; + while (true) { + xSemaphoreTake(s_hci_driver_uart_env.tx_sem, portMAX_DELAY); + while (true) { + tx_len = hci_driver_util_tx_list_dequeue(0xffffff, &data, &last_frame); + if (tx_len == 0) { + break; + } + ESP_LOGD(TAG, "uart tx"); + ESP_LOG_BUFFER_HEXDUMP(TAG, data, tx_len, ESP_LOG_DEBUG); + uart_write_bytes(port, data, tx_len); + } + } +} + +static void +hci_driver_uart_rx_task(void *p) +{ + void *data; + int read_len; + int ret; + uart_port_t port; + uart_event_t uart_event; + + port = s_hci_driver_uart_env.hci_uart_params->hci_uart_port; + while (true) { + xQueueReceive(s_hci_driver_uart_env.rx_event_queue, &uart_event, portMAX_DELAY); + data = s_hci_driver_uart_env.rx_data; + while (true) { + read_len = uart_read_bytes(port, data, CONFIG_BT_LE_HCI_RX_PROC_DATA_LEN, 0); + if (read_len == 0) { + break; + } + ESP_LOGD(TAG, "uart rx"); + ESP_LOG_BUFFER_HEXDUMP(TAG, data, read_len, ESP_LOG_DEBUG); + ret = hci_h4_sm_rx(s_hci_driver_uart_env.h4_sm, data, read_len); + if (ret < 0) { + r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR); + } + } + } +} + +static int +hci_driver_uart_task_create(void) +{ + /* !TODO: Set the core id by menuconfig */ + xTaskCreatePinnedToCore(hci_driver_uart_tx_task, "hci_driver_uart_tx_task", + CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE, NULL, + ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_env.tx_task_handler, + 0); + assert(s_hci_driver_uart_env.tx_task_handler); + + xTaskCreatePinnedToCore(hci_driver_uart_rx_task, "hci_driver_uart_rx_task", + CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE, NULL, + ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_env.rx_task_handler, + 0); + assert(s_hci_driver_uart_env.rx_task_handler); + + ESP_LOGI(TAG, "hci transport task create successfully, prio:%d, stack size: %ld", + ESP_TASK_BT_CONTROLLER_PRIO, CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE); + + return 0; +} + +static void +hci_driver_uart_deinit(void) +{ + if (s_hci_driver_uart_env.tx_task_handler) { + vTaskDelete(s_hci_driver_uart_env.tx_task_handler); + s_hci_driver_uart_env.tx_task_handler = NULL; + } + + if (s_hci_driver_uart_env.rx_task_handler) { + vTaskDelete(s_hci_driver_uart_env.rx_task_handler); + s_hci_driver_uart_env.rx_task_handler = NULL; + } + + ESP_ERROR_CHECK(uart_driver_delete(s_hci_driver_uart_env.hci_uart_params->hci_uart_port)); + + if (!s_hci_driver_uart_env.tx_sem) { + vSemaphoreDelete(s_hci_driver_uart_env.tx_sem); + } + + hci_driver_util_deinit(); + memset(&s_hci_driver_uart_env, 0, sizeof(hci_driver_uart_env_t)); +} + +static int +hci_driver_uart_init(hci_driver_forward_fn *cb) +{ + int rc; + memset(&s_hci_driver_uart_env, 0, sizeof(hci_driver_uart_env_t)); + + s_hci_driver_uart_env.h4_sm = &s_hci_driver_uart_h4_sm; + hci_h4_sm_init(s_hci_driver_uart_env.h4_sm, &s_hci_driver_mem_alloc, hci_driver_uart_h4_frame_cb); + + rc = hci_driver_util_init(); + if (rc) { + goto error; + } + + s_hci_driver_uart_env.tx_sem = xSemaphoreCreateBinary(); + if (!s_hci_driver_uart_env.tx_sem) { + goto error; + } + + s_hci_driver_uart_env.rx_data = s_hci_driver_uart_rx_data; + s_hci_driver_uart_env.forward_cb = cb; + s_hci_driver_uart_env.hci_uart_params = &hci_driver_uart_params; + hci_driver_uart_config(&hci_driver_uart_params); + /* Currently, the queue size is set to 1. It will be considered as semaphore. */ + ESP_ERROR_CHECK(uart_driver_install(s_hci_driver_uart_env.hci_uart_params->hci_uart_port, + CONFIG_BT_LE_HCI_UART_RX_BUFFER_SIZE, + CONFIG_BT_LE_HCI_UART_TX_BUFFER_SIZE, + 1, &s_hci_driver_uart_env.rx_event_queue, + 0)); + + rc = hci_driver_uart_task_create(); + if (rc) { + goto error; + } + + return 0; + +error: + hci_driver_uart_deinit(); + return rc; +} + +int +hci_driver_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin) +{ + hci_driver_uart_params_config_t *uart_param = s_hci_driver_uart_env.hci_uart_params; + uart_param->hci_uart_tx_pin = tx_pin; + uart_param->hci_uart_rx_pin = rx_pin; + uart_param->hci_uart_rts_pin = rts_pin; + uart_param->hci_uart_cts_pin = cts_pin; + return hci_driver_uart_config(uart_param); +} + +hci_driver_ops_t hci_driver_uart_ops = { + .hci_driver_tx = hci_driver_uart_tx, + .hci_driver_init = hci_driver_uart_init, + .hci_driver_deinit = hci_driver_uart_deinit, +}; diff --git a/components/bt/porting/transport/driver/uart/hci_driver_uart.h b/components/bt/porting/transport/driver/uart/hci_driver_uart.h new file mode 100644 index 0000000000..8b5f5eb856 --- /dev/null +++ b/components/bt/porting/transport/driver/uart/hci_driver_uart.h @@ -0,0 +1,97 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif +#include +#include "driver/uart.h" +#include "os/os_mbuf.h" +#include "esp_bt.h" +#include "esp_hci_transport.h" + +/** + * @brief UART configuration parameters for the HCI driver + */ +typedef struct hci_driver_uart_params_config +{ + uint8_t hci_uart_port; /*!< Port of UART for HCI */ + uint8_t hci_uart_data_bits; /*!< Data bits of UART for HCI */ + uint8_t hci_uart_stop_bits; /*!< Stop bits of UART for HCI */ + uint8_t hci_uart_flow_ctrl; /*!< Flow control of UART for HCI */ + uint8_t hci_uart_parity; /*!< UART parity */ + uint8_t hci_uart_driver_mode; /*!< UART driver mode */ + uint32_t hci_uart_baud; /*!< Baudrate of UART for HCI */ + int hci_uart_tx_pin; /*!< Tx Pin number of UART for HCI */ + int hci_uart_rx_pin; /*!< Rx Pin number of UART for HCI */ + int hci_uart_rts_pin; /*!< RTS Pin number of UART for HCI */ + int hci_uart_cts_pin; /*!< CTS Pin number of UART for HCI */ +} hci_driver_uart_params_config_t; + +#define BT_HCI_DRIVER_UART_CONFIG_DEFAULT() { \ + .hci_uart_port = DEFAULT_BT_LE_HCI_UART_PORT, \ + .hci_uart_baud = DEFAULT_BT_LE_HCI_UART_BAUD, \ + .hci_uart_tx_pin = DEFAULT_BT_LE_HCI_UART_TX_PIN , \ + .hci_uart_rx_pin = DEFAULT_BT_LE_HCI_UART_RX_PIN, \ + .hci_uart_cts_pin = DEFAULT_BT_LE_HCI_UART_CTS_PIN, \ + .hci_uart_rts_pin = DEFAULT_BT_LE_HCI_UART_RTS_PIN, \ + .hci_uart_data_bits = DEFAULT_BT_LE_HCI_UART_DATA_BITS, \ + .hci_uart_stop_bits = DEFAULT_BT_LE_HCI_UART_STOP_BITS, \ + .hci_uart_flow_ctrl = DEFAULT_BT_LE_HCI_UART_FLOW_CTRL, \ + .hci_uart_parity = DEFAULT_BT_LE_HCI_UART_PARITY, \ +} + +/** + * @brief Configures the HCI driver UART parameters. + * This function sets up the UART interface according to the specified configuration parameters. + * + * @param uart_config A pointer to a structure containing the UART configuration parameters. + * The structure should include details such as baud rate, parity, stop bits, and flow control. + * Ensure that the uart_config structure is correctly initialized before calling this function. + * + * @return int Returns 0 on success, or a non-zero error code on failure. + * + * @note This function should be called before any UART communication is initiated. + */ +int hci_driver_uart_config(hci_driver_uart_params_config_t *uart_config); + +#if CONFIG_BT_LE_UART_HCI_DMA_MODE +/** + * @brief Reconfigure the UART pins for the HCI driver. + * + * This function changes the UART pin configuration for the HCI driver. + * + * @param tx_pin The pin number for the UART TX (transmit) line. + * @param rx_pin The pin number for the UART RX (receive) line. + * @param cts_pin The pin number for the UART CTS (clear to send) line. + * @param rts_pin The pin number for the UART RTS (request to send) line. + * + * @return int Returns 0 on success, or a negative error code on failure. + */ +int hci_driver_uart_dma_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin); +#define hci_uart_reconfig_pin hci_driver_uart_dma_reconfig_pin +#else +/** + * @brief Reconfigure the UART pins for the HCI driver. + * + * This function changes the UART pin configuration for the HCI driver. + * + * @param tx_pin The pin number for the UART TX (transmit) line. + * @param rx_pin The pin number for the UART RX (receive) line. + * @param cts_pin The pin number for the UART CTS (clear to send) line. + * @param rts_pin The pin number for the UART RTS (request to send) line. + * + * @return int Returns 0 on success, or a negative error code on failure. + */ +int hci_driver_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin); +#define hci_uart_reconfig_pin hci_driver_uart_reconfig_pin +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE + +#ifdef __cplusplus +} +#endif diff --git a/components/bt/porting/transport/driver/uart/hci_driver_uart_config.c b/components/bt/porting/transport/driver/uart/hci_driver_uart_config.c new file mode 100644 index 0000000000..8bb6494e10 --- /dev/null +++ b/components/bt/porting/transport/driver/uart/hci_driver_uart_config.c @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_log.h" +#include "driver/uart.h" +#include "hci_driver_uart.h" + + +static const char *TAG = "hci_uart_config"; +static uart_config_t s_uart_cfg; + +int hci_driver_uart_config(hci_driver_uart_params_config_t *uart_config) +{ + uart_config_t *uart_cfg; + uart_cfg = &s_uart_cfg; + uart_cfg->baud_rate = uart_config->hci_uart_baud; + uart_cfg->data_bits = uart_config->hci_uart_data_bits; + uart_cfg->stop_bits = uart_config->hci_uart_stop_bits; + uart_cfg->parity = uart_config->hci_uart_parity; + uart_cfg->flow_ctrl = uart_config->hci_uart_flow_ctrl; + uart_cfg->source_clk= UART_SCLK_DEFAULT; + uart_cfg->rx_flow_ctrl_thresh = UART_FIFO_LEN - 1; + + ESP_LOGI(TAG,"set uart pin tx:%d, rx:%d.\n", uart_config->hci_uart_tx_pin, uart_config->hci_uart_rx_pin); + ESP_LOGI(TAG,"set rts:%d, cts:%d.\n", uart_config->hci_uart_rts_pin, uart_config->hci_uart_cts_pin); + ESP_LOGI(TAG,"set baud_rate:%d.\n", uart_config->hci_uart_baud); + ESP_LOGI(TAG,"set flow_ctrl:%d.\n", uart_config->hci_uart_flow_ctrl); + + ESP_ERROR_CHECK(uart_driver_delete(uart_config->hci_uart_port)); + ESP_ERROR_CHECK(uart_param_config(uart_config->hci_uart_port, uart_cfg)); + ESP_ERROR_CHECK(uart_set_pin(uart_config->hci_uart_port, uart_config->hci_uart_tx_pin, uart_config->hci_uart_rx_pin, + uart_config->hci_uart_rts_pin, uart_config->hci_uart_cts_pin)); + return 0; +} diff --git a/components/bt/porting/transport/driver/uart/hci_driver_uart_dma.c b/components/bt/porting/transport/driver/uart/hci_driver_uart_dma.c new file mode 100644 index 0000000000..3111a7cea3 --- /dev/null +++ b/components/bt/porting/transport/driver/uart/hci_driver_uart_dma.c @@ -0,0 +1,671 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "esp_log.h" +#include "driver/uart.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" +#include "common/hci_driver_h4.h" +#include "common/hci_driver_util.h" +#include "common/hci_driver_mem.h" +#include "hci_driver_uart.h" + +#include "ble_hci_trans.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/gdma.h" +#include "hal/uhci_ll.h" + +/* + * UART DMA Desc struct + * + * -------------------------------------------------------------- + * | own | EoF | sub_sof | 5'b0 | length [11:0] | size [11:0] | + * -------------------------------------------------------------- + * | buf_ptr [31:0] | + * -------------------------------------------------------------- + * | next_desc_ptr [31:0] | + * -------------------------------------------------------------- + */ + +/* this bitfield is start from the LSB!!! */ +typedef struct uhci_lldesc_s { + volatile uint32_t size : 12, + length: 12, + offset: 5, /* h/w reserved 5bit, s/w use it as offset in buffer */ + sosf : 1, /* start of sub-frame */ + eof : 1, /* end of frame */ + owner : 1; /* hw or sw */ + volatile const uint8_t *buf; /* point to buffer data */ + union { + volatile uint32_t empty; + STAILQ_ENTRY(uhci_lldesc_s) qe; /* pointing to the next desc */ + }; +} uhci_lldesc_t; + +/** + * @brief Enumeration of HCI transport transmission states. + */ +typedef enum { + HCI_TRANS_TX_IDLE, ///< HCI Transport TX is in idle state. + HCI_TRANS_TX_START, ///< HCI Transport TX is starting transmission. + HCI_TRANS_TX_END, ///< HCI Transport TX has completed transmission. +} hci_trans_tx_state_t; + +typedef struct { + TaskHandle_t task_handler; + hci_driver_uart_params_config_t *hci_uart_params; + SemaphoreHandle_t process_sem; + struct hci_h4_sm *h4_sm; + hci_driver_forward_fn *forward_cb; + struct os_mempool *hci_rx_data_pool; /*!< Init a memory pool for rx_data cache */ + uint8_t *hci_rx_data_buffer; + struct os_mempool *hci_rxinfo_pool; /*!< Init a memory pool for rxinfo cache */ + os_membuf_t *hci_rxinfo_buffer; + volatile bool rxinfo_mem_exhausted; /*!< Indicate rxinfo memory does not exist */ + volatile bool is_continue_rx; /*!< Continue to rx */ + volatile hci_trans_tx_state_t hci_tx_state; /*!< HCI Tx State */ + struct os_mempool lldesc_mem_pool;/*!< Init a memory pool for uhci_lldesc_t */ + uhci_lldesc_t *lldesc_mem; +} hci_driver_uart_dma_env_t; + +#define ESP_BT_HCI_TL_STATUS_OK (0) /*!< HCI_TL Tx/Rx operation status OK */ +/* The number of lldescs pool */ +#define HCI_LLDESCS_POOL_NUM (CONFIG_BT_LE_HCI_LLDESCS_POOL_NUM) +/* Default block size for HCI RX data */ +#define HCI_RX_DATA_BLOCK_SIZE (DEFAULT_BT_LE_ACL_BUF_SIZE + BLE_HCI_TRANS_CMD_SZ) +#define HCI_RX_DATA_POOL_NUM (CONFIG_BT_LE_HCI_TRANS_RX_MEM_NUM) +#define HCI_RX_INFO_POOL_NUM (CONFIG_BT_LE_HCI_TRANS_RX_MEM_NUM + 1) + +/** + * @brief callback function for HCI Transport Layer send/receive operations + */ +typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status); + +struct uart_txrxchannel { + esp_bt_hci_tl_callback_t callback; + void *arg; + uhci_lldesc_t *link_head; +}; + +struct uart_env_tag { + struct uart_txrxchannel tx; + struct uart_txrxchannel rx; +}; + +typedef struct hci_message { + void *ptr; ///< Pointer to the message data. + uint32_t length; ///< Length of the message data. + STAILQ_ENTRY(hci_message) next; ///< Next element in the linked list. +} hci_message_t; + +static void hci_driver_uart_dma_recv_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg); +int hci_driver_uart_dma_rx_start(uint8_t *rx_data, uint32_t length); +int hci_driver_uart_dma_tx_start(esp_bt_hci_tl_callback_t callback, void *arg); + +static const char *TAG = "uart_dma"; +static hci_driver_uart_dma_env_t s_hci_driver_uart_dma_env; +static struct hci_h4_sm s_hci_driver_uart_h4_sm; +static hci_driver_uart_params_config_t hci_driver_uart_dma_params = BT_HCI_DRIVER_UART_CONFIG_DEFAULT(); + +/* The list for hci_rx_data */ +STAILQ_HEAD(g_hci_rxinfo_list, hci_message); + +DRAM_ATTR struct g_hci_rxinfo_list g_hci_rxinfo_head; +static DRAM_ATTR struct uart_env_tag uart_env; +static volatile uhci_dev_t *s_uhci_hw = &UHCI0; +static DRAM_ATTR gdma_channel_handle_t s_rx_channel; +static DRAM_ATTR gdma_channel_handle_t s_tx_channel; + +static int hci_driver_uart_dma_memory_deinit(void) +{ + + if (s_hci_driver_uart_dma_env.hci_rxinfo_buffer) { + free(s_hci_driver_uart_dma_env.hci_rxinfo_buffer); + s_hci_driver_uart_dma_env.hci_rxinfo_buffer = NULL; + } + + if (s_hci_driver_uart_dma_env.hci_rxinfo_pool) { + free(s_hci_driver_uart_dma_env.hci_rxinfo_pool); + s_hci_driver_uart_dma_env.hci_rxinfo_pool = NULL; + } + + if (s_hci_driver_uart_dma_env.hci_rx_data_buffer) { + free(s_hci_driver_uart_dma_env.hci_rx_data_buffer); + s_hci_driver_uart_dma_env.hci_rx_data_buffer = NULL; + } + + if (s_hci_driver_uart_dma_env.hci_rx_data_pool) { + free(s_hci_driver_uart_dma_env.hci_rx_data_pool); + s_hci_driver_uart_dma_env.hci_rx_data_pool = NULL; + } + + if (s_hci_driver_uart_dma_env.lldesc_mem) { + free(s_hci_driver_uart_dma_env.lldesc_mem); + s_hci_driver_uart_dma_env.lldesc_mem = NULL; + } + + return 0; +} + +static int hci_driver_uart_dma_memory_init(void) +{ + int rc = 0; + + s_hci_driver_uart_dma_env.lldesc_mem = malloc(OS_MEMPOOL_SIZE(HCI_LLDESCS_POOL_NUM, + sizeof (uhci_lldesc_t)) * sizeof(os_membuf_t)); + if (!s_hci_driver_uart_dma_env.lldesc_mem) { + return -1; + } + + rc = os_mempool_init(&s_hci_driver_uart_dma_env.lldesc_mem_pool, HCI_LLDESCS_POOL_NUM, + sizeof (uhci_lldesc_t), s_hci_driver_uart_dma_env.lldesc_mem, "hci_lldesc_pool"); + if (rc) { + goto init_err; + } + + s_hci_driver_uart_dma_env.hci_rx_data_pool = (struct os_mempool *)malloc(sizeof(struct os_mempool)); + if (!s_hci_driver_uart_dma_env.hci_rx_data_pool) { + goto init_err; + } + + memset(s_hci_driver_uart_dma_env.hci_rx_data_pool, 0, sizeof(struct os_mempool)); + s_hci_driver_uart_dma_env.hci_rx_data_buffer = malloc(OS_MEMPOOL_SIZE(HCI_RX_DATA_POOL_NUM, + HCI_RX_DATA_BLOCK_SIZE) * sizeof(os_membuf_t)); + if (!s_hci_driver_uart_dma_env.hci_rx_data_buffer) { + goto init_err; + } + + memset(s_hci_driver_uart_dma_env.hci_rx_data_buffer, 0, OS_MEMPOOL_SIZE(HCI_RX_DATA_POOL_NUM, + HCI_RX_DATA_BLOCK_SIZE) * sizeof(os_membuf_t)); + rc = os_mempool_init(s_hci_driver_uart_dma_env.hci_rx_data_pool, HCI_RX_DATA_POOL_NUM, + HCI_RX_DATA_BLOCK_SIZE, s_hci_driver_uart_dma_env.hci_rx_data_buffer, + "hci_rx_data_pool"); + if (rc) { + goto init_err; + } + + + /* Malloc hci rxinfo pool */ + s_hci_driver_uart_dma_env.hci_rxinfo_pool = (struct os_mempool *)malloc(sizeof(struct os_mempool)); + if (!s_hci_driver_uart_dma_env.hci_rxinfo_pool) { + goto init_err; + } + + memset(s_hci_driver_uart_dma_env.hci_rxinfo_pool, 0, sizeof(struct os_mempool)); + s_hci_driver_uart_dma_env.hci_rxinfo_buffer = malloc(OS_MEMPOOL_SIZE(HCI_RX_INFO_POOL_NUM, + sizeof(hci_message_t)) * sizeof(os_membuf_t)); + if (!s_hci_driver_uart_dma_env.hci_rxinfo_buffer) { + goto init_err; + } + + memset(s_hci_driver_uart_dma_env.hci_rxinfo_buffer, 0, OS_MEMPOOL_SIZE(HCI_RX_INFO_POOL_NUM, + sizeof(hci_message_t)) * sizeof(os_membuf_t)); + rc = os_mempool_init(s_hci_driver_uart_dma_env.hci_rxinfo_pool, HCI_RX_INFO_POOL_NUM, + sizeof(hci_message_t), s_hci_driver_uart_dma_env.hci_rxinfo_buffer, + "hci_rxinfo_pool"); + if (rc) { + goto init_err; + } + + return rc; +init_err: + hci_driver_uart_dma_memory_deinit(); + return rc; +} + +static IRAM_ATTR bool hci_uart_tl_rx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + esp_bt_hci_tl_callback_t callback = uart_env.rx.callback; + void *arg = uart_env.rx.arg; + assert(dma_chan == s_rx_channel); + assert(uart_env.rx.callback != NULL); + // clear callback pointer + uart_env.rx.callback = NULL; + uart_env.rx.arg = NULL; + // call handler + callback(arg, ESP_BT_HCI_TL_STATUS_OK); + return true; +} + +static IRAM_ATTR bool hci_uart_tl_tx_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + esp_bt_hci_tl_callback_t callback = uart_env.tx.callback; + assert(dma_chan == s_tx_channel); + assert(uart_env.tx.callback != NULL); + // clear callback pointer + uart_env.tx.callback = NULL; + // call handler + callback(uart_env.tx.arg, ESP_BT_HCI_TL_STATUS_OK); + uart_env.tx.arg = NULL; + return true; +} + +uint8_t * IRAM_ATTR hci_driver_uart_dma_rxdata_memory_get(void) +{ + uint8_t *rx_data; + rx_data = os_memblock_get(s_hci_driver_uart_dma_env.hci_rx_data_pool); + return rx_data; +} + +hci_message_t * IRAM_ATTR hci_driver_uart_dma_rxinfo_memory_get(void) +{ + hci_message_t *rx_info; + rx_info = os_memblock_get(s_hci_driver_uart_dma_env.hci_rxinfo_pool); + return rx_info; +} + +void IRAM_ATTR hci_driver_uart_dma_cache_rxinfo(hci_message_t *hci_rxinfo) +{ + os_sr_t sr; + + OS_ENTER_CRITICAL(sr); + STAILQ_INSERT_TAIL(&g_hci_rxinfo_head, hci_rxinfo, next); + OS_EXIT_CRITICAL(sr); +} + +void IRAM_ATTR hci_driver_uart_dma_continue_rx_enable(bool enable) +{ + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + s_hci_driver_uart_dma_env.is_continue_rx = enable; + OS_EXIT_CRITICAL(sr); +} + +void IRAM_ATTR hci_driver_uart_dma_rxinfo_mem_exhausted_set(bool is_exhausted) +{ + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + s_hci_driver_uart_dma_env.rxinfo_mem_exhausted = is_exhausted; + OS_EXIT_CRITICAL(sr); +} + +void IRAM_ATTR hci_driver_uart_dma_recv_callback(void *arg, uint8_t status) +{ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + hci_message_t *hci_rxinfo; + uint8_t *rx_data; + + if (s_hci_driver_uart_dma_env.rxinfo_mem_exhausted) { + ESP_LOGE(TAG, "Will lost rx data, need adjust rxinfo memory count\n"); + assert(0); + } + + hci_rxinfo = hci_driver_uart_dma_rxinfo_memory_get(); + if (!hci_rxinfo) { + ESP_LOGW(TAG, "set rxinfo mem exhausted flag\n"); + hci_driver_uart_dma_rxinfo_mem_exhausted_set(true); + xSemaphoreGiveFromISR(s_hci_driver_uart_dma_env.process_sem, &xHigherPriorityTaskWoken); + return; + } + + hci_rxinfo->ptr = (void *)uart_env.rx.link_head->buf; + hci_rxinfo->length = uart_env.rx.link_head->length; + hci_driver_uart_dma_cache_rxinfo(hci_rxinfo); + xSemaphoreGiveFromISR(s_hci_driver_uart_dma_env.process_sem, &xHigherPriorityTaskWoken); + rx_data = hci_driver_uart_dma_rxdata_memory_get(); + if (!rx_data) { + hci_driver_uart_dma_continue_rx_enable(true); + }else { + hci_driver_uart_dma_rx_start(rx_data, HCI_RX_DATA_BLOCK_SIZE); + } +} + +void IRAM_ATTR hci_driver_uart_dma_txstate_set(hci_trans_tx_state_t tx_state) +{ + os_sr_t sr; + OS_ENTER_CRITICAL(sr); + s_hci_driver_uart_dma_env.hci_tx_state = tx_state; + OS_EXIT_CRITICAL(sr); +} + +void IRAM_ATTR hci_driver_uart_dma_send_callback(void *arg, uint8_t status) +{ + uhci_lldesc_t *lldesc_head; + uhci_lldesc_t *lldesc_nxt; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + lldesc_head = uart_env.tx.link_head; + while (lldesc_head) { + lldesc_nxt = lldesc_head->qe.stqe_next; + os_memblock_put(&s_hci_driver_uart_dma_env.lldesc_mem_pool, lldesc_head); + lldesc_head = lldesc_nxt; + } + + uart_env.tx.link_head = NULL; + hci_driver_uart_dma_txstate_set(HCI_TRANS_TX_IDLE); + xSemaphoreGiveFromISR(s_hci_driver_uart_dma_env.process_sem, &xHigherPriorityTaskWoken); +} + +static IRAM_ATTR void hci_driver_uart_dma_recv_async(uint8_t *buf, uint32_t size, esp_bt_hci_tl_callback_t callback, void *arg) +{ + uhci_lldesc_t *lldesc_head; + assert(buf != NULL); + assert(size != 0); + assert(callback != NULL); + uart_env.rx.callback = callback; + uart_env.rx.arg = arg; + lldesc_head = uart_env.rx.link_head; + + while (lldesc_head) { + os_memblock_put(&s_hci_driver_uart_dma_env.lldesc_mem_pool, lldesc_head), + lldesc_head = lldesc_head->qe.stqe_next; + } + + uart_env.rx.link_head = NULL; + lldesc_head = os_memblock_get(&s_hci_driver_uart_dma_env.lldesc_mem_pool); + assert(lldesc_head); + memset(lldesc_head, 0, sizeof(uhci_lldesc_t)); + lldesc_head->buf = buf; + lldesc_head->size = size; + lldesc_head->eof = 0; + s_uhci_hw->pkt_thres.pkt_thrs = size; + uart_env.rx.link_head = lldesc_head; + gdma_start(s_rx_channel, (intptr_t)(uart_env.rx.link_head)); +} + +int IRAM_ATTR hci_driver_uart_dma_rx_start(uint8_t *rx_data, uint32_t length) +{ + hci_driver_uart_dma_recv_async(rx_data, length, hci_driver_uart_dma_recv_callback, NULL); + return 0; +} + +int hci_driver_uart_dma_tx_start(esp_bt_hci_tl_callback_t callback, void *arg) +{ + void *data; + bool last_frame; + bool head_is_setted; + uint32_t tx_len; + uhci_lldesc_t *lldesc_data; + uhci_lldesc_t *lldesc_head; + uhci_lldesc_t *lldesc_tail; + + lldesc_head = NULL; + lldesc_tail = NULL; + head_is_setted = false; + last_frame = false; + while (true) { + tx_len = hci_driver_util_tx_list_dequeue(0xffffff, &data, &last_frame); + if (!tx_len) { + break; + } + + lldesc_data = os_memblock_get(&s_hci_driver_uart_dma_env.lldesc_mem_pool); + /* According to the current processing logic, It should not be empty */ + assert(lldesc_data); + memset(lldesc_data, 0, sizeof(uhci_lldesc_t)); + lldesc_data->length = tx_len; + lldesc_data->buf = data; + lldesc_data->eof = 0; + if (!head_is_setted) { + lldesc_head = lldesc_data; + head_is_setted = true; + } else { + lldesc_tail->qe.stqe_next = lldesc_data; + } + + lldesc_tail = lldesc_data; + if (last_frame) { + break; + } + } + + if (lldesc_head) { + lldesc_tail->eof = 1; + uart_env.tx.link_head = lldesc_head; + uart_env.tx.callback = callback; + uart_env.tx.arg = arg; + /* The DMA interrupt may have been triggered before setting the tx_state, + * So we set it first. + */ + hci_driver_uart_dma_txstate_set(HCI_TRANS_TX_START); + gdma_start(s_tx_channel, (intptr_t)(uart_env.tx.link_head)); + return 0; + } else { + return -1; + } +} + +static void hci_driver_uart_dma_install(void) +{ + periph_module_enable(PERIPH_UHCI0_MODULE); + periph_module_reset(PERIPH_UHCI0_MODULE); + // install DMA driver + gdma_channel_alloc_config_t tx_channel_config = { + .flags.reserve_sibling = 1, + .direction = GDMA_CHANNEL_DIRECTION_TX, + }; + + ESP_ERROR_CHECK(gdma_new_channel(&tx_channel_config, &s_tx_channel)); + gdma_channel_alloc_config_t rx_channel_config = { + .direction = GDMA_CHANNEL_DIRECTION_RX, + .sibling_chan = s_tx_channel, + }; + + ESP_ERROR_CHECK(gdma_new_channel(&rx_channel_config, &s_rx_channel)); + gdma_connect(s_tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UHCI, 0)); + gdma_connect(s_rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_UHCI, 0)); + gdma_strategy_config_t strategy_config = { + .auto_update_desc = false, + .owner_check = false + }; + + gdma_apply_strategy(s_tx_channel, &strategy_config); + gdma_apply_strategy(s_rx_channel, &strategy_config); + gdma_rx_event_callbacks_t rx_cbs = { + .on_recv_eof = hci_uart_tl_rx_eof_callback + }; + + gdma_register_rx_event_callbacks(s_rx_channel, &rx_cbs, NULL); + gdma_tx_event_callbacks_t tx_cbs = { + .on_trans_eof = hci_uart_tl_tx_eof_callback + }; + + gdma_register_tx_event_callbacks(s_tx_channel, &tx_cbs, NULL); + // configure UHCI + uhci_ll_init((uhci_dev_t *)s_uhci_hw); + // uhci_ll_set_eof_mode((uhci_dev_t *)s_uhci_hw, UHCI_RX_LEN_EOF); + uhci_ll_set_eof_mode((uhci_dev_t *)s_uhci_hw, UHCI_RX_IDLE_EOF); + // disable software flow control + s_uhci_hw->escape_conf.val = 0; + uhci_ll_attach_uart_port((uhci_dev_t *)s_uhci_hw, s_hci_driver_uart_dma_env.hci_uart_params->hci_uart_port); +} + +static int +hci_driver_uart_dma_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + /* By now, this layer is only used by controller. */ + assert(dir == HCI_DRIVER_DIR_C2H); + ESP_LOGD(TAG, "dma tx:"); + ESP_LOG_BUFFER_HEXDUMP(TAG, data, length, ESP_LOG_DEBUG); + + hci_driver_util_tx_list_enqueue(data_type, data, length); + xSemaphoreGive(s_hci_driver_uart_dma_env.process_sem); + return 0; +} + +static int +hci_driver_uart_dma_h4_frame_cb(uint8_t pkt_type, void *data) +{ + hci_driver_forward_fn *forward_cb; + forward_cb = s_hci_driver_uart_dma_env.forward_cb; + if (!forward_cb) { + return -1; + } + ESP_LOGD(TAG, "h4 frame\n"); + return forward_cb(pkt_type, data, 0, HCI_DRIVER_DIR_H2C); +} + +static void +hci_driver_uart_dma_process_task(void *p) +{ + hci_message_t *rxinfo_container; + os_sr_t sr; + int ret; + uint8_t* rx_data; + uint32_t rx_len; + + while (true) { + xSemaphoreTake(s_hci_driver_uart_dma_env.process_sem, portMAX_DELAY); + ESP_LOGD(TAG, "task run:%d\n",s_hci_driver_uart_dma_env.hci_tx_state); + /* Process Tx data */ + if (s_hci_driver_uart_dma_env.hci_tx_state == HCI_TRANS_TX_IDLE) { + hci_driver_uart_dma_tx_start(hci_driver_uart_dma_send_callback, (void*)&uart_env); + } + + if (s_hci_driver_uart_dma_env.rxinfo_mem_exhausted) { + rx_data = (void *)uart_env.rx.link_head->buf; + rx_len = uart_env.rx.link_head->length; + ESP_LOGD(TAG, "rxinfo exhausted:"); + ESP_LOG_BUFFER_HEXDUMP(TAG, rx_data, rx_len, ESP_LOG_DEBUG); + ret = hci_h4_sm_rx(s_hci_driver_uart_dma_env.h4_sm, rx_data, rx_len); + hci_driver_uart_dma_rx_start(rx_data, HCI_RX_DATA_BLOCK_SIZE); + hci_driver_uart_dma_rxinfo_mem_exhausted_set(false); + if (ret < 0) { + ESP_LOGW(TAG, "parse rx data error!\n"); + r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR); + } + } + + while (!STAILQ_EMPTY(&g_hci_rxinfo_head)) { + OS_ENTER_CRITICAL(sr); + rxinfo_container = STAILQ_FIRST(&g_hci_rxinfo_head); + STAILQ_REMOVE_HEAD(&g_hci_rxinfo_head, next); + OS_EXIT_CRITICAL(sr); + + rx_data = rxinfo_container->ptr; + rx_len = rxinfo_container->length; + ESP_LOGD(TAG, "uart rx"); + ESP_LOG_BUFFER_HEXDUMP(TAG, rx_data, rx_len, ESP_LOG_DEBUG); + ret = hci_h4_sm_rx(s_hci_driver_uart_dma_env.h4_sm, rx_data, rx_len); + if (ret < 0) { + ESP_LOGW(TAG, "parse rx data error!\n"); + r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR); + } + + os_memblock_put(s_hci_driver_uart_dma_env.hci_rxinfo_pool, rxinfo_container); + /* No need to enter CRITICAL */ + if (s_hci_driver_uart_dma_env.is_continue_rx) { + /* We should set continux rx flag first, RX interrupted may happened when rx start soon */ + hci_driver_uart_dma_continue_rx_enable(false); + hci_driver_uart_dma_rx_start(rx_data, HCI_RX_DATA_BLOCK_SIZE); + } else { + os_memblock_put(s_hci_driver_uart_dma_env.hci_rx_data_pool, rx_data); + } + } + } +} + +static int +hci_driver_uart_dma_task_create(void) +{ + /* !TODO: Set the core id by menuconfig */ + xTaskCreatePinnedToCore(hci_driver_uart_dma_process_task, "hci_driver_uart_dma_process_task", + CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE, NULL, + ESP_TASK_BT_CONTROLLER_PRIO, &s_hci_driver_uart_dma_env.task_handler, + 0); + assert(s_hci_driver_uart_dma_env.task_handler); + + ESP_LOGI(TAG, "hci transport task create successfully, prio:%d, stack size: %ld", + ESP_TASK_BT_CONTROLLER_PRIO, CONFIG_BT_LE_HCI_TRANS_TASK_STACK_SIZE); + + return 0; +} + + +static void +hci_driver_uart_dma_deinit(void) +{ + if (s_hci_driver_uart_dma_env.task_handler) { + vTaskDelete(s_hci_driver_uart_dma_env.task_handler); + s_hci_driver_uart_dma_env.task_handler = NULL; + } + + ESP_ERROR_CHECK(uart_driver_delete(s_hci_driver_uart_dma_env.hci_uart_params->hci_uart_port)); + hci_driver_uart_dma_memory_deinit(); + if (!s_hci_driver_uart_dma_env.process_sem) { + vSemaphoreDelete(s_hci_driver_uart_dma_env.process_sem); + } + + hci_driver_util_deinit(); + memset(&s_hci_driver_uart_dma_env, 0, sizeof(hci_driver_uart_dma_env_t)); +} + + +static int +hci_driver_uart_dma_init(hci_driver_forward_fn *cb) +{ + int rc; + + memset(&s_hci_driver_uart_dma_env, 0, sizeof(hci_driver_uart_dma_env_t)); + + s_hci_driver_uart_dma_env.h4_sm = &s_hci_driver_uart_h4_sm; + hci_h4_sm_init(s_hci_driver_uart_dma_env.h4_sm, &s_hci_driver_mem_alloc, hci_driver_uart_dma_h4_frame_cb); + + rc = hci_driver_util_init(); + if (rc) { + goto error; + } + + s_hci_driver_uart_dma_env.process_sem = xSemaphoreCreateBinary(); + if (!s_hci_driver_uart_dma_env.process_sem) { + goto error; + } + + rc = hci_driver_uart_dma_memory_init(); + if (rc) { + goto error; + } + + s_hci_driver_uart_dma_env.forward_cb = cb; + s_hci_driver_uart_dma_env.hci_uart_params = &hci_driver_uart_dma_params; + hci_driver_uart_config(&hci_driver_uart_dma_params); + + ESP_LOGI(TAG, "uart attach uhci!"); + hci_driver_uart_dma_install(); + + STAILQ_INIT(&g_hci_rxinfo_head); + + rc = hci_driver_uart_dma_task_create(); + if (rc) { + goto error; + } + + s_hci_driver_uart_dma_env.hci_tx_state = HCI_TRANS_TX_IDLE; + s_hci_driver_uart_dma_env.rxinfo_mem_exhausted = false; + s_hci_driver_uart_dma_env.is_continue_rx = false; + hci_driver_uart_dma_rx_start(os_memblock_get(s_hci_driver_uart_dma_env.hci_rx_data_pool), + HCI_RX_DATA_BLOCK_SIZE); + return 0; + +error: + hci_driver_uart_dma_deinit(); + return rc; +} + +int +hci_driver_uart_dma_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin) +{ + hci_driver_uart_params_config_t *uart_param = s_hci_driver_uart_dma_env.hci_uart_params; + uart_param->hci_uart_tx_pin = tx_pin; + uart_param->hci_uart_rx_pin = rx_pin; + uart_param->hci_uart_rts_pin = rts_pin; + uart_param->hci_uart_cts_pin = cts_pin; + return hci_driver_uart_config(uart_param); +} + + +hci_driver_ops_t hci_driver_uart_dma_ops = { + .hci_driver_tx = hci_driver_uart_dma_tx, + .hci_driver_init = hci_driver_uart_dma_init, + .hci_driver_deinit = hci_driver_uart_dma_deinit, +}; diff --git a/components/bt/porting/transport/driver/vhci/hci_driver_nimble.c b/components/bt/porting/transport/driver/vhci/hci_driver_nimble.c new file mode 100644 index 0000000000..9a117eb88a --- /dev/null +++ b/components/bt/porting/transport/driver/vhci/hci_driver_nimble.c @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "esp_hci_internal.h" +#include "esp_hci_driver.h" + +typedef struct { + hci_driver_forward_fn *forward_cb; +} hci_driver_vhci_env_t; + +static hci_driver_vhci_env_t s_hci_driver_vhci_env; + +static int +hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data) +{ + /* The length is contained in the data. */ + return s_hci_driver_vhci_env.forward_cb(data_type, data, 0, HCI_DRIVER_DIR_C2H); +} + +static int +hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + return s_hci_driver_vhci_env.forward_cb(data_type, data, length, HCI_DRIVER_DIR_H2C); +} + +static int +hci_driver_vhci_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + int rc; + + if (dir == HCI_DRIVER_DIR_C2H) { + rc = hci_driver_vhci_controller_tx(data_type, data); + } else { + rc = hci_driver_vhci_host_tx(data_type, data, length); + } + return rc; +} + +static int +hci_driver_vhci_init(hci_driver_forward_fn *cb) +{ + s_hci_driver_vhci_env.forward_cb = cb; + return 0; +} + +static void +hci_driver_vhci_deinit(void) +{ + memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t)); +} + +hci_driver_ops_t hci_driver_vhci_ops = { + .hci_driver_tx = hci_driver_vhci_tx, + .hci_driver_init = hci_driver_vhci_init, + .hci_driver_deinit = hci_driver_vhci_deinit, +}; diff --git a/components/bt/porting/transport/driver/vhci/hci_driver_standard.c b/components/bt/porting/transport/driver/vhci/hci_driver_standard.c new file mode 100644 index 0000000000..2cdab4359e --- /dev/null +++ b/components/bt/porting/transport/driver/vhci/hci_driver_standard.c @@ -0,0 +1,149 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "os/os_mbuf.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" +#include "esp_hci_driver.h" +#include "esp_bt.h" + +typedef struct { + hci_driver_forward_fn *forward_cb; + const esp_vhci_host_callback_t *host_recv_cb; +} hci_driver_vhci_env_t; + +static hci_driver_vhci_env_t s_hci_driver_vhci_env; + +static int +hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + int rc; + uint16_t buf_len = 0; + uint8_t *buf = NULL; + struct os_mbuf *om; + + if (data_type == HCI_DRIVER_TYPE_ACL) { + om = (struct os_mbuf *)data; + buf_len = length + 1; + buf = malloc(buf_len); + /* TODO: If there is no memory, should handle it in the controller. */ + assert(buf); + buf[0] = HCI_DRIVER_TYPE_ACL; + os_mbuf_copydata(om, 0, length, &buf[1]); + os_mbuf_free_chain(om); + } else if (data_type == HCI_DRIVER_TYPE_EVT) { + buf_len = length + 1; + buf = malloc(buf_len); + /* TODO: If there is no memory, should handle it in the controller. */ + assert(buf != NULL); + buf[0] = HCI_DRIVER_TYPE_EVT; + memcpy(&buf[1], data, length); + r_ble_hci_trans_buf_free(data); + } + + rc = s_hci_driver_vhci_env.forward_cb(data_type, buf, buf_len, HCI_DRIVER_DIR_C2H); + free(buf); + + return rc; +} + +static int +hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + uint8_t *cmd; + struct os_mbuf *om; + + if (data_type == HCI_DRIVER_TYPE_ACL) { + om = os_msys_get_pkthdr(length, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); + assert(om); + assert(os_mbuf_append(om, &data[1], length - 1) == 0); + data = (uint8_t *)om; + } else if (data_type == HCI_DRIVER_TYPE_CMD) { + cmd = r_ble_hci_trans_buf_alloc(ESP_HCI_INTERNAL_BUF_CMD); + assert(cmd); + memcpy(cmd, data + 1, length - 1); + data = cmd; + } + + return s_hci_driver_vhci_env.forward_cb(data_type, data, length, HCI_DRIVER_DIR_H2C); +} + +static int +hci_driver_vhci_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + int rc; + + if (dir == HCI_DRIVER_DIR_C2H) { + rc = hci_driver_vhci_controller_tx(data_type, data, length); + } else { + rc = hci_driver_vhci_host_tx(data_type, data, length); + } + return rc; +} + +static int +hci_driver_vhci_init(hci_driver_forward_fn *cb) +{ + memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t)); + s_hci_driver_vhci_env.forward_cb = cb; + return 0; +} + +static void +hci_driver_vhci_deinit(void) +{ + memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t)); +} + +hci_driver_ops_t hci_driver_vhci_ops = { + .hci_driver_tx = hci_driver_vhci_tx, + .hci_driver_init = hci_driver_vhci_init, + .hci_driver_deinit = hci_driver_vhci_deinit, +}; + +/* Special APIs declared in the `esp_bt.h'. */ +static int +hci_driver_vhci_host_recv_cb(hci_trans_pkt_ind_t type, uint8_t *data, uint16_t len) +{ + static const esp_vhci_host_callback_t *host_recv_cb; + + host_recv_cb = s_hci_driver_vhci_env.host_recv_cb; + if (host_recv_cb) { + return host_recv_cb->notify_host_recv(data, len); + } + + return -1; +} + +esp_err_t +esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) +{ + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + return ESP_FAIL; + } + + s_hci_driver_vhci_env.host_recv_cb = callback; + if(hci_transport_host_callback_register(hci_driver_vhci_host_recv_cb)) { + s_hci_driver_vhci_env.host_recv_cb = NULL; + return ESP_FAIL; + } + + return ESP_OK; +} + +void +esp_vhci_host_send_packet(uint8_t *data, uint16_t len) +{ + hci_driver_vhci_tx(data[0], data, len, HCI_DRIVER_DIR_H2C); +} + +bool +esp_vhci_host_check_send_available(void) +{ + return true; +} diff --git a/components/bt/porting/transport/driver/vhci/hci_driver_tamplete.c b/components/bt/porting/transport/driver/vhci/hci_driver_tamplete.c new file mode 100644 index 0000000000..63feb934da --- /dev/null +++ b/components/bt/porting/transport/driver/vhci/hci_driver_tamplete.c @@ -0,0 +1,133 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "os/os_mbuf.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" +#include "esp_hci_driver.h" + +typedef struct { + hci_driver_forward_fn *forward_cb; +} hci_driver_vhci_env_t; + +static hci_driver_vhci_env_t s_hci_driver_vhci_env; + +static int +hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + int rc; + uint16_t len = 0; + uint8_t *buf = NULL; + struct os_mbuf *om; + + if (data_type == HCI_DRIVER_TYPE_ACL) { + /* The ACL data will be packaged as structure of `os_mbuf`. + * 1. Allocate a buffer suitable for the host. Use the following method to copy the data + * from the os_mbuf to the newly allocated memory. + * ```c + * buf = malloc(length); + * os_mbuf_copydata(om, 0, length, buf); + * ``` + * 2. Free the controller's os_mbuf + * ```c + * os_mbuf_free_chain(om); + * ``` + */ + } else if (data_type == HCI_DRIVER_TYPE_EVT) { + /* The event data will be packaged as an array. + * 1. Allocate a buffer suitable for the host. Use the following method to copy the data + * from the controller buffer to the newly allocated memory. + * ```c + * buf = malloc(length); + * memcpy(buf, data, length); + * ``` + * 2. Free the controller's buffer. + * ```c + * r_ble_hci_trans_buf_free(data); + * ``` + */ + } else { + assert(0); + } + + rc = s_hci_driver_vhci_env.forward_cb(data_type, buf, len, HCI_DRIVER_DIR_C2H); + free(buf); + + return rc; +} + +static int +hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + uint8_t *hci_data; + struct os_mbuf *om; + + if (data_type == HCI_DRIVER_TYPE_ACL) { + /* The ACL data needs to be packaged as structure of `os_mbuf`. + * 1. Get an os_mbuf in the following way. + * ```c + * om = os_msys_get_pkthdr(length, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE); + * ``` + * 2. Copy the host's data into this os_mbuf using the following method. + * ```c + * assert(os_mbuf_append(om, data, length) == 0); + * hci_data = (uint8_t *)om; + * ``` + * 3. Free the host's buffer if needed. + */ + } else if (data_type == HCI_DRIVER_TYPE_CMD) { + /* The COMMAND data needs to be packaged as an array. + * 1. Get a command buffer from the controller. + * ```c + * hci_data = r_ble_hci_trans_buf_alloc(ESP_HCI_INTERNAL_BUF_CMD); + * ``` + * 2. Copy the host's data into this buffer. + * ```c + * memcpy(hci_data, data, length); + * ``` + * 3. Free the host's buffer if needed. + */ + } else { + assert(0); + } + + return s_hci_driver_vhci_env.forward_cb(data_type, hci_data, length, HCI_DRIVER_DIR_H2C); +} + +static int +hci_driver_vhci_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + int rc; + + if (dir == HCI_DRIVER_DIR_C2H) { + rc = hci_driver_vhci_controller_tx(data_type, data, length); + } else { + rc = hci_driver_vhci_host_tx(data_type, data, length); + } + return rc; +} + +static int +hci_driver_vhci_init(hci_driver_forward_fn *cb) +{ + memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t)); + s_hci_driver_vhci_env.forward_cb = cb; + return 0; +} + +static void +hci_driver_vhci_deinit(void) +{ + memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t)); +} + +hci_driver_ops_t hci_driver_vhci_ops = { + .hci_driver_tx = hci_driver_vhci_tx, + .hci_driver_init = hci_driver_vhci_init, + .hci_driver_deinit = hci_driver_vhci_deinit, +}; diff --git a/components/bt/porting/transport/include/common/hci_driver_h4.h b/components/bt/porting/transport/include/common/hci_driver_h4.h new file mode 100644 index 0000000000..32d2dd8ba6 --- /dev/null +++ b/components/bt/porting/transport/include/common/hci_driver_h4.h @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +#ifndef _HCI_H4_H_ +#define _HCI_H4_H_ + +#include + +#define HCI_H4_NONE 0x00 +#define HCI_H4_CMD 0x01 +#define HCI_H4_ACL 0x02 +#define HCI_H4_EVT 0x04 +#define HCI_H4_ISO 0x05 + +typedef void *(hci_h4_alloc_cmd)(void); +typedef void *(hci_h4_alloc_evt)(int); +typedef struct os_mbuf *(hci_h4_alloc_acl)(void); +typedef struct os_mbuf *(hci_h4_alloc_iso)(void); + +struct hci_h4_allocators { + hci_h4_alloc_cmd *cmd; + hci_h4_alloc_acl *acl; + hci_h4_alloc_evt *evt; + hci_h4_alloc_iso *iso; +}; + +extern const struct hci_h4_allocators hci_h4_allocs_from_ll; +extern const struct hci_h4_allocators hci_h4_allocs_from_hs; + +typedef int (hci_h4_frame_cb)(uint8_t pkt_type, void *data); + +struct hci_h4_sm { + uint8_t state; + uint8_t pkt_type; + uint8_t min_len; + uint16_t len; + uint16_t exp_len; + uint8_t hdr[4]; + union { + uint8_t *buf; + struct os_mbuf *om; + }; + + const struct hci_h4_allocators *allocs; + hci_h4_frame_cb *frame_cb; +}; + +void hci_h4_sm_init(struct hci_h4_sm *h4sm, + const struct hci_h4_allocators *allocs, + hci_h4_frame_cb *frame_cb); + +int hci_h4_sm_rx(struct hci_h4_sm *h4sm, const uint8_t *buf, uint16_t len); + +#endif /* _HCI_H4_H_ */ diff --git a/components/bt/porting/transport/include/common/hci_driver_mem.h b/components/bt/porting/transport/include/common/hci_driver_mem.h new file mode 100644 index 0000000000..769b18369e --- /dev/null +++ b/components/bt/porting/transport/include/common/hci_driver_mem.h @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _H_HCI_DRIVER_MEM_ +#define _H_HCI_DRIVER_MEM_ +#include +#include "os/os_mbuf.h" + +void *hci_driver_mem_cmd_alloc(void); + +void *hci_driver_mem_evt_alloc(int discardable); + +struct os_mbuf *hci_driver_mem_acl_alloc(void); + +struct os_mbuf *hci_driver_mem_acl_len_alloc(uint32_t len); + +struct os_mbuf *hci_driver_mem_iso_alloc(void); + +struct os_mbuf *hci_driver_mem_iso_len_alloc(uint32_t len); + +extern const struct hci_h4_allocators s_hci_driver_mem_alloc; + +#endif // _H_HCI_DRIVER_MEM_ diff --git a/components/bt/porting/transport/include/common/hci_driver_util.h b/components/bt/porting/transport/include/common/hci_driver_util.h new file mode 100644 index 0000000000..05b7abd502 --- /dev/null +++ b/components/bt/porting/transport/include/common/hci_driver_util.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _H_HCI_DRIVER_UTIL_ +#define _H_HCI_DRIVER_UTIL_ +#include + +int hci_driver_util_init(void); + +void hci_driver_util_deinit(void); + +void hci_driver_util_tx_list_enqueue(hci_driver_data_type_t type, uint8_t *data, uint32_t len); + +uint32_t hci_driver_util_tx_list_dequeue(uint32_t max_tx_len, void **tx_data, bool *last_frame); + +#endif // _H_HCI_DRIVER_UTIL_ diff --git a/components/bt/porting/transport/include/esp_hci_driver.h b/components/bt/porting/transport/include/esp_hci_driver.h new file mode 100644 index 0000000000..09102edff8 --- /dev/null +++ b/components/bt/porting/transport/include/esp_hci_driver.h @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef H_ESP_HCI_DRIVER_ +#define H_ESP_HCI_DRIVER_ +#include + +/** + * @brief Enumeration of HCI transport direction. + */ +typedef enum { + HCI_DRIVER_DIR_C2H = 0x00, ///< From controller to host. + HCI_DRIVER_DIR_H2C, ///< From host to controller. +} hci_driver_direction_t; + +typedef enum { + HCI_DRIVER_TYPE_CMD = 0x01, ///< HCI Command Indicator. + HCI_DRIVER_TYPE_ACL, ///< HCI ACL Data Indicator. + HCI_DRIVER_TYPE_SYNC, ///< HCI Synchronous Data Indicator. + HCI_DRIVER_TYPE_EVT, ///< HCI Event Indicator. + HCI_DRIVER_TYPE_ISO, ///< HCI Isochronous Data Indicator. + HCI_DRIVER_TYPE_VENDOR, ///< HCI Vendor data Indicator. +} hci_driver_data_type_t; + +typedef int hci_driver_forward_fn(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir); + +/** + * @brief Structure of HCI driver operations. + */ +typedef struct hci_driver_ops { + int (*hci_driver_tx)(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir); + int (*hci_driver_init)(hci_driver_forward_fn *cb); + void (*hci_driver_deinit)(void); +} hci_driver_ops_t; + + +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM +extern hci_driver_ops_t hci_driver_vhci_ops; +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + +#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART +extern hci_driver_ops_t hci_driver_uart_ops; +#if CONFIG_BT_LE_UART_HCI_DMA_MODE +extern hci_driver_ops_t hci_driver_uart_dma_ops; +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART + +#endif // H_ESP_HCI_DRIVER_ diff --git a/components/bt/porting/transport/include/esp_hci_internal.h b/components/bt/porting/transport/include/esp_hci_internal.h new file mode 100644 index 0000000000..2b1c335308 --- /dev/null +++ b/components/bt/porting/transport/include/esp_hci_internal.h @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_ESP_HCI_INTERNAL_ +#define H_ESP_HCI_INTERNAL_ + +#ifdef __cplusplus +extern "C" { +#endif +#include +#include "os/os_mbuf.h" + + +/* The leadingspace in user info header for ACL data */ +#define ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE (4) + +#define ESP_HCI_INTERNAL_BUF_CMD (3) + +/** + * @brief Define the HCI hardware error code for synchronization loss. + * This error code is used to indicate a loss of synchronization between the controller and the host. + */ +#define ESP_HCI_SYNC_LOSS_ERR (0x1) +/** Callback function types; executed when HCI packets are received. */ +typedef int esp_hci_internal_rx_cmd_fn(uint8_t *cmd, void *arg); +typedef int esp_hci_internal_rx_acl_fn(struct os_mbuf *om, void *arg); + +/** + * Configures the HCI transport to operate with a host. The transport will + * execute specified callbacks upon receiving HCI packets from the controller. + * + * @param evt_cb The callback to execute upon receiving an HCI + * event. + * @param evt_arg Optional argument to pass to the event + * callback. + * @param acl_cb The callback to execute upon receiving ACL + * data. + * @param acl_arg Optional argument to pass to the ACL + * callback. + */ +void r_ble_hci_trans_cfg_hs(esp_hci_internal_rx_cmd_fn *evt_cb, void *evt_arg, + esp_hci_internal_rx_acl_fn *acl_cb, void *acl_arg); +/** + * Sends ACL data from host to controller. + * + * @param om The ACL data packet to send. + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int r_ble_hci_trans_hs_acl_tx(struct os_mbuf *om); + +/** + * Sends an HCI command from the host to the controller. + * + * @param cmd The HCI command to send. This buffer must be + * allocated via ble_hci_trans_buf_alloc(). + * + * @return 0 on success; + * A BLE_ERR_[...] error code on failure. + */ +int r_ble_hci_trans_hs_cmd_tx(uint8_t *cmd); + +/** + * Allocates a flat buffer of the specified type. + * + * @param type The type of buffer to allocate; one of the + * BLE_HCI_TRANS_BUF_[...] constants. + * + * @return The allocated buffer on success; + * NULL on buffer exhaustion. + */ +uint8_t * r_ble_hci_trans_buf_alloc(int type); + +/** + * Frees the specified flat buffer. The buffer must have been allocated via + * ble_hci_trans_buf_alloc(). + * + * @param buf The buffer to free. + */ +void r_ble_hci_trans_buf_free(uint8_t *buf); + +/** + * Configures a callback to get executed whenever an ACL data packet is freed. + * The function is called immediately before the free occurs. + * + * @param cb The callback to configure. + * @param arg An optional argument to pass to the callback. + * + * @return 0 on success; + * BLE_ERR_UNSUPPORTED if the transport does not + * support this operation. + */ +int r_ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg); + +/** + * @brief Handle an HCI hardware error event. + * This function processes a hardware error code and generates the appropriate HCI hardware error event. + * + * @param hw_err The hardware error code that needs to be processed. The specific meaning of the error code + * depends on the implementation and the hardware. + * + * @return int Returns 0 on success, or a non-zero error code on failure. + * + * @note This function should be called whenever a hardware error is detected in the HCI Layer. + */ +int r_ble_ll_hci_ev_hw_err(uint8_t hw_err); + +//!TODO: Check what this API is used for +int r_ble_hci_trans_reset(void); + +//!TODO: Should we initialize the hci layer in IDF ? +void esp_ble_hci_trans_init(uint8_t); + +#ifdef __cplusplus +} +#endif +#endif /* H_ESP_HCI_INTERNAL_ */ diff --git a/components/bt/porting/transport/include/esp_hci_transport.h b/components/bt/porting/transport/include/esp_hci_transport.h new file mode 100644 index 0000000000..044ebfdfb8 --- /dev/null +++ b/components/bt/porting/transport/include/esp_hci_transport.h @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_ESP_HCI_TRANSPORT_ +#define H_ESP_HCI_TRANSPORT_ + +#ifdef __cplusplus +extern "C" { +#endif +#include +#include "os/os_mbuf.h" +#include "esp_hci_driver.h" + +/** + * @brief Enumeration of HCI packet indicators + */ +typedef enum { + HCI_CMD_IND = 0x01, /*!< HCI Command Indicator */ + HCI_ACL_IND, /*!< HCI ACL Data Indicator */ + HCI_SYNC_IND, /*!< HCI Synchronous Data Indicator */ + HCI_EVT_IND, /*!< HCI Event Indicator */ + HCI_ISO_IND, /*!< HCI Isochronous Data Indicator */ + HCI_VENDOR_IND, /*!< HCI Vendor data Indicator */ +} hci_trans_pkt_ind_t; + +/** + * @brief Enumeration of HCI Transport Mode + */ +typedef enum { + HCI_TRANSPORT_VHCI, /*!< VHCI Transport Mode */ + HCI_TRANSPORT_UART_NO_DMA, /*!< UART_NO_DMA Transport Mode */ + HCI_TRANSPORT_UART_UHCI, /*!< UART_UHCI Transport Mode */ + HCI_TRANSPORT_SDIO, /*!< SDIO Transport Mode */ + HCI_TRANSPORT_USB, /*!< USB Transport Mode */ +} hci_trans_mode_t; + +typedef int hci_transport_host_recv_fn(hci_trans_pkt_ind_t type, uint8_t *data, uint16_t len); + +/** + * @brief Initialize the HCI transport layer. + * It should be called before using any other functions in the transport layer. + * + * @param hci_transport_mode The mode in which the HCI transport should operate. + * + * @return int Returns 0 on success, or a non-zero error code on failure. + */ +int hci_transport_init(uint8_t hci_transport_mode); + +/** + * @brief Deinitialize the HCI transport layer for releasing any allocated resources. + */ +void hci_transport_deinit(void); + +/** + * @brief Set the host's HCI callback which will be invoked when receiving ACL/Events from controller. + * @param callback hci_transport_host_recv_fn type variable + * @return int 0 on success, non-zero error code on failure. + */ +int hci_transport_host_callback_register(hci_transport_host_recv_fn *callback); + +/** + * @brief Called to send HCI commands form host to controller. + * @param data Point to the commands data + * @param length Length of data + * @return int 0 on success, non-zero error code on failure. + */ +int hci_transport_host_cmd_tx(uint8_t *data, uint32_t length); + +/** + * @brief Called to send HCI ACL form host to controller. + * @param data Point to the ACL data + * @param length Length of data + * @return int 0 on success, non-zero error code on failure. + */ +int hci_transport_host_acl_tx(uint8_t *data, uint32_t length); + +#ifdef __cplusplus +} +#endif +#endif /* H_ESP_HCI_TRANSPORT_ */ diff --git a/components/bt/porting/transport/include/hci_uart.h b/components/bt/porting/transport/include/hci_uart.h deleted file mode 100644 index 02bc91b403..0000000000 --- a/components/bt/porting/transport/include/hci_uart.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include "driver/uart.h" - -/** - * Function prototype for UART driver to ask for more data to send. - * Returns -1 if no more data is available for TX. - * Driver must call this with interrupts disabled. - */ -typedef int (*hci_uart_tx_char)(void *arg); - -/** - * Function prototype for UART driver to report that transmission is - * complete. This should be called when transmission of last byte is - * finished. - * Driver must call this with interrupts disabled. - */ -typedef void (*hci_uart_tx_done)(void *arg); - -/** - * Function prototype for UART driver to report incoming byte of data. - * Returns -1 if data was dropped. - * Driver must call this with interrupts disabled. - */ -typedef int (*hci_uart_rx_char)(void *arg, uint8_t byte); - - -/** - * Initializes given uart. Mapping of logical UART number to physical - * UART/GPIO pins is in BSP. - */ -int hci_uart_init_cbs(int uart, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); - - -/** - * Applies given configuration to UART. - * - * @param port_num The UART number to configure - * @param speed The baudrate in bps to configure - * @param databits The number of databits to send per byte - * @param stopbits The number of stop bits to send - * @param parity The UART parity - * @param flow_ctl Flow control settings on the UART - * - * @return 0 on success, non-zero error code on failure - */ -int hci_uart_config(int port_num, int32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); - -/** - * Close UART port. Can call hal_uart_config() with different settings after - * calling this. - * - * @param port_num The UART number to close - */ -int hci_uart_close(int port_num); - -/** - * More data queued for transmission. UART driver will start asking for that - * data. - * - * @param port_num The UART number to start TX on - */ -void hci_uart_start_tx(int port_num); - -/** - * Upper layers have consumed some data, and are now ready to receive more. - * This is meaningful after uart_rx_char callback has returned -1 telling - * that no more data can be accepted. - * - * @param port_num The UART number to begin RX on - */ -void hci_uart_start_rx(int port_num); - -/** - * @brief reconfig hci uart pin - * - * @param tx_pin The Tx pin - * @param rx_pin The Rx pin - * @param cts_pin The CTS pin - * @param rts_pin The RTS pin - * @return int 0 on success, non-zero error code on failure - */ -int hci_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin); - -#ifdef __cplusplus -} -#endif diff --git a/components/bt/porting/transport/src/hci_transport.c b/components/bt/porting/transport/src/hci_transport.c new file mode 100644 index 0000000000..29c2e00131 --- /dev/null +++ b/components/bt/porting/transport/src/hci_transport.c @@ -0,0 +1,177 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include "esp_log.h" +#include "esp_hci_transport.h" +#include "esp_hci_internal.h" +#include "esp_bt.h" + +typedef struct hci_transport_env +{ + hci_transport_host_recv_fn *host_recv_cb; + hci_driver_ops_t *driver_ops; +} hci_transport_env_t; + +static hci_transport_env_t s_hci_transport_env; + +/* Functions for packets Rx. */ +static int +hci_transport_controller_packet_rx(hci_driver_data_type_t data_type, uint8_t *data) +{ + if (data_type == HCI_DRIVER_TYPE_CMD) { + r_ble_hci_trans_hs_cmd_tx(data); + } + + if (data_type == HCI_DRIVER_TYPE_ACL) { + r_ble_hci_trans_hs_acl_tx((struct os_mbuf *) data); + } + return 0; +} + +static int +hci_transport_host_packet_rx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length) +{ + if (!s_hci_transport_env.host_recv_cb) { + return -1; + } + return s_hci_transport_env.host_recv_cb((hci_trans_pkt_ind_t)data_type, data, length); +} + +static int +hci_transport_packet_rx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length, + hci_driver_direction_t dir) +{ + int rc; + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + return -1; + } + + if (dir == HCI_DRIVER_DIR_C2H) { + rc = hci_transport_host_packet_rx(data_type, data, length); + } else { + rc = hci_transport_controller_packet_rx(data_type, data); + } + + return rc; +} + +/* Functions for controller Tx. */ +static int +hci_transport_controller_tx_dummy(void *data, void *arg) +{ + return -1; +} + +static int +hci_transport_controller_evt_tx(uint8_t *hci_ev, void *arg) +{ + uint32_t len; + + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + r_ble_hci_trans_buf_free(hci_ev); + return -1; + } + + len = hci_ev[1] + 2; + return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_EVT, hci_ev, len, + HCI_DRIVER_DIR_C2H); +} + +static int +hci_transport_controller_acl_tx(struct os_mbuf *om, void *arg) +{ + uint16_t len; + if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) { + os_mbuf_free_chain(om); + return -1; + } + + len = OS_MBUF_PKTHDR(om)->omp_len; + return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_ACL, (uint8_t *)om, len, + HCI_DRIVER_DIR_C2H); +} + +/* Functions for host Tx. */ +int +hci_transport_host_cmd_tx(uint8_t *data, uint32_t length) +{ + return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_CMD, data, length, + HCI_DRIVER_DIR_H2C); +} + +int +hci_transport_host_acl_tx(uint8_t *data, uint32_t length) +{ + return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_ACL, data, length, + HCI_DRIVER_DIR_H2C); +} + +int +hci_transport_host_callback_register(hci_transport_host_recv_fn *callback) +{ + s_hci_transport_env.host_recv_cb = callback; + return 0; +} + +int +hci_transport_init(uint8_t hci_transport_mode) +{ + int rc; + hci_driver_ops_t *ops; + + memset(&s_hci_transport_env, 0, sizeof(hci_transport_env_t)); + + switch(hci_transport_mode) { +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + case HCI_TRANSPORT_VHCI: + ops = &hci_driver_vhci_ops; + break; +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM +#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART +#if CONFIG_BT_LE_UART_HCI_DMA_MODE + case HCI_TRANSPORT_UART_UHCI: + ops = &hci_driver_uart_dma_ops; + break; +#else + case HCI_TRANSPORT_UART_NO_DMA: + ops = &hci_driver_uart_ops; + break; +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART + default: + assert(0); + } + + rc = ops->hci_driver_init(hci_transport_packet_rx); + if (rc) { + goto error; + } + + s_hci_transport_env.driver_ops = ops; + r_ble_hci_trans_cfg_hs(hci_transport_controller_evt_tx, NULL, hci_transport_controller_acl_tx, NULL); + + return 0; + +error: + hci_transport_deinit(); + return rc; +} + +void +hci_transport_deinit(void) +{ + hci_driver_ops_t *ops; + + r_ble_hci_trans_cfg_hs((esp_hci_internal_rx_cmd_fn *)hci_transport_controller_tx_dummy, NULL, + (esp_hci_internal_rx_acl_fn *)hci_transport_controller_tx_dummy, NULL); + + ops = s_hci_transport_env.driver_ops; + if (ops) { + ops->hci_driver_deinit(); + } + memset(&s_hci_transport_env, 0, sizeof(hci_transport_env_t)); +} diff --git a/components/bt/porting/transport/uart/hci_uart.c b/components/bt/porting/transport/uart/hci_uart.c deleted file mode 100644 index 0f89ebf857..0000000000 --- a/components/bt/porting/transport/uart/hci_uart.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "driver/uart.h" -#include "hci_uart.h" -#include "esp_log.h" -#include "esp_attr.h" - -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static const char *TAG = "hci_uart"; - -#define BUF_SIZE (1024) -#define RD_BUF_SIZE (BUF_SIZE) - -#define HCI_UART_TX_PIN CONFIG_BT_LE_HCI_UART_TX_PIN -#define HCI_UART_RX_PIN CONFIG_BT_LE_HCI_UART_RX_PIN - - -#ifdef CONFIG_BT_LE_HCI_UART_FLOWCTRL -#define HCI_UART_FLOWCTRL UART_HW_FLOWCTRL_CTS_RTS -#define HCI_UART_RTS_PIN CONFIG_BT_LE_HCI_UART_RTS_PIN -#define HCI_UART_CTS_PIN CONFIG_BT_LE_HCI_UART_CTS_PIN -#else -#define HCI_UART_FLOWCTRL UART_HW_FLOWCTRL_DISABLE -#define HCI_UART_RTS_PIN (-1) -#define HCI_UART_CTS_PIN (-1) -#endif - - -typedef struct { - bool uart_opened; - uart_port_t port; - uart_config_t cfg; - QueueHandle_t evt_queue; - TaskHandle_t rx_task_handler; - hci_uart_tx_char tx_char; - hci_uart_tx_done tx_done; - hci_uart_rx_char rx_char; - void *u_func_arg; - -} hci_uart_t; - -static hci_uart_t hci_uart; - -static void IRAM_ATTR hci_uart_rx_task(void *pvParameters) -{ - uart_event_t event; - uint8_t *dtmp = (uint8_t *) malloc(RD_BUF_SIZE); - while (hci_uart.uart_opened) { - //Waiting for UART event. - if (xQueueReceive(hci_uart.evt_queue, (void * )&event, (TickType_t)portMAX_DELAY)) { - bzero(dtmp, RD_BUF_SIZE); - ESP_LOGD(TAG, "uart[%d] event:", hci_uart.port); - switch (event.type) { - //Event of UART receving data - /*We'd better handler data event fast, there would be much more data events than - other types of events. If we take too much time on data event, the queue might - be full.*/ - case UART_DATA: - // ESP_LOGI(TAG, "[UART DATA]: %d", event.size); - uart_read_bytes(hci_uart.port, dtmp, event.size, portMAX_DELAY); - for (int i = 0 ; i < event.size; i++) { - hci_uart.rx_char(hci_uart.u_func_arg, dtmp[i]); - } - break; - //Event of HW FIFO overflow detected - case UART_FIFO_OVF: - ESP_LOGI(TAG, "hw fifo overflow"); - // If fifo overflow happened, you should consider adding flow control for your application. - // The ISR has already reset the rx FIFO, - uart_flush_input(hci_uart.port); - xQueueReset(hci_uart.evt_queue); - break; - //Event of UART ring buffer full - case UART_BUFFER_FULL: - ESP_LOGI(TAG, "ring buffer full"); - // If buffer full happened, you should consider encreasing your buffer size - uart_flush_input(hci_uart.port); - xQueueReset(hci_uart.evt_queue); - break; - //Event of UART RX break detected - case UART_BREAK: - ESP_LOGI(TAG, "uart rx break"); - break; - //Event of UART parity check error - case UART_PARITY_ERR: - ESP_LOGI(TAG, "uart parity error"); - break; - //Event of UART frame error - case UART_FRAME_ERR: - ESP_LOGI(TAG, "uart frame error"); - break; - //Others - default: - ESP_LOGI(TAG, "uart event type: %d", event.type); - break; - } - } - } - free(dtmp); - dtmp = NULL; - hci_uart.rx_task_handler = NULL; - vTaskDelete(NULL); -} - -int hci_uart_config(int port_num, int32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl) -{ - uart_config_t uart_cfg = { - .baud_rate = baud_rate, - .data_bits = data_bits, - .parity = parity, - .stop_bits = stop_bits, - .flow_ctrl = HCI_UART_FLOWCTRL, - .source_clk = UART_SCLK_DEFAULT, - .rx_flow_ctrl_thresh = UART_FIFO_LEN - 1, - }; - hci_uart.port = port_num; - hci_uart.cfg = uart_cfg; - - int intr_alloc_flags = 0; - intr_alloc_flags = ESP_INTR_FLAG_IRAM; - - printf("set uart pin tx:%d, rx:%d.\n", HCI_UART_TX_PIN, HCI_UART_RX_PIN); - printf("set rts:%d, cts:%d.\n", HCI_UART_RTS_PIN, HCI_UART_CTS_PIN); - printf("set baud_rate:%d.\n", baud_rate); - - ESP_ERROR_CHECK(uart_driver_delete(port_num)); - ESP_ERROR_CHECK(uart_driver_install(port_num, BUF_SIZE * 2, BUF_SIZE * 2, 20, &hci_uart.evt_queue, intr_alloc_flags)); - ESP_ERROR_CHECK(uart_param_config(port_num, &hci_uart.cfg)); - ESP_ERROR_CHECK(uart_set_pin(port_num, HCI_UART_TX_PIN, HCI_UART_RX_PIN, HCI_UART_RTS_PIN, HCI_UART_CTS_PIN)); - - hci_uart.uart_opened = true; - - //Create a task to handler UART event from ISR - xTaskCreate(hci_uart_rx_task, "hci_uart_rx_task", 2048, NULL, 12, &hci_uart.rx_task_handler); - return 0; -} - -void IRAM_ATTR hci_uart_start_tx(int port_num) -{ - int data; - uint8_t u8_data = 0; - while (1) { - data = hci_uart.tx_char(hci_uart.u_func_arg); - if (data >= 0) { - u8_data = data; - uart_write_bytes(port_num, (char *)&u8_data, 1); - } else { - break; - } - } - if (hci_uart.tx_done) { - hci_uart.tx_done(hci_uart.u_func_arg); - } -} - -int hci_uart_init_cbs(int port_num, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - hci_uart.tx_char = tx_func; - hci_uart.rx_char = rx_func; - hci_uart.tx_done = tx_done; - hci_uart.u_func_arg = arg; - return 0; -} - -int hci_uart_close(int port_num) -{ - uart_event_t uart_event; - uart_event.type = UART_BREAK; - hci_uart.uart_opened = false; - // Stop uart rx task - if (hci_uart.rx_task_handler != NULL) { - xQueueSend(hci_uart.evt_queue, (void *)&uart_event, 1000); - ESP_LOGW(TAG, "Waiting for uart task finish..."); - } - while (hci_uart.rx_task_handler != NULL); - - uart_driver_delete(port_num); - ESP_LOGI(TAG, "hci uart close success."); - return 0; -} - -int hci_uart_reconfig_pin(int tx_pin, int rx_pin, int cts_pin, int rts_pin) -{ - int port_num = hci_uart.port; - int32_t baud_rate = hci_uart.cfg.baud_rate; - uint8_t data_bits = hci_uart.cfg.data_bits; - uint8_t stop_bits = hci_uart.cfg.stop_bits; - uart_parity_t parity = hci_uart.cfg.parity; - uart_hw_flowcontrol_t flow_ctl = hci_uart.cfg.flow_ctrl; - hci_uart_close(port_num); - hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - ESP_ERROR_CHECK(uart_set_pin(port_num, tx_pin, rx_pin, rts_pin, cts_pin)); - return 0; -} -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART diff --git a/components/bt/sdkconfig.rename b/components/bt/sdkconfig.rename index cdaf6d3014..55beeffcfd 100644 --- a/components/bt/sdkconfig.rename +++ b/components/bt/sdkconfig.rename @@ -284,3 +284,6 @@ CONFIG_BT_NIMBLE_ACL_BUF_SIZE CONFIG_BT_NIMBLE_TRA CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT CONFIG_BT_NIMBLE_TRANSPORT_EVT_DISCARD_COUNT + +CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EN CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EN +CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_DIS CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_DIS diff --git a/components/bt/sdkconfig.rename.esp32c3 b/components/bt/sdkconfig.rename.esp32c3 new file mode 100644 index 0000000000..38906e4cb4 --- /dev/null +++ b/components/bt/sdkconfig.rename.esp32c3 @@ -0,0 +1,5 @@ +# sdkconfig replacement configurations for deprecated options formatted as +# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION + +CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EN CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN +CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_DIS CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS diff --git a/components/bt/sdkconfig.rename.esp32s3 b/components/bt/sdkconfig.rename.esp32s3 new file mode 100644 index 0000000000..38906e4cb4 --- /dev/null +++ b/components/bt/sdkconfig.rename.esp32s3 @@ -0,0 +1,5 @@ +# sdkconfig replacement configurations for deprecated options formatted as +# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION + +CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_EN CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EN +CONFIG_BT_NIMBLE_COEX_PHY_CODED_TX_RX_TLIM_DIS CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_DIS diff --git a/components/efuse/esp32c2/esp_efuse_rtc_calib.c b/components/efuse/esp32c2/esp_efuse_rtc_calib.c index 0e36070959..058687cbe3 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; } @@ -67,12 +67,12 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in { 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 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. */ @@ -97,7 +97,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/efuse/esp32c6/esp_efuse_table.c b/components/efuse/esp32c6/esp_efuse_table.c index e6bf085e8a..8b04686b30 100644 --- a/components/efuse/esp32c6/esp_efuse_table.c +++ b/components/efuse/esp32c6/esp_efuse_table.c @@ -9,7 +9,7 @@ #include #include "esp_efuse_table.h" -// md5_digest_table fd5a35cea89bfad954e834bc92bed385 +// md5_digest_table 0d9c0c6a65ccf2d4a7279ede32b6f797 // 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. @@ -187,6 +187,34 @@ static const esp_efuse_desc_t WR_DIS_MAC_EXT[] = { {EFUSE_BLK0, 20, 1}, // [] wr_dis of MAC_EXT, }; +static const esp_efuse_desc_t WR_DIS_ACTIVE_HP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of ACTIVE_HP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_ACTIVE_LP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of ACTIVE_LP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_LSLP_HP_DBG[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of LSLP_HP_DBG, +}; + +static const esp_efuse_desc_t WR_DIS_LSLP_HP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of LSLP_HP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_DSLP_LP_DBG[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of DSLP_LP_DBG, +}; + +static const esp_efuse_desc_t WR_DIS_DSLP_LP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of DSLP_LP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_DBIAS_VOL_GAP[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of DBIAS_VOL_GAP, +}; + static const esp_efuse_desc_t WR_DIS_WAFER_VERSION_MINOR[] = { {EFUSE_BLK0, 20, 1}, // [] wr_dis of WAFER_VERSION_MINOR, }; @@ -553,6 +581,34 @@ static const esp_efuse_desc_t MAC_EXT[] = { {EFUSE_BLK1, 48, 8}, // [] Stores the extended bits of MAC address, }; +static const esp_efuse_desc_t ACTIVE_HP_DBIAS[] = { + {EFUSE_BLK1, 64, 5}, // [] Stores the active hp dbias, +}; + +static const esp_efuse_desc_t ACTIVE_LP_DBIAS[] = { + {EFUSE_BLK1, 69, 5}, // [] Stores the active lp dbias, +}; + +static const esp_efuse_desc_t LSLP_HP_DBG[] = { + {EFUSE_BLK1, 74, 2}, // [] Stores the lslp hp dbg, +}; + +static const esp_efuse_desc_t LSLP_HP_DBIAS[] = { + {EFUSE_BLK1, 76, 4}, // [] Stores the lslp hp dbias, +}; + +static const esp_efuse_desc_t DSLP_LP_DBG[] = { + {EFUSE_BLK1, 80, 3}, // [] Stores the dslp lp dbg, +}; + +static const esp_efuse_desc_t DSLP_LP_DBIAS[] = { + {EFUSE_BLK1, 83, 4}, // [] Stores the dslp lp dbias, +}; + +static const esp_efuse_desc_t DBIAS_VOL_GAP[] = { + {EFUSE_BLK1, 87, 5}, // [] Stores the hp and lp dbias vol gap, +}; + static const esp_efuse_desc_t WAFER_VERSION_MINOR[] = { {EFUSE_BLK1, 114, 4}, // [], }; @@ -912,6 +968,41 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC_EXT[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_HP_DBIAS[] = { + &WR_DIS_ACTIVE_HP_DBIAS[0], // [] wr_dis of ACTIVE_HP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_LP_DBIAS[] = { + &WR_DIS_ACTIVE_LP_DBIAS[0], // [] wr_dis of ACTIVE_LP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_LSLP_HP_DBG[] = { + &WR_DIS_LSLP_HP_DBG[0], // [] wr_dis of LSLP_HP_DBG + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_LSLP_HP_DBIAS[] = { + &WR_DIS_LSLP_HP_DBIAS[0], // [] wr_dis of LSLP_HP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DSLP_LP_DBG[] = { + &WR_DIS_DSLP_LP_DBG[0], // [] wr_dis of DSLP_LP_DBG + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DSLP_LP_DBIAS[] = { + &WR_DIS_DSLP_LP_DBIAS[0], // [] wr_dis of DSLP_LP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DBIAS_VOL_GAP[] = { + &WR_DIS_DBIAS_VOL_GAP[0], // [] wr_dis of DBIAS_VOL_GAP + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MINOR[] = { &WR_DIS_WAFER_VERSION_MINOR[0], // [] wr_dis of WAFER_VERSION_MINOR NULL @@ -1368,6 +1459,41 @@ const esp_efuse_desc_t* ESP_EFUSE_MAC_EXT[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_HP_DBIAS[] = { + &ACTIVE_HP_DBIAS[0], // [] Stores the active hp dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_LP_DBIAS[] = { + &ACTIVE_LP_DBIAS[0], // [] Stores the active lp dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_LSLP_HP_DBG[] = { + &LSLP_HP_DBG[0], // [] Stores the lslp hp dbg + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_LSLP_HP_DBIAS[] = { + &LSLP_HP_DBIAS[0], // [] Stores the lslp hp dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DSLP_LP_DBG[] = { + &DSLP_LP_DBG[0], // [] Stores the dslp lp dbg + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DSLP_LP_DBIAS[] = { + &DSLP_LP_DBIAS[0], // [] Stores the dslp lp dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DBIAS_VOL_GAP[] = { + &DBIAS_VOL_GAP[0], // [] Stores the hp and lp dbias vol gap + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MINOR[] = { &WAFER_VERSION_MINOR[0], // [] NULL diff --git a/components/efuse/esp32c6/esp_efuse_table.csv b/components/efuse/esp32c6/esp_efuse_table.csv index 9cfbb6fb6d..7f0f52ec39 100644 --- a/components/efuse/esp32c6/esp_efuse_table.csv +++ b/components/efuse/esp32c6/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: 709e8ea096e8a03a10006d40d5451a49 +# This file was generated by regtools.py based on the efuses.yaml file with the version: df46b69f0ed3913114ba53d3a0b2b843 WR_DIS, EFUSE_BLK0, 0, 32, [] Disable programming of individual eFuses WR_DIS.RD_DIS, EFUSE_BLK0, 0, 1, [] wr_dis of RD_DIS @@ -54,6 +54,13 @@ WR_DIS.DISABLE_BLK_VERSION_MAJOR, EFUSE_BLK0, 19, 1, [] wr_dis WR_DIS.BLK1, EFUSE_BLK0, 20, 1, [] wr_dis of BLOCK1 WR_DIS.MAC, EFUSE_BLK0, 20, 1, [WR_DIS.MAC_FACTORY] wr_dis of MAC WR_DIS.MAC_EXT, EFUSE_BLK0, 20, 1, [] wr_dis of MAC_EXT +WR_DIS.ACTIVE_HP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of ACTIVE_HP_DBIAS +WR_DIS.ACTIVE_LP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of ACTIVE_LP_DBIAS +WR_DIS.LSLP_HP_DBG, EFUSE_BLK0, 20, 1, [] wr_dis of LSLP_HP_DBG +WR_DIS.LSLP_HP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of LSLP_HP_DBIAS +WR_DIS.DSLP_LP_DBG, EFUSE_BLK0, 20, 1, [] wr_dis of DSLP_LP_DBG +WR_DIS.DSLP_LP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of DSLP_LP_DBIAS +WR_DIS.DBIAS_VOL_GAP, EFUSE_BLK0, 20, 1, [] wr_dis of DBIAS_VOL_GAP WR_DIS.WAFER_VERSION_MINOR, EFUSE_BLK0, 20, 1, [] wr_dis of WAFER_VERSION_MINOR WR_DIS.WAFER_VERSION_MAJOR, EFUSE_BLK0, 20, 1, [] wr_dis of WAFER_VERSION_MAJOR WR_DIS.PKG_VERSION, EFUSE_BLK0, 20, 1, [] wr_dis of PKG_VERSION @@ -150,6 +157,13 @@ MAC, EFUSE_BLK1, 40, 8, [MAC_FACT , EFUSE_BLK1, 0, 8, [MAC_FACTORY] MAC address MAC_EXT, EFUSE_BLK1, 56, 8, [] Stores the extended bits of MAC address , EFUSE_BLK1, 48, 8, [] Stores the extended bits of MAC address +ACTIVE_HP_DBIAS, EFUSE_BLK1, 64, 5, [] Stores the active hp dbias +ACTIVE_LP_DBIAS, EFUSE_BLK1, 69, 5, [] Stores the active lp dbias +LSLP_HP_DBG, EFUSE_BLK1, 74, 2, [] Stores the lslp hp dbg +LSLP_HP_DBIAS, EFUSE_BLK1, 76, 4, [] Stores the lslp hp dbias +DSLP_LP_DBG, EFUSE_BLK1, 80, 3, [] Stores the dslp lp dbg +DSLP_LP_DBIAS, EFUSE_BLK1, 83, 4, [] Stores the dslp lp dbias +DBIAS_VOL_GAP, EFUSE_BLK1, 87, 5, [] Stores the hp and lp dbias vol gap WAFER_VERSION_MINOR, EFUSE_BLK1, 114, 4, [] WAFER_VERSION_MAJOR, EFUSE_BLK1, 118, 2, [] PKG_VERSION, EFUSE_BLK1, 120, 3, [] Package version diff --git a/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h index e2cb7610fd..9e65f777b5 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/esp32c6/include/esp_efuse_table.h b/components/efuse/esp32c6/include/esp_efuse_table.h index 28379f9672..c0dec3c99b 100644 --- a/components/efuse/esp32c6/include/esp_efuse_table.h +++ b/components/efuse/esp32c6/include/esp_efuse_table.h @@ -10,7 +10,7 @@ extern "C" { #include "esp_efuse.h" -// md5_digest_table fd5a35cea89bfad954e834bc92bed385 +// md5_digest_table 0d9c0c6a65ccf2d4a7279ede32b6f797 // 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. @@ -70,6 +70,13 @@ extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK1[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC[]; #define ESP_EFUSE_WR_DIS_MAC_FACTORY ESP_EFUSE_WR_DIS_MAC extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC_EXT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_HP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_LP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_LSLP_HP_DBG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_LSLP_HP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DSLP_LP_DBG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DSLP_LP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DBIAS_VOL_GAP[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MINOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MAJOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PKG_VERSION[]; @@ -187,6 +194,13 @@ extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_BLK_VERSION_MAJOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_MAC[]; #define ESP_EFUSE_MAC_FACTORY ESP_EFUSE_MAC extern const esp_efuse_desc_t* ESP_EFUSE_MAC_EXT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_HP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_LP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_LSLP_HP_DBG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_LSLP_HP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DSLP_LP_DBG[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DSLP_LP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DBIAS_VOL_GAP[]; extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MINOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MAJOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[]; diff --git a/components/efuse/esp32h2/esp_efuse_rtc_calib.c b/components/efuse/esp32h2/esp_efuse_rtc_calib.c index 5c41630475..2ff20ea3a3 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/esp_efuse_table.c b/components/efuse/esp32h2/esp_efuse_table.c index 5a89b0fa7a..31482481ed 100644 --- a/components/efuse/esp32h2/esp_efuse_table.c +++ b/components/efuse/esp32h2/esp_efuse_table.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,7 +9,7 @@ #include #include "esp_efuse_table.h" -// md5_digest_table 47596a1f76a01780351e34b4785323dd +// md5_digest_table 1b79da735c5daed71ed7a91a0c55c5b6 // 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. @@ -183,6 +183,34 @@ static const esp_efuse_desc_t WR_DIS_MAC_EXT[] = { {EFUSE_BLK0, 20, 1}, // [] wr_dis of MAC_EXT, }; +static const esp_efuse_desc_t WR_DIS_RXIQ_VERSION[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of RXIQ_VERSION, +}; + +static const esp_efuse_desc_t WR_DIS_RXIQ_0[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of RXIQ_0, +}; + +static const esp_efuse_desc_t WR_DIS_RXIQ_1[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of RXIQ_1, +}; + +static const esp_efuse_desc_t WR_DIS_ACTIVE_HP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of ACTIVE_HP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_ACTIVE_LP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of ACTIVE_LP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_DSLP_DBIAS[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of DSLP_DBIAS, +}; + +static const esp_efuse_desc_t WR_DIS_DBIAS_VOL_GAP[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of DBIAS_VOL_GAP, +}; + static const esp_efuse_desc_t WR_DIS_WAFER_VERSION_MINOR[] = { {EFUSE_BLK0, 20, 1}, // [] wr_dis of WAFER_VERSION_MINOR, }; @@ -231,6 +259,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, }; @@ -485,12 +569,40 @@ static const esp_efuse_desc_t MAC_EXT[] = { {EFUSE_BLK1, 48, 8}, // [] Stores the extended bits of MAC address, }; +static const esp_efuse_desc_t RXIQ_VERSION[] = { + {EFUSE_BLK1, 64, 3}, // [] Stores RF Calibration data. RXIQ version, +}; + +static const esp_efuse_desc_t RXIQ_0[] = { + {EFUSE_BLK1, 67, 7}, // [] Stores RF Calibration data. RXIQ data 0, +}; + +static const esp_efuse_desc_t RXIQ_1[] = { + {EFUSE_BLK1, 74, 7}, // [] Stores RF Calibration data. RXIQ data 1, +}; + +static const esp_efuse_desc_t ACTIVE_HP_DBIAS[] = { + {EFUSE_BLK1, 81, 5}, // [] Stores the PMU active hp dbias, +}; + +static const esp_efuse_desc_t ACTIVE_LP_DBIAS[] = { + {EFUSE_BLK1, 86, 5}, // [] Stores the PMU active lp dbias, +}; + +static const esp_efuse_desc_t DSLP_DBIAS[] = { + {EFUSE_BLK1, 91, 4}, // [] Stores the PMU sleep dbias, +}; + +static const esp_efuse_desc_t DBIAS_VOL_GAP[] = { + {EFUSE_BLK1, 95, 5}, // [] Stores the low 1 bit of dbias_vol_gap, +}; + static const esp_efuse_desc_t WAFER_VERSION_MINOR[] = { - {EFUSE_BLK1, 114, 3}, // [], + {EFUSE_BLK1, 114, 3}, // [] Stores the wafer version minor, }; static const esp_efuse_desc_t WAFER_VERSION_MAJOR[] = { - {EFUSE_BLK1, 117, 2}, // [], + {EFUSE_BLK1, 117, 2}, // [] Stores the wafer version major, }; static const esp_efuse_desc_t DISABLE_WAFER_VERSION_MAJOR[] = { @@ -498,15 +610,15 @@ static const esp_efuse_desc_t DISABLE_WAFER_VERSION_MAJOR[] = { }; static const esp_efuse_desc_t FLASH_CAP[] = { - {EFUSE_BLK1, 120, 3}, // [], + {EFUSE_BLK1, 120, 3}, // [] Stores the flash cap, }; static const esp_efuse_desc_t FLASH_TEMP[] = { - {EFUSE_BLK1, 123, 2}, // [], + {EFUSE_BLK1, 123, 2}, // [] Stores the flash temp, }; static const esp_efuse_desc_t FLASH_VENDOR[] = { - {EFUSE_BLK1, 125, 3}, // [], + {EFUSE_BLK1, 125, 3}, // [] Stores the flash vendor, }; static const esp_efuse_desc_t PKG_VERSION[] = { @@ -518,7 +630,7 @@ static const esp_efuse_desc_t OPTIONAL_UNIQUE_ID[] = { }; static const esp_efuse_desc_t BLK_VERSION_MINOR[] = { - {EFUSE_BLK2, 130, 3}, // [] BLK_VERSION_MINOR of BLOCK2, + {EFUSE_BLK2, 130, 3}, // [] BLK_VERSION_MINOR of BLOCK2. 1: RF Calibration data in BLOCK1, }; static const esp_efuse_desc_t BLK_VERSION_MAJOR[] = { @@ -529,6 +641,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, }; @@ -779,6 +947,41 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC_EXT[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RXIQ_VERSION[] = { + &WR_DIS_RXIQ_VERSION[0], // [] wr_dis of RXIQ_VERSION + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RXIQ_0[] = { + &WR_DIS_RXIQ_0[0], // [] wr_dis of RXIQ_0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RXIQ_1[] = { + &WR_DIS_RXIQ_1[0], // [] wr_dis of RXIQ_1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_HP_DBIAS[] = { + &WR_DIS_ACTIVE_HP_DBIAS[0], // [] wr_dis of ACTIVE_HP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_LP_DBIAS[] = { + &WR_DIS_ACTIVE_LP_DBIAS[0], // [] wr_dis of ACTIVE_LP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DSLP_DBIAS[] = { + &WR_DIS_DSLP_DBIAS[0], // [] wr_dis of DSLP_DBIAS + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DBIAS_VOL_GAP[] = { + &WR_DIS_DBIAS_VOL_GAP[0], // [] wr_dis of DBIAS_VOL_GAP + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MINOR[] = { &WR_DIS_WAFER_VERSION_MINOR[0], // [] wr_dis of WAFER_VERSION_MINOR NULL @@ -839,6 +1042,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 @@ -1155,13 +1428,48 @@ const esp_efuse_desc_t* ESP_EFUSE_MAC_EXT[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_RXIQ_VERSION[] = { + &RXIQ_VERSION[0], // [] Stores RF Calibration data. RXIQ version + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_RXIQ_0[] = { + &RXIQ_0[0], // [] Stores RF Calibration data. RXIQ data 0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_RXIQ_1[] = { + &RXIQ_1[0], // [] Stores RF Calibration data. RXIQ data 1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_HP_DBIAS[] = { + &ACTIVE_HP_DBIAS[0], // [] Stores the PMU active hp dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_LP_DBIAS[] = { + &ACTIVE_LP_DBIAS[0], // [] Stores the PMU active lp dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DSLP_DBIAS[] = { + &DSLP_DBIAS[0], // [] Stores the PMU sleep dbias + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_DBIAS_VOL_GAP[] = { + &DBIAS_VOL_GAP[0], // [] Stores the low 1 bit of dbias_vol_gap + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MINOR[] = { - &WAFER_VERSION_MINOR[0], // [] + &WAFER_VERSION_MINOR[0], // [] Stores the wafer version minor NULL }; const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MAJOR[] = { - &WAFER_VERSION_MAJOR[0], // [] + &WAFER_VERSION_MAJOR[0], // [] Stores the wafer version major NULL }; @@ -1171,17 +1479,17 @@ const esp_efuse_desc_t* ESP_EFUSE_DISABLE_WAFER_VERSION_MAJOR[] = { }; const esp_efuse_desc_t* ESP_EFUSE_FLASH_CAP[] = { - &FLASH_CAP[0], // [] + &FLASH_CAP[0], // [] Stores the flash cap NULL }; const esp_efuse_desc_t* ESP_EFUSE_FLASH_TEMP[] = { - &FLASH_TEMP[0], // [] + &FLASH_TEMP[0], // [] Stores the flash temp NULL }; const esp_efuse_desc_t* ESP_EFUSE_FLASH_VENDOR[] = { - &FLASH_VENDOR[0], // [] + &FLASH_VENDOR[0], // [] Stores the flash vendor NULL }; @@ -1196,7 +1504,7 @@ const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[] = { }; const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MINOR[] = { - &BLK_VERSION_MINOR[0], // [] BLK_VERSION_MINOR of BLOCK2 + &BLK_VERSION_MINOR[0], // [] BLK_VERSION_MINOR of BLOCK2. 1: RF Calibration data in BLOCK1 NULL }; @@ -1210,6 +1518,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 0cf4ca0966..20b5cec21d 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: 304372753f7bc2d7665354c487c05b4e +# This file was generated by regtools.py based on the efuses.yaml file with the version: ef562916e77cf77203c1a4c0cff35ac5 WR_DIS, EFUSE_BLK0, 0, 32, [] Disable programming of individual eFuses WR_DIS.RD_DIS, EFUSE_BLK0, 0, 1, [] wr_dis of RD_DIS @@ -53,6 +53,13 @@ WR_DIS.HYS_EN_PAD1, EFUSE_BLK0, 19, 1, [] wr_dis WR_DIS.BLK1, EFUSE_BLK0, 20, 1, [] wr_dis of BLOCK1 WR_DIS.MAC, EFUSE_BLK0, 20, 1, [WR_DIS.MAC_FACTORY] wr_dis of MAC WR_DIS.MAC_EXT, EFUSE_BLK0, 20, 1, [] wr_dis of MAC_EXT +WR_DIS.RXIQ_VERSION, EFUSE_BLK0, 20, 1, [] wr_dis of RXIQ_VERSION +WR_DIS.RXIQ_0, EFUSE_BLK0, 20, 1, [] wr_dis of RXIQ_0 +WR_DIS.RXIQ_1, EFUSE_BLK0, 20, 1, [] wr_dis of RXIQ_1 +WR_DIS.ACTIVE_HP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of ACTIVE_HP_DBIAS +WR_DIS.ACTIVE_LP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of ACTIVE_LP_DBIAS +WR_DIS.DSLP_DBIAS, EFUSE_BLK0, 20, 1, [] wr_dis of DSLP_DBIAS +WR_DIS.DBIAS_VOL_GAP, EFUSE_BLK0, 20, 1, [] wr_dis of DBIAS_VOL_GAP WR_DIS.WAFER_VERSION_MINOR, EFUSE_BLK0, 20, 1, [] wr_dis of WAFER_VERSION_MINOR WR_DIS.WAFER_VERSION_MAJOR, EFUSE_BLK0, 20, 1, [] wr_dis of WAFER_VERSION_MAJOR WR_DIS.DISABLE_WAFER_VERSION_MAJOR, EFUSE_BLK0, 20, 1, [] wr_dis of DISABLE_WAFER_VERSION_MAJOR @@ -65,6 +72,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 @@ -133,17 +154,38 @@ MAC, EFUSE_BLK1, 40, 8, [MAC_FACT , EFUSE_BLK1, 0, 8, [MAC_FACTORY] MAC address MAC_EXT, EFUSE_BLK1, 56, 8, [] Stores the extended bits of MAC address , EFUSE_BLK1, 48, 8, [] Stores the extended bits of MAC address -WAFER_VERSION_MINOR, EFUSE_BLK1, 114, 3, [] -WAFER_VERSION_MAJOR, EFUSE_BLK1, 117, 2, [] +RXIQ_VERSION, EFUSE_BLK1, 64, 3, [] Stores RF Calibration data. RXIQ version +RXIQ_0, EFUSE_BLK1, 67, 7, [] Stores RF Calibration data. RXIQ data 0 +RXIQ_1, EFUSE_BLK1, 74, 7, [] Stores RF Calibration data. RXIQ data 1 +ACTIVE_HP_DBIAS, EFUSE_BLK1, 81, 5, [] Stores the PMU active hp dbias +ACTIVE_LP_DBIAS, EFUSE_BLK1, 86, 5, [] Stores the PMU active lp dbias +DSLP_DBIAS, EFUSE_BLK1, 91, 4, [] Stores the PMU sleep dbias +DBIAS_VOL_GAP, EFUSE_BLK1, 95, 5, [] Stores the low 1 bit of dbias_vol_gap +WAFER_VERSION_MINOR, EFUSE_BLK1, 114, 3, [] Stores the wafer version minor +WAFER_VERSION_MAJOR, EFUSE_BLK1, 117, 2, [] Stores the wafer version major DISABLE_WAFER_VERSION_MAJOR, EFUSE_BLK1, 119, 1, [] Disables check of wafer version major -FLASH_CAP, EFUSE_BLK1, 120, 3, [] -FLASH_TEMP, EFUSE_BLK1, 123, 2, [] -FLASH_VENDOR, EFUSE_BLK1, 125, 3, [] +FLASH_CAP, EFUSE_BLK1, 120, 3, [] Stores the flash cap +FLASH_TEMP, EFUSE_BLK1, 123, 2, [] Stores the flash temp +FLASH_VENDOR, EFUSE_BLK1, 125, 3, [] Stores the flash vendor PKG_VERSION, EFUSE_BLK1, 128, 3, [] Package version OPTIONAL_UNIQUE_ID, EFUSE_BLK2, 0, 128, [] Optional unique 128-bit ID -BLK_VERSION_MINOR, EFUSE_BLK2, 130, 3, [] BLK_VERSION_MINOR of BLOCK2 +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_rtc_calib.h b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h index a71ed13784..2101902a7b 100644 --- a/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h @@ -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,21 @@ 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. ESP32H2 only supports one ADC unit + * @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 +56,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/efuse/esp32h2/include/esp_efuse_table.h b/components/efuse/esp32h2/include/esp_efuse_table.h index feab76c131..2aa6a22ee4 100644 --- a/components/efuse/esp32h2/include/esp_efuse_table.h +++ b/components/efuse/esp32h2/include/esp_efuse_table.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,7 +10,7 @@ extern "C" { #include "esp_efuse.h" -// md5_digest_table 47596a1f76a01780351e34b4785323dd +// md5_digest_table 1b79da735c5daed71ed7a91a0c55c5b6 // 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. @@ -68,6 +68,13 @@ extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK1[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC[]; #define ESP_EFUSE_WR_DIS_MAC_FACTORY ESP_EFUSE_WR_DIS_MAC extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_MAC_EXT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RXIQ_VERSION[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RXIQ_0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_RXIQ_1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_HP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ACTIVE_LP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DSLP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DBIAS_VOL_GAP[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MINOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MAJOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_DISABLE_WAFER_VERSION_MAJOR[]; @@ -80,6 +87,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[]; @@ -168,6 +189,13 @@ extern const esp_efuse_desc_t* ESP_EFUSE_HYS_EN_PAD1[]; extern const esp_efuse_desc_t* ESP_EFUSE_MAC[]; #define ESP_EFUSE_MAC_FACTORY ESP_EFUSE_MAC extern const esp_efuse_desc_t* ESP_EFUSE_MAC_EXT[]; +extern const esp_efuse_desc_t* ESP_EFUSE_RXIQ_VERSION[]; +extern const esp_efuse_desc_t* ESP_EFUSE_RXIQ_0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_RXIQ_1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_HP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ACTIVE_LP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DSLP_DBIAS[]; +extern const esp_efuse_desc_t* ESP_EFUSE_DBIAS_VOL_GAP[]; extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MINOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MAJOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_WAFER_VERSION_MAJOR[]; @@ -179,6 +207,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/efuse/esp32s3/esp_efuse_table.c b/components/efuse/esp32s3/esp_efuse_table.c index 85bb0d2900..b48f6b2010 100644 --- a/components/efuse/esp32s3/esp_efuse_table.c +++ b/components/efuse/esp32s3/esp_efuse_table.c @@ -9,7 +9,7 @@ #include #include "esp_efuse_table.h" -// md5_digest_table 7f80667718451ae522bb4d60ced03d49 +// md5_digest_table e0674ff40a1e124670c6eecf33410e76 // 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. @@ -275,6 +275,30 @@ static const esp_efuse_desc_t WR_DIS_BLK_VERSION_MINOR[] = { {EFUSE_BLK0, 20, 1}, // [] wr_dis of BLK_VERSION_MINOR, }; +static const esp_efuse_desc_t WR_DIS_FLASH_CAP[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of FLASH_CAP, +}; + +static const esp_efuse_desc_t WR_DIS_FLASH_TEMP[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of FLASH_TEMP, +}; + +static const esp_efuse_desc_t WR_DIS_FLASH_VENDOR[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of FLASH_VENDOR, +}; + +static const esp_efuse_desc_t WR_DIS_PSRAM_CAP[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of PSRAM_CAP, +}; + +static const esp_efuse_desc_t WR_DIS_PSRAM_TEMP[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of PSRAM_TEMP, +}; + +static const esp_efuse_desc_t WR_DIS_PSRAM_VENDOR[] = { + {EFUSE_BLK0, 20, 1}, // [] wr_dis of PSRAM_VENDOR, +}; + static const esp_efuse_desc_t WR_DIS_K_RTC_LDO[] = { {EFUSE_BLK0, 20, 1}, // [] wr_dis of K_RTC_LDO, }; @@ -732,6 +756,30 @@ static const esp_efuse_desc_t BLK_VERSION_MINOR[] = { {EFUSE_BLK1, 120, 3}, // [] BLK_VERSION_MINOR, }; +static const esp_efuse_desc_t FLASH_CAP[] = { + {EFUSE_BLK1, 123, 3}, // [] Flash capacity {0: "None"; 1: "8M"; 2: "4M"}, +}; + +static const esp_efuse_desc_t FLASH_TEMP[] = { + {EFUSE_BLK1, 126, 2}, // [] Flash temperature {0: "None"; 1: "105C"; 2: "85C"}, +}; + +static const esp_efuse_desc_t FLASH_VENDOR[] = { + {EFUSE_BLK1, 128, 3}, // [] Flash vendor {0: "None"; 1: "XMC"; 2: "GD"; 3: "FM"; 4: "TT"; 5: "BY"}, +}; + +static const esp_efuse_desc_t PSRAM_CAP[] = { + {EFUSE_BLK1, 131, 2}, // [] PSRAM capacity {0: "None"; 1: "8M"; 2: "2M"}, +}; + +static const esp_efuse_desc_t PSRAM_TEMP[] = { + {EFUSE_BLK1, 133, 2}, // [] PSRAM temperature {0: "None"; 1: "105C"; 2: "85C"}, +}; + +static const esp_efuse_desc_t PSRAM_VENDOR[] = { + {EFUSE_BLK1, 135, 2}, // [] PSRAM vendor {0: "None"; 1: "AP_3v3"; 2: "AP_1v8"}, +}; + static const esp_efuse_desc_t K_RTC_LDO[] = { {EFUSE_BLK1, 141, 7}, // [] BLOCK1 K_RTC_LDO, }; @@ -1205,6 +1253,36 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MINOR[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_CAP[] = { + &WR_DIS_FLASH_CAP[0], // [] wr_dis of FLASH_CAP + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_TEMP[] = { + &WR_DIS_FLASH_TEMP[0], // [] wr_dis of FLASH_TEMP + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_VENDOR[] = { + &WR_DIS_FLASH_VENDOR[0], // [] wr_dis of FLASH_VENDOR + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PSRAM_CAP[] = { + &WR_DIS_PSRAM_CAP[0], // [] wr_dis of PSRAM_CAP + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PSRAM_TEMP[] = { + &WR_DIS_PSRAM_TEMP[0], // [] wr_dis of PSRAM_TEMP + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PSRAM_VENDOR[] = { + &WR_DIS_PSRAM_VENDOR[0], // [] wr_dis of PSRAM_VENDOR + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_K_RTC_LDO[] = { &WR_DIS_K_RTC_LDO[0], // [] wr_dis of K_RTC_LDO NULL @@ -1775,6 +1853,36 @@ const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MINOR[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_FLASH_CAP[] = { + &FLASH_CAP[0], // [] Flash capacity {0: "None"; 1: "8M"; 2: "4M"} + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_FLASH_TEMP[] = { + &FLASH_TEMP[0], // [] Flash temperature {0: "None"; 1: "105C"; 2: "85C"} + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_FLASH_VENDOR[] = { + &FLASH_VENDOR[0], // [] Flash vendor {0: "None"; 1: "XMC"; 2: "GD"; 3: "FM"; 4: "TT"; 5: "BY"} + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_PSRAM_CAP[] = { + &PSRAM_CAP[0], // [] PSRAM capacity {0: "None"; 1: "8M"; 2: "2M"} + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_PSRAM_TEMP[] = { + &PSRAM_TEMP[0], // [] PSRAM temperature {0: "None"; 1: "105C"; 2: "85C"} + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_PSRAM_VENDOR[] = { + &PSRAM_VENDOR[0], // [] PSRAM vendor {0: "None"; 1: "AP_3v3"; 2: "AP_1v8"} + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_K_RTC_LDO[] = { &K_RTC_LDO[0], // [] BLOCK1 K_RTC_LDO NULL diff --git a/components/efuse/esp32s3/esp_efuse_table.csv b/components/efuse/esp32s3/esp_efuse_table.csv index 9f995a13a1..a55cfa2d59 100644 --- a/components/efuse/esp32s3/esp_efuse_table.csv +++ b/components/efuse/esp32s3/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: 6925129eca795b8b087d31be539740ec +# This file was generated by regtools.py based on the efuses.yaml file with the version: f75f74727101326a187188a23f4a6c70 WR_DIS, EFUSE_BLK0, 0, 32, [] Disable programming of individual eFuses WR_DIS.RD_DIS, EFUSE_BLK0, 0, 1, [] wr_dis of RD_DIS @@ -76,6 +76,12 @@ WR_DIS.SPI_PAD_CONFIG_D7, EFUSE_BLK0, 20, 1, [] wr_dis WR_DIS.WAFER_VERSION_MINOR_LO, EFUSE_BLK0, 20, 1, [] wr_dis of WAFER_VERSION_MINOR_LO WR_DIS.PKG_VERSION, EFUSE_BLK0, 20, 1, [] wr_dis of PKG_VERSION WR_DIS.BLK_VERSION_MINOR, EFUSE_BLK0, 20, 1, [] wr_dis of BLK_VERSION_MINOR +WR_DIS.FLASH_CAP, EFUSE_BLK0, 20, 1, [] wr_dis of FLASH_CAP +WR_DIS.FLASH_TEMP, EFUSE_BLK0, 20, 1, [] wr_dis of FLASH_TEMP +WR_DIS.FLASH_VENDOR, EFUSE_BLK0, 20, 1, [] wr_dis of FLASH_VENDOR +WR_DIS.PSRAM_CAP, EFUSE_BLK0, 20, 1, [] wr_dis of PSRAM_CAP +WR_DIS.PSRAM_TEMP, EFUSE_BLK0, 20, 1, [] wr_dis of PSRAM_TEMP +WR_DIS.PSRAM_VENDOR, EFUSE_BLK0, 20, 1, [] wr_dis of PSRAM_VENDOR WR_DIS.K_RTC_LDO, EFUSE_BLK0, 20, 1, [] wr_dis of K_RTC_LDO WR_DIS.K_DIG_LDO, EFUSE_BLK0, 20, 1, [] wr_dis of K_DIG_LDO WR_DIS.V_RTC_DBIAS20, EFUSE_BLK0, 20, 1, [] wr_dis of V_RTC_DBIAS20 @@ -194,6 +200,12 @@ SPI_PAD_CONFIG_D7, EFUSE_BLK1, 108, 6, [] SPI_PA WAFER_VERSION_MINOR_LO, EFUSE_BLK1, 114, 3, [] WAFER_VERSION_MINOR least significant bits PKG_VERSION, EFUSE_BLK1, 117, 3, [] Package version BLK_VERSION_MINOR, EFUSE_BLK1, 120, 3, [] BLK_VERSION_MINOR +FLASH_CAP, EFUSE_BLK1, 123, 3, [] Flash capacity {0: "None"; 1: "8M"; 2: "4M"} +FLASH_TEMP, EFUSE_BLK1, 126, 2, [] Flash temperature {0: "None"; 1: "105C"; 2: "85C"} +FLASH_VENDOR, EFUSE_BLK1, 128, 3, [] Flash vendor {0: "None"; 1: "XMC"; 2: "GD"; 3: "FM"; 4: "TT"; 5: "BY"} +PSRAM_CAP, EFUSE_BLK1, 131, 2, [] PSRAM capacity {0: "None"; 1: "8M"; 2: "2M"} +PSRAM_TEMP, EFUSE_BLK1, 133, 2, [] PSRAM temperature {0: "None"; 1: "105C"; 2: "85C"} +PSRAM_VENDOR, EFUSE_BLK1, 135, 2, [] PSRAM vendor {0: "None"; 1: "AP_3v3"; 2: "AP_1v8"} K_RTC_LDO, EFUSE_BLK1, 141, 7, [] BLOCK1 K_RTC_LDO K_DIG_LDO, EFUSE_BLK1, 148, 7, [] BLOCK1 K_DIG_LDO V_RTC_DBIAS20, EFUSE_BLK1, 155, 8, [] BLOCK1 voltage of rtc dbias20 diff --git a/components/efuse/esp32s3/include/esp_efuse_table.h b/components/efuse/esp32s3/include/esp_efuse_table.h index f34fce781a..5fb75b6872 100644 --- a/components/efuse/esp32s3/include/esp_efuse_table.h +++ b/components/efuse/esp32s3/include/esp_efuse_table.h @@ -10,7 +10,7 @@ extern "C" { #include "esp_efuse.h" -// md5_digest_table 7f80667718451ae522bb4d60ced03d49 +// md5_digest_table e0674ff40a1e124670c6eecf33410e76 // 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. @@ -96,6 +96,12 @@ extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SPI_PAD_CONFIG_D7[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_WAFER_VERSION_MINOR_LO[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PKG_VERSION[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK_VERSION_MINOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_CAP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_TEMP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_VENDOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PSRAM_CAP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PSRAM_TEMP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_PSRAM_VENDOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_K_RTC_LDO[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_K_DIG_LDO[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_V_RTC_DBIAS20[]; @@ -242,6 +248,12 @@ extern const esp_efuse_desc_t* ESP_EFUSE_SPI_PAD_CONFIG_D7[]; extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MINOR_LO[]; extern const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[]; extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MINOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_CAP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TEMP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_VENDOR[]; +extern const esp_efuse_desc_t* ESP_EFUSE_PSRAM_CAP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_PSRAM_TEMP[]; +extern const esp_efuse_desc_t* ESP_EFUSE_PSRAM_VENDOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_K_RTC_LDO[]; extern const esp_efuse_desc_t* ESP_EFUSE_K_DIG_LDO[]; extern const esp_efuse_desc_t* ESP_EFUSE_V_RTC_DBIAS20[]; diff --git a/components/efuse/include/esp_efuse.h b/components/efuse/include/esp_efuse.h index 80db72a608..fa075f91ac 100644 --- a/components/efuse/include/esp_efuse.h +++ b/components/efuse/include/esp_efuse.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -235,7 +235,7 @@ esp_err_t esp_efuse_write_reg(esp_efuse_block_t blk, unsigned int num_reg, uint3 /** * @brief Return efuse coding scheme for blocks. * - * Note: The coding scheme is applicable only to 1, 2 and 3 blocks. For 0 block, the coding scheme is always ``NONE``. + * @note The coding scheme is applicable only to 1, 2 and 3 blocks. For 0 block, the coding scheme is always ``NONE``. * * @param[in] blk Block number of eFuse. * @return Return efuse coding scheme for blocks @@ -708,6 +708,12 @@ esp_err_t esp_efuse_set_write_protect_of_digest_revoke(unsigned num_digest); * * The burn of a key, protection bits, and a purpose happens in batch mode. * + * @note This API also enables the read protection efuse bit for certain key blocks like XTS-AES, HMAC, ECDSA etc. + * This ensures that the key is only accessible to hardware peripheral. + * + * @note For SoC's with capability `SOC_EFUSE_ECDSA_USE_HARDWARE_K` (e.g., ESP32-H2), this API writes an additional + * efuse bit for ECDSA key purpose to enforce hardware TRNG generated k mode in the peripheral. + * * @param[in] block Block to read purpose for. Must be in range EFUSE_BLK_KEY0 to EFUSE_BLK_KEY_MAX. Key block must be unused (esp_efuse_key_block_unused). * @param[in] purpose Purpose to set for this key. Purpose must be already unset. * @param[in] key Pointer to data to write. @@ -727,6 +733,12 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo * * The burn of keys, protection bits, and purposes happens in batch mode. * + * @note This API also enables the read protection efuse bit for certain key blocks like XTS-AES, HMAC, ECDSA etc. + * This ensures that the key is only accessible to hardware peripheral. + * + * @note For SoC's with capability `SOC_EFUSE_ECDSA_USE_HARDWARE_K` (e.g., ESP32-H2), this API writes an additional + * efuse bit for ECDSA key purpose to enforce hardware TRNG generated k mode in the peripheral. + * * @param[in] purposes Array of purposes (purpose[number_of_keys]). * @param[in] keys Array of keys (uint8_t keys[number_of_keys][32]). Each key is 32 bytes long. * @param[in] number_of_keys The number of keys to write (up to 6 keys). diff --git a/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c b/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c index da1afb7a6c..f41b092c45 100644 --- a/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c +++ b/components/efuse/src/efuse_controller/keys/with_key_purposes/esp_efuse_api_key.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -312,6 +312,12 @@ esp_err_t esp_efuse_write_key(esp_efuse_block_t block, esp_efuse_purpose_t purpo purpose == ESP_EFUSE_KEY_PURPOSE_HMAC_UP) { ESP_EFUSE_CHK(esp_efuse_set_key_dis_read(block)); } +#if SOC_EFUSE_ECDSA_USE_HARDWARE_K + if (purpose == ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY) { + // Permanently enable the hardware TRNG supplied k mode (most secure mode) + ESP_EFUSE_CHK(esp_efuse_write_field_bit(ESP_EFUSE_ECDSA_FORCE_USE_HARDWARE_K)); + } +#endif ESP_EFUSE_CHK(esp_efuse_set_key_purpose(block, purpose)); ESP_EFUSE_CHK(esp_efuse_set_keypurpose_dis_write(block)); return esp_efuse_batch_write_commit(); diff --git a/components/esp_adc/.build-test-rules.yml b/components/esp_adc/.build-test-rules.yml index 389eceee9d..2a7e4f4184 100644 --- a/components/esp_adc/.build-test-rules.yml +++ b/components/esp_adc/.build-test-rules.yml @@ -3,3 +3,4 @@ components/esp_adc/test_apps/adc: disable: - if: SOC_ADC_SUPPORTED != 1 + - if: CONFIG_NAME == "gdma_iram_safe" and IDF_TARGET in ["esp32", "esp32s2", "esp32c2"] diff --git a/components/esp_adc/adc_common.c b/components/esp_adc/adc_common.c index 1165bd3fc2..4d1479ed52 100644 --- a/components/esp_adc/adc_common.c +++ b/components/esp_adc/adc_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,42 +19,6 @@ static const char *TAG = "adc_common"; -static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED; -extern portMUX_TYPE rtc_spinlock; - -/*------------------------------------------------------------------------------ -* For those who use APB_SARADC periph -*----------------------------------------------------------------------------*/ -static int s_adc_digi_ctrlr_cnt; - -void adc_apb_periph_claim(void) -{ - portENTER_CRITICAL(&s_spinlock); - s_adc_digi_ctrlr_cnt++; - if (s_adc_digi_ctrlr_cnt == 1) { - //enable ADC digital part - periph_module_enable(PERIPH_SARADC_MODULE); - //reset ADC digital part - periph_module_reset(PERIPH_SARADC_MODULE); - } - - portEXIT_CRITICAL(&s_spinlock); -} - -void adc_apb_periph_free(void) -{ - portENTER_CRITICAL(&s_spinlock); - s_adc_digi_ctrlr_cnt--; - if (s_adc_digi_ctrlr_cnt == 0) { - periph_module_disable(PERIPH_SARADC_MODULE); - } else if (s_adc_digi_ctrlr_cnt < 0) { - portEXIT_CRITICAL(&s_spinlock); - ESP_LOGE(TAG, "%s called, but `s_adc_digi_ctrlr_cnt == 0`", __func__); - abort(); - } - - portEXIT_CRITICAL(&s_spinlock); -} /*--------------------------------------------------------------- ADC IOs diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 0638cd53ee..d6a85d246a 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2016-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,7 +67,7 @@ static void adc_dma_intr_handler(void *arg); static int8_t adc_digi_get_io_num(adc_unit_t adc_unit, uint8_t adc_channel) { - assert(adc_unit <= SOC_ADC_PERIPH_NUM); + assert(adc_unit < SOC_ADC_PERIPH_NUM); uint8_t adc_n = (adc_unit == ADC_UNIT_1) ? 0 : 1; return adc_channel_io_map[adc_n][adc_channel]; } @@ -236,10 +236,7 @@ esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_confi adc_ctx->fsm = ADC_FSM_INIT; *ret_handle = adc_ctx; - //enable ADC digital part - periph_module_enable(PERIPH_SARADC_MODULE); - //reset ADC digital part - periph_module_reset(PERIPH_SARADC_MODULE); + adc_apb_periph_claim(); #if SOC_ADC_CALIBRATION_V1_SUPPORTED adc_hal_calibration_init(ADC_UNIT_1); @@ -331,6 +328,9 @@ esp_err_t adc_continuous_start(adc_continuous_handle_t handle) ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_STATE, ADC_TAG, "The driver isn't initialised"); ESP_RETURN_ON_FALSE(handle->fsm == ADC_FSM_INIT, ESP_ERR_INVALID_STATE, ADC_TAG, "ADC continuous mode isn't in the init state, it's started already"); + //reset ADC digital part to reset ADC sampling EOF counter + periph_module_reset(PERIPH_SARADC_MODULE); + if (handle->pm_lock) { ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(handle->pm_lock), ADC_TAG, "acquire pm_lock failed"); } @@ -390,6 +390,11 @@ esp_err_t adc_continuous_stop(adc_continuous_handle_t handle) //stop ADC adc_hal_digi_stop(&handle->hal); +#if ADC_LL_WORKAROUND_CLEAR_EOF_COUNTER + periph_module_reset(PERIPH_SARADC_MODULE); + adc_hal_digi_clr_eof(); +#endif + adc_hal_digi_deinit(&handle->hal); if (handle->use_adc2) { @@ -472,7 +477,7 @@ esp_err_t adc_continuous_deinit(adc_continuous_handle_t handle) free(handle); handle = NULL; - periph_module_disable(PERIPH_SARADC_MODULE); + adc_apb_periph_free(); return ESP_OK; } diff --git a/components/esp_adc/adc_filter.c b/components/esp_adc/adc_filter.c index ea397dee1f..fdb413b877 100644 --- a/components/esp_adc/adc_filter.c +++ b/components/esp_adc/adc_filter.c @@ -21,8 +21,8 @@ static portMUX_TYPE s_filter_spinlock = portMUX_INITIALIZER_UNLOCKED; #if SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED -static atomic_bool s_adc_filter_claimed[SOC_ADC_PERIPH_NUM] = {ATOMIC_VAR_INIT(false), -#if (SOC_ADC_PERIPH_NUM >= 2) +static atomic_bool s_adc_filter_claimed[SOC_ADC_DIGI_IIR_FILTER_NUM] = {ATOMIC_VAR_INIT(false), +#if (SOC_ADC_DIGI_IIR_FILTER_NUM >= 2) ATOMIC_VAR_INIT(false) #endif }; @@ -59,16 +59,18 @@ static esp_err_t s_adc_filter_claim(adc_continuous_handle_t handle, adc_iir_filt { (void)unit; assert(handle && filter_ctx); + + portENTER_CRITICAL(&s_filter_spinlock); for (int i = 0; i < SOC_ADC_DIGI_IIR_FILTER_NUM; i++) { - portENTER_CRITICAL(&s_filter_spinlock); bool found = !handle->iir_filter[i]; - handle->iir_filter[i] = filter_ctx; - filter_ctx->filter_id = i; - portEXIT_CRITICAL(&s_filter_spinlock); if (found) { + handle->iir_filter[i] = filter_ctx; + filter_ctx->filter_id = i; + portEXIT_CRITICAL(&s_filter_spinlock); return ESP_OK; } } + portEXIT_CRITICAL(&s_filter_spinlock); return ESP_ERR_NOT_FOUND; } 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 58cd8476cb..d4120d2471 100644 --- a/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.c +++ b/components/esp_adc/deprecated/esp32/esp_adc_cal_legacy.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 */ @@ -312,7 +312,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 { @@ -332,8 +332,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 dd007d10a6..b8729678e4 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 0421b27fd4..88f845bc76 100644 --- a/components/esp_adc/esp32/adc_cali_line_fitting.c +++ b/components/esp_adc/esp32/adc_cali_line_fitting.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 */ @@ -192,7 +192,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 { @@ -253,8 +253,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 6eae21f7a5..a462582374 100644 --- a/components/esp_adc/esp32c2/adc_cali_line_fitting.c +++ b/components/esp_adc/esp32c2/adc_cali_line_fitting.c @@ -122,7 +122,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/esp32h2/curve_fitting_coefficients.c b/components/esp_adc/esp32h2/curve_fitting_coefficients.c new file mode 100644 index 0000000000..34932b1c47 --- /dev/null +++ b/components/esp_adc/esp32h2/curve_fitting_coefficients.c @@ -0,0 +1,59 @@ +/* + * 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 + +/** + * @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}, {0, 0}, {0, 0}}, //atten0 + {{8359230818901277, 1e16}, {9025419089179, 1e19}, {0, 1}, {0, 0}, {0, 0}}, //atten1 + {{1165668771581976, 1e15}, {8294679249061, 1e19}, {0, 1}, {0, 0}, {0, 0}}, //atten2 + {{3637329628677273, 1e16}, {19607259738935, 1e18}, {7871689227, 1e16}, {0, 0}, {0, 0}}, //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, 0, 0}, //atten0 + {-1, 1, 1, 0, 0}, //atten1 + {-1, 1, 1, 0, 0}, //atten2 + {-1, -1, 1, 0, 0}, //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)]; + ctx->sign = &adc1_error_sign[VER2IDX(adc_calib_ver)]; +} diff --git a/components/esp_adc/esp32h2/include/adc_cali_schemes.h b/components/esp_adc/esp32h2/include/adc_cali_schemes.h index 16dc6be4f1..96067994e0 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/esp32s2/adc_cali_line_fitting.c b/components/esp_adc/esp32s2/adc_cali_line_fitting.c index 9826b73860..f44b2314a6 100644 --- a/components/esp_adc/esp32s2/adc_cali_line_fitting.c +++ b/components/esp_adc/esp32s2/adc_cali_line_fitting.c @@ -184,7 +184,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/include/esp_private/adc_private.h b/components/esp_adc/include/esp_private/adc_private.h index 03aa22298c..6ebe244bb6 100644 --- a/components/esp_adc/include/esp_private/adc_private.h +++ b/components/esp_adc/include/esp_private/adc_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,23 +16,6 @@ extern "C" { #endif -/*------------------------------------------------------------------------------ -* For those who use APB_SARADC periph -*----------------------------------------------------------------------------*/ -/** - * @brief Claim the usage of the APB_SARADC periph - * - * Reference count inside - */ -void adc_apb_periph_claim(void); - -/** - * @brief Free the usage of the APB_SARADC periph - * - * Reference count inside - */ -void adc_apb_periph_free(void); - /*--------------------------------------------------------------- ADC IOs diff --git a/components/esp_adc/linker.lf b/components/esp_adc/linker.lf index b2e1851e28..755c83f1d6 100644 --- a/components/esp_adc/linker.lf +++ b/components/esp_adc/linker.lf @@ -3,3 +3,23 @@ archive: libesp_adc.a entries: if ADC_ONESHOT_CTRL_FUNC_IN_IRAM = y: adc_oneshot: adc_oneshot_read_isr (noflash) + +[mapping:adc_hal] +archive: libhal.a +entries: + if ADC_ONESHOT_CTRL_FUNC_IN_IRAM = y: + adc_oneshot_hal (noflash) + if COMPILER_OPTIMIZATION_DEBUG = y: + adc_hal_common: get_controller (noflash) + adc_hal_common: adc_hal_set_controller (noflash) + if SOC_ADC_ARBITER_SUPPORTED = y: + adc_hal_common: adc_hal_arbiter_config (noflash) + if SOC_ADC_CALIBRATION_V1_SUPPORTED = y: + adc_hal_common: adc_hal_set_calibration_param (noflash) + adc_hal_common: adc_hal_calibration_init (noflash) + if ADC_CONTINUOUS_ISR_IRAM_SAFE = y || GDMA_ISR_IRAM_SAFE = y: + adc_hal: adc_hal_get_reading_result (noflash) + if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y: + adc_hal: adc_hal_check_event (noflash) + adc_hal: adc_hal_digi_clr_intr (noflash) + adc_hal: adc_hal_get_desc_addr (noflash) diff --git a/components/esp_adc/test_apps/adc/main/CMakeLists.txt b/components/esp_adc/test_apps/adc/main/CMakeLists.txt index b545b3fc48..f72f9580b2 100644 --- a/components/esp_adc/test_apps/adc/main/CMakeLists.txt +++ b/components/esp_adc/test_apps/adc/main/CMakeLists.txt @@ -3,7 +3,8 @@ set(srcs "test_app_main.c" "test_adc_performance.c" "test_adc_driver.c" "test_adc_driver_iram.c" - "test_adc2_wifi.c" + "test_adc_wifi.c" + "test_adc_tsens.c" "test_common_adc.c") # In order for the cases defined by `TEST_CASE` to be linked into the final elf, 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 6e1055acd3..2dfc911352 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc.c +++ b/components/esp_adc/test_apps/adc/main/test_adc.c @@ -12,6 +12,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"; @@ -63,7 +64,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)); @@ -117,7 +118,43 @@ 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_12; + 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 /*--------------------------------------------------------------- @@ -249,14 +286,14 @@ static void s_adc_oneshot_with_sleep(adc_unit_t unit_id, adc_channel_t channel) #define ADC2_SLEEP_TEST_CHAN ADC_CHANNEL_0 #endif -TEST_CASE("test ADC1 Single Read with Light Sleep", "[adc][manul][ignore]") +TEST_CASE("test ADC1 Single Read with Light Sleep", "[adc]") { s_adc_oneshot_with_sleep(ADC_UNIT_1, ADC1_SLEEP_TEST_CHAN); } #if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3 //ESP32C3 ADC2 oneshot mode is not supported anymore -TEST_CASE("test ADC2 Single Read with Light Sleep", "[adc][manul][ignore]") +TEST_CASE("test ADC2 Single Read with Light Sleep", "[adc]") { s_adc_oneshot_with_sleep(ADC_UNIT_2, ADC2_SLEEP_TEST_CHAN); } 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 590ffa50d5..308e5ab3f9 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,8 @@ #include "esp_rom_sys.h" #include "esp_adc/adc_oneshot.h" #include "test_common_adc.h" +#include "esp_adc/adc_continuous.h" +#include "esp_adc/adc_filter.h" const __attribute__((unused)) static char *TAG = "TEST_ADC"; @@ -79,7 +81,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.adc_handle, ADC1_TEST_CHAN0, &config)); @@ -127,3 +129,99 @@ TEST_CASE("ADC oneshot fast work with ISR", "[adc_oneshot]") TEST_ESP_OK(gptimer_del_timer(timer)); TEST_ESP_OK(adc_oneshot_del_unit(isr_test_ctx.adc_handle)); } + +#if SOC_ADC_DMA_SUPPORTED + +#if (SOC_ADC_DIGI_RESULT_BYTES == 2) +#define ADC_DRIVER_TEST_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE1 +#define ADC_DRIVER_TEST_GET_CHANNEL(p_data) ((p_data)->type1.channel) +#define ADC_DRIVER_TEST_GET_DATA(p_data) ((p_data)->type1.data) +#else +#define ADC_DRIVER_TEST_OUTPUT_TYPE ADC_DIGI_OUTPUT_FORMAT_TYPE2 +#define ADC_DRIVER_TEST_GET_CHANNEL(p_data) ((p_data)->type2.channel) +#define ADC_DRIVER_TEST_GET_DATA(p_data) ((p_data)->type2.data) +#endif + +#define ADC_RESTART_TEST_SIZE 4096 +#define ADC_READ_TEST_COUNT 10 + +TEST_CASE("ADC continuous test after restarting", "[adc_continuous]") +{ + adc_continuous_handle_t handle = NULL; + adc_continuous_handle_cfg_t adc_config = { + .max_store_buf_size = ADC_RESTART_TEST_SIZE, + .conv_frame_size = ADC_RESTART_TEST_SIZE, + }; + TEST_ESP_OK(adc_continuous_new_handle(&adc_config, &handle)); + + adc_continuous_config_t dig_cfg = { + .sample_freq_hz = 50 * 1000, + .conv_mode = ADC_CONV_SINGLE_UNIT_1, + .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_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; + dig_cfg.adc_pattern = adc_pattern; + dig_cfg.pattern_num = 1; + TEST_ESP_OK(adc_continuous_config(handle, &dig_cfg)); + + uint8_t* result = malloc(ADC_RESTART_TEST_SIZE); + TEST_ASSERT(result); + + test_adc_set_io_level(ADC_UNIT_1, ADC1_TEST_CHAN0, 0); + + for (int i = 0; i < ADC_READ_TEST_COUNT; i++) { + uint32_t ret_num = 0; + TEST_ESP_OK(adc_continuous_start(handle)); + TEST_ESP_OK(adc_continuous_read(handle, result, ADC_RESTART_TEST_SIZE, &ret_num, ADC_MAX_DELAY)); + TEST_ASSERT_EQUAL(ADC_RESTART_TEST_SIZE, ret_num); + for (int i = 0; i < ret_num; i += SOC_ADC_DIGI_RESULT_BYTES) { + adc_digi_output_data_t *p = (void*)&result[i]; + uint32_t chan_num = ADC_DRIVER_TEST_GET_CHANNEL(p); + TEST_ASSERT(chan_num < SOC_ADC_CHANNEL_NUM(ADC_UNIT_1)); + } + TEST_ESP_OK(adc_continuous_stop(handle)); + } + + TEST_ESP_OK(adc_continuous_deinit(handle)); + free(result); +} + +#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED +TEST_CASE("ADC filter exhausted allocation", "[adc_oneshot]") +{ + adc_continuous_handle_t handle = NULL; + adc_continuous_handle_cfg_t adc_config = { + .max_store_buf_size = 1024, + .conv_frame_size = 1024, + }; + TEST_ESP_OK(adc_continuous_new_handle(&adc_config, &handle)); + + adc_iir_filter_handle_t filter_hdl[SOC_ADC_DIGI_IIR_FILTER_NUM + 1] = {}; + adc_continuous_iir_filter_config_t filter_config = { + .unit = ADC_UNIT_1, + .channel = ADC_CHANNEL_0, + .coeff = ADC_DIGI_IIR_FILTER_COEFF_2, + }; + for (int i = 0; i < SOC_ADC_DIGI_IIR_FILTER_NUM; i++) { +#if SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED + //On these chips, the unit and the filter_id should be the same + filter_config.unit = i; +#endif + TEST_ESP_OK(adc_new_continuous_iir_filter(handle, &filter_config, &filter_hdl[i])); + } + + filter_config.unit = ADC_UNIT_1; + TEST_ASSERT(adc_new_continuous_iir_filter(handle, &filter_config, &filter_hdl[SOC_ADC_DIGI_IIR_FILTER_NUM]) == ESP_ERR_NOT_FOUND); + + for (int i = 0; i < SOC_ADC_DIGI_IIR_FILTER_NUM; i++) { + TEST_ESP_OK(adc_del_continuous_iir_filter(filter_hdl[i])); + } + + TEST_ESP_OK(adc_continuous_deinit(handle)); +} +#endif //#if SOC_ADC_DIG_IIR_FILTER_SUPPORTED +#endif //#if SOC_ADC_DMA_SUPPORTED 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 a258a5b743..a74dfd1648 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 @@ -85,7 +85,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)); @@ -144,7 +144,7 @@ TEST_CASE("ADC oneshot fast work with ISR and Flash", "[adc_oneshot]") #endif //#if CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM && CONFIG_GPTIMER_ISR_IRAM_SAFE -#if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE +#if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE || CONFIG_GDMA_ISR_IRAM_SAFE #include "esp_adc/adc_continuous.h" /*--------------------------------------------------------------- ADC continuous work with cache safe ISR @@ -252,7 +252,7 @@ TEST_CASE("ADC continuous work with ISR and Flash", "[adc_oneshot]") TEST_ESP_OK(adc_continuous_deinit(handle)); } -#endif //#if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE +#endif //#if CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE || CONFIG_GDMA_ISR_IRAM_SAFE static void IRAM_ATTR NOINLINE_ATTR s_test_cache_disable_period_us(test_adc_iram_ctx_t *ctx, uint32_t period_us) { 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 db9b7294c8..7ee8c1afa5 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 @@ -270,29 +270,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 @@ -376,7 +376,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_tsens.c b/components/esp_adc/test_apps/adc/main/test_adc_tsens.c new file mode 100644 index 0000000000..159fa1b7ef --- /dev/null +++ b/components/esp_adc/test_apps/adc/main/test_adc_tsens.c @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "esp_log.h" +#include "soc/adc_periph.h" +#include "esp_adc/adc_oneshot.h" +#include "driver/gpio.h" +#include "driver/rtc_io.h" +#include "driver/temperature_sensor.h" +#include "nvs_flash.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "test_common_adc.h" +#include "test_utils.h" + +#if SOC_TEMP_SENSOR_SUPPORTED && SOC_ADC_SUPPORTED + +static const char *TAG = "adc_tsens"; + +#define EXAMPLE_ADC1_CHAN0 ADC_CHANNEL_2 +#define EXAMPLE_ADC1_CHAN1 ADC_CHANNEL_4 +#define EXAMPLE_ADC_ATTEN ADC_ATTEN_DB_12 + +static int adc_raw[2][10]; + +TEST_CASE("Test temperature sensor cannot be influenced by ADC", "[adc]") +{ + ESP_LOGI(TAG, "Install temperature sensor, expected temp ranger range: 10~50 ℃"); + temperature_sensor_handle_t temp_sensor = NULL; + temperature_sensor_config_t temp_sensor_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(-10, 80); + TEST_ESP_OK(temperature_sensor_install(&temp_sensor_config, &temp_sensor)); + int cnt = 2; + float tsens_value; + while (cnt--) { + temperature_sensor_enable(temp_sensor); + TEST_ESP_OK(temperature_sensor_get_celsius(temp_sensor, &tsens_value)); + ESP_LOGI(TAG, "Temperature value %.02f ℃", tsens_value); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ESP_OK(temperature_sensor_disable(temp_sensor)); + } + + adc_oneshot_unit_handle_t adc1_handle; + adc_oneshot_unit_init_cfg_t init_config1 = { + .unit_id = ADC_UNIT_1, + }; + TEST_ESP_OK(adc_oneshot_new_unit(&init_config1, &adc1_handle)); + + //-------------ADC1 Config---------------// + adc_oneshot_chan_cfg_t config = { + .bitwidth = ADC_BITWIDTH_DEFAULT, + .atten = EXAMPLE_ADC_ATTEN, + }; + TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN0, &config)); + TEST_ESP_OK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN1, &config)); + + cnt = 2; + while (cnt--) { + TEST_ESP_OK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0][0])); + ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, adc_raw[0][0]); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + TEST_ESP_OK(adc_oneshot_del_unit(adc1_handle)); + + cnt = 2; + while (cnt--) { + temperature_sensor_enable(temp_sensor); + TEST_ESP_OK(temperature_sensor_get_celsius(temp_sensor, &tsens_value)); + ESP_LOGI(TAG, "Temperature value %.02f ℃", tsens_value); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ESP_OK(temperature_sensor_disable(temp_sensor)); + } + + TEST_ESP_OK(temperature_sensor_uninstall(temp_sensor)); +} + +#endif diff --git a/components/esp_adc/test_apps/adc/main/test_adc2_wifi.c b/components/esp_adc/test_apps/adc/main/test_adc_wifi.c similarity index 54% rename from components/esp_adc/test_apps/adc/main/test_adc2_wifi.c rename to components/esp_adc/test_apps/adc/main/test_adc_wifi.c index 8a25812526..80b937646b 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc2_wifi.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_wifi.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 */ @@ -18,32 +18,32 @@ #include "test_common_adc.h" #include "test_utils.h" -/** - * On ESP32C3, ADC2 is no longer supported, due to its HW limitation. - */ -#if (SOC_ADC_PERIPH_NUM > 1) && !CONFIG_IDF_TARGET_ESP32C3 +#if SOC_WIFI_SUPPORTED && SOC_ADC_SUPPORTED -static const char* TAG = "test_adc2"; +static const char* TAG = "test_adc_wifi"; #define DEFAULT_SSID "TEST_SSID" #define DEFAULT_PWD "TEST_PASS" +//ADC Channels #if CONFIG_IDF_TARGET_ESP32 -#define TEST_ADC2_CHAN0 ADC_CHANNEL_9 -#elif CONFIG_IDF_TARGET_ESP32S2 -#define TEST_ADC2_CHAN0 ADC_CHANNEL_0 -#elif CONFIG_IDF_TARGET_ESP32C3 -#define TEST_ADC2_CHAN0 ADC_CHANNEL_0 -#elif CONFIG_IDF_TARGET_ESP32S3 -#define TEST_ADC2_CHAN0 ADC_CHANNEL_0 +#define ADC1_WIFI_TEST_CHAN0 ADC_CHANNEL_4 +#define ADC2_WIFI_TEST_CHAN0 ADC_CHANNEL_9 +#else +#define ADC1_WIFI_TEST_CHAN0 ADC_CHANNEL_0 +#define ADC2_WIFI_TEST_CHAN0 ADC_CHANNEL_0 #endif -#define ADC_ERROR_THRES 100 +#define ADC_ERROR_THRES 200 #define TEST_NUM 8 #define MINUS_UNTIL_ZERO(a, b) ( ((a) > (b)) ? ((a)-(b)): 0) #define TIME_REMAIN(start, now, timeout) ((now) >= (start) ? MINUS_UNTIL_ZERO((timeout), (now)-(start)) : -1) +static int read_raw; +static int target_value; +static int test_adc_io; +static bool test_list[TEST_NUM] = {1, 1, 0, 0, 1, 0, 1, 0}; static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) @@ -98,7 +98,30 @@ static int event_deinit(void) return ESP_OK; } -TEST_CASE("adc2 work with wifi","[adc]") +static void s_test_adc_work_when_wifi_on(adc_oneshot_unit_handle_t adc_handle, adc_channel_t channel) +{ + esp_err_t ret = ESP_FAIL; + int32_t start = xTaskGetTickCount(); + int32_t now; + int32_t remain_wait_ms = 0; + int32_t timeout = pdMS_TO_TICKS(10); + do { + now = xTaskGetTickCount(); + remain_wait_ms = pdTICKS_TO_MS(TIME_REMAIN(start, now, timeout)); + ret = adc_oneshot_read(adc_handle, channel, &read_raw); + if (ret == ESP_OK) { + printf("When WiFi is ON, ADC read: %d (target_value: %d)\n", read_raw, target_value); + TEST_ASSERT_INT_WITHIN(ADC_ERROR_THRES, target_value, read_raw); + break; + } else if (ret == ESP_ERR_TIMEOUT) { + continue; + } else { + TEST_ESP_OK(ret); + } + } while (remain_wait_ms); +} + +__attribute__((unused)) static void adc_work_with_wifi(adc_unit_t unit_id, adc_channel_t channel) { test_case_uses_tcpip(); @@ -132,82 +155,83 @@ TEST_CASE("adc2 work with wifi","[adc]") TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); //---------------------------------ADC init-----------------------------------// - int read_raw; - int target_value; - int test_adc_io; - bool test_list[TEST_NUM] = {1, 1, 0, 0, 1, 0, 1, 0}; - TEST_ESP_OK(adc_oneshot_channel_to_io(ADC_UNIT_2, TEST_ADC2_CHAN0, &test_adc_io)); + TEST_ESP_OK(adc_oneshot_channel_to_io(unit_id, channel, &test_adc_io)); printf("test_adc_io is %d\n", test_adc_io); - //-------------ADC2 Init---------------// - adc_oneshot_unit_handle_t adc2_handle; - adc_oneshot_unit_init_cfg_t init_config2 = { - .unit_id = ADC_UNIT_2, + //-------------ADC Init---------------// + adc_oneshot_unit_handle_t adc_handle; + adc_oneshot_unit_init_cfg_t init_config = { + .unit_id = unit_id, .ulp_mode = ADC_ULP_MODE_DISABLE, }; - TEST_ESP_OK(adc_oneshot_new_unit(&init_config2, &adc2_handle)); + TEST_ESP_OK(adc_oneshot_new_unit(&init_config, &adc_handle)); - //-------------ADC2 TEST Channel 0 Config---------------// + //-------------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(adc2_handle, TEST_ADC2_CHAN0, &config)); + TEST_ESP_OK(adc_oneshot_config_channel(adc_handle, channel, &config)); for (int i = 0; i < TEST_NUM; i++) { /* Tune test ADC channel level */ - test_adc_set_io_level(ADC_UNIT_2, TEST_ADC2_CHAN0, test_list[i]); + test_adc_set_io_level(unit_id, channel, test_list[i]); target_value = test_list[i] ? ADC_TEST_HIGH_VAL : ADC_TEST_LOW_VAL; - /* ADC2 single read before WIFI start */ - TEST_ESP_OK(adc_oneshot_read(adc2_handle, TEST_ADC2_CHAN0, &read_raw)); + /* ADC single read before WIFI start */ + TEST_ESP_OK(adc_oneshot_read(adc_handle, channel, &read_raw)); printf("Before WiFi starts, ADC read: %d (target_value: %d)\n", read_raw, target_value); TEST_ASSERT_INT_WITHIN(ADC_ERROR_THRES, target_value, read_raw); - /* ADC2 single read when WIFI is on */ + /* ADC single read when WIFI is on */ TEST_ESP_OK(esp_wifi_start()); #if CONFIG_IDF_TARGET_ESP32 - TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, adc_oneshot_read(adc2_handle, TEST_ADC2_CHAN0, &read_raw)); + if (unit_id == 1) { + // On ESP32 ADC2, PWDET/PKDET controller is for Wi-Fi internal use only. + // If Wi-Fi module is using the SAR ADC2, users can not measure the analog signal from the pins using SAR ADC2. + // After SAR ADC2 is released by Wi-Fi, users can use SAR ADC2 normally. + TEST_ASSERT_EQUAL(ESP_ERR_TIMEOUT, adc_oneshot_read(adc_handle, channel, &read_raw)); + } else { + s_test_adc_work_when_wifi_on(adc_handle, channel); + } #else - esp_err_t ret = ESP_FAIL; - int32_t start = xTaskGetTickCount(); - int32_t now; - int32_t remain_wait_ms = 0; - int32_t timeout = pdMS_TO_TICKS(10); - - do { - now = xTaskGetTickCount(); - remain_wait_ms = pdTICKS_TO_MS(TIME_REMAIN(start, now, timeout)); - ret = adc_oneshot_read(adc2_handle, TEST_ADC2_CHAN0, &read_raw); - if (ret == ESP_OK) { - printf("When WiFi is ON, ADC read: %d (target_value: %d)\n", read_raw, target_value); - TEST_ASSERT_INT_WITHIN(ADC_ERROR_THRES, target_value, read_raw); - break; - } else if (ret == ESP_ERR_TIMEOUT) { - continue; - } else { - TEST_ESP_OK(ret); - } - } while (remain_wait_ms); + s_test_adc_work_when_wifi_on(adc_handle, channel); #endif - - - /* ADC2 single read after WIFI is off */ + /* ADC single read after WIFI is off */ TEST_ESP_OK(esp_wifi_stop()); - TEST_ESP_OK(adc_oneshot_read(adc2_handle, TEST_ADC2_CHAN0, &read_raw)); + TEST_ESP_OK(adc_oneshot_read(adc_handle, channel, &read_raw)); printf("After WiFi is OFF, ADC read: %d (target_value: %d)\n\n", read_raw, target_value); TEST_ASSERT_INT_WITHIN(ADC_ERROR_THRES, target_value, read_raw); } + TEST_ESP_OK(adc_oneshot_del_unit(adc_handle)); + ESP_LOGI(TAG, "ADC%d with WiFi test is success", unit_id + 1); + TEST_ESP_OK(esp_wifi_deinit()); event_deinit(); nvs_flash_deinit(); - TEST_ESP_OK(adc_oneshot_del_unit(adc2_handle)); TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of esp_netif and event_loop."); } -#endif //#if (SOC_ADC_PERIPH_NUM > 1) +#if CONFIG_IDF_TARGET_ESP32C6 +// On ESP32C6, ADC need to call two modem clocks: modem_syscon_ll_enable_fe_80m_clock and modem_syscon_ll_enable_fe_apb_clock. +// Without calling these two clocks, PWDET mode will not take into effect, so ADC readings will be wrong. +TEST_CASE("ADC1 work with WiFi","[adc]") +{ + adc_work_with_wifi(ADC_UNIT_1, ADC1_WIFI_TEST_CHAN0); +} +#endif // CONFIG_IDF_TARGET_ESP32C6 + +#if (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3 +// On ESP32C3, ADC2 is no longer supported, due to its HW limitation. +TEST_CASE("ADC2 work with WiFi","[adc]") +{ + adc_work_with_wifi(ADC_UNIT_2, ADC2_WIFI_TEST_CHAN0); +} +#endif // (SOC_ADC_PERIPH_NUM >= 2) && !CONFIG_IDF_TARGET_ESP32C3 + +#endif //SOC_WIFI_SUPPORTED && SOC_ADC_SUPPORTED 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 9bb4a3b79f..2a32ea4540 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_adc/test_apps/adc/main/test_common_adc.h b/components/esp_adc/test_apps/adc/main/test_common_adc.h index f77200add2..78186d08d9 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/esp_adc/test_apps/adc/pytest_adc.py b/components/esp_adc/test_apps/adc/pytest_adc.py index 17cd79c432..fa7c737a4d 100644 --- a/components/esp_adc/test_apps/adc/pytest_adc.py +++ b/components/esp_adc/test_apps/adc/pytest_adc.py @@ -35,3 +35,15 @@ def test_adc(dut: Dut) -> None: ) def test_adc_esp32c2_xtal_26mhz(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) + + +@pytest.mark.esp32s3 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.adc +@pytest.mark.parametrize('config', [ + 'gdma_iram_safe', +], indirect=True) +def test_adc_gdma_iram(dut: Dut) -> None: + dut.run_all_single_board_cases(timeout=120) diff --git a/components/esp_adc/test_apps/adc/sdkconfig.ci.gdma_iram_safe b/components/esp_adc/test_apps/adc/sdkconfig.ci.gdma_iram_safe new file mode 100644 index 0000000000..67db32cae0 --- /dev/null +++ b/components/esp_adc/test_apps/adc/sdkconfig.ci.gdma_iram_safe @@ -0,0 +1,7 @@ +CONFIG_COMPILER_DUMP_RTL_FILES=y +CONFIG_GDMA_ISR_IRAM_SAFE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=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 +CONFIG_HAL_ASSERTION_SILENT=y diff --git a/components/esp_app_format/include/esp_app_desc.h b/components/esp_app_format/include/esp_app_desc.h index fd7582be79..0a64c5c530 100644 --- a/components/esp_app_format/include/esp_app_desc.h +++ b/components/esp_app_format/include/esp_app_desc.h @@ -37,6 +37,7 @@ typedef struct { /** @cond */ ESP_STATIC_ASSERT(sizeof(esp_app_desc_t) == 256, "esp_app_desc_t should be 256 bytes"); +ESP_STATIC_ASSERT(offsetof(esp_app_desc_t, secure_version) == 4, "secure_version field must be at 4 offset"); /** @endcond */ /** diff --git a/components/esp_coex/CMakeLists.txt b/components/esp_coex/CMakeLists.txt index 55c482ced6..8918bdd600 100644 --- a/components/esp_coex/CMakeLists.txt +++ b/components/esp_coex/CMakeLists.txt @@ -32,6 +32,9 @@ if(CONFIG_ESP_COEX_SW_COEXIST_ENABLE OR CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE) add_prebuilt_library(${blob} "${CMAKE_CURRENT_SOURCE_DIR}/lib/${target_name}/lib${blob}.a" REQUIRES ${COMPONENT_NAME}) target_link_libraries(${COMPONENT_LIB} PUBLIC ${blob}) + if(CONFIG_IDF_TARGET_ESP32) + target_link_libraries(${COMPONENT_LIB} PRIVATE btdm_app) + endif() endif() target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/esp_coex/Kconfig b/components/esp_coex/Kconfig index e526c2705c..d5de082a3c 100644 --- a/components/esp_coex/Kconfig +++ b/components/esp_coex/Kconfig @@ -26,4 +26,11 @@ menu "Wireless Coexistence" This function depends on BT-off because currently we do not support external coex and internal coex simultaneously. -endmenu # Wi-Fi + config ESP_COEX_POWER_MANAGEMENT + bool "Support power management under coexistence" + default n + depends on (ESP_COEX_SW_COEXIST_ENABLE) + help + If enabled, coexist power management will be enabled. + +endmenu # Wireless Coexistence diff --git a/components/esp_coex/esp32/esp_coex_adapter.c b/components/esp_coex/esp32/esp_coex_adapter.c index a120e11d53..d3b297036d 100644 --- a/components/esp_coex/esp32/esp_coex_adapter.c +++ b/components/esp_coex/esp32/esp_coex_adapter.c @@ -18,7 +18,7 @@ #include "freertos/portmacro.h" #include "esp_heap_caps.h" #include "esp_timer.h" -#include "esp_coexist_adapter.h" +#include "private/esp_coexist_adapter.h" #include "esp32/rom/ets_sys.h" #define TAG "esp_coex_adapter" diff --git a/components/esp_coex/esp32c2/esp_coex_adapter.c b/components/esp_coex/esp32c2/esp_coex_adapter.c index 84adc6f088..25805bc7ed 100644 --- a/components/esp_coex/esp32c2/esp_coex_adapter.c +++ b/components/esp_coex/esp32c2/esp_coex_adapter.c @@ -20,7 +20,7 @@ #include "esp_timer.h" #include "soc/rtc.h" #include "esp_private/esp_clk.h" -#include "esp_coexist_adapter.h" +#include "private/esp_coexist_adapter.h" #include "esp32c2/rom/ets_sys.h" #define TAG "esp_coex_adapter" diff --git a/components/esp_coex/esp32c3/esp_coex_adapter.c b/components/esp_coex/esp32c3/esp_coex_adapter.c index 005b858f4b..9dd290e5af 100644 --- a/components/esp_coex/esp32c3/esp_coex_adapter.c +++ b/components/esp_coex/esp32c3/esp_coex_adapter.c @@ -20,7 +20,7 @@ #include "esp_timer.h" #include "soc/rtc.h" #include "esp_private/esp_clk.h" -#include "esp_coexist_adapter.h" +#include "private/esp_coexist_adapter.h" #include "esp32c3/rom/ets_sys.h" #include "soc/system_reg.h" diff --git a/components/esp_coex/esp32c6/esp_coex_adapter.c b/components/esp_coex/esp32c6/esp_coex_adapter.c index e792c0ebad..1fde5726f8 100644 --- a/components/esp_coex/esp32c6/esp_coex_adapter.c +++ b/components/esp_coex/esp32c6/esp_coex_adapter.c @@ -20,7 +20,7 @@ #include "esp_timer.h" #include "soc/rtc.h" #include "esp_private/esp_clk.h" -#include "esp_coexist_adapter.h" +#include "private/esp_coexist_adapter.h" #include "esp32c6/rom/ets_sys.h" #define TAG "esp_coex_adapter" diff --git a/components/esp_coex/esp32h2/esp_coex_adapter.c b/components/esp_coex/esp32h2/esp_coex_adapter.c index 630d4745ad..6cdfdd9bd9 100644 --- a/components/esp_coex/esp32h2/esp_coex_adapter.c +++ b/components/esp_coex/esp32h2/esp_coex_adapter.c @@ -20,7 +20,7 @@ #include "esp_timer.h" #include "soc/rtc.h" #include "esp_private/esp_clk.h" -#include "esp_coexist_adapter.h" +#include "private/esp_coexist_adapter.h" #include "esp32c6/rom/ets_sys.h" #define TAG "esp_coex_adapter" diff --git a/components/esp_coex/esp32s2/esp_coex_adapter.c b/components/esp_coex/esp32s2/esp_coex_adapter.c index 9100bfabe0..c8d50258bf 100644 --- a/components/esp_coex/esp32s2/esp_coex_adapter.c +++ b/components/esp_coex/esp32s2/esp_coex_adapter.c @@ -20,7 +20,7 @@ #include "esp_timer.h" #include "soc/rtc.h" #include "esp_private/esp_clk.h" -#include "esp_coexist_adapter.h" +#include "private/esp_coexist_adapter.h" #include "esp32s2/rom/ets_sys.h" #define TAG "esp_coex_adapter" diff --git a/components/esp_coex/esp32s3/esp_coex_adapter.c b/components/esp_coex/esp32s3/esp_coex_adapter.c index bf277eb789..6aa42b1a98 100644 --- a/components/esp_coex/esp32s3/esp_coex_adapter.c +++ b/components/esp_coex/esp32s3/esp_coex_adapter.c @@ -20,7 +20,7 @@ #include "esp_timer.h" #include "soc/rtc.h" #include "esp_private/esp_clk.h" -#include "esp_coexist_adapter.h" +#include "private/esp_coexist_adapter.h" #include "esp32s3/rom/ets_sys.h" #include "soc/system_reg.h" diff --git a/components/esp_coex/include/esp_coex_i154.h b/components/esp_coex/include/esp_coex_i154.h index 8bd181eeb5..942de35613 100644 --- a/components/esp_coex/include/esp_coex_i154.h +++ b/components/esp_coex/include/esp_coex_i154.h @@ -17,6 +17,7 @@ typedef enum { void esp_coex_ieee802154_txrx_pti_set(ieee802154_coex_event_t event); void esp_coex_ieee802154_ack_pti_set(ieee802154_coex_event_t event); +void esp_coex_ieee802154_coex_break_notify(void); #endif #endif diff --git a/components/esp_coex/include/esp_coexist.h b/components/esp_coex/include/esp_coexist.h index 9fda8c6d2f..63e83dfcd0 100644 --- a/components/esp_coex/include/esp_coexist.h +++ b/components/esp_coex/include/esp_coexist.h @@ -15,6 +15,10 @@ extern "C" { #endif +#define EXTERNAL_COEXIST_WIRE_1 0 +#define EXTERNAL_COEXIST_WIRE_2 1 +#define EXTERNAL_COEXIST_WIRE_3 2 +#define EXTERNAL_COEXIST_WIRE_4 3 /** * @brief coex prefer value */ @@ -26,10 +30,10 @@ typedef enum { } esp_coex_prefer_t; typedef enum { - EXTERN_COEX_WIRE_1 = 0, - EXTERN_COEX_WIRE_2, - EXTERN_COEX_WIRE_3, - EXTERN_COEX_WIRE_4, + EXTERN_COEX_WIRE_1 = EXTERNAL_COEXIST_WIRE_1, + EXTERN_COEX_WIRE_2 = EXTERNAL_COEXIST_WIRE_2, + EXTERN_COEX_WIRE_3 = EXTERNAL_COEXIST_WIRE_3, + EXTERN_COEX_WIRE_4 = EXTERNAL_COEXIST_WIRE_4, EXTERN_COEX_WIRE_NUM, } external_coex_wire_t; @@ -49,19 +53,19 @@ typedef enum { typedef struct { union { uint32_t in_pin0 __attribute__((deprecated("Use 'request' instead"))); - gpio_num_t request; /**< request gpio signal from slave to master */ + gpio_num_t request; /**< request gpio signal from follower to leader */ }; union { uint32_t in_pin1 __attribute__((deprecated("Use 'priority' instead"))); - gpio_num_t priority; /**< request gpio signal priority from slave to master */ + gpio_num_t priority; /**< request gpio signal priority from follower to leader */ }; union { uint32_t out_pin0 __attribute__((deprecated("Use 'grant' instead"))); - gpio_num_t grant; /**< grant gpio signal from master to slave */ + gpio_num_t grant; /**< grant gpio signal from leader to follower */ }; union { uint32_t out_pin1 __attribute__((deprecated("Use 'tx_line' instead"))); - gpio_num_t tx_line; /**< tx_line gpio signal from master to slave, indicates whether the master's WiFi is transmitting or not*/ + gpio_num_t tx_line; /**< tx_line gpio signal from leader to follower, indicates whether the leader's WiFi is transmitting or not*/ }; } esp_external_coex_gpio_set_t; diff --git a/components/esp_coex/include/esp_coexist_adapter.h b/components/esp_coex/include/private/esp_coexist_adapter.h similarity index 91% rename from components/esp_coex/include/esp_coexist_adapter.h rename to components/esp_coex/include/private/esp_coexist_adapter.h index fde83d1111..539fd3ec63 100644 --- a/components/esp_coex/include/esp_coexist_adapter.h +++ b/components/esp_coex/include/private/esp_coexist_adapter.h @@ -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 */ @@ -51,6 +51,12 @@ typedef struct { extern coex_adapter_funcs_t g_coex_adapter_funcs; +typedef struct { + uint8_t major; + uint8_t minor; + uint8_t patch; +} coex_version_t; + #ifdef __cplusplus } #endif diff --git a/components/esp_coex/include/esp_coexist_internal.h b/components/esp_coex/include/private/esp_coexist_internal.h similarity index 89% rename from components/esp_coex/include/esp_coexist_internal.h rename to components/esp_coex/include/private/esp_coexist_internal.h index 5d1fe2c5a5..20cea8a437 100644 --- a/components/esp_coex/include/esp_coexist_internal.h +++ b/components/esp_coex/include/private/esp_coexist_internal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,7 +9,7 @@ #include #include "esp_coexist.h" -#include "esp_coexist_adapter.h" +#include "private/esp_coexist_adapter.h" #ifdef __cplusplus extern "C" { @@ -75,6 +75,14 @@ void coex_disable(void); */ const char *coex_version_get(void); +/** + * @brief Get software coexist version value + * extern function for internal use. + * @param ptr_version : points to version structure + * @return : ESP_OK - success, other - failed + */ +esp_err_t coex_version_get_value(coex_version_t* ptr_version); + /** * @brief Coexist performance preference set from libbt.a * extern function for internal use. @@ -165,7 +173,6 @@ int coex_register_bt_cb(coex_func_cb_t callback); * @brief To acquire the spin-lock used in resetting Bluetooth baseband. * This function is only used to workaround ESP32 hardware issue. * - * @param callback: callback function registered to coexistence module * @return : value of the spinlock to be restored */ uint32_t coex_bb_reset_lock(void); @@ -260,7 +267,7 @@ void * coex_schm_curr_phase_get(void); /** * @brief Set current coexistence scheme phase index. * - * @param interval : Coexistence scheme phase index + * @param idx : Coexistence scheme phase index * @return : 0 - success, other - failed */ int coex_schm_curr_phase_idx_set(int idx); @@ -306,7 +313,7 @@ esp_err_t esp_coex_adapter_register(coex_adapter_funcs_t *funcs); #if CONFIG_EXTERNAL_COEX_ENABLE /** - * @brief Set external coexistence advanced informations, like working mode. + * @brief Set external coexistence advanced information, like working mode. * * @param out_pti1 This parameter no longer works, will be deprecated and later removed in future releases. * @param out_pti2 This parameter no longer works, will be deprecated and later removed in future releases. @@ -337,6 +344,14 @@ esp_err_t esp_coex_external_set(esp_coex_pti_level_t level1, */ void esp_coex_external_stop(void); +/** + * @brief Set external coexistence wire type. + * + * @param wire_type Set external coexistence wire type. + * + */ +void esp_coex_external_set_wire_type(external_coex_wire_t wire_type); + #if SOC_EXTERNAL_COEX_LEADER_TX_LINE /** * @brief Enable external coexist tx line @@ -350,6 +365,25 @@ void esp_coex_external_set_txline(bool en); #endif /*SOC_EXTERNAL_COEX_LEADER_TX_LINE*/ #endif /*External Coex*/ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT +/** + * @brief Set coexist scheme flexible period + * + * @param period flexible period + * + * @return + * - ESP_OK: succeed + */ +int coex_schm_flexible_period_set(uint8_t period); + +/** + * @brief Get coexist scheme flexible period + * + * @return Coexist scheme flexible period + */ +uint8_t coex_schm_flexible_period_get(void); +#endif + /** * @brief Check the MD5 values of the coexistence adapter header files in IDF and WiFi library * diff --git a/components/esp_coex/include/esp_modem_wrapper.h b/components/esp_coex/include/private/esp_modem_wrapper.h similarity index 100% rename from components/esp_coex/include/esp_modem_wrapper.h rename to components/esp_coex/include/private/esp_modem_wrapper.h diff --git a/components/esp_coex/lib b/components/esp_coex/lib index 37698e17a4..d17141ba29 160000 --- a/components/esp_coex/lib +++ b/components/esp_coex/lib @@ -1 +1 @@ -Subproject commit 37698e17a4c7fd2e0872317fc8befaac3bb10cb4 +Subproject commit d17141ba292d6a4b7434c5080cb0b0e7ce170fc8 diff --git a/components/esp_coex/linker.lf b/components/esp_coex/linker.lf index 89f1fd620d..10d99add7e 100644 --- a/components/esp_coex/linker.lf +++ b/components/esp_coex/linker.lf @@ -1,5 +1,23 @@ +[sections:coex_iram] +entries: + .coexiram+ + +[sections:coex_sleep_iram] +entries: + .coexsleepiram+ + +[scheme:coex_iram_config] +entries: + if ESP_WIFI_IRAM_OPT = y: + coex_iram -> iram0_text + else: + coex_iram -> flash_text + if ESP_WIFI_SLP_IRAM_OPT = y: + coex_sleep_iram -> iram0_text + else: + coex_sleep_iram -> flash_text + [mapping:coexist] archive: libcoexist.a entries: - if ESP_WIFI_SLP_IRAM_OPT = y: - * (wifi_slp_iram) + * (coex_iram_config) diff --git a/components/esp_coex/src/coexist.c b/components/esp_coex/src/coexist.c index 5e8a175df4..e5d1477933 100644 --- a/components/esp_coex/src/coexist.c +++ b/components/esp_coex/src/coexist.c @@ -5,7 +5,7 @@ */ #include "esp_coexist.h" -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #if CONFIG_EXTERNAL_COEX_ENABLE #include "esp_log.h" @@ -162,7 +162,7 @@ esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, esp_ex ESP_LOGE(TAG, "Configure external coex with unexpected gpio pin!!!\n"); return ESP_ERR_INVALID_ARG; } - + esp_coex_external_set_wire_type(wire_type); #if SOC_EXTERNAL_COEX_ADVANCE esp_coex_external_params(g_external_coex_params, 0, 0); #endif diff --git a/components/esp_coex/test_md5/test_md5.sh b/components/esp_coex/test_md5/test_md5.sh index 0b62e8e3e6..65a32ebb49 100755 --- a/components/esp_coex/test_md5/test_md5.sh +++ b/components/esp_coex/test_md5/test_md5.sh @@ -58,7 +58,7 @@ function check_md5() } echo "Checking libraries for target ${IDF_TARGET}..." -check_md5 ${IDF_PATH}/components/esp_coex/include/esp_coexist_adapter.h g_coex_adapter_funcs_md5 +check_md5 ${IDF_PATH}/components/esp_coex/include/private/esp_coexist_adapter.h g_coex_adapter_funcs_md5 case $IDF_TARGET in esp32c6|esp32h2) diff --git a/components/esp_common/include/esp_err.h b/components/esp_common/include/esp_err.h index b00c4ad304..361dbba118 100644 --- a/components/esp_common/include/esp_err.h +++ b/components/esp_common/include/esp_err.h @@ -34,6 +34,8 @@ typedef int esp_err_t; #define ESP_ERR_INVALID_VERSION 0x10A /*!< Version was invalid */ #define ESP_ERR_INVALID_MAC 0x10B /*!< MAC address was invalid */ #define ESP_ERR_NOT_FINISHED 0x10C /*!< There are items remained to retrieve */ +#define ESP_ERR_NOT_ALLOWED 0x10D /*!< Operation is not allowed */ +#define ESP_ERR_ROC_IN_PROGRESS 0x10E /*!< ROC Operation is in progress */ #define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */ @@ -78,7 +80,6 @@ const char *esp_err_to_name_r(esp_err_t code, char *buf, size_t buflen); /** @cond */ void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression); -/** @cond */ void _esp_error_check_failed_without_abort(esp_err_t rc, const char *file, int line, const char *function, const char *expression); #ifndef __ASSERT_FUNC diff --git a/components/esp_common/include/esp_idf_version.h b/components/esp_common/include/esp_idf_version.h index a05a15efe6..7aa122ac1f 100644 --- a/components/esp_common/include/esp_idf_version.h +++ b/components/esp_common/include/esp_idf_version.h @@ -15,7 +15,7 @@ extern "C" { /** Minor version number (x.X.x) */ #define ESP_IDF_VERSION_MINOR 1 /** Patch version number (x.x.X) */ -#define ESP_IDF_VERSION_PATCH 0 +#define ESP_IDF_VERSION_PATCH 4 /** * Macro to convert IDF version number into an integer diff --git a/components/esp_common/include/esp_macros.h b/components/esp_common/include/esp_macros.h index 9a1c834588..ee0ce4fc40 100644 --- a/components/esp_common/include/esp_macros.h +++ b/components/esp_common/include/esp_macros.h @@ -75,6 +75,10 @@ extern "C" { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 #endif +#ifndef ESP_UNUSED +#define ESP_UNUSED(x) ((void)(x)) +#endif + /* test macros */ #define foo_args(...) 1 #define foo_no_args() 2 diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index 44da581452..3a795d308d 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -130,6 +130,12 @@ static const esp_err_msg_t esp_err_msg_table[] = { # endif # ifdef ESP_ERR_NOT_FINISHED ERR_TBL_IT(ESP_ERR_NOT_FINISHED), /* 268 0x10c There are items remained to retrieve */ +# endif +# ifdef ESP_ERR_NOT_ALLOWED + ERR_TBL_IT(ESP_ERR_NOT_ALLOWED), /* 269 0x10d Operation is not allowed */ +# endif +# ifdef ESP_ERR_ROC_IN_PROGRESS + ERR_TBL_IT(ESP_ERR_ROC_IN_PROGRESS), /* 270 0x10e ROC Operation is in progress */ # endif // components/nvs_flash/include/nvs.h # ifdef ESP_ERR_NVS_BASE @@ -407,6 +413,9 @@ static const esp_err_msg_t esp_err_msg_table[] = { # endif # ifdef ESP_ERR_WIFI_TWT_SETUP_REJECT ERR_TBL_IT(ESP_ERR_WIFI_TWT_SETUP_REJECT), /* 12314 0x301a The twt setup request was rejected by the AP */ +# endif +# ifdef ESP_ERR_WIFI_DISCARD + ERR_TBL_IT(ESP_ERR_WIFI_DISCARD), /* 12315 0x301b Discard frame */ # endif // components/wpa_supplicant/esp_supplicant/include/esp_wps.h # ifdef ESP_ERR_WIFI_REGISTRAR @@ -455,6 +464,9 @@ static const esp_err_msg_t esp_err_msg_table[] = { # endif # ifdef ESP_ERR_DPP_INVALID_ATTR ERR_TBL_IT(ESP_ERR_DPP_INVALID_ATTR), /* 12441 0x3099 Encountered invalid DPP Attribute */ +# endif +# ifdef ESP_ERR_DPP_AUTH_TIMEOUT + ERR_TBL_IT(ESP_ERR_DPP_AUTH_TIMEOUT), /* 12442 0x309a DPP Auth response was not recieved in time */ # endif // components/esp_common/include/esp_err.h # ifdef ESP_ERR_MESH_BASE diff --git a/components/esp_event/.build-test-rules.yml b/components/esp_event/.build-test-rules.yml index eb6a06f0c2..f928409861 100644 --- a/components/esp_event/.build-test-rules.yml +++ b/components/esp_event/.build-test-rules.yml @@ -1,5 +1,10 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps +components/esp_event/host_test/esp_event_unit_test: + enable: + - if: IDF_TARGET == "linux" + reason: only test on linux + components/esp_event/test_apps: enable: - if: IDF_TARGET in ["esp32", "esp32s2", "esp32c3"] diff --git a/components/esp_event/include/esp_event.h b/components/esp_event/include/esp_event.h index bf5d98bcb4..2867367fc5 100644 --- a/components/esp_event/include/esp_event.h +++ b/components/esp_event/include/esp_event.h @@ -363,7 +363,7 @@ esp_err_t esp_event_post(esp_event_base_t event_base, * the copy's lifetime automatically (allocation + deletion); this ensures that the data the * handler receives is always valid. * - * This function behaves in the same manner as esp_event_post_to, except the additional specification of the event loop + * This function behaves in the same manner as esp_event_post, except the additional specification of the event loop * to post the event to. * * @param[in] event_loop the event loop to post to, must not be NULL diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 379b911cba..b29f78b068 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -16,7 +16,7 @@ if(${target} STREQUAL "esp32c6") list(APPEND priv_requires hal) endif() -set(srcs "cpu.c" "esp_memory_utils.c" "port/${IDF_TARGET}/cpu_region_protect.c") +set(srcs "cpu.c" "port/${IDF_TARGET}/esp_cpu_intr.c" "esp_memory_utils.c" "port/${IDF_TARGET}/cpu_region_protect.c") if(NOT BOOTLOADER_BUILD) list(APPEND srcs "esp_clk.c" "clk_ctrl_os.c" @@ -24,9 +24,12 @@ if(NOT BOOTLOADER_BUILD) "intr_alloc.c" "mac_addr.c" "periph_ctrl.c" + "revision.c" "rtc_module.c" "sleep_modes.c" + "sleep_console.c" "sleep_gpio.c" + "sleep_event.c" "sleep_modem.c" "regi2c_ctrl.c" "esp_gpio_reserve.c" @@ -56,6 +59,9 @@ if(NOT BOOTLOADER_BUILD) if(CONFIG_SOC_GDMA_SUPPORTED) list(APPEND srcs "dma/gdma.c" "dma/async_memcpy_impl_gdma.c") + if(CONFIG_SOC_PAU_SUPPORTED) + list(APPEND srcs "dma/gdma_sleep_retention.c") + endif() endif() if(CONFIG_SOC_CP_DMA_SUPPORTED) @@ -114,12 +120,6 @@ if(NOT BOOTLOADER_BUILD) if(CONFIG_SOC_RTC_FAST_MEM_SUPPORTED) list(APPEND srcs "sleep_wake_stub.c") endif() - - if(CONFIG_IDF_TARGET_ESP32H2) - list(REMOVE_ITEM srcs - "sleep_wake_stub.c" # TODO: IDF-6268 - ) - endif() else() # Requires "_esp_error_check_failed()" function list(APPEND priv_requires "esp_system") diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 11d938e4d2..fde8b3ecf3 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -52,6 +52,13 @@ menu "Hardware Settings" If you have an invalid MAC CRC (ESP_ERR_INVALID_CRC) problem and you still want to use this chip, you can enable this option to bypass such an error. This applies to both MAC_FACTORY and CUSTOM_MAC efuses. + + config ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC + bool "Enable using custom mac as base mac" + default n + help + When this configuration is enabled, the user can invoke `esp_read_mac` to obtain the desired type of + MAC using a custom MAC as the base MAC. endmenu menu "Sleep Config" @@ -136,36 +143,72 @@ menu "Hardware Settings" This option provides a software workaround for this issue. Configure to isolate all GPIO pins in sleep state. - config ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY - int "Extra delay in deep sleep wake stub (in us)" - depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 - default 2000 + config ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY + int "Extra delay (in us) after flash powerdown sleep wakeup to wait flash ready" + default 2000 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 + default 0 range 0 5000 help - When the chip exits deep sleep, the CPU and the flash chip are powered on - at the same time. CPU will run deep sleep stub first, and then - proceed to load code from flash. Some flash chips need sufficient - time to pass between power on and first read operation. By default, - without any extra delay, this time is approximately 900us, although + When the chip exits sleep, the CPU and the flash chip are powered on at the same time. + CPU will run rom code (deepsleep) or ram code (lightsleep) first, and then load or execute + code from flash. + + Some flash chips need sufficient time to pass between power on and first read operation. + By default, without any extra delay, this time is approximately 900us, although some flash chip types need more than that. - By default extra delay is set to 2000us. When optimizing startup time + (!!! Please adjust this value according to the Data Sheet of SPI Flash used in your project.) + In Flash Data Sheet, the parameters that define the Flash ready timing after power-up (minimum + time from Vcc(min) to CS activeare) usually named tVSL in ELECTRICAL CHARACTERISTICS chapter, + and the configuration value here should be: + ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY = tVSL - 900 + + For esp32 and esp32s3, the default extra delay is set to 2000us. When optimizing startup time for applications which require it, this value may be reduced. - If you are seeing "flash read err, 1000" message printed to the - console after deep sleep reset, try increasing this value. - endmenu + If you are seeing "flash read err, 1000" message printed to the console after deep sleep reset + on esp32, or triggered RTC_WDT/LP_WDT after lightsleep wakeup, try increasing this value. + (For esp32, the delay will be executed in both deep sleep and light sleep wake up flow. + For chips after esp32, the delay will be executed only in light sleep flow, the delay + controlled by the EFUSE_FLASH_TPUW in ROM will be executed in deepsleep wake up flow.) - menu "ESP_SLEEP_WORKAROUND" - # No visible menu/configs for workaround - visible if 0 - config ESP_SLEEP_SYSTIMER_STALL_WORKAROUND - bool "ESP32C3 SYSTIMER Stall Issue Workaround" - depends on IDF_TARGET_ESP32C3 + config ESP_SLEEP_DEBUG + bool "esp sleep debug" + default n + help + Enable esp sleep debug. + + config ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS + bool "Allow to enable internal pull-up/downs for the Deep-Sleep wakeup IOs" + default y help - Its not able to stall ESP32C3 systimer in sleep. - To fix related RTOS TICK issue, select it to disable related systimer during sleep. - TODO: IDF-7036 + When using rtc gpio wakeup source during deepsleep without external pull-up/downs, you may want to + make use of the internal ones. + + config ESP_SLEEP_EVENT_CALLBACKS + bool "Enable registration of sleep event callbacks" + depends on FREERTOS_USE_TICKLESS_IDLE + default n + help + If enabled, it allows user to register sleep event callbacks. It is primarily designed for internal + developers and customers can use PM_LIGHT_SLEEP_CALLBACKS as an alternative. + + NOTE: These callbacks are executed from the IDLE task context hence you cannot have any blocking calls + in your callbacks. + + NOTE: Enabling these callbacks may change sleep duration calculations based on time spent in + callback and hence it is highly recommended to keep them as short as possible. + + config ESP_SLEEP_CACHE_SAFE_ASSERTION + bool "Check the cache safety of the sleep wakeup code in sleep process" + default n + select ESP_PANIC_HANDLER_IRAM + help + Enabling it will check the cache safety of the code before the flash power is ready after + light sleep wakeup, and check PM_SLP_IRAM_OPT related code cache safety. This option is + only for code quality inspection. Enabling it will increase the time overhead of entering + and exiting sleep. It is not recommended to enable it in the release version. + endmenu menu "RTC Clock Config" diff --git a/components/esp_hw_support/adc_share_hw_ctrl.c b/components/esp_hw_support/adc_share_hw_ctrl.c index 0d272dc5cf..e5142c9904 100644 --- a/components/esp_hw_support/adc_share_hw_ctrl.c +++ b/components/esp_hw_support/adc_share_hw_ctrl.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -30,6 +30,8 @@ #include "hal/adc_hal_common.h" #include "esp_private/adc_share_hw_ctrl.h" #include "esp_private/sar_periph_ctrl.h" +#include "esp_private/periph_ctrl.h" +#include "soc/periph_defs.h" //For calibration #if CONFIG_IDF_TARGET_ESP32S2 #include "esp_efuse_rtc_table.h" @@ -198,3 +200,39 @@ esp_err_t adc2_wifi_release(void) return ESP_OK; } + +static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED; + +/*------------------------------------------------------------------------------ +* For those who use APB_SARADC periph +*----------------------------------------------------------------------------*/ +static int s_adc_digi_ctrlr_cnt; + +void adc_apb_periph_claim(void) +{ + portENTER_CRITICAL(&s_spinlock); + s_adc_digi_ctrlr_cnt++; + if (s_adc_digi_ctrlr_cnt == 1) { + //enable ADC digital part + periph_module_enable(PERIPH_SARADC_MODULE); + //reset ADC digital part + periph_module_reset(PERIPH_SARADC_MODULE); + } + + portEXIT_CRITICAL(&s_spinlock); +} + +void adc_apb_periph_free(void) +{ + portENTER_CRITICAL(&s_spinlock); + s_adc_digi_ctrlr_cnt--; + if (s_adc_digi_ctrlr_cnt == 0) { + periph_module_disable(PERIPH_SARADC_MODULE); + } else if (s_adc_digi_ctrlr_cnt < 0) { + portEXIT_CRITICAL(&s_spinlock); + ESP_LOGE(TAG, "%s called, but `s_adc_digi_ctrlr_cnt == 0`", __func__); + abort(); + } + + portEXIT_CRITICAL(&s_spinlock); +} diff --git a/components/esp_hw_support/cpu.c b/components/esp_hw_support/cpu.c index c3b7dd4121..69713eddc1 100644 --- a/components/esp_hw_support/cpu.c +++ b/components/esp_hw_support/cpu.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -120,167 +120,6 @@ void esp_cpu_wait_for_intr(void) #endif // __XTENSA__ } -/* -------------------------------------------------- CPU Registers ---------------------------------------------------- - * - * ------------------------------------------------------------------------------------------------------------------ */ - -/* ------------------------------------------------- CPU Interrupts ---------------------------------------------------- - * - * ------------------------------------------------------------------------------------------------------------------ */ - -// ---------------- Interrupt Descriptors ------------------ - -#if SOC_CPU_HAS_FLEXIBLE_INTC - -static bool is_intr_num_resv(int intr_num) -{ - // Workaround to reserve interrupt number 1 for Wi-Fi, 5,8 for Bluetooth, 6 for "permanently disabled interrupt" - // [TODO: IDF-2465] - uint32_t reserved = BIT(1) | BIT(5) | BIT(6) | BIT(8); - - // int_num 0,3,4,7 are inavaliable for PULP cpu -#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2// TODO: IDF-5728 replace with a better macro name - reserved |= BIT(0) | BIT(3) | BIT(4) | BIT(7); -#endif - - if (reserved & BIT(intr_num)) { - return true; - } - - extern int _vector_table; - extern int _interrupt_handler; - const intptr_t pc = (intptr_t)(&_vector_table + intr_num); - - /* JAL instructions are relative to the PC there are executed from. */ - const intptr_t destination = pc + riscv_decode_offset_from_jal_instruction(pc); - - return destination != (intptr_t)&_interrupt_handler; -} - -void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) -{ - intr_desc_ret->priority = 1; //Todo: We should make this -1 - intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; -#if __riscv - intr_desc_ret->flags = is_intr_num_resv(intr_num) ? ESP_CPU_INTR_DESC_FLAG_RESVD : 0; -#else - intr_desc_ret->flags = 0; -#endif -} - -#else // SOC_CPU_HAS_FLEXIBLE_INTC - -typedef struct { - int priority; - esp_cpu_intr_type_t type; - uint32_t flags[SOC_CPU_CORES_NUM]; -} intr_desc_t; - -#if SOC_CPU_CORES_NUM > 1 -// Note: We currently only have dual core targets, so the table initializer is hard coded -const static intr_desc_t intr_desc_table [SOC_CPU_INTR_NUM] = { - { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //0 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //1 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, //2 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, //3 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, 0 } }, //4 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //5 -#if CONFIG_FREERTOS_CORETIMER_0 - { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //6 -#else - { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //6 -#endif - { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //7 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //8 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, //9 - { 1, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } }, //10 - { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //11 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0} }, //12 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0} }, //13 - { 7, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //14, NMI -#if CONFIG_FREERTOS_CORETIMER_1 - { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //15 -#else - { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //15 -#endif - { 5, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //16 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, //17 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, //18 - { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, //19 - { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, //20 - { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, //21 - { 3, ESP_CPU_INTR_TYPE_EDGE, { ESP_CPU_INTR_DESC_FLAG_RESVD, 0 } }, //22 - { 3, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, //23 - { 4, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, 0 } }, //24 - { 4, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //25 - { 5, ESP_CPU_INTR_TYPE_LEVEL, { 0, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //26 - { 3, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //27 - { 4, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } }, //28 - { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //29 - { 4, ESP_CPU_INTR_TYPE_EDGE, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //30 - { 5, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, //31 -}; - -#else // SOC_CPU_CORES_NUM > 1 - -const static intr_desc_t intr_desc_table [SOC_CPU_INTR_NUM] = { - { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //0 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //1 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //2 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //3 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //4 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //5 -#if CONFIG_FREERTOS_CORETIMER_0 - { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //6 -#else - { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //6 -#endif - { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //7 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //8 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //9 - { 1, ESP_CPU_INTR_TYPE_EDGE, { 0 } }, //10 - { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //11 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //12 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //13 - { 7, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //14, NMI -#if CONFIG_FREERTOS_CORETIMER_1 - { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //15 -#else - { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //15 -#endif - { 5, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //16 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //17 - { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //18 - { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //19 - { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //20 - { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //21 - { 3, ESP_CPU_INTR_TYPE_EDGE, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //22 - { 3, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //23 - { 4, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //24 - { 4, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //25 - { 5, ESP_CPU_INTR_TYPE_LEVEL, { 0 } }, //26 - { 3, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //27 - { 4, ESP_CPU_INTR_TYPE_EDGE, { 0 } }, //28 - { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, //29 - { 4, ESP_CPU_INTR_TYPE_EDGE, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //30 - { 5, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD } }, //31 -}; - -#endif // SOC_CPU_CORES_NUM > 1 - -void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) -{ - assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM); -#if SOC_CPU_CORES_NUM == 1 - core_id = 0; //If this is a single core target, hard code CPU ID to 0 -#endif - intr_desc_ret->priority = intr_desc_table[intr_num].priority; - intr_desc_ret->type = intr_desc_table[intr_num].type; - intr_desc_ret->flags = intr_desc_table[intr_num].flags[core_id]; -} - -#endif // SOC_CPU_HAS_FLEXIBLE_INTC - /* ---------------------------------------------------- Debugging ------------------------------------------------------ * * ------------------------------------------------------------------------------------------------------------------ */ @@ -310,8 +149,9 @@ esp_err_t esp_cpu_set_breakpoint(int bp_num, const void *bp_addr) if (ret == 0) { return ESP_ERR_INVALID_RESPONSE; } - } - rv_utils_set_breakpoint(bp_num, (uint32_t)bp_addr); + } else { + rv_utils_set_breakpoint(bp_num, (uint32_t)bp_addr); + } #endif // __XTENSA__ return ESP_OK; } @@ -332,8 +172,9 @@ esp_err_t esp_cpu_clear_breakpoint(int bp_num) if (ret == 0) { return ESP_ERR_INVALID_RESPONSE; } - } - rv_utils_clear_breakpoint(bp_num); + } else { + rv_utils_clear_breakpoint(bp_num); + } #endif // __XTENSA__ return ESP_OK; } @@ -344,11 +185,19 @@ esp_err_t esp_cpu_set_watchpoint(int wp_num, const void *wp_addr, size_t size, e { /* Todo: - - Check that wp_num is in range - Check if the wp_num is already in use */ - // Check if size is 2^n, where n is in [0...6] - if (size < 1 || size > 64 || (size & (size - 1)) != 0) { + if (wp_num < 0 || wp_num >= SOC_CPU_WATCHPOINTS_NUM) { + return ESP_ERR_INVALID_ARG; + } + + // Check that the watched region's start address is naturally aligned to the size of the region + if ((uint32_t)wp_addr % size) { + return ESP_ERR_INVALID_ARG; + } + + // Check if size is 2^n, and size is in the range of [1 ... SOC_CPU_WATCHPOINT_MAX_REGION_SIZE] + if (size < 1 || size > SOC_CPU_WATCHPOINT_MAX_REGION_SIZE || (size & (size - 1)) != 0) { return ESP_ERR_INVALID_ARG; } bool on_read = (trigger == ESP_CPU_WATCHPOINT_LOAD || trigger == ESP_CPU_WATCHPOINT_ACCESS); @@ -365,8 +214,9 @@ esp_err_t esp_cpu_set_watchpoint(int wp_num, const void *wp_addr, size_t size, e if (ret == 0) { return ESP_ERR_INVALID_RESPONSE; } - } - rv_utils_set_watchpoint(wp_num, (uint32_t)wp_addr, size, on_read, on_write); + } else { + rv_utils_set_watchpoint(wp_num, (uint32_t)wp_addr, size, on_read, on_write); + } #endif // __XTENSA__ return ESP_OK; } @@ -387,8 +237,9 @@ esp_err_t esp_cpu_clear_watchpoint(int wp_num) if (ret == 0) { return ESP_ERR_INVALID_RESPONSE; } - } - rv_utils_clear_watchpoint(wp_num); + } else { + rv_utils_clear_watchpoint(wp_num); + } #endif // __XTENSA__ return ESP_OK; } diff --git a/components/esp_hw_support/dma/gdma.c b/components/esp_hw_support/dma/gdma.c index 4c70a4ebbb..4194821fdd 100644 --- a/components/esp_hw_support/dma/gdma.c +++ b/components/esp_hw_support/dma/gdma.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,10 @@ #include "gdma_priv.h" #include "hal/cache_hal.h" +#if CONFIG_PM_ENABLE && SOC_PAU_SUPPORTED +#include "esp_private/gdma_sleep_retention.h" +#endif + static const char *TAG = "gdma"; #define GDMA_INVALID_PERIPH_TRIG (0x3F) @@ -606,6 +610,9 @@ static void gdma_release_pair_handle(gdma_pair_t *pair) if (do_deinitialize) { free(pair); +#if CONFIG_PM_ENABLE && SOC_PAU_SUPPORTED + gdma_sleep_retention_deinit(group->group_id, pair_id); +#endif ESP_LOGD(TAG, "del pair (%d,%d)", group->group_id, pair_id); gdma_release_group_handle(group); } @@ -638,6 +645,10 @@ static gdma_pair_t *gdma_acquire_pair_handle(gdma_group_t *group, int pair_id) portENTER_CRITICAL(&s_platform.spinlock); s_platform.group_ref_counts[group->group_id]++; // pair obtains a reference to group portEXIT_CRITICAL(&s_platform.spinlock); + +#if CONFIG_PM_ENABLE && SOC_PAU_SUPPORTED + gdma_sleep_retention_init(group->group_id, pair->pair_id); +#endif ESP_LOGD(TAG, "new pair (%d,%d) at %p", group->group_id, pair->pair_id, pair); } else { free(pre_alloc_pair); diff --git a/components/esp_hw_support/dma/gdma_sleep_retention.c b/components/esp_hw_support/dma/gdma_sleep_retention.c new file mode 100644 index 0000000000..2b818c33ba --- /dev/null +++ b/components/esp_hw_support/dma/gdma_sleep_retention.c @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "soc/soc_caps.h" + +#include "esp_err.h" +#if CONFIG_GDMA_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" +#include "esp_private/sleep_retention.h" +#include "esp_private/esp_regdma.h" + +#include "hal/gdma_ll.h" + +static const char *TAG = "gdma"; + +typedef struct { + int group_id; + int pair_id; +} gdma_channel_retention_arg_t; + +typedef struct gdma_chx_reg_ctx_link { + const sleep_retention_entries_config_t *link_list; + uint32_t link_num; +} gdma_chx_reg_ctx_link_t; + +#include "sleep_gdma_retention_context.inc" + +static esp_err_t sleep_gdma_channel_retention_init(void *arg) +{ + gdma_channel_retention_arg_t *parg = (gdma_channel_retention_arg_t *)arg; + int group_id = parg->group_id; + int pair_id = parg->pair_id; + + sleep_retention_module_bitmap_t module = GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id); + esp_err_t err = sleep_retention_entries_create(gdma_chx_regs_retention[group_id][pair_id].link_list, gdma_chx_regs_retention[group_id][pair_id].link_num, REGDMA_LINK_PRI_7, module); + if (err == ESP_OK) { + ESP_LOGD(TAG, "GDMA pair (%d, %d) retention initialization", group_id, pair_id); + } + + ESP_RETURN_ON_ERROR(err, TAG, "Failed to create sleep retention linked list for GDMA pair (%d, %d) retention", group_id, pair_id); + return err; +} + +esp_err_t gdma_sleep_retention_init(int group_id, int pair_id) +{ + gdma_channel_retention_arg_t arg = { .group_id = group_id, .pair_id = pair_id }; + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_gdma_channel_retention_init, .arg = &arg } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + sleep_retention_module_bitmap_t module = GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id); + esp_err_t err = sleep_retention_module_init(module, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(module); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Failed to allocate sleep retention linked list for GDMA retention"); + } + } + return err; +} + +esp_err_t gdma_sleep_retention_deinit(int group_id, int pair_id) +{ + esp_err_t err = sleep_retention_module_free(GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id)); + if (err != ESP_OK) { + ESP_LOGW(TAG, "GDMA pair (%d, %d) retention destroy failed", group_id, pair_id); + } + err = sleep_retention_module_deinit(GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id)); + if (err != ESP_OK) { + ESP_LOGW(TAG, "GDMA pair (%d, %d) retention deinit failed", group_id, pair_id); + } + return err; +} diff --git a/components/esp_hw_support/esp_hmac.c b/components/esp_hw_support/esp_hmac.c index 25e5c8bc8e..8f762ff6ce 100644 --- a/components/esp_hw_support/esp_hmac.c +++ b/components/esp_hw_support/esp_hmac.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -170,7 +170,7 @@ esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token) ESP_LOGD(TAG, "HMAC computation in downstream mode is completed."); - ets_hmac_disable(); + periph_module_disable(PERIPH_HMAC_MODULE); esp_crypto_hmac_lock_release(); @@ -180,7 +180,9 @@ esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token) esp_err_t esp_hmac_jtag_disable() { esp_crypto_hmac_lock_acquire(); + periph_module_enable(PERIPH_HMAC_MODULE); REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1); + periph_module_disable(PERIPH_HMAC_MODULE); esp_crypto_hmac_lock_release(); ESP_LOGD(TAG, "Invalidate JTAG result register. JTAG disabled."); @@ -215,7 +217,6 @@ esp_err_t esp_hmac_calculate(hmac_key_id_t key_id, } else { return ESP_OK; } - } esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id, const uint8_t *token) @@ -262,7 +263,9 @@ esp_err_t esp_hmac_jtag_disable() { esp_crypto_dma_lock_acquire(); + ets_hmac_enable(); REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1); + ets_hmac_disable(); esp_crypto_dma_lock_release(); diff --git a/components/esp_hw_support/include/esp_cpu.h b/components/esp_hw_support/include/esp_cpu.h index 33a5ad1cc9..36f9d7ba40 100644 --- a/components/esp_hw_support/include/esp_cpu.h +++ b/components/esp_hw_support/include/esp_cpu.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 */ @@ -470,9 +470,15 @@ esp_err_t esp_cpu_clear_breakpoint(int bp_num); * the CPU accesses (according to the trigger type) on a certain memory range. * * @note Overwrites previously set watchpoint with same watchpoint number. + * On RISC-V chips, this API uses method0(Exact matching) and method1(NAPOT matching) according to the + * riscv-debug-spec-0.13 specification for address matching. + * If the watch region size is 1byte, it uses exact matching (method 0). + * If the watch region size is larger than 1byte, it uses NAPOT matching (method 1). This mode requires + * the watching region start address to be aligned to the watching region size. + * * @param wp_num Hardware watchpoint number [0..SOC_CPU_WATCHPOINTS_NUM - 1] - * @param wp_addr Watchpoint's base address - * @param size Size of the region to watch. Must be one of 2^n, with n in [0..6]. + * @param wp_addr Watchpoint's base address, must be naturally aligned to the size of the region + * @param size Size of the region to watch. Must be one of 2^n and in the range of [1 ... SOC_CPU_WATCHPOINT_MAX_REGION_SIZE] * @param trigger Trigger type * @return ESP_ERR_INVALID_ARG on invalid arg, ESP_OK otherwise */ diff --git a/components/esp_hw_support/include/esp_intr_alloc.h b/components/esp_hw_support/include/esp_intr_alloc.h index 9aa3852509..8314f7041d 100644 --- a/components/esp_hw_support/include/esp_intr_alloc.h +++ b/components/esp_hw_support/include/esp_intr_alloc.h @@ -304,7 +304,7 @@ void esp_intr_disable_source(int inum); */ static inline int esp_intr_flags_to_level(int flags) { - return __builtin_ffs((flags & ESP_INTR_FLAG_LEVELMASK) >> 1) + 1; + return __builtin_ffs((flags & ESP_INTR_FLAG_LEVELMASK) >> 1); } /**@}*/ diff --git a/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h b/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h index 4d9de5270c..5bf1084730 100644 --- a/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h +++ b/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -156,6 +156,24 @@ void adc2_cal_include(void); #define adc2_cal_include() #endif //CONFIG_IDF_TARGET_* +/*------------------------------------------------------------------------------ +* For those who use APB_SARADC periph +*----------------------------------------------------------------------------*/ +/** + * @brief Claim the usage of the APB_SARADC periph + * + * Reference count inside + */ +void adc_apb_periph_claim(void); + +/** + * @brief Free the usage of the APB_SARADC periph + * + * Reference count inside + */ +void adc_apb_periph_free(void); + + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/include/esp_private/esp_modem_clock.h b/components/esp_hw_support/include/esp_private/esp_modem_clock.h index bd822ebfbd..a09d450ac3 100644 --- a/components/esp_hw_support/include/esp_private/esp_modem_clock.h +++ b/components/esp_hw_support/include/esp_private/esp_modem_clock.h @@ -70,15 +70,6 @@ void modem_clock_module_disable(periph_module_t module); */ void modem_clock_module_mac_reset(periph_module_t module); -/** - * @brief Initialize the clock gating control signal of each clock domain of the modem - * - * This is a global modem clock gating signal initialization interface, which is - * only configured during system initialization, and each modem module cannot - * use this interface. - */ -void modem_clock_domain_pmu_state_icg_map_init(void); - #if SOC_PMU_SUPPORTED /** * @brief Enable modem clock domain clock gate to gate it's output @@ -124,6 +115,13 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module); */ void modem_clock_wifi_mac_reset(void); +/** + * @brief Enable clock registers which shared by both modem and ADC. Need a ref count to enable/disable them + * + * @param enable true: enable; false: disable + */ +void modem_clock_shared_enable(bool enable); + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/include/esp_private/esp_pau.h b/components/esp_hw_support/include/esp_private/esp_pau.h index db6b059d27..7fdbaaa98d 100644 --- a/components/esp_hw_support/include/esp_private/esp_pau.h +++ b/components/esp_hw_support/include/esp_private/esp_pau.h @@ -43,7 +43,7 @@ void pau_regdma_trigger_modem_link_backup(void); void pau_regdma_trigger_modem_link_restore(void); #endif -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA /** * @brief Set the address of system REGDMA Link in active state * @param link_addr linked lists address diff --git a/components/esp_hw_support/include/esp_private/esp_pmu.h b/components/esp_hw_support/include/esp_private/esp_pmu.h index 187784fae6..1d8d2c309b 100644 --- a/components/esp_hw_support/include/esp_private/esp_pmu.h +++ b/components/esp_hw_support/include/esp_private/esp_pmu.h @@ -41,31 +41,64 @@ extern "C" { #else #define RTC_EXT0_TRIG_EN 0 #endif + #if SOC_PM_SUPPORT_EXT1_WAKEUP #define RTC_EXT1_TRIG_EN PMU_EXT1_WAKEUP_EN //!< EXT1 wakeup +#else +#define RTC_EXT1_TRIG_EN 0 #endif + #define RTC_GPIO_TRIG_EN PMU_GPIO_WAKEUP_EN //!< GPIO wakeup + +#if SOC_LP_TIMER_SUPPORTED #define RTC_TIMER_TRIG_EN PMU_LP_TIMER_WAKEUP_EN //!< Timer wakeup +#else +#define RTC_TIMER_TRIG_EN 0 +#endif + +#if SOC_WIFI_SUPPORTED #define RTC_WIFI_TRIG_EN PMU_WIFI_SOC_WAKEUP_EN //!< WIFI wakeup (light sleep only) +#else +#define RTC_WIFI_TRIG_EN 0 +#endif + +#if SOC_UART_SUPPORT_WAKEUP_INT #define RTC_UART0_TRIG_EN PMU_UART0_WAKEUP_EN //!< UART0 wakeup (light sleep only) #define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only) +#else +#define RTC_UART0_TRIG_EN 0 +#define RTC_UART1_TRIG_EN 0 +#endif + +#if SOC_BT_SUPPORTED #define RTC_BT_TRIG_EN PMU_BLE_SOC_WAKEUP_EN //!< BT wakeup (light sleep only) +#else +#define RTC_BT_TRIG_EN 0 +#endif + #define RTC_USB_TRIG_EN PMU_USB_WAKEUP_EN + #if SOC_LP_CORE_SUPPORTED #define RTC_LP_CORE_TRIG_EN PMU_LP_CORE_WAKEUP_EN //!< LP core wakeup +#else +#define RTC_LP_CORE_TRIG_EN 0 #endif //SOC_LP_CORE_SUPPORTED + #define RTC_XTAL32K_DEAD_TRIG_EN 0 // TODO #define RTC_BROWNOUT_DET_TRIG_EN 0 // TODO /** * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip */ -#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN | \ +#define RTC_SLEEP_REJECT_MASK (RTC_EXT0_TRIG_EN | \ + RTC_EXT1_TRIG_EN | \ + RTC_GPIO_TRIG_EN | \ RTC_TIMER_TRIG_EN | \ RTC_WIFI_TRIG_EN | \ RTC_UART0_TRIG_EN | \ RTC_UART1_TRIG_EN | \ RTC_BT_TRIG_EN | \ + RTC_LP_CORE_TRIG_EN | \ RTC_XTAL32K_DEAD_TRIG_EN | \ RTC_USB_TRIG_EN | \ RTC_BROWNOUT_DET_TRIG_EN) @@ -258,6 +291,11 @@ void pmu_init(void); */ void pmu_sleep_enable_hp_sleep_sysclk(bool enable); +/** + * Get the time overhead used by regdma to work on the retention link during the hardware wake-up process + * @return regdma time cost during hardware wake-up stage in microseconds + */ +uint32_t pmu_sleep_get_wakup_retention_cost(void); #endif //#if SOC_PMU_SUPPORTED diff --git a/components/esp_hw_support/include/esp_private/esp_regdma.h b/components/esp_hw_support/include/esp_private/esp_regdma.h index ebf7ed423c..5ad9b74497 100644 --- a/components/esp_hw_support/include/esp_private/esp_regdma.h +++ b/components/esp_hw_support/include/esp_private/esp_regdma.h @@ -43,6 +43,7 @@ extern "C" { #define REGDMA_BLE_MAC_LINK(_pri) ((0x15 << 8) | _pri) #define REGDMA_MODEM_BT_BB_LINK(_pri) ((0x16 << 8) | _pri) #define REGDMA_MODEM_IEEE802154_LINK(_pri) ((0x17 << 8) | _pri) +#define REGDMA_MODEM_GDMA_LINK(_pri) ((0x18 << 8) | _pri) #define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri) typedef enum { @@ -577,11 +578,11 @@ void regdma_link_stats(void *link, int entry); void regdma_link_set_write_wait_content(void *link, uint32_t value, uint32_t mask); /** - * @brief Print all node information of the REGDMA linked list indicated by the entry argument + * @brief Dump all node information of the REGDMA linked list indicated by the entry argument * @param link The REGDMA linkded list head pointer * @param entry For nodes that support branching, use the branch specified by entry argument recursively */ -void regdma_link_show_memories(void *link, int entry); +void regdma_link_dump(FILE *out, void *link, int entry); /** * @brief Update REGDMA linked list node next pointers @@ -624,7 +625,7 @@ void *regdma_find_module_link_tail(void *link, void *tail, int entry, uint32_t m /** * @brief Find the tail node of the previous module of the specified module in the REGDMA linked list - * indicated by the entry argument starting from the link argment to the end of the tail argument + * indicated by the entry argument starting from the link argument to the end of the tail argument * @param link The REGDMA linkded list head pointer * @param tail The REGDMA linkded list tail pointer * @param entry For nodes that support branching, use the branch specified by entry argument recursively @@ -635,7 +636,7 @@ void *regdma_find_prev_module_link_tail(void *link, void *tail, int entry, uint3 /** * @brief Find the head node of the next module of the specified module in the REGDMA linked list - * indicated by the entry argument starting from the link argment to the end of the tail argument + * indicated by the entry argument starting from the link argument to the end of the tail argument * @param link The REGDMA linkded list head pointer * @param tail The REGDMA linkded list tail pointer * @param entry For nodes that support branching, use the branch specified by entry argument recursively diff --git a/components/esp_hw_support/include/esp_private/esp_riscv_intr.h b/components/esp_hw_support/include/esp_private/esp_riscv_intr.h new file mode 100644 index 0000000000..e53f8a2151 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/esp_riscv_intr.h @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include + +#if CONFIG_IDF_TARGET_ARCH_RISCV + +#if SOC_INT_CLIC_SUPPORTED + +/** + * @brief Checks whether the given interrupt number is reserved either in the given mask or in the + * _mtvt_table, which contains the routines the CPU will jump to when an interrupt or an exception + * occurs, on RISC-V targets. + * + * @param intr_num External interrupt number to check, in range 0~32 + * @param rsvd_mask Reserved interrupt mask, where bit i is 1 if interrupt i is reserved. + * + * @returns ESP_CPU_INTR_DESC_FLAG_RESVD if the interrupt is reserved, 0 else + */ +static inline uint32_t esp_riscv_intr_num_flags(int intr_num, uint32_t rsvd_mask) +{ + if (rsvd_mask & BIT(intr_num)) { + return ESP_CPU_INTR_DESC_FLAG_RESVD; + } + + extern intptr_t _mtvt_table[48]; + extern intptr_t _interrupt_handler; + + /* The first 16 entries of the array are internal interrupt, ignore them */ + const intptr_t destination = _mtvt_table[16 + intr_num]; + + return (destination != (intptr_t)&_interrupt_handler) ? ESP_CPU_INTR_DESC_FLAG_RESVD : 0; +} + + + +#else // !SOC_INT_CLIC_SUPPORTED + +#include "esp_cpu.h" +#include "riscv/instruction_decode.h" + +/** + * @brief Checks whether the given interrupt number is reserved either in the given mask or in the + * _vector_table, which contains the routines the CPU will jump to when an interrupt or an exception + * occurs, on RISC-V targets. + * + * @param intr_num Interrupt number to check, in range 0~32 + * @param rsvd_mask Reserved interrupt mask, where bit i is 1 if interrupt i is reserved. + * + * @returns ESP_CPU_INTR_DESC_FLAG_RESVD if the interrupt is reserved, 0 else + */ +static inline uint32_t esp_riscv_intr_num_flags(int intr_num, uint32_t rsvd_mask) +{ + if (rsvd_mask & BIT(intr_num)) { + return ESP_CPU_INTR_DESC_FLAG_RESVD; + } + + extern intptr_t _vector_table[32]; + extern int _interrupt_handler; + const intptr_t pc = (intptr_t) &_vector_table[intr_num]; + + /* JAL instructions are relative to the PC they are executed from. */ + const intptr_t destination = pc + riscv_decode_offset_from_jal_instruction(pc); + + return (destination != (intptr_t)&_interrupt_handler) ? ESP_CPU_INTR_DESC_FLAG_RESVD : 0; +} + +#endif // SOC_INT_CLIC_SUPPORTED + +#endif // CONFIG_IDF_TARGET_ARCH_RISCV diff --git a/components/esp_hw_support/include/esp_private/esp_sleep_internal.h b/components/esp_hw_support/include/esp_private/esp_sleep_internal.h index 56a6b5fde1..e46c936be9 100644 --- a/components/esp_hw_support/include/esp_private/esp_sleep_internal.h +++ b/components/esp_hw_support/include/esp_private/esp_sleep_internal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,12 +7,30 @@ #pragma once #include #include "sdkconfig.h" +#include "esp_sleep.h" #ifdef __cplusplus extern "C" { #endif +#if CONFIG_ESP_SLEEP_DEBUG +typedef struct { + uint32_t lightsleep_cnt; + uint64_t sleep_in_rtc_time_stamp; + uint64_t sleep_out_rtc_time_stamp; + uint32_t wakeup_triggers; + uint32_t sleep_flags; + esp_err_t sleep_request_result; +} esp_sleep_context_t; + +/** + * @brief Set the context pointer of last sleep request + * @param sleep_ctx Structure where the context of the sleep information needs to be recorded in + */ +void esp_sleep_set_sleep_context(esp_sleep_context_t *sleep_ctx); +#endif + /** * @brief Enables the use of ADC and temperature sensor in monitor (ULP) mode * @@ -30,6 +48,29 @@ void esp_sleep_enable_adc_tsens_monitor(bool enable); void esp_sleep_isolate_digital_gpio(void); #endif +/** + * Register a callback to be called from the deep sleep prepare for maintain the PHY state + * CPU is equal to min_freq_mhz (if DFS is enabled) when running this callback, + * and PLL clock is exists) + * + * @warning deepsleep PHY callbacks should without parameters, and MUST NOT, + * UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK. + * + * @param new_dslp_cb Callback to be called to close PHY related modules + * + * @return + * - ESP_OK: PHY callback registered to the phy modules deepsleep prepare + * - ESP_ERR_NO_MEM: No more hook space for register the callback + */ +esp_err_t esp_deep_sleep_register_phy_hook(esp_deep_sleep_cb_t new_dslp_cb); + +/** + * @brief Unregister an PHY deepsleep callback + * + * @param old_dslp_cb Callback to be unregistered + */ +void esp_deep_sleep_deregister_phy_hook(esp_deep_sleep_cb_t old_dslp_cb); + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/include/esp_private/gdma_sleep_retention.h b/components/esp_hw_support/include/esp_private/gdma_sleep_retention.h new file mode 100644 index 0000000000..12bf5cecdb --- /dev/null +++ b/components/esp_hw_support/include/esp_private/gdma_sleep_retention.h @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// DO NOT USE THESE APIS IN ANY APPLICATIONS +// GDMA driver is not public for end users, but for ESP-IDF developers. + +#pragma once + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initialize GDMA channel retention link for powerdown the TOP powerdomain during lightsleep + * @param group_id Group id + * @param pair_id Pair id + * @return + * - ESP_OK: Create DMA retention link successfully + * - ESP_ERR_NO_MEM: Create DMA retention link failed because out of memory + */ +esp_err_t gdma_sleep_retention_init(int group_id, int pair_id); + + + +/** + * Destroy GDMA channel retention link + * @param group_id Group id + * @param pair_id Pair id + * @return always return ESP_OK + */ +esp_err_t gdma_sleep_retention_deinit(int group_id, int pair_id); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/rtc_clk.h b/components/esp_hw_support/include/esp_private/rtc_clk.h index 7edf69be06..17c1a939b6 100644 --- a/components/esp_hw_support/include/esp_private/rtc_clk.h +++ b/components/esp_hw_support/include/esp_private/rtc_clk.h @@ -44,6 +44,12 @@ void rtc_clk_bbpll_add_consumer(void); */ void rtc_clk_bbpll_remove_consumer(void); +/** + * @brief Workaround for C2, S3, C6, H2. Trigger the calibration of PLL. Should be called when the bootloader doesn't provide a good enough PLL accuracy. +*/ +void rtc_clk_recalib_bbpll(void); + + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/include/esp_private/sleep_clock.h b/components/esp_hw_support/include/esp_private/sleep_clock.h index 5b204c1856..9cecc583b3 100644 --- a/components/esp_hw_support/include/esp_private/sleep_clock.h +++ b/components/esp_hw_support/include/esp_private/sleep_clock.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,34 +31,6 @@ extern "C" { */ bool clock_domain_pd_allowed(void); -/** - * @brief PCR module power down initialize - * - * @return ESP_OK on success - * ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args - * No memory for the retention link - */ -esp_err_t sleep_clock_system_retention_init(void); - -/** - * @brief PCR module power down deinitialize - */ -void sleep_clock_system_retention_deinit(void); - -/** - * @brief Modem syscon module power down initialize - * - * @return ESP_OK on success - * ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args - * No memory for the retention link - */ -esp_err_t sleep_clock_modem_retention_init(void); - -/** - * @brief Modem syscon module power down deinitialize - */ -void sleep_clock_modem_retention_deinit(void); - #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/include/esp_private/sleep_console.h b/components/esp_hw_support/include/esp_private/sleep_console.h new file mode 100644 index 0000000000..612c51692c --- /dev/null +++ b/components/esp_hw_support/include/esp_private/sleep_console.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_USB_SERIAL_JTAG_SUPPORTED +typedef struct { + bool usj_clock_enabled; + bool usj_pad_enabled; +} sleep_console_usj_enable_state_t; + +/** + * @brief Disable usb-serial-jtag pad during light sleep to avoid current leakage and + * backup the enable state before light sleep + */ +void sleep_console_usj_pad_backup_and_disable(void); + +/** + * @brief Restore initial usb-serial-jtag pad enable state when wakeup from light sleep + */ +void sleep_console_usj_pad_restore(void); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/sleep_event.h b/components/esp_hw_support/include/esp_private/sleep_event.h new file mode 100644 index 0000000000..7a7efaabfc --- /dev/null +++ b/components/esp_hw_support/include/esp_private/sleep_event.h @@ -0,0 +1,120 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef enum { + /** + * Using SLEEP_EVENT to determine the execution of specific + * code at a particular point in the sleep flow. + */ + SLEEP_EVENT_HW_EXIT_SLEEP, // CPU wake up and start to work + SLEEP_EVENT_SW_CLK_READY, // CPU frequency restore + SLEEP_EVENT_SW_EXIT_SLEEP, // End of esp_light_sleep_start + SLEEP_EVENT_SW_GOTO_SLEEP, // Beginning of esp_light_sleep_start + SLEEP_EVENT_HW_TIME_START, // Start timing the sleep time + SLEEP_EVENT_HW_GOTO_SLEEP, // Hardware is about to power off + SLEEP_EVENT_SW_CPU_TO_MEM_START, // CPU registers are starting to be saved + SLEEP_EVENT_SW_CPU_TO_MEM_END, // CPU registers have finished saving +#if CONFIG_IDF_TARGET_ESP32H2 + SLEEP_EVENT_HW_FLASH_BBPLL_EN_START, // Beginning of rtc_clk_bbpll_enable when using FLASH_PLL + SLEEP_EVENT_HW_FLASH_BBPLL_EN_STOP, // End of rtc_clk_bbpll_enable when using FLASH_PLL +#endif + SLEEP_EVENT_HW_BBPLL_EN_START, // Beginning of rtc_clk_bbpll_enable + SLEEP_EVENT_HW_BBPLL_EN_STOP, // End of rtc_clk_bbpll_enable + SLEEP_EVENT_CB_INDEX_NUM, +} esp_sleep_event_cb_index_t; + +/** + * @brief Function prototype for light sleep event callback functions (if CONFIG_FREERTOS_USE_TICKLESS_IDLE). + * @param user_arg is the user provided argument while registering callbacks. + * @param ext_arg is an externally provided parameter that is used when the callback is executed. + * @return None + */ + +typedef esp_err_t (*esp_sleep_event_cb_t)(void *user_arg, void *ext_arg); + +/** + * @brief Function entry parameter types for light sleep event callback functions (if CONFIG_FREERTOS_USE_TICKLESS_IDLE) + */ +struct _esp_sleep_event_cb_config_t { + /** + * Callback function defined by internal developers. + */ + esp_sleep_event_cb_t cb; + /** + * Input parameters of callback function defined by internal developers. + */ + void *user_arg; + /** + * Execution priority of callback function defined by internal developers. + * The smaller the priority, the earlier it executes when call esp_sleep_execute_event_callbacks. + * If functions have the same priority, the function registered first will be executed first. + */ + uint32_t prior; + /** + * Next callback configuration defined by internal developer. + */ + struct _esp_sleep_event_cb_config_t *next; +}; + +typedef struct _esp_sleep_event_cb_config_t esp_sleep_event_cb_config_t; + +struct _esp_sleep_event_cbs_config_t { + /** + * Callback configurations defined by internal developers. + */ + esp_sleep_event_cb_config_t *sleep_event_cb_config[SLEEP_EVENT_CB_INDEX_NUM]; +}; + +typedef struct _esp_sleep_event_cbs_config_t esp_sleep_event_cbs_config_t; + +/** + * @brief Register event callbacks for light sleep internal events (if CONFIG_FREERTOS_USE_TICKLESS_IDLE) + * @param event_id Designed to register the corresponding event_cb in g_sleep_event_cbs_config + * @param event_cb_conf Config struct containing event callback function and corresponding argument + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if the input parameter event_cb_conf is NULL or event_id is out of range + * - ESP_ERR_NO_MEM if the remaining memory is insufficient to support malloc + * - ESP_FAIL if register the same function repeatedly + * + * @note Some of these callback functions are called from IDLE task context hence they cannot call any blocking functions + * @note Passing NULL value will not deregister the callbacks, it will silently ignore and return ESP_OK + */ +esp_err_t esp_sleep_register_event_callback(esp_sleep_event_cb_index_t event_id, const esp_sleep_event_cb_config_t *event_cb_conf); + +/** + * @brief Unregister event callbacks for light sleep internal events (if CONFIG_FREERTOS_USE_TICKLESS_IDLE) + * @param event_id Designed to unregister the corresponding event_cb in g_sleep_event_cbs_config + * @param event_cb_conf Config struct containing event callback function and corresponding argument + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if the input parameter cb is NULL or event_id is out of range + */ +esp_err_t esp_sleep_unregister_event_callback(esp_sleep_event_cb_index_t event_id, esp_sleep_event_cb_t cb); + +/** + * @brief Designed to execute functions in the esp_sleep_event_cb_config_t linked list + * + * @param event_id Designed to annotate the corresponding event_cb in g_sleep_event_cbs_config + * @param ext_arg Designed to pass external parameters + * @return None + */ +void esp_sleep_execute_event_callbacks(esp_sleep_event_cb_index_t event_id, void *ext_arg); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/sleep_modem.h b/components/esp_hw_support/include/esp_private/sleep_modem.h index 2e84830b6d..7922c24fc8 100644 --- a/components/esp_hw_support/include/esp_private/sleep_modem.h +++ b/components/esp_hw_support/include/esp_private/sleep_modem.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 */ @@ -9,6 +9,7 @@ #include #include "sdkconfig.h" #include "esp_err.h" +#include "esp_sleep.h" #ifdef __cplusplus extern "C" { @@ -40,6 +41,42 @@ void mac_bb_power_up_cb_execute(void); #endif // CONFIG_MAC_BB_PD +#if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD +/** + * @brief Register sleep prepare callback for Bluetooth/IEEE802154 MAC and baseband + * + * @param pd_cb function to call when power down + * @param pu_cb function to call when power up + */ +void sleep_modem_register_mac_bb_module_prepare_callback(mac_bb_power_down_cb_t pd_cb, + mac_bb_power_up_cb_t pu_cb); + +/** + * @brief Unregister sleep prepare callback for Bluetooth/IEEE802154 MAC and baseband + * + * @param pd_cb function to call when power down + * @param pu_cb function to call when power up + */ +void sleep_modem_unregister_mac_bb_module_prepare_callback(mac_bb_power_down_cb_t pd_cb, + mac_bb_power_up_cb_t pu_cb); + +/** + * @brief MAC and baseband power up operation + * + * In light sleep mode, execute IEEE802154/Bluetooth module MAC and baseband + * power down and backup prepare operations. + */ +void sleep_modem_mac_bb_power_down_prepare(void); + +/** + * @brief MAC and baseband power up operation + * + * In light sleep mode, execute IEEE802154/Bluetooth module MAC and baseband + * power up and restore prepare operations. + */ +void sleep_modem_mac_bb_power_up_prepare(void); +#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD + #if SOC_PM_SUPPORT_PMU_MODEM_STATE /** @@ -161,6 +198,35 @@ void esp_pm_register_light_sleep_default_params_config_callback(update_light_sle */ void esp_pm_unregister_light_sleep_default_params_config_callback(void); +#if SOC_PM_SUPPORT_PMU_MODEM_STATE +/** + * @brief Init Wi-Fi modem state. + * + * This function init wifi modem state. + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM if no memory for link + */ +esp_err_t sleep_modem_wifi_modem_state_init(void); + +/** + * @brief Deinit Wi-Fi modem state. + * + * This function deinit wifi modem state. + */ +void sleep_modem_wifi_modem_state_deinit(void); + +/** + * @brief Function to check Wi-Fi modem state to skip light sleep. + * + * This function is to check if light sleep should skip by Wi-Fi modem state . + * @return + * - true skip light sleep + * - false not skip light sleep + */ +bool sleep_modem_wifi_modem_state_skip_light_sleep(void); +#endif + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/include/esp_private/sleep_retention.h b/components/esp_hw_support/include/esp_private/sleep_retention.h index e64a95a9c0..14a058b451 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,30 +23,55 @@ extern "C" { * includes sleep retention list creation, destruction and debugging interfaces. */ +typedef enum sleep_retention_module { + SLEEP_RETENTION_MODULE_MIN = 0, + /* clock module, which includes system and modem */ + SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = 1, + SLEEP_RETENTION_MODULE_CLOCK_MODEM = 2, + + /* modem module, which includes WiFi, BLE and 802.15.4 */ + SLEEP_RETENTION_MODULE_WIFI_MAC = 10, + SLEEP_RETENTION_MODULE_WIFI_BB = 11, + SLEEP_RETENTION_MODULE_BLE_MAC = 12, + SLEEP_RETENTION_MODULE_BT_BB = 13, + SLEEP_RETENTION_MODULE_802154_MAC = 14, + + /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, + * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_SYS_PERIPH = 16, + + SLEEP_RETENTION_MODULE_ADC = 17, + + SLEEP_RETENTION_MODULE_GDMA_CH0 = 24, + SLEEP_RETENTION_MODULE_GDMA_CH1 = 25, + SLEEP_RETENTION_MODULE_GDMA_CH2 = 26, + + SLEEP_RETENTION_MODULE_MAX = 31 +} sleep_retention_module_t; + typedef enum sleep_retention_module_bitmap { /* clock module, which includes system and modem */ - SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = BIT(1), - SLEEP_RETENTION_MODULE_CLOCK_MODEM = BIT(2), + SLEEP_RETENTION_MODULE_BM_CLOCK_SYSTEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM), + SLEEP_RETENTION_MODULE_BM_CLOCK_MODEM = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM), /* modem module, which includes WiFi, BLE and 802.15.4 */ - SLEEP_RETENTION_MODULE_WIFI_MAC = BIT(10), - SLEEP_RETENTION_MODULE_WIFI_BB = BIT(11), - SLEEP_RETENTION_MODULE_BLE_MAC = BIT(12), - SLEEP_RETENTION_MODULE_BT_BB = BIT(13), - SLEEP_RETENTION_MODULE_802154_MAC = BIT(14), + SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC), + SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB), + SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC), + SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB), + SLEEP_RETENTION_MODULE_BM_802154_MAC = BIT(SLEEP_RETENTION_MODULE_802154_MAC), /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_INTR_MATRIX = BIT(16), - SLEEP_RETENTION_MODULE_HP_SYSTEM = BIT(17), - SLEEP_RETENTION_MODULE_TEE_APM = BIT(18), - SLEEP_RETENTION_MODULE_UART0 = BIT(19), - SLEEP_RETENTION_MODULE_TG0 = BIT(20), - SLEEP_RETENTION_MODULE_IOMUX = BIT(21), - SLEEP_RETENTION_MODULE_SPIMEM = BIT(22), - SLEEP_RETENTION_MODULE_SYSTIMER = BIT(23), - - SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1 + SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), + + SLEEP_RETENTION_MODULE_BM_ADC = BIT(SLEEP_RETENTION_MODULE_ADC), + + SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), + SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), + SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), + + SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1 } sleep_retention_module_bitmap_t; typedef regdma_entry_buf_t sleep_retention_entries_t; @@ -56,6 +81,21 @@ typedef struct { uint32_t owner; /**< Indicates which regdma entries the current node will insert into */ } sleep_retention_entries_config_t; +typedef esp_err_t (*sleep_retention_callback_t)(void *args); + +typedef struct { + sleep_retention_callback_t handle; + void *arg; +} sleep_retention_create_callback_t; + +typedef struct { + sleep_retention_create_callback_t create; /*!< A function handle is used to register the implementation of creating a sleep retention linked list and is executed when the corresponding module is created */ +} sleep_retention_module_callbacks_t; + +typedef enum { + SLEEP_RETENTION_MODULE_ATTR_PASSIVE = 0x1 +} sleep_retention_module_attribute_t; + /** * @brief Create a runtime sleep retention linked list * @@ -63,26 +103,19 @@ typedef struct { * @param num the total number of sleep retention linked list configuration * items * @param priority the priority of the created sleep retention linked list - * @param module the bitmap of the module to which the created sleep retention + * @param module the number of the module to which the created sleep retention * linked list belongs * @return * - ESP_OK on success * - ESP_ERR_NO_MEM not enough memory for sleep retention * - ESP_ERR_INVALID_ARG if either of the arguments is out of range */ -esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module); +esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module); /** - * @brief Destroy a runtime sleep retention linked list - * - * @param module the bitmap of the module to be destroyed + * @brief Dump all runtime sleep retention linked lists */ -void sleep_retention_entries_destroy(int module); - -/** - * @brief Print all runtime sleep retention linked lists - */ -void sleep_retention_entries_show_memories(void); +void sleep_retention_dump_entries(FILE *out); /** * @brief Find the linked list node with the unique id @@ -100,31 +133,101 @@ void * sleep_retention_find_link_by_id(int id); */ void sleep_retention_entries_get(sleep_retention_entries_t *entries); -#if SOC_PM_RETENTION_HAS_CLOCK_BUG +typedef struct sleep_retention_module_init_param { + sleep_retention_module_callbacks_t cbs; /*!< The callbacks list of the initialize module */ + sleep_retention_module_attribute_t attribute; /*!< A bitmap indicating attribute of the initialize module */ + sleep_retention_module_bitmap_t depends; /*!< A bitmap identifying all modules that the current module depends on */ +} sleep_retention_module_init_param_t; + /** - * @brief Software trigger REGDMA to do extra linked list retention + * @brief sleep retention initialization for the module * - * @param backup_or_restore true for backup register context to memory - * or false for restore to register from memory + * @param module the module number that needs initialization + * @param param the initialize parameters for module sleep retention initialization + * + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM not enough memory for sleep retention + * - ESP_ERR_INVALID_ARG if either of the arguments is out of range + * - ESP_ERR_INVALID_STATE if the retention context of module already been allocated */ -void sleep_retention_do_extra_retention(bool backup_or_restore); +esp_err_t sleep_retention_module_init(sleep_retention_module_t module, sleep_retention_module_init_param_t *param); -void sleep_retention_module_deinit(void); -#endif +/** + * @brief sleep retention de-initialization for the module + * + * @param module the module number that needs de-initialization + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if either of the arguments is out of range + * - ESP_ERR_INVALID_STATE if the retention context of module already been allocated + */ +esp_err_t sleep_retention_module_deinit(sleep_retention_module_t module); + +/** + * @brief Allocate the sleep retention context for the module + * + * @param module the module number that need to allocating sleep retention context + * + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM not enough memory for sleep retention + * - ESP_ERR_INVALID_ARG if either of the arguments is out of range + * - ESP_ERR_INVALID_STATE if the module is de-initialized + * - ESP_ERR_NOT_ALLOWED if the attribute of module is set to SLEEP_RETENTION_MODULE_ATTR_PASSIVE + */ +esp_err_t sleep_retention_module_allocate(sleep_retention_module_t module); + +/** + * @brief Free the sleep retention context for the module + * + * @param module the module number that need to free sleep retention context + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if either of the arguments is out of range + * - ESP_ERR_INVALID_STATE if the module is de-initialized + * - ESP_ERR_NOT_ALLOWED if the attribute of module is set to SLEEP_RETENTION_MODULE_ATTR_PASSIVE + */ +esp_err_t sleep_retention_module_free(sleep_retention_module_t module); /** - * @brief Get all registered modules that require sleep retention + * @brief Get all initialized modules that require sleep retention * * This is an unprotected interface for getting a bitmap of all modules that * require sleep retention. * * It can only be called by the sleep procedure. * - * @return the bitmap of all modules requiring sleep retention + * @return the bitmap for all modules that require sleep retention */ -uint32_t sleep_retention_get_modules(void); +uint32_t sleep_retention_get_inited_modules(void); + +/** + * @brief Get all created modules that require sleep retention + * + * This is an unprotected interface for getting a bitmap of all modules that + * require sleep retention. + * + * It can only be called by the sleep procedure. + * + * @return the bitmap for all modules that have successfully created a sleep + * retention context + */ +uint32_t sleep_retention_get_created_modules(void); + +#if SOC_PM_RETENTION_HAS_CLOCK_BUG +/** + * @brief Software trigger REGDMA to do extra linked list retention + * + * @param backup_or_restore true for backup register context to memory + * or false for restore to register from memory + */ +void sleep_retention_do_extra_retention(bool backup_or_restore); +#endif -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA /** * @brief Software trigger REGDMA to do system linked list retention * diff --git a/components/esp_hw_support/include/esp_private/sleep_sys_periph.h b/components/esp_hw_support/include/esp_private/sleep_sys_periph.h index ee4af519ce..b66826c099 100644 --- a/components/esp_hw_support/include/esp_private/sleep_sys_periph.h +++ b/components/esp_hw_support/include/esp_private/sleep_sys_periph.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,15 +29,6 @@ extern "C" { */ bool peripheral_domain_pd_allowed(void); -/** - * @brief Digital peripheral power down initialize - * - * @return ESP_OK on success - * ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args - * No memory for the retention link - */ -void sleep_sys_periph_retention_init(void); - #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index a836a399c2..83a67eef03 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,10 +26,21 @@ typedef void (*esp_deep_sleep_cb_t)(void); /** * @brief Logic function used for EXT1 wakeup mode. */ +#if SOC_PM_SUPPORT_EXT1_WAKEUP +#if CONFIG_IDF_TARGET_ESP32 typedef enum { ESP_EXT1_WAKEUP_ALL_LOW = 0, //!< Wake the chip when all selected GPIOs go low ESP_EXT1_WAKEUP_ANY_HIGH = 1 //!< Wake the chip when any of the selected GPIOs go high } esp_sleep_ext1_wakeup_mode_t; +#else +typedef enum { + ESP_EXT1_WAKEUP_ANY_LOW = 0, //!< Wake the chip when any of the selected GPIOs go low + ESP_EXT1_WAKEUP_ANY_HIGH = 1, //!< Wake the chip when any of the selected GPIOs go high + ESP_EXT1_WAKEUP_ALL_LOW __attribute__((deprecated("wakeup mode \"ALL_LOW\" is no longer supported after ESP32, \ + please use ESP_EXT1_WAKEUP_ANY_LOW instead"))) = ESP_EXT1_WAKEUP_ANY_LOW +} esp_sleep_ext1_wakeup_mode_t; +#endif +#endif #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP typedef enum { @@ -240,7 +251,126 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level); * It will work even if RTC peripherals are shut down during sleep. * * This feature can monitor any number of pins which are in RTC IOs. - * Once any of the selected pins goes into the state given by mode argument, + * Once selected pins go into the state given by level_mode argument, + * the chip will be woken up. + * + * @note This function does not modify pin configuration. The pins are + * configured in esp_deep_sleep_start/esp_light_sleep_start, + * immediately before entering sleep mode. + * + * @note Internal pullups and pulldowns don't work when RTC peripherals are + * shut down. In this case, external resistors need to be added. + * Alternatively, RTC peripherals (and pullups/pulldowns) may be + * kept enabled using esp_sleep_pd_config function. If we turn off the + * ``RTC_PERIPH`` domain or certain chips lack the ``RTC_PERIPH`` domain, + * we will use the HOLD feature to maintain the pull-up and pull-down on + * the pins during sleep. HOLD feature will be acted on the pin internally + * before the system entering sleep, and this can further reduce power consumption. + * + * @note Call this func will reset the previous ext1 configuration. + * + * @note This function will be deprecated in release/v6.0. Please switch to use `esp_sleep_enable_ext1_wakeup_io` and `esp_sleep_disable_ext1_wakeup_io` + * + * @param io_mask Bit mask of GPIO numbers which will cause wakeup. Only GPIOs + * which have RTC functionality can be used in this bit map. + * For different SoCs, the related GPIOs are: + * - ESP32: 0, 2, 4, 12-15, 25-27, 32-39 + * - ESP32-S2: 0-21 + * - ESP32-S3: 0-21 + * - ESP32-C6: 0-7 + * - ESP32-H2: 7-14 + * @param level_mode Select logic function used to determine wakeup condition: + * When target chip is ESP32: + * - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low + * - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high + * When target chip is ESP32-S2, ESP32-S3, ESP32-C6 or ESP32-H2: + * - ESP_EXT1_WAKEUP_ANY_LOW: wake up when any of the selected GPIOs is low + * - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if io_mask is zero, + * or mode is invalid + */ +esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t io_mask, esp_sleep_ext1_wakeup_mode_t level_mode); + +/** + * @brief Enable ext1 wakeup pins with IO masks. + * + * This will append selected IOs to the wakeup IOs, it will not reset previously enabled IOs. + * To reset specific previously enabled IOs, call esp_sleep_disable_ext1_wakeup_io with the io_mask. + * To reset all the enabled IOs, call esp_sleep_disable_ext1_wakeup_io(0). + * + * This function uses external wakeup feature of RTC controller. + * It will work even if RTC peripherals are shut down during sleep. + * + * This feature can monitor any number of pins which are in RTC IOs. + * Once selected pins go into the state given by level_mode argument, + * the chip will be woken up. + * + * @note This function does not modify pin configuration. The pins are + * configured in esp_deep_sleep_start/esp_light_sleep_start, + * immediately before entering sleep mode. + * + * @note Internal pullups and pulldowns don't work when RTC peripherals are + * shut down. In this case, external resistors need to be added. + * Alternatively, RTC peripherals (and pullups/pulldowns) may be + * kept enabled using esp_sleep_pd_config function. If we turn off the + * ``RTC_PERIPH`` domain or certain chips lack the ``RTC_PERIPH`` domain, + * we will use the HOLD feature to maintain the pull-up and pull-down on + * the pins during sleep. HOLD feature will be acted on the pin internally + * before the system entering sleep, and this can further reduce power consumption. + * + * @param io_mask Bit mask of GPIO numbers which will cause wakeup. Only GPIOs + * which have RTC functionality can be used in this bit map. + * For different SoCs, the related GPIOs are: + * - ESP32: 0, 2, 4, 12-15, 25-27, 32-39 + * - ESP32-S2: 0-21 + * - ESP32-S3: 0-21 + * - ESP32-C6: 0-7 + * - ESP32-H2: 7-14 + * @param level_mode Select logic function used to determine wakeup condition: + * When target chip is ESP32: + * - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low + * - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high + * When target chip is ESP32-S2, ESP32-S3, ESP32-C6 or ESP32-H2: + * - ESP_EXT1_WAKEUP_ANY_LOW: wake up when any of the selected GPIOs is low + * - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO, + * or mode is invalid + * - ESP_ERR_NOT_SUPPORTED when wakeup level will become different between + * ext1 IOs if !SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN + */ +esp_err_t esp_sleep_enable_ext1_wakeup_io(uint64_t io_mask, esp_sleep_ext1_wakeup_mode_t level_mode); + +/** + * @brief Disable ext1 wakeup pins with IO masks. This will remove selected IOs from the wakeup IOs. + * @param io_mask Bit mask of GPIO numbers which will cause wakeup. Only GPIOs + * which have RTC functionality can be used in this bit map. + * If value is zero, this func will remove all previous ext1 configuration. + * For different SoCs, the related GPIOs are: + * - ESP32: 0, 2, 4, 12-15, 25-27, 32-39 + * - ESP32-S2: 0-21 + * - ESP32-S3: 0-21 + * - ESP32-C6: 0-7 + * - ESP32-H2: 7-14 + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO. + */ +esp_err_t esp_sleep_disable_ext1_wakeup_io(uint64_t io_mask); + +#if SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN +/** + * @brief Enable wakeup using multiple pins, allows different trigger mode per pin + * + * This function uses external wakeup feature of RTC controller. + * It will work even if RTC peripherals are shut down during sleep. + * + * This feature can monitor any number of pins which are in RTC IOs. + * Once selected pins go into the state given by level_mode argument, * the chip will be woken up. * * @note This function does not modify pin configuration. The pins are @@ -250,25 +380,29 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level); * @note Internal pullups and pulldowns don't work when RTC peripherals are * shut down. In this case, external resistors need to be added. * Alternatively, RTC peripherals (and pullups/pulldowns) may be - * kept enabled using esp_sleep_pd_config function. - * - * @param mask bit mask of GPIO numbers which will cause wakeup. Only GPIOs - * which have RTC functionality can be used in this bit map. - * For different SoCs, the related GPIOs are: - * - ESP32: 0, 2, 4, 12-15, 25-27, 32-39; - * - ESP32-S2: 0-21; - * - ESP32-S3: 0-21. - * - ESP32-C6: 0-7. - * @param mode select logic function used to determine wakeup condition: - * - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low - * - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high + * kept enabled using esp_sleep_pd_config function. If we turn off the + * ``RTC_PERIPH`` domain or certain chips lack the ``RTC_PERIPH`` domain, + * we will use the HOLD feature to maintain the pull-up and pull-down on + * the pins during sleep. HOLD feature will be acted on the pin internally + * before the system entering sleep, and this can further reduce power consumption. + * + * @param io_mask Bit mask of GPIO numbers which will cause wakeup. Only GPIOs + * which have RTC functionality can be used in this bit map. + * For different SoCs, the related GPIOs are: + * - ESP32-C6: 0-7. + * - ESP32-H2: 7-14. + * @param level_mask Select logic function used to determine wakeup condition per pin. + * Each bit of the level_mask corresponds to the respective GPIO. Each bit's corresponding + * position is set to 0, the wakeup level will be low, on the contrary, + * each bit's corresponding position is set to 1, the wakeup level will be high. * @return * - ESP_OK on success * - ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO, * or mode is invalid */ -esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode); +esp_err_t esp_sleep_enable_ext1_wakeup_with_level_mask(uint64_t io_mask, uint64_t level_mask); +#endif // SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN #endif // SOC_PM_SUPPORT_EXT1_WAKEUP #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP @@ -280,9 +414,13 @@ esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode * @note This function does not modify pin configuration. The pins are * configured inside esp_deep_sleep_start, immediately before entering sleep mode. * - * @note You don't need to care to pull-up or pull-down before using this - * function, because this will be set internally in esp_deep_sleep_start - * based on the wakeup mode. BTW, when you use low level to wake up the + * @note You don't need to worry about pull-up or pull-down resistors before + * using this function because the ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS + * option is enabled by default. It will automatically set pull-up or pull-down + * resistors internally in esp_deep_sleep_start based on the wakeup mode. However, + * when using external pull-up or pull-down resistors, please be sure to disable + * the ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS option, as the combination of internal + * and external resistors may cause interference. BTW, when you use low level to wake up the * chip, we strongly recommend you to add external resistors (pull-up). * * @param gpio_pin_mask Bit mask of GPIO numbers which will cause wakeup. Only GPIOs @@ -415,7 +553,22 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, /** * @brief Enter deep sleep with the configured wakeup options * - * This function does not return. + * @note In general, the function does not return, but if the sleep is rejected, + * then it returns from it. + * + * The reason for the rejection can be such as a short sleep time. + * + * @return + * - No return - If the sleep is not rejected. + * - ESP_ERR_SLEEP_REJECT sleep request is rejected(wakeup source set before the sleep request) + */ +esp_err_t esp_deep_sleep_try_to_start(void); + +/** + * @brief Enter deep sleep with the configured wakeup options + * + * @note The function does not do a return (no rejection). Even if wakeup source set before the sleep request + * it goes to deep sleep anyway. */ void esp_deep_sleep_start(void) __attribute__((__noreturn__)); @@ -442,9 +595,29 @@ esp_err_t esp_light_sleep_start(void); * followed by a call to esp_deep_sleep_start. * * @param time_in_us deep-sleep time, unit: microsecond + * + * @return + * - No return - If the sleep is not rejected. + * - ESP_ERR_SLEEP_REJECT sleep request is rejected(wakeup source set before the sleep request) */ -void esp_deep_sleep(uint64_t time_in_us) __attribute__((__noreturn__)); +esp_err_t esp_deep_sleep_try(uint64_t time_in_us); +/** + * @brief Enter deep-sleep mode + * + * The device will automatically wake up after the deep-sleep time + * Upon waking up, the device calls deep sleep wake stub, and then proceeds + * to load application. + * + * Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup + * followed by a call to esp_deep_sleep_start. + * + * @note The function does not do a return (no rejection).. Even if wakeup source set before the sleep request + * it goes to deep sleep anyway. + * + * @param time_in_us deep-sleep time, unit: microsecond + */ +void esp_deep_sleep(uint64_t time_in_us) __attribute__((__noreturn__)); /** * @brief Register a callback to be called from the deep sleep prepare diff --git a/components/esp_hw_support/include/soc/esp32c2/esp_crypto_lock.h b/components/esp_hw_support/include/soc/esp32c2/esp_crypto_lock.h new file mode 100644 index 0000000000..09d4f295f8 --- /dev/null +++ b/components/esp_hw_support/include/soc/esp32c2/esp_crypto_lock.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Acquire lock for the ECC cryptography peripheral. + * + */ +void esp_crypto_ecc_lock_acquire(void); + +/** + * @brief Release lock for the ECC cryptography peripheral. + * + */ +void esp_crypto_ecc_lock_release(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/soc/esp32c6/esp_crypto_lock.h b/components/esp_hw_support/include/soc/esp32c6/esp_crypto_lock.h index 67a08741b5..5b5bf54128 100644 --- a/components/esp_hw_support/include/soc/esp32c6/esp_crypto_lock.h +++ b/components/esp_hw_support/include/soc/esp32c6/esp_crypto_lock.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 */ @@ -63,6 +63,18 @@ void esp_crypto_mpi_lock_acquire(void); */ void esp_crypto_mpi_lock_release(void); +/** + * @brief Acquire lock for the ECC cryptography peripheral. + * + */ +void esp_crypto_ecc_lock_acquire(void); + +/** + * @brief Release lock for the ECC cryptography peripheral. + * + */ +void esp_crypto_ecc_lock_release(void); + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/include/soc/esp32h2/esp_crypto_lock.h b/components/esp_hw_support/include/soc/esp32h2/esp_crypto_lock.h index c768bd7377..6855caae23 100644 --- a/components/esp_hw_support/include/soc/esp32h2/esp_crypto_lock.h +++ b/components/esp_hw_support/include/soc/esp32h2/esp_crypto_lock.h @@ -63,6 +63,34 @@ void esp_crypto_mpi_lock_acquire(void); */ void esp_crypto_mpi_lock_release(void); + +/** + * @brief Acquire lock for the ECC cryptography peripheral. + * + */ +void esp_crypto_ecc_lock_acquire(void); + +/** + * @brief Release lock for the ECC cryptography peripheral. + * + */ +void esp_crypto_ecc_lock_release(void); + + +/** + * @brief Acquire lock for ECDSA cryptography peripheral + * + * Internally also locks the ECC and MPI peripheral, as the ECDSA depends on these peripherals + */ +void esp_crypto_ecdsa_lock_acquire(void); + +/** + * @brief Release lock for ECDSA cryptography peripheral + * + * Internally also releases the ECC and MPI peripheral, as the ECDSA depends on these peripherals + */ +void esp_crypto_ecdsa_lock_release(void); + #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/intr_alloc.c b/components/esp_hw_support/intr_alloc.c index 40434232ed..3ca66375bb 100644 --- a/components/esp_hw_support/intr_alloc.c +++ b/components/esp_hw_support/intr_alloc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -90,6 +90,8 @@ struct non_shared_isr_arg_t { int source; }; +static esp_err_t intr_free_for_current_cpu(intr_handle_t handle); + //Linked list of vector descriptions, sorted by cpu.intno value static vector_desc_t *vector_desc_head = NULL; @@ -257,7 +259,7 @@ static bool is_vect_desc_usable(vector_desc_t *vd, int flags, int cpu, int force } //check if edge/level type matches what we want if (((flags & ESP_INTR_FLAG_EDGE) && (intr_desc.type == ESP_CPU_INTR_TYPE_LEVEL)) || - (((!(flags & ESP_INTR_FLAG_EDGE)) && (intr_desc.type == ESP_CPU_INTR_TYPE_EDGE)))) { + (((!(flags & ESP_INTR_FLAG_EDGE)) && (intr_desc.type == ESP_CPU_INTR_TYPE_EDGE)))) { ALCHLOG("....Unusable: incompatible trigger type"); return false; } @@ -364,8 +366,8 @@ static int get_available_int(int flags, int cpu, int force, int source) esp_cpu_intr_get_desc(cpu, x, &intr_desc); ALCHLOG("Int %d reserved %d priority %d %s hasIsr %d", - x, intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_RESVD, intr_desc.priority, - intr_desc.type == ESP_CPU_INTR_TYPE_LEVEL? "LEVEL" : "EDGE", esp_cpu_intr_has_handler(x)); + x, intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_RESVD, intr_desc.priority, + intr_desc.type == ESP_CPU_INTR_TYPE_LEVEL? "LEVEL" : "EDGE", esp_cpu_intr_has_handler(x)); if (!is_vect_desc_usable(vd, flags, cpu, force)) { continue; @@ -465,7 +467,7 @@ static void IRAM_ATTR non_shared_intr_isr(void *arg) //We use ESP_EARLY_LOG* here because this can be called before the scheduler is running. esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusreg, uint32_t intrstatusmask, intr_handler_t handler, - void *arg, intr_handle_t *ret_handle) + void *arg, intr_handle_t *ret_handle) { intr_handle_data_t *ret=NULL; int force = -1; @@ -552,7 +554,7 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre //Allocate that int! if (flags & ESP_INTR_FLAG_SHARED) { //Populate vector entry and add to linked list. - shared_vector_desc_t *sh_vec=malloc(sizeof(shared_vector_desc_t)); + shared_vector_desc_t *sh_vec = heap_caps_malloc(sizeof(shared_vector_desc_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); if (sh_vec == NULL) { portEXIT_CRITICAL(&spinlock); free(ret); @@ -575,7 +577,7 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre vd->flags = VECDESC_FL_NONSHARED; if (handler) { #if CONFIG_APPTRACE_SV_ENABLE - non_shared_isr_arg_t *ns_isr_arg=malloc(sizeof(non_shared_isr_arg_t)); + non_shared_isr_arg_t *ns_isr_arg = heap_caps_malloc(sizeof(non_shared_isr_arg_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); if (!ns_isr_arg) { portEXIT_CRITICAL(&spinlock); free(ret); @@ -620,7 +622,7 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre esp_intr_disable(ret); } -#ifdef SOC_CPU_HAS_FLEXIBLE_INTC +#if SOC_CPU_HAS_FLEXIBLE_INTC //Extract the level from the interrupt passed flags int level = esp_intr_flags_to_level(flags); esp_cpu_intr_set_priority(intr, level); @@ -632,6 +634,11 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre } #endif +#if SOC_INT_PLIC_SUPPORTED + /* Make sure the interrupt is not delegated to user mode (IDF uses machine mode only) */ + RV_CLEAR_CSR(mideleg, BIT(intr)); +#endif + portEXIT_CRITICAL(&spinlock); //Fill return handle if needed, otherwise free handle. @@ -662,7 +669,7 @@ esp_err_t IRAM_ATTR esp_intr_set_in_iram(intr_handle_t handle, bool is_in_iram) } vector_desc_t *vd = handle->vector_desc; if (vd->flags & VECDESC_FL_SHARED) { - return ESP_ERR_INVALID_ARG; + return ESP_ERR_INVALID_ARG; } portENTER_CRITICAL(&spinlock); uint32_t mask = (1 << vd->intno); @@ -678,27 +685,45 @@ esp_err_t IRAM_ATTR esp_intr_set_in_iram(intr_handle_t handle, bool is_in_iram) } #if !CONFIG_FREERTOS_UNICORE -static void esp_intr_free_cb(void *arg) +static void intr_free_for_other_cpu(void *arg) { - (void)esp_intr_free((intr_handle_t)arg); + (void)intr_free_for_current_cpu((intr_handle_t)arg); } #endif /* !CONFIG_FREERTOS_UNICORE */ esp_err_t esp_intr_free(intr_handle_t handle) { - bool free_shared_vector=false; if (!handle) { return ESP_ERR_INVALID_ARG; } #if !CONFIG_FREERTOS_UNICORE //Assign this routine to the core where this interrupt is allocated on. - if (handle->vector_desc->cpu != esp_cpu_get_core_id()) { - esp_err_t ret = esp_ipc_call_blocking(handle->vector_desc->cpu, &esp_intr_free_cb, (void *)handle); + + bool task_can_be_run_on_any_core; +#if CONFIG_FREERTOS_SMP + UBaseType_t core_affinity = vTaskCoreAffinityGet(NULL); + task_can_be_run_on_any_core = (__builtin_popcount(core_affinity) > 1); +#else + UBaseType_t core_affinity = xTaskGetAffinity(NULL); + task_can_be_run_on_any_core = (core_affinity == tskNO_AFFINITY); +#endif + + if (task_can_be_run_on_any_core || handle->vector_desc->cpu != esp_cpu_get_core_id()) { + // If the task can be run on any core then we can not rely on the current CPU id (in case if task switching occurs). + // It is safer to call intr_free_for_current_cpu() from a pinned to a certain CPU task. It is done through the IPC call. + esp_err_t ret = esp_ipc_call_blocking(handle->vector_desc->cpu, &intr_free_for_other_cpu, (void *)handle); return ret == ESP_OK ? ESP_OK : ESP_FAIL; } #endif /* !CONFIG_FREERTOS_UNICORE */ + return intr_free_for_current_cpu(handle); +} + +static esp_err_t intr_free_for_current_cpu(intr_handle_t handle) +{ + bool free_shared_vector = false; + portENTER_CRITICAL(&spinlock); esp_intr_disable(handle); if (handle->vector_desc->flags & VECDESC_FL_SHARED) { diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 744de22edc..b75aa54a47 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -23,6 +23,8 @@ entries: rtc_time (noflash_text) if SOC_PMU_SUPPORTED = y: pmu_sleep (noflash) + if SOC_USB_SERIAL_JTAG_SUPPORTED = y: + sleep_console (noflash) if PM_SLP_IRAM_OPT = y && IDF_TARGET_ESP32 = n: sleep_modem:periph_inform_out_light_sleep_overhead (noflash) if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y: diff --git a/components/esp_hw_support/mac_addr.c b/components/esp_hw_support/mac_addr.c index 838d9948a1..3def09c287 100644 --- a/components/esp_hw_support/mac_addr.c +++ b/components/esp_hw_support/mac_addr.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 */ @@ -63,7 +63,7 @@ static mac_t s_mac_table[] = { #define ITEMS_IN_MAC_TABLE (sizeof(s_mac_table) / sizeof(mac_t)) static esp_err_t generate_mac(uint8_t *mac, uint8_t *base_mac_addr, esp_mac_type_t type); -static esp_err_t get_efuse_mac_get_default(uint8_t *mac); +static esp_err_t get_efuse_factory_mac(uint8_t *mac); static esp_err_t get_efuse_mac_custom(uint8_t *mac); #if CONFIG_SOC_IEEE802154_SUPPORTED static esp_err_t get_efuse_mac_ext(uint8_t *mac); @@ -89,11 +89,19 @@ static esp_err_t get_mac_addr_from_mac_table(uint8_t *mac, int idx, bool silent) esp_mac_type_t type = s_mac_table[idx].type; if (ESP_MAC_BASE <= type && type <= ESP_MAC_EFUSE_EXT) { esp_err_t err = ESP_OK; - if (type == ESP_MAC_BASE || type == ESP_MAC_EFUSE_FACTORY) { - err = get_efuse_mac_get_default(s_mac_table[idx].mac); - } else if (type == ESP_MAC_EFUSE_CUSTOM) { - err = get_efuse_mac_custom(s_mac_table[idx].mac); - } + if (type == ESP_MAC_EFUSE_FACTORY +#ifndef CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC + || type == ESP_MAC_BASE +#endif + ) { + err = get_efuse_factory_mac(s_mac_table[idx].mac); + } else if (type == ESP_MAC_EFUSE_CUSTOM +#ifdef CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC + || type == ESP_MAC_BASE +#endif + ) { + err = get_efuse_mac_custom(s_mac_table[idx].mac); + } #if CONFIG_SOC_IEEE802154_SUPPORTED else if (type == ESP_MAC_EFUSE_EXT) { err = get_efuse_mac_ext(s_mac_table[idx].mac); @@ -246,7 +254,7 @@ static esp_err_t get_efuse_mac_custom(uint8_t *mac) esp_err_t esp_efuse_mac_get_default(uint8_t *mac) { - esp_err_t err = get_efuse_mac_get_default(mac); + esp_err_t err = get_efuse_factory_mac(mac); if (err != ESP_OK) { return err; } @@ -257,7 +265,7 @@ esp_err_t esp_efuse_mac_get_default(uint8_t *mac) #endif } -static esp_err_t get_efuse_mac_get_default(uint8_t *mac) +static esp_err_t get_efuse_factory_mac(uint8_t *mac) { size_t size_bits = esp_efuse_get_field_size(ESP_EFUSE_MAC_FACTORY); assert((size_bits % 8) == 0); diff --git a/components/esp_hw_support/modem_clock.c b/components/esp_hw_support/modem_clock.c index 715a8ac211..fb21ea0126 100644 --- a/components/esp_hw_support/modem_clock.c +++ b/components/esp_hw_support/modem_clock.c @@ -17,11 +17,13 @@ #include "esp_private/esp_pmu.h" #include "esp_sleep.h" #include "hal/efuse_hal.h" +#include "hal/clk_tree_ll.h" // Please define the frequently called modules in the low bit, // which will improve the execution efficiency typedef enum { - MODEM_CLOCK_FE, + MODEM_CLOCK_MODEM_ADC_COMMON_FE, + MODEM_CLOCK_MODEM_PRIVATE_FE, MODEM_CLOCK_COEXIST, MODEM_CLOCK_I2C_MASTER, #if SOC_WIFI_SUPPORTED @@ -74,7 +76,6 @@ static void IRAM_ATTR modem_clock_wifi_bb_configure(modem_clock_context_t *ctx, #if SOC_BT_SUPPORTED static void IRAM_ATTR modem_clock_ble_mac_configure(modem_clock_context_t *ctx, bool enable) { - modem_syscon_ll_enable_etm_clock(ctx->hal->syscon_dev, enable); modem_syscon_ll_enable_modem_sec_clock(ctx->hal->syscon_dev, enable); modem_syscon_ll_enable_ble_timer_clock(ctx->hal->syscon_dev, enable); } @@ -90,7 +91,6 @@ static void IRAM_ATTR modem_clock_ble_bb_configure(modem_clock_context_t *ctx, b #if SOC_IEEE802154_SUPPORTED static void IRAM_ATTR modem_clock_ieee802154_mac_configure(modem_clock_context_t *ctx, bool enable) { - modem_syscon_ll_enable_etm_clock(ctx->hal->syscon_dev, enable); modem_syscon_ll_enable_ieee802154_apb_clock(ctx->hal->syscon_dev, enable); modem_syscon_ll_enable_ieee802154_mac_clock(ctx->hal->syscon_dev, enable); } @@ -101,9 +101,14 @@ static void IRAM_ATTR modem_clock_coex_configure(modem_clock_context_t *ctx, boo modem_lpcon_ll_enable_coex_clock(ctx->hal->lpcon_dev, enable); } -static void IRAM_ATTR modem_clock_fe_configure(modem_clock_context_t *ctx, bool enable) +static void IRAM_ATTR modem_clock_modem_adc_common_fe_configure(modem_clock_context_t *ctx, bool enable) +{ + modem_clock_hal_enable_modem_adc_common_fe_clock(ctx->hal, enable); +} + +static void IRAM_ATTR modem_clock_modem_private_fe_configure(modem_clock_context_t *ctx, bool enable) { - modem_clock_hal_enable_fe_clock(ctx->hal, enable); + modem_clock_hal_enable_modem_private_fe_clock(ctx->hal, enable); } static void IRAM_ATTR modem_clock_i2c_master_configure(modem_clock_context_t *ctx, bool enable) @@ -129,22 +134,23 @@ modem_clock_context_t * __attribute__((weak)) IRAM_ATTR MODEM_CLOCK_instance(voi static DRAM_ATTR modem_clock_context_t modem_clock_context = { .hal = &modem_clock_hal, .lock = portMUX_INITIALIZER_UNLOCKED, .dev = { - [MODEM_CLOCK_FE] = { .refs = 0, .configure = modem_clock_fe_configure }, - [MODEM_CLOCK_COEXIST] = { .refs = 0, .configure = modem_clock_coex_configure }, - [MODEM_CLOCK_I2C_MASTER] = { .refs = 0, .configure = modem_clock_i2c_master_configure }, + [MODEM_CLOCK_MODEM_ADC_COMMON_FE] = { .refs = 0, .configure = modem_clock_modem_adc_common_fe_configure }, + [MODEM_CLOCK_MODEM_PRIVATE_FE] = { .refs = 0, .configure = modem_clock_modem_private_fe_configure }, + [MODEM_CLOCK_COEXIST] = { .refs = 0, .configure = modem_clock_coex_configure }, + [MODEM_CLOCK_I2C_MASTER] = { .refs = 0, .configure = modem_clock_i2c_master_configure }, #if SOC_WIFI_SUPPORTED - [MODEM_CLOCK_WIFI_MAC] = { .refs = 0, .configure = modem_clock_wifi_mac_configure }, - [MODEM_CLOCK_WIFI_BB] = { .refs = 0, .configure = modem_clock_wifi_bb_configure }, + [MODEM_CLOCK_WIFI_MAC] = { .refs = 0, .configure = modem_clock_wifi_mac_configure }, + [MODEM_CLOCK_WIFI_BB] = { .refs = 0, .configure = modem_clock_wifi_bb_configure }, #endif - [MODEM_CLOCK_ETM] = { .refs = 0, .configure = modem_clock_etm_configure }, + [MODEM_CLOCK_ETM] = { .refs = 0, .configure = modem_clock_etm_configure }, #if SOC_BT_SUPPORTED - [MODEM_CLOCK_BLE_MAC] = { .refs = 0, .configure = modem_clock_ble_mac_configure }, - [MODEM_CLOCK_BLE_BB] = { .refs = 0, .configure = modem_clock_ble_bb_configure }, + [MODEM_CLOCK_BLE_MAC] = { .refs = 0, .configure = modem_clock_ble_mac_configure }, + [MODEM_CLOCK_BLE_BB] = { .refs = 0, .configure = modem_clock_ble_bb_configure }, #endif #if SOC_IEEE802154_SUPPORTED - [MODEM_CLOCK_802154_MAC] = { .refs = 0, .configure = modem_clock_ieee802154_mac_configure }, + [MODEM_CLOCK_802154_MAC] = { .refs = 0, .configure = modem_clock_ieee802154_mac_configure }, #endif - [MODEM_CLOCK_DATADUMP] = { .refs = 0, .configure = modem_clock_data_dump_configure } + [MODEM_CLOCK_DATADUMP] = { .refs = 0, .configure = modem_clock_data_dump_configure } }, .lpclk_src = { [0 ... PERIPH_MODEM_MODULE_NUM - 1] = MODEM_CLOCK_LPCLK_SRC_INVALID } }; @@ -152,36 +158,6 @@ modem_clock_context_t * __attribute__((weak)) IRAM_ATTR MODEM_CLOCK_instance(voi } #if SOC_PM_SUPPORT_PMU_MODEM_STATE -static void IRAM_ATTR modem_clock_domain_power_state_icg_map_init(modem_clock_context_t *ctx) -{ - #define ICG_NOGATING_SLEEP (BIT(PMU_HP_ICG_MODEM_CODE_SLEEP)) - #define ICG_NOGATING_MODEM (BIT(PMU_HP_ICG_MODEM_CODE_MODEM)) - #define ICG_NOGATING_ACTIVE (BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE)) - - /* the ICG code's bit 0, 1 and 2 indicates the ICG state - * of pmu SLEEP, MODEM and ACTIVE mode respectively */ - const uint32_t code[MODEM_CLOCK_DOMAIN_MAX] = { - [MODEM_CLOCK_DOMAIN_MODEM_APB] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, - [MODEM_CLOCK_DOMAIN_MODEM_PERIPH] = ICG_NOGATING_ACTIVE, - [MODEM_CLOCK_DOMAIN_WIFI] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, - [MODEM_CLOCK_DOMAIN_BT] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, - [MODEM_CLOCK_DOMAIN_FE] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, - [MODEM_CLOCK_DOMAIN_IEEE802154] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, - [MODEM_CLOCK_DOMAIN_LP_APB] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, - [MODEM_CLOCK_DOMAIN_I2C_MASTER] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, - [MODEM_CLOCK_DOMAIN_COEX] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, - [MODEM_CLOCK_DOMAIN_WIFIPWR] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, - }; - for (modem_clock_domain_t domain = MODEM_CLOCK_DOMAIN_MODEM_APB; domain < MODEM_CLOCK_DOMAIN_MAX; domain++) { - modem_clock_hal_set_clock_domain_icg_bitmap(ctx->hal, domain, code[domain]); - } -} - -void modem_clock_domain_pmu_state_icg_map_init(void) -{ - modem_clock_domain_power_state_icg_map_init(MODEM_CLOCK_instance()); -} - esp_err_t modem_clock_domain_clk_gate_enable(modem_clock_domain_t domain, pmu_hp_icg_modem_mode_t mode) { if (domain >= MODEM_CLOCK_DOMAIN_MAX || domain < MODEM_CLOCK_DOMAIN_MODEM_APB) { @@ -277,32 +253,80 @@ void IRAM_ATTR modem_clock_module_mac_reset(periph_module_t module) portEXIT_CRITICAL_SAFE(&ctx->lock); } -#define WIFI_CLOCK_DEPS (BIT(MODEM_CLOCK_WIFI_MAC) | BIT(MODEM_CLOCK_FE) | BIT(MODEM_CLOCK_WIFI_BB) | BIT(MODEM_CLOCK_COEXIST)) -#define BLE_CLOCK_DEPS (BIT(MODEM_CLOCK_BLE_MAC) | BIT(MODEM_CLOCK_FE) | BIT(MODEM_CLOCK_BLE_BB) | BIT(MODEM_CLOCK_ETM) | BIT(MODEM_CLOCK_COEXIST)) -#define IEEE802154_CLOCK_DEPS (BIT(MODEM_CLOCK_802154_MAC) | BIT(MODEM_CLOCK_FE) | BIT(MODEM_CLOCK_BLE_BB) | BIT(MODEM_CLOCK_ETM) | BIT(MODEM_CLOCK_COEXIST)) -#define COEXIST_CLOCK_DEPS (BIT(MODEM_CLOCK_COEXIST)) -#define PHY_CLOCK_DEPS (BIT(MODEM_CLOCK_I2C_MASTER) | BIT(MODEM_CLOCK_FE)) +#define WIFI_CLOCK_DEPS (BIT(MODEM_CLOCK_WIFI_MAC) | BIT(MODEM_CLOCK_WIFI_BB) | BIT(MODEM_CLOCK_COEXIST)) +#define BLE_CLOCK_DEPS (BIT(MODEM_CLOCK_BLE_MAC) | BIT(MODEM_CLOCK_BLE_BB) | BIT(MODEM_CLOCK_ETM) | BIT(MODEM_CLOCK_COEXIST)) +#define IEEE802154_CLOCK_DEPS (BIT(MODEM_CLOCK_802154_MAC) | BIT(MODEM_CLOCK_BLE_BB) | BIT(MODEM_CLOCK_ETM) | BIT(MODEM_CLOCK_COEXIST)) +#define COEXIST_CLOCK_DEPS (BIT(MODEM_CLOCK_COEXIST)) +#define PHY_CLOCK_DEPS (BIT(MODEM_CLOCK_I2C_MASTER) | BIT(MODEM_CLOCK_MODEM_ADC_COMMON_FE) | BIT(MODEM_CLOCK_MODEM_PRIVATE_FE)) +#define I2C_ANA_MST_CLOCK_DEPS (BIT(MODEM_CLOCK_I2C_MASTER)) +#define MODEM_ETM_CLOCK_DEPS (BIT(MODEM_CLOCK_ETM)) +#define MODEM_ADC_COMMON_FE_CLOCK_DEPS (BIT(MODEM_CLOCK_MODEM_ADC_COMMON_FE)) -static inline uint32_t modem_clock_get_module_deps(periph_module_t module) +static IRAM_ATTR uint32_t modem_clock_get_module_deps(periph_module_t module) { uint32_t deps = 0; - if (module == PERIPH_PHY_MODULE) {deps = PHY_CLOCK_DEPS;} - else if (module == PERIPH_COEX_MODULE) { deps = COEXIST_CLOCK_DEPS; } + switch (module) { + case PERIPH_ANA_I2C_MASTER_MODULE: deps = I2C_ANA_MST_CLOCK_DEPS; break; + case PERIPH_PHY_MODULE: deps = PHY_CLOCK_DEPS; break; + case PERIPH_MODEM_ADC_COMMON_FE_MODULE: deps = MODEM_ADC_COMMON_FE_CLOCK_DEPS; break; +#if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED + case PERIPH_COEX_MODULE: deps = COEXIST_CLOCK_DEPS; break; +#endif #if SOC_WIFI_SUPPORTED - else if (module == PERIPH_WIFI_MODULE) { deps = WIFI_CLOCK_DEPS; } + case PERIPH_WIFI_MODULE: deps = WIFI_CLOCK_DEPS; break; #endif #if SOC_BT_SUPPORTED - else if (module == PERIPH_BT_MODULE) { deps = BLE_CLOCK_DEPS; } + case PERIPH_BT_MODULE: deps = BLE_CLOCK_DEPS; break; #endif #if SOC_IEEE802154_SUPPORTED - else if (module == PERIPH_IEEE802154_MODULE) { deps = IEEE802154_CLOCK_DEPS; } + case PERIPH_IEEE802154_MODULE: deps = IEEE802154_CLOCK_DEPS; break; +#endif +#if SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED + case PERIPH_MODEM_ETM_MODULE: deps = MODEM_ETM_CLOCK_DEPS; break; #endif + default: + assert(0); + } return deps; } +#if SOC_PM_SUPPORT_PMU_MODEM_STATE +/* the ICG code's bit 0, 1 and 2 indicates the ICG state + * of pmu SLEEP, MODEM and ACTIVE mode respectively */ +#define ICG_NOGATING_SLEEP (BIT(PMU_HP_ICG_MODEM_CODE_SLEEP)) +#define ICG_NOGATING_MODEM (BIT(PMU_HP_ICG_MODEM_CODE_MODEM)) +#define ICG_NOGATING_ACTIVE (BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE)) + +static const DRAM_ATTR uint32_t initial_gating_mode[MODEM_CLOCK_DOMAIN_MAX] = { + [MODEM_CLOCK_DOMAIN_MODEM_APB] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_MODEM_PERIPH] = ICG_NOGATING_ACTIVE, + [MODEM_CLOCK_DOMAIN_WIFI] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_BT] = ICG_NOGATING_ACTIVE, + [MODEM_CLOCK_DOMAIN_MODEM_FE] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_IEEE802154] = ICG_NOGATING_ACTIVE, + [MODEM_CLOCK_DOMAIN_LP_APB] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_I2C_MASTER] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_COEX] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_WIFIPWR] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, +}; + +static IRAM_ATTR void modem_clock_module_icg_map_init_all(void) +{ + portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); + for (int domain = 0; domain < MODEM_CLOCK_DOMAIN_MAX; domain++) { + uint32_t code = modem_clock_hal_get_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain); + modem_clock_hal_set_clock_domain_icg_bitmap(MODEM_CLOCK_instance()->hal, domain, initial_gating_mode[domain] | code); + } + portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock); +} +#endif // SOC_PM_SUPPORT_PMU_MODEM_STATE + void IRAM_ATTR modem_clock_module_enable(periph_module_t module) { assert(IS_MODEM_MODULE(module)); +#if SOC_PM_SUPPORT_PMU_MODEM_STATE + modem_clock_module_icg_map_init_all(); +#endif uint32_t deps = modem_clock_get_module_deps(module); modem_clock_device_enable(MODEM_CLOCK_instance(), deps); } @@ -331,17 +355,36 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl #if SOC_BT_SUPPORTED case PERIPH_BT_MODULE: +#if CONFIG_IDF_TARGET_ESP32H2 + bool rc_clk_en = true; + bool selected = (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) || + (src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW); + if (selected) { + rc_clk_en = clk_ll_rc32k_is_enabled(); + if (!rc_clk_en) { + clk_ll_rc32k_enable(); + } + modem_clock_hal_select_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal, MODEM_CLOCK_LPCLK_SRC_RC32K); + } +#endif // CONFIG_IDF_TARGET_ESP32H2 modem_clock_hal_deselect_all_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal); modem_clock_hal_select_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal, src); modem_clock_hal_set_ble_rtc_timer_divisor_value(MODEM_CLOCK_instance()->hal, divider); modem_clock_hal_enable_ble_rtc_timer_clock(MODEM_CLOCK_instance()->hal, true); +#if CONFIG_IDF_TARGET_ESP32H2 + if (!rc_clk_en) { + extern void r_esp_ble_rtc_ticks_delay(uint32_t ticks); + r_esp_ble_rtc_ticks_delay(2); + clk_ll_rc32k_disable(); + } +#endif // CONFIG_IDF_TARGET_ESP32H2 #if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND if (efuse_hal_chip_revision() != 0) { if (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { pmu_sleep_enable_hp_sleep_sysclk(true); + modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, true); + modem_clock_domain_clk_gate_disable(MODEM_CLOCK_DOMAIN_WIFIPWR, PMU_HP_ICG_MODEM_CODE_SLEEP); } - modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, true); - modem_clock_domain_clk_gate_disable(MODEM_CLOCK_DOMAIN_WIFIPWR, PMU_HP_ICG_MODEM_CODE_SLEEP); } #endif break; @@ -401,9 +444,9 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module) if (efuse_hal_chip_revision() != 0) { if (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { pmu_sleep_enable_hp_sleep_sysclk(false); + modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, false); + modem_clock_domain_clk_gate_enable(MODEM_CLOCK_DOMAIN_WIFIPWR, PMU_HP_ICG_MODEM_CODE_SLEEP); } - modem_clock_hal_enable_wifipwr_clock(MODEM_CLOCK_instance()->hal, false); - modem_clock_domain_clk_gate_enable(MODEM_CLOCK_DOMAIN_WIFI, PMU_HP_ICG_MODEM_CODE_SLEEP); } #endif break; diff --git a/components/esp_hw_support/mspi_timing_tuning.c b/components/esp_hw_support/mspi_timing_tuning.c index 30b538140f..d736662107 100644 --- a/components/esp_hw_support/mspi_timing_tuning.c +++ b/components/esp_hw_support/mspi_timing_tuning.c @@ -180,14 +180,21 @@ static bool get_working_pll_freq(const uint8_t *reference_data, bool is_flash, u uint32_t min_freq = big_num; rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); - //BBPLL CALIBRATION START - regi2c_ctrl_ll_bbpll_calibration_start(); for (int pll_mhz_tuning = MSPI_TIMING_PLL_FREQ_SCAN_RANGE_MHZ_MIN; pll_mhz_tuning <= MSPI_TIMING_PLL_FREQ_SCAN_RANGE_MHZ_MAX; pll_mhz_tuning += 8) { + //bbpll calibration start + regi2c_ctrl_ll_bbpll_calibration_start(); + /** * pll_mhz = xtal_mhz * (oc_div + 4) / (oc_ref_div + 1) */ clk_ll_bbpll_set_frequency_for_mspi_tuning(xtal_freq, pll_mhz_tuning, ((pll_mhz_tuning / 4) - 4), 9); + //wait calibration done + while(!regi2c_ctrl_ll_bbpll_calibration_is_done()); + + //bbpll calibration stop + regi2c_ctrl_ll_bbpll_calibration_stop(); + memset(read_data, 0, MSPI_TIMING_TEST_DATA_LEN); if (is_flash) { mspi_timing_config_flash_read_data(read_data, MSPI_TIMING_FLASH_TEST_DATA_ADDR, MSPI_TIMING_TEST_DATA_LEN); @@ -213,12 +220,13 @@ static bool get_working_pll_freq(const uint8_t *reference_data, bool is_flash, u //restore PLL config clk_ll_bbpll_set_freq_mhz(previous_config.source_freq_mhz); + //bbpll calibration start + regi2c_ctrl_ll_bbpll_calibration_start(); + //set pll clk_ll_bbpll_set_config(previous_config.source_freq_mhz, xtal_freq); - - //WAIT CALIBRATION DONE + //wait calibration done while(!regi2c_ctrl_ll_bbpll_calibration_is_done()); - - //BBPLL CALIBRATION STOP + //bbpll calibration stop regi2c_ctrl_ll_bbpll_calibration_stop(); @@ -300,8 +308,6 @@ static uint32_t select_best_tuning_config_dtr(mspi_timing_config_t *config, uint static uint32_t select_best_tuning_config_str(mspi_timing_config_t *config, uint32_t consecutive_length, uint32_t end) { #if (MSPI_TIMING_CORE_CLOCK_MHZ == 120 || MSPI_TIMING_CORE_CLOCK_MHZ == 240) - ESP_EARLY_LOGW("FLASH/PSRAM", "DO NOT USE FOR MASS PRODUCTION! Timing parameters may be updated in future IDF version."); - //STR best point scheme uint32_t best_point; diff --git a/components/esp_hw_support/periph_ctrl.c b/components/esp_hw_support/periph_ctrl.c index ecdde6f3df..ef76e860fd 100644 --- a/components/esp_hw_support/periph_ctrl.c +++ b/components/esp_hw_support/periph_ctrl.c @@ -59,7 +59,7 @@ IRAM_ATTR void wifi_bt_common_module_enable(void) #else ENTER_CRITICAL_SECTION(); if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) { - periph_ll_wifi_bt_module_enable_clk_clear_rst(); + periph_ll_wifi_bt_module_enable_clk(); } ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]++; LEAVE_CRITICAL_SECTION(); @@ -74,7 +74,7 @@ IRAM_ATTR void wifi_bt_common_module_disable(void) ENTER_CRITICAL_SECTION(); ref_counts[PERIPH_WIFI_BT_COMMON_MODULE]--; if (ref_counts[PERIPH_WIFI_BT_COMMON_MODULE] == 0) { - periph_ll_wifi_bt_module_disable_clk_set_rst(); + periph_ll_wifi_bt_module_disable_clk(); } LEAVE_CRITICAL_SECTION(); #endif diff --git a/components/esp_hw_support/port/esp32/CMakeLists.txt b/components/esp_hw_support/port/esp32/CMakeLists.txt index 81d3206176..5e69eaaa5d 100644 --- a/components/esp_hw_support/port/esp32/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32/CMakeLists.txt @@ -1,5 +1,4 @@ target_include_directories(${COMPONENT_LIB} PUBLIC .) -target_include_directories(${COMPONENT_LIB} PUBLIC private_include) set(srcs "rtc_clk.c" diff --git a/components/esp_hw_support/port/esp32/esp_cpu_intr.c b/components/esp_hw_support/port/esp32/esp_cpu_intr.c new file mode 100644 index 0000000000..5ac8c8f704 --- /dev/null +++ b/components/esp_hw_support/port/esp32/esp_cpu_intr.c @@ -0,0 +1,207 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#include "soc/soc_caps.h" +#include "esp_cpu.h" + +/* Xtensa core has 3 interrupts dedicated to timers, we can use either timer0 or timer1 depending on the Kconfig, + * timer2 is always set to SPECIAL in our configuration array */ + +/** + * @brief Type defined for the table below + */ +typedef struct { + int priority; + esp_cpu_intr_type_t type; + uint32_t flags[SOC_CPU_CORES_NUM]; +} intr_desc_t; + + +/** + * @brief Reserve interrupt 5 or 25 for Bluetooth BR/EDR and BLE controller. + */ +#if CONFIG_BTDM_CTRL_HLI + #define STATE_INTERRUPT_5 0 + #define STATE_INTERRUPT_25 ESP_CPU_INTR_DESC_FLAG_RESVD +#else // !CONFIG_BTDM_CTRL_HLI + #define STATE_INTERRUPT_5 ESP_CPU_INTR_DESC_FLAG_RESVD + #define STATE_INTERRUPT_25 0 +#endif // CONFIG_BTDM_CTRL_HLI + + +/** + * @brief Interrupt 1 is used by UART HCI, regardless of High-Level Interrupt (HLI) configuration + */ +#if CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 + #define STATE_INTERRUPT_1 ESP_CPU_INTR_DESC_FLAG_RESVD + /* Interrupt 7 being a software interrupt, it is marked as "special" if not used */ + #define STATE_INTERRUPT_7 ESP_CPU_INTR_DESC_FLAG_SPECIAL +#else // !BTDM_CTRL_HCI_MODE_UART_H4 + #define STATE_INTERRUPT_1 0 + #define STATE_INTERRUPT_7 ESP_CPU_INTR_DESC_FLAG_RESVD +#endif // BTDM_CTRL_HCI_MODE_UART_H4 + + +/** + * @brief Reserve the interrupts on the core where Bluetooth will run. + * The macro CONFIG_BTDM_CTRL_PINNED_TO_CORE is only defined if Bluetooth controller is enabled. + * It is set to the core where it will run. + */ +#ifdef CONFIG_BTDM_CTRL_PINNED_TO_CORE + #if CONFIG_BTDM_CTRL_PINNED_TO_CORE == 0 + /* Interrupt 1 is used by Bluetooth UART HCI, check code above */ + #define CORE_0_INTERRUPT_1 STATE_INTERRUPT_1 + #define CORE_1_INTERRUPT_1 0 + /* Interrupt 5 may be used by Bluetooth BR/EDR and BLE controller */ + #define CORE_0_INTERRUPT_5 STATE_INTERRUPT_5 + #define CORE_1_INTERRUPT_5 0 + /* Interrupt 7 is used by Bluetooth VHCI software interrupt */ + #define CORE_0_INTERRUPT_7 STATE_INTERRUPT_7 + #define CORE_1_INTERRUPT_7 ESP_CPU_INTR_DESC_FLAG_SPECIAL + /* Interrupt 8 is used by Bluetooth BB */ + #define CORE_0_INTERRUPT_8 ESP_CPU_INTR_DESC_FLAG_RESVD + #define CORE_1_INTERRUPT_8 0 + /* Interrupt 25 may be used by Bluetooth BR/EDR and BLE controller */ + #define CORE_0_INTERRUPT_25 STATE_INTERRUPT_25 + #define CORE_1_INTERRUPT_25 0 + #elif CONFIG_BTDM_CTRL_PINNED_TO_CORE == 1 + /* Interrupt 1 is used by Bluetooth UART HCI, check code above */ + #define CORE_0_INTERRUPT_1 0 + #define CORE_1_INTERRUPT_1 STATE_INTERRUPT_1 + /* Interrupt 5 may be used by Bluetooth BR/EDR and BLE controller */ + #define CORE_0_INTERRUPT_5 0 + #define CORE_1_INTERRUPT_5 STATE_INTERRUPT_5 + /* Interrupt 7 is used by Bluetooth VHCI software interrupt */ + #define CORE_0_INTERRUPT_7 ESP_CPU_INTR_DESC_FLAG_SPECIAL + #define CORE_1_INTERRUPT_7 STATE_INTERRUPT_7 + /* Interrupt 8 is used by Bluetooth BB */ + #define CORE_0_INTERRUPT_8 0 + #define CORE_1_INTERRUPT_8 ESP_CPU_INTR_DESC_FLAG_RESVD + /* Interrupt 25 may be used by Bluetooth BR/EDR and BLE controller */ + #define CORE_0_INTERRUPT_25 0 + #define CORE_1_INTERRUPT_25 STATE_INTERRUPT_25 + #endif +#else // Bluetooth not enabled + #define CORE_0_INTERRUPT_1 0 + #define CORE_1_INTERRUPT_1 0 + #define CORE_0_INTERRUPT_5 0 + #define CORE_1_INTERRUPT_5 0 + #define CORE_0_INTERRUPT_7 ESP_CPU_INTR_DESC_FLAG_SPECIAL + #define CORE_1_INTERRUPT_7 ESP_CPU_INTR_DESC_FLAG_SPECIAL + #define CORE_0_INTERRUPT_8 0 + #define CORE_1_INTERRUPT_8 0 + #define CORE_0_INTERRUPT_25 0 + #define CORE_1_INTERRUPT_25 0 +#endif + + +/** + * @brief The system interrupts (memory access, cache, watchdog, ...) can be allocated on either level 4 or level 5 interrupts. + * Check the configuration. + */ +#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 + #define CORE_0_INTERRUPT_24 0 + #define CORE_1_INTERRUPT_24 0 + /* If CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is enabled, Bluetooth macros above take care of interrupt 25 */ + /* Interrupt 26 reserved for T1 Watchdog, cache and memory access errors */ + #define CORE_0_INTERRUPT_26 ESP_CPU_INTR_DESC_FLAG_RESVD + #define CORE_1_INTERRUPT_26 ESP_CPU_INTR_DESC_FLAG_RESVD + #define CORE_0_INTERRUPT_28 0 + #define CORE_1_INTERRUPT_28 0 + /* Interrupt 31 reserved for IPC ISRs */ + #define CORE_0_INTERRUPT_31 ESP_CPU_INTR_DESC_FLAG_RESVD + #define CORE_1_INTERRUPT_31 ESP_CPU_INTR_DESC_FLAG_RESVD +#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4 + /* Interrupt reserved for T1 Watchdog, make sure it is enabled */ + #if CONFIG_ESP_INT_WDT + #define CORE_0_INTERRUPT_24 ESP_CPU_INTR_DESC_FLAG_RESVD + #define CORE_1_INTERRUPT_24 ESP_CPU_INTR_DESC_FLAG_RESVD + #else // !CONFIG_ESP_INT_WDT + #define CORE_0_INTERRUPT_24 0 + #define CORE_1_INTERRUPT_24 0 + #endif + /* If CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4 is enabled, Bluetooth HLI is not enabled for sure (guaranteed by Kconfig), + * so we can discard the macro previously defined for interrupt 25 */ + #undef CORE_0_INTERRUPT_25 + #undef CORE_1_INTERRUPT_25 + /* Interrupt reserved for memory access and cache errors */ + #define CORE_0_INTERRUPT_25 ESP_CPU_INTR_DESC_FLAG_RESVD + #define CORE_1_INTERRUPT_25 ESP_CPU_INTR_DESC_FLAG_RESVD + #define CORE_0_INTERRUPT_26 0 + #define CORE_1_INTERRUPT_26 0 + /* Interrupt reserved for IPC ISRs */ + #define CORE_0_INTERRUPT_28 ESP_CPU_INTR_DESC_FLAG_RESVD + #define CORE_1_INTERRUPT_28 ESP_CPU_INTR_DESC_FLAG_RESVD + #define CORE_0_INTERRUPT_31 0 + #define CORE_1_INTERRUPT_31 0 +#endif // CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 + + +const static intr_desc_t intr_desc_table [SOC_CPU_INTR_NUM] = { + /* Interrupt 0 reserved for WMAC (Wifi) */ + [0] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, + /* Interrupt 1 reserved for BT/BLE Host HCI DMA when CONFIG_BTDM_CTRL_HCI_MODE_UART_H4 is enabled */ + [1] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_1, CORE_1_INTERRUPT_1 } }, + [2] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [3] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + /* Interrupt 4 reserved for WBB */ + [4] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, 0 } }, + /* Interrupt 5 reserved for BT/BLE Controller when Bluetooth HLI is enabled */ + [5] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_5, CORE_1_INTERRUPT_5 } }, +#if CONFIG_FREERTOS_CORETIMER_0 + [6] = { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, +#else + [6] = { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, +#endif + /* Interrupt 7 reserved for Bluetooth VHCI (software interrupt) */ + [7] = { 1, ESP_CPU_INTR_TYPE_NA, { CORE_0_INTERRUPT_7, CORE_1_INTERRUPT_7 } }, + /* Interrupt 8 reserved for BT/BLE BB(RX/TX) */ + [8] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_8, CORE_1_INTERRUPT_8 } }, + [9] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [10] = { 1, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } }, + [11] = { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, + [12] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [13] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [14] = { 7, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, // NMI +#if CONFIG_FREERTOS_CORETIMER_1 + [15] = { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, +#else + [15] = { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, +#endif + [16] = { 5, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, + [17] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [18] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [19] = { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [20] = { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [21] = { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [22] = { 3, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } }, + [23] = { 3, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + /* Interrupt 24 reserved for T1 WDT when CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4 is enabled */ + [24] = { 4, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_24, CORE_1_INTERRUPT_24 } }, + /* Interrupt 25 reserved for Memory access and cache errors when CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4 is enabled + * Reserved for BT/BLE Controller when CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is enabled */ + [25] = { 4, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_25, CORE_1_INTERRUPT_25 } }, + /* Interrupt 26 reserved for T1 WDT, Memory access and cache errors when CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is enabled */ + [26] = { 5, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_26, CORE_1_INTERRUPT_26 } }, + [27] = { 3, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + /* Interrupt 28 reserved for IPC when CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4 is enabled */ + [28] = { 4, ESP_CPU_INTR_TYPE_EDGE, { CORE_0_INTERRUPT_28, CORE_1_INTERRUPT_28 } }, + [29] = { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, + [30] = { 4, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } }, + /* Interrupt 31 reserved for IPC when CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is enabled */ + [31] = { 5, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_31, CORE_1_INTERRUPT_31 } }, +}; + + +void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) +{ + assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM && intr_desc_ret != NULL); + intr_desc_ret->priority = intr_desc_table[intr_num].priority; + intr_desc_ret->type = intr_desc_table[intr_num].type; + intr_desc_ret->flags = intr_desc_table[intr_num].flags[core_id]; +} diff --git a/components/esp_hw_support/port/esp32/rtc_init.c b/components/esp_hw_support/port/esp32/rtc_init.c index ab0fa4bd1d..087824c279 100644 --- a/components/esp_hw_support/port/esp32/rtc_init.c +++ b/components/esp_hw_support/port/esp32/rtc_init.c @@ -28,6 +28,7 @@ void rtc_init(rtc_config_t cfg) * No worry about the power consumption, Because modem Force PD will be set at the end of this function. */ CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU | RTC_CNTL_TXRF_I2C_PU | RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU); diff --git a/components/esp_hw_support/port/esp32/rtc_sleep.c b/components/esp_hw_support/port/esp32/rtc_sleep.c index a2dbe875e7..912e15d3a7 100644 --- a/components/esp_hw_support/port/esp32/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32/rtc_sleep.c @@ -183,7 +183,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) } if (cfg.modem_pd_en) { - REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO | RTC_CNTL_WIFI_FORCE_ISO); + REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO); REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU); SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN); } else { diff --git a/components/esp_hw_support/port/esp32/rtc_time.c b/components/esp_hw_support/port/esp32/rtc_time.c index d24d61e74c..6746196833 100644 --- a/components/esp_hw_support/port/esp32/rtc_time.c +++ b/components/esp_hw_support/port/esp32/rtc_time.c @@ -110,6 +110,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); uint64_t ratio_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT)) / slowclk_cycles; uint32_t ratio = (uint32_t)(ratio_64 & UINT32_MAX); @@ -125,6 +126,7 @@ static inline bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slo uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); @@ -140,6 +142,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) { + assert(period); /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. * TODO: fix overflow. */ diff --git a/components/esp_hw_support/port/esp32c2/CMakeLists.txt b/components/esp_hw_support/port/esp32c2/CMakeLists.txt index d0774a5029..9943669d5b 100644 --- a/components/esp_hw_support/port/esp32c2/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c2/CMakeLists.txt @@ -7,12 +7,11 @@ set(srcs "rtc_clk_init.c" if(NOT BOOTLOADER_BUILD) - list(APPEND srcs "sar_periph_ctrl.c") + list(APPEND srcs "esp_crypto_lock.c" + "sar_periph_ctrl.c") endif() add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") -target_include_directories(${COMPONENT_LIB} PUBLIC . private_include) -target_include_directories(${COMPONENT_LIB} PRIVATE ../hal) diff --git a/components/esp_hw_support/port/esp32c2/Kconfig.rtc b/components/esp_hw_support/port/esp32c2/Kconfig.rtc index 1fcd0d64b2..dff672e1c6 100644 --- a/components/esp_hw_support/port/esp32c2/Kconfig.rtc +++ b/components/esp_hw_support/port/esp32c2/Kconfig.rtc @@ -16,7 +16,7 @@ config RTC_CLK_CAL_CYCLES int "Number of cycles for RTC_SLOW_CLK calibration" default 3000 if RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 default 1024 if RTC_CLK_SRC_INT_RC - range 0 27000 if RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 + range 0 8190 if RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 range 0 32766 if RTC_CLK_SRC_INT_RC help When the startup code initializes RTC_SLOW_CLK, it can perform diff --git a/components/esp_hw_support/port/esp32c2/esp_cpu_intr.c b/components/esp_hw_support/port/esp32c2/esp_cpu_intr.c new file mode 100644 index 0000000000..6a901a2fdb --- /dev/null +++ b/components/esp_hw_support/port/esp32c2/esp_cpu_intr.c @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_cpu.h" +#include "esp_riscv_intr.h" + +void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) +{ + /* On the ESP32-C2, interrupt: + * - 1 is for Wi-Fi + * - 6 for "permanently disabled interrupt", named INT_MUX_DISABLED_INTNO in the interrupt allocator + */ + // [TODO: IDF-2465] + const uint32_t rsvd_mask = BIT(1) | BIT(6); + + intr_desc_ret->priority = 1; + intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; + intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask); +} diff --git a/components/esp_hw_support/port/esp32c2/esp_crypto_lock.c b/components/esp_hw_support/port/esp32c2/esp_crypto_lock.c new file mode 100644 index 0000000000..53a2500a47 --- /dev/null +++ b/components/esp_hw_support/port/esp32c2/esp_crypto_lock.c @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "esp_crypto_lock.h" + +/* Lock overview: +ECC: independent +*/ + +/* Lock for ECC peripheral */ +static _lock_t s_crypto_ecc_lock; + +void esp_crypto_ecc_lock_acquire(void) +{ + _lock_acquire(&s_crypto_ecc_lock); +} + +void esp_crypto_ecc_lock_release(void) +{ + _lock_release(&s_crypto_ecc_lock); +} diff --git a/components/esp_hw_support/port/esp32c2/rtc_clk.c b/components/esp_hw_support/port/esp32c2/rtc_clk.c index c065b4476a..2501c2f6df 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c2/rtc_clk.c @@ -128,6 +128,7 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq) clk_ll_bbpll_set_config(pll_freq, xtal_freq); /* WAIT CALIBRATION DONE */ while(!regi2c_ctrl_ll_bbpll_calibration_is_done()); + esp_rom_delay_us(10); /* BBPLL CALIBRATION STOP */ regi2c_ctrl_ll_bbpll_calibration_stop(); @@ -357,6 +358,24 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +void rtc_clk_recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32c2/rtc_sleep.c b/components/esp_hw_support/port/esp32c2/rtc_sleep.c index 325a22699f..6b6f08d0a6 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c2/rtc_sleep.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include "esp_attr.h" #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" @@ -21,6 +22,8 @@ #include "soc/regi2c_lp_bias.h" #include "soc/regi2c_dig_reg.h" +static const DRAM_ATTR rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); + /** * Configure whether certain peripherals are powered down in deep sleep * @param cfg power down flags as rtc_sleep_pu_config_t structure @@ -143,7 +146,6 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_ void rtc_sleep_init(rtc_sleep_config_t cfg) { if (cfg.lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } @@ -229,7 +231,6 @@ static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu) /* restore config if it is a light sleep */ if (lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } return reject; diff --git a/components/esp_hw_support/port/esp32c2/rtc_time.c b/components/esp_hw_support/port/esp32c2/rtc_time.c index 180c51b8bc..51df561d4a 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_time.c +++ b/components/esp_hw_support/port/esp32c2/rtc_time.c @@ -124,6 +124,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); uint64_t ratio_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT)) / slowclk_cycles; uint32_t ratio = (uint32_t)(ratio_64 & UINT32_MAX); @@ -139,6 +140,7 @@ static inline bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slo uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); @@ -154,6 +156,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) { + assert(period); /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. * TODO: fix overflow. */ diff --git a/components/esp_hw_support/port/esp32c3/CMakeLists.txt b/components/esp_hw_support/port/esp32c3/CMakeLists.txt index b383b815a6..03cf2f4cc9 100644 --- a/components/esp_hw_support/port/esp32c3/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c3/CMakeLists.txt @@ -22,5 +22,3 @@ endif() add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") -target_include_directories(${COMPONENT_LIB} PUBLIC . private_include) -target_include_directories(${COMPONENT_LIB} PRIVATE ../hal) diff --git a/components/esp_hw_support/port/esp32c3/Kconfig.hw_support b/components/esp_hw_support/port/esp32c3/Kconfig.hw_support index 050f392399..8e7c12f8d7 100644 --- a/components/esp_hw_support/port/esp32c3/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32c3/Kconfig.hw_support @@ -19,6 +19,8 @@ choice ESP32C3_REV_MIN bool "Rev v0.3 (ECO3)" config ESP32C3_REV_MIN_4 bool "Rev v0.4 (ECO4)" + config ESP32C3_REV_MIN_101 + bool "Rev v1.1" endchoice config ESP32C3_REV_MIN_FULL @@ -28,6 +30,7 @@ config ESP32C3_REV_MIN_FULL default 2 if ESP32C3_REV_MIN_2 default 3 if ESP32C3_REV_MIN_3 default 4 if ESP32C3_REV_MIN_4 + default 101 if ESP32C3_REV_MIN_101 config ESP_REV_MIN_FULL int @@ -37,7 +40,7 @@ config ESP_REV_MIN_FULL # MAX Revision # - comment "Maximum Supported ESP32-C3 Revision (Rev v0.99)" + comment "Maximum Supported ESP32-C3 Revision (Rev v1.99)" # Maximum revision that IDF supports. # It can not be changed by user. # Only Espressif can change it when a new version will be supported in IDF. @@ -45,7 +48,7 @@ config ESP_REV_MIN_FULL config ESP32C3_REV_MAX_FULL int - default 99 + default 199 # keep in sync the "Maximum Supported Revision" description with this value config ESP_REV_MAX_FULL diff --git a/components/esp_hw_support/port/esp32c3/Kconfig.rtc b/components/esp_hw_support/port/esp32c3/Kconfig.rtc index b68d2a9199..2125a01f52 100644 --- a/components/esp_hw_support/port/esp32c3/Kconfig.rtc +++ b/components/esp_hw_support/port/esp32c3/Kconfig.rtc @@ -20,7 +20,7 @@ config RTC_CLK_CAL_CYCLES int "Number of cycles for RTC_SLOW_CLK calibration" default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 default 1024 if RTC_CLK_SRC_INT_RC - range 0 27000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 + range 0 8190 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 range 0 32766 if RTC_CLK_SRC_INT_RC help When the startup code initializes RTC_SLOW_CLK, it can perform 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 c98c6479fe..954f931148 100644 --- a/components/esp_hw_support/port/esp32c3/adc2_init_cal.c +++ b/components/esp_hw_support/port/esp32c3/adc2_init_cal.c @@ -26,9 +26,9 @@ extern int rtc_spinlock; static 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); ENTER_CRITICAL_SECTION(); - adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_11); + adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); LEAVE_CRITICAL_SECTION(); } diff --git a/components/esp_hw_support/port/esp32c3/esp_cpu_intr.c b/components/esp_hw_support/port/esp32c3/esp_cpu_intr.c new file mode 100644 index 0000000000..6dfc26cbe6 --- /dev/null +++ b/components/esp_hw_support/port/esp32c3/esp_cpu_intr.c @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_cpu.h" +#include "esp_riscv_intr.h" + +void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) +{ + /* On the ESP32-C3, interrupt: + * - 1 is for Wi-Fi + * - 6 for "permanently disabled interrupt", named INT_MUX_DISABLED_INTNO in the interrupt allocator + */ + // [TODO: IDF-2465] + const uint32_t rsvd_mask = BIT(1) | BIT(6); + + intr_desc_ret->priority = 1; + intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; + intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask); +} diff --git a/components/esp_hw_support/port/esp32c3/rtc_init.c b/components/esp_hw_support/port/esp32c3/rtc_init.c index a88adda43f..c7a1eb55f0 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_init.c +++ b/components/esp_hw_support/port/esp32c3/rtc_init.c @@ -40,6 +40,7 @@ void rtc_init(rtc_config_t cfg) * No worry about the power consumption, Because modem Force PD will be set at the end of this function. */ CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0); @@ -263,7 +264,7 @@ uint32_t get_rtc_dbias_by_efuse(uint8_t chip_version, uint32_t dig_dbias) static void set_rtc_dig_dbias() { /* - 1. a reasonable dig_dbias which by scaning pvt to make 160 CPU run successful stored in efuse; + 1. a reasonable dig_dbias which by scanning pvt to make 160 CPU run successful stored in efuse; 2. also we store some value in efuse, include: k_rtc_ldo (slope of rtc voltage & rtc_dbias); k_dig_ldo (slope of digital voltage & digital_dbias); diff --git a/components/esp_hw_support/port/esp32c3/rtc_sleep.c b/components/esp_hw_support/port/esp32c3/rtc_sleep.c index 97d7c866e3..ad3b5b4e9f 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32c3/rtc_sleep.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include +#include "esp_attr.h" #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" @@ -23,10 +24,12 @@ #include "soc/regi2c_dig_reg.h" #include "soc/regi2c_lp_bias.h" #include "hal/efuse_hal.h" -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND #include "soc/systimer_reg.h" #endif +static const DRAM_ATTR rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); + /** * Configure whether certain peripherals are powered down in deep sleep * @param cfg power down flags as rtc_sleep_pu_config_t structure @@ -168,18 +171,17 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_ void rtc_sleep_init(rtc_sleep_config_t cfg) { if (cfg.lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } if (cfg.wifi_pd_en) { - REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO | RTC_CNTL_WIFI_FORCE_ISO); + REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO); REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU); SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN); } else { CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN); } if (cfg.bt_pd_en) { - REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_NOISO | RTC_CNTL_BT_FORCE_ISO); + REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_NOISO); REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PU); SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN); } else { @@ -220,6 +222,8 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) } /* mem force pu */ SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU); + SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU); + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU, cfg.rtc_regulator_fpu); if (!cfg.int_8m_pd_en) { SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU); @@ -248,17 +252,6 @@ void rtc_sleep_low_init(uint32_t slowclk_period) REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES); } -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND -void rtc_sleep_systimer_enable(bool en) -{ - if (en) { - REG_SET_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN); - } else { - REG_CLR_BIT(SYSTIMER_CONF_REG, SYSTIMER_TIMER_UNIT1_WORK_EN); - } -} -#endif - static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu); uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu) @@ -368,7 +361,6 @@ static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu) /* restore config if it is a light sleep */ if (lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } return reject; diff --git a/components/esp_hw_support/port/esp32c3/rtc_time.c b/components/esp_hw_support/port/esp32c3/rtc_time.c index aa277ba66c..37f40e8b1c 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_time.c +++ b/components/esp_hw_support/port/esp32c3/rtc_time.c @@ -128,6 +128,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); uint64_t ratio_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT)) / slowclk_cycles; uint32_t ratio = (uint32_t)(ratio_64 & UINT32_MAX); @@ -143,6 +144,7 @@ static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cy uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); @@ -157,6 +159,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) { + assert(period); /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. * TODO: fix overflow. */ diff --git a/components/esp_hw_support/port/esp32c6/CMakeLists.txt b/components/esp_hw_support/port/esp32c6/CMakeLists.txt index e82e407cb0..4f251876b0 100644 --- a/components/esp_hw_support/port/esp32c6/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c6/CMakeLists.txt @@ -22,4 +22,3 @@ add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") target_include_directories(${COMPONENT_LIB} PUBLIC . private_include) -target_include_directories(${COMPONENT_LIB} PRIVATE ../hal) diff --git a/components/esp_hw_support/port/esp32c6/Kconfig.rtc b/components/esp_hw_support/port/esp32c6/Kconfig.rtc index 297ffc1c4a..24a5b8fb94 100644 --- a/components/esp_hw_support/port/esp32c6/Kconfig.rtc +++ b/components/esp_hw_support/port/esp32c6/Kconfig.rtc @@ -20,7 +20,7 @@ config RTC_CLK_CAL_CYCLES int "Number of cycles for RTC_SLOW_CLK calibration" default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K default 1024 if RTC_CLK_SRC_INT_RC - range 0 27000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K + range 0 8190 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K range 0 32766 if RTC_CLK_SRC_INT_RC help When the startup code initializes RTC_SLOW_CLK, it can perform diff --git a/components/esp_hw_support/port/esp32c6/cpu_region_protect.c b/components/esp_hw_support/port/esp32c6/cpu_region_protect.c index 4b1b8dce2c..33d2cb48d4 100644 --- a/components/esp_hw_support/port/esp32c6/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32c6/cpu_region_protect.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,17 +13,22 @@ #ifdef BOOTLOADER_BUILD // Without L bit set #define CONDITIONAL_NONE 0x0 +#define CONDITIONAL_R PMP_R #define CONDITIONAL_RX PMP_R | PMP_X #define CONDITIONAL_RW PMP_R | PMP_W #define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X #else // With L bit set #define CONDITIONAL_NONE NONE +#define CONDITIONAL_R R #define CONDITIONAL_RX RX #define CONDITIONAL_RW RW #define CONDITIONAL_RWX RWX #endif +#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1)) +#define ALIGN_DOWN_TO_MMU_PAGE_SIZE(addr) ((addr) & ~((SOC_MMU_PAGE_SIZE) - 1)) + static void esp_cpu_configure_invalid_regions(void) { const unsigned PMA_NONE = PMA_L | PMA_EN; @@ -32,10 +37,10 @@ static void esp_cpu_configure_invalid_regions(void) __attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X; // 1. Gap at bottom of address space - PMA_ENTRY_SET_TOR(0, SOC_DEBUG_LOW, PMA_TOR | PMA_NONE); + PMA_ENTRY_SET_TOR(0, SOC_CPU_SUBSYSTEM_LOW, PMA_TOR | PMA_NONE); - // 2. Gap between debug region & IROM - PMA_ENTRY_SET_TOR(1, SOC_DEBUG_HIGH, PMA_NONE); + // 2. Gap between CPU subsystem region & IROM + PMA_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE); PMA_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE); // 3. Gap between ROM & RAM @@ -97,7 +102,7 @@ void esp_cpu_configure_region_protection(void) * We also lock these entries so the R/W/X permissions are enforced even for machine mode */ const unsigned NONE = PMP_L; - const unsigned R = PMP_L | PMP_R; + __attribute__((unused)) const unsigned R = PMP_L | PMP_R; const unsigned RW = PMP_L | PMP_R | PMP_W; const unsigned RX = PMP_L | PMP_R | PMP_X; const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X; @@ -111,20 +116,15 @@ void esp_cpu_configure_region_protection(void) // Configure all the valid address regions using PMP // - // 1. Debug region - const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_DEBUG_LOW, SOC_DEBUG_HIGH); + // 1. CPU Subsystem region - contains debug mode code and interrupt config registers + const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_CPU_SUBSYSTEM_LOW, SOC_CPU_SUBSYSTEM_HIGH); PMP_ENTRY_SET(0, pmpaddr0, PMP_NAPOT | RWX); - _Static_assert(SOC_DEBUG_LOW < SOC_DEBUG_HIGH, "Invalid CPU debug region"); + _Static_assert(SOC_CPU_SUBSYSTEM_LOW < SOC_CPU_SUBSYSTEM_HIGH, "Invalid CPU subsystem region"); - // 2.1 I-ROM + // 2.1 I/D-ROM PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE); PMP_ENTRY_SET(2, SOC_IROM_MASK_HIGH, PMP_TOR | RX); - _Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I-ROM region"); - - // 2.2 D-ROM - PMP_ENTRY_SET(3, SOC_DROM_MASK_LOW, NONE); - PMP_ENTRY_SET(4, SOC_DROM_MASK_HIGH, PMP_TOR | R); - _Static_assert(SOC_DROM_MASK_LOW < SOC_DROM_MASK_HIGH, "Invalid D-ROM region"); + _Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I/D-ROM region"); if (esp_cpu_dbgr_is_attached()) { // Anti-FI check that cpu is really in ocd mode @@ -155,15 +155,26 @@ void esp_cpu_configure_region_protection(void) #endif } - // 4. I_Cache (flash) - const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH); - PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | RX); - _Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I_Cache region"); +#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD + extern int _instruction_reserved_end; + extern int _rodata_reserved_end; + + const uint32_t irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_instruction_reserved_end)); + const uint32_t drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_end)); - // 5. D_Cache (flash) - const uint32_t pmpaddr9 = PMPADDR_NAPOT(SOC_DROM_LOW, SOC_DROM_HIGH); - PMP_ENTRY_SET(9, pmpaddr9, PMP_NAPOT | R); - _Static_assert(SOC_DROM_LOW < SOC_DROM_HIGH, "Invalid D_Cache region"); + // 4. I_Cache / D_Cache (flash) + PMP_ENTRY_CFG_RESET(8); + PMP_ENTRY_CFG_RESET(9); + PMP_ENTRY_CFG_RESET(10); + PMP_ENTRY_SET(8, SOC_IROM_LOW, NONE); + PMP_ENTRY_SET(9, irom_resv_end, PMP_TOR | RX); + PMP_ENTRY_SET(10, drom_resv_end, PMP_TOR | R); +#else + // 4. I_Cache / D_Cache (flash) + const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH); + PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | CONDITIONAL_RX); + _Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I/D_Cache region"); +#endif // 6. LP memory #if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD @@ -171,29 +182,29 @@ void esp_cpu_configure_region_protection(void) /* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits * Bootloader might have given extra permissions and those won't be cleared */ - PMP_ENTRY_CFG_RESET(10); PMP_ENTRY_CFG_RESET(11); PMP_ENTRY_CFG_RESET(12); PMP_ENTRY_CFG_RESET(13); - PMP_ENTRY_SET(10, SOC_RTC_IRAM_LOW, NONE); + PMP_ENTRY_CFG_RESET(14); + PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW, NONE); #if CONFIG_ULP_COPROC_RESERVE_MEM // First part of LP mem is reserved for coprocessor - PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM, PMP_TOR | RW); + PMP_ENTRY_SET(12, SOC_RTC_IRAM_LOW + CONFIG_ULP_COPROC_RESERVE_MEM, PMP_TOR | RW); #else // CONFIG_ULP_COPROC_RESERVE_MEM // Repeat same previous entry, to ensure next entry has correct base address (TOR) - PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW, NONE); + PMP_ENTRY_SET(12, SOC_RTC_IRAM_LOW, NONE); #endif // !CONFIG_ULP_COPROC_RESERVE_MEM - PMP_ENTRY_SET(12, (int)&_rtc_text_end, PMP_TOR | RX); - PMP_ENTRY_SET(13, SOC_RTC_IRAM_HIGH, PMP_TOR | RW); + PMP_ENTRY_SET(13, (int)&_rtc_text_end, PMP_TOR | RX); + PMP_ENTRY_SET(14, SOC_RTC_IRAM_HIGH, PMP_TOR | RW); #else - const uint32_t pmpaddr10 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH); - PMP_ENTRY_SET(10, pmpaddr10, PMP_NAPOT | CONDITIONAL_RWX); + const uint32_t pmpaddr11 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH); + PMP_ENTRY_SET(11, pmpaddr11, PMP_NAPOT | CONDITIONAL_RWX); _Static_assert(SOC_RTC_IRAM_LOW < SOC_RTC_IRAM_HIGH, "Invalid RTC IRAM region"); #endif // 7. Peripheral addresses - const uint32_t pmpaddr14 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH); - PMP_ENTRY_SET(14, pmpaddr14, PMP_NAPOT | RW); + const uint32_t pmpaddr15 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH); + PMP_ENTRY_SET(15, pmpaddr15, PMP_NAPOT | RW); _Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region"); } diff --git a/components/esp_hw_support/port/esp32c6/esp_cpu_intr.c b/components/esp_hw_support/port/esp32c6/esp_cpu_intr.c new file mode 100644 index 0000000000..38fdf890d8 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/esp_cpu_intr.c @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_cpu.h" +#include "esp_riscv_intr.h" + +void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) +{ + /* On the ESP32-C6, interrupt: + * - 1 is for Wi-Fi + * - 6 for "permanently disabled interrupt" + * + * Interrupts 3, 4 and 7 are unavailable for PULP CPU as they are bound to Core-Local Interrupts (CLINT) + */ + // [TODO: IDF-2465] + const uint32_t rsvd_mask = BIT(1) | BIT(3) | BIT(4) | BIT(6) | BIT(7); + + intr_desc_ret->priority = 1; + intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; + intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask); +} diff --git a/components/esp_hw_support/port/esp32c6/esp_crypto_lock.c b/components/esp_hw_support/port/esp32c6/esp_crypto_lock.c index 34f307b54c..4f02050294 100644 --- a/components/esp_hw_support/port/esp32c6/esp_crypto_lock.c +++ b/components/esp_hw_support/port/esp32c6/esp_crypto_lock.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 */ @@ -12,6 +12,7 @@ SHA: peripheral independent, but DMA is shared with AES AES: peripheral independent, but DMA is shared with SHA MPI/RSA: independent +ECC: independent HMAC: needs SHA DS: needs HMAC (which needs SHA), AES and MPI */ @@ -28,6 +29,9 @@ static _lock_t s_crypto_mpi_lock; /* Single lock for SHA and AES, sharing a reserved GDMA channel */ static _lock_t s_crypto_sha_aes_lock; +/* Lock for ECC peripheral */ +static _lock_t s_crypto_ecc_lock; + void esp_crypto_hmac_lock_acquire(void) { _lock_acquire(&s_crypto_hmac_lock); @@ -73,3 +77,13 @@ void esp_crypto_mpi_lock_release(void) { _lock_release(&s_crypto_mpi_lock); } + +void esp_crypto_ecc_lock_acquire(void) +{ + _lock_acquire(&s_crypto_ecc_lock); +} + +void esp_crypto_ecc_lock_release(void) +{ + _lock_release(&s_crypto_ecc_lock); +} diff --git a/components/esp_hw_support/port/esp32c6/pmu_init.c b/components/esp_hw_support/port/esp32c6/pmu_init.c index 8c04486f02..e64111e19b 100644 --- a/components/esp_hw_support/port/esp32c6/pmu_init.c +++ b/components/esp_hw_support/port/esp32c6/pmu_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,13 +23,13 @@ typedef struct { const pmu_hp_system_power_param_t *power; const pmu_hp_system_clock_param_t *clock; const pmu_hp_system_digital_param_t *digital; - const pmu_hp_system_analog_param_t *analog; + pmu_hp_system_analog_param_t *analog; //param determined at runtime const pmu_hp_system_retention_param_t *retent; } pmu_hp_system_param_t; typedef struct { const pmu_lp_system_power_param_t *power; - const pmu_lp_system_analog_param_t *analog; + pmu_lp_system_analog_param_t *analog; //param determined at runtime } pmu_lp_system_param_t; pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) @@ -42,7 +42,7 @@ pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) return &pmu_context; } -void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_param_t *param) +void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_system_param_t *param) { const pmu_hp_system_power_param_t *power = param->power; const pmu_hp_system_clock_param_t *clock = param->clock; @@ -101,7 +101,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP); } -void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, pmu_lp_system_param_t *param) +void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param) { const pmu_lp_system_power_param_t *power = param->power; const pmu_lp_system_analog_param_t *anlg = param->analog; @@ -137,38 +137,46 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx) }; for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) { - pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false); - pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false); pmu_ll_hp_set_power_force_power_up (ctx->hal->dev, pmu_hp_domains[idx], false); pmu_ll_hp_set_power_force_no_reset (ctx->hal->dev, pmu_hp_domains[idx], false); pmu_ll_hp_set_power_force_no_isolate(ctx->hal->dev, pmu_hp_domains[idx], false); pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false); } /* Isolate all memory banks while sleeping, avoid memory leakage current */ pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0); - pmu_ll_lp_set_power_force_reset (ctx->hal->dev, false); - pmu_ll_lp_set_power_force_isolate (ctx->hal->dev, false); pmu_ll_lp_set_power_force_power_up (ctx->hal->dev, false); pmu_ll_lp_set_power_force_no_reset (ctx->hal->dev, false); pmu_ll_lp_set_power_force_no_isolate(ctx->hal->dev, false); pmu_ll_lp_set_power_force_power_down(ctx->hal->dev, false); + pmu_ll_lp_set_power_force_isolate (ctx->hal->dev, false); + pmu_ll_lp_set_power_force_reset (ctx->hal->dev, false); } static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param) { + assert (param->analog); + param->power = pmu_hp_system_power_param_default(mode); param->clock = pmu_hp_system_clock_param_default(mode); param->digital = pmu_hp_system_digital_param_default(mode); - param->analog = pmu_hp_system_analog_param_default(mode); + *param->analog = *pmu_hp_system_analog_param_default(mode); //copy default value param->retent = pmu_hp_system_retention_param_default(mode); + + if (mode == PMU_MODE_HP_ACTIVE || mode == PMU_MODE_HP_MODEM) { + param->analog->regulator0.dbias = get_act_hp_dbias(); + } } static void pmu_hp_system_init_default(pmu_context_t *ctx) { assert(ctx); - pmu_hp_system_param_t param = { 0 }; for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) { + pmu_hp_system_analog_param_t analog = {}; + pmu_hp_system_param_t param = {.analog = &analog}; + pmu_hp_system_param_default(mode, ¶m); pmu_hp_system_init(ctx, mode, ¶m); } @@ -176,15 +184,23 @@ static void pmu_hp_system_init_default(pmu_context_t *ctx) static inline void pmu_lp_system_param_default(pmu_lp_mode_t mode, pmu_lp_system_param_t *param) { + assert (param->analog); + param->power = pmu_lp_system_power_param_default(mode); - param->analog = pmu_lp_system_analog_param_default(mode); + *param->analog = *pmu_lp_system_analog_param_default(mode); //copy default value + + if (mode == PMU_MODE_LP_ACTIVE) { + param->analog->regulator0.dbias = get_act_lp_dbias(); + } } static void pmu_lp_system_init_default(pmu_context_t *ctx) { assert(ctx); - pmu_lp_system_param_t param; for (pmu_lp_mode_t mode = PMU_MODE_LP_ACTIVE; mode < PMU_MODE_LP_MAX; mode++) { + pmu_lp_system_analog_param_t analog = {}; + pmu_lp_system_param_t param = {.analog = &analog}; + pmu_lp_system_param_default(mode, ¶m); pmu_lp_system_init(ctx, mode, ¶m); } diff --git a/components/esp_hw_support/port/esp32c6/pmu_param.c b/components/esp_hw_support/port/esp32c6/pmu_param.c index 6d2d818419..41c15ab8d0 100644 --- a/components/esp_hw_support/port/esp32c6/pmu_param.c +++ b/components/esp_hw_support/port/esp32c6/pmu_param.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,11 @@ #include "pmu_param.h" #include "soc/pmu_icg_mapping.h" #include "esp_private/esp_pmu.h" +#include "hal/efuse_ll.h" +#include "hal/efuse_hal.h" +#include "esp_hw_log.h" + +static __attribute__((unused)) const char *TAG = "pmu_param"; #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -209,9 +214,9 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp .slp_mem_xpd = 0, \ .slp_logic_xpd = 0, \ .xpd = 1, \ - .slp_mem_dbias = 0xc, \ - .slp_logic_dbias = 0xc, \ - .dbias = 0x19 \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = HP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -229,9 +234,9 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp .slp_mem_xpd = 0, \ .slp_logic_xpd = 0, \ .xpd = 1, \ - .slp_mem_dbias = 0xc, \ - .slp_logic_dbias = 0xc, \ - .dbias = 0x1a \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = HP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -246,12 +251,12 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp .bias_sleep = 0 \ }, \ .regulator0 = { \ - .slp_mem_xpd = 1, \ - .slp_logic_xpd = 1, \ - .xpd = 0, \ - .slp_mem_dbias = 0x4, \ - .slp_logic_dbias = 0x4, \ - .dbias = 0x1a \ + .slp_mem_xpd = 0, \ + .slp_logic_xpd = 0, \ + .xpd = 1, \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = 1 \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -286,6 +291,7 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m .hp_modem2active_backup_en = 0, \ }, \ .backup_clk = ( \ + BIT(PMU_ICG_FUNC_ENA_GDMA) | \ BIT(PMU_ICG_FUNC_ENA_REGDMA) | \ BIT(PMU_ICG_FUNC_ENA_TG0) | \ BIT(PMU_ICG_FUNC_ENA_TG1) | \ @@ -335,6 +341,7 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m .hp_active2sleep_backup_en = 0, \ }, \ .backup_clk = ( \ + BIT(PMU_ICG_FUNC_ENA_GDMA) | \ BIT(PMU_ICG_FUNC_ENA_REGDMA) | \ BIT(PMU_ICG_FUNC_ENA_TG0) | \ BIT(PMU_ICG_FUNC_ENA_TG1) | \ @@ -361,14 +368,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 \ } \ @@ -404,8 +417,8 @@ const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mod .regulator0 = { \ .slp_xpd = 0, \ .xpd = 1, \ - .slp_dbias = 0x0, \ - .dbias = 0x1a \ + .slp_dbias = 0, \ + .dbias = LP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -415,15 +428,15 @@ const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mod #define PMU_LP_SLEEP_ANALOG_CONFIG_DEFAULT() { \ .bias = { \ .xpd_bias = 0, \ - .dbg_atten = 0x0, \ + .dbg_atten = 0, \ .pd_cur = 1, \ .bias_sleep = 1, \ }, \ .regulator0 = { \ - .slp_xpd = 1, \ - .xpd = 0, \ - .slp_dbias = 0x0, \ - .dbias = 0x12 \ + .slp_xpd = 0, \ + .xpd = 1, \ + .slp_dbias = 0, \ + .dbias = 12 \ }, \ .regulator1 = { \ .drv_b = 0x0 \ @@ -439,3 +452,53 @@ const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_m assert(mode < ARRAY_SIZE(lp_analog)); return &lp_analog[mode]; } + +uint32_t get_act_hp_dbias(void) +{ + /* hp_cali_dbias is read from efuse to ensure that the hp_active_voltage is close to 1.15V + */ + uint32_t hp_cali_dbias = HP_CALI_DBIAS_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + hp_cali_dbias = efuse_ll_get_active_hp_dbias(); + if (hp_cali_dbias != 0) { + //efuse dbias need to add 2 to meet the CPU frequency switching + if (hp_cali_dbias + 2 > 31) { + hp_cali_dbias = 31; + } else { + hp_cali_dbias += 2; + } + } else { + hp_cali_dbias = HP_CALI_DBIAS_DEFAULT; + ESP_HW_LOGD(TAG, "hp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %d\n", blk_version); + } + } + + return hp_cali_dbias; +} + +uint32_t get_act_lp_dbias(void) +{ + /* lp_cali_dbias is read from efuse to ensure that the lp_active_voltage is close to 1.15V + */ + uint32_t lp_cali_dbias = LP_CALI_DBIAS_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + lp_cali_dbias = efuse_ll_get_active_lp_dbias(); + if (lp_cali_dbias != 0) { + //efuse dbias need to add 2 to meet the CPU frequency switching + if (lp_cali_dbias + 2 > 31) { + lp_cali_dbias = 31; + } else { + lp_cali_dbias += 2; + } + } else { + lp_cali_dbias = LP_CALI_DBIAS_DEFAULT; + ESP_HW_LOGD(TAG, "lp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %d\n", blk_version); + } + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, act dbias not burnt in efuse\n"); + } + + return lp_cali_dbias; +} diff --git a/components/esp_hw_support/port/esp32c6/pmu_sleep.c b/components/esp_hw_support/port/esp32c6/pmu_sleep.c index dfb63c9ff3..5cf7aa1615 100644 --- a/components/esp_hw_support/port/esp32c6/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32c6/pmu_sleep.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,13 +16,70 @@ #include "soc/pmu_struct.h" #include "hal/lp_aon_hal.h" #include "esp_private/esp_pmu.h" +#include "pmu_param.h" +#include "hal/efuse_ll.h" +#include "hal/efuse_hal.h" +#include "esp_hw_log.h" + +static __attribute__((unused)) const char *TAG = "pmu_sleep"; #define HP(state) (PMU_MODE_HP_ ## state) #define LP(state) (PMU_MODE_LP_ ## state) - static bool s_pmu_sleep_regdma_backup_enabled; +uint32_t get_lslp_dbg(void) +{ + uint32_t pmu_dbg_atten_lightsleep = PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + pmu_dbg_atten_lightsleep = efuse_ll_get_lslp_dbg(); + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, lslp dbg not burnt in efuse\n"); + } + + return pmu_dbg_atten_lightsleep; +} + +uint32_t get_lslp_hp_dbias(void) +{ + uint32_t pmu_hp_dbias_lightsleep_0v6 = PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + pmu_hp_dbias_lightsleep_0v6 = efuse_ll_get_lslp_hp_dbias(); + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, lslp hp dbias not burnt in efuse\n"); + } + + return pmu_hp_dbias_lightsleep_0v6; +} + +uint32_t get_dslp_dbg(void) +{ + uint32_t pmu_dbg_atten_deepsleep = PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + pmu_dbg_atten_deepsleep = efuse_ll_get_dslp_dbg() + EFUSE_BURN_OFFSET_DSLP_DBG; + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, dslp dbg not burnt in efuse\n"); + } + + return pmu_dbg_atten_deepsleep; +} + +uint32_t get_dslp_lp_dbias(void) +{ + uint32_t pmu_lp_dbias_deepsleep_0v7 = PMU_LP_DBIAS_DEEPSLEEP_0V7_DEFAULT; + uint32_t blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + pmu_lp_dbias_deepsleep_0v7 = efuse_ll_get_dslp_lp_dbias() + EFUSE_BURN_OFFSET_DSLP_LP_DBIAS; + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, dslp lp dbias not burnt in efuse\n"); + } + + return pmu_lp_dbias_deepsleep_0v7; +} + void pmu_sleep_enable_regdma_backup(void) { if(!s_pmu_sleep_regdma_backup_enabled){ @@ -155,28 +212,34 @@ const pmu_sleep_config_t* pmu_sleep_config_default( config->param = *pmu_sleep_param_config_default(¶m_default, &power_default, pd_flags, adjustment, slowclk_period, fastclk_period); if (dslp) { + config->param.lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US, slowclk_period); pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags); + analog_default.lp_sys[LP(SLEEP)].analog.dbg_atten = get_dslp_dbg(); + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_dslp_lp_dbias(); config->analog = analog_default; } else { pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags); config->digital = digital_default; pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags); - if (!(pd_flags & PMU_SLEEP_PD_TOP) || !(pd_flags & PMU_SLEEP_PD_MODEM)){ - analog_default.hp_sys.analog.xpd = 1; - analog_default.hp_sys.analog.dbias = 2; - } + analog_default.hp_sys.analog.dbg_atten = get_lslp_dbg(); + analog_default.hp_sys.analog.dbias = get_lslp_hp_dbias(); + analog_default.lp_sys[LP(SLEEP)].analog.dbias = PMU_LP_DBIAS_LIGHTSLEEP_0V7_DEFAULT; if (!(pd_flags & PMU_SLEEP_PD_XTAL)){ - analog_default.hp_sys.analog.xpd = 1; - analog_default.hp_sys.analog.pd_cur = 0; - analog_default.hp_sys.analog.bias_sleep = 0; - analog_default.hp_sys.analog.dbias = 25; - - analog_default.lp_sys[LP(SLEEP)].analog.xpd = 1; - analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = 0; - analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = 0; - analog_default.lp_sys[LP(SLEEP)].analog.dbias = 26; + analog_default.hp_sys.analog.pd_cur = PMU_PD_CUR_SLEEP_ON; + analog_default.hp_sys.analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; + analog_default.hp_sys.analog.dbg_atten = PMU_DBG_ATTEN_ACTIVE_DEFAULT; + analog_default.hp_sys.analog.dbias = get_act_hp_dbias(); + + analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON; + analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; + analog_default.lp_sys[LP(SLEEP)].analog.dbg_atten = PMU_DBG_ATTEN_ACTIVE_DEFAULT; + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias(); + } else if (!(pd_flags & PMU_SLEEP_PD_RC_FAST)) { + analog_default.hp_sys.analog.dbias = get_act_hp_dbias(); + analog_default.lp_sys[LP(SLEEP)].analog.dbg_atten = PMU_DBG_ATTEN_LIGHTSLEEP_NODROP; + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias(); } config->analog = analog_default; @@ -206,25 +269,17 @@ static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_c static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_config_t *analog, bool dslp) { assert(ctx->hal); + pmu_ll_hp_set_dbg_atten (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbg_atten); pmu_ll_hp_set_current_power_off (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.pd_cur); pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.bias_sleep); - pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_xpd); - pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_xpd); pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd); - pmu_ll_hp_set_regulator_sleep_memory_dbias(ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_dbias); - pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_dbias); pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias); pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b); - pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_xpd); - pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_dbias); - pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.xpd); - pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.dbias); - pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.drv_b); - pmu_ll_lp_set_dbg_atten (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbg_atten); pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur); pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep); + pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_xpd); pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd); pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias); pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias); @@ -276,7 +331,6 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp pmu_ll_hp_clear_wakeup_intr_status(PMU_instance()->hal->dev); pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev); pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev); - pmu_ll_hp_clear_sw_intr_status(PMU_instance()->hal->dev); /* Start entry into sleep mode */ pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev); @@ -292,6 +346,9 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp bool pmu_sleep_finish(void) { + // Wait eFuse memory update done. + while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE); + return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); } @@ -299,3 +356,9 @@ void pmu_sleep_enable_hp_sleep_sysclk(bool enable) { pmu_ll_hp_set_icg_sysclk_enable(PMU_instance()->hal->dev, HP(SLEEP), enable); } + +uint32_t pmu_sleep_get_wakup_retention_cost(void) +{ + const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + return mc->hp.regdma_s2a_work_time_us; +} 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 2608204a7a..44ffce061a 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,49 @@ extern "C" { #endif +#define HP_CALI_DBIAS_DEFAULT 25 +#define LP_CALI_DBIAS_DEFAULT 26 + +// FOR XTAL FORCE PU IN SLEEP +#define PMU_PD_CUR_SLEEP_ON 0 +#define PMU_BIASSLP_SLEEP_ON 0 + +// FOR BOTH LIGHTSLEEP & DEEPSLEEP +#define PMU_PD_CUR_SLEEP_DEFAULT 1 +#define PMU_BIASSLP_SLEEP_DEFAULT 1 +#define PMU_LP_XPD_SLEEP_DEFAULT 1 +#define PMU_LP_SLP_XPD_SLEEP_DEFAULT 0 +#define PMU_LP_SLP_DBIAS_SLEEP_DEFAULT 0 + +// FOR LIGHTSLEEP +#define PMU_HP_DRVB_LIGHTSLEEP 0 +#define PMU_LP_DRVB_LIGHTSLEEP 0 +#define PMU_HP_XPD_LIGHTSLEEP 1 + +#define PMU_DBG_ATTEN_LIGHTSLEEP_NODROP 0 +#define PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT 0 +#define PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT 1 +#define PMU_LP_DBIAS_LIGHTSLEEP_0V7_DEFAULT 12 + +// FOR LIGHTSLEEP: XTAL FORCE PU +#define PMU_DBG_ATTEN_ACTIVE_DEFAULT 0 + +// FOR DEEPSLEEP +#define PMU_DBG_HP_DEEPSLEEP 0 +#define PMU_HP_XPD_DEEPSLEEP 0 +#define PMU_LP_DRVB_DEEPSLEEP 0 + +#define PMU_REGDMA_S2A_WORK_TIME_US 480 + +#define PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT 12 +#define PMU_LP_DBIAS_DEEPSLEEP_0V7_DEFAULT 23 + +#define EFUSE_BURN_OFFSET_DSLP_DBG 8 +#define EFUSE_BURN_OFFSET_DSLP_LP_DBIAS 23 + +uint32_t get_act_hp_dbias(void); +uint32_t get_act_lp_dbias(void); + typedef struct { pmu_hp_dig_power_reg_t dig_power; pmu_hp_clk_power_reg_t clk_power; @@ -211,6 +254,7 @@ typedef struct { #define PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32) /* Fast OSC as PMU work clock source is about 2 us */ #define PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES (32) /* Fast OSC as PMU work clock source is about 2 us */ +#define PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US (500) /* Slow OSC as PMU slow clock source in deepsleep is about 500 us */ typedef struct { struct { @@ -253,8 +297,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 \ } \ }, \ @@ -293,84 +337,52 @@ typedef struct { } lp_sys[PMU_MODE_LP_MAX]; } pmu_sleep_analog_config_t; -#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \ - .hp_sys = { \ - .analog = { \ - .xpd_bias = 0, \ - .dbg_atten = 0, \ - .pd_cur = 1, \ - .bias_sleep = 1, \ - .slp_mem_xpd = 1, \ - .slp_logic_xpd = 1, \ - .slp_mem_dbias = 4, \ - .slp_logic_dbias = 4, \ - .xpd = 0, \ - .dbias = 0, \ - .drv_b = 0 \ - } \ - }, \ - .lp_sys[PMU_MODE_LP_ACTIVE] = { \ - .analog = { \ - .slp_xpd = 0, \ - .slp_dbias = 0, \ - .xpd = 1, \ - .dbias = 26, \ - .drv_b = 0 \ - } \ - }, \ - .lp_sys[PMU_MODE_LP_SLEEP] = { \ - .analog = { \ - .xpd_bias = 0, \ - .dbg_atten = 0, \ - .pd_cur = 1, \ - .bias_sleep = 1, \ - .xpd = 0, \ - .dbias = 28, \ - .slp_xpd = 1, \ - .slp_dbias = 3, \ - .drv_b = 0 \ - } \ - } \ +#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ + .analog = { \ + .drv_b = PMU_HP_DRVB_LIGHTSLEEP, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ + .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ + .xpd = PMU_HP_XPD_LIGHTSLEEP, \ + .dbg_atten = PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT, \ + .dbias = PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_SLEEP] = { \ + .analog = { \ + .drv_b = PMU_LP_DRVB_DEEPSLEEP, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ + .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ + .slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \ + .slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT, \ + .xpd = PMU_LP_XPD_SLEEP_DEFAULT, \ + .dbg_atten = PMU_DBG_ATTEN_LIGHTSLEEP_DEFAULT, \ + .dbias = PMU_LP_DBIAS_LIGHTSLEEP_0V7_DEFAULT \ + } \ + } \ } -#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags) { \ - .hp_sys = { \ - .analog = { \ - .xpd_bias = 0, \ - .dbg_atten = 0, \ - .pd_cur = 0, \ - .bias_sleep = 0, \ - .slp_mem_xpd = 0, \ - .slp_logic_xpd = 0, \ - .slp_mem_dbias = 0, \ - .slp_logic_dbias = 0, \ - .xpd = 0, \ - .dbias = 0, \ - .drv_b = 0 \ - } \ - }, \ - .lp_sys[PMU_MODE_LP_ACTIVE] = { \ - .analog = { \ - .slp_xpd = 0, \ - .slp_dbias = 0, \ - .xpd = 1, \ - .dbias = 26, \ - .drv_b = 0 \ - } \ - }, \ - .lp_sys[PMU_MODE_LP_SLEEP] = { \ - .analog = { \ - .xpd_bias = 0, \ - .dbg_atten = 14, \ - .pd_cur = 1, \ - .bias_sleep = 1, \ - .xpd = 0, \ - .dbias = 0, \ - .slp_xpd = 1, \ - .slp_dbias = 14, \ - .drv_b = 0 \ - } \ - } \ +#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ + .analog = { \ + .pd_cur = PMU_PD_CUR_SLEEP_ON, \ + .bias_sleep = PMU_BIASSLP_SLEEP_ON, \ + .xpd = PMU_HP_XPD_DEEPSLEEP, \ + .dbg_atten = PMU_DBG_HP_DEEPSLEEP \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_SLEEP] = { \ + .analog = { \ + .drv_b = PMU_LP_DRVB_DEEPSLEEP, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ + .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ + .slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \ + .slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT, \ + .xpd = PMU_LP_XPD_SLEEP_DEFAULT, \ + .dbg_atten = PMU_DBG_ATTEN_DEEPSLEEP_DEFAULT, \ + .dbias = PMU_LP_DBIAS_DEEPSLEEP_0V7_DEFAULT \ + } \ + } \ } typedef struct { @@ -456,7 +468,7 @@ typedef struct pmu_sleep_machine_constant { .power_supply_wait_time_us = 2, \ .power_up_wait_time_us = 2, \ .regdma_s2m_work_time_us = 172, \ - .regdma_s2a_work_time_us = 480, \ + .regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \ .regdma_m2a_work_time_us = 278, \ .regdma_a2s_work_time_us = 382, \ .regdma_rf_on_work_time_us = 70, \ diff --git a/components/esp_hw_support/port/esp32c6/private_include/sleep_gdma_retention_context.inc b/components/esp_hw_support/port/esp32c6/private_include/sleep_gdma_retention_context.inc new file mode 100644 index 0000000000..803ff57073 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/private_include/sleep_gdma_retention_context.inc @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc_caps.h" +#include "soc/gdma_reg.h" + + +/* GDMA Channel (Group0, Pair0) Registers Context + Include: GDMA_MISC_CONF_REG / + GDMA_IN_INT_ENA_CH0_REG / GDMA_OUT_INT_ENA_CH0_REG / GDMA_IN_PERI_SEL_CH0_REG / GDMA_OUT_PERI_SEL_CH0_REG + GDMA_IN_CONF0_CH0_REG / GDMA_IN_CONF1_CH0_REG / GDMA_IN_LINK_CH0_REG / GDMA_IN_PRI_CH0_REG + GDMA_OUT_CONF0_CH0_REG / GDMA_OUT_CONF1_CH0_REG / GDMA_OUT_LINK_CH0_REG /GDMA_OUT_PRI_CH0_REG +*/ +#define G0P0_RETENTION_REGS_CNT 13 +#define G0P0_RETENTION_MAP_BASE GDMA_IN_INT_ENA_CH0_REG +static const uint32_t g0p0_regs_map[4] = {0x4C801001, 0x604C0060, 0, 0}; +static const sleep_retention_entries_config_t gdma_g0p0_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P0_RETENTION_MAP_BASE, G0P0_RETENTION_MAP_BASE, \ + G0P0_RETENTION_REGS_CNT, 0, 0, \ + g0p0_regs_map[0], g0p0_regs_map[1], \ + g0p0_regs_map[2], g0p0_regs_map[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +/* GDMA Channel (Group0, Pair1) Registers Context + Include: GDMA_MISC_CONF_REG / + GDMA_IN_INT_ENA_CH1_REG / GDMA_OUT_INT_ENA_CH1_REG / GDMA_IN_PERI_SEL_CH1_REG / GDMA_OUT_PERI_SEL_CH1_REG + GDMA_IN_CONF0_CH1_REG / GDMA_IN_CONF1_CH1_REG / GDMA_IN_LINK_CH1_REG / GDMA_IN_PRI_CH1_REG + GDMA_OUT_CONF0_CH1_REG / GDMA_OUT_CONF1_CH1_REG / GDMA_OUT_LINK_CH1_REG /GDMA_OUT_PRI_CH1_REG +*/ +#define G0P1_RETENTION_REGS_CNT 13 +#define G0P1_RETENTION_MAP_BASE GDMA_IN_INT_ENA_CH1_REG +static const uint32_t g0p1_regs_map[4] = {0x81001, 0, 0xC00604C0, 0x604}; +static const sleep_retention_entries_config_t gdma_g0p1_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P1_RETENTION_MAP_BASE, G0P1_RETENTION_MAP_BASE, \ + G0P1_RETENTION_REGS_CNT, 0, 0, \ + g0p1_regs_map[0], g0p1_regs_map[1], \ + g0p1_regs_map[2], g0p1_regs_map[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +/* GDMA Channel (Group0, Pair2) Registers Context + Include: GDMA_MISC_CONF_REG / + GDMA_IN_INT_ENA_CH2_REG / GDMA_OUT_INT_ENA_CH2_REG / GDMA_IN_PERI_SEL_CH2_REG / GDMA_OUT_PERI_SEL_CH2_REG + GDMA_IN_CONF0_CH2_REG / GDMA_IN_CONF1_CH2_REG / GDMA_IN_LINK_CH2_REG / GDMA_IN_PRI_CH2_REG + GDMA_OUT_CONF0_CH2_REG / GDMA_OUT_CONF1_CH2_REG / GDMA_OUT_LINK_CH2_REG /GDMA_OUT_PRI_CH2_REG +*/ +#define G0P2_RETENTION_REGS_CNT_0 6 +#define G0P2_RETENTION_MAP_BASE_0 GDMA_IN_INT_ENA_CH2_REG +#define G0P2_RETENTION_REGS_CNT_1 7 +#define G0P2_RETENTION_MAP_BASE_1 GDMA_IN_PRI_CH2_REG +static const uint32_t g0p2_regs_map0[4] = {0x9001, 0, 0, 0x4C0000}; +static const uint32_t g0p2_regs_map1[4] = {0x3026003, 0, 0, 0}; +static const sleep_retention_entries_config_t gdma_g0p2_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P2_RETENTION_MAP_BASE_0, G0P2_RETENTION_MAP_BASE_0, \ + G0P2_RETENTION_REGS_CNT_0, 0, 0, \ + g0p2_regs_map0[0], g0p2_regs_map0[1], \ + g0p2_regs_map0[2], g0p2_regs_map0[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \ + G0P2_RETENTION_REGS_CNT_1, 0, 0, \ + g0p2_regs_map1[0], g0p2_regs_map1[1], \ + g0p2_regs_map1[2], g0p2_regs_map1[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_GROUPS][SOC_GDMA_PAIRS_PER_GROUP] = { + [0] = { + [0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)}, + [1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)}, + [2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)} + } +}; diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk.c b/components/esp_hw_support/port/esp32c6/rtc_clk.c index 439663fa92..14ede0160a 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_clk.c +++ b/components/esp_hw_support/port/esp32c6/rtc_clk.c @@ -19,6 +19,13 @@ #include "hal/regi2c_ctrl_ll.h" #include "soc/io_mux_reg.h" #include "soc/lp_aon_reg.h" +#include "esp_private/sleep_event.h" + +#ifdef BOOTLOADER_BUILD +#include "hal/modem_lpcon_ll.h" +#else +#include "esp_private/esp_modem_clock.h" +#endif static const char *TAG = "rtc_clk"; @@ -142,19 +149,34 @@ static void rtc_clk_bbpll_enable(void) clk_ll_bbpll_enable(); } +static void rtc_clk_enable_i2c_ana_master_clock(bool enable) +{ +#ifdef BOOTLOADER_BUILD + modem_lpcon_ll_enable_i2c_master_clock(&MODEM_LPCON, enable); +#else + if (enable) { + modem_clock_module_enable(PERIPH_ANA_I2C_MASTER_MODULE); + } else { + modem_clock_module_disable(PERIPH_ANA_I2C_MASTER_MODULE); + } +#endif +} + static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq) { /* Digital part */ clk_ll_bbpll_set_freq_mhz(pll_freq); /* Analog part */ + rtc_clk_enable_i2c_ana_master_clock(true); /* BBPLL CALIBRATION START */ regi2c_ctrl_ll_bbpll_calibration_start(); clk_ll_bbpll_set_config(pll_freq, xtal_freq); /* WAIT CALIBRATION DONE */ while(!regi2c_ctrl_ll_bbpll_calibration_is_done()); + esp_rom_delay_us(10); /* BBPLL CALIBRATION STOP */ regi2c_ctrl_ll_bbpll_calibration_stop(); - + rtc_clk_enable_i2c_ana_master_clock(false); s_cur_pll_freq = pll_freq; } @@ -237,6 +259,10 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou return true; } +__attribute__((weak)) void rtc_clk_set_cpu_switch_to_bbpll(int event_id) +{ +} + void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) { soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src(); @@ -248,10 +274,12 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) } } else if (config->source == SOC_CPU_CLK_SRC_PLL) { if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL) { + rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_BBPLL_EN_START); rtc_clk_bbpll_enable(); rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz); } rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); + rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_BBPLL_EN_STOP); } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { rtc_clk_cpu_freq_to_8m(); if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL) && !s_bbpll_digi_consumers_ref_count) { @@ -339,6 +367,7 @@ rtc_xtal_freq_t rtc_clk_xtal_freq_get(void) uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz(); if (xtal_freq_mhz == 0) { ESP_HW_LOGW(TAG, "invalid RTC_XTAL_FREQ_REG value, assume 40MHz"); + clk_ll_xtal_store_freq_mhz(RTC_XTAL_FREQ_40M); return RTC_XTAL_FREQ_40M; } return (rtc_xtal_freq_t)xtal_freq_mhz; @@ -399,6 +428,25 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +void rtc_clk_recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} + + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk_init.c b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c index 4f19d05c68..bb9c6fff00 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,6 +24,8 @@ #include "hal/pmu_ll.h" #include "hal/modem_syscon_ll.h" #include "hal/modem_lpcon_ll.h" +#include "soc/pmu_reg.h" +#include "pmu_param.h" static const char *TAG = "rtc_clk_init"; @@ -72,6 +74,15 @@ void rtc_clk_init(rtc_clk_config_t cfg) REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_SCK_DCAP, cfg.slow_clk_dcap); REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); + + uint32_t hp_cali_dbias = get_act_hp_dbias(); + uint32_t lp_cali_dbias = get_act_lp_dbias(); + + SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S); + SET_PERI_REG_BITS(PMU_HP_MODEM_HP_REGULATOR0_REG, PMU_HP_MODEM_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S); + SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); clk_ll_rc_fast_tick_conf(); diff --git a/components/esp_hw_support/port/esp32c6/rtc_time.c b/components/esp_hw_support/port/esp32c6/rtc_time.c index f662965f1e..bb42b65645 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_time.c +++ b/components/esp_hw_support/port/esp32c6/rtc_time.c @@ -208,6 +208,7 @@ static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cy uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); /*The Fosc CLK of calibration circuit is divided by 32 for ECO1. @@ -233,6 +234,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) { + assert(period); /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. * TODO: fix overflow. */ diff --git a/components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c index 483f274d25..f5935e1eda 100644 --- a/components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c +++ b/components/esp_hw_support/port/esp32c6/sar_periph_ctrl.c @@ -19,6 +19,7 @@ #include "sdkconfig.h" #include "esp_log.h" #include "esp_private/sar_periph_ctrl.h" +#include "esp_private/esp_modem_clock.h" #include "hal/sar_ctrl_ll.h" static const char *TAG = "sar_periph_ctrl"; @@ -60,6 +61,7 @@ static int s_pwdet_power_on_cnt; static void s_sar_power_acquire(void) { + modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); ENTER_CRITICAL_SECTION(); s_pwdet_power_on_cnt++; if (s_pwdet_power_on_cnt == 1) { @@ -80,6 +82,7 @@ static void s_sar_power_release(void) sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM); } LEAVE_CRITICAL_SECTION(); + modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); } diff --git a/components/esp_hw_support/port/esp32h2/CMakeLists.txt b/components/esp_hw_support/port/esp32h2/CMakeLists.txt index 9c1949a12c..2c4cd900da 100644 --- a/components/esp_hw_support/port/esp32h2/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32h2/CMakeLists.txt @@ -16,4 +16,3 @@ add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}") target_sources(${COMPONENT_LIB} PRIVATE "${srcs}") target_include_directories(${COMPONENT_LIB} PUBLIC . private_include) -target_include_directories(${COMPONENT_LIB} PRIVATE ../hal) diff --git a/components/esp_hw_support/port/esp32h2/Kconfig.hw_support b/components/esp_hw_support/port/esp32h2/Kconfig.hw_support index d2ff886707..f94d5c930f 100644 --- a/components/esp_hw_support/port/esp32h2/Kconfig.hw_support +++ b/components/esp_hw_support/port/esp32h2/Kconfig.hw_support @@ -1,5 +1,5 @@ choice ESP32H2_REV_MIN - prompt "Minimum Supported ESP32-C6 Revision" + prompt "Minimum Supported ESP32-H2 Revision" default ESP32H2_REV_MIN_0 help Required minimum chip revision. ESP-IDF will check for it and diff --git a/components/esp_hw_support/port/esp32h2/Kconfig.rtc b/components/esp_hw_support/port/esp32h2/Kconfig.rtc index 297ffc1c4a..24a5b8fb94 100644 --- a/components/esp_hw_support/port/esp32h2/Kconfig.rtc +++ b/components/esp_hw_support/port/esp32h2/Kconfig.rtc @@ -20,7 +20,7 @@ config RTC_CLK_CAL_CYCLES int "Number of cycles for RTC_SLOW_CLK calibration" default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K default 1024 if RTC_CLK_SRC_INT_RC - range 0 27000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K + range 0 8190 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_RC32K range 0 32766 if RTC_CLK_SRC_INT_RC help When the startup code initializes RTC_SLOW_CLK, it can perform diff --git a/components/esp_hw_support/port/esp32h2/cpu_region_protect.c b/components/esp_hw_support/port/esp32h2/cpu_region_protect.c index cfe2d66837..c8817ca176 100644 --- a/components/esp_hw_support/port/esp32h2/cpu_region_protect.c +++ b/components/esp_hw_support/port/esp32h2/cpu_region_protect.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,17 +13,22 @@ #ifdef BOOTLOADER_BUILD // Without L bit set #define CONDITIONAL_NONE 0x0 +#define CONDITIONAL_R PMP_R #define CONDITIONAL_RX PMP_R | PMP_X #define CONDITIONAL_RW PMP_R | PMP_W #define CONDITIONAL_RWX PMP_R | PMP_W | PMP_X #else // With L bit set #define CONDITIONAL_NONE NONE +#define CONDITIONAL_R R #define CONDITIONAL_RX RX #define CONDITIONAL_RW RW #define CONDITIONAL_RWX RWX #endif +#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1)) +#define ALIGN_DOWN_TO_MMU_PAGE_SIZE(addr) ((addr) & ~((SOC_MMU_PAGE_SIZE) - 1)) + static void esp_cpu_configure_invalid_regions(void) { const unsigned PMA_NONE = PMA_L | PMA_EN; @@ -32,10 +37,10 @@ static void esp_cpu_configure_invalid_regions(void) __attribute__((unused)) const unsigned PMA_RWX = PMA_L | PMA_EN | PMA_R | PMA_W | PMA_X; // 1. Gap at bottom of address space - PMA_ENTRY_SET_TOR(0, SOC_DEBUG_LOW, PMA_TOR | PMA_NONE); + PMA_ENTRY_SET_TOR(0, SOC_CPU_SUBSYSTEM_LOW, PMA_TOR | PMA_NONE); - // 2. Gap between debug region & IROM - PMA_ENTRY_SET_TOR(1, SOC_DEBUG_HIGH, PMA_NONE); + // 2. Gap between CPU subsystem region & IROM + PMA_ENTRY_SET_TOR(1, SOC_CPU_SUBSYSTEM_HIGH, PMA_NONE); PMA_ENTRY_SET_TOR(2, SOC_IROM_MASK_LOW, PMA_TOR | PMA_NONE); // 3. Gap between ROM & RAM @@ -97,7 +102,7 @@ void esp_cpu_configure_region_protection(void) * We also lock these entries so the R/W/X permissions are enforced even for machine mode */ const unsigned NONE = PMP_L; - const unsigned R = PMP_L | PMP_R; + __attribute__((unused)) const unsigned R = PMP_L | PMP_R; const unsigned RW = PMP_L | PMP_R | PMP_W; const unsigned RX = PMP_L | PMP_R | PMP_X; const unsigned RWX = PMP_L | PMP_R | PMP_W | PMP_X; @@ -111,20 +116,15 @@ void esp_cpu_configure_region_protection(void) // Configure all the valid address regions using PMP // - // 1. Debug region - const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_DEBUG_LOW, SOC_DEBUG_HIGH); + // 1. CPU Subsystem region - contains debug mode code and interrupt config registers + const uint32_t pmpaddr0 = PMPADDR_NAPOT(SOC_CPU_SUBSYSTEM_LOW, SOC_CPU_SUBSYSTEM_HIGH); PMP_ENTRY_SET(0, pmpaddr0, PMP_NAPOT | RWX); - _Static_assert(SOC_DEBUG_LOW < SOC_DEBUG_HIGH, "Invalid CPU debug region"); + _Static_assert(SOC_CPU_SUBSYSTEM_LOW < SOC_CPU_SUBSYSTEM_HIGH, "Invalid CPU subsystem region"); - // 2.1 I-ROM + // 2.1 I/D-ROM PMP_ENTRY_SET(1, SOC_IROM_MASK_LOW, NONE); PMP_ENTRY_SET(2, SOC_IROM_MASK_HIGH, PMP_TOR | RX); - _Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I-ROM region"); - - // 2.2 D-ROM - PMP_ENTRY_SET(3, SOC_DROM_MASK_LOW, NONE); - PMP_ENTRY_SET(4, SOC_DROM_MASK_HIGH, PMP_TOR | R); - _Static_assert(SOC_DROM_MASK_LOW < SOC_DROM_MASK_HIGH, "Invalid D-ROM region"); + _Static_assert(SOC_IROM_MASK_LOW < SOC_IROM_MASK_HIGH, "Invalid I/D-ROM region"); if (esp_cpu_dbgr_is_attached()) { // Anti-FI check that cpu is really in ocd mode @@ -155,15 +155,26 @@ void esp_cpu_configure_region_protection(void) #endif } - // 4. I_Cache (flash) - const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH); - PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | RX); - _Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I_Cache region"); +#if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD + extern int _instruction_reserved_end; + extern int _rodata_reserved_end; + + const uint32_t irom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_instruction_reserved_end)); + const uint32_t drom_resv_end = ALIGN_UP_TO_MMU_PAGE_SIZE((uint32_t)(&_rodata_reserved_end)); - // 5. D_Cache (flash) - const uint32_t pmpaddr9 = PMPADDR_NAPOT(SOC_DROM_LOW, SOC_DROM_HIGH); - PMP_ENTRY_SET(9, pmpaddr9, PMP_NAPOT | R); - _Static_assert(SOC_DROM_LOW < SOC_DROM_HIGH, "Invalid D_Cache region"); + // 4. I_Cache / D_Cache (flash) + PMP_ENTRY_CFG_RESET(8); + PMP_ENTRY_CFG_RESET(9); + PMP_ENTRY_CFG_RESET(10); + PMP_ENTRY_SET(8, SOC_IROM_LOW, NONE); + PMP_ENTRY_SET(9, irom_resv_end, PMP_TOR | RX); + PMP_ENTRY_SET(10, drom_resv_end, PMP_TOR | R); +#else + // 4. I_Cache / D_Cache (flash) + const uint32_t pmpaddr8 = PMPADDR_NAPOT(SOC_IROM_LOW, SOC_IROM_HIGH); + PMP_ENTRY_SET(8, pmpaddr8, PMP_NAPOT | CONDITIONAL_RX); + _Static_assert(SOC_IROM_LOW < SOC_IROM_HIGH, "Invalid I/D_Cache region"); +#endif // 6. LP memory #if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT && !BOOTLOADER_BUILD @@ -171,20 +182,20 @@ void esp_cpu_configure_region_protection(void) /* Reset the corresponding PMP config because PMP_ENTRY_SET only sets the given bits * Bootloader might have given extra permissions and those won't be cleared */ - PMP_ENTRY_CFG_RESET(10); PMP_ENTRY_CFG_RESET(11); PMP_ENTRY_CFG_RESET(12); - PMP_ENTRY_SET(10, SOC_RTC_IRAM_LOW, NONE); - PMP_ENTRY_SET(11, (int)&_rtc_text_end, PMP_TOR | RX); - PMP_ENTRY_SET(12, SOC_RTC_IRAM_HIGH, PMP_TOR | RW); + PMP_ENTRY_CFG_RESET(13); + PMP_ENTRY_SET(11, SOC_RTC_IRAM_LOW, NONE); + PMP_ENTRY_SET(12, (int)&_rtc_text_end, PMP_TOR | RX); + PMP_ENTRY_SET(13, SOC_RTC_IRAM_HIGH, PMP_TOR | RW); #else - const uint32_t pmpaddr10 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH); - PMP_ENTRY_SET(10, pmpaddr10, PMP_NAPOT | CONDITIONAL_RWX); + const uint32_t pmpaddr11 = PMPADDR_NAPOT(SOC_RTC_IRAM_LOW, SOC_RTC_IRAM_HIGH); + PMP_ENTRY_SET(11, pmpaddr11, PMP_NAPOT | CONDITIONAL_RWX); _Static_assert(SOC_RTC_IRAM_LOW < SOC_RTC_IRAM_HIGH, "Invalid RTC IRAM region"); #endif // 7. Peripheral addresses - const uint32_t pmpaddr13 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH); - PMP_ENTRY_SET(13, pmpaddr13, PMP_NAPOT | RW); + const uint32_t pmpaddr14 = PMPADDR_NAPOT(SOC_PERIPHERAL_LOW, SOC_PERIPHERAL_HIGH); + PMP_ENTRY_SET(14, pmpaddr14, PMP_NAPOT | RW); _Static_assert(SOC_PERIPHERAL_LOW < SOC_PERIPHERAL_HIGH, "Invalid peripheral region"); } diff --git a/components/esp_hw_support/port/esp32h2/esp_cpu_intr.c b/components/esp_hw_support/port/esp32h2/esp_cpu_intr.c new file mode 100644 index 0000000000..9ce7dfa69c --- /dev/null +++ b/components/esp_hw_support/port/esp32h2/esp_cpu_intr.c @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_cpu.h" +#include "esp_riscv_intr.h" + +void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) +{ + /* On the ESP32-H2, interrupt: + * - 1 is for Wi-Fi + * - 6 for "permanently disabled interrupt" + * + * Interrupts 3, 4 and 7 are unavailable for PULP CPU as they are bound to Core-Local Interrupts (CLINT) + */ + // [TODO: IDF-2465] + const uint32_t rsvd_mask = BIT(1) | BIT(3) | BIT(4) | BIT(6) | BIT(7); + + intr_desc_ret->priority = 1; + intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; + intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask); +} diff --git a/components/esp_hw_support/port/esp32h2/esp_crypto_lock.c b/components/esp_hw_support/port/esp32h2/esp_crypto_lock.c index 3936a75b76..209866fe4f 100644 --- a/components/esp_hw_support/port/esp32h2/esp_crypto_lock.c +++ b/components/esp_hw_support/port/esp32h2/esp_crypto_lock.c @@ -12,8 +12,10 @@ SHA: peripheral independent, but DMA is shared with AES AES: peripheral independent, but DMA is shared with SHA MPI/RSA: independent +ECC: independent HMAC: needs SHA DS: needs HMAC (which needs SHA), AES and MPI +ECDSA: needs ECC and MPI */ /* Lock for DS peripheral */ @@ -28,6 +30,12 @@ static _lock_t s_crypto_mpi_lock; /* Single lock for SHA and AES, sharing a reserved GDMA channel */ static _lock_t s_crypto_sha_aes_lock; +/* Lock for ECC peripheral */ +static _lock_t s_crypto_ecc_lock; + +/* Lock for ECDSA peripheral */ +static _lock_t s_crypto_ecdsa_lock; + void esp_crypto_hmac_lock_acquire(void) { _lock_acquire(&s_crypto_hmac_lock); @@ -73,3 +81,27 @@ void esp_crypto_mpi_lock_release(void) { _lock_release(&s_crypto_mpi_lock); } + +void esp_crypto_ecc_lock_acquire(void) +{ + _lock_acquire(&s_crypto_ecc_lock); +} + +void esp_crypto_ecc_lock_release(void) +{ + _lock_release(&s_crypto_ecc_lock); +} + +void esp_crypto_ecdsa_lock_acquire(void) +{ + _lock_acquire(&s_crypto_ecdsa_lock); + esp_crypto_ecc_lock_acquire(); + esp_crypto_mpi_lock_acquire(); +} + +void esp_crypto_ecdsa_lock_release(void) +{ + esp_crypto_mpi_lock_release(); + esp_crypto_ecc_lock_release(); + _lock_release(&s_crypto_ecdsa_lock); +} diff --git a/components/esp_hw_support/port/esp32h2/pmu_init.c b/components/esp_hw_support/port/esp32h2/pmu_init.c index 0548461a2b..a82f944368 100644 --- a/components/esp_hw_support/port/esp32h2/pmu_init.c +++ b/components/esp_hw_support/port/esp32h2/pmu_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,13 +24,13 @@ typedef struct { const pmu_hp_system_power_param_t *power; const pmu_hp_system_clock_param_t *clock; const pmu_hp_system_digital_param_t *digital; - const pmu_hp_system_analog_param_t *analog; + pmu_hp_system_analog_param_t *analog; //param determined at runtime const pmu_hp_system_retention_param_t *retent; } pmu_hp_system_param_t; typedef struct { const pmu_lp_system_power_param_t *power; - const pmu_lp_system_analog_param_t *analog; + pmu_lp_system_analog_param_t *analog; //param determined at runtime } pmu_lp_system_param_t; pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) @@ -43,7 +43,7 @@ pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) return &pmu_context; } -void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_param_t *param) +void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_system_param_t *param) { const pmu_hp_system_power_param_t *power = param->power; const pmu_hp_system_clock_param_t *clock = param->clock; @@ -102,7 +102,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP); } -void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, pmu_lp_system_param_t *param) +void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param) { const pmu_lp_system_power_param_t *power = param->power; const pmu_lp_system_analog_param_t *anlg = param->analog; @@ -136,39 +136,47 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx) }; for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) { - pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false); - pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false); pmu_ll_hp_set_power_force_power_up (ctx->hal->dev, pmu_hp_domains[idx], false); pmu_ll_hp_set_power_force_no_reset (ctx->hal->dev, pmu_hp_domains[idx], false); pmu_ll_hp_set_power_force_no_isolate(ctx->hal->dev, pmu_hp_domains[idx], false); pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false); } /* Isolate all memory banks while sleeping, avoid memory leakage current */ pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0); - pmu_ll_lp_set_power_force_reset (ctx->hal->dev, false); - pmu_ll_lp_set_power_force_isolate (ctx->hal->dev, false); pmu_ll_lp_set_power_force_power_up (ctx->hal->dev, false); pmu_ll_lp_set_power_force_no_reset (ctx->hal->dev, false); pmu_ll_lp_set_power_force_no_isolate(ctx->hal->dev, false); pmu_ll_lp_set_power_force_power_down(ctx->hal->dev, false); + pmu_ll_lp_set_power_force_isolate (ctx->hal->dev, false); + pmu_ll_lp_set_power_force_reset (ctx->hal->dev, false); } static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param) { + assert (param->analog); + param->power = pmu_hp_system_power_param_default(mode); param->clock = pmu_hp_system_clock_param_default(mode); param->digital = pmu_hp_system_digital_param_default(mode); - param->analog = pmu_hp_system_analog_param_default(mode); + *param->analog = *pmu_hp_system_analog_param_default(mode); //copy default value param->retent = pmu_hp_system_retention_param_default(mode); + + if (mode == PMU_MODE_HP_ACTIVE || mode == PMU_MODE_HP_MODEM) { + param->analog->regulator0.dbias = get_act_hp_dbias(); + } } static void pmu_hp_system_init_default(pmu_context_t *ctx) { assert(ctx); - pmu_hp_system_param_t param = { 0 }; for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) { + pmu_hp_system_analog_param_t analog = {}; + pmu_hp_system_param_t param = {.analog = &analog}; + pmu_hp_system_param_default(mode, ¶m); pmu_hp_system_init(ctx, mode, ¶m); } @@ -176,15 +184,23 @@ static void pmu_hp_system_init_default(pmu_context_t *ctx) static inline void pmu_lp_system_param_default(pmu_lp_mode_t mode, pmu_lp_system_param_t *param) { + assert (param->analog); + param->power = pmu_lp_system_power_param_default(mode); - param->analog = pmu_lp_system_analog_param_default(mode); + *param->analog = *pmu_lp_system_analog_param_default(mode); //copy default value + + if (mode == PMU_MODE_LP_ACTIVE) { + param->analog->regulator0.dbias = get_act_lp_dbias(); + } } static void pmu_lp_system_init_default(pmu_context_t *ctx) { assert(ctx); - pmu_lp_system_param_t param; for (pmu_lp_mode_t mode = PMU_MODE_LP_ACTIVE; mode < PMU_MODE_LP_MAX; mode++) { + pmu_lp_system_analog_param_t analog = {}; + pmu_lp_system_param_t param = {.analog = &analog}; + pmu_lp_system_param_default(mode, ¶m); pmu_lp_system_init(ctx, mode, ¶m); } diff --git a/components/esp_hw_support/port/esp32h2/pmu_param.c b/components/esp_hw_support/port/esp32h2/pmu_param.c index 715c5552ca..b15e97b78e 100644 --- a/components/esp_hw_support/port/esp32h2/pmu_param.c +++ b/components/esp_hw_support/port/esp32h2/pmu_param.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,11 @@ #include "pmu_param.h" #include "soc/pmu_icg_mapping.h" #include "esp_private/esp_pmu.h" +#include "hal/efuse_ll.h" +#include "hal/efuse_hal.h" +#include "esp_hw_log.h" + +static __attribute__((unused)) const char *TAG = "pmu_param"; #ifndef ARRAY_SIZE #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) @@ -210,9 +215,9 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp .slp_mem_xpd = 0, \ .slp_logic_xpd = 0, \ .xpd = 1, \ - .slp_mem_dbias = 0x5, \ - .slp_logic_dbias = 0xc, \ - .dbias = 0xf \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = HP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x1a \ @@ -230,9 +235,9 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp .slp_mem_xpd = 0, \ .slp_logic_xpd = 0, \ .xpd = 1, \ - .slp_mem_dbias = 0x5, \ - .slp_logic_dbias = 0xc, \ - .dbias = 0xd \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ + .dbias = HP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ .drv_b = 0x1b \ @@ -247,11 +252,11 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp .bias_sleep = 1 \ }, \ .regulator0 = { \ - .slp_mem_xpd = 1, \ - .slp_logic_xpd = 1, \ - .xpd = 0, \ - .slp_mem_dbias = 0x1, \ - .slp_logic_dbias = 0x5, \ + .slp_mem_xpd = 0, \ + .slp_logic_xpd = 0, \ + .xpd = 1, \ + .slp_mem_dbias = 0, \ + .slp_logic_dbias = 0, \ .dbias = 0 \ }, \ .regulator1 = { \ @@ -269,7 +274,6 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m assert(mode < ARRAY_SIZE(hp_analog)); return &hp_analog[mode]; } - #define PMU_HP_RETENTION_REGDMA_CONFIG(dir, entry) ((((dir)<<2) | (entry & 0x3)) & 0x7) #define PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT() { \ @@ -286,7 +290,9 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m .hp_sleep2active_backup_en = 0, \ .hp_modem2active_backup_en = 0, \ }, \ - .backup_clk = (BIT(PMU_ICG_FUNC_ENA_REGDMA) \ + .backup_clk = ( \ + BIT(PMU_ICG_FUNC_ENA_GDMA) \ + | BIT(PMU_ICG_FUNC_ENA_REGDMA) \ | BIT(PMU_ICG_FUNC_ENA_TG0) \ | BIT(PMU_ICG_FUNC_ENA_HPBUS) \ | BIT(PMU_ICG_FUNC_ENA_MSPI) \ @@ -333,14 +339,16 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m .hp_modem2sleep_backup_en = 0, \ .hp_active2sleep_backup_en = 0, \ }, \ - .backup_clk = (BIT(PMU_ICG_FUNC_ENA_REGDMA) \ + .backup_clk = ( \ + BIT(PMU_ICG_FUNC_ENA_GDMA) \ + | BIT(PMU_ICG_FUNC_ENA_REGDMA) \ | BIT(PMU_ICG_FUNC_ENA_TG0) \ | BIT(PMU_ICG_FUNC_ENA_HPBUS) \ | BIT(PMU_ICG_FUNC_ENA_MSPI) \ | BIT(PMU_ICG_FUNC_ENA_IOMUX) \ | BIT(PMU_ICG_FUNC_ENA_SPI2) \ - | BIT(PMU_ICG_FUNC_ENA_SEC) \ - | BIT(PMU_ICG_FUNC_ENA_PWM) \ + | BIT(PMU_ICG_FUNC_ENA_SEC) \ + | BIT(PMU_ICG_FUNC_ENA_PWM) \ | BIT(PMU_ICG_FUNC_ENA_SYSTIMER) \ | BIT(PMU_ICG_FUNC_ENA_UART0)), \ } @@ -359,13 +367,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 \ @@ -403,10 +417,10 @@ const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mod .slp_xpd = 0, \ .xpd = 1, \ .slp_dbias = 0, \ - .dbias = 0xe \ + .dbias = LP_CALI_DBIAS_DEFAULT \ }, \ .regulator1 = { \ - .drv_b = 3 \ + .drv_b = 0 \ } \ } @@ -417,10 +431,10 @@ const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mod .bias_sleep = 1, \ }, \ .regulator0 = { \ - .slp_xpd = 1, \ - .xpd = 0, \ - .slp_dbias = 0xf, \ - .dbias = 0 \ + .slp_xpd = 0, \ + .xpd = 1, \ + .slp_dbias = 0, \ + .dbias = 1 \ }, \ .regulator1 = { \ .drv_b = 9 \ @@ -436,3 +450,53 @@ const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_m assert(mode < ARRAY_SIZE(lp_analog)); return &lp_analog[mode]; } + +uint32_t get_act_hp_dbias(void) +{ + /* hp_cali_dbias is read from efuse to ensure that the hp_active_voltage is close to 0.93V */ + unsigned blk_version = efuse_hal_blk_version(); + uint32_t hp_cali_dbias = HP_CALI_DBIAS_DEFAULT; + if (blk_version >= 3) { + hp_cali_dbias = efuse_ll_get_active_hp_dbias(); + if (hp_cali_dbias != 0) { + //efuse dbias need to add 2 to meet the CPU frequency switching + if (hp_cali_dbias + 2 > 31) { + hp_cali_dbias = 31; + } else { + hp_cali_dbias += 2; + } + } else { + hp_cali_dbias = HP_CALI_DBIAS_DEFAULT; + ESP_HW_LOGD(TAG, "hp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %d\n", blk_version); + } + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, act dbias not burnt in efuse\n"); + } + + return hp_cali_dbias; +} + +uint32_t get_act_lp_dbias(void) +{ + /* lp_cali_dbias are read from efuse to ensure that the lp_active_voltage is close to 0.925V */ + unsigned blk_version = efuse_hal_blk_version(); + uint32_t lp_cali_dbias = LP_CALI_DBIAS_DEFAULT; + if (blk_version >= 3) { + lp_cali_dbias = efuse_ll_get_active_lp_dbias(); + if (lp_cali_dbias != 0) { + //efuse dbias need to add 2 to meet the CPU frequency switching + if (lp_cali_dbias + 2 > 31) { + lp_cali_dbias = 31; + } else { + lp_cali_dbias += 2; + } + } else { + lp_cali_dbias = LP_CALI_DBIAS_DEFAULT; + ESP_HW_LOGD(TAG, "lp_cali_dbias not burnt in efuse or wrong value was burnt in blk version: %d\n", blk_version); + } + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, act dbias not burnt in efuse\n"); + } + + return lp_cali_dbias; +} diff --git a/components/esp_hw_support/port/esp32h2/pmu_sleep.c b/components/esp_hw_support/port/esp32h2/pmu_sleep.c index 30ef282da7..a59e81f1ec 100644 --- a/components/esp_hw_support/port/esp32h2/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32h2/pmu_sleep.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,28 +14,56 @@ #include "soc/soc.h" #include "soc/rtc.h" #include "soc/pmu_struct.h" +#include "hal/lp_aon_hal.h" #include "esp_private/esp_pmu.h" +#include "pmu_param.h" +#include "hal/efuse_ll.h" +#include "hal/efuse_hal.h" +#include "esp_hw_log.h" + +static __attribute__((unused)) const char *TAG = "pmu_sleep"; #define HP(state) (PMU_MODE_HP_ ## state) #define LP(state) (PMU_MODE_LP_ ## state) +uint32_t get_slp_lp_dbias(void) +{ + /* pmu_lp_dbias_sleep_0v7 is read from efuse to ensure that the HP_LDO_voltage is close to 0.68V, + ** and the LP_LDO_voltage is close to 0.73V + */ + uint32_t pmu_lp_dbias_sleep_0v7 = PMU_LP_DBIAS_SLEEP_0V7_DEFAULT; + unsigned blk_version = efuse_hal_blk_version(); + if (blk_version >= 3) { + pmu_lp_dbias_sleep_0v7 = efuse_ll_get_dslp_dbias(); + if (pmu_lp_dbias_sleep_0v7 == 0) { + pmu_lp_dbias_sleep_0v7 = PMU_LP_DBIAS_SLEEP_0V7_DEFAULT; + ESP_HW_LOGD(TAG, "slp dbias not burnt in efuse or wrong value was burnt in blk version: %d\n", blk_version); + } + } else { + ESP_HW_LOGD(TAG, "blk_version is less than 3, slp dbias not burnt in efuse\n"); + } + + return pmu_lp_dbias_sleep_0v7; +} void pmu_sleep_enable_regdma_backup(void) { - /* ESP32H2 does not have PMU HP_AON power domain. because the registers - * of PAU REGDMA is included to PMU TOP power domain, cause the contents - * of PAU REGDMA registers will be lost when the TOP domain is powered down - * during light sleep, so we does not need to enable REGDMA backup here. - * We will use the software to trigger REGDMA to backup or restore. */ + assert(PMU_instance()->hal); + /* entry 0, 1, 2 is used by pmu HP_SLEEP and HP_ACTIVE, HP_SLEEP + * and HP_MODEM or HP_MODEM and HP_ACTIVE states switching, + * respectively. entry 3 is reserved, not used yet! */ + pmu_hal_hp_set_sleep_active_backup_enable(PMU_instance()->hal); } void pmu_sleep_disable_regdma_backup(void) { + assert(PMU_instance()->hal); + pmu_hal_hp_set_sleep_active_backup_disable(PMU_instance()->hal); } uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_period, uint32_t fastclk_period) { - const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; /* LP core hardware wait time, microsecond */ const int lp_clk_switch_time_us = rtc_time_slowclk_to_us(mc->lp.clk_switch_cycle, slowclk_period); @@ -47,6 +75,11 @@ uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_pe /* HP core hardware wait time, microsecond */ const int hp_digital_power_up_wait_time_us = mc->hp.power_supply_wait_time_us + mc->hp.power_up_wait_time_us; + if (pd_flags & PMU_SLEEP_PD_TOP) { + mc->hp.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US; + } else { + mc->hp.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_PU_TOP_US; + } const int hp_regdma_wait_time_us = mc->hp.regdma_s2a_work_time_us; const int hp_clock_wait_time_us = mc->hp.xtal_wait_stable_time_us + mc->hp.pll_wait_stable_time_us; @@ -113,27 +146,27 @@ const pmu_sleep_config_t* pmu_sleep_config_default( if (dslp) { pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags); + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_slp_lp_dbias(); config->analog = analog_default; } else { pmu_sleep_digital_config_t digital_default = PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags); config->digital = digital_default; pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags); - if (!(pd_flags & PMU_SLEEP_PD_TOP) || !(pd_flags & PMU_SLEEP_PD_MODEM)){ - analog_default.hp_sys.analog.xpd = 1; - analog_default.hp_sys.analog.dbias = 2; - } + analog_default.hp_sys.analog.dbias = PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT; + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_slp_lp_dbias(); if (!(pd_flags & PMU_SLEEP_PD_XTAL)){ - analog_default.hp_sys.analog.xpd_trx = 1; - analog_default.hp_sys.analog.xpd = 1; - analog_default.hp_sys.analog.dbias = 25; - analog_default.hp_sys.analog.pd_cur = 0; - analog_default.hp_sys.analog.bias_sleep = 0; - - analog_default.lp_sys[LP(SLEEP)].analog.xpd = 1; - analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = 0; - analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = 0; - analog_default.lp_sys[LP(SLEEP)].analog.dbias = 26; + analog_default.hp_sys.analog.xpd_trx = PMU_XPD_TRX_SLEEP_ON; + analog_default.hp_sys.analog.dbias = get_act_hp_dbias(); + analog_default.hp_sys.analog.pd_cur = PMU_PD_CUR_SLEEP_ON; + analog_default.hp_sys.analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; + + analog_default.lp_sys[LP(SLEEP)].analog.pd_cur = PMU_PD_CUR_SLEEP_ON; + analog_default.lp_sys[LP(SLEEP)].analog.bias_sleep = PMU_BIASSLP_SLEEP_ON; + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias(); + } else if (!(pd_flags & PMU_SLEEP_PD_RC_FAST)) { + analog_default.hp_sys.analog.dbias = get_act_hp_dbias(); + analog_default.lp_sys[LP(SLEEP)].analog.dbias = get_act_lp_dbias(); } config->analog = analog_default; } @@ -164,23 +197,13 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con assert(ctx->hal); pmu_ll_hp_set_current_power_off (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.pd_cur); pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.bias_sleep); - pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_xpd); - pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_xpd); pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd); - pmu_ll_hp_set_regulator_sleep_memory_dbias(ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_dbias); - pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_dbias); pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias); pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b); pmu_ll_hp_set_trx_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd_trx); - - pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_xpd); - pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_dbias); - pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.xpd); - pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.dbias); - pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.drv_b); - pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur); pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep); + pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_xpd); pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd); pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias); pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias); @@ -218,6 +241,8 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp { assert(PMU_instance()->hal); + lp_aon_hal_inform_wakeup_type(dslp); + pmu_ll_hp_set_wakeup_enable(PMU_instance()->hal->dev, wakeup_opt); pmu_ll_hp_set_reject_enable(PMU_instance()->hal->dev, reject_opt); @@ -240,3 +265,9 @@ bool pmu_sleep_finish(void) { return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); } + +uint32_t pmu_sleep_get_wakup_retention_cost(void) +{ + const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + return mc->hp.regdma_s2a_work_time_us; +} 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 22ca4216e4..58fbf97ff4 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 @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,42 @@ extern "C" { #endif +#define HP_CALI_DBIAS_DEFAULT 17 +#define LP_CALI_DBIAS_DEFAULT 18 + +// FOR XTAL FORCE PU IN SLEEP +#define PMU_PD_CUR_SLEEP_ON 0 +#define PMU_BIASSLP_SLEEP_ON 0 +#define PMU_XPD_TRX_SLEEP_ON 1 + + +// FOR BOTH LIGHTSLEEP & DEEPSLEEP +#define PMU_PD_CUR_SLEEP_DEFAULT 1 +#define PMU_BIASSLP_SLEEP_DEFAULT 1 +#define PMU_LP_XPD_SLEEP_DEFAULT 1 +#define PMU_XPD_TRX_SLEEP_DEFAULT 0 +#define PMU_LP_SLP_XPD_SLEEP_DEFAULT 0 +#define PMU_LP_SLP_DBIAS_SLEEP_DEFAULT 0 + +// FOR LIGHTSLEEP +#define PMU_HP_XPD_LIGHTSLEEP 1 +#define PMU_HP_DRVB_LIGHTSLEEP 0xFFFFF8 +#define PMU_LP_DRVB_LIGHTSLEEP 0 + +#define PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT 1 +#define PMU_LP_DBIAS_SLEEP_0V7_DEFAULT 6 + +#define PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US 0 +// The current value of this depends on the restoration time overhead of the longest chain in regdma +#define PMU_REGDMA_S2A_WORK_TIME_PU_TOP_US 390 + +// FOR DEEPSLEEP +#define PMU_HP_XPD_DEEPSLEEP 0 +#define PMU_LP_DRVB_DEEPSLEEP 7 + +uint32_t get_act_hp_dbias(void); +uint32_t get_act_lp_dbias(void); + typedef struct { pmu_hp_dig_power_reg_t dig_power; pmu_hp_clk_power_reg_t clk_power; @@ -250,8 +286,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 \ } \ }, \ @@ -291,80 +327,48 @@ typedef struct { } lp_sys[PMU_MODE_LP_MAX]; } pmu_sleep_analog_config_t; -#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \ - .hp_sys = { \ - .analog = { \ - .xpd_trx = 0, \ - .xpd_bias = 0x0, \ - .pd_cur = 1, \ - .bias_sleep = 1, \ - .slp_mem_xpd = 0, \ - .slp_logic_xpd = 0, \ - .slp_mem_dbias = 0, \ - .slp_logic_dbias = 0, \ - .xpd = 1, \ - .dbias = 0, \ - .drv_b = 0xFFFFF8 \ - } \ - }, \ - .lp_sys[PMU_MODE_LP_ACTIVE] = { \ - .analog = { \ - .slp_xpd = 0, \ - .slp_dbias = 0x0, \ - .xpd = 1, \ - .dbias = 0xe, \ - .drv_b = 0x0 \ - } \ - }, \ - .lp_sys[PMU_MODE_LP_SLEEP] = { \ - .analog = { \ - .xpd_bias = 0, \ - .pd_cur = 1, \ - .bias_sleep = 1, \ - .xpd = 0, \ - .dbias = 0, \ - .slp_xpd = 1, \ - .slp_dbias = 0x5, \ - .drv_b = 0x7 \ - } \ - } \ -} - -#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags) { \ +#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \ .hp_sys = { \ .analog = { \ - .xpd_bias = 0, \ - .pd_cur = 1, \ - .bias_sleep = 1, \ - .xpd = 0, \ - .dbias = 0x15, \ - .slp_mem_xpd = 1, \ - .slp_mem_dbias = 0xc, \ - .slp_logic_xpd = 1, \ - .slp_logic_dbias = 0x5, \ - .drv_b = 0x18c \ + .xpd_trx = PMU_XPD_TRX_SLEEP_DEFAULT, \ + .drv_b = PMU_HP_DRVB_LIGHTSLEEP, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ + .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ + .xpd = PMU_HP_XPD_LIGHTSLEEP, \ + .dbias = PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT \ } \ }, \ - .lp_sys[PMU_MODE_LP_ACTIVE] = { \ + .lp_sys[PMU_MODE_LP_SLEEP] = { \ + .analog = { \ + .drv_b = PMU_LP_DRVB_DEEPSLEEP, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ + .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ + .slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \ + .slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT,\ + .xpd = PMU_LP_XPD_SLEEP_DEFAULT, \ + .dbias = PMU_LP_DBIAS_SLEEP_0V7_DEFAULT \ + } \ + } \ +} + +#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ .analog = { \ - .xpd = 1, \ - .dbias = 0x1a, \ - .slp_xpd = 0, \ - .slp_dbias = 0, \ - .drv_b = 0x7 \ + .xpd_trx = PMU_XPD_TRX_SLEEP_DEFAULT, \ + .pd_cur = PMU_PD_CUR_SLEEP_ON, \ + .bias_sleep = PMU_BIASSLP_SLEEP_ON, \ + .xpd = PMU_HP_XPD_DEEPSLEEP \ } \ }, \ .lp_sys[PMU_MODE_LP_SLEEP] = { \ .analog = { \ - .xpd_bias = 0, \ - .dbg_atten = 0xe, \ - .pd_cur = 1, \ - .bias_sleep = 1, \ - .xpd = 0, \ - .dbias = 0, \ - .slp_xpd = 1, \ - .slp_dbias = 0xe, \ - .drv_b = 0 \ + .drv_b = PMU_LP_DRVB_DEEPSLEEP, \ + .pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \ + .bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \ + .slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \ + .slp_dbias = PMU_LP_SLP_DBIAS_SLEEP_DEFAULT,\ + .xpd = PMU_LP_XPD_SLEEP_DEFAULT, \ + .dbias = PMU_LP_DBIAS_SLEEP_0V7_DEFAULT \ } \ } \ } @@ -440,7 +444,7 @@ typedef struct pmu_sleep_machine_constant { .analog_wait_time_us = 154, \ .power_supply_wait_time_us = 2, \ .power_up_wait_time_us = 2, \ - .regdma_s2a_work_time_us = 0, \ + .regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US, \ .regdma_a2s_work_time_us = 0, \ .xtal_wait_stable_time_us = 250, \ .pll_wait_stable_time_us = 1 \ diff --git a/components/esp_hw_support/port/esp32h2/private_include/sleep_gdma_retention_context.inc b/components/esp_hw_support/port/esp32h2/private_include/sleep_gdma_retention_context.inc new file mode 100644 index 0000000000..803ff57073 --- /dev/null +++ b/components/esp_hw_support/port/esp32h2/private_include/sleep_gdma_retention_context.inc @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc_caps.h" +#include "soc/gdma_reg.h" + + +/* GDMA Channel (Group0, Pair0) Registers Context + Include: GDMA_MISC_CONF_REG / + GDMA_IN_INT_ENA_CH0_REG / GDMA_OUT_INT_ENA_CH0_REG / GDMA_IN_PERI_SEL_CH0_REG / GDMA_OUT_PERI_SEL_CH0_REG + GDMA_IN_CONF0_CH0_REG / GDMA_IN_CONF1_CH0_REG / GDMA_IN_LINK_CH0_REG / GDMA_IN_PRI_CH0_REG + GDMA_OUT_CONF0_CH0_REG / GDMA_OUT_CONF1_CH0_REG / GDMA_OUT_LINK_CH0_REG /GDMA_OUT_PRI_CH0_REG +*/ +#define G0P0_RETENTION_REGS_CNT 13 +#define G0P0_RETENTION_MAP_BASE GDMA_IN_INT_ENA_CH0_REG +static const uint32_t g0p0_regs_map[4] = {0x4C801001, 0x604C0060, 0, 0}; +static const sleep_retention_entries_config_t gdma_g0p0_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P0_RETENTION_MAP_BASE, G0P0_RETENTION_MAP_BASE, \ + G0P0_RETENTION_REGS_CNT, 0, 0, \ + g0p0_regs_map[0], g0p0_regs_map[1], \ + g0p0_regs_map[2], g0p0_regs_map[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +/* GDMA Channel (Group0, Pair1) Registers Context + Include: GDMA_MISC_CONF_REG / + GDMA_IN_INT_ENA_CH1_REG / GDMA_OUT_INT_ENA_CH1_REG / GDMA_IN_PERI_SEL_CH1_REG / GDMA_OUT_PERI_SEL_CH1_REG + GDMA_IN_CONF0_CH1_REG / GDMA_IN_CONF1_CH1_REG / GDMA_IN_LINK_CH1_REG / GDMA_IN_PRI_CH1_REG + GDMA_OUT_CONF0_CH1_REG / GDMA_OUT_CONF1_CH1_REG / GDMA_OUT_LINK_CH1_REG /GDMA_OUT_PRI_CH1_REG +*/ +#define G0P1_RETENTION_REGS_CNT 13 +#define G0P1_RETENTION_MAP_BASE GDMA_IN_INT_ENA_CH1_REG +static const uint32_t g0p1_regs_map[4] = {0x81001, 0, 0xC00604C0, 0x604}; +static const sleep_retention_entries_config_t gdma_g0p1_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P1_RETENTION_MAP_BASE, G0P1_RETENTION_MAP_BASE, \ + G0P1_RETENTION_REGS_CNT, 0, 0, \ + g0p1_regs_map[0], g0p1_regs_map[1], \ + g0p1_regs_map[2], g0p1_regs_map[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +/* GDMA Channel (Group0, Pair2) Registers Context + Include: GDMA_MISC_CONF_REG / + GDMA_IN_INT_ENA_CH2_REG / GDMA_OUT_INT_ENA_CH2_REG / GDMA_IN_PERI_SEL_CH2_REG / GDMA_OUT_PERI_SEL_CH2_REG + GDMA_IN_CONF0_CH2_REG / GDMA_IN_CONF1_CH2_REG / GDMA_IN_LINK_CH2_REG / GDMA_IN_PRI_CH2_REG + GDMA_OUT_CONF0_CH2_REG / GDMA_OUT_CONF1_CH2_REG / GDMA_OUT_LINK_CH2_REG /GDMA_OUT_PRI_CH2_REG +*/ +#define G0P2_RETENTION_REGS_CNT_0 6 +#define G0P2_RETENTION_MAP_BASE_0 GDMA_IN_INT_ENA_CH2_REG +#define G0P2_RETENTION_REGS_CNT_1 7 +#define G0P2_RETENTION_MAP_BASE_1 GDMA_IN_PRI_CH2_REG +static const uint32_t g0p2_regs_map0[4] = {0x9001, 0, 0, 0x4C0000}; +static const uint32_t g0p2_regs_map1[4] = {0x3026003, 0, 0, 0}; +static const sleep_retention_entries_config_t gdma_g0p2_regs_retention[] = { + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P2_RETENTION_MAP_BASE_0, G0P2_RETENTION_MAP_BASE_0, \ + G0P2_RETENTION_REGS_CNT_0, 0, 0, \ + g0p2_regs_map0[0], g0p2_regs_map0[1], \ + g0p2_regs_map0[2], g0p2_regs_map0[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, + [1] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_MODEM_GDMA_LINK(0x00), \ + G0P2_RETENTION_MAP_BASE_1, G0P2_RETENTION_MAP_BASE_1, \ + G0P2_RETENTION_REGS_CNT_1, 0, 0, \ + g0p2_regs_map1[0], g0p2_regs_map1[1], \ + g0p2_regs_map1[2], g0p2_regs_map1[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, +}; + +const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_GROUPS][SOC_GDMA_PAIRS_PER_GROUP] = { + [0] = { + [0] = {gdma_g0p0_regs_retention, ARRAY_SIZE(gdma_g0p0_regs_retention)}, + [1] = {gdma_g0p1_regs_retention, ARRAY_SIZE(gdma_g0p1_regs_retention)}, + [2] = {gdma_g0p2_regs_retention, ARRAY_SIZE(gdma_g0p2_regs_retention)} + } +}; diff --git a/components/esp_hw_support/port/esp32h2/rtc_clk.c b/components/esp_hw_support/port/esp32h2/rtc_clk.c index d834c09cb4..1f6fd3b8fe 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32h2/rtc_clk.c @@ -20,6 +20,13 @@ #include "soc/io_mux_reg.h" #include "soc/lp_aon_reg.h" #include "soc/lp_clkrst_reg.h" +#include "esp_private/sleep_event.h" + +#ifdef BOOTLOADER_BUILD +#include "hal/modem_lpcon_ll.h" +#else +#include "esp_private/esp_modem_clock.h" +#endif static const char *TAG = "rtc_clk"; @@ -154,19 +161,34 @@ static void rtc_clk_bbpll_enable(void) clk_ll_bbpll_enable(); } +static void rtc_clk_enable_i2c_ana_master_clock(bool enable) +{ +#ifdef BOOTLOADER_BUILD + modem_lpcon_ll_enable_i2c_master_clock(&MODEM_LPCON, enable); +#else + if (enable) { + modem_clock_module_enable(PERIPH_ANA_I2C_MASTER_MODULE); + } else { + modem_clock_module_disable(PERIPH_ANA_I2C_MASTER_MODULE); + } +#endif +} + static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq) { /* Digital part */ clk_ll_bbpll_set_freq_mhz(pll_freq); /* Analog part */ + rtc_clk_enable_i2c_ana_master_clock(true); /* BBPLL CALIBRATION START */ regi2c_ctrl_ll_bbpll_calibration_start(); clk_ll_bbpll_set_config(pll_freq, xtal_freq); /* WAIT CALIBRATION DONE */ while(!regi2c_ctrl_ll_bbpll_calibration_is_done()); + esp_rom_delay_us(10); /* BBPLL CALIBRATION STOP */ regi2c_ctrl_ll_bbpll_calibration_stop(); - + rtc_clk_enable_i2c_ana_master_clock(false); s_cur_pll_freq = pll_freq; } @@ -277,6 +299,10 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou return true; } +__attribute__((weak)) void rtc_clk_set_cpu_switch_to_bbpll(int event_id) +{ +} + void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) { soc_cpu_clk_src_t old_cpu_clk_src = clk_ll_cpu_get_src(); @@ -288,10 +314,12 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) } } else if (config->source == SOC_CPU_CLK_SRC_PLL) { if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL && old_cpu_clk_src != SOC_CPU_CLK_SRC_FLASH_PLL) { + rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_BBPLL_EN_START); rtc_clk_bbpll_enable(); rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz); } rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz); + rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_BBPLL_EN_STOP); } else if (config->source == SOC_CPU_CLK_SRC_RC_FAST) { rtc_clk_cpu_freq_to_8m(); if ((old_cpu_clk_src == SOC_CPU_CLK_SRC_PLL || old_cpu_clk_src == SOC_CPU_CLK_SRC_FLASH_PLL) && @@ -302,10 +330,12 @@ void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config) if (old_cpu_clk_src != SOC_CPU_CLK_SRC_PLL && old_cpu_clk_src != SOC_CPU_CLK_SRC_FLASH_PLL) { // On ESP32H2, FLASH_PLL (64MHz) is directly derived from the BBPLL (96MHz) // Therefore, enabling and configuration are applied to BBPLL. + rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_FLASH_BBPLL_EN_START); rtc_clk_bbpll_enable(); rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), CLK_LL_PLL_96M_FREQ_MHZ); } rtc_clk_cpu_freq_to_flash_pll(config->freq_mhz, config->div); + rtc_clk_set_cpu_switch_to_bbpll(SLEEP_EVENT_HW_FLASH_BBPLL_EN_STOP); } } @@ -445,3 +475,21 @@ bool rtc_dig_8m_enabled(void) { return clk_ll_rc_fast_digi_is_enabled(); } + +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +void rtc_clk_recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. Flash_PLL comes from the same source as PLL. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL || old_config.source == SOC_CPU_CLK_SRC_FLASH_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} diff --git a/components/esp_hw_support/port/esp32h2/rtc_clk_init.c b/components/esp_hw_support/port/esp32h2/rtc_clk_init.c index aaa476e5b6..c01cd13947 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32h2/rtc_clk_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,8 @@ #include "sdkconfig.h" #include "esp_rom_uart.h" #include "hal/clk_tree_ll.h" +#include "soc/pmu_reg.h" +#include "pmu_param.h" static const char *TAG = "rtc_clk_init"; @@ -39,6 +41,15 @@ void rtc_clk_init(rtc_clk_config_t cfg) REG_SET_FIELD(LP_CLKRST_FOSC_CNTL_REG, LP_CLKRST_FOSC_DFREQ, cfg.clk_8m_dfreq); REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OC_SCK_DCAP, cfg.slow_clk_dcap); REG_SET_FIELD(LP_CLKRST_RC32K_CNTL_REG, LP_CLKRST_RC32K_DFREQ, cfg.rc32k_dfreq); + REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG, 0); + REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG, 0); + + uint32_t hp_cali_dbias = get_act_hp_dbias(); + uint32_t lp_cali_dbias = get_act_lp_dbias(); + + SET_PERI_REG_BITS(PMU_HP_MODEM_HP_REGULATOR0_REG, PMU_HP_MODEM_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_MODEM_HP_REGULATOR_DBIAS_S); + SET_PERI_REG_BITS(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, hp_cali_dbias, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS_S); + SET_PERI_REG_BITS(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, lp_cali_dbias, PMU_HP_SLEEP_LP_REGULATOR_DBIAS_S); clk_ll_rc_fast_tick_conf(); diff --git a/components/esp_hw_support/port/esp32h2/rtc_time.c b/components/esp_hw_support/port/esp32h2/rtc_time.c index 4502e98015..2dfac35c71 100644 --- a/components/esp_hw_support/port/esp32h2/rtc_time.c +++ b/components/esp_hw_support/port/esp32h2/rtc_time.c @@ -208,6 +208,7 @@ static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cy uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); /*The Fosc CLK of calibration circuit is divided by 32 for ECO2. @@ -233,6 +234,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) { + assert(period); /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. * TODO: fix overflow. */ diff --git a/components/esp_hw_support/port/esp32h2/sar_periph_ctrl.c b/components/esp_hw_support/port/esp32h2/sar_periph_ctrl.c index 9d72d3c2db..4acb3fc48d 100644 --- a/components/esp_hw_support/port/esp32h2/sar_periph_ctrl.c +++ b/components/esp_hw_support/port/esp32h2/sar_periph_ctrl.c @@ -18,6 +18,7 @@ #include "esp_log.h" #include "esp_private/sar_periph_ctrl.h" +#include "esp_private/esp_modem_clock.h" #include "hal/sar_ctrl_ll.h" static const char *TAG = "sar_periph_ctrl"; @@ -59,6 +60,7 @@ static int s_pwdet_power_on_cnt; static void s_sar_power_acquire(void) { + modem_clock_module_enable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); ENTER_CRITICAL_SECTION(); s_pwdet_power_on_cnt++; if (s_pwdet_power_on_cnt == 1) { @@ -79,6 +81,7 @@ static void s_sar_power_release(void) sar_ctrl_ll_set_power_mode_from_pwdet(SAR_CTRL_LL_POWER_FSM); } LEAVE_CRITICAL_SECTION(); + modem_clock_module_disable(PERIPH_MODEM_ADC_COMMON_FE_MODULE); } diff --git a/components/esp_hw_support/port/esp32p4/esp_cpu_intr.c b/components/esp_hw_support/port/esp32p4/esp_cpu_intr.c new file mode 100644 index 0000000000..da246c75de --- /dev/null +++ b/components/esp_hw_support/port/esp32p4/esp_cpu_intr.c @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_cpu.h" +#include "esp_riscv_intr.h" + +void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) +{ + /* On targets that uses CLIC as the interrupt controller, the first 16 lines (0..15) are reserved for software + * interrupts, all the other lines starting from 16 and above can be used by external peripheral. + * + * Only interrupt line 6 is reserved at the moment since it is used for disabling interrupts in the + * interrupt allocator (INT_MUX_DISABLED_INTNO) */ + const uint32_t rsvd_mask = BIT(6); + + intr_desc_ret->priority = 1; + intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; + intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask); +} diff --git a/components/esp_hw_support/port/esp32s2/CMakeLists.txt b/components/esp_hw_support/port/esp32s2/CMakeLists.txt index a2a386d9d0..a0ee667fd6 100644 --- a/components/esp_hw_support/port/esp32s2/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32s2/CMakeLists.txt @@ -1,5 +1,4 @@ target_include_directories(${COMPONENT_LIB} PUBLIC .) -target_include_directories(${COMPONENT_LIB} PUBLIC private_include) set(srcs "rtc_clk.c" diff --git a/components/esp_hw_support/port/esp32s2/Kconfig.rtc b/components/esp_hw_support/port/esp32s2/Kconfig.rtc index 338a394b76..aa874f49dd 100644 --- a/components/esp_hw_support/port/esp32s2/Kconfig.rtc +++ b/components/esp_hw_support/port/esp32s2/Kconfig.rtc @@ -35,7 +35,8 @@ config RTC_CLK_CAL_CYCLES int "Number of cycles for RTC_SLOW_CLK calibration" default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 default 576 if RTC_CLK_SRC_INT_RC - range 0 125000 + range 0 8190 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 + range 0 32766 if RTC_CLK_SRC_INT_RC help When the startup code initializes RTC_SLOW_CLK, it can perform calibration by comparing the RTC_SLOW_CLK frequency with main XTAL 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 c98c6479fe..954f931148 100644 --- a/components/esp_hw_support/port/esp32s2/adc2_init_cal.c +++ b/components/esp_hw_support/port/esp32s2/adc2_init_cal.c @@ -26,9 +26,9 @@ extern int rtc_spinlock; static 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); ENTER_CRITICAL_SECTION(); - adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_11); + adc_set_hw_calibration_code(ADC_UNIT_2, ADC_ATTEN_DB_12); LEAVE_CRITICAL_SECTION(); } diff --git a/components/esp_hw_support/port/esp32s2/esp_cpu_intr.c b/components/esp_hw_support/port/esp32s2/esp_cpu_intr.c new file mode 100644 index 0000000000..34979086e6 --- /dev/null +++ b/components/esp_hw_support/port/esp32s2/esp_cpu_intr.c @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include +#include "soc/soc_caps.h" +#include "esp_cpu.h" + +/* Xtensa core has 3 interrupts dedicated to timers, we can use either timer0 or timer1 depending on the Kconfig, + * timer2 is always set to SPECIAL in our configuration array */ + +/** + * @brief Type defined for the table below + */ +typedef struct { + int priority; + esp_cpu_intr_type_t type; + uint32_t flags; +} intr_desc_t; + + +const static intr_desc_t intr_desc_table [SOC_CPU_INTR_NUM] = { + /* Interrupt 0 reserved for WMAC (Wifi) */ + [0] = { 1, ESP_CPU_INTR_TYPE_LEVEL, ESP_CPU_INTR_DESC_FLAG_RESVD }, + [1] = { 1, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [2] = { 1, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [3] = { 1, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + /* Interrupt 4 reserved for WBB */ + [4] = { 1, ESP_CPU_INTR_TYPE_LEVEL, ESP_CPU_INTR_DESC_FLAG_RESVD }, + [5] = { 1, ESP_CPU_INTR_TYPE_LEVEL, 0 }, +#if CONFIG_FREERTOS_CORETIMER_0 + [6] = { 1, ESP_CPU_INTR_TYPE_NA, ESP_CPU_INTR_DESC_FLAG_RESVD }, +#else + [6] = { 1, ESP_CPU_INTR_TYPE_NA, ESP_CPU_INTR_DESC_FLAG_SPECIAL }, +#endif + [7] = { 1, ESP_CPU_INTR_TYPE_NA, ESP_CPU_INTR_DESC_FLAG_SPECIAL }, + [8] = { 1, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [9] = { 1, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [10] = { 1, ESP_CPU_INTR_TYPE_EDGE, 0 }, + [11] = { 3, ESP_CPU_INTR_TYPE_NA, ESP_CPU_INTR_DESC_FLAG_SPECIAL }, + [12] = { 1, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [13] = { 1, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + /* Interrupt 14 reserved for NMI (Non-Maskable Interrupts) */ + [14] = { 7, ESP_CPU_INTR_TYPE_LEVEL, ESP_CPU_INTR_DESC_FLAG_RESVD }, +#if CONFIG_FREERTOS_CORETIMER_1 + [15] = { 3, ESP_CPU_INTR_TYPE_NA, ESP_CPU_INTR_DESC_FLAG_RESVD }, +#else + [15] = { 3, ESP_CPU_INTR_TYPE_NA, ESP_CPU_INTR_DESC_FLAG_SPECIAL }, +#endif + [16] = { 5, ESP_CPU_INTR_TYPE_NA, ESP_CPU_INTR_DESC_FLAG_SPECIAL }, + [17] = { 1, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [18] = { 1, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [19] = { 2, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [20] = { 2, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [21] = { 2, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [22] = { 3, ESP_CPU_INTR_TYPE_EDGE, 0 }, + [23] = { 3, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + /* Interrupt 24 reserved for T1 WDT */ + [24] = { 4, ESP_CPU_INTR_TYPE_LEVEL, ESP_CPU_INTR_DESC_FLAG_RESVD }, + /* Interrupt 25 reserved for memory access errors */ + [25] = { 4, ESP_CPU_INTR_TYPE_LEVEL, ESP_CPU_INTR_DESC_FLAG_RESVD }, + [26] = { 5, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [27] = { 3, ESP_CPU_INTR_TYPE_LEVEL, 0 }, + [28] = { 4, ESP_CPU_INTR_TYPE_EDGE, 0 }, + [29] = { 3, ESP_CPU_INTR_TYPE_NA, ESP_CPU_INTR_DESC_FLAG_SPECIAL }, + [30] = { 4, ESP_CPU_INTR_TYPE_EDGE, 0 }, + [31] = { 5, ESP_CPU_INTR_TYPE_LEVEL, 0 }, +}; + + +void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) +{ + assert(core_id == 0 && intr_num < SOC_CPU_INTR_NUM && intr_desc_ret != NULL); + intr_desc_ret->priority = intr_desc_table[intr_num].priority; + intr_desc_ret->type = intr_desc_table[intr_num].type; + intr_desc_ret->flags = intr_desc_table[intr_num].flags; +} diff --git a/components/esp_hw_support/port/esp32s2/rtc_clk.c b/components/esp_hw_support/port/esp32s2/rtc_clk.c index 9f788edbd3..f4627e0605 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s2/rtc_clk.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 */ @@ -256,13 +256,41 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq) */ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) { - int dbias = (cpu_freq_mhz == 240) ? DIG_DBIAS_240M : DIG_DBIAS_80M_160M; + /* To avoid the problem of insufficient voltage when the CPU frequency is switched: + * When the CPU frequency is switched from low to high, it is necessary to + * increase the voltage first and then increase the frequency, and the frequency + * needs to wait for the voltage to fully increase before proceeding. + * When the frequency of the CPU is switched from high to low, it is necessary + * to reduce the frequency first and then reduce the voltage. + */ + + rtc_cpu_freq_config_t cur_config; + rtc_clk_cpu_freq_get_config(&cur_config); + /* cpu_frequency < 240M: dbias = DIG_DBIAS_XTAL_80M_160M; + * cpu_frequency = 240M: dbias = DIG_DBIAS_240M; + */ + if (cpu_freq_mhz > cur_config.freq_mhz) { + if (cpu_freq_mhz == 240) { + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_240M); + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, RTC_DBIAS_240M); + esp_rom_delay_us(40); + } + } + clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz); clk_ll_cpu_set_divider(1); - REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); rtc_clk_apb_freq_update(80 * MHZ); esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); + + if (cpu_freq_mhz < cur_config.freq_mhz) { + if (cur_config.freq_mhz == 240) { + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL_80M_160M); + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, RTC_DBIAS_XTAL_80M_160M); + esp_rom_delay_us(40); + } + } + } bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t* out_config) @@ -411,6 +439,9 @@ void rtc_clk_cpu_set_to_default_config(void) */ static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div) { + rtc_cpu_freq_config_t cur_config; + rtc_clk_cpu_freq_get_config(&cur_config); + esp_rom_set_cpu_ticks_per_us(cpu_freq); /* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */ clk_ll_cpu_set_divider(1); @@ -419,15 +450,25 @@ static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div) /* switch clock source */ clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL); rtc_clk_apb_freq_update(cpu_freq * MHZ); - /* lower the voltage */ - int dbias = (cpu_freq <= 2) ? DIG_DBIAS_2M : DIG_DBIAS_XTAL; - REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias); + + /* lower the voltage + * cpu_frequency < 240M: dbias = DIG_DBIAS_XTAL_80M_160M; + * cpu_frequency = 240M: dbias = DIG_DBIAS_240M; + */ + if (cur_config.freq_mhz == 240) { + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL_80M_160M); + REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, RTC_DBIAS_XTAL_80M_160M); + esp_rom_delay_us(40); + } + } static void rtc_clk_cpu_freq_to_8m(void) { + assert(0 && "LDO dbias need to modified"); esp_rom_set_cpu_ticks_per_us(8); REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL); + esp_rom_delay_us(40); clk_ll_cpu_set_divider(1); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST); rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX); diff --git a/components/esp_hw_support/port/esp32s2/rtc_init.c b/components/esp_hw_support/port/esp32s2/rtc_init.c index 5674123f79..549cdffd43 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_init.c +++ b/components/esp_hw_support/port/esp32s2/rtc_init.c @@ -37,6 +37,7 @@ void rtc_init(rtc_config_t cfg) * No worry about the power consumption, Because modem Force PD will be set at the end of this function. */ CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU); REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, cfg.pll_wait); @@ -46,7 +47,7 @@ void rtc_init(rtc_config_t cfg) // set shortest possible sleep time limit REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL, RTC_CNTL_MIN_SLP_VAL_MIN); - /* This power domian removed + /* This power domain removed * set rom&ram timer * REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_ROM_RAM_POWERUP_TIMER, ROM_RAM_POWERUP_CYCLES); * REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_ROM_RAM_WAIT_TIMER, ROM_RAM_WAIT_CYCLES); diff --git a/components/esp_hw_support/port/esp32s2/rtc_sleep.c b/components/esp_hw_support/port/esp32s2/rtc_sleep.c index 46d786f6b8..31e5f3f293 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32s2/rtc_sleep.c @@ -201,7 +201,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) } if (cfg.wifi_pd_en) { - REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO | RTC_CNTL_WIFI_FORCE_ISO); + REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO); REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU); SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN); } else { diff --git a/components/esp_hw_support/port/esp32s2/rtc_time.c b/components/esp_hw_support/port/esp32s2/rtc_time.c index aae694037e..9723d8366b 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_time.c +++ b/components/esp_hw_support/port/esp32s2/rtc_time.c @@ -121,6 +121,7 @@ static uint32_t rtc_clk_cal_internal_cycling(rtc_cal_sel_t cal_clk, uint32_t slo */ static uint32_t rtc_clk_xtal_to_slowclk(uint64_t xtal_cycles, uint32_t slowclk_cycles) { + assert(slowclk_cycles); rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles; uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider; @@ -189,6 +190,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, ui uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles, RTC_TIME_CAL_ONEOFF_MODE); uint64_t ratio_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT)) / slowclk_cycles; uint32_t ratio = (uint32_t)(ratio_64 & UINT32_MAX); @@ -222,6 +224,7 @@ uint32_t rtc_clk_cal_cycling(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) { + assert(period); /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. * TODO: fix overflow. */ diff --git a/components/esp_hw_support/port/esp32s3/CMakeLists.txt b/components/esp_hw_support/port/esp32s3/CMakeLists.txt index bb4a29c5af..4829b57f34 100644 --- a/components/esp_hw_support/port/esp32s3/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32s3/CMakeLists.txt @@ -1,5 +1,4 @@ target_include_directories(${COMPONENT_LIB} PUBLIC .) -target_include_directories(${COMPONENT_LIB} PUBLIC private_include) set(srcs "rtc_clk.c" diff --git a/components/esp_hw_support/port/esp32s3/Kconfig.rtc b/components/esp_hw_support/port/esp32s3/Kconfig.rtc index b68d2a9199..2125a01f52 100644 --- a/components/esp_hw_support/port/esp32s3/Kconfig.rtc +++ b/components/esp_hw_support/port/esp32s3/Kconfig.rtc @@ -20,7 +20,7 @@ config RTC_CLK_CAL_CYCLES int "Number of cycles for RTC_SLOW_CLK calibration" default 3000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 default 1024 if RTC_CLK_SRC_INT_RC - range 0 27000 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 + range 0 8190 if RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC || RTC_CLK_SRC_INT_8MD256 range 0 32766 if RTC_CLK_SRC_INT_RC help When the startup code initializes RTC_SLOW_CLK, it can perform diff --git a/components/esp_hw_support/port/esp32s3/esp_cpu_intr.c b/components/esp_hw_support/port/esp32s3/esp_cpu_intr.c new file mode 100644 index 0000000000..7c0ef80acc --- /dev/null +++ b/components/esp_hw_support/port/esp32s3/esp_cpu_intr.c @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "esp_cpu.h" + +/* The ESP32-S3 uses the SysTimer for the FreeRTOS system tick, there is no need to use Xtensa core timer interrupts, + * marked as ESP_CPU_INTR_DESC_FLAG_SPECIAL in the table below */ + +/** + * @brief Type defined for the table below + */ +typedef struct { + int priority; + esp_cpu_intr_type_t type; + uint32_t flags[SOC_CPU_CORES_NUM]; +} intr_desc_t; + + +const static intr_desc_t intr_desc_table [SOC_CPU_INTR_NUM] = { + /* Interrupt 0 reserved for WMAC (Wifi) */ +#if CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0 + [0] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, 0 } }, +#else + [0] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, ESP_CPU_INTR_DESC_FLAG_RESVD } }, +#endif + [1] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [2] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [3] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + /* Interrupt 4 reserved for WBB */ + [4] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, 0 } }, + [5] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [6] = { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, + [7] = { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, + [8] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [9] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [10] = { 1, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } }, + [11] = { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, + [12] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [13] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + /* Interrupt 14 reserved for NMI (Non-Maskable Interrupts) */ + [14] = { 7, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, // NMI + [15] = { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, + [16] = { 5, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, + [17] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [18] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [19] = { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [20] = { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [21] = { 2, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [22] = { 3, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } }, + [23] = { 3, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + /* Interrupt 24 reserved for T1 WDT */ + [24] = { 4, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, + /* Interrupt 25 reserved for memory access and cache errors */ + [25] = { 4, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, + [26] = { 5, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + [27] = { 3, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, + /* Interrupt 28 reserved for IPC */ + [28] = { 4, ESP_CPU_INTR_TYPE_EDGE, { ESP_CPU_INTR_DESC_FLAG_RESVD, ESP_CPU_INTR_DESC_FLAG_RESVD } }, + [29] = { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, + [30] = { 4, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } }, + [31] = { 5, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, +}; + + +void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) +{ + assert(core_id >= 0 && core_id < SOC_CPU_CORES_NUM && intr_desc_ret != NULL); + intr_desc_ret->priority = intr_desc_table[intr_num].priority; + intr_desc_ret->type = intr_desc_table[intr_num].type; + intr_desc_ret->flags = intr_desc_table[intr_num].flags[core_id]; +} diff --git a/components/esp_hw_support/port/esp32s3/mspi_timing_config.c b/components/esp_hw_support/port/esp32s3/mspi_timing_config.c index 7beecc59c1..bbcb19f9e8 100644 --- a/components/esp_hw_support/port/esp32s3/mspi_timing_config.c +++ b/components/esp_hw_support/port/esp32s3/mspi_timing_config.c @@ -118,8 +118,8 @@ static uint32_t spi_timing_config_get_dummy(void) abort(); } -#if CONFIG_SPI_FLASH_HPM_ENABLE - if (spi_flash_hpm_dummy_adjust()) { // HPM is enabled +#if CONFIG_SPI_FLASH_HPM_DC_ON + if (spi_flash_hpm_dummy_adjust()) { // HPM-DC is enabled const spi_flash_hpm_dummy_conf_t *hpm_dummy = spi_flash_hpm_get_dummy(); switch (mode) { case MSPI_TIMING_LL_FLASH_QIO_MODE: @@ -139,7 +139,7 @@ static uint32_t spi_timing_config_get_dummy(void) } } else #endif - { // HPM is not enabled + { // HPM-DC is not enabled switch (mode) { case MSPI_TIMING_LL_FLASH_QIO_MODE: return SPI1_R_QIO_DUMMY_CYCLELEN; diff --git a/components/esp_hw_support/port/esp32s3/rtc_clk.c b/components/esp_hw_support/port/esp32s3/rtc_clk.c index 29b96aac18..07f609c5f3 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s3/rtc_clk.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 */ @@ -172,6 +172,7 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq) clk_ll_bbpll_set_config(pll_freq, xtal_freq); /* WAIT CALIBRATION DONE */ while(!regi2c_ctrl_ll_bbpll_calibration_is_done()); + esp_rom_delay_us(10); /* BBPLL CALIBRATION STOP */ regi2c_ctrl_ll_bbpll_calibration_stop(); @@ -185,18 +186,6 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq) */ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) { - /* cpu_frequency < 240M: dbias = pvt-dig + 2; - cpu_frequency = 240M: dbias = pvt-dig + 3; - */ - if (cpu_freq_mhz != 240) { - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m); - } else { - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_240m); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_240m); - } - esp_rom_delay_us(40); - /* There are totally 6 LDO slaves(all on by default). At the moment of swithing LDO slave, LDO voltage will also change instantaneously. * LDO slave can reduce the voltage change caused by switching frequency. * CPU frequency <= 40M : just open 3 LDO slaves; CPU frequency = 80M : open 4 LDO slaves; CPU frequency = 160M : open 5 LDO slaves; CPU frequency = 240M : open 6 LDO slaves; @@ -207,21 +196,32 @@ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz) int pd_slave = cpu_freq_mhz / 80; rtc_cpu_freq_config_t cur_config; rtc_clk_cpu_freq_get_config(&cur_config); + /* cpu_frequency < 240M: dbias = pvt-dig + 2; + * cpu_frequency = 240M: dbias = pvt-dig + 3; + */ if (cpu_freq_mhz > cur_config.freq_mhz) { + if (cpu_freq_mhz == 240) { + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_240m); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_240m); + esp_rom_delay_us(40); + } REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE >> pd_slave); - clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz); - clk_ll_cpu_set_divider(1); - /* switch clock source */ - clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); - rtc_clk_apb_freq_update(80 * MHZ); - esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); - } else { - clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz); - clk_ll_cpu_set_divider(1); - /* switch clock source */ - clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); - rtc_clk_apb_freq_update(80 * MHZ); - esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); + } + + clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz); + clk_ll_cpu_set_divider(1); + /* switch clock source */ + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); + rtc_clk_apb_freq_update(80 * MHZ); + esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); + + if (cpu_freq_mhz < cur_config.freq_mhz) { + if (cur_config.freq_mhz == 240) { + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m); + esp_rom_delay_us(40); + } + REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE >> pd_slave); } } @@ -376,9 +376,9 @@ void rtc_clk_cpu_set_to_default_config(void) */ void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div) { - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m); - esp_rom_delay_us(40); + rtc_cpu_freq_config_t cur_config; + rtc_clk_cpu_freq_get_config(&cur_config); + esp_rom_set_cpu_ticks_per_us(cpu_freq); /* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */ clk_ll_cpu_set_divider(1); @@ -386,18 +386,25 @@ void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div) /* switch clock source */ clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL); rtc_clk_apb_freq_update(cpu_freq * MHZ); + + if (cur_config.freq_mhz == 240) { + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m); + esp_rom_delay_us(40); + } + REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE); } static void rtc_clk_cpu_freq_to_8m(void) { + assert(0 && "LDO dbias need to modified"); esp_rom_set_cpu_ticks_per_us(20); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m); - esp_rom_delay_us(40); clk_ll_cpu_set_divider(1); clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST); rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m); REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE); } @@ -453,6 +460,25 @@ bool rtc_dig_8m_enabled(void) return clk_ll_rc_fast_digi_is_enabled(); } +// Workaround for bootloader not calibrated well issue. +// Placed in IRAM because disabling BBPLL may influence the cache +void rtc_clk_recalib_bbpll(void) +{ + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + + // There are two paths we arrive here: 1. CPU reset. 2. Other reset reasons. + // - For other reasons, the bootloader will set CPU source to BBPLL and enable it. But there are calibration issues. + // Turn off the BBPLL and do calibration again to fix the issue. + // - For CPU reset, the CPU source will be set to XTAL, while the BBPLL is kept to meet USB Serial JTAG's + // requirements. In this case, we don't touch BBPLL to avoid USJ disconnection. + if (old_config.source == SOC_CPU_CLK_SRC_PLL) { + rtc_clk_cpu_freq_set_xtal(); + rtc_clk_cpu_freq_set_config(&old_config); + } +} + + /* Name used in libphy.a:phy_chip_v7.o * TODO: update the library to use rtc_clk_xtal_freq_get */ diff --git a/components/esp_hw_support/port/esp32s3/rtc_init.c b/components/esp_hw_support/port/esp32s3/rtc_init.c index 7bff7b2d2d..bbdf99ee89 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_init.c +++ b/components/esp_hw_support/port/esp32s3/rtc_init.c @@ -54,6 +54,7 @@ void rtc_init(rtc_config_t cfg) * No worry about the power consumption, Because modem Force PD will be set at the end of this function. */ CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0); REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0); @@ -382,7 +383,7 @@ static uint32_t get_dig1v3_dbias_by_efuse(uint8_t pvt_scheme_ver) static void rtc_set_stored_dbias(void) { /* - 1. a reasonable dig_dbias which by scaning pvt to make 240 CPU run successful stored in efuse; + 1. a reasonable dig_dbias which by scanning pvt to make 240 CPU run successful stored in efuse; 2. also we store some value in efuse, include: k_rtc_ldo (slope of rtc voltage & rtc_dbias); k_dig_ldo (slope of digital voltage & digital_dbias); diff --git a/components/esp_hw_support/port/esp32s3/rtc_sleep.c b/components/esp_hw_support/port/esp32s3/rtc_sleep.c index 836a484602..e2fa68fb15 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_sleep.c +++ b/components/esp_hw_support/port/esp32s3/rtc_sleep.c @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include "esp_attr.h" #include "soc/soc.h" #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" @@ -20,6 +21,8 @@ #define RTC_CNTL_MEM_FOLW_CPU (RTC_CNTL_SLOWMEM_FOLW_CPU | RTC_CNTL_FASTMEM_FOLW_CPU) +static const DRAM_ATTR rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); + /** * Configure whether certain peripherals are powered up in sleep * @param cfg power down flags as rtc_sleep_pu_config_t structure @@ -171,12 +174,11 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_ void rtc_sleep_init(rtc_sleep_config_t cfg) { if (cfg.lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } if (cfg.modem_pd_en) { - REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO | RTC_CNTL_WIFI_FORCE_ISO); + REG_CLR_BIT(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO); REG_CLR_BIT(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU); SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN); } else { @@ -231,6 +233,8 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) } /* mem force pu */ SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU); + SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU); + SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_SLOWMEM_FORCE_LPU); REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU, cfg.rtc_regulator_fpu); if (!cfg.int_8m_pd_en) { @@ -289,7 +293,6 @@ static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu) /* restore config if it is a light sleep */ if (lslp_mem_inf_fpu) { - rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1); rtc_sleep_pu(pu_cfg); } diff --git a/components/esp_hw_support/port/esp32s3/rtc_time.c b/components/esp_hw_support/port/esp32s3/rtc_time.c index ff58ed4d71..76f3022bec 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_time.c +++ b/components/esp_hw_support/port/esp32s3/rtc_time.c @@ -126,6 +126,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); uint64_t ratio_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT)) / slowclk_cycles; uint32_t ratio = (uint32_t)(ratio_64 & UINT32_MAX); @@ -141,6 +142,7 @@ static inline bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slo uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) { + assert(slowclk_cycles); rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get(); uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles); @@ -156,6 +158,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) uint64_t rtc_time_us_to_slowclk(uint64_t time_in_us, uint32_t period) { + assert(period); /* Overflow will happen in this function if time_in_us >= 2^45, which is about 400 days. * TODO: fix overflow. */ diff --git a/components/esp_hw_support/port/esp_clk_tree_common.c b/components/esp_hw_support/port/esp_clk_tree_common.c index 4ce76b0631..71a3ec507c 100644 --- a/components/esp_hw_support/port/esp_clk_tree_common.c +++ b/components/esp_hw_support/port/esp_clk_tree_common.c @@ -152,10 +152,6 @@ uint32_t esp_clk_tree_rc_fast_get_freq_hz(esp_clk_tree_src_freq_precision_t prec if (precision == ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX) { return SOC_CLK_RC_FAST_FREQ_APPROX; } -// Re-evaluate this when H2 ECO2 is back IDF-7229 -#if CONFIG_IDF_TARGET_ESP32H2 - ESP_HW_LOGW(TAG, "RC_FAST(FOSC) clock calibration is expected to have significant hardware change in the near future, don't use it for mass production. Upgrade IDF version to support the updated hardware."); -#endif #if SOC_CLK_RC_FAST_D256_SUPPORTED // If RC_FAST_D256 clock exists, calibration on a slow freq clock is much faster (less slow clock cycles need to wait) return esp_clk_tree_rc_fast_d256_get_freq_hz(precision) << 8; diff --git a/components/esp_hw_support/port/pau_regdma.c b/components/esp_hw_support/port/pau_regdma.c index aab6b17860..0ff2a8e6cd 100644 --- a/components/esp_hw_support/port/pau_regdma.c +++ b/components/esp_hw_support/port/pau_regdma.c @@ -62,7 +62,7 @@ void pau_regdma_trigger_modem_link_restore(void) } #endif -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA void IRAM_ATTR pau_regdma_set_system_link_addr(void *link_addr) { /* ESP32H2 use software to trigger REGDMA to restore instead of PMU, @@ -88,18 +88,18 @@ void IRAM_ATTR pau_regdma_trigger_system_link_restore(void) } #endif -void pau_regdma_set_extra_link_addr(void *link_addr) +void IRAM_ATTR pau_regdma_set_extra_link_addr(void *link_addr) { pau_hal_set_regdma_extra_link_addr(PAU_instance()->hal, link_addr); } -void pau_regdma_trigger_extra_link_backup(void) +void IRAM_ATTR pau_regdma_trigger_extra_link_backup(void) { pau_hal_start_regdma_extra_link(PAU_instance()->hal, true); pau_hal_stop_regdma_extra_link(PAU_instance()->hal); } -void pau_regdma_trigger_extra_link_restore(void) +void IRAM_ATTR pau_regdma_trigger_extra_link_restore(void) { pau_hal_start_regdma_extra_link(PAU_instance()->hal, false); pau_hal_stop_regdma_extra_link(PAU_instance()->hal); diff --git a/components/esp_hw_support/port/regdma_link.c b/components/esp_hw_support/port/regdma_link.c index a51fb03d43..e1df99c925 100644 --- a/components/esp_hw_support/port/regdma_link.c +++ b/components/esp_hw_support/port/regdma_link.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -445,9 +445,22 @@ static void regdma_link_update_stats_wrapper(void *link, int entry, int depth) regdma_link_update_stats(regdma_link_get_stats(link), entry, depth); } +static void regdma_link_iterator(void *link, int entry, void (*hook)(void *, int, int)) +{ + assert(entry < REGDMA_LINK_ENTRY_NUM); + + int iter = 0; + while (link) { + if (hook) { + (*hook)(link, entry, iter++); + } + link = regdma_link_get_next(link, entry); + } +} + void regdma_link_stats(void *link, int entry) { - regdma_link_recursive_impl(link, entry, 0, regdma_link_update_stats_wrapper); + regdma_link_iterator(link, entry, regdma_link_update_stats_wrapper); } static void regdma_link_destroy_wrapper(void *link, int entry, int depth) @@ -698,71 +711,81 @@ void * regdma_find_prev_module_link_tail(void *link, void *tail, int entry, uint } #if REGDMA_LINK_DBG -static const char *TAG = "regdma_link"; +static __attribute__((unused)) const char *TAG = "regdma_link"; + +static void print_info_link_data(FILE *out, const uint32_t buf[], int len) +{ + for (int i = 0; i < len; i++) { + fprintf(out, ((i + 1) % 8) ? "%08lx " : "%08lx\n", buf[i]); + } + if (len % 8) { + fprintf(out, "\n"); + } +} -static void print_info_continuous_wrapper(void *link) +static void print_info_continuous_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_continuous_t *cons = __containerof(link, regdma_link_continuous_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:%x, backup:%x, restore:%x, buff:%x", - cons->stat.module, cons->stat.id, link, cons->head, cons->body.next, + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, restore:%p, buff:%p\n", + cons->stat.module, cons->stat.id, link, *(uint32_t *)&cons->head, cons->body.next, cons->body.backup, cons->body.restore, cons->body.mem); - ESP_LOG_BUFFER_HEX(TAG, (const void *)cons->body.mem, head.length); + print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length); } -static void print_info_addr_map_wrapper(void *link) +static void print_info_addr_map_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_addr_map_t *map = __containerof(link, regdma_link_addr_map_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:%x, backup:%x, restore:%x, buff:%x, map:{%x,%x,%x,%x}", - map->stat.module, map->stat.id, link, map->head, map->body.next, map->body.backup, + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, restore:%p, buff:%p, map:{%lx,%lx,%lx,%lx}\n", + map->stat.module, map->stat.id, link, *(uint32_t *)&map->head, map->body.next, map->body.backup, map->body.restore, map->body.mem, map->body.map[0], map->body.map[1], map->body.map[2], map->body.map[3]); - ESP_LOG_BUFFER_HEX(TAG, (const void *)map->body.mem, head.length); + print_info_link_data(out, (const uint32_t *)map->body.mem, head.length); } -static void print_info_write_wait_wrapper(void *link) +static void print_info_write_wait_wrapper(FILE *out, void *link) { regdma_link_write_wait_t *ww = __containerof(link, regdma_link_write_wait_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:%x, backup:%x, value:%x, mask:%x", - ww->stat.module, ww->stat.id, link, ww->head, ww->body.next, + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:%p, backup:%p, value:%lx, mask:%lx\n", + ww->stat.module, ww->stat.id, link, *(uint32_t *)&ww->head, ww->body.next, ww->body.backup, ww->body.value, ww->body.mask); } -static void print_info_branch_continuous_wrapper(void *link) +static void print_info_branch_continuous_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_branch_continuous_t *cons = __containerof(link, regdma_link_branch_continuous_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:{%x,%x,%x,%x}, backup:%x, restore:%x, buff:%x", - cons->stat.module, cons->stat.id, link, cons->head, cons->body.next[0], cons->body.next[1], + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, restore:%p, buff:%p\n", + cons->stat.module, cons->stat.id, link, *(uint32_t *)&cons->head, cons->body.next[0], cons->body.next[1], cons->body.next[2], cons->body.next[3], cons->body.backup, cons->body.restore, cons->body.mem); - ESP_LOG_BUFFER_HEX(TAG, (const void *)cons->body.mem, head.length); + print_info_link_data(out, (const uint32_t *)cons->body.mem, head.length); } -static void print_info_branch_addr_map_wrapper(void *link) +static void print_info_branch_addr_map_wrapper(FILE *out, void *link) { regdma_link_head_t head = REGDMA_LINK_HEAD(link); regdma_link_branch_addr_map_t *map = __containerof(link, regdma_link_branch_addr_map_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:{%x,%x,%x,%x}, backup:%x, restore:%x, buff:%x, map:{%x,%x,%x,%x}", - map->stat.module, map->stat.id, link, map->head, map->body.next[0], map->body.next[1], map->body.next[2], + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, restore:%p, buff:%p, map:{%lx,%lx,%lx,%lx}\n", + map->stat.module, map->stat.id, link, *(uint32_t *)&map->head, map->body.next[0], map->body.next[1], map->body.next[2], map->body.next[3], map->body.backup, map->body.restore, map->body.mem, map->body.map[0], map->body.map[1], map->body.map[2], map->body.map[3]); - ESP_LOG_BUFFER_HEX(TAG, (const void *)map->body.mem, head.length); + print_info_link_data(out, (const uint32_t *)map->body.mem, head.length); } -static void print_info_branch_write_wait_wrapper(void *link) +static void print_info_branch_write_wait_wrapper(FILE *out, void *link) { regdma_link_branch_write_wait_t *ww = __containerof(link, regdma_link_branch_write_wait_t, head); - ESP_EARLY_LOGI(TAG, "[%08x/%04x] link:%x, head:%x, next:{%x,%x,%x,%x}, backup:%x, value:%x, mask:%x", - ww->stat.module, ww->stat.id, link, ww->head, ww->body.next[0], ww->body.next[1], + fprintf(out, "[%08lx/%04x] link:%p, head:%lx, next:{%p,%p,%p,%p}, backup:%p, value:%lx, mask:%lx\n", + ww->stat.module, ww->stat.id, link, *(uint32_t *)&ww->head, ww->body.next[0], ww->body.next[1], ww->body.next[2], ww->body.next[3], ww->body.backup, ww->body.value, ww->body.mask); } -static void print_link_info(void *args, int entry, int depth) +static void print_link_info(FILE *out, void *args, int entry, int depth) { - typedef void (*prinf_fn_t)(void *); + typedef void (*prinf_fn_t)(FILE *, void *); const static prinf_fn_t prinf_fn[] = { [0] = (prinf_fn_t)print_info_continuous_wrapper, @@ -779,20 +802,20 @@ static void print_link_info(void *args, int entry, int depth) int it = (head.branch << 2) | head.mode; assert(it < ARRAY_SIZE(prinf_fn)); - (*prinf_fn[it])(args); + (*prinf_fn[it])(out, args); } -void regdma_link_show_memories(void *link, int entry) +void regdma_link_dump(FILE *out, void *link, int entry) { assert(entry < REGDMA_LINK_ENTRY_NUM); void *next = link; if (link) { do { - print_link_info(next, entry, 0); + print_link_info(out, next, entry, 0); } while ((next = regdma_link_get_next(next, entry)) != NULL); } else { - ESP_EARLY_LOGW(TAG, "This REGDMA linked list is empty!\n"); + fprintf(out, "This REGDMA linked list is empty!\n"); } } #endif diff --git a/components/esp_hw_support/revision.c b/components/esp_hw_support/revision.c new file mode 100644 index 0000000000..723eddcab9 --- /dev/null +++ b/components/esp_hw_support/revision.c @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "esp_assert.h" + +/* +Source used to store ESP chip revision and ESP-IDF minimum supported revision in the future. +Currently only used to hold static assert to check that the configured minimum and maximum supported chip revisions of +ESP-IDF are valid. +*/ + +ESP_STATIC_ASSERT(CONFIG_ESP_REV_MIN_FULL <= CONFIG_ESP_REV_MAX_FULL); diff --git a/components/esp_hw_support/sar_periph_ctrl_common.c b/components/esp_hw_support/sar_periph_ctrl_common.c index 2b0d009178..d569ada3b5 100644 --- a/components/esp_hw_support/sar_periph_ctrl_common.c +++ b/components/esp_hw_support/sar_periph_ctrl_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,9 @@ #if SOC_TEMP_SENSOR_SUPPORTED #include "hal/temperature_sensor_ll.h" #include "soc/temperature_sensor_periph.h" +#include "soc/periph_defs.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/adc_share_hw_ctrl.h" extern int rtc_spinlock; @@ -39,6 +42,11 @@ void temperature_sensor_power_acquire(void) RTC_ENTER_CRITICAL(); s_temperature_sensor_power_cnt++; if (s_temperature_sensor_power_cnt == 1) { + adc_apb_periph_claim(); + periph_module_enable(PERIPH_TEMPSENSOR_MODULE); + periph_module_reset(PERIPH_TEMPSENSOR_MODULE); + regi2c_saradc_enable(); + temperature_sensor_ll_clk_enable(true); temperature_sensor_ll_enable(true); } RTC_EXIT_CRITICAL(); @@ -54,7 +62,11 @@ void temperature_sensor_power_release(void) ESP_LOGE(TAG_TSENS, "%s called, but s_temperature_sensor_power_cnt == 0", __func__); abort(); } else if (s_temperature_sensor_power_cnt == 0) { + temperature_sensor_ll_clk_enable(false); temperature_sensor_ll_enable(false); + regi2c_saradc_disable(); + periph_module_disable(PERIPH_TEMPSENSOR_MODULE); + adc_apb_periph_free(); } RTC_EXIT_CRITICAL(); } diff --git a/components/esp_hw_support/sdkconfig.rename.esp32 b/components/esp_hw_support/sdkconfig.rename.esp32 index 91bac13a64..058f851538 100644 --- a/components/esp_hw_support/sdkconfig.rename.esp32 +++ b/components/esp_hw_support/sdkconfig.rename.esp32 @@ -21,7 +21,8 @@ CONFIG_SPIRAM_SUPPORT CONFIG_SPIRAM CONFIG_ESP32_SPIRAM_SUPPORT CONFIG_SPIRAM CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP -CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY CONFIG_ESP32_XTAL_FREQ_26 CONFIG_XTAL_FREQ_26 CONFIG_ESP32_XTAL_FREQ_40 CONFIG_XTAL_FREQ_40 diff --git a/components/esp_hw_support/sdkconfig.rename.esp32s3 b/components/esp_hw_support/sdkconfig.rename.esp32s3 index 77e595a907..39a3d34cca 100644 --- a/components/esp_hw_support/sdkconfig.rename.esp32s3 +++ b/components/esp_hw_support/sdkconfig.rename.esp32s3 @@ -10,4 +10,5 @@ CONFIG_ESP32S3_RTC_XTAL_CAL_RETRY CONFIG_RTC_XTAL_CAL_RE CONFIG_ESP32S3_SPIRAM_SUPPORT CONFIG_SPIRAM -CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY +CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY +CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY diff --git a/components/esp_hw_support/sleep_clock.c b/components/esp_hw_support/sleep_clock.c index a2ad1257cf..b75683187e 100644 --- a/components/esp_hw_support/sleep_clock.c +++ b/components/esp_hw_support/sleep_clock.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,13 +23,13 @@ #include "soc/pcr_reg.h" #include "modem/modem_syscon_reg.h" -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA #include "modem/modem_lpcon_reg.h" #endif static __attribute__((unused)) const char *TAG = "sleep_clock"; -esp_err_t sleep_clock_system_retention_init(void) +static esp_err_t sleep_clock_system_retention_init(void *arg) { #if CONFIG_IDF_TARGET_ESP32C6 #define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) @@ -40,64 +40,98 @@ esp_err_t sleep_clock_system_retention_init(void) [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* pcr */ }; - esp_err_t err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_1, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); + esp_err_t err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_0, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention"); ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); return ESP_OK; } -void sleep_clock_system_retention_deinit(void) -{ - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); -} - -esp_err_t sleep_clock_modem_retention_init(void) +#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE +static esp_err_t sleep_clock_modem_retention_init(void *arg) { #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA #define N_REGS_LPCON() (((MODEM_LPCON_MEM_CONF_REG - MODEM_LPCON_TEST_CONF_REG) / 4) + 1) #endif +#if SOC_WIFI_SUPPORTED + #define MODEM_WIFI_RETENTION_CLOCK (MODEM_SYSCON_CLK_WIFI_APB_FO | MODEM_SYSCON_CLK_FE_APB_FO) + #define MODEM_WIFI_RETENTION_CLOCK_MASK (MODEM_SYSCON_CLK_WIFI_APB_FO_M | MODEM_SYSCON_CLK_FE_APB_FO_M) +#endif + const static sleep_retention_entries_config_t modem_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */ -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */ + { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */ +#if SOC_WIFI_SUPPORTED + { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(1), MODEM_SYSCON_CLK_CONF1_FORCE_ON_REG, MODEM_WIFI_RETENTION_CLOCK, MODEM_WIFI_RETENTION_CLOCK_MASK, 0, 0), .owner = ENTRY(0) }, /* WiFi (MAC, BB and FE) retention clock enable */ +#endif +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA + { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */ #endif }; - - esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_CLOCK_MODEM); +#if SOC_WIFI_SUPPORTED + const static sleep_retention_entries_config_t modem_retention_clock[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_MODEMSYSCON_LINK(0xf0), MODEM_SYSCON_CLK_CONF1_FORCE_ON_REG, 0x0, MODEM_WIFI_RETENTION_CLOCK_MASK, 0, 0), .owner = ENTRY(0) } /* WiFi (MAC, BB and FE) retention clock disable */ + }; +#endif + esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_1, SLEEP_RETENTION_MODULE_CLOCK_MODEM); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 2 level priority"); +#if SOC_WIFI_SUPPORTED + err = sleep_retention_entries_create(modem_retention_clock, ARRAY_SIZE(modem_retention_clock), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_CLOCK_MODEM); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, lowest level priority"); +#endif ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization"); return ESP_OK; } - -void sleep_clock_modem_retention_deinit(void) -{ - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_MODEM); -} +#endif bool IRAM_ATTR clock_domain_pd_allowed(void) { - const uint32_t modules = sleep_retention_get_modules(); - const uint32_t mask = (const uint32_t) ( - SLEEP_RETENTION_MODULE_CLOCK_SYSTEM -#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE - | SLEEP_RETENTION_MODULE_CLOCK_MODEM + const uint32_t inited_modules = sleep_retention_get_inited_modules(); + const uint32_t created_modules = sleep_retention_get_created_modules(); + const uint32_t sys_clk_dep_modules = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); + + /* The clock and reset of MODEM (WiFi, BLE and 15.4) modules are managed + * through MODEM_SYSCON, when one or more MODEMs are initialized, it is + * necessary to check the state of CLOCK_MODEM to determine MODEM domain on + * or off. The clock and reset of digital peripherals are managed through + * PCR, with TOP domain similar to MODEM domain. */ + uint32_t modem_clk_dep_modules = 0; +#if SOC_WIFI_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | BIT(SLEEP_RETENTION_MODULE_WIFI_BB); +#endif +#if SOC_BT_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif +#if SOC_IEEE802154_SUPPORTED + modem_clk_dep_modules |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); #endif - ); - return ((modules & mask) == mask); + + uint32_t mask = 0; + if (inited_modules & sys_clk_dep_modules) { + mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); + } + if (inited_modules & modem_clk_dep_modules) { +#if SOC_WIFI_SUPPORTED || SOC_BT_SUPPORTED || SOC_IEEE802154_SUPPORTED + mask |= BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM); +#endif + } + return ((inited_modules & mask) == (created_modules & mask)); } -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP || CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE ESP_SYSTEM_INIT_FN(sleep_clock_startup_init, BIT(0), 106) { -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP - sleep_clock_system_retention_init(); -#endif + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_clock_system_retention_init, .arg = NULL } }, + .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE + }; + sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM, &init_param); #if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE - sleep_clock_modem_retention_init(); + init_param = (sleep_retention_module_init_param_t) { + .cbs = { .create = { .handle = sleep_clock_modem_retention_init, .arg = NULL } }, + .attribute = SLEEP_RETENTION_MODULE_ATTR_PASSIVE + }; + sleep_retention_module_init(SLEEP_RETENTION_MODULE_CLOCK_MODEM, &init_param); #endif return ESP_OK; } -#endif diff --git a/components/esp_hw_support/sleep_console.c b/components/esp_hw_support/sleep_console.c new file mode 100644 index 0000000000..62df8daf06 --- /dev/null +++ b/components/esp_hw_support/sleep_console.c @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc/soc_caps.h" +#include "esp_private/sleep_console.h" +#include "esp_attr.h" + +#if SOC_USB_SERIAL_JTAG_SUPPORTED +#include "hal/usb_serial_jtag_ll.h" + +static sleep_console_usj_enable_state_t s_usj_state = {0}; + +void sleep_console_usj_pad_backup_and_disable(void) +{ + s_usj_state.usj_clock_enabled = usb_serial_jtag_ll_module_is_enabled(); + if (!s_usj_state.usj_clock_enabled) { + // Enable USJ clock and clear reset + usb_serial_jtag_ll_enable_bus_clock(true); + usb_serial_jtag_ll_reset_register(); + } + s_usj_state.usj_pad_enabled = usb_serial_jtag_ll_phy_is_pad_enabled(); + usb_serial_jtag_ll_phy_enable_pad(false); + // Disable USJ clock + usb_serial_jtag_ll_enable_bus_clock(false); +} + +void sleep_console_usj_pad_restore(void) +{ + usb_serial_jtag_ll_enable_bus_clock(true); + usb_serial_jtag_ll_phy_enable_pad(s_usj_state.usj_pad_enabled); + if (!s_usj_state.usj_clock_enabled) { + usb_serial_jtag_ll_enable_bus_clock(false); + } +} +#endif diff --git a/components/esp_hw_support/sleep_cpu.c b/components/esp_hw_support/sleep_cpu.c index abd018415f..1a7b17ed3d 100644 --- a/components/esp_hw_support/sleep_cpu.c +++ b/components/esp_hw_support/sleep_cpu.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,10 +14,11 @@ #include "esp_check.h" #include "esp_sleep.h" #include "esp_log.h" -#include "esp_crc.h" +#include "esp_rom_crc.h" #include "esp_heap_caps.h" #include "soc/soc_caps.h" #include "esp_private/sleep_cpu.h" +#include "esp_private/sleep_event.h" #include "sdkconfig.h" #if SOC_PMU_SUPPORTED @@ -506,18 +507,18 @@ static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(voi frame->pmacfg1 = RV_READ_CSR(CSR_PMACFG(1)); frame->pmacfg2 = RV_READ_CSR(CSR_PMACFG(2)); frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(3)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(4)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(5)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(6)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(7)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(8)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(9)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(10)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(11)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(12)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(13)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(14)); - frame->pmacfg3 = RV_READ_CSR(CSR_PMACFG(15)); + frame->pmacfg4 = RV_READ_CSR(CSR_PMACFG(4)); + frame->pmacfg5 = RV_READ_CSR(CSR_PMACFG(5)); + frame->pmacfg6 = RV_READ_CSR(CSR_PMACFG(6)); + frame->pmacfg7 = RV_READ_CSR(CSR_PMACFG(7)); + frame->pmacfg8 = RV_READ_CSR(CSR_PMACFG(8)); + frame->pmacfg9 = RV_READ_CSR(CSR_PMACFG(9)); + frame->pmacfg10 = RV_READ_CSR(CSR_PMACFG(10)); + frame->pmacfg11 = RV_READ_CSR(CSR_PMACFG(11)); + frame->pmacfg12 = RV_READ_CSR(CSR_PMACFG(12)); + frame->pmacfg13 = RV_READ_CSR(CSR_PMACFG(13)); + frame->pmacfg14 = RV_READ_CSR(CSR_PMACFG(14)); + frame->pmacfg15 = RV_READ_CSR(CSR_PMACFG(15)); #endif // SOC_CPU_HAS_PMA frame->utvec = RV_READ_CSR(utvec); @@ -652,12 +653,12 @@ static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t * #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME static void update_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) { - *(frame_crc_ptr) = esp_crc32_le(0, (void *)frame_ptr, frame_check_size); + *(frame_crc_ptr) = esp_rom_crc32_le(0, (void *)frame_ptr, frame_check_size); } static void validate_retention_frame_crc(uint32_t *frame_ptr, uint32_t frame_check_size, uint32_t *frame_crc_ptr) { - if(*(frame_crc_ptr) != esp_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ + if(*(frame_crc_ptr) != esp_rom_crc32_le(0, (void *)(frame_ptr), frame_check_size)){ // resume uarts for (int i = 0; i < SOC_UART_NUM; ++i) { #ifndef CONFIG_IDF_TARGET_ESP32 @@ -684,6 +685,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, { RvCoreCriticalSleepFrame * frame = rv_core_critical_regs_save(); if ((frame->pmufunc & 0x3) == 0x1) { + esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_END, (void *)0); #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME /* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */ update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); @@ -703,6 +705,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) { + esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_START, (void *)0); uint32_t mstatus = save_mstatus_and_disable_global_int(); cpu_domain_dev_regs_save(s_cpu_retention.retent.plic_frame); @@ -727,7 +730,6 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin cpu_domain_dev_regs_restore(s_cpu_retention.retent.intpri_frame); cpu_domain_dev_regs_restore(s_cpu_retention.retent.clint_frame); cpu_domain_dev_regs_restore(s_cpu_retention.retent.plic_frame); - restore_mstatus(mstatus); return err; } diff --git a/components/esp_hw_support/sleep_cpu_asm.S b/components/esp_hw_support/sleep_cpu_asm.S index b84dd4d421..65d0e6de06 100644 --- a/components/esp_hw_support/sleep_cpu_asm.S +++ b/components/esp_hw_support/sleep_cpu_asm.S @@ -166,9 +166,16 @@ wait_sync_done: .section .iram1,"ax" .global rv_core_critical_regs_restore + .weak rv_core_critical_regs_restore .type rv_core_critical_regs_restore,@function + .global _rv_core_critical_regs_restore + .type _rv_core_critical_regs_restore,@function .align 4 +_rv_core_critical_regs_restore: /* export a strong symbol to jump to here, used + * for a static callback */ + nop + rv_core_critical_regs_restore: la t0, rv_core_critical_regs_frame diff --git a/components/esp_hw_support/sleep_event.c b/components/esp_hw_support/sleep_event.c new file mode 100644 index 0000000000..02bc704f58 --- /dev/null +++ b/components/esp_hw_support/sleep_event.c @@ -0,0 +1,92 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "sdkconfig.h" +#include "soc/soc_caps.h" +#include "esp_private/sleep_event.h" + +#include "esp_sleep.h" +#include "esp_log.h" +#include "esp_check.h" +#include "freertos/FreeRTOS.h" + +static __attribute__((unused)) const char *TAG = "sleep_event"; + +#if CONFIG_ESP_SLEEP_EVENT_CALLBACKS +esp_sleep_event_cbs_config_t g_sleep_event_cbs_config; +static portMUX_TYPE s_sleep_event_mutex = portMUX_INITIALIZER_UNLOCKED; + +esp_err_t esp_sleep_register_event_callback(esp_sleep_event_cb_index_t event_id, const esp_sleep_event_cb_config_t *event_cb_conf) { + if (event_cb_conf == NULL || event_id >= SLEEP_EVENT_CB_INDEX_NUM) { + return ESP_ERR_INVALID_ARG; + } + esp_sleep_event_cb_config_t *new_config = (esp_sleep_event_cb_config_t *)heap_caps_malloc(sizeof(esp_sleep_event_cb_config_t), MALLOC_CAP_INTERNAL); + if (new_config == NULL) { + return ESP_ERR_NO_MEM; /* Memory allocation failed */ + } + + portENTER_CRITICAL(&s_sleep_event_mutex); + esp_sleep_event_cb_config_t **current_ptr = &(g_sleep_event_cbs_config.sleep_event_cb_config[event_id]); + while (*current_ptr != NULL) { + if (((*current_ptr)->cb) == (event_cb_conf->cb)) { + free(new_config); + portEXIT_CRITICAL(&s_sleep_event_mutex); + return ESP_FAIL; + } + current_ptr = &((*current_ptr)->next); + } + + *new_config = *event_cb_conf; + while (*current_ptr != NULL && (*current_ptr)->prior <= new_config->prior) { + current_ptr = &((*current_ptr)->next); + } + new_config->next = *current_ptr; + *current_ptr = new_config; + portEXIT_CRITICAL(&s_sleep_event_mutex); + return ESP_OK; +} + +esp_err_t esp_sleep_unregister_event_callback(esp_sleep_event_cb_index_t event_id, esp_sleep_event_cb_t cb) { + if (cb == NULL || event_id >= SLEEP_EVENT_CB_INDEX_NUM) { + return ESP_ERR_INVALID_ARG; + } + portENTER_CRITICAL(&s_sleep_event_mutex); + esp_sleep_event_cb_config_t **current_ptr = &(g_sleep_event_cbs_config.sleep_event_cb_config[event_id]); + while (*current_ptr != NULL) { + if (((*current_ptr)->cb) == cb) { + esp_sleep_event_cb_config_t *temp = *current_ptr; + *current_ptr = (*current_ptr)->next; + free(temp); + break; + } + current_ptr = &((*current_ptr)->next); + } + portEXIT_CRITICAL(&s_sleep_event_mutex); + return ESP_OK; +} +#endif + +void IRAM_ATTR esp_sleep_execute_event_callbacks(esp_sleep_event_cb_index_t event_id, void *ext_arg) +{ +#if CONFIG_ESP_SLEEP_EVENT_CALLBACKS + if (event_id >= SLEEP_EVENT_CB_INDEX_NUM) { + ESP_EARLY_LOGW(TAG, "event_id out of range"); + return; + } + esp_sleep_event_cb_config_t *current = g_sleep_event_cbs_config.sleep_event_cb_config[event_id]; + while (current != NULL) { + if (current->cb != NULL) { + if (ESP_OK != (*current->cb)(current->user_arg, ext_arg)) { + ESP_EARLY_LOGW(TAG, "esp_sleep_execute_event_callbacks has an err, current->cb = %p", current->cb); + } + } + current = current->next; + } +#endif +} diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index 8a420fce9b..759659d1a9 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -20,14 +20,13 @@ #include "driver/gpio.h" #include "hal/gpio_hal.h" #include "hal/rtc_io_hal.h" +#include "soc/rtc_io_periph.h" #if SOC_LP_AON_SUPPORTED #include "hal/lp_aon_hal.h" #else -#if !CONFIG_IDF_TARGET_ESP32H2 #include "hal/rtc_hal.h" #endif -#endif #include "esp_private/gpio.h" #include "esp_private/sleep_gpio.h" diff --git a/components/esp_hw_support/sleep_modem.c b/components/esp_hw_support/sleep_modem.c index d73f32845c..613b9dd8dc 100644 --- a/components/esp_hw_support/sleep_modem.c +++ b/components/esp_hw_support/sleep_modem.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,6 +28,7 @@ #if SOC_PM_SUPPORT_PMU_MODEM_STATE #include "soc/pmu_reg.h" #include "esp_private/esp_pau.h" +#include "esp_private/esp_pmu.h" #endif static __attribute__((unused)) const char *TAG = "sleep_modem"; @@ -36,9 +37,15 @@ static __attribute__((unused)) const char *TAG = "sleep_modem"; static void esp_pm_light_sleep_default_params_config(int min_freq_mhz, int max_freq_mhz); #endif +#if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD +static bool s_modem_sleep = false; +static uint8_t s_modem_prepare_ref = 0; +static _lock_t s_modem_prepare_lock; +#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD + #if CONFIG_MAC_BB_PD -#define MAC_BB_POWER_DOWN_CB_NO (2) -#define MAC_BB_POWER_UP_CB_NO (2) +#define MAC_BB_POWER_DOWN_CB_NO (3) +#define MAC_BB_POWER_UP_CB_NO (3) static DRAM_ATTR mac_bb_power_down_cb_t s_mac_bb_power_down_cb[MAC_BB_POWER_DOWN_CB_NO]; static DRAM_ATTR mac_bb_power_up_cb_t s_mac_bb_power_up_cb[MAC_BB_POWER_UP_CB_NO]; @@ -167,7 +174,7 @@ typedef struct sleep_modem_config { static sleep_modem_config_t s_sleep_modem = { .wifi.phy_link = NULL, .wifi.flags = 0 }; -static __attribute__((unused)) esp_err_t sleep_modem_wifi_modem_state_init(void) +esp_err_t sleep_modem_wifi_modem_state_init(void) { esp_err_t err = ESP_OK; phy_i2c_master_command_attribute_t cmd; @@ -244,7 +251,7 @@ static __attribute__((unused)) esp_err_t sleep_modem_wifi_modem_state_init(void) return err; } -static __attribute__((unused)) void sleep_modem_wifi_modem_state_deinit(void) +__attribute__((unused)) void sleep_modem_wifi_modem_state_deinit(void) { if (s_sleep_modem.wifi.phy_link) { regdma_link_destroy(s_sleep_modem.wifi.phy_link, 0); @@ -278,16 +285,20 @@ inline __attribute__((always_inline)) bool sleep_modem_wifi_modem_link_done(void bool IRAM_ATTR modem_domain_pd_allowed(void) { #if SOC_PM_MODEM_RETENTION_BY_REGDMA - const uint32_t modules = sleep_retention_get_modules(); - const uint32_t mask_wifi = (const uint32_t) (SLEEP_RETENTION_MODULE_WIFI_MAC | - SLEEP_RETENTION_MODULE_WIFI_BB); - const uint32_t mask_ble = (const uint32_t) (SLEEP_RETENTION_MODULE_BLE_MAC | - SLEEP_RETENTION_MODULE_BT_BB); - const uint32_t mask_154 = (const uint32_t) (SLEEP_RETENTION_MODULE_802154_MAC | - SLEEP_RETENTION_MODULE_BT_BB); - return (((modules & mask_wifi) == mask_wifi) || - ((modules & mask_ble) == mask_ble) || - ((modules & mask_154) == mask_154)); + const uint32_t inited_modules = sleep_retention_get_inited_modules(); + const uint32_t created_modules = sleep_retention_get_created_modules(); + + uint32_t mask = 0; +#if SOC_WIFI_SUPPORTED + mask |= BIT(SLEEP_RETENTION_MODULE_WIFI_MAC) | BIT(SLEEP_RETENTION_MODULE_WIFI_BB); +#endif +#if SOC_BT_SUPPORTED + mask |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif +#if SOC_IEEE802154_SUPPORTED + mask |= BIT(SLEEP_RETENTION_MODULE_802154_MAC) | BIT(SLEEP_RETENTION_MODULE_BT_BB); +#endif + return ((inited_modules & mask) == (created_modules & mask)); #else return false; /* MODEM power domain is controlled by each module (WiFi, Bluetooth or 15.4) of modem */ #endif @@ -302,7 +313,7 @@ uint32_t IRAM_ATTR sleep_modem_reject_triggers(void) return reject_triggers; } -static __attribute__((unused)) bool IRAM_ATTR sleep_modem_wifi_modem_state_skip_light_sleep(void) +bool IRAM_ATTR sleep_modem_wifi_modem_state_skip_light_sleep(void) { bool skip = false; #if SOC_PM_SUPPORT_PMU_MODEM_STATE @@ -317,17 +328,8 @@ static __attribute__((unused)) bool IRAM_ATTR sleep_modem_wifi_modem_state_skip_ esp_err_t sleep_modem_configure(int max_freq_mhz, int min_freq_mhz, bool light_sleep_enable) { #if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP - extern int esp_wifi_internal_mac_sleep_configure(bool, bool); - if (light_sleep_enable) { - if (sleep_modem_wifi_modem_state_init() == ESP_OK) { - esp_pm_register_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep); - esp_wifi_internal_mac_sleep_configure(light_sleep_enable, true); /* require WiFi to enable automatically receives the beacon */ - } - } else { - esp_wifi_internal_mac_sleep_configure(light_sleep_enable, false); /* require WiFi to disable automatically receives the beacon */ - esp_pm_unregister_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep); - sleep_modem_wifi_modem_state_deinit(); - } + extern int esp_wifi_internal_light_sleep_configure(bool); + esp_wifi_internal_light_sleep_configure(light_sleep_enable); #endif #if CONFIG_PM_SLP_DEFAULT_PARAMS_OPT if (light_sleep_enable) { @@ -337,7 +339,7 @@ esp_err_t sleep_modem_configure(int max_freq_mhz, int min_freq_mhz, bool light_s return ESP_OK; } -#define PERIPH_INFORM_OUT_LIGHT_SLEEP_OVERHEAD_NO 1 +#define PERIPH_INFORM_OUT_LIGHT_SLEEP_OVERHEAD_NO 2 /* Inform peripherals of light sleep wakeup overhead time */ static inform_out_light_sleep_overhead_cb_t s_periph_inform_out_light_sleep_overhead_cb[PERIPH_INFORM_OUT_LIGHT_SLEEP_OVERHEAD_NO]; @@ -399,3 +401,78 @@ static void esp_pm_light_sleep_default_params_config(int min_freq_mhz, int max_f } } #endif + +#if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD +void sleep_modem_register_mac_bb_module_prepare_callback(mac_bb_power_down_cb_t pd_cb, + mac_bb_power_up_cb_t pu_cb) +{ + _lock_acquire(&s_modem_prepare_lock); + if (s_modem_prepare_ref++ == 0) { + esp_register_mac_bb_pd_callback(pd_cb); + esp_register_mac_bb_pu_callback(pu_cb); + } + _lock_release(&s_modem_prepare_lock); +} + +void sleep_modem_unregister_mac_bb_module_prepare_callback(mac_bb_power_down_cb_t pd_cb, + mac_bb_power_up_cb_t pu_cb) +{ + _lock_acquire(&s_modem_prepare_lock); + assert(s_modem_prepare_ref); + if (--s_modem_prepare_ref == 0) { + esp_unregister_mac_bb_pd_callback(pd_cb); + esp_unregister_mac_bb_pu_callback(pu_cb); + } + _lock_release(&s_modem_prepare_lock); + +} + +/** + * @brief Switch root clock source to PLL do retention and switch back + * + * This function is used when Bluetooth/IEEE802154 module requires register backup/restore, this function + * is called ONLY when SOC_PM_RETENTION_HAS_CLOCK_BUG is set. + * @param backup true for backup, false for restore + * @param cpu_freq_mhz cpu frequency to do retention + * @param do_retention function for retention + */ +static void IRAM_ATTR rtc_clk_cpu_freq_to_pll_mhz_and_do_retention(bool backup, int cpu_freq_mhz, void (*do_retention)(bool)) +{ +#if SOC_PM_SUPPORT_PMU_MODEM_STATE + if (pmu_sleep_pll_already_enabled()) { + return; + } +#endif + rtc_cpu_freq_config_t config, pll_config; + rtc_clk_cpu_freq_get_config(&config); + + rtc_clk_cpu_freq_mhz_to_config(cpu_freq_mhz, &pll_config); + rtc_clk_cpu_freq_set_config(&pll_config); + + if (do_retention) { + (*do_retention)(backup); + } + + rtc_clk_cpu_freq_set_config(&config); +} + +void IRAM_ATTR sleep_modem_mac_bb_power_down_prepare(void) +{ + if (s_modem_sleep == false) { + rtc_clk_cpu_freq_to_pll_mhz_and_do_retention(true, + CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, + sleep_retention_do_extra_retention); + s_modem_sleep = true; + } +} + +void IRAM_ATTR sleep_modem_mac_bb_power_up_prepare(void) +{ + if (s_modem_sleep) { + rtc_clk_cpu_freq_to_pll_mhz_and_do_retention(false, + CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, + sleep_retention_do_extra_retention); + s_modem_sleep = false; + } +} +#endif /* SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD */ diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 10dded152a..8cb60dfa32 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +17,7 @@ #include "esp_sleep.h" #include "esp_private/esp_sleep_internal.h" #include "esp_private/esp_timer_private.h" +#include "esp_private/sleep_event.h" #include "esp_private/system_internal.h" #include "esp_log.h" #include "esp_cpu.h" @@ -25,6 +26,15 @@ #include "driver/rtc_io.h" #include "hal/rtc_io_hal.h" +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND +#include "hal/systimer_ll.h" +#endif + +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND +#include "hal/mwdt_ll.h" +#include "hal/timer_ll.h" +#endif + #if SOC_PM_SUPPORT_PMU_MODEM_STATE #include "esp_private/pm_impl.h" #endif @@ -32,11 +42,9 @@ #if SOC_LP_AON_SUPPORTED #include "hal/lp_aon_hal.h" #else -#if !CONFIG_IDF_TARGET_ESP32H2 #include "hal/rtc_cntl_ll.h" #include "hal/rtc_hal.h" #endif -#endif #include "driver/uart.h" @@ -58,6 +66,7 @@ #include "esp_rom_uart.h" #include "esp_rom_sys.h" #include "esp_private/brownout.h" +#include "esp_private/sleep_console.h" #include "esp_private/sleep_cpu.h" #include "esp_private/sleep_modem.h" #include "esp_private/esp_clk.h" @@ -83,13 +92,13 @@ #include "esp32c2/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C6 #include "esp32c6/rom/rtc.h" -#include "hal/lp_timer_hal.h" #include "hal/gpio_ll.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/rtc.h" #include "esp32h2/rom/cache.h" #include "esp32h2/rom/rtc.h" #include "soc/extmem_reg.h" +#include "hal/gpio_ll.h" #endif #if SOC_LP_TIMER_SUPPORTED @@ -102,7 +111,7 @@ #include "esp_private/sleep_clock.h" #endif -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA #include "esp_private/sleep_retention.h" #endif @@ -173,7 +182,8 @@ #define MAX_DSLP_HOOKS 3 -static esp_deep_sleep_cb_t s_dslp_cb[MAX_DSLP_HOOKS]={0}; +static esp_deep_sleep_cb_t s_dslp_cb[MAX_DSLP_HOOKS] = {0}; +static esp_deep_sleep_cb_t s_dslp_phy_cb[MAX_DSLP_HOOKS] = {0}; /** * Internal structure which holds all requested deep sleep parameters @@ -188,15 +198,17 @@ typedef struct { uint64_t sleep_duration; uint32_t wakeup_triggers : 15; #if SOC_PM_SUPPORT_EXT1_WAKEUP - uint32_t ext1_trigger_mode : 1; - uint32_t ext1_rtc_gpio_mask : 22; // 22 is the maximum RTCIO number in all chips + uint32_t ext1_trigger_mode : 22; // 22 is the maximum RTCIO number in all chips + uint32_t ext1_rtc_gpio_mask : 22; #endif #if SOC_PM_SUPPORT_EXT0_WAKEUP uint32_t ext0_trigger_level : 1; uint32_t ext0_rtc_gpio_num : 5; #endif +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP uint32_t gpio_wakeup_mask : 8; // 8 is the maximum RTCIO number in all chips that support GPIO wakeup uint32_t gpio_trigger_mode : 8; +#endif uint32_t sleep_time_adjustment; uint32_t ccount_ticks_record; uint32_t sleep_time_overhead_out; @@ -206,6 +218,17 @@ typedef struct { } sleep_config_t; +#if CONFIG_ESP_SLEEP_DEBUG +static esp_sleep_context_t *s_sleep_ctx = NULL; + +void esp_sleep_set_sleep_context(esp_sleep_context_t *sleep_ctx) +{ + s_sleep_ctx = sleep_ctx; +} +#endif + +static uint32_t s_lightsleep_cnt = 0; + _Static_assert(22 >= SOC_RTCIO_PIN_COUNT, "Chip has more RTCIOs than 22, should increase ext1_rtc_gpio_mask field size"); static sleep_config_t s_config = { @@ -257,7 +280,6 @@ static void touch_wakeup_prepare(void); static void gpio_deep_sleep_wakeup_prepare(void); #endif -#if !CONFIG_IDF_TARGET_ESP32H2 #if SOC_RTC_FAST_MEM_SUPPORTED #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY static RTC_FAST_ATTR esp_deep_sleep_wake_stub_fn_t wake_stub_fn_handler = NULL; @@ -366,7 +388,6 @@ void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void); #endif // SOC_RTC_FAST_MEM_SUPPORTED -#endif // !CONFIG_IDF_TARGET_ESP32H2 void esp_deep_sleep(uint64_t time_in_us) { @@ -374,12 +395,18 @@ void esp_deep_sleep(uint64_t time_in_us) esp_deep_sleep_start(); } -esp_err_t esp_deep_sleep_register_hook(esp_deep_sleep_cb_t new_dslp_cb) +esp_err_t esp_deep_sleep_try(uint64_t time_in_us) +{ + esp_sleep_enable_timer_wakeup(time_in_us); + return esp_deep_sleep_try_to_start(); +} + +static esp_err_t s_sleep_hook_register(esp_deep_sleep_cb_t new_cb, esp_deep_sleep_cb_t s_cb_array[MAX_DSLP_HOOKS]) { RTC_DEEP_SLEEP_ENTER_CRITICAL(); - for(int n = 0; n < MAX_DSLP_HOOKS; n++){ - if (s_dslp_cb[n]==NULL || s_dslp_cb[n]==new_dslp_cb) { - s_dslp_cb[n]=new_dslp_cb; + for (int n = 0; n < MAX_DSLP_HOOKS; n++) { + if (s_cb_array[n]==NULL || s_cb_array[n]==new_cb) { + s_cb_array[n]=new_cb; RTC_DEEP_SLEEP_EXIT_CRITICAL(); return ESP_OK; } @@ -389,17 +416,109 @@ esp_err_t esp_deep_sleep_register_hook(esp_deep_sleep_cb_t new_dslp_cb) return ESP_ERR_NO_MEM; } -void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb) +static void s_sleep_hook_deregister(esp_deep_sleep_cb_t old_cb, esp_deep_sleep_cb_t s_cb_array[MAX_DSLP_HOOKS]) { RTC_DEEP_SLEEP_ENTER_CRITICAL(); - for(int n = 0; n < MAX_DSLP_HOOKS; n++){ - if(s_dslp_cb[n] == old_dslp_cb) { - s_dslp_cb[n] = NULL; + for (int n = 0; n < MAX_DSLP_HOOKS; n++) { + if(s_cb_array[n] == old_cb) { + s_cb_array[n] = NULL; } } RTC_DEEP_SLEEP_EXIT_CRITICAL(); } +esp_err_t esp_deep_sleep_register_hook(esp_deep_sleep_cb_t new_dslp_cb) +{ + return s_sleep_hook_register(new_dslp_cb, s_dslp_cb); +} + +void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb) +{ + s_sleep_hook_deregister(old_dslp_cb, s_dslp_cb); +} + +esp_err_t esp_deep_sleep_register_phy_hook(esp_deep_sleep_cb_t new_dslp_cb) +{ + return s_sleep_hook_register(new_dslp_cb, s_dslp_phy_cb); +} + +void esp_deep_sleep_deregister_phy_hook(esp_deep_sleep_cb_t old_dslp_cb) +{ + s_sleep_hook_deregister(old_dslp_cb, s_dslp_phy_cb); +} + +static void s_do_deep_sleep_phy_callback(void) +{ + for (int n = 0; n < MAX_DSLP_HOOKS; n++) { + if (s_dslp_phy_cb[n] != NULL) { + s_dslp_phy_cb[n](); + } + } +} + +static int s_cache_suspend_cnt = 0; + +static void IRAM_ATTR suspend_cache(void) { + s_cache_suspend_cnt++; + if (s_cache_suspend_cnt == 1) { + cache_hal_suspend(CACHE_TYPE_ALL); + } +} + +static void IRAM_ATTR resume_cache(void) { + s_cache_suspend_cnt--; + assert(s_cache_suspend_cnt >= 0 && "cache resume doesn't match suspend ops"); + if (s_cache_suspend_cnt == 0) { + cache_hal_resume(CACHE_TYPE_ALL); + } +} + +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND +static uint32_t s_stopped_tgwdt_bmap = 0; +#endif + +// Must be called from critical sections. +static void IRAM_ATTR suspend_timers(uint32_t pd_flags) { + if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND + /* If timegroup implemented task watchdog or interrupt watchdog is running, we have to stop it. */ + for (uint32_t tg_num = 0; tg_num < SOC_TIMER_GROUPS; ++tg_num) { + if (mwdt_ll_check_if_enabled(TIMER_LL_GET_HW(tg_num))) { + mwdt_ll_write_protect_disable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_disable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_write_protect_enable(TIMER_LL_GET_HW(tg_num)); + s_stopped_tgwdt_bmap |= BIT(tg_num); + } + } +#endif +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND + for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) { + systimer_ll_enable_counter(&SYSTIMER, counter_id, false); + } +#endif + } +} + +// Must be called from critical sections. +static void IRAM_ATTR resume_timers(uint32_t pd_flags) { + if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { +#if SOC_SLEEP_SYSTIMER_STALL_WORKAROUND + for (uint32_t counter_id = 0; counter_id < SOC_SYSTIMER_COUNTER_NUM; ++counter_id) { + systimer_ll_enable_counter(&SYSTIMER, counter_id, true); + } +#endif +#if SOC_SLEEP_TGWDT_STOP_WORKAROUND + for (uint32_t tg_num = 0; tg_num < SOC_TIMER_GROUPS; ++tg_num) { + if (s_stopped_tgwdt_bmap & BIT(tg_num)) { + mwdt_ll_write_protect_disable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_enable(TIMER_LL_GET_HW(tg_num)); + mwdt_ll_write_protect_enable(TIMER_LL_GET_HW(tg_num)); + } + } +#endif + } +} + // [refactor-todo] provide target logic for body of uart functions below static void IRAM_ATTR flush_uarts(void) { @@ -474,12 +593,17 @@ static void IRAM_ATTR resume_uarts(void) static bool light_sleep_uart_prepare(uint32_t pd_flags, int64_t sleep_duration) { bool should_skip_sleep = false; -#if !SOC_PM_SUPPORT_TOP_PD +#if !SOC_PM_SUPPORT_TOP_PD || !CONFIG_ESP_CONSOLE_UART suspend_uarts(); #else - if (pd_flags & PMU_SLEEP_PD_TOP) { +#ifdef CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION +#define FORCE_FLUSH_CONSOLE_UART 1 +#else +#define FORCE_FLUSH_CONSOLE_UART 0 +#endif + if (FORCE_FLUSH_CONSOLE_UART || (pd_flags & PMU_SLEEP_PD_TOP)) { if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && - // +1 is for cover the last charactor flush time + // +1 is for cover the last character flush time (sleep_duration < (int64_t)((UART_LL_FIFO_DEF_LEN - uart_ll_get_txfifo_len(CONSOLE_UART_DEV) + 1) * UART_FLUSH_US_PER_CHAR) + SLEEP_UART_FLUSH_DONE_TO_SLEEP_US)) { should_skip_sleep = true; } else { @@ -506,6 +630,10 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep) } } } else { +#if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP + // Only avoid USJ pad leakage here, USB OTG pad leakage is prevented through USB Host driver. + sleep_console_usj_pad_backup_and_disable(); +#endif #if CONFIG_MAC_BB_PD mac_bb_power_down_cb_execute(); #endif @@ -517,9 +645,6 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep) #endif #if REGI2C_ANA_CALI_PD_WORKAROUND regi2c_analog_cali_reg_read(); -#endif -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG - sleep_retention_do_system_retention(true); #endif } @@ -534,8 +659,8 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep) */ inline static void IRAM_ATTR misc_modules_wake_prepare(void) { -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG - sleep_retention_do_system_retention(false); +#if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP + sleep_console_usj_pad_restore(); #endif sar_periph_ctrl_power_enable(); #if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL @@ -552,9 +677,37 @@ inline static void IRAM_ATTR misc_modules_wake_prepare(void) #endif } +static IRAM_ATTR void sleep_low_power_clock_calibration(bool is_dslp) +{ + // Calibrate rtc slow clock +#ifdef CONFIG_ESP_SYSTEM_RTC_EXT_XTAL + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + uint64_t time_per_us = 1000000ULL; + s_config.rtc_clk_cal_period = (time_per_us << RTC_CLK_CAL_FRACT) / rtc_clk_slow_freq_get_hz(); + } else { + // If the external 32 kHz XTAL does not exist, use the internal 150 kHz RC oscillator + // as the RTC slow clock source. + s_config.rtc_clk_cal_period = rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES); + esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period); + } +#elif CONFIG_RTC_CLK_SRC_INT_RC && CONFIG_IDF_TARGET_ESP32S2 + s_config.rtc_clk_cal_period = rtc_clk_cal_cycling(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES); + esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period); +#else + s_config.rtc_clk_cal_period = rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES); + esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period); +#endif + + // Calibrate rtc fast clock, only PMU supported chips sleep process is needed. +#if SOC_PMU_SUPPORTED + s_config.fast_clk_cal_period = rtc_clk_cal(RTC_CAL_RC_FAST, FAST_CLK_SRC_CAL_CYCLES); +#endif +} + + inline static uint32_t call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu, bool dslp); -static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mode) +static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mode, bool allow_sleep_rejection) { // Stop UART output so that output is not lost due to APB frequency change. // For light sleep, suspend UART output — it will resume after wakeup. @@ -595,6 +748,18 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m should_skip_sleep = light_sleep_uart_prepare(pd_flags, sleep_duration); } + // Do deep-sleep PHY related callback, which need to be executed when the PLL clock is exists. + // For light-sleep, PHY state is managed by the upper layer of the wifi/bt protocol stack. + if (deep_sleep) { + s_do_deep_sleep_phy_callback(); + } + +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA + if (!deep_sleep && (pd_flags & PMU_SLEEP_PD_TOP)) { + sleep_retention_do_system_retention(true); + } +#endif + // Save current frequency and switch to XTAL rtc_cpu_freq_config_t cpu_freq_config; rtc_clk_cpu_freq_get_config(&cpu_freq_config); @@ -618,16 +783,24 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m } #endif -#if CONFIG_ULP_COPROC_TYPE_FSM +#if CONFIG_ULP_COPROC_ENABLED // Enable ULP wakeup +#if CONFIG_ULP_COPROC_TYPE_FSM if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { +#elif CONFIG_ULP_COPROC_TYPE_RISCV + if (s_config.wakeup_triggers & (RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN)) { +#elif CONFIG_ULP_COPROC_TYPE_LP_CORE + if (s_config.wakeup_triggers & RTC_LP_CORE_TRIG_EN) { +#endif #ifdef CONFIG_IDF_TARGET_ESP32 rtc_hal_ulp_wakeup_enable(); +#elif CONFIG_ULP_COPROC_TYPE_LP_CORE + pmu_ll_hp_clear_sw_intr_status(&PMU); #else rtc_hal_ulp_int_clear(); #endif } -#endif +#endif // CONFIG_ULP_COPROC_ENABLED misc_modules_sleep_prepare(deep_sleep); @@ -652,10 +825,14 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m } #endif - /* Enable sleep reject for faster return from this function, - * in case the wakeup is already triggerred. - */ - uint32_t reject_triggers = (s_config.wakeup_triggers & RTC_SLEEP_REJECT_MASK) | sleep_modem_reject_triggers(); + uint32_t reject_triggers = allow_sleep_rejection ? (s_config.wakeup_triggers & RTC_SLEEP_REJECT_MASK) : 0; + + if (!deep_sleep) { + /* Enable sleep reject for faster return from this function, + * in case the wakeup is already triggerred. + */ + reject_triggers |= sleep_modem_reject_triggers(); + } //Append some flags in addition to power domains uint32_t sleep_flags = pd_flags; @@ -669,11 +846,17 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m sleep_flags |= RTC_SLEEP_DIG_USE_8M; } +#if CONFIG_ESP_SLEEP_DEBUG + if (s_sleep_ctx != NULL) { + s_sleep_ctx->sleep_flags = sleep_flags; + } +#endif + // Enter sleep esp_err_t result; #if SOC_PMU_SUPPORTED pmu_sleep_config_t config; - pmu_sleep_init(pmu_sleep_config_default(&config, pd_flags, s_config.sleep_time_adjustment, + pmu_sleep_init(pmu_sleep_config_default(&config, sleep_flags, s_config.sleep_time_adjustment, s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period, deep_sleep), deep_sleep); #else @@ -690,25 +873,24 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m // Configure timer wakeup if (!should_skip_sleep && (s_config.wakeup_triggers & RTC_TIMER_TRIG_EN)) { if (timer_wakeup_prepare(sleep_duration) != ESP_OK) { - should_skip_sleep = true; + should_skip_sleep = allow_sleep_rejection ? true : false; } } -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND - if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { - rtc_sleep_systimer_enable(false); - } -#endif if (should_skip_sleep) { result = ESP_ERR_SLEEP_REJECT; } else { +#if CONFIG_ESP_SLEEP_DEBUG + if (s_sleep_ctx != NULL) { + s_sleep_ctx->wakeup_triggers = s_config.wakeup_triggers; + } +#endif if (deep_sleep) { #if !SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP esp_sleep_isolate_digital_gpio(); #endif -#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268 #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY // Enter Deep Sleep #if SOC_PMU_SUPPORTED @@ -728,16 +910,15 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers); #endif #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY -#else // !CONFIG_IDF_TARGET_ESP32H2 - result = ESP_OK; -#endif // !CONFIG_IDF_TARGET_ESP32H2 } else { + suspend_timers(pd_flags); + /* Cache Suspend 1: will wait cache idle in cache suspend to avoid cache load wrong data after spi io isolation */ + suspend_cache(); /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode. In order to avoid the leakage of the SPI cs pin, hold it here */ #if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) #if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet if(!(pd_flags & PMU_SLEEP_PD_VDDSDIO)) { - cache_hal_freeze(CACHE_TYPE_ALL); gpio_ll_hold_en(&GPIO, SPI_CS0_GPIO_NUM); } #endif @@ -745,12 +926,15 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #if SOC_PMU_SUPPORTED #if SOC_PM_CPU_RETENTION_BY_SW + esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_GOTO_SLEEP, (void *)0); if (pd_flags & PMU_SLEEP_PD_CPU) { result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); - } else { + } else #endif + { result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); } + esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_EXIT_SLEEP, (void *)0); #else result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep); #endif @@ -760,18 +944,22 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet if(!(pd_flags & PMU_SLEEP_PD_VDDSDIO)) { gpio_ll_hold_dis(&GPIO, SPI_CS0_GPIO_NUM); - cache_hal_unfreeze(CACHE_TYPE_ALL); } #endif #endif + /* Cache Resume 1: Resume cache for continue running*/ + resume_cache(); + resume_timers(pd_flags); } + } -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND - if (!(pd_flags & RTC_SLEEP_PD_XTAL)) { - rtc_sleep_systimer_enable(true); - } -#endif +#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION + if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { + /* Cache Suspend 2: If previous sleep powerdowned the flash, suspend cache here so that the + access to flash before flash ready can be explicitly exposed. */ + suspend_cache(); } +#endif // Restore CPU frequency #if SOC_PM_SUPPORT_PMU_MODEM_STATE @@ -783,6 +971,18 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m rtc_clk_cpu_freq_set_config(&cpu_freq_config); } + esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CLK_READY, (void *)0); + + if (!deep_sleep) { + s_config.ccount_ticks_record = esp_cpu_get_cycle_count(); +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA + if (pd_flags & PMU_SLEEP_PD_TOP) { + sleep_retention_do_system_retention(false); + } +#endif + misc_modules_wake_prepare(); + } + // Set mspi clock to ROM default one. if (cpu_freq_config.source == SOC_CPU_CLK_SRC_PLL) { #if SOC_MEMSPI_CLOCK_IS_INDEPENDENT @@ -794,11 +994,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #endif } - if (!deep_sleep) { - s_config.ccount_ticks_record = esp_cpu_get_cycle_count(); - misc_modules_wake_prepare(); - } - // re-enable UART output resume_uarts(); return result ? ESP_ERR_SLEEP_REJECT : ESP_OK; @@ -815,7 +1010,7 @@ inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers, #endif } -void IRAM_ATTR esp_deep_sleep_start(void) +static esp_err_t IRAM_ATTR deep_sleep_start(bool allow_sleep_rejection) { #if CONFIG_IDF_TARGET_ESP32S2 /* Due to hardware limitations, on S2 the brownout detector sometimes trigger during deep sleep @@ -834,7 +1029,8 @@ void IRAM_ATTR esp_deep_sleep_start(void) // Decide which power domains can be powered down uint32_t pd_flags = get_power_down_flags(); - s_config.rtc_clk_cal_period = esp_clk_slowclk_cal_get(); + // Re-calibrate the RTC clock + sleep_low_power_clock_calibration(true); // Correct the sleep time s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US; @@ -842,6 +1038,9 @@ void IRAM_ATTR esp_deep_sleep_start(void) #if SOC_PMU_SUPPORTED uint32_t force_pd_flags = PMU_SLEEP_PD_TOP | PMU_SLEEP_PD_VDDSDIO | PMU_SLEEP_PD_MODEM | PMU_SLEEP_PD_HP_PERIPH \ | PMU_SLEEP_PD_CPU | PMU_SLEEP_PD_MEM | PMU_SLEEP_PD_XTAL; +#if SOC_PM_SUPPORT_HP_AON_PD + force_pd_flags |= PMU_SLEEP_PD_HP_AON; +#endif #else uint32_t force_pd_flags = RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | RTC_SLEEP_PD_INT_8M | RTC_SLEEP_PD_XTAL; #endif @@ -863,17 +1062,39 @@ void IRAM_ATTR esp_deep_sleep_start(void) #endif // Enter sleep - if (esp_sleep_start(force_pd_flags | pd_flags, ESP_SLEEP_MODE_DEEP_SLEEP) == ESP_ERR_SLEEP_REJECT) { - ESP_EARLY_LOGW(TAG, "Deep sleep request is rejected"); + esp_err_t err = ESP_OK; + if (esp_sleep_start(force_pd_flags | pd_flags, ESP_SLEEP_MODE_DEEP_SLEEP, allow_sleep_rejection) == ESP_ERR_SLEEP_REJECT) { + err = ESP_ERR_SLEEP_REJECT; +#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION + /* Cache Resume 2: if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is enabled, cache has been suspended in esp_sleep_start */ + resume_cache(); +#endif + ESP_EARLY_LOGE(TAG, "Deep sleep request is rejected"); + } else { + // Because RTC is in a slower clock domain than the CPU, it + // can take several CPU cycles for the sleep mode to start. + while (1) { + ; + } } + // Never returns here, except that the sleep is rejected. + esp_ipc_isr_release_other_cpu(); + portEXIT_CRITICAL(&spinlock_rtc_deep_sleep); + return err; +} - // Because RTC is in a slower clock domain than the CPU, it - // can take several CPU cycles for the sleep mode to start. - while (1) { - ; - } +void IRAM_ATTR esp_deep_sleep_start(void) +{ + bool allow_sleep_rejection = true; + deep_sleep_start(!allow_sleep_rejection); // Never returns here - RTC_DEEP_SLEEP_EXIT_CRITICAL(); + abort(); +} + +esp_err_t IRAM_ATTR esp_deep_sleep_try_to_start(void) +{ + bool allow_sleep_rejection = true; + return deep_sleep_start(allow_sleep_rejection); } /** @@ -886,11 +1107,14 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, uint32_t flash_enable_time_us) { +#if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED + rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config(); +#endif + // Enter sleep - esp_err_t reject = esp_sleep_start(pd_flags, ESP_SLEEP_MODE_LIGHT_SLEEP); + esp_err_t reject = esp_sleep_start(pd_flags, ESP_SLEEP_MODE_LIGHT_SLEEP, true); #if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED - rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config(); // If VDDSDIO regulator was controlled by RTC registers before sleep, // restore the configuration. if (vddsdio_config.force) { @@ -900,10 +1124,29 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, // If SPI flash was powered down, wait for it to become ready if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { +#if SOC_PM_SUPPORT_TOP_PD + if (pd_flags & PMU_SLEEP_PD_TOP) { + uint32_t flash_ready_hw_waited_time_us = pmu_sleep_get_wakup_retention_cost(); + uint32_t flash_ready_sw_waited_time_us = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / MHZ); + uint32_t flash_ready_waited_time_us = flash_ready_hw_waited_time_us + flash_ready_sw_waited_time_us; + if (flash_enable_time_us > flash_ready_waited_time_us){ + flash_enable_time_us -= flash_ready_waited_time_us; + } else { + flash_enable_time_us = 0; + } + } +#endif // Wait for the flash chip to start up esp_rom_delay_us(flash_enable_time_us); } +#if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION + if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { + /* Cache Resume 2: flash is ready now, we can resume the cache and access flash safely after */ + resume_cache(); + } +#endif + return reject; } @@ -926,6 +1169,7 @@ static inline bool can_power_down_vddsdio(uint32_t pd_flags, const uint32_t vdds esp_err_t esp_light_sleep_start(void) { s_config.ccount_ticks_record = esp_cpu_get_cycle_count(); + esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_GOTO_SLEEP, (void *)0); #if CONFIG_ESP_TASK_WDT_USE_ESP_TIMER esp_err_t timerret = ESP_OK; @@ -957,15 +1201,18 @@ esp_err_t esp_light_sleep_start(void) */ esp_clk_private_lock(); -#if SOC_LP_TIMER_SUPPORTED - s_config.rtc_ticks_at_sleep_start = lp_timer_hal_get_cycle_count(); -#else s_config.rtc_ticks_at_sleep_start = rtc_time_get(); -#endif uint32_t ccount_at_sleep_start = esp_cpu_get_cycle_count(); + esp_sleep_execute_event_callbacks(SLEEP_EVENT_HW_TIME_START, (void *)0); uint64_t high_res_time_at_start = esp_timer_get_time(); uint32_t sleep_time_overhead_in = (ccount_at_sleep_start - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL); +#if CONFIG_ESP_SLEEP_DEBUG + if (s_sleep_ctx != NULL) { + s_sleep_ctx->sleep_in_rtc_time_stamp = s_config.rtc_ticks_at_sleep_start; + } +#endif + // Decide which power domains can be powered down uint32_t pd_flags = get_power_down_flags(); @@ -974,24 +1221,8 @@ esp_err_t esp_light_sleep_start(void) pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; #endif - // Re-calibrate the RTC Timer clock -#ifdef CONFIG_ESP_SYSTEM_RTC_EXT_XTAL - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { - uint64_t time_per_us = 1000000ULL; - s_config.rtc_clk_cal_period = (time_per_us << RTC_CLK_CAL_FRACT) / rtc_clk_slow_freq_get_hz(); - } else { - // If the external 32 kHz XTAL does not exist, use the internal 150 kHz RC oscillator - // as the RTC slow clock source. - s_config.rtc_clk_cal_period = rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES); - esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period); - } -#elif CONFIG_RTC_CLK_SRC_INT_RC && CONFIG_IDF_TARGET_ESP32S2 - s_config.rtc_clk_cal_period = rtc_clk_cal_cycling(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES); - esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period); -#else - s_config.rtc_clk_cal_period = rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES); - esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period); -#endif + // Re-calibrate the RTC clock + sleep_low_power_clock_calibration(false); /* * Adjustment time consists of parts below: @@ -1000,9 +1231,7 @@ esp_err_t esp_light_sleep_start(void) * 3. Code execution time when clock is not stable; * 4. Code execution time which can be measured; */ - #if SOC_PMU_SUPPORTED - s_config.fast_clk_cal_period = rtc_clk_cal(RTC_CAL_RC_FAST, FAST_CLK_SRC_CAL_CYCLES); int sleep_time_sw_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out; int sleep_time_hw_adjustment = pmu_sleep_calculate_hw_wait_time(pd_flags, s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period); s_config.sleep_time_adjustment = sleep_time_sw_adjustment + sleep_time_hw_adjustment; @@ -1076,6 +1305,13 @@ esp_err_t esp_light_sleep_start(void) // reset light sleep wakeup flag before a new light sleep s_light_sleep_wakeup = false; + s_lightsleep_cnt++; +#if CONFIG_ESP_SLEEP_DEBUG + if (s_sleep_ctx != NULL) { + s_sleep_ctx->lightsleep_cnt = s_lightsleep_cnt; + } +#endif + // if rtc timer wakeup source is enabled, need to compare final sleep duration and min sleep duration to avoid late wakeup if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && (final_sleep_duration_us <= min_sleep_duration_us)) { err = ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION; @@ -1088,13 +1324,15 @@ esp_err_t esp_light_sleep_start(void) s_light_sleep_wakeup = (err == ESP_OK); // System timer has been stopped for the duration of the sleep, correct for that. -#if SOC_LP_TIMER_SUPPORTED - uint64_t rtc_ticks_at_end = lp_timer_hal_get_cycle_count(); -#else uint64_t rtc_ticks_at_end = rtc_time_get(); -#endif uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, s_config.rtc_clk_cal_period); +#if CONFIG_ESP_SLEEP_DEBUG + if (s_sleep_ctx != NULL) { + s_sleep_ctx->sleep_out_rtc_time_stamp = rtc_ticks_at_end; + } +#endif + /** * If sleep duration is too small(less than 1 rtc_slow_clk cycle), rtc_time_diff will be zero. * In this case, just ignore the time compensation and keep esp_timer monotonic. @@ -1121,7 +1359,14 @@ esp_err_t esp_light_sleep_start(void) } #endif // CONFIG_ESP_TASK_WDT_USE_ESP_TIMER + esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_EXIT_SLEEP, (void *)0); s_config.sleep_time_overhead_out = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL); + +#if CONFIG_ESP_SLEEP_DEBUG + if (s_sleep_ctx != NULL) { + s_sleep_ctx->sleep_request_result = err; + } +#endif return err; } @@ -1218,7 +1463,7 @@ static esp_err_t timer_wakeup_prepare(int64_t sleep_duration) #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP // Last timer wake-up validity check if ((sleep_duration == 0) || \ - (target_wakeup_tick < lp_timer_hal_get_cycle_count() + SLEEP_TIMER_ALARM_TO_SLEEP_TICKS)) { + (target_wakeup_tick < rtc_time_get() + SLEEP_TIMER_ALARM_TO_SLEEP_TICKS)) { // Treat too short sleep duration setting as timer reject return ESP_ERR_SLEEP_REJECT; } @@ -1286,11 +1531,11 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status(void) bool esp_sleep_is_valid_wakeup_gpio(gpio_num_t gpio_num) { -#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED +#if SOC_RTCIO_PIN_COUNT > 0 return RTC_GPIO_IS_VALID_GPIO(gpio_num); #else return GPIO_IS_DEEP_SLEEP_WAKEUP_VALID_GPIO(gpio_num); -#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED +#endif } #if SOC_PM_SUPPORT_EXT0_WAKEUP @@ -1325,15 +1570,27 @@ static void ext0_wakeup_prepare(void) #endif // SOC_PM_SUPPORT_EXT0_WAKEUP #if SOC_PM_SUPPORT_EXT1_WAKEUP -esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode) +esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t io_mask, esp_sleep_ext1_wakeup_mode_t level_mode) { - if (mode > ESP_EXT1_WAKEUP_ANY_HIGH) { + if (io_mask == 0 && level_mode > ESP_EXT1_WAKEUP_ANY_HIGH) { + return ESP_ERR_INVALID_ARG; + } + // Reset all EXT1 configs + esp_sleep_disable_ext1_wakeup_io(0); + + return esp_sleep_enable_ext1_wakeup_io(io_mask, level_mode); +} + + +esp_err_t esp_sleep_enable_ext1_wakeup_io(uint64_t io_mask, esp_sleep_ext1_wakeup_mode_t level_mode) +{ + if (io_mask == 0 && level_mode > ESP_EXT1_WAKEUP_ANY_HIGH) { return ESP_ERR_INVALID_ARG; } // Translate bit map of GPIO numbers into the bit map of RTC IO numbers uint32_t rtc_gpio_mask = 0; - for (int gpio = 0; mask; ++gpio, mask >>= 1) { - if ((mask & 1) == 0) { + for (int gpio = 0; io_mask; ++gpio, io_mask >>= 1) { + if ((io_mask & 1) == 0) { continue; } if (!esp_sleep_is_valid_wakeup_gpio(gpio)) { @@ -1342,11 +1599,89 @@ esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode } rtc_gpio_mask |= BIT(rtc_io_number_get(gpio)); } + +#if !SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN + uint32_t ext1_rtc_gpio_mask = 0; + uint32_t ext1_trigger_mode = 0; + + ext1_rtc_gpio_mask = s_config.ext1_rtc_gpio_mask | rtc_gpio_mask; + if (level_mode) { + ext1_trigger_mode = s_config.ext1_trigger_mode | rtc_gpio_mask; + } else { + ext1_trigger_mode = s_config.ext1_trigger_mode & (~rtc_gpio_mask); + } + if (((ext1_rtc_gpio_mask & ext1_trigger_mode) != ext1_rtc_gpio_mask) && + ((ext1_rtc_gpio_mask & ext1_trigger_mode) != 0)) { + return ESP_ERR_NOT_SUPPORTED; + } +#endif + + s_config.ext1_rtc_gpio_mask |= rtc_gpio_mask; + if (level_mode) { + s_config.ext1_trigger_mode |= rtc_gpio_mask; + } else { + s_config.ext1_trigger_mode &= (~rtc_gpio_mask); + } + s_config.wakeup_triggers |= RTC_EXT1_TRIG_EN; + return ESP_OK; +} + +esp_err_t esp_sleep_disable_ext1_wakeup_io(uint64_t io_mask) +{ + if (io_mask == 0) { + s_config.ext1_rtc_gpio_mask = 0; + s_config.ext1_trigger_mode = 0; + } else { + // Translate bit map of GPIO numbers into the bit map of RTC IO numbers + uint32_t rtc_gpio_mask = 0; + for (int gpio = 0; io_mask; ++gpio, io_mask >>= 1) { + if ((io_mask & 1) == 0) { + continue; + } + if (!esp_sleep_is_valid_wakeup_gpio(gpio)) { + ESP_LOGE(TAG, "Not an RTC IO Considering io_mask: GPIO%d", gpio); + return ESP_ERR_INVALID_ARG; + } + rtc_gpio_mask |= BIT(rtc_io_number_get(gpio)); + } + s_config.ext1_rtc_gpio_mask &= (~rtc_gpio_mask); + s_config.ext1_trigger_mode &= (~rtc_gpio_mask); + } + + if (s_config.ext1_rtc_gpio_mask == 0) { + s_config.wakeup_triggers &= (~RTC_EXT1_TRIG_EN); + } + return ESP_OK; +} + +#if SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN +esp_err_t esp_sleep_enable_ext1_wakeup_with_level_mask(uint64_t io_mask, uint64_t level_mask) +{ + if ((level_mask & io_mask) != level_mask) { + return ESP_ERR_INVALID_ARG; + } + // Translate bit map of GPIO numbers into the bit map of RTC IO numbers + // Translate bit map of GPIO wakeup mode into the bit map of RTC IO wakeup mode + uint32_t rtc_gpio_mask = 0, rtc_gpio_wakeup_mode_mask = 0; + for (int gpio = 0; io_mask; ++gpio, io_mask >>= 1, level_mask >>= 1) { + if ((io_mask & 1) == 0) { + continue; + } + if (!esp_sleep_is_valid_wakeup_gpio(gpio)) { + ESP_LOGE(TAG, "Not an RTC IO Considering io_mask: GPIO%d", gpio); + return ESP_ERR_INVALID_ARG; + } + rtc_gpio_mask |= BIT(rtc_io_number_get(gpio)); + if ((level_mask & 1) == 1) { + rtc_gpio_wakeup_mode_mask |= BIT(rtc_io_number_get(gpio)); + } + } s_config.ext1_rtc_gpio_mask = rtc_gpio_mask; - s_config.ext1_trigger_mode = mode; + s_config.ext1_trigger_mode = rtc_gpio_wakeup_mode_mask; s_config.wakeup_triggers |= RTC_EXT1_TRIG_EN; return ESP_OK; } +#endif static void ext1_wakeup_prepare(void) { @@ -1362,20 +1697,23 @@ static void ext1_wakeup_prepare(void) rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_RTC); // set input enable in sleep mode rtcio_hal_input_enable(rtc_pin); -#endif - #if SOC_PM_SUPPORT_RTC_PERIPH_PD // Pad configuration depends on RTC_PERIPH state in sleep mode if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option != ESP_PD_OPTION_ON) { -#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED - // RTC_PERIPH will be powered down, so RTC_IO_ registers will - // loose their state. Lock pad configuration. - // Pullups/pulldowns also need to be disabled. - rtcio_hal_pullup_disable(rtc_pin); - rtcio_hal_pulldown_disable(rtc_pin); -#endif rtcio_hal_hold_enable(rtc_pin); } +#endif +#else + /* ESP32H2 use hp iomux to config rtcio, and there is no complete + * rtcio functionality. In the case of EXT1 wakeup, rtcio only provides + * a pathway to EXT1. */ + + // Route pad to DIGITAL + rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_DIGITAL); + // set input enable + gpio_ll_input_enable(&GPIO, gpio); + // hold rtc_pin to use it during sleep state + rtcio_hal_hold_enable(rtc_pin); #endif // Keep track of pins which are processed to bail out early rtc_gpio_mask &= ~BIT(rtc_pin); @@ -1383,7 +1721,7 @@ static void ext1_wakeup_prepare(void) // Clear state from previous wakeup rtc_hal_ext1_clear_wakeup_status(); - // Set RTC IO pins and mode (any high, all low) to be used for wakeup + // Set RTC IO pins and mode to be used for wakeup rtc_hal_ext1_set_wakeup_pins(s_config.ext1_rtc_gpio_mask, s_config.ext1_trigger_mode); } @@ -1413,24 +1751,19 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void) #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP uint64_t esp_sleep_get_gpio_wakeup_status(void) { -#if CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268 - return 0; -#else if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) { return 0; } - return rtc_hal_gpio_get_wakeup_status(); -#endif // !CONFIG_IDF_TARGET_ESP32H2 } static void gpio_deep_sleep_wakeup_prepare(void) { -#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268 for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) { if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) { continue; } +#if CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS if (s_config.gpio_trigger_mode & BIT(gpio_idx)) { ESP_ERROR_CHECK(gpio_pullup_dis(gpio_idx)); ESP_ERROR_CHECK(gpio_pulldown_en(gpio_idx)); @@ -1438,11 +1771,11 @@ static void gpio_deep_sleep_wakeup_prepare(void) ESP_ERROR_CHECK(gpio_pullup_en(gpio_idx)); ESP_ERROR_CHECK(gpio_pulldown_dis(gpio_idx)); } +#endif ESP_ERROR_CHECK(gpio_hold_en(gpio_idx)); } // Clear state from previous wakeup rtc_hal_gpio_clear_wakeup_status(); -#endif // !CONFIG_IDF_TARGET_ESP32H2 } esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode) @@ -1731,7 +2064,6 @@ static uint32_t get_power_down_flags(void) } #endif - #ifdef CONFIG_IDF_TARGET_ESP32 s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option = ESP_PD_OPTION_OFF; #endif @@ -1796,7 +2128,11 @@ static uint32_t get_power_down_flags(void) #endif #if SOC_PM_SUPPORT_MODEM_PD - if ((s_config.domain[ESP_PD_DOMAIN_MODEM].pd_option != ESP_PD_OPTION_ON) && modem_domain_pd_allowed()) { + if ((s_config.domain[ESP_PD_DOMAIN_MODEM].pd_option != ESP_PD_OPTION_ON) && modem_domain_pd_allowed() +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + && clock_domain_pd_allowed() +#endif + ) { pd_flags |= RTC_SLEEP_PD_MODEM; } #endif diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c index f04bb741ff..22ec20bd39 100644 --- a/components/esp_hw_support/sleep_retention.c +++ b/components/esp_hw_support/sleep_retention.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,6 +23,92 @@ static __attribute__((unused)) const char *TAG = "sleep"; +struct sleep_retention_module_object { + sleep_retention_module_callbacks_t cbs; /* A callback list that can extend more sleep retention event callbacks */ + sleep_retention_module_bitmap_t dependents; /* A bitmap identifying all modules that the current module depends on */ + sleep_retention_module_bitmap_t references; /* A bitmap indicating all other modules that depend on (or reference) the current module, + * It will update at runtime based on whether the module is referenced by other modules */ + sleep_retention_module_attribute_t attributes; /* A bitmap indicating attribute of the current module */ +}; + +static inline void sleep_retention_module_object_ctor(struct sleep_retention_module_object * const self, sleep_retention_module_callbacks_t *cbs) +{ + self->cbs = *cbs; + self->dependents = 0; + self->references = 0; + self->attributes = 0; +} + +static inline void sleep_retention_module_object_dtor(struct sleep_retention_module_object * const self) +{ + self->cbs = (sleep_retention_module_callbacks_t) { .create = { .handle = NULL, .arg = NULL } }; +} + +static inline void set_dependencies(struct sleep_retention_module_object * const self, sleep_retention_module_bitmap_t depends) +{ + self->dependents = depends; +} + +static inline void clr_dependencies(struct sleep_retention_module_object * const self) +{ + self->dependents = 0; +} + +static inline sleep_retention_module_bitmap_t get_dependencies(struct sleep_retention_module_object * const self) +{ + return self->dependents; +} + +static inline void set_reference(struct sleep_retention_module_object * const self, sleep_retention_module_t module) +{ + self->references |= BIT(module); +} + +static inline void clr_reference(struct sleep_retention_module_object * const self, sleep_retention_module_t module) +{ + self->references &= ~BIT(module); +} + +static inline sleep_retention_module_bitmap_t get_references(struct sleep_retention_module_object * const self) +{ + return self->references; +} + +static inline bool references_exist(struct sleep_retention_module_object * const self) +{ + return (get_references(self) != 0); +} + +static inline void set_attributes(struct sleep_retention_module_object * const self, sleep_retention_module_attribute_t attributes) +{ + self->attributes = attributes; +} + +static inline void clr_attributes(struct sleep_retention_module_object * const self) +{ + self->attributes = 0; +} + +static inline sleep_retention_module_attribute_t get_attributes(struct sleep_retention_module_object * const self) +{ + return self->attributes; +} + +static inline bool module_is_passive(struct sleep_retention_module_object * const self) +{ + return (get_attributes(self) & SLEEP_RETENTION_MODULE_ATTR_PASSIVE) ? true : false; +} + +static inline bool module_is_inited(sleep_retention_module_t module) +{ + return (sleep_retention_get_inited_modules() & BIT(module)) ? true : false; +} + +static inline bool module_is_created(sleep_retention_module_t module) +{ + return (sleep_retention_get_created_modules() & BIT(module)) ? true : false; +} + /** * Internal structure which holds all requested sleep retention parameters */ @@ -82,6 +168,7 @@ typedef struct { #define SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES (8u) #define SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY (0) #define SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY (SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES - 1) +#define SLEEP_RETENTION_MODULE_INVALID ((sleep_retention_module_t)(-1)) /* the final node does not belong to any module */ struct { sleep_retention_entries_t entries; uint32_t entries_bitmap: REGDMA_LINK_ENTRY_NUM, @@ -90,18 +177,18 @@ typedef struct { void *entries_tail; } lists[SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES]; regdma_link_priority_t highpri; - uint32_t modules; + uint32_t inited_modules; + uint32_t created_modules; + + struct sleep_retention_module_object instance[32]; + #if SOC_PM_RETENTION_HAS_CLOCK_BUG #define EXTRA_LINK_NUM (REGDMA_LINK_ENTRY_NUM - 1) - int extra_refs; #endif } sleep_retention_t; static DRAM_ATTR __attribute__((unused)) sleep_retention_t s_retention = { - .highpri = (uint8_t)-1, .modules = 0 -#if SOC_PM_RETENTION_HAS_CLOCK_BUG - , .extra_refs = 0 -#endif + .highpri = (uint8_t)-1, .inited_modules = 0, .created_modules = 0 }; K_SEM_DEFINE(s_retention_lock, 0, 5); @@ -109,9 +196,14 @@ K_SEM_DEFINE(s_retention_lock, 0, 5); #define SLEEP_RETENTION_ENTRY_BITMAP_MASK (BIT(REGDMA_LINK_ENTRY_NUM) - 1) #define SLEEP_RETENTION_ENTRY_BITMAP(bitmap) ((bitmap) & SLEEP_RETENTION_ENTRY_BITMAP_MASK) -static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module); +static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module); static void sleep_retention_entries_join(void); +static inline sleep_retention_module_bitmap_t module_num2map(sleep_retention_module_t module) +{ + return (module == SLEEP_RETENTION_MODULE_INVALID) ? 0 : BIT(module); +} + static inline bool sleep_retention_entries_require_branch(uint32_t owner, uint32_t runtime_bitmap) { bool use_new_entry = SLEEP_RETENTION_ENTRY_BITMAP(owner & ~runtime_bitmap) ? true : false; @@ -119,7 +211,7 @@ static inline bool sleep_retention_entries_require_branch(uint32_t owner, uint32 return use_new_entry && intersection_exist; } -static esp_err_t sleep_retention_entries_check_and_create_default(uint32_t owner, uint32_t runtime_bitmap, uint32_t entries_bitmap, regdma_link_priority_t priority, uint32_t module) +static esp_err_t sleep_retention_entries_check_and_create_default(uint32_t owner, uint32_t runtime_bitmap, uint32_t entries_bitmap, regdma_link_priority_t priority, sleep_retention_module_t module) { assert(sleep_retention_entries_require_branch(owner, runtime_bitmap)); @@ -138,7 +230,7 @@ static esp_err_t sleep_retention_entries_check_and_create_final_default(void) esp_err_t err = ESP_OK; k_sem_take(&s_retention_lock, K_FOREVER); if (s_retention.lists[SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY].entries_bitmap == 0) { - err = sleep_retention_entries_create_impl(&final_dummy, 1, SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY, 0); + err = sleep_retention_entries_create_impl(&final_dummy, 1, SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY, SLEEP_RETENTION_MODULE_INVALID); } k_sem_give(&s_retention_lock); return err; @@ -162,7 +254,7 @@ static void sleep_retention_entries_update(uint32_t owner, void *new_link, regdm k_sem_give(&s_retention_lock); } -static void * sleep_retention_entries_try_create(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, uint32_t module) +static void * sleep_retention_entries_try_create(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, sleep_retention_module_t module) { void *link = NULL; assert(owner > 0 && owner < BIT(REGDMA_LINK_ENTRY_NUM)); @@ -170,9 +262,9 @@ static void * sleep_retention_entries_try_create(const regdma_link_config_t *con k_sem_take(&s_retention_lock, K_FOREVER); if (sleep_retention_entries_require_branch(owner, s_retention.lists[priority].runtime_bitmap)) { if (sleep_retention_entries_check_and_create_default(owner, s_retention.lists[priority].runtime_bitmap, - s_retention.lists[priority].entries_bitmap, priority, module) == ESP_OK) { /* branch node can't as tail node */ + s_retention.lists[priority].entries_bitmap, priority, module_num2map(module)) == ESP_OK) { /* branch node can't as tail node */ link = regdma_link_init_safe( - config, true, module, + config, true, module_num2map(module), (owner & BIT(0)) ? s_retention.lists[priority].entries[0] : NULL, (owner & BIT(1)) ? s_retention.lists[priority].entries[1] : NULL, (owner & BIT(2)) ? s_retention.lists[priority].entries[2] : NULL, @@ -180,18 +272,18 @@ static void * sleep_retention_entries_try_create(const regdma_link_config_t *con ); } } else { - link = regdma_link_init_safe(config, false, module, s_retention.lists[priority].entries[__builtin_ffs(owner) - 1]); + link = regdma_link_init_safe(config, false, module_num2map(module), s_retention.lists[priority].entries[__builtin_ffs(owner) - 1]); } k_sem_give(&s_retention_lock); return link; } -static void * sleep_retention_entries_try_create_bonding(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, uint32_t module) +static void * sleep_retention_entries_try_create_bonding(const regdma_link_config_t *config, uint32_t owner, regdma_link_priority_t priority, sleep_retention_module_t module) { assert(owner > 0 && owner < BIT(REGDMA_LINK_ENTRY_NUM)); k_sem_take(&s_retention_lock, K_FOREVER); void *link = regdma_link_init_safe( - config, true, module, + config, true, module_num2map(module), (owner & BIT(0)) ? s_retention.lists[priority].entries[0] : NULL, (owner & BIT(1)) ? s_retention.lists[priority].entries[1] : NULL, (owner & BIT(2)) ? s_retention.lists[priority].entries[2] : NULL, @@ -213,13 +305,13 @@ static void sleep_retention_entries_stats(void) } #if REGDMA_LINK_DBG -void sleep_retention_entries_show_memories(void) +void sleep_retention_dump_entries(FILE *out) { k_sem_take(&s_retention_lock, K_FOREVER); if (s_retention.highpri >= SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY && s_retention.highpri <= SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) { for (int entry = 0; entry < ARRAY_SIZE(s_retention.lists[s_retention.highpri].entries); entry++) { - ESP_LOGW(TAG, "Print sleep retention entries[%d] memories:", entry); - regdma_link_show_memories(s_retention.lists[s_retention.highpri].entries[entry], entry); + fprintf(out, "\nsleep retention entries[%d] context:\n", entry); + regdma_link_dump(out, s_retention.lists[s_retention.highpri].entries[entry], entry); } } k_sem_give(&s_retention_lock); @@ -251,7 +343,7 @@ static uint32_t sleep_retention_entries_owner_bitmap(sleep_retention_entries_t * return owner; } -static bool sleep_retention_entries_get_destroy_context(regdma_link_priority_t priority, uint32_t module, sleep_retention_entries_t *destroy_entries, void **destroy_tail, sleep_retention_entries_t *next_entries, void **prev_tail) +static bool sleep_retention_entries_get_destroy_context(regdma_link_priority_t priority, sleep_retention_module_t module, sleep_retention_entries_t *destroy_entries, void **destroy_tail, sleep_retention_entries_t *next_entries, void **prev_tail) { bool exist = false; sleep_retention_entries_t destroy_tails, prev_tails; @@ -262,13 +354,13 @@ static bool sleep_retention_entries_get_destroy_context(regdma_link_priority_t p k_sem_take(&s_retention_lock, K_FOREVER); for (int entry = 0; entry < ARRAY_SIZE(s_retention.lists[priority].entries); entry++) { (*destroy_entries)[entry] = regdma_find_module_link_head( - s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module); + s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module)); destroy_tails [entry] = regdma_find_module_link_tail( - s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module); + s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module)); (*next_entries) [entry] = regdma_find_next_module_link_head( - s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module); + s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module)); prev_tails [entry] = regdma_find_prev_module_link_tail( - s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module); + s_retention.lists[priority].entries[entry], s_retention.lists[priority].entries_tail, entry, module_num2map(module)); if ((*destroy_entries)[entry] && destroy_tails[entry]) { exist = true; } @@ -327,12 +419,12 @@ static void sleep_retention_entries_check_and_distroy_final_default(void) { k_sem_take(&s_retention_lock, K_FOREVER); assert(s_retention.highpri == SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY); - assert(s_retention.modules == 0); + assert(s_retention.created_modules == 0); sleep_retention_entries_destroy_wrapper(&s_retention.lists[SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY].entries); k_sem_give(&s_retention_lock); } -static void sleep_retention_entries_all_destroy_wrapper(uint32_t module) +static void sleep_retention_entries_all_destroy_wrapper(sleep_retention_module_t module) { void *destroy_tail = NULL, *prev_tail = NULL; sleep_retention_entries_t destroy_entries, next_entries; @@ -353,13 +445,13 @@ static void sleep_retention_entries_all_destroy_wrapper(uint32_t module) priority++; } } while (priority < SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES); - s_retention.modules &= ~module; + s_retention.created_modules &= ~module_num2map(module); k_sem_give(&s_retention_lock); } -static void sleep_retention_entries_do_destroy(int module) +static void sleep_retention_entries_do_destroy(sleep_retention_module_t module) { - assert(module != 0); + assert(SLEEP_RETENTION_MODULE_MIN <= module && module <= SLEEP_RETENTION_MODULE_MAX); k_sem_take(&s_retention_lock, K_FOREVER); sleep_retention_entries_join(); sleep_retention_entries_stats(); @@ -367,12 +459,12 @@ static void sleep_retention_entries_do_destroy(int module) k_sem_give(&s_retention_lock); } -void sleep_retention_entries_destroy(int module) +static void sleep_retention_entries_destroy(sleep_retention_module_t module) { - assert(module != 0); + assert(SLEEP_RETENTION_MODULE_MIN <= module && module <= SLEEP_RETENTION_MODULE_MAX); k_sem_take(&s_retention_lock, K_FOREVER); sleep_retention_entries_do_destroy(module); - if (s_retention.modules == 0) { + if (s_retention.created_modules == 0) { sleep_retention_entries_check_and_distroy_final_default(); pmu_sleep_disable_regdma_backup(); memset((void *)s_retention.lists, 0, sizeof(s_retention.lists)); @@ -384,7 +476,7 @@ void sleep_retention_entries_destroy(int module) k_sem_give(&s_retention_lock); } -static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module) +static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module) { k_sem_take(&s_retention_lock, K_FOREVER); for (int i = num - 1; i >= 0; i--) { @@ -407,7 +499,7 @@ static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entri return ESP_OK; } -static esp_err_t sleep_retention_entries_create_bonding(regdma_link_priority_t priority, uint32_t module) +static esp_err_t sleep_retention_entries_create_bonding(regdma_link_priority_t priority, sleep_retention_module_t module) { static const sleep_retention_entries_config_t bonding_dummy = { REGDMA_LINK_WAIT_INIT(0xffff, 0, 0, 0, 1, 1), SLEEP_RETENTION_ENTRY_BITMAP_MASK }; @@ -446,7 +538,7 @@ static void sleep_retention_entries_join(void) k_sem_give(&s_retention_lock); } -static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, uint32_t module) +static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module) { k_sem_take(&s_retention_lock, K_FOREVER); esp_err_t err = sleep_retention_entries_create_bonding(priority, module); @@ -455,7 +547,7 @@ static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_en if(err) goto error; err = sleep_retention_entries_create_bonding(priority, module); if(err) goto error; - s_retention.modules |= module; + s_retention.created_modules |= module_num2map(module); sleep_retention_entries_join(); error: @@ -463,9 +555,15 @@ static esp_err_t sleep_retention_entries_create_wrapper(const sleep_retention_en return err; } -esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, int module) +esp_err_t sleep_retention_entries_create(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module) { - if (!(retent && num > 0 && (priority < SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES) && (module != 0))) { + if (retent == NULL || num <= 0) { + return ESP_ERR_INVALID_ARG; + } + if (priority >= SLEEP_RETENTION_REGDMA_LINK_NR_PRIORITIES) { + return ESP_ERR_INVALID_ARG; + } + if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { return ESP_ERR_INVALID_ARG; } esp_err_t err = sleep_retention_entries_check_and_create_final_default(); @@ -490,50 +588,213 @@ void sleep_retention_entries_get(sleep_retention_entries_t *entries) k_sem_give(&s_retention_lock); } -uint32_t IRAM_ATTR sleep_retention_get_modules(void) +uint32_t IRAM_ATTR sleep_retention_get_inited_modules(void) { - return s_retention.modules; + return s_retention.inited_modules; } -#if SOC_PM_RETENTION_HAS_CLOCK_BUG -void sleep_retention_do_extra_retention(bool backup_or_restore) +uint32_t IRAM_ATTR sleep_retention_get_created_modules(void) { + return s_retention.created_modules; +} + +esp_err_t sleep_retention_module_init(sleep_retention_module_t module, sleep_retention_module_init_param_t *param) +{ + if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { + return ESP_ERR_INVALID_ARG; + } + if (param == NULL || param->cbs.create.handle == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (s_retention.lock == NULL) { + /* Passive modules will be initialized during the system startup, with the + * operating system scheduler not yet enabled. There is no risk of contention + * for lock initialization here. */ + k_sem_take(&s_retention_lock, K_FOREVER); + if (s_retention.lock == NULL) { + ESP_LOGE(TAG, "Create sleep retention lock failed"); + return ESP_ERR_NO_MEM; + } + } + + esp_err_t err = ESP_OK; k_sem_take(&s_retention_lock, K_FOREVER); - if (s_retention.highpri < SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY || - s_retention.highpri > SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) { + if (module_is_created(module) || module_is_inited(module)) { + err = ESP_ERR_INVALID_STATE; + } else { + sleep_retention_module_object_ctor(&s_retention.instance[module], ¶m->cbs); + set_dependencies(&s_retention.instance[module], param->depends); + set_attributes(&s_retention.instance[module], param->attribute); + s_retention.inited_modules |= module_num2map(module); + } + k_sem_give(&s_retention_lock); + return err; +} + +esp_err_t sleep_retention_module_deinit(sleep_retention_module_t module) +{ + if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { + return ESP_ERR_INVALID_ARG; + } + + esp_err_t err = ESP_OK; + bool do_lock_release = false; + k_sem_take(&s_retention_lock, K_FOREVER); + if (module_is_created(module) || !module_is_inited(module)) { + err = ESP_ERR_INVALID_STATE; + } else { + clr_attributes(&s_retention.instance[module]); + clr_dependencies(&s_retention.instance[module]); + sleep_retention_module_object_dtor(&s_retention.instance[module]); + s_retention.inited_modules &= ~module_num2map(module); + do_lock_release = (sleep_retention_get_inited_modules() == 0); + } + k_sem_give(&s_retention_lock); + + if (do_lock_release) { k_sem_give(&s_retention_lock); - return; + s_retention.lock = NULL; } - const uint32_t clk_bug_modules = SLEEP_RETENTION_MODULE_BLE_MAC | SLEEP_RETENTION_MODULE_802154_MAC; - const int cnt_modules = __builtin_popcount(clk_bug_modules & s_retention.modules); - // Set extra linked list head pointer to hardware - pau_regdma_set_extra_link_addr(s_retention.lists[s_retention.highpri].entries[EXTRA_LINK_NUM]); - if (backup_or_restore) { - if (s_retention.extra_refs++ == (cnt_modules - 1)) { - pau_regdma_trigger_extra_link_backup(); + return err; +} + +static esp_err_t sleep_retention_passive_module_allocate(sleep_retention_module_t module) +{ + assert(module >= SLEEP_RETENTION_MODULE_MIN && module <= SLEEP_RETENTION_MODULE_MAX); + + esp_err_t err = ESP_OK; + k_sem_take(&s_retention_lock, K_FOREVER); + assert(module_is_passive(&s_retention.instance[module]) && "Illegal dependency"); + assert(module_is_inited(module) && "All passive module must be inited first!"); + if (!module_is_created(module)) { + sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]); + for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) { + if (depends & BIT(0)) { + set_reference(&s_retention.instance[i], module); + err = sleep_retention_passive_module_allocate(i); + } } - } else { - if (--s_retention.extra_refs == (cnt_modules - 1)) { - pau_regdma_trigger_extra_link_restore(); + if (err == ESP_OK) { + sleep_retention_callback_t fn = s_retention.instance[module].cbs.create.handle; + if (fn) { + err = (*fn)(s_retention.instance[module].cbs.create.arg); + } } } - int refs = s_retention.extra_refs; k_sem_give(&s_retention_lock); - assert(refs >= 0 && refs <= cnt_modules); + return err; (void)refs; } -void sleep_retention_module_deinit(void) +esp_err_t sleep_retention_module_allocate(sleep_retention_module_t module) { + if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { + return ESP_ERR_INVALID_ARG; + } + + esp_err_t err = ESP_OK; k_sem_take(&s_retention_lock, K_FOREVER); - if (s_retention.extra_refs) { - s_retention.extra_refs--; + if (!module_is_passive(&s_retention.instance[module])) { + if (module_is_inited(module) && !module_is_created(module)) { + sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]); + for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) { + if (depends & BIT(0)) { + set_reference(&s_retention.instance[i], module); + if (module_is_passive(&s_retention.instance[i])) { /* the callee ensures this module is inited */ + err = sleep_retention_passive_module_allocate(i); + } + } + } + if (err == ESP_OK) { + sleep_retention_callback_t fn = s_retention.instance[module].cbs.create.handle; + if (fn) { + err = (*fn)(s_retention.instance[module].cbs.create.arg); + } + } + } else { + err = ESP_ERR_INVALID_STATE; + } + } else { + err = ESP_ERR_NOT_ALLOWED; } k_sem_give(&s_retention_lock); + return err; +} + +static esp_err_t sleep_retention_passive_module_free(sleep_retention_module_t module) +{ + assert(module >= SLEEP_RETENTION_MODULE_MIN && module <= SLEEP_RETENTION_MODULE_MAX); + + esp_err_t err = ESP_OK; + k_sem_take(&s_retention_lock, K_FOREVER); + assert(module_is_passive(&s_retention.instance[module]) && "Illegal dependency"); + assert(module_is_inited(module) && "All passive module must be inited first!"); + if (module_is_created(module)) { + if (!references_exist(&s_retention.instance[module])) { + sleep_retention_entries_destroy(module); + + sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]); + for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) { + if (depends & BIT(0)) { + clr_reference(&s_retention.instance[i], module); + err = sleep_retention_passive_module_free(i); + } + } + } + } + k_sem_give(&s_retention_lock); + return err; +} + +esp_err_t sleep_retention_module_free(sleep_retention_module_t module) +{ + if (module < SLEEP_RETENTION_MODULE_MIN || module > SLEEP_RETENTION_MODULE_MAX) { + return ESP_ERR_INVALID_ARG; + } + + esp_err_t err = ESP_OK; + k_sem_take(&s_retention_lock, K_FOREVER); + if (!module_is_passive(&s_retention.instance[module])) { + if (module_is_inited(module) && module_is_created(module)) { + sleep_retention_entries_destroy(module); + + sleep_retention_module_bitmap_t depends = get_dependencies(&s_retention.instance[module]); + for (int i = 0; (err == ESP_OK) && depends; depends >>= 1, i++) { + if (depends & BIT(0)) { + clr_reference(&s_retention.instance[i], module); + if (module_is_passive(&s_retention.instance[i])) { + err = sleep_retention_passive_module_free(i); + } + } + } + } else { + err = ESP_ERR_INVALID_STATE; + } + } else { + err = ESP_ERR_NOT_ALLOWED; + } + k_sem_give(&s_retention_lock); + return err; +} + +#if SOC_PM_RETENTION_HAS_CLOCK_BUG +void IRAM_ATTR sleep_retention_do_extra_retention(bool backup_or_restore) +{ + if (s_retention.highpri < SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY || + s_retention.highpri > SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) { + return; + } + // Set extra linked list head pointer to hardware + pau_regdma_set_extra_link_addr(s_retention.lists[s_retention.highpri].entries[EXTRA_LINK_NUM]); + if (backup_or_restore) { + pau_regdma_trigger_extra_link_backup(); + } else { + pau_regdma_trigger_extra_link_restore(); + } } #endif -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA void IRAM_ATTR sleep_retention_do_system_retention(bool backup_or_restore) { #define SYSTEM_LINK_NUM (0) @@ -541,6 +802,8 @@ void IRAM_ATTR sleep_retention_do_system_retention(bool backup_or_restore) s_retention.highpri <= SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) { // Set extra linked list head pointer to hardware pau_regdma_set_system_link_addr(s_retention.lists[s_retention.highpri].entries[SYSTEM_LINK_NUM]); + // When PD TOP, we need to prevent the PMU from triggering the REGDMA backup, because REGDMA will power off + pmu_sleep_disable_regdma_backup(); if (backup_or_restore) { pau_regdma_trigger_system_link_backup(); } else { diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 8f472d84d8..202d1b535e 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,12 +28,13 @@ #include "soc/gpio_reg.h" #include "soc/io_mux_reg.h" #include "soc/interrupt_matrix_reg.h" +#include "hal/mwdt_ll.h" static __attribute__((unused)) const char *TAG = "sleep_sys_periph"; #define SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT (REGDMA_LINK_PRI_6) -esp_err_t sleep_sys_periph_intr_matrix_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_intr_matrix_retention_init(void *arg) { #define N_REGS_INTR_MATRIX() (((INTMTX_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_MATRIX_BASE) / 4) + 1) @@ -41,13 +42,13 @@ esp_err_t sleep_sys_periph_intr_matrix_retention_init(void) [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_MATRIX_BASE, DR_REG_INTERRUPT_MATRIX_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */ }; - esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_INTR_MATRIX); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Interrupt matrix) retention"); - ESP_LOGI(TAG, "Interrupt Matrix sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Interrupt matrix"); + ESP_LOGD(TAG, "Interrupt Matrix sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_hp_system_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_hp_system_retention_init(void *arg) { #define N_REGS_HP_SYSTEM() (((HP_SYSTEM_MEM_TEST_CONF_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1) @@ -55,46 +56,52 @@ esp_err_t sleep_sys_periph_hp_system_retention_init(void) [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* hp system */ }; - esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_HP_SYSTEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (HP system) retention"); - ESP_LOGI(TAG, "HP System sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "HP system"); + ESP_LOGD(TAG, "HP System sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_tee_apm_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init(void *arg) { #define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1) #define N_REGS_APM() (((HP_APM_CLOCK_GATE_REG - DR_REG_HP_APM_BASE) / 4) + 1) const static sleep_retention_entries_config_t tee_apm_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(0), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* tee */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_HP_APM_BASE, DR_REG_HP_APM_BASE, N_REGS_APM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* apm */ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(0), DR_REG_HP_APM_BASE, DR_REG_HP_APM_BASE, N_REGS_APM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* apm */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */ }; - esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_TEE_APM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (TEE/APM) retention"); - ESP_LOGI(TAG, "TEE/APM sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_SYS_PERIPH); + if (err == ESP_OK) { + const static sleep_retention_entries_config_t regs_highpri_retention[] = { + [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) } + }; + err = sleep_retention_entries_create(regs_highpri_retention, ARRAY_SIZE(regs_highpri_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_SYS_PERIPH); + } + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "TEE/APM"); + ESP_LOGD(TAG, "TEE/APM sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_uart0_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_uart0_retention_init(void *arg) { - #define N_REGS_UART() (((UART_ID_REG(0) - REG_UART_BASE(0)) / 4) + 1) + #define N_REGS_UART() (((UART_ID_REG(0) - UART_INT_RAW_REG(0)) / 4) + 1) const static sleep_retention_entries_config_t uart_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), REG_UART_BASE(0), REG_UART_BASE(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ /* Note: uart register should set update reg to make the configuration take effect */ [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_UART0); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (UART) retention"); - ESP_LOGI(TAG, "UART sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "UART"); + ESP_LOGD(TAG, "UART sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_tg0_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_tg0_retention_init(void *arg) { #define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) @@ -110,21 +117,21 @@ esp_err_t sleep_sys_periph_tg0_retention_init(void) [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_TG0); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Timer Group) retention"); - ESP_LOGI(TAG, "Timer Group sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Timer Group"); + ESP_LOGD(TAG, "Timer Group sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_iomux_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_iomux_retention_init(void *arg) { #if CONFIG_IDF_TARGET_ESP32C6 - #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) + #define N_REGS_IOMUX_0() (((IO_MUX_GPIO30_REG - REG_IO_MUX_BASE) / 4) + 1) #define N_REGS_IOMUX_1() (((GPIO_FUNC34_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) #define N_REGS_IOMUX_2() (((GPIO_FUNC124_IN_SEL_CFG_REG - GPIO_STATUS_NEXT_REG) / 4) + 1) #define N_REGS_IOMUX_3() (((GPIO_PIN34_REG - DR_REG_GPIO_BASE) / 4) + 1) #elif CONFIG_IDF_TARGET_ESP32H2 - #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) + #define N_REGS_IOMUX_0() (((IO_MUX_GPIO27_REG - REG_IO_MUX_BASE) / 4) + 1) #define N_REGS_IOMUX_1() (((GPIO_FUNC31_OUT_SEL_CFG_REG - GPIO_FUNC0_OUT_SEL_CFG_REG) / 4) + 1) #define N_REGS_IOMUX_2() (((GPIO_FUNC124_IN_SEL_CFG_REG - GPIO_STATUS_NEXT_REG) / 4) + 1) #define N_REGS_IOMUX_3() (((GPIO_PIN31_REG - DR_REG_GPIO_BASE) / 4) + 1) @@ -136,13 +143,13 @@ esp_err_t sleep_sys_periph_iomux_retention_init(void) [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_IOMUX); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (IO Matrix) retention"); - ESP_LOGI(TAG, "IO Matrix sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "IO Matrix"); + ESP_LOGD(TAG, "IO Matrix sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_spimem_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_spimem_retention_init(void *arg) { #define N_REGS_SPI1_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1) #define N_REGS_SPI1_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(1) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1)) / 4) + 1) @@ -168,13 +175,13 @@ esp_err_t sleep_sys_periph_spimem_retention_init(void) [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SPIMEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SPI mem) retention"); - ESP_LOGI(TAG, "SPI Mem sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "SPI mem"); + ESP_LOGD(TAG, "SPI Mem sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_systimer_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_systimer_retention_init(void *arg) { #define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) @@ -207,30 +214,30 @@ esp_err_t sleep_sys_periph_systimer_retention_init(void) [18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */ }; - esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYSTIMER); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SysTimer) retention"); - ESP_LOGI(TAG, "SysTimer sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "SysTimer"); + ESP_LOGD(TAG, "SysTimer sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *arg) { esp_err_t err; - err = sleep_sys_periph_intr_matrix_retention_init(); + err = sleep_sys_periph_intr_matrix_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_hp_system_retention_init(); + err = sleep_sys_periph_hp_system_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_tee_apm_retention_init(); + err = sleep_sys_periph_tee_apm_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_uart0_retention_init(); + err = sleep_sys_periph_uart0_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_tg0_retention_init(); + err = sleep_sys_periph_tg0_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_iomux_retention_init(); + err = sleep_sys_periph_iomux_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_spimem_retention_init(); + err = sleep_sys_periph_spimem_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_systimer_retention_init(); + err = sleep_sys_periph_systimer_retention_init(arg); error: return err; @@ -238,23 +245,31 @@ esp_err_t sleep_sys_periph_retention_init(void) bool IRAM_ATTR peripheral_domain_pd_allowed(void) { - const uint32_t modules = sleep_retention_get_modules(); - const uint32_t mask = (const uint32_t) ( - SLEEP_RETENTION_MODULE_INTR_MATRIX | \ - SLEEP_RETENTION_MODULE_HP_SYSTEM | \ - SLEEP_RETENTION_MODULE_TEE_APM | \ - SLEEP_RETENTION_MODULE_UART0 | \ - SLEEP_RETENTION_MODULE_TG0 | \ - SLEEP_RETENTION_MODULE_IOMUX | \ - SLEEP_RETENTION_MODULE_SPIMEM | \ - SLEEP_RETENTION_MODULE_SYSTIMER); - return ((modules & mask) == mask); +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP + const uint32_t inited_modules = sleep_retention_get_inited_modules(); + const uint32_t created_modules = sleep_retention_get_created_modules(); + const uint32_t mask = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); + + return ((inited_modules & mask) == (created_modules & mask)); +#else + return false; +#endif } #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP ESP_SYSTEM_INIT_FN(sleep_sys_periph_startup_init, BIT(0), 107) { - sleep_sys_periph_retention_init(); + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_sys_periph_retention_init, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_SYS_PERIPH, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_SYS_PERIPH); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for system peripherals retention"); + } + } return ESP_OK; } #endif diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_intr_alloc.c b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_intr_alloc.c index daf1cd36b5..1a1ac88334 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_intr_alloc.c +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_intr_alloc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -275,7 +275,7 @@ void isr_free_task(void *param) vTaskDelete(NULL); } -void isr_alloc_free_test(void) +void isr_alloc_free_test(bool isr_free_task_no_affinity) { intr_handle_t test_handle = NULL; esp_err_t ret = esp_intr_alloc(spi_periph_signal[1].irq, 0, int_handler1, NULL, &test_handle); @@ -284,16 +284,27 @@ void isr_alloc_free_test(void) } else { printf("alloc isr handle on core %d\n", esp_intr_get_cpu(test_handle)); } - TEST_ASSERT(ret == ESP_OK); - xTaskCreatePinnedToCore(isr_free_task, "isr_free_task", 1024 * 2, (void *)&test_handle, 10, NULL, !xPortGetCoreID()); - vTaskDelay(1000 / portTICK_PERIOD_MS); - TEST_ASSERT(test_handle == NULL); + TEST_ESP_OK(ret); + if (isr_free_task_no_affinity) { + xTaskCreate(isr_free_task, "isr_free_task", 1024 * 2, (void *)&test_handle, 3, NULL); + esp_rom_delay_us(500); + vTaskDelay(500 / portTICK_PERIOD_MS); + } else { + xTaskCreatePinnedToCore(isr_free_task, "isr_free_task", 1024 * 2, (void *)&test_handle, 10, NULL, !xPortGetCoreID()); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + TEST_ASSERT_NULL(test_handle); printf("test passed\n"); } TEST_CASE("alloc and free isr handle on different core", "[intr_alloc]") { - isr_alloc_free_test(); + isr_alloc_free_test(false); +} + +TEST_CASE("alloc and free isr handle on different core when isr_free_task is NO_AFFINITY", "[intr_alloc]") +{ + isr_alloc_free_test(true); } #endif diff --git a/components/esp_hw_support/test_apps/etm/main/test_gpio_etm.c b/components/esp_hw_support/test_apps/etm/main/test_gpio_etm.c index ee80ca8a4d..cd2c0d1bcb 100644 --- a/components/esp_hw_support/test_apps/etm/main/test_gpio_etm.c +++ b/components/esp_hw_support/test_apps/etm/main/test_gpio_etm.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -81,7 +81,7 @@ TEST_CASE("gpio_etm_self_trigger", "[etm]") // delete gpio etm task without remove all bounded GPIOs should fail TEST_ESP_ERR(ESP_ERR_INVALID_STATE, esp_etm_del_task(gpio_task)); // remove unrelated GPIO from the task should fail - TEST_ESP_ERR(ESP_ERR_INVALID_STATE, gpio_etm_task_rm_gpio(gpio_task, 10)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_etm_task_rm_gpio(gpio_task, 10)); // delete etm primitives TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task, output_gpio)); @@ -90,3 +90,118 @@ TEST_CASE("gpio_etm_self_trigger", "[etm]") TEST_ESP_OK(esp_etm_del_event(gpio_event)); TEST_ESP_OK(esp_etm_del_channel(etm_channel_a)); } + +TEST_CASE("gpio_etm_self_trigger_multi_action", "[etm]") +{ + // GPIO 0 pos edge event ---> GPIO 1 set level task + // GPIO 22 pos edge event ---> GPIO 1 clear level task + + const uint32_t input_gpio1 = 0; + const uint32_t input_gpio2 = 22; + const uint32_t output_gpio = 1; + printf("allocate etm channels\r\n"); + esp_etm_channel_config_t etm_config = {}; + esp_etm_channel_handle_t etm_channel_a = NULL; + esp_etm_channel_handle_t etm_channel_b = NULL; + TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel_a)); + TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel_b)); + + printf("allocate GPIO etm event and task\r\n"); + esp_etm_task_handle_t gpio_task_a = NULL; + esp_etm_event_handle_t gpio_event_a = NULL; + esp_etm_task_handle_t gpio_task_b = NULL; + esp_etm_event_handle_t gpio_event_b = NULL; + gpio_etm_event_config_t gpio_event_config = {}; + gpio_event_config.edges[0] = GPIO_ETM_EVENT_EDGE_POS; + TEST_ESP_OK(gpio_new_etm_event(&gpio_event_config, &gpio_event_a)); + esp_etm_event_handle_t gpio_event_c = NULL; // an extra event only used for testing binding + gpio_event_config.edges[1] = GPIO_ETM_EVENT_EDGE_ANY; + TEST_ESP_OK(gpio_new_etm_event(&gpio_event_config, &gpio_event_b, &gpio_event_c)); + gpio_etm_task_config_t gpio_task_config = {}; + gpio_task_config.actions[0] = GPIO_ETM_TASK_ACTION_CLR; + gpio_task_config.actions[1] = GPIO_ETM_TASK_ACTION_SET; + TEST_ESP_OK(gpio_new_etm_task(&gpio_task_config, &gpio_task_b, &gpio_task_a)); + + // bind GPIO to the event and task + TEST_ESP_OK(gpio_etm_event_bind_gpio(gpio_event_a, input_gpio1)); + TEST_ESP_OK(gpio_etm_event_bind_gpio(gpio_event_b, input_gpio2)); + TEST_ESP_OK(gpio_etm_task_add_gpio(gpio_task_a, output_gpio)); + TEST_ESP_OK(gpio_etm_task_add_gpio(gpio_task_b, output_gpio)); + + // try an infeasible bind of second event to a GPIO + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_etm_event_bind_gpio(gpio_event_c, input_gpio1)); + // try a feasible bind of second event to a GPIO + TEST_ESP_OK(gpio_etm_event_bind_gpio(gpio_event_c, input_gpio2)); + // delete the event to unbind it from the GPIO + TEST_ESP_OK(esp_etm_del_event(gpio_event_c)); + + printf("initialize gpio\r\n"); + gpio_config_t task_gpio_config = { + .intr_type = GPIO_INTR_DISABLE, + .mode = GPIO_MODE_INPUT_OUTPUT, // we want to read the GPIO value, so it should be input and output + .pin_bit_mask = 1ULL << output_gpio, + }; + TEST_ESP_OK(gpio_config(&task_gpio_config)); + // set the initial level + TEST_ESP_OK(gpio_set_level(output_gpio, 0)); + + gpio_config_t event_gpio_config = { + .intr_type = GPIO_INTR_DISABLE, + .mode = GPIO_MODE_INPUT_OUTPUT, // we want to simulate the edge signal by software, so it should be input and output + .pull_up_en = GPIO_PULLUP_ENABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .pin_bit_mask = (1ULL << input_gpio1) | (1ULL << input_gpio2), + }; + TEST_ESP_OK(gpio_config(&event_gpio_config)); + // set the initial level + TEST_ESP_OK(gpio_set_level(input_gpio1, 0)); + TEST_ESP_OK(gpio_set_level(input_gpio2, 0)); + + printf("connect event and task to the channel\r\n"); + TEST_ESP_OK(esp_etm_channel_connect(etm_channel_a, gpio_event_a, gpio_task_a)); + TEST_ESP_OK(esp_etm_channel_connect(etm_channel_b, gpio_event_b, gpio_task_b)); + + TEST_ESP_OK(esp_etm_channel_enable(etm_channel_a)); + TEST_ESP_OK(esp_etm_channel_enable(etm_channel_b)); + + // input_gpio1 pos edge ---> output_gpio level being set + TEST_ESP_OK(gpio_set_level(input_gpio1, 1)); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ASSERT_EQUAL(1, gpio_get_level(output_gpio)); + + // input_gpio1 neg edge does not affect output_gpio level + TEST_ESP_OK(gpio_set_level(input_gpio1, 0)); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ASSERT_EQUAL(1, gpio_get_level(output_gpio)); + + // input_gpio2 pos edge ---> output_gpio level being cleared + TEST_ESP_OK(gpio_set_level(input_gpio2, 1)); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ASSERT_EQUAL(0, gpio_get_level(output_gpio)); + + // input_gpio2 neg edge does not affect output_gpio level + TEST_ESP_OK(gpio_set_level(input_gpio2, 0)); + vTaskDelay(pdMS_TO_TICKS(100)); + TEST_ASSERT_EQUAL(0, gpio_get_level(output_gpio)); + + // Create a new gpio etm task separately, and add it to the output_gpio should fail (the task does not belong to the same GPIO ETM task channel as gpio_task_a and gpio_task_b) + esp_etm_task_handle_t gpio_task_c = NULL; + gpio_etm_task_config_t gpio_task_config_2 = { + .action = GPIO_ETM_TASK_ACTION_TOG, + }; + TEST_ESP_OK(gpio_new_etm_task(&gpio_task_config_2, &gpio_task_c)); + TEST_ESP_ERR(ESP_ERR_INVALID_ARG, gpio_etm_task_add_gpio(gpio_task_c, output_gpio)); + + // delete etm primitives + TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task_a, output_gpio)); + TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task_b, output_gpio)); + TEST_ESP_OK(esp_etm_channel_disable(etm_channel_a)); + TEST_ESP_OK(esp_etm_channel_disable(etm_channel_b)); + TEST_ESP_OK(esp_etm_del_task(gpio_task_a)); + TEST_ESP_OK(esp_etm_del_task(gpio_task_b)); + TEST_ESP_OK(esp_etm_del_task(gpio_task_c)); + TEST_ESP_OK(esp_etm_del_event(gpio_event_a)); + TEST_ESP_OK(esp_etm_del_event(gpio_event_b)); + TEST_ESP_OK(esp_etm_del_channel(etm_channel_a)); + TEST_ESP_OK(esp_etm_del_channel(etm_channel_b)); +} diff --git a/components/esp_hw_support/test_apps/etm/main/test_systimer_etm.c b/components/esp_hw_support/test_apps/etm/main/test_systimer_etm.c index 81b6e48f2c..23b0cba960 100644 --- a/components/esp_hw_support/test_apps/etm/main/test_systimer_etm.c +++ b/components/esp_hw_support/test_apps/etm/main/test_systimer_etm.c @@ -79,7 +79,7 @@ TEST_CASE("esp_timer_etm_event", "[etm]") printf("allocate GPIO etm task\r\n"); esp_etm_task_handle_t gpio_task = NULL; gpio_etm_task_config_t gpio_task_config = { - .action = GPIO_ETM_TASK_ACTION_TOG, + .action = GPIO_ETM_TASK_ACTION_CLR, }; TEST_ESP_OK(gpio_new_etm_task(&gpio_task_config, &gpio_task)); @@ -114,12 +114,14 @@ TEST_CASE("esp_timer_etm_event", "[etm]") TEST_ESP_OK(esp_timer_create(&periodic_timer_args, &periodic_timer)); TEST_ESP_OK(esp_timer_start_periodic(periodic_timer, 500000)); - // should see a 1Hz square wave on the GPIO - vTaskDelay(pdMS_TO_TICKS(1200)); - - // check the final GPIO level + vTaskDelay(pdMS_TO_TICKS(100)); + // etm event not active yet, so the GPIO level should still be the initial state TEST_ASSERT_EQUAL(1, gpio_get_level(output_gpio)); + vTaskDelay(pdMS_TO_TICKS(1000)); + // etm event should have cleared the GPIO level + TEST_ASSERT_EQUAL(0, gpio_get_level(output_gpio)); + TEST_ESP_OK(esp_timer_stop(periodic_timer)); TEST_ESP_OK(esp_timer_delete(periodic_timer)); diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr index 85f4adc6e7..3ce4e3c454 100644 --- a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr @@ -3,5 +3,7 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_SPI_FLASH_HPM_ENA=y CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_BOOTLOADER_FLASH_DC_AWARE=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_120sdr b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_120sdr index 8a9f5d4520..c05d0bbab3 100644 --- a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_120sdr +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_120sdr @@ -3,7 +3,9 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_SPI_FLASH_HPM_ENA=y CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_BOOTLOADER_FLASH_DC_AWARE=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_SPIRAM=y CONFIG_SPIRAM_SPEED_120M=y diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_40sdr b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_40sdr index 6af77f08da..60dacd89a4 100644 --- a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_40sdr +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_40sdr @@ -3,7 +3,9 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_SPI_FLASH_HPM_ENA=y CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_BOOTLOADER_FLASH_DC_AWARE=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_SPIRAM=y CONFIG_SPIRAM_SPEED_40M=y diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_os_silent b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_os_silent index 0a5cdf1d50..da05ca4710 100644 --- a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_os_silent +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r4_120sdr_os_silent @@ -7,5 +7,7 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_SPI_FLASH_HPM_ENA=y CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_BOOTLOADER_FLASH_DC_AWARE=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r8_120sdr b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r8_120sdr index 27b14db382..03b2c9106c 100644 --- a/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r8_120sdr +++ b/components/esp_hw_support/test_apps/mspi/sdkconfig.ci.f4r8_120sdr @@ -3,5 +3,7 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_SPI_FLASH_HPM_ENA=y CONFIG_ESPTOOLPY_FLASHFREQ_120M=y +CONFIG_BOOTLOADER_FLASH_DC_AWARE=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/components/esp_phy/Kconfig b/components/esp_phy/Kconfig index b94aca1cbe..b6b4e4923e 100644 --- a/components/esp_phy/Kconfig +++ b/components/esp_phy/Kconfig @@ -106,13 +106,20 @@ menu "PHY" When brownout reset occurs, reduce PHY TX power to keep the code running. config ESP_PHY_ENABLE_USB - bool "Enable USB when phy init" - depends on USB_OTG_SUPPORTED || ESP_CONSOLE_USB_SERIAL_JTAG || ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG - default y if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 + bool "Keep the USB PHY enabled when initializing WiFi" + depends on SOC_WIFI_PHY_NEEDS_USB_WORKAROUND + default y if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 \ + || ESP_CONSOLE_USB_SERIAL_JTAG || ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG default n help - When using USB Serial/JTAG/OTG/CDC, PHY should enable USB, otherwise USB module - can not work properly. Notice: Enabling this configuration option will slightly impact wifi performance. + On some ESP targets, the USB PHY can interfere with WiFi thus lowering WiFi performance. As a result, on + those affected ESP targets, the ESP PHY library's initialization will automatically disable the USB PHY to + get best WiFi performance. This option controls whether or not the ESP PHY library will keep the USB PHY + enabled on initialization. + + Note: This option can be disabled to increase WiFi performance. However, disabling this option will also + mean that the USB PHY cannot be used while WiFi is enabled. + config ESP_PHY_ENABLE_CERT_TEST bool "Enable RF certification test functions" @@ -154,4 +161,10 @@ menu "PHY" high interference, enable this option will sacrifice Wi-Fi OFDM receive performance. But to guarantee 11b receive performance serves as a bottom line in this case. + config ESP_PHY_PLL_TRACK_DEBUG + bool "Enable pll track logging" + default n + help + If enabled, there will be some logs while pll tracking + endmenu # PHY diff --git a/components/esp_phy/include/esp_phy_init.h b/components/esp_phy/include/esp_phy_init.h index fb0ab1b235..50b9ceb765 100644 --- a/components/esp_phy/include/esp_phy_init.h +++ b/components/esp_phy/include/esp_phy_init.h @@ -27,6 +27,15 @@ typedef struct { uint8_t params[128]; /*!< opaque PHY initialization parameters */ } esp_phy_init_data_t; +/** + * @brief PHY enable or disable modem + */ +typedef enum { + PHY_MODEM_WIFI = 1, /*!< PHY modem WIFI */ + PHY_MODEM_BT = 2, /*!< PHY modem BT */ + PHY_MODEM_IEEE802154 = 4, /*!< PHY modem IEEE802154 */ +} esp_phy_modem_t; + /** * @brief Opaque PHY calibration data */ @@ -145,8 +154,9 @@ esp_err_t esp_phy_erase_cal_data_in_nvs(void); * Now PHY and RF enabling job is done automatically when start WiFi or BT. Users should not * call this API in their application. * + * @param modem the modem to call the phy enable. */ -void esp_phy_enable(void); +void esp_phy_enable(esp_phy_modem_t modem); /** * @brief Disable PHY and RF module @@ -155,8 +165,9 @@ void esp_phy_enable(void); * Now PHY and RF disabling job is done automatically when stop WiFi or BT. Users should not * call this API in their application. * + * @param modem the modem to call the phy disable. */ -void esp_phy_disable(void); +void esp_phy_disable(esp_phy_modem_t modem); /** * @brief Enable BTBB module @@ -260,16 +271,17 @@ esp_err_t esp_phy_apply_phy_init_data(uint8_t *init_data); char * get_phy_version_str(void); /** - * @brief Enable phy track pll - * + * @brief Set PHY init parameters + * @param param is 1 means combo module */ -void phy_track_pll_init(void); +void phy_init_param_set(uint8_t param); /** - * @brief Disable phy track pll - * + * @brief Wi-Fi RX enable + * @param enable True for enable wifi receiving mode as default, false for closing wifi receiving mode as default. */ -void phy_track_pll_deinit(void); +void phy_wifi_enable_set(uint8_t enable); + #ifdef __cplusplus } #endif diff --git a/components/esp_phy/include/esp_private/phy.h b/components/esp_phy/include/esp_private/phy.h index 858847d129..5a223c80b3 100644 --- a/components/esp_phy/include/esp_private/phy.h +++ b/components/esp_phy/include/esp_private/phy.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -140,6 +140,46 @@ void phy_eco_version_sel(uint8_t chip_ver); void phy_improve_rx_special(bool enable); #endif +/** + * @brief Enable phy track pll + * + */ +void phy_track_pll_init(void); + +/** + * @brief Disable phy track pll + * + */ +void phy_track_pll_deinit(void); + +/** + * @brief Set the flag recorded which modem has already enabled phy + * + */ +void phy_set_modem_flag(esp_phy_modem_t modem); + +/** + * @brief Clear the flag to record which modem calls phy disenable + */ +void phy_clr_modem_flag(esp_phy_modem_t modem); + +/** + * @brief Get the flag recorded which modem has already enabled phy + * + */ +esp_phy_modem_t phy_get_modem_flag(void); + +/** + * @brief Get the PHY lock, only used in esp_phy, the user should not use this function. + * + */ +_lock_t phy_get_lock(void); + +/** + * @brief Call this funnction to track pll immediately. + * + */ +void phy_track_pll(void); #ifdef __cplusplus } #endif diff --git a/components/esp_phy/lib b/components/esp_phy/lib index 998e056363..06e7625de1 160000 --- a/components/esp_phy/lib +++ b/components/esp_phy/lib @@ -1 +1 @@ -Subproject commit 998e05636344949ba219e8ac56feb733e27bf5d2 +Subproject commit 06e7625de197bc12797dd701d6762229bca01826 diff --git a/components/esp_phy/src/btbb_init.c b/components/esp_phy/src/btbb_init.c index 6c8c9f6ab4..41d78dd83a 100644 --- a/components/esp_phy/src/btbb_init.c +++ b/components/esp_phy/src/btbb_init.c @@ -28,7 +28,7 @@ static const char* TAG = "btbb_init"; #define BTBB_LINK_OWNER ENTRY(0) | ENTRY(2) #endif // SOC_PM_RETENTION_HAS_CLOCK_BUG -static esp_err_t btbb_sleep_retention_init(void) +static esp_err_t btbb_sleep_retention_init(void *arg) { const static sleep_retention_entries_config_t btbb_regs_retention[] = { [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x00), BB_PART_0_ADDR, BB_PART_0_ADDR, BB_PART_0_SIZE, 0, 0), .owner = BTBB_LINK_OWNER }, @@ -37,13 +37,20 @@ static esp_err_t btbb_sleep_retention_init(void) }; esp_err_t err = sleep_retention_entries_create(btbb_regs_retention, ARRAY_SIZE(btbb_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BT_BB); ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for btbb retention"); - ESP_LOGI(TAG, "btbb sleep retention initialization"); + ESP_LOGD(TAG, "btbb sleep retention initialization"); return ESP_OK; } static void btbb_sleep_retention_deinit(void) { - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BT_BB); + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BT_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to destroy sleep retention linked list for btbb retention"); + } + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BT_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "Modem BT BB retention callback unregister failed"); + } } #endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE @@ -54,7 +61,19 @@ void esp_btbb_enable(void) if (s_btbb_access_ref == 0) { bt_bb_v2_init_cmplx(BTBB_ENABLE_VERSION_PRINT); #if SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE - btbb_sleep_retention_init(); + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = btbb_sleep_retention_init, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BT_BB, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BT_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for btbb retention"); + } + } else { + ESP_LOGW(TAG, "Modem BT BB retention callback register failed"); + } #endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE } s_btbb_access_ref++; diff --git a/components/esp_phy/src/phy_common.c b/components/esp_phy/src/phy_common.c index b71b3aa0e8..759f3b5de8 100644 --- a/components/esp_phy/src/phy_common.c +++ b/components/esp_phy/src/phy_common.c @@ -1,36 +1,96 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include "esp_log.h" #include "esp_timer.h" +#include "esp_phy_init.h" +#include "esp_private/phy.h" #include +static volatile uint16_t s_phy_modem_flag = 0; -extern void bt_track_pll_cap(void); +extern void phy_param_track_tot(bool en_wifi, bool en_ble_154); static esp_timer_handle_t phy_track_pll_timer; -static volatile int64_t s_previous_timestamp; +#if CONFIG_ESP_WIFI_ENABLED +static volatile int64_t s_wifi_prev_timestamp; +#endif +#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED +static volatile int64_t s_bt_154_prev_timestamp; +#endif #define PHY_TRACK_PLL_PERIOD_IN_US 1000000 +static void phy_track_pll_internal(void); -static void phy_track_pll_timer_callback(void* arg) +#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED || CONFIG_ESP_WIFI_ENABLED +bool phy_enabled_modem_contains(esp_phy_modem_t modem) { -#if IEEE802154_ENABLED || BT_ENABLED - bt_track_pll_cap(); -#endif - s_previous_timestamp = esp_timer_get_time(); + return (s_phy_modem_flag & modem) != 0; } +#endif -void phy_track_pll_init(void) +void phy_track_pll(void) { // Light sleep scenario: enabling and disabling PHY frequently, the timer will not get triggered. // 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. - int64_t now = esp_timer_get_time(); - if (now - s_previous_timestamp > PHY_TRACK_PLL_PERIOD_IN_US) { - phy_track_pll_timer_callback((void* )0); + bool need_track_pll = false; +#if CONFIG_ESP_WIFI_ENABLED + if (phy_enabled_modem_contains(PHY_MODEM_WIFI)) { + 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 + if (phy_enabled_modem_contains(PHY_MODEM_BT | PHY_MODEM_IEEE802154)) { + need_track_pll = need_track_pll || ((esp_timer_get_time() - s_bt_154_prev_timestamp) > PHY_TRACK_PLL_PERIOD_IN_US); + } +#endif + if (need_track_pll) { + phy_track_pll_internal(); + } +} + +static void phy_track_pll_internal(void) +{ + bool wifi_track_pll = false; + bool ble_154_track_pll = false; +#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(); + } +#endif + +#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED + if (phy_enabled_modem_contains(PHY_MODEM_BT | PHY_MODEM_IEEE802154)) { + ble_154_track_pll = true; + s_bt_154_prev_timestamp = esp_timer_get_time(); + } +#endif + if (wifi_track_pll || ble_154_track_pll) { +#if CONFIG_ESP_PHY_PLL_TRACK_DEBUG +#if CONFIG_IEEE802154_ENABLED || CONFIG_BT_ENABLED + ESP_LOGI("PLL_TRACK", "BT or IEEE802154 tracks PLL: %s", ble_154_track_pll ? "True" : "False"); +#endif +#if CONFIG_ESP_WIFI_ENABLED + ESP_LOGI("PLL_TRACK", "Wi-Fi tracks PLL: %s", wifi_track_pll ? "True" : "False"); +#endif +#endif + phy_param_track_tot(wifi_track_pll, ble_154_track_pll); } +} + +static void phy_track_pll_timer_callback(void* arg) +{ + _lock_t phy_lock = phy_get_lock(); + _lock_acquire(&phy_lock); + phy_track_pll_internal(); + _lock_release(&phy_lock); +} +void phy_track_pll_init(void) +{ const esp_timer_create_args_t phy_track_pll_timer_args = { .callback = &phy_track_pll_timer_callback, .name = "phy-track-pll-timer" @@ -44,3 +104,18 @@ void phy_track_pll_deinit(void) ESP_ERROR_CHECK(esp_timer_stop(phy_track_pll_timer)); ESP_ERROR_CHECK(esp_timer_delete(phy_track_pll_timer)); } + +void phy_set_modem_flag(esp_phy_modem_t modem) +{ + s_phy_modem_flag |= modem; +} + +void phy_clr_modem_flag(esp_phy_modem_t modem) +{ + s_phy_modem_flag &= ~modem; +} + +esp_phy_modem_t phy_get_modem_flag(void) +{ + return s_phy_modem_flag; +} diff --git a/components/esp_phy/src/phy_init.c b/components/esp_phy/src/phy_init.c index 545c4a664a..2b4b47c30e 100644 --- a/components/esp_phy/src/phy_init.c +++ b/components/esp_phy/src/phy_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,8 @@ #include "esp_log.h" #include "esp_efuse.h" #include "esp_timer.h" -#include "esp_sleep.h" +#include "esp_private/esp_sleep_internal.h" +#include "esp_check.h" #include "sdkconfig.h" #include #include @@ -63,9 +64,6 @@ static DRAM_ATTR struct { #endif // !SOC_PMU_SUPPORTED #endif // SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD -/* Reference count of enabling PHY */ -static uint8_t s_phy_access_ref = 0; - #if CONFIG_IDF_TARGET_ESP32 /* time stamp updated when the PHY/RF is turned on */ static int64_t s_phy_rf_en_ts = 0; @@ -83,8 +81,10 @@ static bool s_is_phy_calibrated = false; static bool s_is_phy_reg_stored = false; /* Memory to store PHY digital registers */ static uint32_t* s_phy_digital_regs_mem = NULL; -static uint8_t s_phy_modem_init_ref = 0; #endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA +#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP +static uint8_t s_phy_modem_init_ref = 0; +#endif #if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN @@ -234,11 +234,10 @@ static inline void phy_digital_regs_load(void) } #endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA -void esp_phy_enable(void) +void esp_phy_enable(esp_phy_modem_t modem) { k_mutex_lock(&s_phy_access_lock, K_FOREVER); - - if (s_phy_access_ref == 0) { + if (phy_get_modem_flag() == 0) { #if CONFIG_IDF_TARGET_ESP32 // Update time stamp s_phy_rf_en_ts = esp_timer_get_time(); @@ -276,18 +275,31 @@ void esp_phy_enable(void) #if CONFIG_IDF_TARGET_ESP32 coex_bt_high_prio(); #endif + +// ESP32 will track pll in the wifi/BT modem interrupt handler. +#if !CONFIG_IDF_TARGET_ESP32 + phy_track_pll_init(); +#endif } - s_phy_access_ref++; + phy_set_modem_flag(modem); +#if !CONFIG_IDF_TARGET_ESP32 + // Immediately track pll when phy enabled. + phy_track_pll(); +#endif k_mutex_unlock(&s_phy_access_lock); } -void esp_phy_disable(void) +void esp_phy_disable(esp_phy_modem_t modem) { k_mutex_lock(&s_phy_access_lock, K_FOREVER); - s_phy_access_ref--; - if (s_phy_access_ref == 0) { + phy_clr_modem_flag(modem); + if (phy_get_modem_flag() == 0) { +// ESP32 will track pll in the wifi/BT modem interrupt handler. +#if !CONFIG_IDF_TARGET_ESP32 + phy_track_pll_deinit(); +#endif #if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA phy_digital_regs_store(); #endif @@ -305,13 +317,12 @@ void esp_phy_disable(void) #endif } #if CONFIG_IDF_TARGET_ESP32 - // Update WiFi MAC time before disalbe WiFi/BT common peripheral clock + // Update WiFi MAC time before disable WiFi/BT common peripheral clock phy_update_wifi_mac_time(true, esp_timer_get_time()); #endif // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG esp_phy_common_clock_disable(); } - k_mutex_unlock(&s_phy_access_lock); } @@ -322,14 +333,18 @@ void IRAM_ATTR esp_wifi_bt_power_domain_on(void) k_mutex_lock(&s_wifi_bt_pd_controller.lock, K_FOREVER); if (s_wifi_bt_pd_controller.count++ == 0) { CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); - -#if !CONFIG_IDF_TARGET_ESP32 + esp_rom_delay_us(10); + wifi_bt_common_module_enable(); +#if CONFIG_IDF_TARGET_ESP32 + DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, MODEM_RESET_FIELD_WHEN_PU); + DPORT_CLEAR_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, MODEM_RESET_FIELD_WHEN_PU); +#else // modem reset when power on SET_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, MODEM_RESET_FIELD_WHEN_PU); CLEAR_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, MODEM_RESET_FIELD_WHEN_PU); #endif - CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); + wifi_bt_common_module_disable(); } k_mutex_unlock(&s_wifi_bt_pd_controller.lock); #endif // !SOC_PMU_SUPPORTED @@ -352,23 +367,29 @@ void esp_wifi_bt_power_domain_off(void) void esp_phy_modem_init(void) { -#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA +#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP k_mutex_lock(&s_phy_access_lock, K_FOREVER); s_phy_modem_init_ref++; +#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA if (s_phy_digital_regs_mem == NULL) { s_phy_digital_regs_mem = (uint32_t *)heap_caps_malloc(SOC_PHY_DIG_REGS_MEM_SIZE, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); } - k_mutex_unlock(&s_phy_access_lock); #endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA +#if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP + sleep_modem_wifi_modem_state_init(); +#endif // CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP + k_mutex_unlock(&s_phy_access_lock); +#endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP } void esp_phy_modem_deinit(void) { -#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA +#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP k_mutex_lock(&s_phy_access_lock, K_FOREVER); s_phy_modem_init_ref--; if (s_phy_modem_init_ref == 0) { +#if SOC_PM_MODEM_RETENTION_BY_BACKUPDMA s_is_phy_reg_stored = false; free(s_phy_digital_regs_mem); s_phy_digital_regs_mem = NULL; @@ -377,11 +398,14 @@ void esp_phy_modem_deinit(void) */ #if CONFIG_IDF_TARGET_ESP32C3 phy_init_flag(); -#endif +#endif // CONFIG_IDF_TARGET_ESP32C3 +#endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA +#if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP + sleep_modem_wifi_modem_state_deinit(); +#endif // CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP } - k_mutex_unlock(&s_phy_access_lock); -#endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA +#endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA || CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP } #if CONFIG_MAC_BB_PD @@ -391,6 +415,21 @@ static uint32_t* s_mac_bb_pd_mem = NULL; static uint8_t s_macbb_backup_mem_ref = 0; /* Reference of powering down MAC and BB */ static bool s_mac_bb_pu = true; +#elif SOC_PM_MODEM_RETENTION_BY_REGDMA +static esp_err_t sleep_retention_wifi_bb_init(void *arg) +{ + const static sleep_retention_entries_config_t bb_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b00, 0x600a7000, 0x600a7000, 121, 0, 0), .owner = BIT(0) | BIT(1) }, /* AGC */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b01, 0x600a7400, 0x600a7400, 14, 0, 0), .owner = BIT(0) | BIT(1) }, /* TX */ + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b02, 0x600a7800, 0x600a7800, 136, 0, 0), .owner = BIT(0) | BIT(1) }, /* NRX */ + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b03, 0x600a7c00, 0x600a7c00, 53, 0, 0), .owner = BIT(0) | BIT(1) }, /* BB */ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b05, 0x600a0000, 0x600a0000, 58, 0, 0), .owner = BIT(0) | BIT(1) } /* FE COEX */ + }; + esp_err_t err = sleep_retention_entries_create(bb_regs_retention, ARRAY_SIZE(bb_regs_retention), 3, SLEEP_RETENTION_MODULE_WIFI_BB); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (%s) retention", "WiFi BB"); + ESP_LOGD(TAG, "WiFi BB sleep retention initialization"); + return ESP_OK; +} #endif // SOC_PM_MODEM_RETENTION_BY_BACKUPDMA void esp_mac_bb_pd_mem_init(void) @@ -403,16 +442,18 @@ void esp_mac_bb_pd_mem_init(void) } k_mutex_unlock(&s_phy_access_lock); #elif SOC_PM_MODEM_RETENTION_BY_REGDMA - const static sleep_retention_entries_config_t bb_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b00, 0x600a7000, 0x600a7000, 121, 0, 0), .owner = BIT(0) | BIT(1) }, /* AGC */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b01, 0x600a7400, 0x600a7400, 14, 0, 0), .owner = BIT(0) | BIT(1) }, /* TX */ - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b02, 0x600a7800, 0x600a7800, 136, 0, 0), .owner = BIT(0) | BIT(1) }, /* NRX */ - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b03, 0x600a7c00, 0x600a7c00, 53, 0, 0), .owner = BIT(0) | BIT(1) }, /* BB */ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(0x0b05, 0x600a0000, 0x600a0000, 58, 0, 0), .owner = BIT(0) | BIT(1) } /* FE COEX */ + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_retention_wifi_bb_init, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) }; - esp_err_t err = sleep_retention_entries_create(bb_regs_retention, ARRAY_SIZE(bb_regs_retention), 3, SLEEP_RETENTION_MODULE_WIFI_BB); + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_WIFI_BB, &init_param); + if (err != ESP_OK) { + ESP_LOGW(TAG, "WiFi BB sleep retention init failed"); + return; + } + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_WIFI_BB); if (err != ESP_OK) { - ESP_LOGW(TAG, "failed to allocate memory for WiFi baseband retention"); + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for wifi bb retention"); } #endif } @@ -428,7 +469,15 @@ void esp_mac_bb_pd_mem_deinit(void) } k_mutex_unlock(&s_phy_access_lock); #elif SOC_PM_MODEM_RETENTION_BY_REGDMA - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_WIFI_BB); + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_WIFI_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to free sleep retention linked list for wifi bb retention"); + return; + } + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_WIFI_BB); + if (err != ESP_OK) { + ESP_LOGW(TAG, "WiFi BB sleep retention deinit failed"); + } #endif } @@ -596,6 +645,13 @@ void esp_phy_load_cal_and_init(void) #if CONFIG_IDF_TARGET_ESP32S2 phy_eco_version_sel(efuse_hal_chip_revision() / 100); #endif + + // Set PHY whether in combo module + // For comode mode, phy enable will be not in WiFi RX state +#if SOC_PHY_COMBO_MODULE + phy_init_param_set(1); +#endif + esp_phy_calibration_data_t* cal_data = (esp_phy_calibration_data_t*) calloc(sizeof(esp_phy_calibration_data_t), 1); if (cal_data == NULL) { @@ -651,8 +707,7 @@ void esp_phy_load_cal_and_init(void) ESP_LOGW(TAG, "saving new calibration data because of checksum failure, mode(%d)", calibration_mode); } - if ((calibration_mode != PHY_RF_CAL_NONE && err != ESP_OK) || - (calibration_mode != PHY_RF_CAL_FULL && ret == ESP_CAL_DATA_CHECK_FAIL)) { + if ((calibration_mode != PHY_RF_CAL_NONE) && ((err != ESP_OK) || (ret == ESP_CAL_DATA_CHECK_FAIL))) { err = esp_phy_store_cal_data_to_nvs(cal_data); } else { err = ESP_OK; @@ -673,9 +728,9 @@ void esp_phy_load_cal_and_init(void) esp_phy_release_init_data(init_data); #endif - ESP_ERROR_CHECK(esp_deep_sleep_register_hook(&phy_close_rf)); + ESP_ERROR_CHECK(esp_deep_sleep_register_phy_hook(&phy_close_rf)); #if !CONFIG_IDF_TARGET_ESP32 - ESP_ERROR_CHECK(esp_deep_sleep_register_hook(&phy_xpd_tsens)); + ESP_ERROR_CHECK(esp_deep_sleep_register_phy_hook(&phy_xpd_tsens)); #endif free(cal_data); // PHY maintains a copy of calibration data, so we can free this @@ -711,7 +766,7 @@ static uint8_t phy_find_bin_type_according_country(const char* country) if (i == sizeof(s_country_code_map_type_table)/sizeof(phy_country_to_bin_type_t)) { phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT; - ESP_LOGW(TAG, "Use the default certification code beacuse %c%c doesn't have a certificate", country[0], country[1]); + ESP_LOGW(TAG, "Use the default certification code because %c%c doesn't have a certificate", country[0], country[1]); } return phy_init_data_type; @@ -929,3 +984,8 @@ esp_err_t esp_phy_update_country_info(const char *country) void esp_wifi_power_domain_on(void) __attribute__((alias("esp_wifi_bt_power_domain_on"))); void esp_wifi_power_domain_off(void) __attribute__((alias("esp_wifi_bt_power_domain_off"))); + +_lock_t phy_get_lock(void) +{ + return s_phy_access_lock; +} diff --git a/components/esp_phy/src/phy_init_esp32hxx.c b/components/esp_phy/src/phy_init_esp32hxx.c index 52d7722a65..d0d3e2a20b 100644 --- a/components/esp_phy/src/phy_init_esp32hxx.c +++ b/components/esp_phy/src/phy_init_esp32hxx.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,10 @@ #include "esp_phy_init.h" #include "esp_private/phy.h" +#if SOC_MODEM_CLOCK_IS_INDEPENDENT +#include "esp_private/esp_modem_clock.h" +#endif + #define PHY_ENABLE_VERSION_PRINT 1 static DRAM_ATTR portMUX_TYPE s_phy_int_mux = portMUX_INITIALIZER_UNLOCKED; @@ -17,7 +21,6 @@ extern void phy_version_print(void); static _lock_t s_phy_access_lock; /* Reference count of enabling PHY */ -static uint8_t s_phy_access_ref = 0; static bool s_phy_is_enabled = false; uint32_t IRAM_ATTR phy_enter_critical(void) @@ -42,10 +45,13 @@ void IRAM_ATTR phy_exit_critical(uint32_t level) } } -void esp_phy_enable(void) +void esp_phy_enable(esp_phy_modem_t modem) { _lock_acquire(&s_phy_access_lock); - if (s_phy_access_ref == 0) { + if (phy_get_modem_flag() == 0) { +#if SOC_MODEM_CLOCK_IS_INDEPENDENT + modem_clock_module_enable(PERIPH_PHY_MODULE); +#endif if (!s_phy_is_enabled) { register_chipv7_phy(NULL, NULL, PHY_RF_CAL_FULL); phy_version_print(); @@ -55,25 +61,30 @@ void esp_phy_enable(void) } phy_track_pll_init(); } - - s_phy_access_ref++; - + phy_set_modem_flag(modem); + // Immediately track pll when phy enabled. + phy_track_pll(); _lock_release(&s_phy_access_lock); } -void esp_phy_disable(void) +void esp_phy_disable(esp_phy_modem_t modem) { _lock_acquire(&s_phy_access_lock); - if (s_phy_access_ref) { - s_phy_access_ref--; - } + phy_clr_modem_flag(modem); + if (phy_get_modem_flag() == 0) { - if (s_phy_access_ref == 0) { phy_track_pll_deinit(); phy_close_rf(); phy_xpd_tsens(); +#if SOC_MODEM_CLOCK_IS_INDEPENDENT + modem_clock_module_disable(PERIPH_PHY_MODULE); +#endif } - _lock_release(&s_phy_access_lock); } + +_lock_t phy_get_lock(void) +{ + return s_phy_access_lock; +} diff --git a/components/esp_phy/test/test_phy_rtc.c b/components/esp_phy/test/test_phy_rtc.c index 88e34e037e..1d653ce15c 100644 --- a/components/esp_phy/test/test_phy_rtc.c +++ b/components/esp_phy/test/test_phy_rtc.c @@ -46,9 +46,15 @@ static void test_phy_rtc_init(void) ret = nvs_flash_init(); } TEST_ESP_OK(ret); - - esp_phy_enable(); - +#if CONFIG_ESP_WIFI_ENABLED + esp_phy_enable(PHY_MODEM_WIFI); +#endif +#if CONFIG_BT_ENABLED + esp_phy_enable(PHY_MODEM_BT); +#endif +#if CONFIG_IEEE802154_ENABLED + esp_phy_enable(PHY_MODEM_IEEE802154); +#endif //must run here, not blocking in above code TEST_ASSERT(1); nvs_flash_deinit(); diff --git a/components/esp_rom/.build-test-rules.yml b/components/esp_rom/.build-test-rules.yml index 8a19709b18..7bc39d1f09 100644 --- a/components/esp_rom/.build-test-rules.yml +++ b/components/esp_rom/.build-test-rules.yml @@ -1,12 +1,12 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps -components/esp_rom/host_test/rom_test: - enable: - - if: IDF_TARGET == "linux" - reason: only test on linux - components/esp_rom/test_apps: disable_test: - if: IDF_TARGET in ["esp32", "esp32c2"] temporary: false reason: lack of memory for testing miniz compressing + +components/esp_rom/test_apps/linux_rom_apis: + enable: + - if: IDF_TARGET == "linux" + reason: only test on linux diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 6634f5ffc7..df01320e24 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -23,10 +23,14 @@ else() # Override regi2c implementation in ROM if(CONFIG_ESP_ROM_HAS_REGI2C_BUG OR CONFIG_ESP_ROM_WITHOUT_REGI2C) - list(APPEND sources "patches/esp_rom_regi2c_${target}.c") + if(target STREQUAL "esp32c6") + list(APPEND sources "patches/esp_rom_hp_regi2c_${target}.c") + else() + list(APPEND sources "patches/esp_rom_regi2c_${target}.c") + 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() @@ -46,10 +50,14 @@ if(CONFIG_HAL_WDT_USE_ROM_IMPL) list(APPEND sources "patches/esp_rom_wdt.c") endif() -if(CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG) +if(CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG OR CONFIG_ESP_ROM_HAS_CACHE_WRITEBACK_BUG) list(APPEND sources "patches/esp_rom_cache_esp32s2_esp32s3.c") endif() +if(CONFIG_ESP_ROM_HAS_CACHE_WRITEBACK_BUG) + list(APPEND sources "patches/esp_rom_cache_writeback_esp32s3.S") +endif() + idf_component_register(SRCS ${sources} INCLUDE_DIRS ${include_dirs} PRIV_REQUIRES ${private_required_comp} @@ -106,7 +114,6 @@ if(BOOTLOADER_BUILD) elseif(target STREQUAL "esp32c2") rom_linker_script("newlib") - rom_linker_script("mbedtls") elseif(target STREQUAL "esp32c6") rom_linker_script("newlib") @@ -208,10 +215,17 @@ else() # Regular app build rom_linker_script("eco3") endif() + if(CONFIG_ESP32C3_REV_MIN_FULL GREATER_EQUAL 101) + rom_linker_script("eco7") + endif() + elseif(target STREQUAL "esp32c2") rom_linker_script("newlib") rom_linker_script("version") - rom_linker_script("mbedtls") + + if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL) + rom_linker_script("mbedtls") + endif() if(CONFIG_NEWLIB_NANO_FORMAT) # nano formatting functions in ROM are also built for 64-bit time_t. @@ -253,7 +267,7 @@ else() # Regular app build rom_linker_script("wdt") endif() - if(CONFIG_NEWLIB_NANO_FORMAT) + if(CONFIG_NEWLIB_NANO_FORMAT AND NOT CONFIG_ESP_ROM_HAS_NEWLIB_NANO_PRINTF_FLOAT_BUG) # nano formatting functions in ROM are also built for 64-bit time_t. rom_linker_script("newlib-nano") endif() @@ -265,7 +279,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() @@ -278,5 +292,5 @@ else() # Regular app build endif() if(target STREQUAL "esp32s2") - target_sources(${COMPONENT_LIB} PRIVATE "esp32s2/usb_descriptors.c") + target_sources(${COMPONENT_LIB} PRIVATE "esp32s2/usb_patches.c") endif() diff --git a/components/esp_rom/esp32/ld/esp32.rom.ld b/components/esp_rom/esp32/ld/esp32.rom.ld index 18ee3a4aa2..b47c3140b8 100644 --- a/components/esp_rom/esp32/ld/esp32.rom.ld +++ b/components/esp_rom/esp32/ld/esp32.rom.ld @@ -652,6 +652,7 @@ PROVIDE ( lc_cmd_cmp_bd_addr_send = 0x4002cec4 ); PROVIDE ( ld_acl_tx_packet_type_select = 0x4002fb40 ); PROVIDE ( ld_acl_sched = 0x40033268 ); PROVIDE ( ld_acl_sniff_sched = 0x4003340c ); +PROVIDE ( ld_acl_sniff_exit = 0x400312b4 ); PROVIDE ( ld_acl_rx = 0x4003274c ); PROVIDE ( ld_acl_tx = 0x4002ffdc ); PROVIDE ( ld_acl_rx_sync = 0x4002fbec ); @@ -1473,7 +1474,7 @@ PROVIDE ( uart_tx_switch = 0x40009028 ); /* These functions are part of the ROM GPIO driver. We do not use them; the provided esp-idf functions -replace them and this way we can re-use the fixed RAM addresses these routines need. +replace them and this way we can reuse the fixed RAM addresses these routines need. */ /* <-- So you don't read over it: This comment disables the next lines. PROVIDE ( gpio_init = 0x40009c20 ); @@ -1622,4 +1623,13 @@ PROVIDE ( ld_acl_sniff_trans_sched = 0x40033734 ); PROVIDE ( lc_pwr_decr_ind_handler = 0x4002859c ); PROVIDE ( lc_pwr_incr_ind_handler = 0x400284a8 ); PROVIDE ( lc_pwr_max_ind_handler = 0x40028690 ); +PROVIDE ( lc_setup_sync_param_check = 0x4002354c ); + +PROVIDE ( lm_sync_conf = 0x3ffb8348 ); +PROVIDE ( lm_nb_sync_active = 0x3ffb8346 ); +PROVIDE ( lm_sync_nego = 0x3ffb8345 ); +PROVIDE ( lm_nego_cnt = 0x3ffb8344 ); +PROVIDE ( lm_nego_cntl = 0x3ffb8342 ); +PROVIDE ( lm_nego_max_cnt = 0x3ffb8343 ); +PROVIDE ( lm_nego_pkt_used = 0x3ffb8340 ); /* Above are static data, but can be used, not generated by script >>>>> btdm data */ diff --git a/components/esp_rom/esp32c2/Kconfig.soc_caps.in b/components/esp_rom/esp32c2/Kconfig.soc_caps.in index 022578b6a3..b2d3381e8c 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 @@ -62,3 +58,7 @@ config ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE config ESP_ROM_RAM_APP_NEEDS_MMU_INIT bool default y + +config ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB + bool + default y diff --git a/components/esp_rom/esp32c2/esp_rom_caps.h b/components/esp_rom/esp32c2/esp_rom_caps.h index c62e783365..cc3fdc5180 100644 --- a/components/esp_rom/esp32c2/esp_rom_caps.h +++ b/components/esp_rom/esp32c2/esp_rom_caps.h @@ -15,9 +15,9 @@ #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 #define ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE (1) // ROM needs to set cache MMU size according to instruction and rodata for flash mmap #define ESP_ROM_RAM_APP_NEEDS_MMU_INIT (1) // ROM doesn't init cache MMU when it's a RAM APP, needs MMU hal to init +#define ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB (1) // ROM has the mbedtls crypto algorithm lib diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index a36b0b3790..a010210258 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -563,10 +563,6 @@ bt_rf_coex_dft_pti_get_default = 0x40000ab4; bt_rf_coex_hooks_p_set = 0x40000ab8; r__os_mbuf_copypkthdr = 0x40000abc; r_ble_controller_get_rom_compile_version = 0x40000ac4; -r_ble_hci_ram_hs_acl_tx = 0x40000ac8; -r_ble_hci_ram_hs_cmd_tx = 0x40000acc; -r_ble_hci_ram_ll_acl_tx = 0x40000ad0; -r_ble_hci_ram_ll_evt_tx = 0x40000ad4; r_ble_hci_ram_reset = 0x40000ad8; r_ble_hci_ram_set_acl_free_cb = 0x40000adc; r_ble_hci_trans_acl_buf_alloc = 0x40000ae0; @@ -579,10 +575,6 @@ r_ble_hci_uart_acl_tx = 0x40000b00; r_ble_hci_uart_cmdevt_tx = 0x40000b04; r_ble_hci_uart_config = 0x40000b08; r_ble_hci_uart_free_pkt = 0x40000b0c; -r_ble_hci_uart_hs_acl_tx = 0x40000b10; -r_ble_hci_uart_hs_cmd_tx = 0x40000b14; -r_ble_hci_uart_ll_acl_tx = 0x40000b18; -r_ble_hci_uart_ll_evt_tx = 0x40000b1c; r_ble_hci_uart_rx_acl = 0x40000b20; r_ble_hci_uart_rx_char = 0x40000b24; r_ble_hci_uart_rx_cmd = 0x40000b28; @@ -613,10 +605,8 @@ r_ble_hw_rng_stop = 0x40000b94; r_ble_hw_rx_local_is_resolved = 0x40000b98; r_ble_hw_rx_local_is_rpa = 0x40000b9c; r_ble_hw_whitelist_add = 0x40000ba0; -r_ble_hw_whitelist_clear = 0x40000ba4; r_ble_hw_whitelist_dev_num = 0x40000ba8; r_ble_hw_whitelist_get_base = 0x40000bac; -r_ble_hw_whitelist_rmv = 0x40000bb0; r_ble_hw_whitelist_search = 0x40000bb4; r_ble_hw_whitelist_sort = 0x40000bb8; r_ble_ll_acl_data_in = 0x40000bbc; @@ -648,7 +638,6 @@ r_ble_ll_adv_get_local_rpa = 0x40000c30; r_ble_ll_adv_get_peer_rpa = 0x40000c34; r_ble_ll_adv_hci_set_random_addr = 0x40000c38; r_ble_ll_adv_init = 0x40000c3c; -r_ble_ll_adv_legacy_pdu_make = 0x40000c40; r_ble_ll_adv_next_chan = 0x40000c44; r_ble_ll_adv_pdu_make = 0x40000c48; r_ble_ll_adv_periodic_check_data_itvl = 0x40000c4c; @@ -669,9 +658,6 @@ r_ble_ll_adv_scan_req_rxd = 0x40000c98; r_ble_ll_adv_scan_rsp_legacy_pdu_make = 0x40000c9c; r_ble_ll_adv_scan_rsp_pdu_make = 0x40000ca0; r_ble_ll_adv_scheduled = 0x40000ca4; -r_ble_ll_adv_send_conn_comp_ev = 0x40000ca8; -r_ble_ll_adv_set_adv_params = 0x40000cb0; -r_ble_ll_adv_set_enable = 0x40000cb4; r_ble_ll_adv_set_random_addr = 0x40000cb8; r_ble_ll_adv_sm_deinit = 0x40000cc4; r_ble_ll_adv_sm_event_init = 0x40000cc8; @@ -693,7 +679,6 @@ r_ble_ll_auth_pyld_tmo_event_send = 0x40000d14; r_ble_ll_calc_offset_ticks_us_for_rampup = 0x40000d18; r_ble_ll_calc_session_key = 0x40000d1c; r_ble_ll_calc_ticks_per_slot = 0x40000d20; -r_ble_ll_check_scan_params = 0x40000d24; r_ble_ll_chk_txrx_octets = 0x40000d28; r_ble_ll_chk_txrx_time = 0x40000d2c; r_ble_ll_conn_adjust_pyld_len = 0x40000d30; @@ -705,7 +690,6 @@ r_ble_ll_conn_calc_itvl_ticks = 0x40000d44; r_ble_ll_conn_chk_csm_flags = 0x40000d48; r_ble_ll_conn_chk_phy_upd_start = 0x40000d4c; r_ble_ll_conn_comp_event_send = 0x40000d50; -r_ble_ll_conn_connect_ind_pdu_make = 0x40000d54; r_ble_ll_conn_create_cancel = 0x40000d5c; r_ble_ll_conn_cth_flow_enable = 0x40000d64; r_ble_ll_conn_cth_flow_error_fn = 0x40000d68; @@ -744,7 +728,6 @@ r_ble_ll_conn_module_reset = 0x40000e04; r_ble_ll_conn_num_comp_pkts_event_send = 0x40000e0c; r_ble_ll_conn_process_conn_params = 0x40000e14; r_ble_ll_conn_req_peer_sca = 0x40000e18; -r_ble_ll_conn_rx_data_pdu = 0x40000e1c; r_ble_ll_conn_set_csa = 0x40000e20; r_ble_ll_conn_set_ext_con_params = 0x40000e24; r_ble_ll_conn_set_global_chanmap = 0x40000e28; @@ -779,8 +762,6 @@ r_ble_ll_ctrl_rej_ext_ind_make = 0x40000ec0; r_ble_ll_ctrl_reject_ind_send = 0x40000ec4; r_ble_ll_ctrl_rx_chanmap_req = 0x40000ec8; r_ble_ll_ctrl_rx_conn_param_req = 0x40000ecc; -r_ble_ll_ctrl_rx_conn_param_rsp = 0x40000ed0; -r_ble_ll_ctrl_rx_conn_update = 0x40000ed4; r_ble_ll_ctrl_rx_enc_req = 0x40000ed8; r_ble_ll_ctrl_rx_enc_rsp = 0x40000edc; r_ble_ll_ctrl_rx_feature_req = 0x40000ee0; @@ -825,7 +806,6 @@ r_ble_ll_hci_cb_set_ctrlr_to_host_fc = 0x40000f9c; r_ble_ll_hci_cb_set_event_mask = 0x40000fa0; r_ble_ll_hci_cb_set_event_mask2 = 0x40000fa4; r_ble_ll_hci_chk_phy_masks = 0x40000fa8; -r_ble_ll_hci_cmd_proc = 0x40000fac; r_ble_ll_hci_cmd_rx = 0x40000fb0; r_ble_ll_hci_disconnect = 0x40000fbc; r_ble_ll_hci_ev_conn_update = 0x40000fc4; @@ -844,7 +824,6 @@ r_ble_ll_hci_ev_send_adv_set_terminated = 0x40000ff4; r_ble_ll_hci_ev_send_scan_req_recv = 0x40000ff8; r_ble_ll_hci_ev_send_scan_timeout = 0x40000ffc; r_ble_ll_hci_ev_send_vendor_err = 0x40001000; -r_ble_ll_hci_event_send = 0x40001004; r_ble_ll_hci_ext_scan_set_enable = 0x40001008; r_ble_ll_hci_get_num_cmd_pkts = 0x4000100c; r_ble_ll_hci_info_params_cmd_proc = 0x40001010; @@ -872,8 +851,6 @@ r_ble_ll_hci_rd_local_version = 0x4000106c; r_ble_ll_hci_scan_set_enable = 0x40001070; r_ble_ll_hci_send_adv_report = 0x40001074; r_ble_ll_hci_send_dir_adv_report = 0x40001078; -r_ble_ll_hci_send_ext_adv_report = 0x4000107c; -r_ble_ll_hci_send_legacy_ext_adv_report = 0x40001080; r_ble_ll_hci_send_noop = 0x40001084; r_ble_ll_hci_set_adv_data = 0x40001088; r_ble_ll_hci_set_le_event_mask = 0x4000108c; @@ -900,7 +877,6 @@ r_ble_ll_pdu_max_tx_octets_get = 0x400010ec; r_ble_ll_pdu_tx_time_get = 0x400010f0; r_ble_ll_phy_to_phy_mode = 0x400010f4; r_ble_ll_qa_enable = 0x400010f8; -r_ble_ll_rand = 0x400010fc; r_ble_ll_rand_data_get = 0x40001100; r_ble_ll_rand_init = 0x4000110c; r_ble_ll_rand_prand_get = 0x40001110; @@ -928,7 +904,6 @@ r_ble_ll_resolv_list_clr = 0x4000117c; r_ble_ll_resolv_list_find = 0x40001180; r_ble_ll_resolv_list_read_size = 0x40001184; r_ble_ll_resolv_list_reset = 0x40001188; -r_ble_ll_resolv_list_rmv = 0x4000118c; r_ble_ll_resolv_local_addr_rd = 0x40001190; r_ble_ll_resolv_peer_addr_rd = 0x40001194; r_ble_ll_resolv_peer_rpa_any = 0x40001198; @@ -979,7 +954,6 @@ r_ble_ll_scan_reset = 0x40001258; r_ble_ll_scan_rx_pkt_in = 0x4000125c; r_ble_ll_scan_rx_pkt_in_restore_addr_data = 0x40001268; r_ble_ll_scan_rxed = 0x4000126c; -r_ble_ll_scan_send_adv_report = 0x40001270; r_ble_ll_scan_send_truncated = 0x40001274; r_ble_ll_scan_set_peer_rpa = 0x4000127c; r_ble_ll_scan_set_perfer_addr = 0x40001280; @@ -1033,12 +1007,10 @@ r_ble_ll_sync_terminate = 0x4000136c; r_ble_ll_sync_transfer = 0x40001370; r_ble_ll_sync_transfer_get = 0x40001374; r_ble_ll_sync_transfer_received = 0x40001378; -r_ble_ll_trace_set_func = 0x40001380; r_ble_ll_trace_u32 = 0x40001384; r_ble_ll_trace_u32x2 = 0x40001388; r_ble_ll_trace_u32x3 = 0x4000138c; r_ble_ll_tx_flat_mbuf_pducb = 0x40001390; -r_ble_ll_tx_pkt_in = 0x40001398; r_ble_ll_update_max_tx_octets_phy_mode = 0x4000139c; r_ble_ll_usecs_to_ticks_round_up = 0x400013a0; r_ble_ll_utils_calc_access_addr = 0x400013a4; @@ -1050,9 +1022,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; @@ -1070,10 +1040,8 @@ r_ble_lll_adv_coex_dpc_update_on_data_updated = 0x40001410; r_ble_lll_adv_coex_dpc_update_on_event_end = 0x40001414; r_ble_lll_adv_coex_dpc_update_on_event_scheduled = 0x40001418; r_ble_lll_adv_done = 0x4000141c; -r_ble_lll_adv_drop_event = 0x40001420; r_ble_lll_adv_event_done = 0x40001424; r_ble_lll_adv_event_rmvd_from_sched = 0x40001428; -r_ble_lll_adv_ext_estimate_data_itvl = 0x4000142c; r_ble_lll_adv_get_sec_pdu_len = 0x40001430; r_ble_lll_adv_make_done = 0x40001438; r_ble_lll_adv_periodic_done = 0x4000143c; @@ -1083,7 +1051,6 @@ r_ble_lll_adv_periodic_schedule_first = 0x40001448; r_ble_lll_adv_pri_schedule_tx_pdu = 0x40001458; r_ble_lll_adv_reschedule_event = 0x4000145c; r_ble_lll_adv_reschedule_periodic_event = 0x40001460; -r_ble_lll_adv_sec_done = 0x40001468; r_ble_lll_adv_sec_event_done = 0x4000146c; r_ble_lll_adv_sec_schedule_next_aux = 0x40001470; r_ble_lll_adv_secondary_tx_start_cb = 0x40001474; @@ -1117,21 +1084,16 @@ r_ble_lll_conn_coex_dpc_update_on_event_scheduled = 0x400014e4; r_ble_lll_conn_coex_dpc_update_on_event_started = 0x400014e8; r_ble_lll_conn_cth_flow_alloc_credit = 0x400014ec; r_ble_lll_conn_current_sm_over = 0x400014f4; -r_ble_lll_conn_event_end = 0x40001504; -r_ble_lll_conn_event_end_timer_cb = 0x40001508; -r_ble_lll_conn_event_halt = 0x4000150c; r_ble_lll_conn_event_is_over = 0x40001510; r_ble_lll_conn_event_start_cb = 0x40001514; r_ble_lll_conn_free_rx_mbuf = 0x40001518; r_ble_lll_conn_get_addr_info_from_rx_buf = 0x4000151c; r_ble_lll_conn_get_ce_end_time = 0x40001520; r_ble_lll_conn_get_next_sched_time = 0x40001524; -r_ble_lll_conn_halt = 0x4000152c; 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; @@ -1184,9 +1146,6 @@ r_ble_lll_per_adv_coex_dpc_update = 0x40001634; r_ble_lll_per_adv_coex_dpc_update_on_data_updated = 0x40001638; r_ble_lll_per_adv_coex_dpc_update_on_scheduled = 0x4000163c; r_ble_lll_per_adv_coex_dpc_update_on_start = 0x40001640; -r_ble_lll_reset = 0x40001644; -r_ble_lll_rfmgmt_controller_sleep_en = 0x40001648; -r_ble_lll_rfmgmt_enable_now = 0x40001658; r_ble_lll_rfmgmt_is_enabled = 0x40001660; r_ble_lll_rfmgmt_release = 0x40001664; r_ble_lll_rfmgmt_scan_changed = 0x40001670; @@ -1197,7 +1156,6 @@ r_ble_lll_rx_pdu_in = 0x40001688; r_ble_lll_rx_pkt_in = 0x4000168c; r_ble_lll_rx_pkt_isr = 0x40001690; r_ble_lll_scan_abort_aux_sched = 0x40001694; -r_ble_lll_scan_aux_data_free = 0x40001698; r_ble_lll_scan_chk_resume = 0x4000169c; r_ble_lll_scan_clean_cur_aux_data = 0x400016a0; r_ble_lll_scan_coex_event_cb = 0x400016a4; @@ -1208,7 +1166,6 @@ r_ble_lll_scan_duration_period_timers_stop = 0x400016b4; r_ble_lll_scan_duration_timer_cb = 0x400016b8; r_ble_lll_scan_event_proc = 0x400016bc; r_ble_lll_scan_ext_adv_init = 0x400016c0; -r_ble_lll_scan_halt = 0x400016c4; r_ble_lll_scan_has_sent_scan_req = 0x400016c8; r_ble_lll_scan_npl_reset = 0x400016d4; r_ble_lll_scan_npl_restore = 0x400016d8; @@ -1216,7 +1173,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; @@ -1227,10 +1183,8 @@ r_ble_lll_sched_adv_resched_pdu = 0x40001720; r_ble_lll_sched_adv_reschedule = 0x40001724; r_ble_lll_sched_aux_scan = 0x40001728; r_ble_lll_sched_conn_overlap = 0x4000172c; -r_ble_lll_sched_conn_reschedule = 0x40001730; r_ble_lll_sched_dtm = 0x40001738; r_ble_lll_sched_execute_item = 0x40001744; -r_ble_lll_sched_init = 0x40001748; r_ble_lll_sched_insert_if_empty = 0x4000174c; r_ble_lll_sched_is_overlap = 0x40001750; r_ble_lll_sched_master_new = 0x40001754; @@ -1245,23 +1199,19 @@ r_ble_lll_sched_slave_new = 0x40001774; r_ble_lll_sched_stop = 0x40001778; r_ble_lll_sched_sync = 0x4000177c; r_ble_lll_sched_sync_overlaps_current = 0x40001780; -r_ble_lll_sched_sync_reschedule = 0x40001784; r_ble_lll_sync_chain_start_cb = 0x40001788; r_ble_lll_sync_coex_dpc_process = 0x4000178c; r_ble_lll_sync_coex_dpc_pti_get = 0x40001790; r_ble_lll_sync_coex_dpc_update = 0x40001794; r_ble_lll_sync_current_sm_over = 0x40001798; r_ble_lll_sync_deinit = 0x4000179c; -r_ble_lll_sync_event_end = 0x400017a0; r_ble_lll_sync_event_end_cb = 0x400017a4; r_ble_lll_sync_get_event_end_time = 0x400017ac; -r_ble_lll_sync_halt = 0x400017b0; r_ble_lll_sync_init = 0x400017b4; r_ble_lll_sync_new = 0x400017b8; r_ble_lll_sync_reset = 0x400017bc; r_ble_lll_sync_reset_sm = 0x400017c0; r_ble_lll_sync_rmvd_from_sched = 0x400017c4; -r_ble_lll_sync_rx_pkt_isr = 0x400017c8; r_ble_lll_sync_schedule_chain = 0x400017cc; r_ble_lll_sync_stop = 0x400017d0; r_ble_lll_sync_trnasfer_sched = 0x400017d4; @@ -1355,9 +1305,7 @@ r_hal_timer_process = 0x40001978; r_hal_timer_read = 0x4000197c; r_hal_timer_read_tick = 0x40001980; r_hal_timer_set_cb = 0x40001984; -r_hal_timer_set_exp_tick = 0x40001988; r_hal_timer_start = 0x4000198c; -r_hal_timer_stop = 0x40001994; r_hal_timer_task_start = 0x40001998; r_ll_assert = 0x4000199c; r_mem_init_mbuf_pool = 0x400019a0; @@ -1404,12 +1352,8 @@ r_os_memblock_put_from_cb = 0x40001a4c; r_os_mempool_clear = 0x40001a50; r_os_mempool_ext_clear = 0x40001a54; r_os_mempool_ext_init = 0x40001a58; -r_os_mempool_info_get_next = 0x40001a5c; r_os_mempool_init = 0x40001a60; -r_os_mempool_init_internal = 0x40001a64; r_os_mempool_is_sane = 0x40001a68; -r_os_mempool_module_init = 0x40001a6c; -r_os_mempool_unregister = 0x40001a70; r_os_mqueue_get = 0x40001a74; r_os_mqueue_init = 0x40001a78; r_os_mqueue_put = 0x40001a7c; @@ -1514,25 +1458,25 @@ g_os_mempool_list = 0x3fcdfdf0; esp_pp_rom_version_get = 0x40001ad4; RC_GetBlockAckTime = 0x40001ad8; ebuf_list_remove = 0x40001adc; -esf_buf_alloc = 0x40001ae0; -esf_buf_alloc_dynamic = 0x40001ae4; -esf_buf_recycle = 0x40001ae8; +/*esf_buf_alloc = 0x40001ae0;*/ +/*esf_buf_alloc_dynamic = 0x40001ae4;*/ +/*esf_buf_recycle = 0x40001ae8;*/ GetAccess = 0x40001aec; hal_mac_is_low_rate_enabled = 0x40001af0; hal_mac_tx_get_blockack = 0x40001af4; -hal_mac_tx_set_ppdu = 0x40001af8; +/*hal_mac_tx_set_ppdu = 0x40001af8;*/ ic_get_trc = 0x40001afc; /* ic_mac_deinit = 0x40001b00; */ ic_mac_init = 0x40001b04; ic_interface_enabled = 0x40001b08; is_lmac_idle = 0x40001b0c; -lmacAdjustTimestamp = 0x40001b10; +/*lmacAdjustTimestamp = 0x40001b10;*/ lmacDiscardAgedMSDU = 0x40001b14; /*lmacDiscardMSDU = 0x40001b18;*/ -lmacEndFrameExchangeSequence = 0x40001b1c; +/*lmacEndFrameExchangeSequence = 0x40001b1c;*/ lmacIsIdle = 0x40001b20; lmacIsLongFrame = 0x40001b24; -lmacMSDUAged = 0x40001b28; +/*lmacMSDUAged = 0x40001b28;*/ lmacPostTxComplete = 0x40001b2c; lmacProcessAllTxTimeout = 0x40001b30; lmacProcessCollisions = 0x40001b34; @@ -1549,10 +1493,10 @@ 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; +/*pm_dream = 0x40001b78;*/ pm_mac_wakeup = 0x40001b7c; pm_mac_sleep = 0x40001b80; pm_enable_active_timer = 0x40001b84; @@ -1573,10 +1517,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; @@ -1596,8 +1540,8 @@ ppRecycleAmpdu = 0x40001c18; ppRecycleRxPkt = 0x40001c1c; ppResortTxAMPDU = 0x40001c20; ppResumeTxAMPDU = 0x40001c24; -ppRxFragmentProc = 0x40001c28; -ppRxPkt = 0x40001c2c; +/*ppRxFragmentProc = 0x40001c28;*/ +/* ppRxPkt = 0x40001c2c; */ ppRxProtoProc = 0x40001c30; ppSearchTxQueue = 0x40001c34; ppSearchTxframe = 0x40001c38; @@ -1607,7 +1551,7 @@ ppTask = 0x40001c44; ppTxPkt = 0x40001c48; ppTxProtoProc = 0x40001c4c; ppTxqUpdateBitmap = 0x40001c50; -pp_coex_tx_request = 0x40001c54; +/*pp_coex_tx_request = 0x40001c54;*/ pp_hdrsize = 0x40001c58; pp_post = 0x40001c5c; pp_process_hmac_waiting_txq = 0x40001c60; @@ -1620,12 +1564,12 @@ rcampduuprate = 0x40001c78; rcClearCurAMPDUSched = 0x40001c7c; rcClearCurSched = 0x40001c80; rcClearCurStat = 0x40001c84; -rcGetSched = 0x40001c88; +/*rcGetSched = 0x40001c88;*/ rcLowerSched = 0x40001c8c; rcSetTxAmpduLimit = 0x40001c90; /* rcTxUpdatePer = 0x40001c94;*/ rcUpdateAckSnr = 0x40001c98; -rcUpdateRate = 0x40001c9c; +/*rcUpdateRate = 0x40001c9c;*/ rcUpdateTxDone = 0x40001ca0; rcUpdateTxDoneAmpdu2 = 0x40001ca4; rcUpSched = 0x40001ca8; @@ -1641,11 +1585,11 @@ trc_SetTxAmpduState = 0x40001ccc; trc_tid_isTxAmpduOperational = 0x40001cd0; trcAmpduSetState = 0x40001cd4; wDevCheckBlockError = 0x40001cd8; -wDev_AppendRxBlocks = 0x40001cdc; +/*wDev_AppendRxBlocks = 0x40001cdc;*/ wDev_DiscardFrame = 0x40001ce0; wDev_GetNoiseFloor = 0x40001ce4; wDev_IndicateAmpdu = 0x40001ce8; -wDev_IndicateFrame = 0x40001cec; +/*wDev_IndicateFrame = 0x40001cec;*/ wdev_mac_reg_load = 0x40001cf0; wdev_mac_reg_store = 0x40001cf4; wdev_mac_special_reg_load = 0x40001cf8; @@ -1653,14 +1597,14 @@ wdev_mac_special_reg_store = 0x40001cfc; wdev_mac_wakeup = 0x40001d00; wdev_mac_sleep = 0x40001d04; /* wDev_ProcessFiq = 0x40001d08; */ -wDev_ProcessRxSucData = 0x40001d0c; +/*wDev_ProcessRxSucData = 0x40001d0c;*/ wdevProcessRxSucDataAll = 0x40001d10; wdev_csi_len_align = 0x40001d14; ppDequeueTxDone_Locked = 0x40001d18; -ppProcTxDone = 0x40001d1c; +/*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; @@ -1678,14 +1622,14 @@ hal_mac_set_txq_invalid = 0x40001d60; hal_mac_txq_disable = 0x40001d64; hal_mac_is_txq_enabled = 0x40001d68; hal_mac_get_txq_pmd = 0x40001d6c; -lmacDiscardFrameExchangeSequence = 0x40001d70; -lmacDisableTransmit = 0x40001d74; -lmacProcessTxTimeout = 0x40001d78; +/*lmacDiscardFrameExchangeSequence = 0x40001d70;*/ +/*lmacDisableTransmit = 0x40001d74;*/ +/*lmacProcessTxTimeout = 0x40001d78;*/ /*lmacProcessTxSuccess = 0x40001d7c;*/ lmacProcessCollision = 0x40001d80; lmacProcessTxRtsError = 0x40001d84; lmacProcessCtsTimeout = 0x40001d88; -lmacProcessTxComplete = 0x40001d8c; +/* lmacProcessTxComplete = 0x40001d8c;*/ lmacProcessAckTimeout = 0x40001d90; lmacProcessTxError = 0x40001d94; lmacProcessTxseckiderr = 0x40001d98; @@ -1700,9 +1644,9 @@ lmacRetryTxFrame = 0x40001db8; lmacProcessCollisions_task = 0x40001dbc; /*lmacProcessTxopQComplete = 0x40001dc0;*/ lmacInitAc = 0x40001dc4; -lmacInit = 0x40001dc8; +/*lmacInit = 0x40001dc8;*/ mac_tx_set_txop_q = 0x40001dcc; -hal_init = 0x40001dd0; +/*hal_init = 0x40001dd0;*/ hal_mac_rx_set_policy = 0x40001dd4; hal_mac_set_bssid = 0x40001dd8; mac_rx_policy_init = 0x40001ddc; @@ -1712,7 +1656,7 @@ mac_last_rxbuf_init = 0x40001de8; hal_attenna_init = 0x40001dec; hal_timer_update_by_rtc = 0x40001df0; hal_coex_pti_init = 0x40001df4; -lmac_stop_hw_txq = 0x40001df8; +/*lmac_stop_hw_txq = 0x40001df8;*/ ppDirectRecycleAmpdu = 0x40001dfc; esp_wifi_internal_set_rts = 0x40001e00; esp_wifi_internal_get_rts = 0x40001e04; @@ -1720,7 +1664,7 @@ esp_wifi_internal_get_rts = 0x40001e04; /*esf_buf_setup = 0x40001e0c;*/ hal_agreement_add_rx_ba = 0x40001e10; hal_agreement_del_rx_ba = 0x40001e14; -hal_crypto_set_key_entry = 0x40001e18; +/*hal_crypto_set_key_entry = 0x40001e18;*/ hal_crypto_get_key_entry = 0x40001e1c; hal_crypto_clr_key_entry = 0x40001e20; config_get_wifi_task_stack_size = 0x40001e24; @@ -1728,12 +1672,12 @@ pp_create_task = 0x40001e28; hal_set_sta_tsf_wakeup = 0x40001e2c; hal_set_rx_beacon_pti = 0x40001e30; /* pm_start = 0x40001e34; */ -pm_stop = 0x40001e38; +/* pm_stop = 0x40001e38; */ hal_disable_sta_tbtt = 0x40001e3c; ppCalTxopDur = 0x40001e40; wDev_IndicateCtrlFrame = 0x40001e44; hal_enable_sta_tbtt = 0x40001e48; -hal_set_sta_tbtt = 0x40001e4c; +/*hal_set_sta_tbtt = 0x40001e4c;*/ /* pm_update_next_tbtt = 0x40001e50;*/ /* pm_set_sleep_type = 0x40001e54; */ wDev_Rxbuf_Init = 0x40001e58; @@ -1758,14 +1702,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; @@ -1777,7 +1721,7 @@ hal_sniffer_enable = 0x40001eec; hal_sniffer_disable = 0x40001ef0; /*hal_sniffer_rx_set_promis = 0x40001ef4;*/ hal_sniffer_rx_clr_statistics = 0x40001ef8; -hal_sniffer_set_promis_misc_pkt = 0x40001efc; +/*hal_sniffer_set_promis_misc_pkt = 0x40001efc;*/ tsf_hal_set_tsf_enable = 0x40001f00; tsf_hal_set_tsf_disable = 0x40001f04; tsf_hal_is_tsf_enabled = 0x40001f08; @@ -1792,7 +1736,7 @@ tsf_hal_set_tbtt_intr_enable = 0x40001f28; tsf_hal_set_tbtt_intr_disable = 0x40001f2c; tsf_hal_set_tbtt_soc_wakeup_enable = 0x40001f30; tsf_hal_set_tbtt_soc_wakeup_disable = 0x40001f34; -tsf_hal_set_tbtt_start_time = 0x40001f38; +/*tsf_hal_set_tbtt_start_time = 0x40001f38;*/ tsf_hal_set_tbtt_early_time = 0x40001f3c; tsf_hal_set_tbtt_interval = 0x40001f40; tsf_hal_get_tbtt_interval = 0x40001f44; @@ -1891,31 +1835,31 @@ ic_ebuf_recycle_rx = 0x40001fa0; ic_ebuf_recycle_tx = 0x40001fa4; ic_reset_rx_ba = 0x40001fa8; ieee80211_align_eb = 0x40001fac; -ieee80211_ampdu_reorder = 0x40001fb0; +/*ieee80211_ampdu_reorder = 0x40001fb0;*/ ieee80211_ampdu_start_age_timer = 0x40001fb4; -ieee80211_encap_esfbuf = 0x40001fb8; +/*ieee80211_encap_esfbuf = 0x40001fb8;*/ ieee80211_is_tx_allowed = 0x40001fbc; ieee80211_output_pending_eb = 0x40001fc0; -ieee80211_output_process = 0x40001fc4; +/* ieee80211_output_process = 0x40001fc4; */ ieee80211_set_tx_desc = 0x40001fc8; /*sta_input = 0x40001fcc;*/ wifi_get_macaddr = 0x40001fd0; wifi_rf_phy_disable = 0x40001fd4; wifi_rf_phy_enable = 0x40001fd8; ic_ebuf_alloc = 0x40001fdc; -ieee80211_classify = 0x40001fe0; +/*ieee80211_classify = 0x40001fe0;*/ ieee80211_copy_eb_header = 0x40001fe4; 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; ieee80211_gettid = 0x40002008; -ieee80211_ccmp_decrypt = 0x4000200c; -ieee80211_ccmp_encrypt = 0x40002010; +/* ieee80211_ccmp_decrypt = 0x4000200c; */ +/* ieee80211_ccmp_encrypt = 0x40002010; */ ccmp_encap = 0x40002014; ccmp_decap = 0x40002018; tkip_encap = 0x4000201c; @@ -1944,7 +1888,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; @@ -1954,7 +1898,7 @@ ieee80211_vnd_lora_ie_set = 0x400020bc; ieee80211_add_wme_param = 0x400020c0; ieee80211_add_dsparams = 0x400020c4; ieee80211_add_csa = 0x400020c8; -ieee80211_add_extcap = 0x400020cc; +/*ieee80211_add_extcap = 0x400020cc;*/ ieee80211_regdomain_get_country = 0x400020d0; ieee80211_add_countryie = 0x400020d4; ieee80211_amsdu_adjust_head = 0x400020dc; @@ -1967,15 +1911,15 @@ ieee80211_output_raw_process = 0x400020f4; ieee80211_raw_frame_sanity_check = 0x400020fc; ieee80211_crypto_aes_128_cmac_encrypt = 0x40002100; ieee80211_alloc_tx_buf = 0x40002108; -ieee80211_output_do = 0x4000210c; +/* ieee80211_output_do = 0x4000210c; */ /* ieee80211_send_nulldata = 0x40002110; */ -ieee80211_setup_robust_mgmtframe = 0x40002114; +/* ieee80211_setup_robust_mgmtframe = 0x40002114; */ ieee80211_encap_null_data = 0x4000211c; ieee80211_send_deauth = 0x40002120; ieee80211_alloc_deauth = 0x40002124; ieee80211_send_proberesp = 0x40002128; ieee80211_getcapinfo = 0x40002130; -sta_rx_csa = 0x40002134; +/* sta_rx_csa = 0x40002134; */ /* sta_recv_sa_query_resp = 0x40002144; */ ieee80211_set_max_rate = 0x4000214c; ic_set_sta = 0x40002150; @@ -2021,12 +1965,12 @@ esp_coex_rom_version_get = 0x40002168; coex_bt_release = 0x4000216c; coex_bt_request = 0x40002170; coex_core_ble_conn_dyn_prio_get = 0x40002174; -coex_core_event_duration_get = 0x40002178; +/*coex_core_event_duration_get = 0x40002178;*/ coex_core_pti_get = 0x4000217c; coex_core_release = 0x40002180; coex_core_request = 0x40002184; coex_core_status_get = 0x40002188; -coex_core_timer_idx_get = 0x4000218c; +/*coex_core_timer_idx_get = 0x4000218c;*/ coex_event_duration_get = 0x40002190; coex_hw_timer_disable = 0x40002194; coex_hw_timer_enable = 0x40002198; @@ -2359,3 +2303,10 @@ bt_bb_tx_cca_fifo_read = 0x40002654; coex_pti_v2 = 0x40002658; bt_bb_set_le_tx_on_delay = 0x4000265c; bt_bb_set_corr_thresh_le = 0x40002660; + +/*************************************** + Group rom_mbedtls md5 + ***************************************/ +mbedtls_md5_starts_ret = 0x40002be4; +mbedtls_md5_update_ret = 0x40002be8; +mbedtls_md5_finish_ret = 0x40002bec; diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.mbedtls.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.mbedtls.ld index bc0f7b24b1..54f24e751c 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.mbedtls.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.mbedtls.ld @@ -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 */ @@ -19,7 +19,95 @@ ***************************************/ /* Functions */ -mbedtls_md5_starts_ret = 0x40002be4; -mbedtls_md5_update_ret = 0x40002be8; -mbedtls_md5_finish_ret = 0x40002bec; +mbedtls_aes_init = 0x40002664; +mbedtls_aes_free = 0x40002688; +mbedtls_aes_setkey_enc = 0x4000268c; +mbedtls_aes_setkey_dec = 0x40002690; +mbedtls_aes_crypt_ecb = 0x40002694; +mbedtls_aes_crypt_cbc = 0x40002698; +mbedtls_internal_aes_encrypt = 0x4000269c; +mbedtls_internal_aes_decrypt = 0x400026a0; +mbedtls_asn1_get_len = 0x400026a4; +mbedtls_asn1_get_tag = 0x400026a8; +mbedtls_asn1_get_bool = 0x400026ac; +mbedtls_asn1_get_int = 0x400026b0; +mbedtls_asn1_get_bitstring = 0x400026b4; +mbedtls_asn1_get_bitstring_null = 0x400026b8; +mbedtls_asn1_get_sequence_of = 0x400026bc; +mbedtls_asn1_get_mpi = 0x400026c0; +mbedtls_asn1_get_alg = 0x400026c4; +mbedtls_asn1_get_alg_null = 0x400026c8; +mbedtls_asn1_write_len = 0x400026cc; +mbedtls_asn1_write_tag = 0x400026d0; +mbedtls_asn1_write_mpi = 0x400026d4; +mbedtls_base64_decode = 0x400026d8; +mbedtls_ccm_star_encrypt_and_tag = 0x40002774; +mbedtls_ccm_star_auth_decrypt = 0x40002778; +mbedtls_cipher_init = 0x4000277c; +mbedtls_cipher_set_padding_mode = 0x40002780; +mbedtls_cipher_reset = 0x40002784; +mbedtls_cipher_finish = 0x40002788; +mbedtls_cipher_crypt = 0x4000278c; +mbedtls_cipher_cmac_starts = 0x40002790; +mbedtls_cipher_cmac_update = 0x40002794; +mbedtls_cipher_cmac_finish = 0x40002798; +mbedtls_ctr_drbg_init = 0x4000279c; +mbedtls_ctr_drbg_seed = 0x400027a0; +mbedtls_ctr_drbg_free = 0x400027a4; +mbedtls_ctr_drbg_reseed = 0x400027a8; +mbedtls_ctr_drbg_random_with_add = 0x400027ac; +mbedtls_ctr_drbg_random = 0x400027b0; +mbedtls_sha1_init = 0x40002a1c; +mbedtls_sha1_free = 0x40002a20; +mbedtls_sha1_clone = 0x40002a24; +mbedtls_sha1_starts = 0x40002a28; +mbedtls_sha1_finish = 0x40002a2c; +mbedtls_sha256_init = 0x40002a30; +mbedtls_sha256_free = 0x40002a34; +mbedtls_sha256_clone = 0x40002a38; +mbedtls_sha256_starts = 0x40002a3c; +mbedtls_sha256_finish = 0x40002a40; +mbedtls_sha256 = 0x40002a44; +mbedtls_sha512_init = 0x40002a48; +mbedtls_sha512_free = 0x40002a4c; +mbedtls_sha512_clone = 0x40002a50; +mbedtls_sha512_starts = 0x40002a54; +mbedtls_sha512_update = 0x40002a58; +mbedtls_sha512_finish = 0x40002a5c; +mbedtls_internal_sha512_process = 0x40002a60; +mbedtls_sha512 = 0x40002a64; +mbedtls_aes_xts_init = 0x40002b68; +mbedtls_aes_xts_free = 0x40002b6c; +mbedtls_aes_xts_setkey_enc = 0x40002b70; +mbedtls_aes_xts_setkey_dec = 0x40002b74; +mbedtls_aes_crypt_xts = 0x40002b78; +mbedtls_aes_crypt_cfb128 = 0x40002b7c; +mbedtls_aes_crypt_ofb = 0x40002b80; +mbedtls_aes_crypt_ctr = 0x40002b84; +mbedtls_ccm_init = 0x40002b98; +mbedtls_ccm_setkey = 0x40002b9c; +mbedtls_ccm_free = 0x40002ba0; +mbedtls_ccm_encrypt_and_tag = 0x40002ba4; +mbedtls_ccm_auth_decrypt = 0x40002ba8; +mbedtls_md5_init = 0x40002bd8; +mbedtls_md5_free = 0x40002bdc; +mbedtls_md5_clone = 0x40002be0; +mbedtls_md5_starts = 0x40002be4; +mbedtls_md5_update = 0x40002be8; +mbedtls_md5_finish = 0x40002bec; +mbedtls_internal_md5_process = 0x40002bf0; +mbedtls_md5 = 0x40002bf4; +mbedtls_sha1 = 0x40002c08; /* Data (.data, .bss, .rodata) */ +mbedtls_rom_osi_funcs_ptr = 0x3fcdfaa0; +AES_FSb_ptr = 0x3fcdfa9c; +AES_RT0_ptr = 0x3fcdfa98; +AES_RT1_ptr = 0x3fcdfa94; +AES_RT2_ptr = 0x3fcdfa90; +AES_RT3_ptr = 0x3fcdfa8c; +AES_FT0_ptr = 0x3fcdfa88; +AES_FT1_ptr = 0x3fcdfa84; +AES_FT2_ptr = 0x3fcdfa80; +AES_FT3_ptr = 0x3fcdfa7c; +bignum_small_prime_ptr = 0x3fcdfa78; +sha512_K_ptr = 0x3fcdfa74; diff --git a/components/esp_rom/esp32c3/Kconfig.soc_caps.in b/components/esp_rom/esp32c3/Kconfig.soc_caps.in index 03b25e62ee..80335147d3 100644 --- a/components/esp_rom/esp32c3/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32c3/Kconfig.soc_caps.in @@ -35,6 +35,10 @@ config ESP_ROM_HAS_ERASE_0_REGION_BUG bool default y +config ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV + bool + default y + config ESP_ROM_GET_CLK_FREQ bool default y diff --git a/components/esp_rom/esp32c3/esp_rom_caps.h b/components/esp_rom/esp32c3/esp_rom_caps.h index 8ff06b7601..4173bc2888 100644 --- a/components/esp_rom/esp32c3/esp_rom_caps.h +++ b/components/esp_rom/esp32c3/esp_rom_caps.h @@ -14,6 +14,7 @@ #define ESP_ROM_USB_SERIAL_DEVICE_NUM (3) // UART uses USB_SERIAL_JTAG port in ROM. #define ESP_ROM_HAS_RETARGETABLE_LOCKING (1) // ROM was built with retargetable locking #define ESP_ROM_HAS_ERASE_0_REGION_BUG (1) // ROM has esp_flash_erase_region(size=0) bug +#define ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV (1) // `esp_flash_write_encrypted` in ROM has bug. #define ESP_ROM_GET_CLK_FREQ (1) // Get clk frequency with rom function `ets_get_cpu_frequency` #define ESP_ROM_NEEDS_SWSETUP_WORKAROUND (1) // ROM uses 32-bit time_t. A workaround is required to prevent printf functions from crashing #define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld index d1b71e56b2..3568b2d6e8 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld @@ -3,11 +3,11 @@ ESP32C3 ECO3 ROM address table Version 3 API's imported from the ROM */ -esf_buf_alloc_dynamic = 0x400015c0; -esf_buf_recycle = 0x400015c4; +/*esf_buf_alloc_dynamic = 0x400015c0;*/ +/*esf_buf_recycle = 0x400015c4;*/ /*lmacTxDone = 0x4000162c;*/ /*ppMapTxQueue = 0x400016d8;*/ -rcGetSched = 0x40001764; +/*rcGetSched = 0x40001764;*/ wDevCheckBlockError = 0x400017b4; /*ppProcTxDone = 0x40001804;*/ /*sta_input = rom_sta_input;*/ @@ -55,26 +55,16 @@ r_lld_ext_adv_dynamic_pti_get = 0x40001b40; r_lld_ext_adv_dynamic_aux_pti_process = 0x40001b44; r_lld_ext_adv_dynamic_pti_process = 0x40001b48; r_lld_adv_ext_pkt_prepare_set = 0x40001b4c; -/* -r_lld_adv_ext_chain_none_construct = 0x40001b50; -*/ r_lld_adv_ext_chain_connectable_construct = 0x40001b54; -/* -r_lld_adv_ext_chain_scannable_construct = 0x40001b58; -*/ r_lld_adv_pkt_rx_connect_post = 0x40001b5c; r_lld_adv_start_init_evt_param = 0x40001b60; r_lld_adv_start_set_cs = 0x40001b64; -r_lld_adv_start_update_filter_policy = 0x40001b68; +/* r_lld_adv_start_update_filter_policy = 0x40001b68; */ r_lld_adv_start_schedule_asap = 0x40001b6c; r_lld_con_tx_prog_new_packet_coex = 0x40001b70; -/* -r_lld_con_tx_prog_new_packet = 0x40001b74; -*/ r_lld_per_adv_dynamic_pti_get = 0x40001b78; r_lld_per_adv_evt_start_chm_upd = 0x40001b7c; r_lld_ext_scan_dynamic_pti_get = 0x40001b80; -r_lld_scan_try_sched = 0x40001b84; r_lld_sync_insert = 0x40001b88; r_sch_prog_ble_push = 0x40001b8c; r_sch_prog_bt_push = 0x40001b90; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld new file mode 100644 index 0000000000..893c20604a --- /dev/null +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld @@ -0,0 +1,241 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +esf_buf_alloc = 0x400015bc; +esf_buf_alloc_dynamic = 0x400015c0; +esf_buf_recycle = 0x400015c4; +/*hal_mac_tx_set_ppdu = 0x400015d4;*/ +ic_mac_deinit = 0x400015dc; +lmacDiscardMSDU = 0x400015f4; +/*lmacSetTxFrame = 0x40001628;*/ +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; +pm_rx_beacon_process = 0x40001690; +pm_rx_data_process = 0x40001694; +/* pm_sleep = 0x40001698;*/ +/* pm_tbtt_process = 0x400016a0;*/ +ppMapTxQueue = 0x400016d8; +ppProcTxSecFrame = 0x400016dc; +/*ppRxFragmentProc = 0x40001704;*/ +/* rcGetSched = 0x40001764;*/ +rcTxUpdatePer = 0x40001770; +rcUpdateTxDone = 0x4000177c; +wDevCheckBlockError = 0x400017b4; +/* wDev_IndicateFrame = 0x400017c8;*/ +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; +ieee80211_decap = 0x400018a0; +/*coex_core_timer_idx_get = 0x400018d0;*/ +rom1_chip_i2c_readReg = 0x40001924; +rom1_chip_i2c_writeReg = 0x40001928; +rom_index_to_txbbgain = 0x40001964; +rom_pbus_xpd_tx_on = 0x400019b0; +rom1_set_noise_floor = 0x400019e8; +rom_set_tx_dig_gain = 0x400019f0; +rom_set_txcap_reg = 0x400019f4; +rom_txbbgain_to_index = 0x40001a0c; +rom1_disable_wifi_agc = 0x40001a1c; +rom1_enable_wifi_agc = 0x40001a20; +rom1_tx_paon_set = 0x40001a44; +rom_agc_reg_init = 0x40001a54; +rom_bb_reg_init = 0x40001a58; +rom1_set_pbus_reg = 0x40001a70; +rom_phy_xpd_rf = 0x40001a78; +rom_write_txrate_power_offset = 0x40001a8c; +rom1_get_rate_fcc_index = 0x40001a90; +rom1_read_sar2_code = 0x40001aa4; +rom2_temp_to_power1 = 0x40001ab4; +rom1_get_i2c_hostid = 0x40001ac8; +rom_open_i2c_xpd = 0x40001af8; +rom2_tsens_read_init1 = 0x40001b00; +rom_tsens_code_read = 0x40001b04; +rom_tsens_dac_cal = 0x40001b10; +rom1_phy_en_hw_set_freq = 0x40001b20; +rom1_phy_dis_hw_set_freq = 0x40001b24; +rom_pll_vol_cal = 0x40001b28; + +rom1_bt_get_tx_gain = 0x40001bb8; +rom1_get_chan_target_power = 0x40001bbc; +rom2_get_tx_gain_value1 = 0x40001bc0; +rom1_wifi_tx_dig_gain = 0x40001bc4; +rom1_wifi_get_tx_gain = 0x40001bc8; +rom1_fe_i2c_reg_renew = 0x40001bcc; +rom1_i2c_master_reset = 0x40001bd4; +rom1_phy_wakeup_init = 0x40001bf0; +rom1_phy_i2c_init1 = 0x40001bf4; +rom1_tsens_temp_read = 0x40001bf8; +rom1_bt_track_pll_cap = 0x40001bfc; +rom1_wifi_set_tx_gain = 0x40001c04; +rom1_txpwr_cal_track = 0x40001c08; +rom1_bt_set_tx_gain = 0x40001c10; +rom1_phy_close_rf = 0x40001c18; + + +/*************************************** + Group eco7_uart + ***************************************/ + +/* Functions */ +uart_tx_switch = 0x40001c44; + + +/*************************************** + Group eco7_bluetooth + ***************************************/ + +/* Functions */ +r_lld_con_count_get = 0x40001c48; +r_lld_update_con_offset = 0x40001c4c; +r_lld_con_update_last_clock = 0x40001c50; +r_lld_con_llcp_ind_info_clear = 0x40001c54; +r_lld_con_update_terminte_info_init = 0x40001c58; +r_lld_con_terminate_max_evt_update = 0x40001c5c; +r_llc_pref_param_compute_eco = 0x40001ce8; +r_llc_hci_con_upd_info_send_eco = 0x40001cec; +r_llc_rem_encrypt_proc_continue_eco = 0x40001cf0; +r_llc_start_eco = 0x40001cf8; +r_lld_ext_adv_dynamic_aux_pti_process_eco = 0x40001cfc; +r_lld_adv_start_eco = 0x40001d04; +r_lld_con_evt_canceled_cbk_eco = 0x40001d08; +r_lld_con_evt_time_update_eco = 0x40001d0c; +r_lld_con_start_eco = 0x40001d10; +r_lld_con_frm_isr_eco = 0x40001d14; +r_lld_con_tx_eco = 0x40001d18; +r_lld_ext_scan_dynamic_pti_process_eco = 0x40001d28; +r_lld_scan_frm_eof_isr_eco = 0x40001d2c; +r_lld_sync_start_eco = 0x40001d30; +r_lld_sync_insert_eco = 0x40001d34; +r_llm_adv_rep_flow_control_update_eco = 0x40001d38; +r_llm_env_adv_dup_filt_init_eco = 0x40001d3c; +r_llm_env_adv_dup_filt_deinit_eco = 0x40001d40; +r_llm_adv_rep_flow_control_check_eco = 0x40001d44; +r_llm_scan_start_eco = 0x40001d48; +r_llm_update_duplicate_scan_count = 0x40001d4c; +r_llc_hci_command_handler_pre = 0x40001d50; +r_llc_hci_command_handler_get = 0x40001d54; +r_llc_hci_command_handler_search = 0x40001d58; +r_llc_llcp_pdu_handler_get_overwrite = 0x40001d5c; +r_llc_llcp_pdu_handler_pre = 0x40001d60; +r_llc_llcp_pdu_handler_end = 0x40001d64; +r_llc_con_conflict_check = 0x40001d6c; +r_sch_prog_hw_reset_try = 0x40001d70; +r_sch_prog_et_state_reset = 0x40001d74; +r_sch_prog_end_isr_handler = 0x40001d78; +r_sch_plan_conflict_check = 0x40001d7c; +r_rwble_isr_hw_fixed = 0x40001d80; +r_bt_bb_recorrect_is_dead = 0x40001d84; +r_bt_bb_restart_hw_recorrect = 0x40001d88; +r_ke_task_handler_pre = 0x40001da0; +r_ke_task_handler_end = 0x40001da4; +r_lld_scan_frm_skip_isr_eco = 0x40001db0; +r_lld_ext_scan_dynamic_pti_reset = 0x40001db4; +r_llc_rem_phy_upd_proc_continue_eco = 0x40001db8; +r_llm_get_preferred_phys = 0x40001dbc; +r_lld_hw_cca_isr_eco = 0x40001dc0; +r_lld_sw_cca_isr_eco = 0x40001dc4; +r_lld_cca_chan_prn_e = 0x40001dc8; +r_lld_cca_chan_prn_s = 0x40001dcc; +r_lld_cca_chan_sel_remap = 0x40001dd0; +r_lld_cca_chan_sel_1 = 0x40001dd4; +r_lld_cca_chan_sel_2 = 0x40001dd8; +r_lld_cca_set_thresh = 0x40001ddc; +r_lld_cca_con_start = 0x40001de0; +r_lld_cca_con_end = 0x40001de4; +r_lld_cca_chm_restore = 0x40001de8; +r_lld_cca_chan_unused_check = 0x40001dec; +r_lld_cca_chm_update_check = 0x40001df0; +r_lld_cca_busy_mode_handle = 0x40001df4; +r_lld_cca_lbt_handle = 0x40001df8; +r_lld_cca_scst_timeout_check = 0x40001dfc; +r_lld_cca_chan_avl_timeout_check = 0x40001e00; + +r_lld_con_start_hook = 0x40001ca8; + +/* ble Functions eco */ +r_bt_bb_isr = 0x40000b9c; +r_bt_rf_coex_conn_phy_coded_data_time_limit_en_get = 0x40000ba8; +r_bt_rtp_get_txpwr_idx_by_act = 0x40000c00; +r_btdm_task_post = 0x40000c14; +r_btdm_task_post_from_isr = 0x40000c18; +r_btdm_task_recycle = 0x40000c1c; +r_hci_register_vendor_desc_tab = 0x40000d9c; +r_ke_task_schedule = 0x40000e80; +r_llc_hci_command_handler = 0x40000ef0; +r_llc_loc_ch_map_proc_continue = 0x40000f5c; +r_llc_loc_con_upd_proc_continue = 0x40000f60; +r_llc_loc_phy_upd_proc_continue = 0x40000f78; +r_llc_rem_con_upd_proc_continue = 0x40000fb4; +r_lld_con_sched = 0x40001118; +r_lld_con_stop = 0x40001124; +r_lld_llcp_rx_ind_handler = 0x400011b0; +r_lld_per_adv_sched = 0x400011f8; +r_lld_scan_process_pkt_rx_adv_rep = 0x40001284; +r_register_esp_vendor_cmd_handler = 0x40001400; +r_rf_txpwr_cs_get = 0x40001428; +r_rf_txpwr_dbm_get = 0x4000142c; +r_sch_arb_event_start_isr = 0x400014f8; +r_sch_plan_set = 0x40001534; +r_sch_prog_end_isr = 0x40001538; +r_lld_adv_ext_chain_scannable_construct = 0x40001b58; + +r_lld_scan_process_pkt_rx = 0x40001280; +r_llm_le_features_get = 0x400013b0; + +/* ble functions rename */ +r_lld_init_start_hack = 0x400011a4; + +/* ble functions disable */ +/* +r_lld_adv_frm_isr_eco = 0x40001d00; +r_lld_res_list_clear = 0x40004638; +r_lld_res_list_rem = 0x40004680; +r_lld_adv_start_hook = 0x40001c80; +r_lld_con_evt_start_cbk_eco = 0x40001d1c; +r_lld_con_tx_prog_new_packet = 0x40001b74; +r_lld_adv_ext_chain_none_construct = 0x40001b50; +r_llc_llcp_send_eco = 0x40001cf4; +r_llc_llcp_channel_map_ind_ack = 0x40001d68; +r_rwble_isr = 0x40001464; +r_lld_scan_start_eco = 0x40001d24; +r_lld_scan_try_sched_eco = 0x40001dac; +r_lld_scan_start_hook = 0x40001c74; +r_lld_init_start_hook = 0x40001cb8; +r_lld_scan_evt_start_cbk_eco = 0x40001d20; +r_ke_task_handler_get_overwrite = 0x40001da8; +*/ + + +/*************************************** + Group eco7_phy + ***************************************/ + +/* Functions */ +rom2_pll_cap_mem_update = 0x40001e04; +rom2_phy_i2c_enter_critical = 0x40001e08; +rom2_phy_i2c_exit_critical = 0x40001e0c; +rom2_rfpll_cap_correct = 0x40001e10; +rom2_write_pll_cap = 0x40001e14; +rom2_read_pll_cap = 0x40001e18; +rom2_tester_wifi_cali = 0x40001e1c; +rom2_wait_hw_freq_busy = 0x40001e20; +rom2_rfpll_cap_track = 0x40001e24; +rom2_ulp_code_track = 0x40001e28; +rom2_ulp_ext_code_set = 0x40001e2c; +rom2_phy_set_tsens_power = 0x40001e30; +rom2_phy_get_tsens_value = 0x40001e34; +rom_mac_tx_chan_offset = 0x40001e38; +rom_rx_gain_force = 0x40001e3c; diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index 49d887783f..ba38ae9609 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -703,14 +703,8 @@ r_ble_util_data_rx_buf_reset = 0x40000b8c; r_bt_bb_get_intr_mask = 0x40000b90; r_bt_bb_intr_clear = 0x40000b94; r_bt_bb_intr_mask_set = 0x40000b98; -/* -r_bt_bb_isr = 0x40000b9c; -*/ r_bt_rf_coex_cfg_set = 0x40000ba0; r_bt_rf_coex_conn_dynamic_pti_en_get = 0x40000ba4; -/* -r_bt_rf_coex_conn_phy_coded_data_time_limit_en_get = 0x40000ba8; -*/ r_bt_rf_coex_ext_adv_dynamic_pti_en_get = 0x40000bac; r_bt_rf_coex_ext_scan_dynamic_pti_en_get = 0x40000bb0; r_bt_rf_coex_legacy_adv_dynamic_pti_en_get = 0x40000bb4; @@ -732,18 +726,10 @@ r_bt_rtp_apply_rule_cs_fmt = 0x40000bf0; r_bt_rtp_apply_rule_cs_idx = 0x40000bf4; r_bt_rtp_deregister_rule_cs_fmt = 0x40000bf8; r_bt_rtp_deregister_rule_cs_idx = 0x40000bfc; -/* -r_bt_rtp_get_txpwr_idx_by_act = 0x40000c00; -*/ r_bt_rtp_init = 0x40000c04; r_bt_rtp_register_rule_cs_fmt = 0x40000c08; r_bt_rtp_register_rule_cs_idx = 0x40000c0c; r_btdm_isr = 0x40000c10; -/* -r_btdm_task_post = 0x40000c14; -r_btdm_task_post_from_isr = 0x40000c18; -r_btdm_task_recycle = 0x40000c1c; -*/ r_cali_phase_match_p = 0x40000c20; r_cmp_abs_time = 0x40000c24; r_cmp_dest_id = 0x40000c28; @@ -839,9 +825,6 @@ r_hci_look_for_evt_desc = 0x40000d8c; r_hci_look_for_le_evt_desc = 0x40000d90; r_hci_look_for_le_evt_desc_esp = 0x40000d94; r_hci_pack_bytes = 0x40000d98; -/* -r_hci_register_vendor_desc_tab = 0x40000d9c; -*/ r_hci_send_2_controller = 0x40000da0; r_hci_send_2_host = 0x40000da4; r_hci_tl_c2h_data_flow_on = 0x40000da8; @@ -898,9 +881,6 @@ r_ke_task_handler_get = 0x40000e70; r_ke_task_init = 0x40000e74; r_ke_task_msg_flush = 0x40000e78; r_ke_task_saved_update = 0x40000e7c; -/* -r_ke_task_schedule = 0x40000e80; -*/ r_ke_time = 0x40000e84; r_ke_time_cmp = 0x40000e88; r_ke_time_past = 0x40000e8c; @@ -928,9 +908,6 @@ r_llc_dl_chg_check = 0x40000ee0; r_llc_dle_proc_err_cb = 0x40000ee4; r_llc_feats_exch_proc_err_cb = 0x40000ee8; r_llc_hci_cmd_handler_tab_p_get = 0x40000eec; -/* -r_llc_hci_command_handler = 0x40000ef0; -*/ r_llc_hci_con_param_req_evt_send = 0x40000ef4; r_llc_hci_con_upd_info_send = 0x40000ef8; r_llc_hci_disconnected_dis = 0x40000efc; @@ -945,7 +922,7 @@ r_llc_init_term_proc = 0x40000f1c; r_llc_iv_skd_rand_gen = 0x40000f20; r_llc_le_ping_proc_continue = 0x40000f24; r_llc_le_ping_proc_err_cb = 0x40000f28; -r_llc_le_ping_restart = 0x40000f2c; +/* r_llc_le_ping_restart = 0x40000f2c; */ r_llc_le_ping_set = 0x40000f30; r_llc_ll_pause_enc_rsp_ack_handler = 0x40000f34; r_llc_ll_reject_ind_ack_handler = 0x40000f38; @@ -957,16 +934,11 @@ r_llc_llcp_send = 0x40000f4c; r_llc_llcp_state_set = 0x40000f50; r_llc_llcp_trans_timer_set = 0x40000f54; r_llc_llcp_tx_check = 0x40000f58; -r_llc_loc_ch_map_proc_continue = 0x40000f5c; -/* -r_llc_loc_con_upd_proc_continue = 0x40000f60; -*/ r_llc_loc_con_upd_proc_err_cb = 0x40000f64; r_llc_loc_dl_upd_proc_continue = 0x40000f68; r_llc_loc_encrypt_proc_continue = 0x40000f6c; r_llc_loc_encrypt_proc_err_cb = 0x40000f70; r_llc_loc_feats_exch_proc_continue = 0x40000f74; -r_llc_loc_phy_upd_proc_continue = 0x40000f78; r_llc_loc_phy_upd_proc_err_cb = 0x40000f7c; r_llc_msg_handler_tab_p_get = 0x40000f80; r_llc_pref_param_compute = 0x40000f84; @@ -981,9 +953,6 @@ r_llc_proc_timer_pause_set = 0x40000fa4; r_llc_proc_timer_set = 0x40000fa8; r_llc_proc_unreg = 0x40000fac; r_llc_rem_ch_map_proc_continue = 0x40000fb0; -/* -r_llc_rem_con_upd_proc_continue = 0x40000fb4; -*/ r_llc_rem_con_upd_proc_err_cb = 0x40000fb8; r_llc_rem_dl_upd_proc = 0x40000fbc; r_llc_rem_encrypt_proc_continue = 0x40000fc0; @@ -1066,20 +1035,14 @@ r_lld_con_pref_slave_evt_dur_set = 0x400010f0; r_lld_con_pref_slave_latency_set = 0x400010f4; r_lld_con_rssi_get = 0x400010f8; r_lld_con_rx = 0x400010fc; -r_lld_con_rx_channel_assess = 0x40001100; +/* r_lld_con_rx_channel_assess = 0x40001100; */ r_lld_con_rx_enc = 0x40001104; r_lld_con_rx_isr = 0x40001108; r_lld_con_rx_link_info_check = 0x4000110c; r_lld_con_rx_llcp_check = 0x40001110; r_lld_con_rx_sync_time_update = 0x40001114; -/* -r_lld_con_sched = 0x40001118; -*/ r_lld_con_set_tx_power = 0x4000111c; r_lld_con_start = 0x40001120; -/* -r_lld_con_stop = 0x40001124; -*/ r_lld_con_tx = 0x40001128; r_lld_con_tx_enc = 0x4000112c; r_lld_con_tx_isr = 0x40001130; @@ -1114,9 +1077,6 @@ r_lld_init_set_tx_power = 0x400011a0; r_lld_init_start = 0x400011a4; r_lld_init_stop = 0x400011a8; r_lld_instant_proc_end = 0x400011ac; -/* -r_lld_llcp_rx_ind_handler = 0x400011b0; -*/ r_lld_per_adv_ch_map_update = 0x400011b4; r_lld_per_adv_chain_construct = 0x400011b8; r_lld_per_adv_cleanup = 0x400011bc; @@ -1134,9 +1094,6 @@ r_lld_per_adv_init = 0x400011e8; r_lld_per_adv_init_info_get = 0x400011ec; r_lld_per_adv_list_add = 0x400011f0; r_lld_per_adv_list_rem = 0x400011f4; -/* -r_lld_per_adv_sched = 0x400011f8; -*/ r_lld_per_adv_set_tx_power = 0x400011fc; r_lld_per_adv_start = 0x40001200; r_lld_per_adv_stop = 0x40001204; @@ -1145,13 +1102,11 @@ r_lld_process_cca_data = 0x4000120c; r_lld_ral_search = 0x40001210; r_lld_read_clock = 0x40001214; r_lld_res_list_add = 0x40001218; -r_lld_res_list_clear = 0x4000121c; r_lld_res_list_is_empty = 0x40001220; r_lld_res_list_local_rpa_get = 0x40001224; r_lld_res_list_peer_rpa_get = 0x40001228; r_lld_res_list_peer_update = 0x4000122c; -r_lld_res_list_priv_mode_update = 0x40001230; -r_lld_res_list_rem = 0x40001234; +/* r_lld_res_list_priv_mode_update = 0x40001230; */ r_lld_reset_reg = 0x40001238; r_lld_rpa_renew = 0x4000123c; r_lld_rpa_renew_evt_canceled_cbk = 0x40001240; @@ -1170,10 +1125,6 @@ r_lld_scan_frm_rx_isr = 0x40001270; r_lld_scan_frm_skip_isr = 0x40001274; r_lld_scan_init = 0x40001278; r_lld_scan_params_update = 0x4000127c; -/* -r_lld_scan_process_pkt_rx = 0x40001280; -r_lld_scan_process_pkt_rx_adv_rep = 0x40001284; -*/ r_lld_scan_process_pkt_rx_aux_adv_ind = 0x40001288; r_lld_scan_process_pkt_rx_aux_chain_ind = 0x4000128c; r_lld_scan_process_pkt_rx_aux_scan_rsp = 0x40001290; @@ -1217,7 +1168,7 @@ r_lld_test_init = 0x40001324; r_lld_test_rx_isr = 0x40001328; r_lld_test_set_tx_power = 0x4000132c; r_lld_test_start = 0x40001330; -r_lld_test_stop = 0x40001334; +/* r_lld_test_stop = 0x40001334; */ r_lld_update_rxbuf = 0x40001338; r_lld_update_rxbuf_isr = 0x4000133c; r_lld_white_list_add = 0x40001340; @@ -1248,9 +1199,6 @@ r_llm_is_dev_synced = 0x400013a0; r_llm_is_non_con_act_ongoing_check = 0x400013a4; r_llm_is_wl_accessible = 0x400013a8; r_llm_le_evt_mask_check = 0x400013ac; -/* -r_llm_le_features_get = 0x400013b0; -*/ r_llm_link_disc = 0x400013b4; r_llm_master_ch_map_get = 0x400013b8; r_llm_msg_handler_tab_p_get = 0x400013bc; @@ -1270,9 +1218,6 @@ r_misc_msg_handler_tab_p_get = 0x400013f0; r_notEqual256 = 0x400013f4; r_phy_upd_proc_start = 0x400013f8; r_platform_reset = 0x400013fc; -/* -r_register_esp_vendor_cmd_handler = 0x40001400; -*/ r_rf_em_init = 0x40001404; r_rf_force_agc_enable = 0x40001408; r_rf_reg_rd = 0x4000140c; @@ -1282,10 +1227,6 @@ r_rf_rssi_convert = 0x40001418; r_rf_rw_v9_le_disable = 0x4000141c; r_rf_rw_v9_le_enable = 0x40001420; r_rf_sleep = 0x40001424; -/* -r_rf_txpwr_cs_get = 0x40001428; -r_rf_txpwr_dbm_get = 0x4000142c; -*/ r_rf_util_cs_fmt_convert = 0x40001430; r_rw_crypto_aes_ccm = 0x40001434; r_rw_crypto_aes_encrypt = 0x40001438; @@ -1299,15 +1240,12 @@ r_rw_crypto_aes_result_handler = 0x40001454; r_rw_crypto_aes_s1 = 0x40001458; r_rw_cryto_aes_cmac = 0x4000145c; r_rw_v9_init_em_radio_table = 0x40001460; -/* -r_rwble_isr = 0x40001464; -*/ r_rwble_sleep_enter = 0x40001468; r_rwble_sleep_wakeup_end = 0x4000146c; -r_rwbtdm_isr_wrapper = 0x40001470; +/* r_rwbtdm_isr_wrapper = 0x40001470; */ r_rwip_active_check = 0x40001474; r_rwip_aes_encrypt = 0x40001478; -r_rwip_assert = 0x4000147c; +/* r_rwip_assert = 0x4000147c; */ r_rwip_crypt_evt_handler = 0x40001480; r_rwip_crypt_isr_handler = 0x40001484; r_rwip_eif_get = 0x40001488; @@ -1329,7 +1267,7 @@ r_rwip_timer_hs_set = 0x400014c4; r_rwip_timer_hus_handler = 0x400014c8; r_rwip_timer_hus_set = 0x400014cc; r_rwip_wakeup = 0x400014d0; -r_rwip_wakeup_end = 0x400014d4; +/* r_rwip_wakeup_end = 0x400014d4; */ r_rwip_wlcoex_set = 0x400014d8; r_sch_alarm_clear = 0x400014dc; r_sch_alarm_init = 0x400014e0; @@ -1338,9 +1276,6 @@ r_sch_alarm_set = 0x400014e8; r_sch_alarm_timer_isr = 0x400014ec; r_sch_arb_conflict_check = 0x400014f0; r_sch_arb_elt_cancel = 0x400014f4; -/* -r_sch_arb_event_start_isr = 0x400014f8; -*/ r_sch_arb_init = 0x400014fc; r_sch_arb_insert = 0x40001500; r_sch_arb_prog_timer = 0x40001504; @@ -1355,10 +1290,6 @@ r_sch_plan_offset_req = 0x40001524; r_sch_plan_position_range_compute = 0x40001528; r_sch_plan_rem = 0x4000152c; r_sch_plan_req = 0x40001530; -/* -r_sch_plan_set = 0x40001534; -r_sch_prog_end_isr = 0x40001538; -*/ r_sch_prog_init = 0x4000153c; r_sch_prog_push = 0x40001540; r_sch_prog_rx_isr = 0x40001544; @@ -1537,14 +1468,8 @@ r_llc_loc_phy_upd_proc_continue_hook = 0x40001c64; r_llc_rem_phy_upd_proc_continue_hook = 0x40001c68; r_lld_scan_frm_eof_isr_hook = 0x40001c6c; r_lld_scan_evt_start_cbk_hook = 0x40001c70; -/* -r_lld_scan_start_hook = 0x40001c74; -*/ r_lld_scan_process_pkt_rx_ext_adv_hook = 0x40001c78; r_lld_scan_sched_hook = 0x40001c7c; -/* -r_lld_adv_start_hook = 0x40001c80; -*/ r_lld_adv_evt_start_cbk_hook = 0x40001c84; r_lld_adv_aux_evt_start_cbk_hook = 0x40001c88; r_lld_adv_frm_isr_hook = 0x40001c8c; @@ -1554,15 +1479,9 @@ r_lld_con_frm_isr_hook = 0x40001c98; r_lld_con_tx_hook = 0x40001c9c; r_lld_con_rx_hook = 0x40001ca0; r_lld_con_evt_start_cbk_hook = 0x40001ca4; -/* -r_lld_con_start_hook = 0x40001ca8; -*/ r_lld_con_tx_prog_new_packet_hook = 0x40001cac; r_lld_init_frm_eof_isr_hook = 0x40001cb0; r_lld_init_evt_start_cbk_hook = 0x40001cb4; -/* -r_lld_init_start_hook = 0x40001cb8; -*/ r_lld_init_sched_hook = 0x40001cbc; r_lld_init_process_pkt_tx_hook = 0x40001cc0; r_lld_per_adv_evt_start_cbk_hook = 0x40001cc4; @@ -1583,7 +1502,7 @@ r_sch_plan_offset_req_hook = 0x40001ce4; esp_pp_rom_version_get = 0x400015b0; RC_GetBlockAckTime = 0x400015b4; ebuf_list_remove = 0x400015b8; -esf_buf_alloc = 0x400015bc; +/*esf_buf_alloc = 0x400015bc;*/ GetAccess = 0x400015c8; hal_mac_is_low_rate_enabled = 0x400015cc; hal_mac_tx_get_blockack = 0x400015d0; @@ -1593,13 +1512,13 @@ ic_get_trc = 0x400015d8; ic_mac_init = 0x400015e0; ic_interface_enabled = 0x400015e4; is_lmac_idle = 0x400015e8; -lmacAdjustTimestamp = 0x400015ec; +/*lmacAdjustTimestamp = 0x400015ec;*/ lmacDiscardAgedMSDU = 0x400015f0; /*lmacDiscardMSDU = 0x400015f4;*/ -lmacEndFrameExchangeSequence = 0x400015f8; +/*lmacEndFrameExchangeSequence = 0x400015f8;*/ lmacIsIdle = 0x400015fc; lmacIsLongFrame = 0x40001600; -lmacMSDUAged = 0x40001604; +/*lmacMSDUAged = 0x40001604;*/ lmacPostTxComplete = 0x40001608; lmacProcessAllTxTimeout = 0x4000160c; lmacProcessCollisions = 0x40001610; @@ -1615,10 +1534,10 @@ 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; +/*pm_dream = 0x40001654;*/ pm_mac_wakeup = 0x40001658; pm_mac_sleep = 0x4000165c; pm_enable_active_timer = 0x40001660; @@ -1639,10 +1558,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; @@ -1661,7 +1580,7 @@ ppRecycleRxPkt = 0x400016f8; ppResortTxAMPDU = 0x400016fc; ppResumeTxAMPDU = 0x40001700; /* ppRxFragmentProc = 0x40001704; */ -ppRxPkt = 0x40001708; +/* ppRxPkt = 0x40001708; */ ppRxProtoProc = 0x4000170c; ppSearchTxQueue = 0x40001710; ppSearchTxframe = 0x40001714; @@ -1671,7 +1590,7 @@ ppTask = 0x40001720; ppTxPkt = 0x40001724; ppTxProtoProc = 0x40001728; ppTxqUpdateBitmap = 0x4000172c; -pp_coex_tx_request = 0x40001730; +/*pp_coex_tx_request = 0x40001730;*/ pp_hdrsize = 0x40001734; pp_post = 0x40001738; pp_process_hmac_waiting_txq = 0x4000173c; @@ -1688,7 +1607,7 @@ rcLowerSched = 0x40001768; rcSetTxAmpduLimit = 0x4000176c; /* rcTxUpdatePer = 0x40001770;*/ rcUpdateAckSnr = 0x40001774; -rcUpdateRate = 0x40001778; +/*rcUpdateRate = 0x40001778;*/ /* rcUpdateTxDone = 0x4000177c; */ rcUpdateTxDoneAmpdu2 = 0x40001780; rcUpSched = 0x40001784; @@ -1703,11 +1622,11 @@ TRC_PER_IS_GOOD = 0x400017a4; trc_SetTxAmpduState = 0x400017a8; trc_tid_isTxAmpduOperational = 0x400017ac; trcAmpduSetState = 0x400017b0; -wDev_AppendRxBlocks = 0x400017b8; +/*wDev_AppendRxBlocks = 0x400017b8;*/ wDev_DiscardFrame = 0x400017bc; wDev_GetNoiseFloor = 0x400017c0; wDev_IndicateAmpdu = 0x400017c4; -wDev_IndicateFrame = 0x400017c8; +/*wDev_IndicateFrame = 0x400017c8;*/ wdev_bank_store = 0x400017cc; wdev_bank_load = 0x400017d0; wdev_mac_reg_load = 0x400017d4; @@ -1718,13 +1637,13 @@ wdev_mac_wakeup = 0x400017e4; wdev_mac_sleep = 0x400017e8; hal_mac_is_dma_enable = 0x400017ec; /*wDev_ProcessFiq = 0x400017f0;*/ -wDev_ProcessRxSucData = 0x400017f4; +/*wDev_ProcessRxSucData = 0x400017f4;*/ wdevProcessRxSucDataAll = 0x400017f8; 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; @@ -1797,19 +1716,19 @@ ic_ebuf_recycle_rx = 0x40001844; ic_ebuf_recycle_tx = 0x40001848; ic_reset_rx_ba = 0x4000184c; ieee80211_align_eb = 0x40001850; -ieee80211_ampdu_reorder = 0x40001854; +/*ieee80211_ampdu_reorder = 0x40001854;*/ ieee80211_ampdu_start_age_timer = 0x40001858; /*ieee80211_encap_esfbuf = 0x4000185c;*/ ieee80211_is_tx_allowed = 0x40001860; ieee80211_output_pending_eb = 0x40001864; -ieee80211_output_process = 0x40001868; +/*ieee80211_output_process = 0x40001868;*/ ieee80211_set_tx_desc = 0x4000186c; rom_sta_input = 0x40001870; wifi_get_macaddr = 0x40001874; wifi_rf_phy_disable = 0x40001878; wifi_rf_phy_enable = 0x4000187c; ic_ebuf_alloc = 0x40001880; -ieee80211_classify = 0x40001884; +/*ieee80211_classify = 0x40001884;*/ ieee80211_copy_eb_header = 0x40001888; ieee80211_recycle_cache_eb = 0x4000188c; ieee80211_search_node = 0x40001890; @@ -1840,7 +1759,7 @@ esp_coex_rom_version_get = 0x400018ac; coex_bt_release = 0x400018b0; coex_bt_request = 0x400018b4; coex_core_ble_conn_dyn_prio_get = 0x400018b8; -coex_core_event_duration_get = 0x400018bc; +/*coex_core_event_duration_get = 0x400018bc;*/ coex_core_pti_get = 0x400018c0; coex_core_release = 0x400018c4; coex_core_request = 0x400018c8; diff --git a/components/esp_rom/esp32c6/Kconfig.soc_caps.in b/components/esp_rom/esp32c6/Kconfig.soc_caps.in index 9e23f349b7..df5e153a0d 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 1ec2d87239..1eeab3bd3e 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.coexist.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.coexist.ld index cec4b9f6e8..5ff011973e 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.coexist.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.coexist.ld @@ -22,12 +22,12 @@ esp_coex_rom_version_get = 0x40000afc; coex_bt_release = 0x40000b00; coex_bt_request = 0x40000b04; coex_core_ble_conn_dyn_prio_get = 0x40000b08; -coex_core_event_duration_get = 0x40000b0c; +/*coex_core_event_duration_get = 0x40000b0c;*/ coex_core_pti_get = 0x40000b10; coex_core_release = 0x40000b14; coex_core_request = 0x40000b18; coex_core_status_get = 0x40000b1c; -coex_core_timer_idx_get = 0x40000b20; +/*coex_core_timer_idx_get = 0x40000b20;*/ coex_event_duration_get = 0x40000b24; coex_hw_timer_disable = 0x40000b28; coex_hw_timer_enable = 0x40000b2c; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld index 1e95388383..bf3d88d66d 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.heap.ld @@ -37,9 +37,7 @@ 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; multi_heap_get_allocated_size_impl = 0x40000458; multi_heap_register_impl = 0x4000045c; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld index 7ce7b8309f..7a73b4d5a7 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.net80211.ld @@ -31,24 +31,24 @@ ic_ebuf_recycle_rx = 0x40000b70; ic_ebuf_recycle_tx = 0x40000b74; ic_reset_rx_ba = 0x40000b78; ieee80211_align_eb = 0x40000b7c; -ieee80211_ampdu_reorder = 0x40000b80; +/*ieee80211_ampdu_reorder = 0x40000b80;*/ ieee80211_ampdu_start_age_timer = 0x40000b84; -ieee80211_encap_esfbuf = 0x40000b88; +/*ieee80211_encap_esfbuf = 0x40000b88;*/ ieee80211_is_tx_allowed = 0x40000b8c; ieee80211_output_pending_eb = 0x40000b90; -ieee80211_output_process = 0x40000b94; +/*ieee80211_output_process = 0x40000b94;*/ ieee80211_set_tx_desc = 0x40000b98; -sta_input = 0x40000b9c; +//sta_input = 0x40000b9c; wifi_get_macaddr = 0x40000ba0; wifi_rf_phy_disable = 0x40000ba4; wifi_rf_phy_enable = 0x40000ba8; ic_ebuf_alloc = 0x40000bac; -ieee80211_classify = 0x40000bb0; +/*ieee80211_classify = 0x40000bb0;*/ 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 cbcf560177..69faa174c1 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.pp.ld @@ -22,7 +22,7 @@ esp_pp_rom_version_get = 0x40000bd8; ppCalTxopRTSThreshold = 0x40000bdc; RC_GetBlockAckTime = 0x40000be0; ebuf_list_remove = 0x40000be4; -esf_buf_alloc = 0x40000be8; +//esf_buf_alloc = 0x40000be8; //esf_buf_alloc_dynamic = 0x40000bec; //esf_buf_recycle = 0x40000bf0; GetAccess = 0x40000bf4; @@ -34,13 +34,13 @@ ic_get_trc = 0x40000c04; ic_mac_init = 0x40000c0c; ic_interface_enabled = 0x40000c10; is_lmac_idle = 0x40000c14; -lmacAdjustTimestamp = 0x40000c18; +/*lmacAdjustTimestamp = 0x40000c18;*/ lmacDiscardAgedMSDU = 0x40000c1c; /*lmacDiscardMSDU = 0x40000c20;*/ -lmacEndFrameExchangeSequence = 0x40000c24; +/*lmacEndFrameExchangeSequence = 0x40000c24;*/ lmacIsIdle = 0x40000c28; lmacIsLongFrame = 0x40000c2c; -lmacMSDUAged = 0x40000c30; +/*lmacMSDUAged = 0x40000c30;*/ lmacPostTxComplete = 0x40000c34; lmacProcessAllTxTimeout = 0x40000c38; lmacProcessCollisions = 0x40000c3c; @@ -56,10 +56,10 @@ 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; +/*pm_dream = 0x40000c7c;*/ pm_mac_wakeup = 0x40000c80; pm_mac_sleep = 0x40000c84; //pm_enable_active_timer = 0x40000c88; @@ -80,7 +80,7 @@ pm_on_data_rx = 0x40000ca8; pm_sleep_for = 0x40000cc4; //pm_tbtt_process = 0x40000cc8; ppAMPDU2Normal = 0x40000ccc; -ppAssembleAMPDU = 0x40000cd0; +/* ppAssembleAMPDU = 0x40000cd0; */ ppCalFrameTimes = 0x40000cd4; ppCalSubFrameLength = 0x40000cd8; //ppCalTxAMPDULength = 0x40000cdc; @@ -100,7 +100,7 @@ ppRecycleAmpdu = 0x40000d10; ppRecycleRxPkt = 0x40000d14; //ppResortTxAMPDU = 0x40000d18; ppResumeTxAMPDU = 0x40000d1c; -ppRxFragmentProc = 0x40000d20; +/*ppRxFragmentProc = 0x40000d20;*/ //ppRxPkt = 0x40000d24; ppRxProtoProc = 0x40000d28; ppSearchTxQueue = 0x40000d2c; @@ -111,7 +111,7 @@ ppSubFromAMPDU = 0x40000d38; //ppTxPkt = 0x40000d40; ppTxProtoProc = 0x40000d44; ppTxqUpdateBitmap = 0x40000d48; -pp_coex_tx_request = 0x40000d4c; +/*pp_coex_tx_request = 0x40000d4c;*/ pp_hdrsize = 0x40000d50; pp_post = 0x40000d54; pp_process_hmac_waiting_txq = 0x40000d58; @@ -124,12 +124,12 @@ rcampduuprate = 0x40000d70; rcClearCurAMPDUSched = 0x40000d74; rcClearCurSched = 0x40000d78; rcClearCurStat = 0x40000d7c; -rcGetSched = 0x40000d80; +/*rcGetSched = 0x40000d80;*/ rcLowerSched = 0x40000d84; rcSetTxAmpduLimit = 0x40000d88; rcTxUpdatePer = 0x40000d8c; rcUpdateAckSnr = 0x40000d90; -rcUpdateRate = 0x40000d94; +/*rcUpdateRate = 0x40000d94;*/ rcUpdateTxDone = 0x40000d98; rcUpdateTxDoneAmpdu2 = 0x40000d9c; rcUpSched = 0x40000da0; @@ -144,12 +144,12 @@ TRC_PER_IS_GOOD = 0x40000dc0; trc_SetTxAmpduState = 0x40000dc4; trc_tid_isTxAmpduOperational = 0x40000dc8; trcAmpduSetState = 0x40000dcc; -wDevCheckBlockError = 0x40000dd0; -wDev_AppendRxBlocks = 0x40000dd4; +//wDevCheckBlockError = 0x40000dd0; +/*wDev_AppendRxBlocks = 0x40000dd4;*/ wDev_DiscardFrame = 0x40000dd8; wDev_GetNoiseFloor = 0x40000ddc; wDev_IndicateAmpdu = 0x40000de0; -wDev_IndicateFrame = 0x40000de4; +//wDev_IndicateFrame = 0x40000de4; wdev_mac_reg_load = 0x40000de8; wdev_mac_reg_store = 0x40000dec; wdev_mac_special_reg_load = 0x40000df0; @@ -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; @@ -274,7 +274,7 @@ tsf_hal_set_tbtt_rf_ctrl_enable = 0x40000fc8; tsf_hal_set_tbtt_rf_ctrl_wait_cycles = 0x40000fcc; tsf_hal_set_tbtt_soc_wakeup_disable = 0x40000fd0; tsf_hal_set_tbtt_soc_wakeup_enable = 0x40000fd4; -tsf_hal_set_tbtt_start_time = 0x40000fd8; +/*tsf_hal_set_tbtt_start_time = 0x40000fd8;*/ tsf_hal_set_time = 0x40000fdc; tsf_hal_set_timer_disable = 0x40000fe0; tsf_hal_set_timer_enable = 0x40000fe4; diff --git a/components/esp_rom/esp32h2/Kconfig.soc_caps.in b/components/esp_rom/esp32h2/Kconfig.soc_caps.in index a5b8f87971..fcc820480e 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 @@ -55,6 +59,10 @@ config ESP_ROM_HAS_NEWLIB_NANO_FORMAT bool default y +config ESP_ROM_HAS_NEWLIB_NANO_PRINTF_FLOAT_BUG + bool + default y + config ESP_ROM_WDT_INIT_PATCH bool default y diff --git a/components/esp_rom/esp32h2/esp_rom_caps.h b/components/esp_rom/esp32h2/esp_rom_caps.h index 321ab91b8e..bfbf47f3c3 100644 --- a/components/esp_rom/esp32h2/esp_rom_caps.h +++ b/components/esp_rom/esp32h2/esp_rom_caps.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,10 +15,12 @@ #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 #define ESP_ROM_HAS_NEWLIB_NANO_FORMAT (1) // ROM has the newlib nano versions of formatting functions +#define ESP_ROM_HAS_NEWLIB_NANO_PRINTF_FLOAT_BUG (1) // ROM has the printf float bug with newlib nano version #define ESP_ROM_WDT_INIT_PATCH (1) // ROM version does not configure the clock #define ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE (1) // ROM needs to set cache MMU size according to instruction and rodata for flash mmap #define ESP_ROM_RAM_APP_NEEDS_MMU_INIT (1) // ROM doesn't init cache MMU when it's a RAM APP, needs MMU hal to init diff --git a/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld b/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld index 3e17e87eba..f57567beb8 100644 --- a/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld +++ b/components/esp_rom/esp32h2/ld/esp32h2.rom.heap.ld @@ -37,9 +37,7 @@ 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; multi_heap_get_allocated_size_impl = 0x40000450; multi_heap_register_impl = 0x40000454; diff --git a/components/esp_rom/esp32s2/Kconfig.soc_caps.in b/components/esp_rom/esp32s2/Kconfig.soc_caps.in index d399b8c5cb..f94ca745ae 100644 --- a/components/esp_rom/esp32s2/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32s2/Kconfig.soc_caps.in @@ -30,3 +30,7 @@ config ESP_ROM_HAS_NEWLIB_NANO_FORMAT config ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG bool default y + +config ESP_ROM_USB_OTG_NUM + int + default 3 diff --git a/components/esp_rom/esp32s2/esp_rom_caps.h b/components/esp_rom/esp32s2/esp_rom_caps.h index 0657e446c0..2261d70b57 100644 --- a/components/esp_rom/esp32s2/esp_rom_caps.h +++ b/components/esp_rom/esp32s2/esp_rom_caps.h @@ -13,3 +13,4 @@ #define ESP_ROM_HAS_REGI2C_BUG (1) // ROM has the regi2c bug #define ESP_ROM_HAS_NEWLIB_NANO_FORMAT (1) // ROM has the newlib nano version of formatting functions #define ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG (1) // ROM api Cache_Count_Flash_Pages will return unexpected value +#define ESP_ROM_USB_OTG_NUM (3) // The serial port ID (UART, USB, ...) of USB_OTG CDC in the ROM. diff --git a/components/esp_rom/esp32s2/usb_descriptors.c b/components/esp_rom/esp32s2/usb_patches.c similarity index 76% rename from components/esp_rom/esp32s2/usb_descriptors.c rename to components/esp_rom/esp32s2/usb_patches.c index 279930095d..978c9b1f78 100644 --- a/components/esp_rom/esp32s2/usb_descriptors.c +++ b/components/esp_rom/esp32s2/usb_patches.c @@ -65,3 +65,19 @@ void rom_usb_cdc_set_descriptor_patch(void) /* Override the pointer to descriptors structure */ rom_usb_curr_desc = &s_acm_usb_descriptors_override; } + +/* On ESP32-S2, ROM doesn't provide interfaces to clear usb_dev and usb_dw_ctrl structures. + * Starting from ESP32-S3, usb_dev_deinit and usb_dw_ctrl_deinit ROM functions are available. + * Here we implement the missing functionality for the ESP32-S2. + */ +void usb_dev_deinit(void) +{ + extern char rom_usb_dev, rom_usb_dev_end; + memset((void *) &rom_usb_dev, 0, &rom_usb_dev_end - &rom_usb_dev); +} + +void usb_dw_ctrl_deinit(void) +{ + extern char rom_usb_dw_ctrl, rom_usb_dw_ctrl_end; + memset((void *) &rom_usb_dw_ctrl, 0, &rom_usb_dw_ctrl_end - &rom_usb_dw_ctrl); +} diff --git a/components/esp_rom/esp32s3/Kconfig.soc_caps.in b/components/esp_rom/esp32s3/Kconfig.soc_caps.in index 3d19266070..d6b5eeeade 100644 --- a/components/esp_rom/esp32s3/Kconfig.soc_caps.in +++ b/components/esp_rom/esp32s3/Kconfig.soc_caps.in @@ -27,6 +27,10 @@ config ESP_ROM_HAS_RETARGETABLE_LOCKING bool default y +config ESP_ROM_USB_OTG_NUM + int + default 3 + config ESP_ROM_USB_SERIAL_DEVICE_NUM int default 4 @@ -35,6 +39,10 @@ config ESP_ROM_HAS_ERASE_0_REGION_BUG bool default y +config ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV + bool + default y + config ESP_ROM_GET_CLK_FREQ bool default y @@ -78,3 +86,7 @@ config ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG config ESP_ROM_HAS_CACHE_SUSPEND_WAITI_BUG bool default y + +config ESP_ROM_HAS_CACHE_WRITEBACK_BUG + bool + default y diff --git a/components/esp_rom/esp32s3/esp_rom_caps.h b/components/esp_rom/esp32s3/esp_rom_caps.h index f960c350bb..a45b21e6ae 100644 --- a/components/esp_rom/esp32s3/esp_rom_caps.h +++ b/components/esp_rom/esp32s3/esp_rom_caps.h @@ -12,8 +12,10 @@ #define ESP_ROM_HAS_JPEG_DECODE (1) // ROM has JPEG decode library #define ESP_ROM_UART_CLK_IS_XTAL (1) // UART clock source is selected to XTAL in ROM #define ESP_ROM_HAS_RETARGETABLE_LOCKING (1) // ROM was built with retargetable locking +#define ESP_ROM_USB_OTG_NUM (3) // The serial port ID (UART, USB, ...) of USB_OTG CDC in the ROM. #define ESP_ROM_USB_SERIAL_DEVICE_NUM (4) // The serial port ID (UART, USB, ...) of USB_SERIAL_JTAG in the ROM. #define ESP_ROM_HAS_ERASE_0_REGION_BUG (1) // ROM has esp_flash_erase_region(size=0) bug +#define ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV (1) // `esp_flash_write_encrypted` in ROM has bug. #define ESP_ROM_GET_CLK_FREQ (1) // Get clk frequency with rom function `ets_get_cpu_frequency` #define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver #define ESP_ROM_NEEDS_SWSETUP_WORKAROUND (1) // ROM uses 32-bit time_t. A workaround is required to prevent printf functions from crashing @@ -25,3 +27,4 @@ #define ESP_ROM_RAM_APP_NEEDS_MMU_INIT (1) // ROM doesn't init cache MMU when it's a RAM APP, needs MMU hal to init #define ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG (1) // ROM api Cache_Count_Flash_Pages will return unexpected value #define ESP_ROM_HAS_CACHE_SUSPEND_WAITI_BUG (1) // ROM api Cache_Suspend_I/DCache and Cache_Freeze_I/DCache_Enable does not waiti +#define ESP_ROM_HAS_CACHE_WRITEBACK_BUG (1) // ROM api Cache_WriteBack_Addr access cacheline being writen back may cause cache hit with wrong value. diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index 312343b38f..e561e313d9 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -381,7 +381,7 @@ PROVIDE( Cache_WriteBack_Items = 0x40001698 ); PROVIDE( Cache_Op_Addr = 0x400016a4 ); PROVIDE( Cache_Invalidate_Addr = 0x400016b0 ); PROVIDE( Cache_Clean_Addr = 0x400016bc ); -PROVIDE( Cache_WriteBack_Addr = 0x400016c8 ); +PROVIDE( rom_Cache_WriteBack_Addr = 0x400016c8 ); PROVIDE( Cache_Invalidate_ICache_All = 0x400016d4 ); PROVIDE( Cache_Invalidate_DCache_All = 0x400016e0 ); PROVIDE( Cache_Clean_All = 0x400016ec ); @@ -792,7 +792,7 @@ usb_dfu_force_detach = 0x40002a54; usb_dev_deinit = 0x40002a60; usb_dw_ctrl_deinit = 0x40002a6c; /* Data (.data, .bss, .rodata) */ -s_usb_osglue = 0x3fceffac; +rom_usb_osglue = 0x3fceffac; /*************************************** @@ -976,14 +976,8 @@ r_ble_util_data_rx_buf_reset = 0x40003288; r_bt_bb_get_intr_mask = 0x40003294; r_bt_bb_intr_clear = 0x400032a0; r_bt_bb_intr_mask_set = 0x400032ac; -/* -r_bt_bb_isr = 0x400032b8; -*/ r_bt_rf_coex_cfg_set = 0x400032c4; r_bt_rf_coex_conn_dynamic_pti_en_get = 0x400032d0; -/* -r_bt_rf_coex_conn_phy_coded_data_time_limit_en_get = 0x400032dc; -*/ r_bt_rf_coex_ext_adv_dynamic_pti_en_get = 0x400032e8; r_bt_rf_coex_ext_scan_dynamic_pti_en_get = 0x400032f4; r_bt_rf_coex_legacy_adv_dynamic_pti_en_get = 0x40003300; @@ -1005,18 +999,10 @@ r_bt_rtp_apply_rule_cs_fmt = 0x400033b4; r_bt_rtp_apply_rule_cs_idx = 0x400033c0; r_bt_rtp_deregister_rule_cs_fmt = 0x400033cc; r_bt_rtp_deregister_rule_cs_idx = 0x400033d8; -/* -r_bt_rtp_get_txpwr_idx_by_act = 0x400033e4; -*/ r_bt_rtp_init = 0x400033f0; r_bt_rtp_register_rule_cs_fmt = 0x400033fc; r_bt_rtp_register_rule_cs_idx = 0x40003408; r_btdm_isr = 0x40003414; -/* -r_btdm_task_post = 0x40003420; -r_btdm_task_post_from_isr = 0x4000342c; -r_btdm_task_recycle = 0x40003438; -*/ r_cali_phase_match_p = 0x40003444; r_cmp_abs_time = 0x40003450; r_cmp_dest_id = 0x4000345c; @@ -1112,9 +1098,6 @@ r_hci_look_for_evt_desc = 0x40003888; r_hci_look_for_le_evt_desc = 0x40003894; r_hci_look_for_le_evt_desc_esp = 0x400038a0; r_hci_pack_bytes = 0x400038ac; -/* -r_hci_register_vendor_desc_tab = 0x400038b8; -*/ r_hci_send_2_controller = 0x400038c4; r_hci_send_2_host = 0x400038d0; r_hci_tl_c2h_data_flow_on = 0x400038dc; @@ -1171,9 +1154,6 @@ r_ke_task_handler_get = 0x40003b34; r_ke_task_init = 0x40003b40; r_ke_task_msg_flush = 0x40003b4c; r_ke_task_saved_update = 0x40003b58; -/* -r_ke_task_schedule = 0x40003b64; -*/ r_ke_time = 0x40003b70; r_ke_time_cmp = 0x40003b7c; r_ke_time_past = 0x40003b88; @@ -1201,9 +1181,6 @@ r_llc_dl_chg_check = 0x40003c84; r_llc_dle_proc_err_cb = 0x40003c90; r_llc_feats_exch_proc_err_cb = 0x40003c9c; r_llc_hci_cmd_handler_tab_p_get = 0x40003ca8; -/* -r_llc_hci_command_handler = 0x40003cb4; -*/ r_llc_hci_con_param_req_evt_send = 0x40003cc0; r_llc_hci_con_upd_info_send = 0x40003ccc; r_llc_hci_disconnected_dis = 0x40003cd8; @@ -1218,7 +1195,7 @@ r_llc_init_term_proc = 0x40003d38; r_llc_iv_skd_rand_gen = 0x40003d44; r_llc_le_ping_proc_continue = 0x40003d50; r_llc_le_ping_proc_err_cb = 0x40003d5c; -r_llc_le_ping_restart = 0x40003d68; +/* r_llc_le_ping_restart = 0x40003d68; */ r_llc_le_ping_set = 0x40003d74; r_llc_ll_pause_enc_rsp_ack_handler = 0x40003d80; r_llc_ll_reject_ind_ack_handler = 0x40003d8c; @@ -1230,16 +1207,12 @@ r_llc_llcp_send = 0x40003dc8; r_llc_llcp_state_set = 0x40003dd4; r_llc_llcp_trans_timer_set = 0x40003de0; r_llc_llcp_tx_check = 0x40003dec; -r_llc_loc_ch_map_proc_continue = 0x40003df8; -/* -r_llc_loc_con_upd_proc_continue = 0x40003e04; -*/ +/* r_llc_loc_ch_map_proc_continue = 0x40003df8; */ r_llc_loc_con_upd_proc_err_cb = 0x40003e10; r_llc_loc_dl_upd_proc_continue = 0x40003e1c; r_llc_loc_encrypt_proc_continue = 0x40003e28; r_llc_loc_encrypt_proc_err_cb = 0x40003e34; r_llc_loc_feats_exch_proc_continue = 0x40003e40; -r_llc_loc_phy_upd_proc_continue = 0x40003e4c; r_llc_loc_phy_upd_proc_err_cb = 0x40003e58; r_llc_msg_handler_tab_p_get = 0x40003e64; r_llc_pref_param_compute = 0x40003e70; @@ -1254,9 +1227,6 @@ r_llc_proc_timer_pause_set = 0x40003ed0; r_llc_proc_timer_set = 0x40003edc; r_llc_proc_unreg = 0x40003ee8; r_llc_rem_ch_map_proc_continue = 0x40003ef4; -/* -r_llc_rem_con_upd_proc_continue = 0x40003f00; -*/ r_llc_rem_con_upd_proc_err_cb = 0x40003f0c; r_llc_rem_dl_upd_proc = 0x40003f18; r_llc_rem_encrypt_proc_continue = 0x40003f24; @@ -1339,20 +1309,14 @@ r_lld_con_pref_slave_evt_dur_set = 0x400042b4; r_lld_con_pref_slave_latency_set = 0x400042c0; r_lld_con_rssi_get = 0x400042cc; r_lld_con_rx = 0x400042d8; -r_lld_con_rx_channel_assess = 0x400042e4; +/* r_lld_con_rx_channel_assess = 0x400042e4; */ r_lld_con_rx_enc = 0x400042f0; r_lld_con_rx_isr = 0x400042fc; r_lld_con_rx_link_info_check = 0x40004308; r_lld_con_rx_llcp_check = 0x40004314; r_lld_con_rx_sync_time_update = 0x40004320; -/* -r_lld_con_sched = 0x4000432c; -*/ r_lld_con_set_tx_power = 0x40004338; r_lld_con_start = 0x40004344; -/* -r_lld_con_stop = 0x40004350; -*/ r_lld_con_tx = 0x4000435c; r_lld_con_tx_enc = 0x40004368; r_lld_con_tx_isr = 0x40004374; @@ -1387,9 +1351,6 @@ r_lld_init_set_tx_power = 0x400044c4; r_lld_init_start = 0x400044d0; r_lld_init_stop = 0x400044dc; r_lld_instant_proc_end = 0x400044e8; -/* -r_lld_llcp_rx_ind_handler = 0x400044f4; -*/ r_lld_per_adv_ch_map_update = 0x40004500; r_lld_per_adv_chain_construct = 0x4000450c; r_lld_per_adv_cleanup = 0x40004518; @@ -1407,9 +1368,6 @@ r_lld_per_adv_init = 0x4000459c; r_lld_per_adv_init_info_get = 0x400045a8; r_lld_per_adv_list_add = 0x400045b4; r_lld_per_adv_list_rem = 0x400045c0; -/* -r_lld_per_adv_sched = 0x400045cc; -*/ r_lld_per_adv_set_tx_power = 0x400045d8; r_lld_per_adv_start = 0x400045e4; r_lld_per_adv_stop = 0x400045f0; @@ -1418,13 +1376,11 @@ r_lld_process_cca_data = 0x40004608; r_lld_ral_search = 0x40004614; r_lld_read_clock = 0x40004620; r_lld_res_list_add = 0x4000462c; -r_lld_res_list_clear = 0x40004638; r_lld_res_list_is_empty = 0x40004644; r_lld_res_list_local_rpa_get = 0x40004650; r_lld_res_list_peer_rpa_get = 0x4000465c; r_lld_res_list_peer_update = 0x40004668; -r_lld_res_list_priv_mode_update = 0x40004674; -r_lld_res_list_rem = 0x40004680; +/* r_lld_res_list_priv_mode_update = 0x40004674; */ r_lld_reset_reg = 0x4000468c; r_lld_rpa_renew = 0x40004698; r_lld_rpa_renew_evt_canceled_cbk = 0x400046a4; @@ -1443,10 +1399,6 @@ r_lld_scan_frm_rx_isr = 0x40004734; r_lld_scan_frm_skip_isr = 0x40004740; r_lld_scan_init = 0x4000474c; r_lld_scan_params_update = 0x40004758; -/* -r_lld_scan_process_pkt_rx = 0x40004764; -r_lld_scan_process_pkt_rx_adv_rep = 0x40004770; -*/ r_lld_scan_process_pkt_rx_aux_adv_ind = 0x4000477c; r_lld_scan_process_pkt_rx_aux_chain_ind = 0x40004788; r_lld_scan_process_pkt_rx_aux_scan_rsp = 0x40004794; @@ -1490,7 +1442,7 @@ r_lld_test_init = 0x40004950; r_lld_test_rx_isr = 0x4000495c; r_lld_test_set_tx_power = 0x40004968; r_lld_test_start = 0x40004974; -r_lld_test_stop = 0x40004980; +/* r_lld_test_stop = 0x40004980;*/ r_lld_update_rxbuf = 0x4000498c; r_lld_update_rxbuf_isr = 0x40004998; r_lld_white_list_add = 0x400049a4; @@ -1521,9 +1473,6 @@ r_llm_is_dev_synced = 0x40004ac4; r_llm_is_non_con_act_ongoing_check = 0x40004ad0; r_llm_is_wl_accessible = 0x40004adc; r_llm_le_evt_mask_check = 0x40004ae8; -/* -r_llm_le_features_get = 0x40004af4; -*/ r_llm_link_disc = 0x40004b00; r_llm_master_ch_map_get = 0x40004b0c; r_llm_msg_handler_tab_p_get = 0x40004b18; @@ -1543,9 +1492,6 @@ r_misc_msg_handler_tab_p_get = 0x40004bb4; r_notEqual256 = 0x40004bc0; r_phy_upd_proc_start = 0x40004bcc; r_platform_reset = 0x40004bd8; -/* -r_register_esp_vendor_cmd_handler = 0x40004be4; -*/ r_rf_em_init = 0x40004bf0; r_rf_force_agc_enable = 0x40004bfc; r_rf_reg_rd = 0x40004c08; @@ -1555,10 +1501,6 @@ r_rf_rssi_convert = 0x40004c2c; r_rf_rw_v9_le_disable = 0x40004c38; r_rf_rw_v9_le_enable = 0x40004c44; r_rf_sleep = 0x40004c50; -/* -r_rf_txpwr_cs_get = 0x40004c5c; -r_rf_txpwr_dbm_get = 0x40004c68; -*/ r_rf_util_cs_fmt_convert = 0x40004c74; r_rw_crypto_aes_ccm = 0x40004c80; r_rw_crypto_aes_encrypt = 0x40004c8c; @@ -1572,15 +1514,12 @@ r_rw_crypto_aes_result_handler = 0x40004ce0; r_rw_crypto_aes_s1 = 0x40004cec; r_rw_cryto_aes_cmac = 0x40004cf8; r_rw_v9_init_em_radio_table = 0x40004d04; -/* -r_rwble_isr = 0x40004d10; -*/ r_rwble_sleep_enter = 0x40004d1c; r_rwble_sleep_wakeup_end = 0x40004d28; -r_rwbtdm_isr_wrapper = 0x40004d34; +/* r_rwbtdm_isr_wrapper = 0x40004d34; */ r_rwip_active_check = 0x40004d40; r_rwip_aes_encrypt = 0x40004d4c; -r_rwip_assert = 0x40004d58; +/* r_rwip_assert = 0x40004d58; */ r_rwip_crypt_evt_handler = 0x40004d64; r_rwip_crypt_isr_handler = 0x40004d70; r_rwip_eif_get = 0x40004d7c; @@ -1602,7 +1541,7 @@ r_rwip_timer_hs_set = 0x40004e30; r_rwip_timer_hus_handler = 0x40004e3c; r_rwip_timer_hus_set = 0x40004e48; r_rwip_wakeup = 0x40004e54; -r_rwip_wakeup_end = 0x40004e60; +/* r_rwip_wakeup_end = 0x40004e60; */ r_rwip_wlcoex_set = 0x40004e6c; r_sch_alarm_clear = 0x40004e78; r_sch_alarm_init = 0x40004e84; @@ -1611,9 +1550,6 @@ r_sch_alarm_set = 0x40004e9c; r_sch_alarm_timer_isr = 0x40004ea8; r_sch_arb_conflict_check = 0x40004eb4; r_sch_arb_elt_cancel = 0x40004ec0; -/* -r_sch_arb_event_start_isr = 0x40004ecc; -*/ r_sch_arb_init = 0x40004ed8; r_sch_arb_insert = 0x40004ee4; r_sch_arb_prog_timer = 0x40004ef0; @@ -1628,10 +1564,6 @@ r_sch_plan_offset_req = 0x40004f50; r_sch_plan_position_range_compute = 0x40004f5c; r_sch_plan_rem = 0x40004f68; r_sch_plan_req = 0x40004f74; -/* -r_sch_plan_set = 0x40004f80; -r_sch_prog_end_isr = 0x40004f8c; -*/ r_sch_prog_init = 0x40004f98; r_sch_prog_push = 0x40004fa4; r_sch_prog_rx_isr = 0x40004fb0; @@ -1667,26 +1599,16 @@ r_lld_ext_adv_dynamic_pti_get = 0x4000510c; r_lld_ext_adv_dynamic_aux_pti_process = 0x40005118; r_lld_ext_adv_dynamic_pti_process = 0x40005124; r_lld_adv_ext_pkt_prepare_set = 0x40005130; -/* -r_lld_adv_ext_chain_none_construct = 0x4000513c; -*/ r_lld_adv_ext_chain_connectable_construct = 0x40005148; -/* -r_lld_adv_ext_chain_scannable_construct = 0x40005154; -*/ r_lld_adv_pkt_rx_connect_post = 0x40005160; r_lld_adv_start_init_evt_param = 0x4000516c; r_lld_adv_start_set_cs = 0x40005178; -r_lld_adv_start_update_filter_policy = 0x40005184; +/* r_lld_adv_start_update_filter_policy = 0x40005184; */ r_lld_adv_start_schedule_asap = 0x40005190; r_lld_con_tx_prog_new_packet_coex = 0x4000519c; -/* -r_lld_con_tx_prog_new_packet = 0x400051a8; -*/ r_lld_per_adv_dynamic_pti_get = 0x400051b4; r_lld_per_adv_evt_start_chm_upd = 0x400051c0; r_lld_ext_scan_dynamic_pti_get = 0x400051cc; -r_lld_scan_try_sched = 0x400051d8; r_lld_sync_insert = 0x400051e4; r_sch_prog_ble_push = 0x400051f0; r_sch_prog_bt_push = 0x400051fc; @@ -1845,14 +1767,8 @@ r_llc_loc_phy_upd_proc_continue_hook = 0x40001c64; r_llc_rem_phy_upd_proc_continue_hook = 0x40001c68; r_lld_scan_frm_eof_isr_hook = 0x40001c6c; r_lld_scan_evt_start_cbk_hook = 0x40001c70; -/* -r_lld_scan_start_hook = 0x40001c74; -*/ r_lld_scan_process_pkt_rx_ext_adv_hook = 0x40001c78; r_lld_scan_sched_hook = 0x40001c7c; -/* -r_lld_adv_start_hook = 0x40001c80; -*/ r_lld_adv_evt_start_cbk_hook = 0x40001c84; r_lld_adv_aux_evt_start_cbk_hook = 0x40001c88; r_lld_adv_frm_isr_hook = 0x40001c8c; @@ -1862,15 +1778,9 @@ r_lld_con_frm_isr_hook = 0x40001c98; r_lld_con_tx_hook = 0x40001c9c; r_lld_con_rx_hook = 0x40001ca0; r_lld_con_evt_start_cbk_hook = 0x40001ca4; -/* -r_lld_con_start_hook = 0x40001ca8; -*/ r_lld_con_tx_prog_new_packet_hook = 0x40001cac; r_lld_init_frm_eof_isr_hook = 0x40001cb0; r_lld_init_evt_start_cbk_hook = 0x40001cb4; -/* -r_lld_init_start_hook = 0x40001cb8; -*/ r_lld_init_sched_hook = 0x40001cbc; r_lld_init_process_pkt_tx_hook = 0x40001cc0; r_lld_per_adv_evt_start_cbk_hook = 0x40001cc4; @@ -1891,8 +1801,8 @@ r_sch_plan_offset_req_hook = 0x40001ce4; esp_pp_rom_version_get = 0x40005250; RC_GetBlockAckTime = 0x4000525c; ebuf_list_remove = 0x40005268; -esf_buf_alloc = 0x40005274; -esf_buf_alloc_dynamic = 0x40005280; +/*esf_buf_alloc = 0x40005274;*/ +/*esf_buf_alloc_dynamic = 0x40005280;*/ /*esf_buf_recycle = 0x4000528c;*/ GetAccess = 0x40005298; hal_mac_is_low_rate_enabled = 0x400052a4; @@ -1903,13 +1813,13 @@ ic_get_trc = 0x400052c8; ic_mac_init = 0x400052e0; ic_interface_enabled = 0x400052ec; is_lmac_idle = 0x400052f8; -lmacAdjustTimestamp = 0x40005304; +/*lmacAdjustTimestamp = 0x40005304;*/ lmacDiscardAgedMSDU = 0x40005310; /*lmacDiscardMSDU = 0x4000531c;*/ -lmacEndFrameExchangeSequence = 0x40005328; +/*lmacEndFrameExchangeSequence = 0x40005328;*/ lmacIsIdle = 0x40005334; lmacIsLongFrame = 0x40005340; -lmacMSDUAged = 0x4000534c; +/*lmacMSDUAged = 0x4000534c;*/ lmacPostTxComplete = 0x40005358; lmacProcessAllTxTimeout = 0x40005364; lmacProcessCollisions = 0x40005370; @@ -1926,10 +1836,10 @@ 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; +/*pm_dream = 0x4000543c;*/ pm_mac_wakeup = 0x40005448; pm_mac_sleep = 0x40005454; pm_enable_active_timer = 0x40005460; @@ -1950,10 +1860,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; @@ -1973,7 +1883,7 @@ ppRecycleRxPkt = 0x40005628; ppResortTxAMPDU = 0x40005634; ppResumeTxAMPDU = 0x40005640; /* ppRxFragmentProc = 0x4000564c; */ -ppRxPkt = 0x40005658; +/* ppRxPkt = 0x40005658; */ ppRxProtoProc = 0x40005664; ppSearchTxQueue = 0x40005670; ppSearchTxframe = 0x4000567c; @@ -1983,7 +1893,7 @@ ppSubFromAMPDU = 0x40005694; ppTxPkt = 0x400056ac; ppTxProtoProc = 0x400056b8; ppTxqUpdateBitmap = 0x400056c4; -pp_coex_tx_request = 0x400056d0; +/*pp_coex_tx_request = 0x400056d0;*/ pp_hdrsize = 0x400056dc; pp_post = 0x400056e8; pp_process_hmac_waiting_txq = 0x400056f4; @@ -1996,12 +1906,12 @@ rcampduuprate = 0x4000573c; rcClearCurAMPDUSched = 0x40005748; rcClearCurSched = 0x40005754; rcClearCurStat = 0x40005760; -rcGetSched = 0x4000576c; +/*rcGetSched = 0x4000576c;*/ rcLowerSched = 0x40005778; rcSetTxAmpduLimit = 0x40005784; /* rcTxUpdatePer = 0x40005790;*/ rcUpdateAckSnr = 0x4000579c; -rcUpdateRate = 0x400057a8; +/*rcUpdateRate = 0x400057a8;*/ /* rcUpdateTxDone = 0x400057b4; */ rcUpdateTxDoneAmpdu2 = 0x400057c0; rcUpSched = 0x400057cc; @@ -2017,11 +1927,11 @@ trc_SetTxAmpduState = 0x40005838; trc_tid_isTxAmpduOperational = 0x40005844; trcAmpduSetState = 0x40005850; wDevCheckBlockError = 0x4000585c; -wDev_AppendRxBlocks = 0x40005868; +/*wDev_AppendRxBlocks = 0x40005868;*/ wDev_DiscardFrame = 0x40005874; wDev_GetNoiseFloor = 0x40005880; wDev_IndicateAmpdu = 0x4000588c; -wDev_IndicateFrame = 0x40005898; +/*wDev_IndicateFrame = 0x40005898;*/ wdev_bank_store = 0x400058a4; wdev_bank_load = 0x400058b0; wdev_mac_reg_load = 0x400058bc; @@ -2032,14 +1942,14 @@ wdev_mac_wakeup = 0x400058ec; wdev_mac_sleep = 0x400058f8; hal_mac_is_dma_enable = 0x40005904; /* wDev_ProcessFiq = 0x40005910; */ -wDev_ProcessRxSucData = 0x4000591c; +/*wDev_ProcessRxSucData = 0x4000591c;*/ wdevProcessRxSucDataAll = 0x40005928; wdev_csi_len_align = 0x40005934; 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; @@ -2114,19 +2024,19 @@ ic_ebuf_recycle_rx = 0x40005a24; ic_ebuf_recycle_tx = 0x40005a30; ic_reset_rx_ba = 0x40005a3c; ieee80211_align_eb = 0x40005a48; -ieee80211_ampdu_reorder = 0x40005a54; +/* ieee80211_ampdu_reorder = 0x40005a54; */ ieee80211_ampdu_start_age_timer = 0x40005a60; /* ieee80211_encap_esfbuf = 0x40005a6c; */ ieee80211_is_tx_allowed = 0x40005a78; ieee80211_output_pending_eb = 0x40005a84; -ieee80211_output_process = 0x40005a90; +/*ieee80211_output_process = 0x40005a90;*/ ieee80211_set_tx_desc = 0x40005a9c; /*sta_input = 0x40005aa8;*/ wifi_get_macaddr = 0x40005ab4; wifi_rf_phy_disable = 0x40005ac0; wifi_rf_phy_enable = 0x40005acc; ic_ebuf_alloc = 0x40005ad8; -ieee80211_classify = 0x40005ae4; +/*ieee80211_classify = 0x40005ae4;*/ ieee80211_copy_eb_header = 0x40005af0; ieee80211_recycle_cache_eb = 0x40005afc; ieee80211_search_node = 0x40005b08; @@ -2158,7 +2068,7 @@ esp_coex_rom_version_get = 0x40005b68; coex_bt_release = 0x40005b74; coex_bt_request = 0x40005b80; coex_core_ble_conn_dyn_prio_get = 0x40005b8c; -coex_core_event_duration_get = 0x40005b98; +/*coex_core_event_duration_get = 0x40005b98;*/ coex_core_pti_get = 0x40005ba4; coex_core_release = 0x40005bb0; coex_core_request = 0x40005bbc; diff --git a/components/esp_rom/include/esp32/rom/uart.h b/components/esp_rom/include/esp32/rom/uart.h index 45b61dd26e..ca69a3a451 100644 --- a/components/esp_rom/include/esp32/rom/uart.h +++ b/components/esp_rom/include/esp32/rom/uart.h @@ -10,6 +10,7 @@ #include "ets_sys.h" #include "soc/soc.h" #include "soc/uart_periph.h" +#include "soc/uart_reg.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_rom/include/esp32h2/rom/rtc.h b/components/esp_rom/include/esp32h2/rom/rtc.h index 7f516d704b..3cb3320a93 100644 --- a/components/esp_rom/include/esp32h2/rom/rtc.h +++ b/components/esp_rom/include/esp32h2/rom/rtc.h @@ -51,6 +51,7 @@ extern "C" { * LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY * LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC * LP_AON_STORE8_REG Store light sleep wake stub addr + * LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep) ************************************************************************************* */ @@ -63,6 +64,7 @@ extern "C" { #define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG #define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG #define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG +#define SLEEP_MODE_REG LP_AON_STORE9_REG #define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. @@ -80,7 +82,6 @@ typedef enum { TG0WDT_SYS_RESET = 7, /**<7, Timer Group0 Watch dog reset digital core*/ TG1WDT_SYS_RESET = 8, /**<8, Timer Group1 Watch dog reset digital core*/ RTCWDT_SYS_RESET = 9, /**<9, RTC Watch dog Reset digital core*/ - INTRUSION_RESET = 10, /**<10, Instrusion tested to reset CPU*/ TG0WDT_CPU_RESET = 11, /**<11, Time Group0 reset CPU*/ RTC_SW_CPU_RESET = 12, /**<12, Software reset CPU*/ RTCWDT_CPU_RESET = 13, /**<13, RTC Watch dog Reset CPU*/ @@ -88,11 +89,11 @@ typedef enum { RTCWDT_RTC_RESET = 16, /**<16, RTC Watch dog reset digital core and rtc module*/ TG1WDT_CPU_RESET = 17, /**<17, Time Group1 reset CPU*/ SUPER_WDT_RESET = 18, /**<18, super watchdog reset digital core and rtc module*/ - GLITCH_RTC_RESET = 19, /**<19, glitch reset digital core and rtc module*/ EFUSE_RESET = 20, /**<20, efuse reset digital core*/ USB_UART_CHIP_RESET = 21, /**<21, usb uart reset digital core */ USB_JTAG_CHIP_RESET = 22, /**<22, usb jtag reset digital core */ POWER_GLITCH_RESET = 23, /**<23, power glitch reset digital core and rtc module*/ + JTAG_CPU_RESET = 24, /**<24, jtag reset CPU*/ } RESET_REASON; // Check if the reset reason defined in ROM is compatible with soc/reset_reasons.h @@ -109,11 +110,11 @@ ESP_STATIC_ASSERT((soc_reset_reason_t)RTCWDT_BROWN_OUT_RESET == RESET_REASON_SYS ESP_STATIC_ASSERT((soc_reset_reason_t)RTCWDT_RTC_RESET == RESET_REASON_SYS_RTC_WDT, "RTCWDT_RTC_RESET != RESET_REASON_SYS_RTC_WDT"); ESP_STATIC_ASSERT((soc_reset_reason_t)TG1WDT_CPU_RESET == RESET_REASON_CPU0_MWDT1, "TG1WDT_CPU_RESET != RESET_REASON_CPU0_MWDT1"); ESP_STATIC_ASSERT((soc_reset_reason_t)SUPER_WDT_RESET == RESET_REASON_SYS_SUPER_WDT, "SUPER_WDT_RESET != RESET_REASON_SYS_SUPER_WDT"); -ESP_STATIC_ASSERT((soc_reset_reason_t)GLITCH_RTC_RESET == RESET_REASON_SYS_CLK_GLITCH, "GLITCH_RTC_RESET != RESET_REASON_SYS_CLK_GLITCH"); ESP_STATIC_ASSERT((soc_reset_reason_t)EFUSE_RESET == RESET_REASON_CORE_EFUSE_CRC, "EFUSE_RESET != RESET_REASON_CORE_EFUSE_CRC"); ESP_STATIC_ASSERT((soc_reset_reason_t)USB_UART_CHIP_RESET == RESET_REASON_CORE_USB_UART, "USB_UART_CHIP_RESET != RESET_REASON_CORE_USB_UART"); ESP_STATIC_ASSERT((soc_reset_reason_t)USB_JTAG_CHIP_RESET == RESET_REASON_CORE_USB_JTAG, "USB_JTAG_CHIP_RESET != RESET_REASON_CORE_USB_JTAG"); ESP_STATIC_ASSERT((soc_reset_reason_t)POWER_GLITCH_RESET == RESET_REASON_CORE_PWR_GLITCH, "POWER_GLITCH_RESET != RESET_REASON_CORE_PWR_GLITCH"); +ESP_STATIC_ASSERT((soc_reset_reason_t)JTAG_CPU_RESET == RESET_REASON_CPU0_JTAG, "JTAG_CPU_RESET != RESET_REASON_CPU0_JTAG"); typedef enum { NO_SLEEP = 0, diff --git a/components/esp_rom/include/esp32s2/rom/usb/cdc_acm.h b/components/esp_rom/include/esp32s2/rom/usb/cdc_acm.h index 38161d7a31..9d203c7c1b 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/cdc_acm.h +++ b/components/esp_rom/include/esp32s2/rom/usb/cdc_acm.h @@ -1,34 +1,8 @@ -/******************************************************************************* - * - * Copyright(c) 2015,2016 Intel Corporation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ +/* + * SPDX-FileCopyrightText: 2015, 2016 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + */ #pragma once #include diff --git a/components/esp_rom/include/esp32s2/rom/usb/chip_usb_dw_wrapper.h b/components/esp_rom/include/esp32s2/rom/usb/chip_usb_dw_wrapper.h index a7c5064359..693412478a 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/chip_usb_dw_wrapper.h +++ b/components/esp_rom/include/esp32s2/rom/usb/chip_usb_dw_wrapper.h @@ -1,16 +1,8 @@ -// Copyright 2019-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: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include diff --git a/components/esp_rom/include/esp32s2/rom/usb/cpio.h b/components/esp_rom/include/esp32s2/rom/usb/cpio.h index 886b5080fb..ca0912e45b 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/cpio.h +++ b/components/esp_rom/include/esp32s2/rom/usb/cpio.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 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: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /** diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_cdc.h b/components/esp_rom/include/esp32s2/rom/usb/usb_cdc.h index c241bcfe06..26c773ec72 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_cdc.h +++ b/components/esp_rom/include/esp32s2/rom/usb/usb_cdc.h @@ -1,7 +1,5 @@ -/* usb_cdc.h - USB CDC-ACM and CDC-ECM public header */ - /* - * Copyright (c) 2017 PHYTEC Messtechnik GmbH + * SPDX-FileCopyrightText: 2017 PHYTEC Messtechnik GmbH * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_common.h b/components/esp_rom/include/esp32s2/rom/usb/usb_common.h index 796a77bc00..7105750d71 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_common.h +++ b/components/esp_rom/include/esp32s2/rom/usb/usb_common.h @@ -1,36 +1,9 @@ -/*************************************************************************** +/* + * SPDX-FileCopyrightText: 2015,2016 Intel Corporation + * SPDX-FileContributor: 2017 PHYTEC Messtechnik GmbH * - * - * Copyright(c) 2015,2016 Intel Corporation. - * Copyright(c) 2017 PHYTEC Messtechnik GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ***************************************************************************/ + * SPDX-License-Identifier: BSD-3-Clause + */ /** * @file diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_dc.h b/components/esp_rom/include/esp32s2/rom/usb/usb_dc.h index f20e897c71..5587cc22ba 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_dc.h +++ b/components/esp_rom/include/esp32s2/rom/usb/usb_dc.h @@ -1,7 +1,5 @@ -/* usb_dc.h - USB device controller driver interface */ - /* - * Copyright (c) 2016 Intel Corporation. + * SPDX-FileCopyrightText: 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ @@ -372,19 +370,43 @@ int usb_dc_ep_read_continue(uint8_t ep); int usb_dc_ep_mps(uint8_t ep); - -//Hack - fake interrupts by pollinfg +/** + * @brief Poll for interrupts that need to be handled + * + * When the USB interrupt is not hooked up to an actual CPU interrupt, you + * can call this periodically to handle the USB events that need handling. + */ void usb_dc_check_poll_for_interrupts(void); -//Prepare for USB persist. You should reboot after this. +/* + * @brief Prepare for USB persist + * + * This takes the USB peripheral offline in such a way that it seems 'just busy' to the + * host. This way, the chip can reboot (e.g. into bootloader mode) and pick up the USB + * configuration again, without the conenction to the host being interrupted. + * + * @note Actual persistence is depending on USBDC_PERSIST_ENA being set in flags, as this + * is also used to e.g. reboot into DFU mode. + * + * @note Please reboot soon after calling this. + */ int usb_dc_prepare_persist(void); - +/* + * @brief USB interrupt handler + * + * This can be hooked up by the OS to the USB peripheral interrupt. + */ void usb_dw_isr_handler(void); +/** + * @brief Provide IDF with an interface to clear the static variable usb_dw_ctrl + * + * + */ +void usb_dw_ctrl_deinit(void); -int usb_dc_ep_write_would_block(const uint8_t ep); #ifdef __cplusplus diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_descriptor.h b/components/esp_rom/include/esp32s2/rom/usb/usb_descriptor.h index 1b20ef80f0..3ac62afa06 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_descriptor.h +++ b/components/esp_rom/include/esp32s2/rom/usb/usb_descriptor.h @@ -1,16 +1,8 @@ -// Copyright 2019-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: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_device.h b/components/esp_rom/include/esp32s2/rom/usb/usb_device.h index a63288c71b..87dbcda15b 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_device.h +++ b/components/esp_rom/include/esp32s2/rom/usb/usb_device.h @@ -1,29 +1,10 @@ /* - * LPCUSB, an USB device driver for LPC microcontrollers - * Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) - * Copyright (c) 2016 Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * SPDX-FileCopyrightText: 2006 Bertrik Sikken (bertrik@sikken.nl) + * SPDX-FileContributor: 2016 Intel Corporation + * + * SPDX-License-Identifier: BSD-3-Clause + * + * LPCUSB, an USB device driver for LPC microcontrollers */ /** @@ -392,6 +373,12 @@ int usb_transfer_sync(uint8_t ep, uint8_t *data, size_t dlen, unsigned int flags */ void usb_cancel_transfer(uint8_t ep); +/** + * @brief Provide IDF with an interface to clear the static variable usb_dev + * + * + */ +void usb_dev_deinit(void); void usb_dev_resume(int configuration); int usb_dev_get_configuration(void); diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_dfu.h b/components/esp_rom/include/esp32s2/rom/usb/usb_dfu.h index dec7ea93a3..442546d2f0 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_dfu.h +++ b/components/esp_rom/include/esp32s2/rom/usb/usb_dfu.h @@ -1,35 +1,9 @@ -/*************************************************************************** - * - * Copyright(c) 2015,2016 Intel Corporation. - * Copyright(c) 2017 PHYTEC Messtechnik GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* + * SPDX-FileCopyrightText: 2015,2016 Intel Corporation + * SPDX-FileContributor: 2017 PHYTEC Messtechnik GmbH * - ***************************************************************************/ + * SPDX-License-Identifier: BSD-3-Clause + */ /** * @file diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_os_glue.h b/components/esp_rom/include/esp32s2/rom/usb/usb_os_glue.h index 74d9b2a778..4989b00ec5 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_os_glue.h +++ b/components/esp_rom/include/esp32s2/rom/usb/usb_os_glue.h @@ -1,16 +1,8 @@ -// Copyright 2019-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: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s2/rom/usb/usb_persist.h b/components/esp_rom/include/esp32s2/rom/usb/usb_persist.h index bcf11b7c48..c45c8b49e2 100644 --- a/components/esp_rom/include/esp32s2/rom/usb/usb_persist.h +++ b/components/esp_rom/include/esp32s2/rom/usb/usb_persist.h @@ -1,16 +1,8 @@ -// Copyright 2019-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: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s3/rom/usb/cdc_acm.h b/components/esp_rom/include/esp32s3/rom/usb/cdc_acm.h index 04e313d858..8e4b606bf7 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/cdc_acm.h +++ b/components/esp_rom/include/esp32s3/rom/usb/cdc_acm.h @@ -1,34 +1,8 @@ -/******************************************************************************* - * - * Copyright(c) 2015,2016 Intel Corporation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ +/* + * SPDX-FileCopyrightText: 2015, 2016 Intel Corporation. + * + * SPDX-License-Identifier: BSD-3-Clause + */ #pragma once #include diff --git a/components/esp_rom/include/esp32s3/rom/usb/chip_usb_dw_wrapper.h b/components/esp_rom/include/esp32s3/rom/usb/chip_usb_dw_wrapper.h index a7c5064359..693412478a 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/chip_usb_dw_wrapper.h +++ b/components/esp_rom/include/esp32s3/rom/usb/chip_usb_dw_wrapper.h @@ -1,16 +1,8 @@ -// Copyright 2019-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: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include diff --git a/components/esp_rom/include/esp32s3/rom/usb/cpio.h b/components/esp_rom/include/esp32s3/rom/usb/cpio.h index 886b5080fb..ca0912e45b 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/cpio.h +++ b/components/esp_rom/include/esp32s3/rom/usb/cpio.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 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: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ /** diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_cdc.h b/components/esp_rom/include/esp32s3/rom/usb/usb_cdc.h index c241bcfe06..f62684f585 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/usb_cdc.h +++ b/components/esp_rom/include/esp32s3/rom/usb/usb_cdc.h @@ -1,12 +1,9 @@ -/* usb_cdc.h - USB CDC-ACM and CDC-ECM public header */ - /* - * Copyright (c) 2017 PHYTEC Messtechnik GmbH + * SPDX-FileCopyrightText: 2017 PHYTEC Messtechnik GmbH * * SPDX-License-Identifier: Apache-2.0 */ - /** * @file * @brief USB Communications Device Class (CDC) public header diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_common.h b/components/esp_rom/include/esp32s3/rom/usb/usb_common.h index c3bd52cfb9..dbe5c8f350 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/usb_common.h +++ b/components/esp_rom/include/esp32s3/rom/usb/usb_common.h @@ -1,36 +1,9 @@ -/*************************************************************************** +/* + * SPDX-FileCopyrightText: 2015,2016 Intel Corporation + * SPDX-FileContributor: 2017 PHYTEC Messtechnik GmbH * - * - * Copyright(c) 2015,2016 Intel Corporation. - * Copyright(c) 2017 PHYTEC Messtechnik GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ***************************************************************************/ + * SPDX-License-Identifier: BSD-3-Clause + */ /** * @file @@ -217,26 +190,6 @@ struct string_descriptor { uint16_t bString[]; } __packed; -#define ROM_MAX_CFG_DESC_CNT 1 - -struct rom_usb_descriptors { - const struct usb_device_descriptor *device_descr; - const void *config_descr[ROM_MAX_CFG_DESC_CNT]; - int string_count; // including string_descriptor_zero - const struct string_descriptor_zero *string0_descr; - const struct string_descriptor *string_descrs[]; -}; - -/* Descriptors defined in the ROM */ -extern struct usb_device_descriptor general_device_descr; -extern const void* acm_config_descr; -extern const void* dfu_config_descr; -extern const struct string_descriptor str_manu_descr; -extern const struct string_descriptor str_prod_descr; -extern const struct string_descriptor_zero string0_descr; -extern const struct rom_usb_descriptors acm_usb_descriptors; -extern const struct rom_usb_descriptors dfu_usb_descriptors; -extern const struct rom_usb_descriptors *rom_usb_curr_desc; #ifdef __cplusplus } diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_dc.h b/components/esp_rom/include/esp32s3/rom/usb/usb_dc.h index f20e897c71..725362fa19 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/usb_dc.h +++ b/components/esp_rom/include/esp32s3/rom/usb/usb_dc.h @@ -1,7 +1,5 @@ -/* usb_dc.h - USB device controller driver interface */ - /* - * Copyright (c) 2016 Intel Corporation. + * SPDX-FileCopyrightText: 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ @@ -372,19 +370,42 @@ int usb_dc_ep_read_continue(uint8_t ep); int usb_dc_ep_mps(uint8_t ep); - -//Hack - fake interrupts by pollinfg +/** + * @brief Poll for interrupts that need to be handled + * + * When the USB interrupt is not hooked up to an actual CPU interrupt, you + * can call this periodically to handle the USB events that need handling. + */ void usb_dc_check_poll_for_interrupts(void); -//Prepare for USB persist. You should reboot after this. +/* + * @brief Prepare for USB persist + * + * This takes the USB peripheral offline in such a way that it seems 'just busy' to the + * host. This way, the chip can reboot (e.g. into bootloader mode) and pick up the USB + * configuration again, without the conenction to the host being interrupted. + * + * @note Actual persistence is depending on USBDC_PERSIST_ENA being set in flags, as this + * is also used to e.g. reboot into DFU mode. + * + * @note Please reboot soon after calling this. + */ int usb_dc_prepare_persist(void); - +/* + * @brief USB interrupt handler + * + * This can be hooked up by the OS to the USB peripheral interrupt. + */ void usb_dw_isr_handler(void); - -int usb_dc_ep_write_would_block(const uint8_t ep); +/** + * @brief Provide IDF with an interface to clear the static variable usb_dw_ctrl + * + * + */ +void usb_dw_ctrl_deinit(void); #ifdef __cplusplus diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_descriptor.h b/components/esp_rom/include/esp32s3/rom/usb/usb_descriptor.h index 1b20ef80f0..3ac62afa06 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/usb_descriptor.h +++ b/components/esp_rom/include/esp32s3/rom/usb/usb_descriptor.h @@ -1,16 +1,8 @@ -// Copyright 2019-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: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_device.h b/components/esp_rom/include/esp32s3/rom/usb/usb_device.h index a63288c71b..87dbcda15b 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/usb_device.h +++ b/components/esp_rom/include/esp32s3/rom/usb/usb_device.h @@ -1,29 +1,10 @@ /* - * LPCUSB, an USB device driver for LPC microcontrollers - * Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl) - * Copyright (c) 2016 Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * SPDX-FileCopyrightText: 2006 Bertrik Sikken (bertrik@sikken.nl) + * SPDX-FileContributor: 2016 Intel Corporation + * + * SPDX-License-Identifier: BSD-3-Clause + * + * LPCUSB, an USB device driver for LPC microcontrollers */ /** @@ -392,6 +373,12 @@ int usb_transfer_sync(uint8_t ep, uint8_t *data, size_t dlen, unsigned int flags */ void usb_cancel_transfer(uint8_t ep); +/** + * @brief Provide IDF with an interface to clear the static variable usb_dev + * + * + */ +void usb_dev_deinit(void); void usb_dev_resume(int configuration); int usb_dev_get_configuration(void); diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_dfu.h b/components/esp_rom/include/esp32s3/rom/usb/usb_dfu.h index dec7ea93a3..13f242d5f3 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/usb_dfu.h +++ b/components/esp_rom/include/esp32s3/rom/usb/usb_dfu.h @@ -1,35 +1,9 @@ -/*************************************************************************** - * - * Copyright(c) 2015,2016 Intel Corporation. - * Copyright(c) 2017 PHYTEC Messtechnik GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* + * SPDX-FileCopyrightText: 2015,2016 Intel Corporation + * SPDX-FileContributor: 2017 PHYTEC Messtechnik GmbH * - ***************************************************************************/ + * SPDX-License-Identifier: BSD-3-Clause + */ /** * @file @@ -140,6 +114,7 @@ int dfu_custom_handle_req(struct usb_setup_packet *pSetup, typedef void(*usb_dfu_detach_routine_t)(int delay); void usb_dfu_set_detach_cb(usb_dfu_detach_routine_t cb); +void usb_dfu_force_detach(void); #ifdef __cplusplus diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_os_glue.h b/components/esp_rom/include/esp32s3/rom/usb/usb_os_glue.h index 9abad6d0b9..4989b00ec5 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/usb_os_glue.h +++ b/components/esp_rom/include/esp32s3/rom/usb/usb_os_glue.h @@ -1,16 +1,8 @@ -// Copyright 2019-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: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -33,7 +25,7 @@ typedef struct { usb_osglue_wait_routine_t wait_proc; } usb_osglue_data_t; -extern usb_osglue_data_t s_usb_osglue; +extern usb_osglue_data_t rom_usb_osglue; #ifdef __cplusplus } diff --git a/components/esp_rom/include/esp32s3/rom/usb/usb_persist.h b/components/esp_rom/include/esp32s3/rom/usb/usb_persist.h index bcf11b7c48..90dfe98e4a 100644 --- a/components/esp_rom/include/esp32s3/rom/usb/usb_persist.h +++ b/components/esp_rom/include/esp32s3/rom/usb/usb_persist.h @@ -1,16 +1,8 @@ -// Copyright 2019-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: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once @@ -34,7 +26,7 @@ extern "C" { //This being non-0 indicates a memory location where a 'testament' is stored, aka a piece of text that should be output //after a reboot. Can contain core dump info or something. -#define USBDC_TESTAMENT_LOC_MASK 0x7FFFF //bits 19-0; this is added to a base address of 0x3FF80000. +#define USBDC_TESTAMENT_LOC_MASK 0x7FFFF //bits 19-0; this is added to a base address of SOC_MEM_INTERNAL_LOW. (0x3FF9E000) //The testament is a FIFO. The ROM will output all data between textstart and textend; if textend is lower than textstart it will //output everything from textstart to memend, then memstart to textend. diff --git a/components/esp_rom/linker.lf b/components/esp_rom/linker.lf index e9cb68a742..bc708c5697 100644 --- a/components/esp_rom/linker.lf +++ b/components/esp_rom/linker.lf @@ -4,7 +4,9 @@ entries: esp_rom_spiflash (noflash) if ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG = y: esp_rom_cache_esp32s2_esp32s3 (noflash) - if HEAP_TLSF_USE_ROM_IMPL = y && ESP_ROM_TLSF_CHECK_PATCH = y: + 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 || 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_cache_esp32s2_esp32s3.c b/components/esp_rom/patches/esp_rom_cache_esp32s2_esp32s3.c index 7b88c6f0fb..9866d652a8 100644 --- a/components/esp_rom/patches/esp_rom_cache_esp32s2_esp32s3.c +++ b/components/esp_rom/patches/esp_rom_cache_esp32s2_esp32s3.c @@ -7,12 +7,16 @@ #include "sdkconfig.h" #include #include "soc/soc_caps.h" -#include "soc/extmem_reg.h" #include "esp_rom_caps.h" +#include "soc/extmem_reg.h" +#include "xtensa/xtruntime.h" #if CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/cache.h" #endif +#define ALIGN_UP(addr, align) (((addr) + (align)-1) & ~((align)-1)) +#define ALIGN_DOWN(addr, align) ((addr) & ~((align) - 1)) + // this api is renamed for patch extern uint32_t rom_Cache_Count_Flash_Pages(uint32_t bus, uint32_t * page0_mapped); uint32_t Cache_Count_Flash_Pages(uint32_t bus, uint32_t * page0_mapped) @@ -64,6 +68,7 @@ uint32_t Cache_Suspend_DCache(void) } extern uint32_t Cache_Suspend_DCache(void); +#if SOC_CACHE_FREEZE_SUPPORTED // renamed for patch extern void rom_Cache_Freeze_ICache_Enable(cache_freeze_mode_t mode); void Cache_Freeze_ICache_Enable(cache_freeze_mode_t mode) @@ -81,4 +86,72 @@ void Cache_Freeze_DCache_Enable(cache_freeze_mode_t mode) Cache_Wait_Idle(0); } extern void Cache_Freeze_DCache_Enable(cache_freeze_mode_t mode); -#endif +#endif //#if SOC_CACHE_FREEZE_SUPPORTED +#endif //#if ESP_ROM_HAS_CACHE_SUSPEND_WAITI_BUG + +#if ESP_ROM_HAS_CACHE_WRITEBACK_BUG +/* Defined in esp_rom_cache_writeback_esp32s3.S */ +extern void cache_writeback_items_freeze(uint32_t addr, uint32_t items); +// renamed for patch +extern int rom_Cache_WriteBack_Addr(uint32_t addr, uint32_t size); +int Cache_WriteBack_Addr(uint32_t addr, uint32_t size) +{ + /* Do special processing for unaligned memory at the start and end of the cache writeback memory. + * 1. Disable the interrupt to prevent the current CPU accessing the same cacheline. + * 2. Enable dcache freeze to prevent the another CPU accessing the same cacheline. + */ + uint32_t irq_status; + uint32_t start_len, end_len; + uint32_t start, end; + uint32_t dcache_line_size; + uint32_t autoload; + int ret = 0; + start = addr; + end = addr + size; + dcache_line_size = Cache_Get_DCache_Line_Size(); + + if (size == 0) { + return 0; + } + + /*the start address is unaligned*/ + if (start & (dcache_line_size -1)) { + addr = ALIGN_UP(start, dcache_line_size); + start_len = addr - start; + size = (size < start_len) ? 0 : (size - start_len); + + /*writeback start unaligned mem, one cacheline*/ + irq_status = XTOS_SET_INTLEVEL(XCHAL_NMILEVEL);//mask all interrupts + cache_writeback_items_freeze(start, 1); + XTOS_RESTORE_INTLEVEL(irq_status); + + if (size == 0) { + return 0; + } + } + + /*the end address is unaligned*/ + if (end & (dcache_line_size -1)) { + end = ALIGN_DOWN(end, dcache_line_size); + end_len = addr + size - end; + size = (size - end_len); + + /*writeback end unaligned mem, one cacheline*/ + irq_status = XTOS_SET_INTLEVEL(XCHAL_NMILEVEL);//mask all interrupts + cache_writeback_items_freeze(end, 1); + XTOS_RESTORE_INTLEVEL(irq_status); + + if (size == 0) { + return 0; + } + } + + /*suspend autoload, avoid load cachelines being written back*/ + autoload = Cache_Suspend_DCache_Autoload(); + ret = rom_Cache_WriteBack_Addr(addr, size); + Cache_Resume_DCache_Autoload(autoload); + + return ret; +} +extern int Cache_WriteBack_Addr(uint32_t addr, uint32_t size); +#endif //#if ESP_ROM_HAS_CACHE_WRITEBACK_BUG diff --git a/components/esp_rom/patches/esp_rom_cache_writeback_esp32s3.S b/components/esp_rom/patches/esp_rom_cache_writeback_esp32s3.S new file mode 100644 index 0000000000..1c87329b0e --- /dev/null +++ b/components/esp_rom/patches/esp_rom_cache_writeback_esp32s3.S @@ -0,0 +1,132 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "esp_bit_defs.h" +#include "soc/extmem_reg.h" + +/** + * @brief Write back the cache items of DCache, enable cache freeze during writeback. + * Operation will be done CACHE_LINE_SIZE aligned. + * If the region is not in DCache addr room, nothing will be done. + * Please do not call this function in your SDK application. + * @param uint32_t addr: start address to write back + * @param uint32_t items: cache lines to invalidate, items * cache_line_size should + * not exceed the bus address size(4MB) + * + * void cache_writeback_items_freeze(uint32_t addr, uint32_t items) +*/ + +/******************************************************************************* + +This function is a cache write-back function that works around the following +hardware errata on the ESP32-S3: + +- Core X manually triggers (via the EXTMEM_DCACHE_SYNC_CTRL_REG register) the +write-back of one or more cache lines. +- While the write-back is in progress, there are two scenarios that may cause +cache hit error. + - Core X enters the interrupt handler and access the same cache line + being written back. + - Core Y access the same cache line being written back. + +To workaround this errata, the following steps must be taken when manually +triggering a cache write-back: + +- Core X must disable interrupts so that it cannot be preempted +- Core X must freeze the cache (via the EXTMEM_DCACHE_FREEZE_REG register) to +prevent Core Y from accessing the same cache lines that are about to be written +back. +- Core X now triggers the cache write-back. During the write-back... + - If Core Y attempts the access any address in the cache region, Core Y will + busy wait until the cache is unfrozen. + - Core X must ensure that it does not access any address in the cache region, + otherwise Core X will busy wait thus causing a deadlock. +- After the write-back is complete, Core X unfreezes the cache, and reenables +interrupts. + +Notes: + +- Please do not modify this function, it must strictly follow the current execution +sequence, otherwise it may cause unexpected errors. +- This function is written in assmebly to ensure that the function itself never +accesses any cache address while the cache is frozen. Unexpected cache access +could occur if... + - the function triggers an window overflow onto a stack placed in PSRAM. + Thus, we only use two window panes (a0 to a8) in this function and trigger + all window overflows before freezing the cache. + - the function accesses literals/read-only variables placed in Flash. + +*******************************************************************************/ + + .align 4 + /* + Create dedicated literal pool for this function. Mostly used to store out + of range movi transformations. + */ + .literal_position + .global cache_writeback_items_freeze + .type cache_writeback_items_freeze, @function +cache_writeback_items_freeze: + entry sp, 32 + + /* REG_WRITE(EXTMEM_DCACHE_SYNC_ADDR_REG, addr); */ + movi a4, EXTMEM_DCACHE_SYNC_ADDR_REG + s32i a2, a4, 0 + /* REG_WRITE(EXTMEM_DCACHE_SYNC_SIZE_REG, items); */ + movi a4, EXTMEM_DCACHE_SYNC_SIZE_REG + s32i a3, a4, 0 + memw /* About to freeze the cache. Ensure all previous memory R/W are completed */ + + movi a2, EXTMEM_DCACHE_FREEZE_REG + movi a3, EXTMEM_DCACHE_SYNC_CTRL_REG + + /* + REG_CLR_BIT(EXTMEM_DCACHE_FREEZE_REG, EXTMEM_DCACHE_FREEZE_MODE); + REG_SET_BIT(EXTMEM_DCACHE_FREEZE_REG, EXTMEM_DCACHE_FREEZE_ENA); + */ + l32i a4, a2, 0 /* a4 = *(EXTMEM_DCACHE_FREEZE_REG) */ + movi a5, ~(EXTMEM_DCACHE_FREEZE_MODE_M) + and a4, a4, a5 + movi a5, EXTMEM_DCACHE_FREEZE_ENA_M + or a4, a4, a5 + s32i a4, a2, 0 /* *(EXTMEM_DCACHE_FREEZE_REG) = a4 */ + + /* while (!REG_GET_BIT(EXTMEM_DCACHE_FREEZE_REG, EXTMEM_DCACHE_FREEZE_DONE)); */ + movi a5, EXTMEM_DCACHE_FREEZE_DONE_M +_wait_freeze_done: + l32i a4, a2, 0 /* a4 = *(EXTMEM_DCACHE_FREEZE_REG) */ + memw + bnone a4, a5, _wait_freeze_done + + /* REG_SET_BIT(EXTMEM_DCACHE_SYNC_CTRL_REG, EXTMEM_DCACHE_WRITEBACK_ENA); */ + l32i a4, a3, 0 /* a4 = *(EXTMEM_DCACHE_SYNC_CTRL_REG) */ + movi a5, EXTMEM_DCACHE_WRITEBACK_ENA_M + or a4, a4, a5 + s32i a4, a3, 0 /* *(EXTMEM_DCACHE_SYNC_CTRL_REG) = a4 */ + + /* while(!REG_GET_BIT(EXTMEM_DCACHE_SYNC_CTRL_REG, EXTMEM_DCACHE_SYNC_DONE)); */ + movi a5, EXTMEM_DCACHE_SYNC_DONE_M +_wait_writeback_done: + l32i a4, a3, 0 /* a4 = *(EXTMEM_DCACHE_SYNC_CTRL_REG) */ + memw + bnone a4, a5, _wait_writeback_done + + /* REG_CLR_BIT(EXTMEM_DCACHE_FREEZE_REG, EXTMEM_DCACHE_FREEZE_ENA); */ + l32i a4, a2, 0 /* a4 = *(EXTMEM_DCACHE_FREEZE_REG) */ + movi a5, ~(EXTMEM_DCACHE_FREEZE_ENA_M) + and a4, a4, a5 + s32i a4, a2, 0 /* *(EXTMEM_DCACHE_FREEZE_REG) = a4 */ + + /* while (REG_GET_BIT(EXTMEM_DCACHE_FREEZE_REG, EXTMEM_DCACHE_FREEZE_DONE)); */ + movi a5, EXTMEM_DCACHE_FREEZE_DONE_M +_wait_unfreeze_done: + l32i a4, a2, 0 /* a4 = *(EXTMEM_DCACHE_FREEZE_REG) */ + memw + bany a4, a5, _wait_unfreeze_done + + retw + .size cache_writeback_items_freeze, . - cache_writeback_items_freeze diff --git a/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c6.c b/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c6.c new file mode 100644 index 0000000000..f89538d210 --- /dev/null +++ b/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c6.c @@ -0,0 +1,188 @@ +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_rom_sys.h" +#include "esp_attr.h" +#include "soc/i2c_ana_mst_reg.h" +#include "modem/modem_lpcon_reg.h" +/** + * BB - 0x67 - BIT0 + * TXRF - 0x6B - BIT1 + * SDM - 0x63 - BIT2 + * PLL - 0x62 - BIT3 + * BIAS - 0x6A - BIT4 + * BBPLL - 0x66 - BIT5 + * ULP - 0x61 - BIT6 + * SAR - 0x69 - BIT7 + * PMU - 0x6d - BIT8 +*/ + +#define REGI2C_BIAS_MST_SEL (BIT(8)) +#define REGI2C_BBPLL_MST_SEL (BIT(9)) +#define REGI2C_ULP_CAL_MST_SEL (BIT(10)) +#define REGI2C_SAR_I2C_MST_SEL (BIT(11)) +#define REGI2C_DIG_REG_MST_SEL (BIT(12)) + +#define REGI2C_BIAS_RD_MASK (~BIT(6) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_BBPLL_RD_MASK (~BIT(7) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_ULP_CAL_RD_MASK (~BIT(8) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_SAR_I2C_RD_MASK (~BIT(9) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_DIG_REG_RD_MASK (~BIT(10) & I2C_ANA_MST_ANA_CONF1_M) + +#define I2C_ANA_MST_I2C_CTRL_REG(n) (I2C_ANA_MST_I2C0_CTRL_REG + n*4) // 0: I2C_ANA_MST_I2C0_CTRL_REG; 1: I2C_ANA_MST_I2C1_CTRL_REG + +#define REGI2C_RTC_BUSY (BIT(25)) +#define REGI2C_RTC_BUSY_M (BIT(25)) +#define REGI2C_RTC_BUSY_V 0x1 +#define REGI2C_RTC_BUSY_S 25 + +#define REGI2C_RTC_WR_CNTL (BIT(24)) +#define REGI2C_RTC_WR_CNTL_M (BIT(24)) +#define REGI2C_RTC_WR_CNTL_V 0x1 +#define REGI2C_RTC_WR_CNTL_S 24 + +#define REGI2C_RTC_DATA 0x000000FF +#define REGI2C_RTC_DATA_M ((I2C_RTC_DATA_V)<<(I2C_RTC_DATA_S)) +#define REGI2C_RTC_DATA_V 0xFF +#define REGI2C_RTC_DATA_S 16 + +#define REGI2C_RTC_ADDR 0x000000FF +#define REGI2C_RTC_ADDR_M ((I2C_RTC_ADDR_V)<<(I2C_RTC_ADDR_S)) +#define REGI2C_RTC_ADDR_V 0xFF +#define REGI2C_RTC_ADDR_S 8 + +#define REGI2C_RTC_SLAVE_ID 0x000000FF +#define REGI2C_RTC_SLAVE_ID_M ((I2C_RTC_SLAVE_ID_V)<<(I2C_RTC_SLAVE_ID_S)) +#define REGI2C_RTC_SLAVE_ID_V 0xFF +#define REGI2C_RTC_SLAVE_ID_S 0 + +/* SLAVE */ + +#define REGI2C_BBPLL (0x66) +#define REGI2C_BBPLL_HOSTID 0 + +#define REGI2C_BIAS (0x6a) +#define REGI2C_BIAS_HOSTID 0 + +#define REGI2C_DIG_REG (0x6d) +#define REGI2C_DIG_REG_HOSTID 0 + +#define REGI2C_ULP_CAL (0x61) +#define REGI2C_ULP_CAL_HOSTID 0 + +#define REGI2C_SAR_I2C (0x69) +#define REGI2C_SAR_I2C_HOSTID 0 + +/* SLAVE END */ + +uint8_t esp_rom_regi2c_read(uint8_t block, uint8_t host_id, uint8_t reg_add) __attribute__((alias("regi2c_read_impl"))); +uint8_t esp_rom_regi2c_read_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) __attribute__((alias("regi2c_read_mask_impl"))); +void esp_rom_regi2c_write(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) __attribute__((alias("regi2c_write_impl"))); +void esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) __attribute__((alias("regi2c_write_mask_impl"))); + +static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block) +{ + uint32_t i2c_sel = 0; + + REG_SET_BIT(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); + REG_SET_BIT(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M); + + /* Before config I2C register, enable corresponding slave. */ + switch (block) { + case REGI2C_BBPLL : + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_BBPLL_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_BBPLL_RD_MASK); + break; + case REGI2C_BIAS : + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_BIAS_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_BIAS_RD_MASK); + break; + case REGI2C_DIG_REG: + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_DIG_REG_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_DIG_REG_RD_MASK); + break; + case REGI2C_ULP_CAL: + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_ULP_CAL_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_ULP_CAL_RD_MASK); + break; + case REGI2C_SAR_I2C: + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_SAR_I2C_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_SAR_I2C_RD_MASK); + break; + } + + return (uint8_t)(i2c_sel ? 0: 1); +} + +uint8_t IRAM_ATTR regi2c_read_impl(uint8_t block, uint8_t host_id, uint8_t reg_add) +{ + (void)host_id; + uint8_t i2c_sel = regi2c_enable_block(block); + + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + uint8_t ret = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); + + return ret; +} + +uint8_t IRAM_ATTR regi2c_read_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) +{ + assert(msb - lsb < 8); + uint8_t i2c_sel = regi2c_enable_block(block); + + (void)host_id; + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + uint32_t data = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); + uint8_t ret = (uint8_t)((data >> lsb) & (~(0xFFFFFFFF << (msb - lsb + 1)))); + + return ret; +} + +void IRAM_ATTR regi2c_write_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) +{ + (void)host_id; + uint8_t i2c_sel = regi2c_enable_block(block); + + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S) + | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) // 0: READ I2C register; 1: Write I2C register; + | (((uint32_t)data & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + +} + +void IRAM_ATTR regi2c_write_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) +{ + (void)host_id; + assert(msb - lsb < 8); + uint8_t i2c_sel = regi2c_enable_block(block); + + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + /*Read the i2c bus register*/ + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + temp = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); + /*Write the i2c bus register*/ + temp &= ((~(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1))); + temp = (((uint32_t)data & (~(0xFFFFFFFF << (msb - lsb + 1)))) << lsb) | temp; + temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S) + | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) + | ((temp & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); +} diff --git a/components/esp_rom/patches/esp_rom_regi2c_esp32c6.c b/components/esp_rom/patches/esp_rom_regi2c_esp32c6.c deleted file mode 100644 index 2923aacb0a..0000000000 --- a/components/esp_rom/patches/esp_rom_regi2c_esp32c6.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "esp_rom_sys.h" -#include "esp_attr.h" -#include "soc/lp_i2c_ana_mst_reg.h" -#include "modem/modem_lpcon_reg.h" -/** - * BB - 0x67 - BIT0 - * TXRF - 0x6B - BIT1 - * SDM - 0x63 - BIT2 - * PLL - 0x62 - BIT3 - * BIAS - 0x6A - BIT4 - * BBPLL - 0x66 - BIT5 - * ULP - 0x61 - BIT6 - * SAR - 0x69 - BIT7 - * PMU - 0x6d - BIT8 -*/ -#define REGI2C_ULP_CAL_DEVICE_EN (BIT(6)) -#define REGI2C_SAR_I2C_DEVICE_EN (BIT(7)) -#define REGI2C_BBPLL_DEVICE_EN (BIT(5)) -#define REGI2C_BIAS_DEVICE_EN (BIT(4)) -#define REGI2C_DIG_REG_DEVICE_EN (BIT(8)) - -#define REGI2C_RTC_BUSY (BIT(25)) -#define REGI2C_RTC_BUSY_M (BIT(25)) -#define REGI2C_RTC_BUSY_V 0x1 -#define REGI2C_RTC_BUSY_S 25 - -#define REGI2C_RTC_WR_CNTL (BIT(24)) -#define REGI2C_RTC_WR_CNTL_M (BIT(24)) -#define REGI2C_RTC_WR_CNTL_V 0x1 -#define REGI2C_RTC_WR_CNTL_S 24 - -#define REGI2C_RTC_DATA 0x000000FF -#define REGI2C_RTC_DATA_M ((I2C_RTC_DATA_V)<<(I2C_RTC_DATA_S)) -#define REGI2C_RTC_DATA_V 0xFF -#define REGI2C_RTC_DATA_S 16 - -#define REGI2C_RTC_ADDR 0x000000FF -#define REGI2C_RTC_ADDR_M ((I2C_RTC_ADDR_V)<<(I2C_RTC_ADDR_S)) -#define REGI2C_RTC_ADDR_V 0xFF -#define REGI2C_RTC_ADDR_S 8 - -#define REGI2C_RTC_SLAVE_ID 0x000000FF -#define REGI2C_RTC_SLAVE_ID_M ((I2C_RTC_SLAVE_ID_V)<<(I2C_RTC_SLAVE_ID_S)) -#define REGI2C_RTC_SLAVE_ID_V 0xFF -#define REGI2C_RTC_SLAVE_ID_S 0 - -/* SLAVE */ - -#define REGI2C_BBPLL (0x66) -#define REGI2C_BBPLL_HOSTID 0 - -#define REGI2C_BIAS (0x6a) -#define REGI2C_BIAS_HOSTID 0 - -#define REGI2C_DIG_REG (0x6d) -#define REGI2C_DIG_REG_HOSTID 0 - -#define REGI2C_ULP_CAL (0x61) -#define REGI2C_ULP_CAL_HOSTID 0 - -#define REGI2C_SAR_I2C (0x69) -#define REGI2C_SAR_I2C_HOSTID 0 - -/* SLAVE END */ - -#define REGI2C_RTC_MAGIC_DEFAULT (0x1C610) - -static IRAM_ATTR void regi2c_enable_block(uint8_t block) -{ - REG_SET_BIT(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); - REG_SET_BIT(LP_I2C_ANA_MST_DATE_REG, LP_I2C_ANA_MST_I2C_MAT_CLK_EN); - - /* Before config I2C register, enable corresponding slave. */ - switch (block) { - case REGI2C_BBPLL : - REG_SET_BIT(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BBPLL_DEVICE_EN); - break; - case REGI2C_BIAS : - REG_SET_BIT(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BIAS_DEVICE_EN); - break; - case REGI2C_DIG_REG: - REG_SET_BIT(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_DIG_REG_DEVICE_EN); - break; - case REGI2C_ULP_CAL: - REG_SET_BIT(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_ULP_CAL_DEVICE_EN); - break; - case REGI2C_SAR_I2C: - REG_SET_BIT(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_SAR_I2C_DEVICE_EN); - break; - default: - return; - } -} - -static IRAM_ATTR void regi2c_disable_block(uint8_t block) -{ - switch (block) { - case REGI2C_BBPLL : - REG_CLR_BIT(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BBPLL_DEVICE_EN); - break; - case REGI2C_BIAS : - REG_CLR_BIT(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BIAS_DEVICE_EN); - break; - case REGI2C_DIG_REG: - REG_CLR_BIT(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_DIG_REG_DEVICE_EN); - break; - case REGI2C_ULP_CAL: - REG_CLR_BIT(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_ULP_CAL_DEVICE_EN); - break; - case REGI2C_SAR_I2C: - REG_CLR_BIT(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_SAR_I2C_DEVICE_EN); - break; - default: - return; - } -} - -uint8_t IRAM_ATTR esp_rom_regi2c_read(uint8_t block, uint8_t host_id, uint8_t reg_add) -{ - regi2c_enable_block(block); - - (void)host_id; - uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) - | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; - REG_WRITE(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); - while (REG_GET_BIT(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY)); - uint8_t ret = REG_GET_FIELD(LP_I2C_ANA_MST_I2C0_DATA_REG, LP_I2C_ANA_MST_I2C0_RDATA); - - regi2c_disable_block(block); - - return ret; -} - -uint8_t IRAM_ATTR esp_rom_regi2c_read_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) -{ - assert(msb - lsb < 8); - regi2c_enable_block(block); - - (void)host_id; - uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) - | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; - REG_WRITE(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); - while (REG_GET_BIT(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY)); - uint32_t data = REG_GET_FIELD(LP_I2C_ANA_MST_I2C0_DATA_REG, LP_I2C_ANA_MST_I2C0_RDATA); - uint8_t ret = (uint8_t)((data >> lsb) & (~(0xFFFFFFFF << (msb - lsb + 1)))); - - regi2c_disable_block(block); - - return ret; -} - -void IRAM_ATTR esp_rom_regi2c_write(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) -{ - (void)host_id; - regi2c_enable_block(block); - - uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) - | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S) - | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) // 0: READ I2C register; 1: Write I2C register; - | (((uint32_t)data & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S); - REG_WRITE(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); - while (REG_GET_BIT(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY)); - - regi2c_disable_block(block); -} - -void IRAM_ATTR esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) -{ - (void)host_id; - assert(msb - lsb < 8); - regi2c_enable_block(block); - - /*Read the i2c bus register*/ - uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) - | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; - REG_WRITE(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); - while (REG_GET_BIT(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY)); - temp = REG_GET_FIELD(LP_I2C_ANA_MST_I2C0_DATA_REG, LP_I2C_ANA_MST_I2C0_RDATA); - /*Write the i2c bus register*/ - temp &= ((~(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1))); - temp = (((uint32_t)data & (~(0xFFFFFFFF << (msb - lsb + 1)))) << lsb) | temp; - temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) - | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S) - | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) - | ((temp & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S); - REG_WRITE(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); - while (REG_GET_BIT(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY)); - - regi2c_disable_block(block); -} diff --git a/components/esp_rom/patches/esp_rom_regi2c_esp32h2.c b/components/esp_rom/patches/esp_rom_regi2c_esp32h2.c index 15df5014df..05ffae9d6b 100644 --- a/components/esp_rom/patches/esp_rom_regi2c_esp32h2.c +++ b/components/esp_rom/patches/esp_rom_regi2c_esp32h2.c @@ -19,11 +19,20 @@ * SAR - 0x69 - BIT7 * PMU - 0x6d - BIT8 */ -#define REGI2C_ULP_CAL_DEVICE_EN (BIT(6) << 4) -#define REGI2C_SAR_I2C_DEVICE_EN (BIT(7) << 4) -#define REGI2C_BBPLL_DEVICE_EN (BIT(5) << 4) -#define REGI2C_BIAS_DEVICE_EN (BIT(4) << 4) -#define REGI2C_PMU_DEVICE_EN (BIT(8) << 4) + +#define REGI2C_BIAS_MST_SEL (BIT(8)) +#define REGI2C_BBPLL_MST_SEL (BIT(9)) +#define REGI2C_ULP_CAL_MST_SEL (BIT(10)) +#define REGI2C_SAR_I2C_MST_SEL (BIT(11)) +#define REGI2C_DIG_REG_MST_SEL (BIT(12)) + +#define REGI2C_BIAS_RD_MASK (~BIT(6) & I2C_MST_ANA_CONF1_M) +#define REGI2C_BBPLL_RD_MASK (~BIT(7) & I2C_MST_ANA_CONF1_M) +#define REGI2C_ULP_CAL_RD_MASK (~BIT(8) & I2C_MST_ANA_CONF1_M) +#define REGI2C_SAR_I2C_RD_MASK (~BIT(9) & I2C_MST_ANA_CONF1_M) +#define REGI2C_DIG_REG_RD_MASK (~BIT(10) & I2C_MST_ANA_CONF1_M) + +#define I2C_ANA_MST_I2C_CTRL_REG(n) (I2C_MST_I2C0_CTRL_REG + n*4) // 0: I2C_ANA_MST_I2C0_CTRL_REG; 1: I2C_ANA_MST_I2C1_CTRL_REG #define REGI2C_RTC_BUSY (BIT(25)) #define REGI2C_RTC_BUSY_M (BIT(25)) @@ -69,117 +78,103 @@ /* SLAVE END */ -static IRAM_ATTR void regi2c_enable_block(uint8_t block) +uint8_t esp_rom_regi2c_read(uint8_t block, uint8_t host_id, uint8_t reg_add) __attribute__((alias("regi2c_read_impl"))); +uint8_t esp_rom_regi2c_read_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) __attribute__((alias("regi2c_read_mask_impl"))); +void esp_rom_regi2c_write(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) __attribute__((alias("regi2c_write_impl"))); +void esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) __attribute__((alias("regi2c_write_mask_impl"))); + +static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block) { + uint32_t i2c_sel = 0; REG_SET_BIT(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); - REG_SET_BIT(I2C_MST_DATE_REG, I2C_MST_CLK_EN); - REG_SET_FIELD(I2C_MST_ANA_CONF2_REG, I2C_MST_ANA_CONF2, 0); - /* Before config I2C register, enable corresponding slave. */ - switch (block) { - case REGI2C_BBPLL : - REG_SET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_BBPLL_DEVICE_EN); - break; - case REGI2C_BIAS : - REG_SET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_BIAS_DEVICE_EN); - break; - case REGI2C_PMU : - REG_SET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_PMU_DEVICE_EN); - break; - case REGI2C_ULP_CAL: - REG_SET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_ULP_CAL_DEVICE_EN); - break; - case REGI2C_SAR_I2C: - REG_SET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_SAR_I2C_DEVICE_EN); - break; - default: - return; - } -} -static IRAM_ATTR void regi2c_disable_block(uint8_t block) -{ + /* Before config I2C register, enable corresponding slave. */ switch (block) { case REGI2C_BBPLL : - REG_SET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_BBPLL_DEVICE_EN); + i2c_sel = REG_GET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_BBPLL_MST_SEL); + REG_WRITE(I2C_MST_ANA_CONF1_REG, REGI2C_BBPLL_RD_MASK); break; case REGI2C_BIAS : - REG_SET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_BIAS_DEVICE_EN); + i2c_sel = REG_GET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_BIAS_MST_SEL); + REG_WRITE(I2C_MST_ANA_CONF1_REG, REGI2C_BIAS_RD_MASK); break; case REGI2C_PMU: - REG_SET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_PMU_DEVICE_EN); + i2c_sel = REG_GET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_DIG_REG_MST_SEL); + REG_WRITE(I2C_MST_ANA_CONF1_REG, REGI2C_DIG_REG_RD_MASK); break; case REGI2C_ULP_CAL: - REG_SET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_ULP_CAL_DEVICE_EN); + i2c_sel = REG_GET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_ULP_CAL_MST_SEL); + REG_WRITE(I2C_MST_ANA_CONF1_REG, REGI2C_ULP_CAL_RD_MASK); break; case REGI2C_SAR_I2C: - REG_SET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_SAR_I2C_DEVICE_EN); + i2c_sel = REG_GET_BIT(I2C_MST_ANA_CONF2_REG, REGI2C_SAR_I2C_MST_SEL); + REG_WRITE(I2C_MST_ANA_CONF1_REG, REGI2C_SAR_I2C_RD_MASK); break; - default: - return; } + + return (uint8_t)(i2c_sel ? 0: 1); } -uint8_t IRAM_ATTR esp_rom_regi2c_read(uint8_t block, uint8_t host_id, uint8_t reg_add) +uint8_t IRAM_ATTR regi2c_read_impl(uint8_t block, uint8_t host_id, uint8_t reg_add) { - regi2c_enable_block(block); - (void)host_id; + uint8_t i2c_sel = regi2c_enable_block(block); + + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; - REG_WRITE(I2C_MST_I2C0_CTRL_REG, temp); - while (REG_GET_BIT(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY)); - uint8_t ret = REG_GET_FIELD(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_DATA); - - regi2c_disable_block(block); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + uint8_t ret = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); return ret; } -uint8_t IRAM_ATTR esp_rom_regi2c_read_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) +uint8_t IRAM_ATTR regi2c_read_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) { assert(msb - lsb < 8); - regi2c_enable_block(block); + uint8_t i2c_sel = regi2c_enable_block(block); (void)host_id; + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; - REG_WRITE(I2C_MST_I2C0_CTRL_REG, temp); - while (REG_GET_BIT(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY)); - uint32_t data = REG_GET_FIELD(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_DATA); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + uint32_t data = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); uint8_t ret = (uint8_t)((data >> lsb) & (~(0xFFFFFFFF << (msb - lsb + 1)))); - regi2c_disable_block(block); - return ret; } -void IRAM_ATTR esp_rom_regi2c_write(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) +void IRAM_ATTR regi2c_write_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) { (void)host_id; - regi2c_enable_block(block); + uint8_t i2c_sel = regi2c_enable_block(block); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S) | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) // 0: READ I2C register; 1: Write I2C register; | (((uint32_t)data & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S); - REG_WRITE(I2C_MST_I2C0_CTRL_REG, temp); - while (REG_GET_BIT(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY)); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); - regi2c_disable_block(block); } -void IRAM_ATTR esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) +void IRAM_ATTR regi2c_write_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) { (void)host_id; assert(msb - lsb < 8); - regi2c_enable_block(block); + uint8_t i2c_sel = regi2c_enable_block(block); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); /*Read the i2c bus register*/ uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; - REG_WRITE(I2C_MST_I2C0_CTRL_REG, temp); - while (REG_GET_BIT(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY)); - temp = REG_GET_FIELD(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_DATA); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + temp = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); /*Write the i2c bus register*/ temp &= ((~(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1))); temp = (((uint32_t)data & (~(0xFFFFFFFF << (msb - lsb + 1)))) << lsb) | temp; @@ -187,8 +182,6 @@ void IRAM_ATTR esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S) | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) | ((temp & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S); - REG_WRITE(I2C_MST_I2C0_CTRL_REG, temp); - while (REG_GET_BIT(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY)); - - regi2c_disable_block(block); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); } diff --git a/components/esp_rom/patches/esp_rom_spiflash.c b/components/esp_rom/patches/esp_rom_spiflash.c index 4c87e73bc2..fb525244db 100644 --- a/components/esp_rom/patches/esp_rom_spiflash.c +++ b/components/esp_rom/patches/esp_rom_spiflash.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 */ @@ -11,6 +11,9 @@ #include "esp32/rom/spi_flash.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/spi_flash.h" +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/spi_flash.h" +#include "esp32s3/rom/opi_flash.h" #endif #define SPI_IDX 1 @@ -697,6 +700,31 @@ esp_rom_spiflash_result_t esp_rom_spiflash_write_disable(void) return ESP_ROM_SPIFLASH_RESULT_OK; } +#elif CONFIG_IDF_TARGET_ESP32S3 +extern void esp_rom_spi_set_address_bit_len(int spi, int addr_bits); +void esp_rom_opiflash_cache_mode_config(esp_rom_spiflash_read_mode_t mode, const esp_rom_opiflash_spi0rd_t *cache) +{ + esp_rom_spi_set_op_mode(0, mode); + REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI); + REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR); + + if (cache) { + esp_rom_spi_set_address_bit_len(0, cache->addr_bit_len); + // Patch for ROM function `esp_rom_opiflash_cache_mode_config`, because when dummy is 0, + // `SPI_MEM_USR_DUMMY` should be 0. `esp_rom_opiflash_cache_mode_config` doesn't handle this + // properly. + if (cache->dummy_bit_len == 0) { + REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY); + } else { + REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY); + REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, cache->dummy_bit_len - 1 + rom_spiflash_legacy_data->dummy_len_plus[0]); + } + REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, cache->cmd); + REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_BITLEN, cache->cmd_bit_len - 1); + REG_SET_FIELD(SPI_MEM_DDR_REG(0), SPI_MEM_SPI_FMEM_VAR_DUMMY, cache->var_dummy_en); + } +} + #endif // IDF_TARGET #endif // CONFIG_SPI_FLASH_ROM_DRIVER_PATCH diff --git a/components/esp_rom/patches/esp_rom_tlsf.c b/components/esp_rom/patches/esp_rom_tlsf.c index 088248acce..06da058328 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/esp_system/Kconfig b/components/esp_system/Kconfig index 3006f40b60..f3ab7b0c80 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -561,6 +561,15 @@ menu "ESP System Settings" (2). For special workflow, the chip needs do more things instead of restarting directly. This part needs to be done in callback function of interrupt. + config ESP_SYSTEM_BBPLL_RECALIB + bool "Re-calibration BBPLL at startup" + depends on IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32H2 + default y + help + This configuration helps to address an BBPLL inaccurate issue when boot from certain bootloader version, + which may increase about the boot-up time by about 200 us. Disable this when your bootloader is built with + ESP-IDF version v5.2 and above. + endmenu # ESP System Settings menu "IPC (Inter-Processor Call)" diff --git a/components/esp_system/esp_ipc.c b/components/esp_system/esp_ipc.c index e536a09c5b..0f1deb9fb4 100644 --- a/components/esp_system/esp_ipc.c +++ b/components/esp_system/esp_ipc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,11 +12,14 @@ #include "esp_ipc.h" #include "esp_private/esp_ipc_isr.h" #include "esp_attr.h" +#include "esp_cpu.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" +#define IPC_MAX_PRIORITY (configMAX_PRIORITIES - 1) + #if !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE) #if CONFIG_COMPILER_OPTIMIZATION_NONE @@ -39,10 +42,11 @@ typedef enum { IPC_WAIT_FOR_END, } esp_ipc_wait_t; -#if CONFIG_APPTRACE_GCOV_ENABLE -static volatile esp_ipc_func_t s_gcov_func = NULL; // Gcov dump starter function which should be called by high priority task -static void * volatile s_gcov_func_arg; // Argument to pass into s_gcov_func -#endif +static esp_ipc_wait_t volatile s_wait_for[portNUM_PROCESSORS]; + +static volatile esp_ipc_func_t s_no_block_func[portNUM_PROCESSORS] = { 0 }; +static volatile bool s_no_block_func_and_arg_are_ready[portNUM_PROCESSORS] = { 0 }; +static void * volatile s_no_block_func_arg[portNUM_PROCESSORS]; static void IRAM_ATTR ipc_task(void* arg) { @@ -54,29 +58,23 @@ static void IRAM_ATTR ipc_task(void* arg) #endif while (true) { - uint32_t ipc_wait; - xTaskNotifyWait(0, ULONG_MAX, &ipc_wait, portMAX_DELAY); - -#if CONFIG_APPTRACE_GCOV_ENABLE - if (s_gcov_func) { - (*s_gcov_func)(s_gcov_func_arg); - s_gcov_func = NULL; - /* we can not interfer with IPC calls so no need for further processing */ - // esp_ipc API and gcov_from_isr APIs can be processed together if they came at the same time - if (ipc_wait == IPC_WAIT_NO) { - continue; - } + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + if (s_no_block_func_and_arg_are_ready[cpuid] && s_no_block_func[cpuid]) { + (*s_no_block_func[cpuid])(s_no_block_func_arg[cpuid]); + s_no_block_func_and_arg_are_ready[cpuid] = false; + s_no_block_func[cpuid] = NULL; } -#endif // CONFIG_APPTRACE_GCOV_ENABLE #ifndef CONFIG_FREERTOS_UNICORE if (s_func[cpuid]) { // we need to cache s_func, s_func_arg and ipc_ack variables locally // because they can be changed by a subsequent IPC call (after xTaskNotify(caller_task_handle)). esp_ipc_func_t func = s_func[cpuid]; - s_func[cpuid] = NULL; void* func_arg = s_func_arg[cpuid]; + esp_ipc_wait_t ipc_wait = s_wait_for[cpuid]; SemaphoreHandle_t ipc_ack = s_ipc_ack[cpuid]; + s_func[cpuid] = NULL; if (ipc_wait == IPC_WAIT_FOR_START) { xSemaphoreGive(ipc_ack); @@ -119,7 +117,7 @@ static void esp_ipc_init(void) s_ipc_mutex[i] = xSemaphoreCreateMutexStatic(&s_ipc_mutex_buffer[i]); s_ipc_ack[i] = xSemaphoreCreateBinaryStatic(&s_ipc_ack_buffer[i]); portBASE_TYPE res = xTaskCreatePinnedToCore(ipc_task, task_name, IPC_STACK_SIZE, (void*) i, - configMAX_PRIORITIES - 1, &s_ipc_task_handle[i], i); + IPC_MAX_PRIORITY, &s_ipc_task_handle[i], i); assert(res == pdTRUE); (void)res; } @@ -151,9 +149,11 @@ static esp_err_t esp_ipc_call_and_wait(uint32_t cpu_id, esp_ipc_func_t func, voi xSemaphoreTake(s_ipc_mutex[0], portMAX_DELAY); #endif - s_func[cpu_id] = func; s_func_arg[cpu_id] = arg; - xTaskNotify(s_ipc_task_handle[cpu_id], wait_for, eSetValueWithOverwrite); + s_wait_for[cpu_id] = wait_for; + // s_func must be set after all other parameters. The ipc_task use this as indicator of the IPC is prepared. + s_func[cpu_id] = func; + xTaskNotifyGive(s_ipc_task_handle[cpu_id]); xSemaphoreTake(s_ipc_ack[cpu_id], portMAX_DELAY); #ifdef CONFIG_ESP_IPC_USES_CALLERS_PRIORITY @@ -174,28 +174,33 @@ esp_err_t esp_ipc_call_blocking(uint32_t cpu_id, esp_ipc_func_t func, void* arg) return esp_ipc_call_and_wait(cpu_id, func, arg, IPC_WAIT_FOR_END); } -// currently this is only called from gcov component -// the top level guarantees that the next call will be only after the previous one has completed -#if CONFIG_APPTRACE_GCOV_ENABLE -esp_err_t esp_ipc_start_gcov_from_isr(uint32_t cpu_id, esp_ipc_func_t func, void* arg) +esp_err_t esp_ipc_call_nonblocking(uint32_t cpu_id, esp_ipc_func_t func, void* arg) { - if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) { + if (cpu_id >= portNUM_PROCESSORS || s_ipc_task_handle[cpu_id] == NULL) { + return ESP_ERR_INVALID_ARG; + } + if (cpu_id == xPortGetCoreID() && xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) { return ESP_ERR_INVALID_STATE; } - // Since it is called from an interrupt, it can not wait for a mutex to be released. - if (s_gcov_func == NULL) { - s_gcov_func_arg = arg; - s_gcov_func = func; + // Since it can be called from an interrupt or Scheduler is Suspened, it can not wait for a mutex to be released. + if (esp_cpu_compare_and_set((volatile uint32_t *)&s_no_block_func[cpu_id], 0, (uint32_t)func)) { + s_no_block_func_arg[cpu_id] = arg; + s_no_block_func_and_arg_are_ready[cpu_id] = true; - // If the target task already has a notification pending then its notification value is not updated (WithoutOverwrite). - xTaskNotifyFromISR(s_ipc_task_handle[cpu_id], IPC_WAIT_NO, eSetValueWithoutOverwrite, NULL); + if (xPortInIsrContext()) { + vTaskNotifyGiveFromISR(s_ipc_task_handle[cpu_id], NULL); + } else { +#ifdef CONFIG_ESP_IPC_USES_CALLERS_PRIORITY + vTaskPrioritySet(s_ipc_task_handle[cpu_id], IPC_MAX_PRIORITY); +#endif + xTaskNotifyGive(s_ipc_task_handle[cpu_id]); + } return ESP_OK; } // the previous call was not completed return ESP_FAIL; } -#endif // CONFIG_APPTRACE_GCOV_ENABLE #endif // !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE) diff --git a/components/esp_system/include/esp_ipc.h b/components/esp_system/include/esp_ipc.h index 3be0620d00..853463043d 100644 --- a/components/esp_system/include/esp_ipc.h +++ b/components/esp_system/include/esp_ipc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/esp_system/include/esp_private/esp_ipc.h b/components/esp_system/include/esp_private/esp_ipc.h new file mode 100644 index 0000000000..a71c9088cc --- /dev/null +++ b/components/esp_system/include/esp_private/esp_ipc.h @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "../esp_ipc.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE) + +/** + * @brief Execute a callback on a given CPU without any blocking operations for the caller + * + * Since it does not have any blocking operations it is suitable to be run from interrupts + * or even when the Scheduler on the current core is suspended. + * + * The function: + * - does not wait for the callback to begin or complete execution, + * - does not change the IPC priority. + * The function returns after sending a notification to the IPC task to execute the callback. + * + * @param[in] cpu_id CPU where the given function should be executed (0 or 1) + * @param[in] func Pointer to a function of type void func(void* arg) to be executed + * @param[in] arg Arbitrary argument of type void* to be passed into the function + * + * @return + * - ESP_ERR_INVALID_ARG if cpu_id is invalid + * - ESP_ERR_INVALID_STATE 1. IPC tasks have not been initialized yet, + * 2. cpu_id requests IPC on the current core, but the FreeRTOS scheduler is not running on it + * (the IPC task cannot be executed). + * - ESP_FAIL IPC is busy due to a previous call was not completed. + * - ESP_OK otherwise + */ +esp_err_t esp_ipc_call_nonblocking(uint32_t cpu_id, esp_ipc_func_t func, void* arg); + +#endif // !defined(CONFIG_FREERTOS_UNICORE) || defined(CONFIG_APPTRACE_GCOV_ENABLE) + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_system/include/esp_private/panic_internal.h b/components/esp_system/include/esp_private/panic_internal.h index bdf8a26420..9d35c7524d 100644 --- a/components/esp_system/include/esp_private/panic_internal.h +++ b/components/esp_system/include/esp_private/panic_internal.h @@ -9,6 +9,7 @@ #include #include +#include "esp_macros.h" #include "soc/soc_caps.h" #include "sdkconfig.h" @@ -19,7 +20,7 @@ extern "C" { #endif extern bool g_panic_abort; - +extern char *g_panic_abort_details; extern void *g_exc_frames[SOC_CPU_CORES_NUM]; // Function to print longer amounts of information such as the details @@ -62,10 +63,10 @@ void panic_print_str(const char *str); void panic_print_dec(int d); void panic_print_hex(int h); #else -#define panic_print_char(c) -#define panic_print_str(str) -#define panic_print_dec(d) -#define panic_print_hex(h) +#define panic_print_char(c) ESP_UNUSED(c) +#define panic_print_str(str) ESP_UNUSED(str) +#define panic_print_dec(d) ESP_UNUSED(d) +#define panic_print_hex(h) ESP_UNUSED(h) #endif void __attribute__((__noreturn__)) panic_abort(const char *details); diff --git a/components/esp_system/include/esp_private/usb_console.h b/components/esp_system/include/esp_private/usb_console.h index 1243b1325c..0440b01697 100644 --- a/components/esp_system/include/esp_private/usb_console.h +++ b/components/esp_system/include/esp_private/usb_console.h @@ -50,14 +50,46 @@ esp_err_t esp_usb_console_init(void); */ ssize_t esp_usb_console_write_buf(const char* buf, size_t size); +/** + * @brief Wait until all buffered USB CDC output is written + * + * @return ssize_t Number of bytes written, or -1 if the driver is not initialized + */ ssize_t esp_usb_console_flush(void); +/** + * @brief Read data from USB CDC + * + * May read less data than requested. + * + * @param buf Buffer to read data into + * @param buf_size Size of the buffer + * @return ssize_t Number of bytes written into the buffer, or -1 if the driver is not initialized + */ ssize_t esp_usb_console_read_buf(char* buf, size_t buf_size); +/** + * @brief Get the number of bytes available for reading from USB CDC + * + * @return ssize_t Number of bytes available, or -1 if the driver is not initialized + */ ssize_t esp_usb_console_available_for_read(void); +/** + * @brief Check if data can be written into USB CDC + * + * @return true if data can be written now without blocking + */ bool esp_usb_console_write_available(void); +/** + * @brief Set RX/TX callback functions to be called from ISR + * + * @param rx_cb RX callback function + * @param tx_cb TX callback function + * @param arg callback-specific context pointer + * @return ESP_OK if the callbacks were set, ESP_ERR_INVALID_STATE if the driver is not initialized + */ esp_err_t esp_usb_console_set_cb(esp_usb_console_cb_t rx_cb, esp_usb_console_cb_t tx_cb, void* arg); #ifdef __cplusplus diff --git a/components/esp_system/include/esp_system.h b/components/esp_system/include/esp_system.h index f3ee93c002..ebf58972f8 100644 --- a/components/esp_system/include/esp_system.h +++ b/components/esp_system/include/esp_system.h @@ -33,6 +33,11 @@ typedef enum { ESP_RST_DEEPSLEEP, //!< Reset after exiting deep sleep mode ESP_RST_BROWNOUT, //!< Brownout reset (software or hardware) ESP_RST_SDIO, //!< Reset over SDIO + ESP_RST_USB, //!< Reset by USB peripheral + ESP_RST_JTAG, //!< Reset by JTAG + ESP_RST_EFUSE, //!< Reset due to efuse error + ESP_RST_PWR_GLITCH, //!< Reset due to power glitch detected + ESP_RST_CPU_LOCKUP, //!< Reset due to CPU lock up } esp_reset_reason_t; /** diff --git a/components/esp_system/include/esp_task.h b/components/esp_system/include/esp_task.h index f292e78dfa..61824fb8b0 100644 --- a/components/esp_system/include/esp_task.h +++ b/components/esp_system/include/esp_task.h @@ -50,7 +50,7 @@ #else #define ESP_TASKD_EVENT_STACK (CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE + TASK_EXTRA_STACK_SIZE) #endif /* CONFIG_LWIP_TCPIP_CORE_LOCKING */ -#define ESP_TASK_TCPIP_PRIO (ESP_TASK_PRIO_MAX - 7) +#define ESP_TASK_TCPIP_PRIO (CONFIG_LWIP_TCPIP_TASK_PRIO) #define ESP_TASK_TCPIP_STACK (CONFIG_LWIP_TCPIP_TASK_STACK_SIZE + TASK_EXTRA_STACK_SIZE) #define ESP_TASK_MAIN_PRIO (ESP_TASK_PRIO_MIN + 1) #define ESP_TASK_MAIN_STACK (CONFIG_ESP_MAIN_TASK_STACK_SIZE + TASK_EXTRA_STACK_SIZE) diff --git a/components/esp_system/include/esp_task_wdt.h b/components/esp_system/include/esp_task_wdt.h index c5c1d5fa11..776d29755e 100644 --- a/components/esp_system/include/esp_task_wdt.h +++ b/components/esp_system/include/esp_task_wdt.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 */ @@ -179,6 +179,31 @@ esp_err_t esp_task_wdt_status(TaskHandle_t task_handle); */ void __attribute__((weak)) esp_task_wdt_isr_user_handler(void); +typedef void (*task_wdt_msg_handler)(void *opaque, const char *msg); + +/** + * @brief Prints or retrieves information about tasks/users that triggered the Task Watchdog Timeout. + * + * This function provides various operations to handle tasks/users that did not reset the Task Watchdog in time. + * It can print detailed information about these tasks/users, such as their names, associated CPUs, and whether they have been reset. + * Additionally, it can retrieve the total length of the printed information or the CPU affinity of the failing tasks. + * + * @param[in] msg_handler Optional message handler function that will be called for each printed line. + * @param[in] opaque Optional pointer to opaque data that will be passed to the message handler function. + * @param[out] cpus_fail Optional pointer to an integer where the CPU affinity of the failing tasks will be stored. + * + * @return + * - ESP_OK: The function executed successfully. + * - ESP_FAIL: No triggered tasks were found, and thus no information was printed or retrieved. + * + * @note + * - If `msg_handler` is not provided, the information will be printed to console using ESP_EARLY_LOGE. + * - If `msg_handler` is provided, the function will send the printed information to the provided message handler function. + * - If `cpus_fail` is provided, the function will store the CPU affinity of the failing tasks in the provided integer. + * - During the execution of this function, logging is allowed in critical sections, as TWDT timeouts are considered fatal errors. + */ +esp_err_t esp_task_wdt_print_triggered_tasks(task_wdt_msg_handler msg_handler, void *opaque, int *cpus_fail); + #ifdef __cplusplus } #endif diff --git a/components/esp_system/ld/esp32c2/sections.ld.in b/components/esp_system/ld/esp32c2/sections.ld.in index a6a9290062..a0e15fae7f 100644 --- a/components/esp_system/ld/esp32c2/sections.ld.in +++ b/components/esp_system/ld/esp32c2/sections.ld.in @@ -35,9 +35,27 @@ SECTIONS . = ORIGIN(dram0_0_seg) + _iram_end - _iram_start; } > dram0_0_seg - .dram0.data : + /** + * This section MUST be placed at the beginning of the DRAM0, + * which will be released along with iram0_bt.text when Bluetooth is no longer in use + */ + .dram0.bt.data : { _data_start = ABSOLUTE(.); + mapping[dram0_bt_data] + . = ALIGN(8); + } > dram0_0_seg + + .dram0.bt.bss (NOLOAD) : + { + . = ALIGN (8); + _bss_bt_start = ABSOLUTE(.); + mapping[dram0_bt_bss] + _bss_bt_end = ABSOLUTE(.); + } > dram0_0_seg + + .dram0.data : + { *(.gnu.linkonce.d.*) *(.data1) __global_pointer$ = . + 0x800; @@ -289,6 +307,18 @@ SECTIONS mapping[iram0_bss] _iram_bss_end = ABSOLUTE(.); + } > iram0_0_seg + + /** + * This section needs to be placed at the end of the IRAM0, + * which will be released along with dram0_bt_data and dram0_bt_bss when Bluetooth is no longer in use + */ + .iram0.bt.text : + { + . = ALIGN(16); + _iram_bt_text_start = ABSOLUTE(.); + mapping[iram0_bt_text] + . = ALIGN(16); _iram_end = ABSOLUTE(.); } > iram0_0_seg diff --git a/components/esp_system/ld/esp32h2/sections.ld.in b/components/esp_system/ld/esp32h2/sections.ld.in index c8e45343f3..8f84717185 100644 --- a/components/esp_system/ld/esp32h2/sections.ld.in +++ b/components/esp_system/ld/esp32h2/sections.ld.in @@ -17,6 +17,8 @@ SECTIONS { . = ALIGN(4); _rtc_fast_start = ABSOLUTE(.); + _rtc_text_start = ABSOLUTE(.); + *(.rtc.entry.text) mapping[rtc_text] diff --git a/components/esp_system/panic.c b/components/esp_system/panic.c index 1804e84f0f..45351535cd 100644 --- a/components/esp_system/panic.c +++ b/components/esp_system/panic.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -60,10 +60,18 @@ #include "hal/usb_serial_jtag_ll.h" #endif +#ifdef __XTENSA__ +#include "xtensa/semihosting.h" +#elif __riscv +#include "riscv/semihosting.h" +#endif + +#define ESP_SEMIHOSTING_SYS_PANIC_REASON 0x116 + #define MWDT_DEFAULT_TICKS_PER_US 500 bool g_panic_abort = false; -static char *s_panic_abort_details = NULL; +char *g_panic_abort_details = NULL; static wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT(); @@ -222,7 +230,7 @@ static inline void disable_all_wdts(void) static void print_abort_details(const void *f) { - panic_print_str(s_panic_abort_details); + panic_print_str(g_panic_abort_details); } // Control arrives from chip-specific panic handler, environment prepared for @@ -237,7 +245,7 @@ void esp_panic_handler(panic_info_t *info) // If the exception was due to an abort, override some of the panic info if (g_panic_abort) { info->description = NULL; - info->details = s_panic_abort_details ? print_abort_details : NULL; + info->details = g_panic_abort_details ? print_abort_details : NULL; info->reason = NULL; info->exception = PANIC_EXCEPTION_ABORT; } @@ -286,7 +294,19 @@ void esp_panic_handler(panic_info_t *info) // If on-chip-debugger is attached, and system is configured to be aware of this, // then only print up to details. Users should be able to probe for the other information // in debug mode. +#if CONFIG_ESP_DEBUG_OCDAWARE if (esp_cpu_dbgr_is_attached()) { + char *panic_reason_str = NULL; + if (info->pseudo_excause) { + panic_reason_str = (char *)info->reason; + } else if (g_panic_abort && strlen(g_panic_abort_details)) { + panic_reason_str = g_panic_abort_details; + } + if (panic_reason_str) { + /* OpenOCD will print the halt cause when target is stopped at the below breakpoint (info->addr) */ + long args[] = {(long)panic_reason_str, strlen(panic_reason_str)}; + semihosting_call_noerrno(ESP_SEMIHOSTING_SYS_PANIC_REASON, args); + } panic_print_str("Setting breakpoint at 0x"); panic_print_hex((uint32_t)info->addr); panic_print_str(" and returning...\r\n"); @@ -303,7 +323,7 @@ void esp_panic_handler(panic_info_t *info) esp_cpu_set_breakpoint(0, info->addr); // use breakpoint 0 return; } - +#endif //CONFIG_ESP_DEBUG_OCDAWARE // start panic WDT to restart system if we hang in this handler if (!wdt_hal_is_enabled(&rtc_wdt_ctx)) { wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false); @@ -358,14 +378,8 @@ void esp_panic_handler(panic_info_t *info) } else { disable_all_wdts(); s_dumping_core = true; -#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH - esp_core_dump_to_flash(info); -#endif -#if CONFIG_ESP_COREDUMP_ENABLE_TO_UART && !CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT - esp_core_dump_to_uart(info); -#endif + esp_core_dump_write(info); s_dumping_core = false; - esp_panic_handler_reconfigure_wdts(1000); } #endif /* CONFIG_ESP_COREDUMP_ENABLE */ @@ -438,7 +452,7 @@ void esp_panic_handler(panic_info_t *info) void IRAM_ATTR __attribute__((noreturn, no_sanitize_undefined)) panic_abort(const char *details) { g_panic_abort = true; - s_panic_abort_details = (char *) details; + g_panic_abort_details = (char *) details; #if CONFIG_APPTRACE_ENABLE #if CONFIG_APPTRACE_SV_ENABLE diff --git a/components/esp_system/port/CMakeLists.txt b/components/esp_system/port/CMakeLists.txt index d14df8b8fb..3e3d88b6a7 100644 --- a/components/esp_system/port/CMakeLists.txt +++ b/components/esp_system/port/CMakeLists.txt @@ -12,6 +12,10 @@ if(CONFIG_SOC_BOD_SUPPORTED) list(APPEND srcs "brownout.c") endif() +if(CONFIG_ESP_CONSOLE_USB_CDC) + list(APPEND srcs "usb_console.c") +endif() + add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) target_sources(${COMPONENT_LIB} PRIVATE ${srcs}) diff --git a/components/esp_system/port/brownout.c b/components/esp_system/port/brownout.c index cb1e823221..5472303fdf 100644 --- a/components/esp_system/port/brownout.c +++ b/components/esp_system/port/brownout.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,11 +11,12 @@ #include "esp_private/system_internal.h" #include "esp_private/rtc_ctrl.h" #include "esp_private/spi_flash_os.h" -#include "esp_rom_sys.h" +#include "esp_log.h" #include "esp_cpu.h" #include "soc/soc.h" #include "soc/rtc_periph.h" #include "esp_attr.h" +#include "esp_rom_sys.h" #include "bootloader_flash.h" #include "esp_intr_alloc.h" #include "hal/brownout_hal.h" @@ -28,6 +29,8 @@ #define BROWNOUT_DET_LVL 0 #endif +static __attribute__((unused)) DRAM_ATTR const char TAG[] = "BOD"; + #if CONFIG_ESP_SYSTEM_BROWNOUT_INTR IRAM_ATTR static void rtc_brownout_isr_handler(void *arg) { @@ -51,10 +54,13 @@ IRAM_ATTR static void rtc_brownout_isr_handler(void *arg) } else #endif // CONFIG_SPI_FLASH_BROWNOUT_RESET { - esp_rom_printf("\r\nBrownout detector was triggered\r\n\r\n"); + ESP_DRAM_LOGI(TAG, "Brownout detector was triggered\r\n\r\n"); } - esp_restart_noos(); + esp_rom_software_reset_system(); + while (true) { + ; + } } #endif // CONFIG_ESP_SYSTEM_BROWNOUT_INTR diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index f8afae2ab4..0d8696c4cb 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,6 +17,8 @@ #include "esp_efuse.h" #include "esp_private/cache_err_int.h" #include "esp_clk_internal.h" +// For workaround `rtc_clk_recalib_bbpll()` +#include "esp_private/rtc_clk.h" #include "esp_rom_efuse.h" #include "esp_rom_uart.h" @@ -108,7 +110,10 @@ extern int _bss_start; extern int _bss_end; extern int _rtc_bss_start; extern int _rtc_bss_end; - +#if CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED +extern int _bss_bt_start; +extern int _bss_bt_end; +#endif // CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED extern int _instruction_reserved_start; extern int _instruction_reserved_end; extern int _rodata_reserved_start; @@ -328,6 +333,11 @@ void IRAM_ATTR call_start_cpu0(void) //Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this. memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start)); +#if CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED + // Clear Bluetooth bss + memset(&_bss_bt_start, 0, (&_bss_bt_end - &_bss_bt_start) * sizeof(_bss_bt_start)); +#endif // CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED + #if defined(CONFIG_IDF_TARGET_ESP32) && defined(CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY) // Clear IRAM BSS memset(&_iram_bss_start, 0, (&_iram_bss_end - &_iram_bss_start) * sizeof(_iram_bss_start)); @@ -404,10 +414,6 @@ void IRAM_ATTR call_start_cpu0(void) Cache_Resume_DCache(0); #endif // CONFIG_IDF_TARGET_ESP32S3 - if (esp_efuse_check_errors() != ESP_OK) { - esp_restart(); - } - #if CONFIG_ESP_ROM_NEEDS_SET_CACHE_MMU_SIZE #if CONFIG_APP_BUILD_TYPE_ELF_RAM // For RAM loadable ELF case, we don't need to reserve IROM/DROM as instructions and data @@ -446,7 +452,14 @@ void IRAM_ATTR call_start_cpu0(void) * In this stage, we re-configure the Flash (and MSPI) to required configuration */ spi_flash_init_chip_state(); + + // In earlier version of ESP-IDF, the PLL provided by bootloader is not stable enough. + // Do calibration again here so that we can use better clock for the timing tuning. +#if CONFIG_ESP_SYSTEM_BBPLL_RECALIB + rtc_clk_recalib_bbpll(); +#endif #if SOC_MEMSPI_SRC_FREQ_120M + // This function needs to be called when PLL is enabled mspi_timing_flash_tuning(); #endif @@ -469,6 +482,10 @@ void IRAM_ATTR call_start_cpu0(void) #endif #endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + if (esp_efuse_check_errors() != ESP_OK) { + esp_restart(); + } + bootloader_init_mem(); #if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE diff --git a/components/esp_system/port/soc/esp32c2/clk.c b/components/esp_system/port/soc/esp32c2/clk.c index 8d8d78c946..207673d853 100644 --- a/components/esp_system/port/soc/esp32c2/clk.c +++ b/components/esp_system/port/soc/esp32c2/clk.c @@ -75,11 +75,16 @@ 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 (1.6 sec on 40MHz XTAL and 2.5 sec on 26MHz XTAL). // 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 1.6sec * 150/32 = 7.5 sec 40MHz XTAL, + // or 11.72 sec on 26MHz XTAL). wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; +#ifdef CONFIG_XTAL_FREQ_26 + uint32_t stage_timeout_ticks = (uint32_t)(2500ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); +#else uint32_t stage_timeout_ticks = (uint32_t)(1600ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); +#endif 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 @@ -243,7 +248,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Set WiFi light sleep clock source to RTC slow clock */ REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); - CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M); + CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW); SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); /* Enable RNG clock. */ diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index 7865e23eee..bdafbc973b 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -287,7 +287,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Set WiFi light sleep clock source to RTC slow clock */ REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); - CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M); + CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW); SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); /* Enable RNG clock. */ diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index 891283a813..ed9de21041 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -175,8 +175,6 @@ void rtc_clk_select_rtc_slow_clk(void) */ __attribute__((weak)) void esp_perip_clk_init(void) { - modem_clock_domain_pmu_state_icg_map_init(); - /* During system initialization, the low-power clock source of the modem * (WiFi, BLE or Coexist) follows the configuration of the slow clock source * of the system. If the WiFi, BLE or Coexist module needs a higher @@ -285,7 +283,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Set WiFi light sleep clock source to RTC slow clock */ REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); - CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M); + CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW); SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); /* Enable RNG clock. */ diff --git a/components/esp_system/port/soc/esp32c6/reset_reason.c b/components/esp_system/port/soc/esp32c6/reset_reason.c index 6bf7ff6122..aaf0160f76 100644 --- a/components/esp_system/port/soc/esp32c6/reset_reason.c +++ b/components/esp_system/port/soc/esp32c6/reset_reason.c @@ -50,6 +50,19 @@ static esp_reset_reason_t get_reset_reason(soc_reset_reason_t rtc_reset_reason, case RESET_REASON_SYS_BROWN_OUT: return ESP_RST_BROWNOUT; + case RESET_REASON_CORE_USB_UART: + case RESET_REASON_CORE_USB_JTAG: + return ESP_RST_USB; + + case RESET_REASON_CORE_EFUSE_CRC: + return ESP_RST_EFUSE; + + case RESET_REASON_CPU0_JTAG: + return ESP_RST_JTAG; + + case RESET_REASON_CORE_SDIO: + return ESP_RST_SDIO; + default: return ESP_RST_UNKNOWN; } diff --git a/components/esp_system/port/soc/esp32h2/Kconfig.system b/components/esp_system/port/soc/esp32h2/Kconfig.system index 1bc6be4b1e..c76dcd88b4 100644 --- a/components/esp_system/port/soc/esp32h2/Kconfig.system +++ b/components/esp_system/port/soc/esp32h2/Kconfig.system @@ -11,7 +11,7 @@ menu "Brownout Detector" choice ESP_BROWNOUT_DET_LVL_SEL prompt "Brownout voltage level" depends on ESP_BROWNOUT_DET - default ESP_BROWNOUT_DET_LVL_SEL_7 + default ESP_BROWNOUT_DET_LVL_SEL_0 help The brownout detector will reset the chip when the supply voltage is approximately below this level. Note that there may be some variation of brownout voltage level @@ -20,21 +20,27 @@ menu "Brownout Detector" #The voltage levels here are estimates, more work needs to be done to figure out the exact voltages #of the brownout threshold levels. config ESP_BROWNOUT_DET_LVL_SEL_7 - bool "2.51V" + bool "2.94V" config ESP_BROWNOUT_DET_LVL_SEL_6 - bool "2.64V" + bool "2.88V" config ESP_BROWNOUT_DET_LVL_SEL_5 - bool "2.76V" + bool "2.83V" config ESP_BROWNOUT_DET_LVL_SEL_4 - bool "2.92V" + bool "2.78V" config ESP_BROWNOUT_DET_LVL_SEL_3 - bool "3.10V" + bool "2.73V" config ESP_BROWNOUT_DET_LVL_SEL_2 - bool "3.27V" + bool "2.67V" + config ESP_BROWNOUT_DET_LVL_SEL_1 + bool "2.62V" + config ESP_BROWNOUT_DET_LVL_SEL_0 + bool "2.57V" endchoice config ESP_BROWNOUT_DET_LVL int + default 0 if ESP_BROWNOUT_DET_LVL_SEL_0 + default 1 if ESP_BROWNOUT_DET_LVL_SEL_1 default 2 if ESP_BROWNOUT_DET_LVL_SEL_2 default 3 if ESP_BROWNOUT_DET_LVL_SEL_3 default 4 if ESP_BROWNOUT_DET_LVL_SEL_4 diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index 7b3e363685..8ced39f8e4 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 @@ -280,7 +280,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Set WiFi light sleep clock source to RTC slow clock */ REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); - CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M); + CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW); SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); /* Enable RNG clock. */ diff --git a/components/esp_system/port/soc/esp32h2/reset_reason.c b/components/esp_system/port/soc/esp32h2/reset_reason.c index 998c933c6f..36aa8d6ede 100644 --- a/components/esp_system/port/soc/esp32h2/reset_reason.c +++ b/components/esp_system/port/soc/esp32h2/reset_reason.c @@ -50,6 +50,19 @@ static esp_reset_reason_t get_reset_reason(soc_reset_reason_t rtc_reset_reason, case RESET_REASON_SYS_BROWN_OUT: return ESP_RST_BROWNOUT; + case RESET_REASON_CORE_USB_UART: + case RESET_REASON_CORE_USB_JTAG: + return ESP_RST_USB; + + case RESET_REASON_CORE_EFUSE_CRC: + return ESP_RST_EFUSE; + + case RESET_REASON_CORE_PWR_GLITCH: + return ESP_RST_PWR_GLITCH; + + case RESET_REASON_CPU0_JTAG: + return ESP_RST_JTAG; + default: return ESP_RST_UNKNOWN; } diff --git a/components/esp_system/port/soc/esp32s2/CMakeLists.txt b/components/esp_system/port/soc/esp32s2/CMakeLists.txt index 03b7d6659d..2adf51698a 100644 --- a/components/esp_system/port/soc/esp32s2/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32s2/CMakeLists.txt @@ -22,9 +22,6 @@ endif() add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) target_sources(${COMPONENT_LIB} PRIVATE ${srcs}) -if(CONFIG_ESP_CONSOLE_USB_CDC) - target_sources(${COMPONENT_LIB} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/usb_console.c") -endif() #ld_include_highint_hdl is added as an undefined symbol because otherwise the #linker will ignore highint_hdl.S as it has no other files depending on any diff --git a/components/esp_system/port/soc/esp32s2/clk.c b/components/esp_system/port/soc/esp32s2/clk.c index a5c7181391..a833604d8f 100644 --- a/components/esp_system/port/soc/esp32s2/clk.c +++ b/components/esp_system/port/soc/esp32s2/clk.c @@ -306,7 +306,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Set WiFi light sleep clock source to RTC slow clock */ DPORT_REG_SET_FIELD(DPORT_BT_LPCK_DIV_INT_REG, DPORT_BT_LPCK_DIV_NUM, 0); - DPORT_CLEAR_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_8M); + DPORT_CLEAR_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_XTAL32K | DPORT_LPCLK_SEL_XTAL | DPORT_LPCLK_SEL_8M | DPORT_LPCLK_SEL_RTC_SLOW); DPORT_SET_PERI_REG_MASK(DPORT_BT_LPCK_DIV_FRAC_REG, DPORT_LPCLK_SEL_RTC_SLOW); diff --git a/components/esp_system/port/soc/esp32s3/CMakeLists.txt b/components/esp_system/port/soc/esp32s3/CMakeLists.txt index bb4f4f1726..c910e6d3ea 100644 --- a/components/esp_system/port/soc/esp32s3/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32s3/CMakeLists.txt @@ -23,9 +23,6 @@ endif() add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) target_sources(${COMPONENT_LIB} PRIVATE ${srcs}) -if(CONFIG_ESP_CONSOLE_USB_CDC) - target_sources(${COMPONENT_LIB} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/usb_console.c") -endif() #ld_include_highint_hdl is added as an undefined symbol because otherwise the #linker will ignore panic_highint_hdl.S as it has no other files depending on any diff --git a/components/esp_system/port/soc/esp32s3/clk.c b/components/esp_system/port/soc/esp32s3/clk.c index 98d6de972a..7b0c2c80dc 100644 --- a/components/esp_system/port/soc/esp32s3/clk.c +++ b/components/esp_system/port/soc/esp32s3/clk.c @@ -308,7 +308,7 @@ __attribute__((weak)) void esp_perip_clk_init(void) /* Set WiFi light sleep clock source to RTC slow clock */ REG_SET_FIELD(SYSTEM_BT_LPCK_DIV_INT_REG, SYSTEM_BT_LPCK_DIV_NUM, 0); - CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_8M); + CLEAR_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL32K | SYSTEM_LPCLK_SEL_XTAL | SYSTEM_LPCLK_SEL_8M | SYSTEM_LPCLK_SEL_RTC_SLOW); SET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_RTC_SLOW); /* Enable RNG clock. */ diff --git a/components/esp_system/port/soc/esp32s3/usb_console.c b/components/esp_system/port/soc/esp32s3/usb_console.c deleted file mode 100644 index 31dbac2a7d..0000000000 --- a/components/esp_system/port/soc/esp32s3/usb_console.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include "sdkconfig.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "esp_system.h" -#include "esp_intr_alloc.h" -#include "esp_private/usb_console.h" -#include "soc/periph_defs.h" -#include "soc/rtc_cntl_reg.h" -#include "soc/usb_struct.h" -#include "soc/usb_reg.h" -#include "spinlock.h" -#include "hal/soc_hal.h" -#include "esp_rom_uart.h" -#include "esp_rom_sys.h" -#include "esp32s3/rom/usb/usb_dc.h" -#include "esp32s3/rom/usb/cdc_acm.h" -#include "esp32s3/rom/usb/usb_dfu.h" -#include "esp32s3/rom/usb/usb_device.h" -#include "esp32s3/rom/usb/usb_os_glue.h" -#include "esp32s3/rom/usb/usb_persist.h" -#include "esp32s3/rom/usb/chip_usb_dw_wrapper.h" - -#define CDC_WORK_BUF_SIZE (ESP_ROM_CDC_ACM_WORK_BUF_MIN + CONFIG_ESP_CONSOLE_USB_CDC_RX_BUF_SIZE) - -typedef enum { - REBOOT_NONE, - REBOOT_NORMAL, - REBOOT_BOOTLOADER, - REBOOT_BOOTLOADER_DFU, -} reboot_type_t; - - -static reboot_type_t s_queue_reboot = REBOOT_NONE; -static int s_prev_rts_state; -static intr_handle_t s_usb_int_handle; -static cdc_acm_device *s_cdc_acm_device; -static char s_usb_tx_buf[ACM_BYTES_PER_TX]; -static size_t s_usb_tx_buf_pos; -static uint8_t cdcmem[CDC_WORK_BUF_SIZE]; -static esp_usb_console_cb_t s_rx_cb; -static esp_usb_console_cb_t s_tx_cb; -static void *s_cb_arg; - -#ifdef CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF -static portMUX_TYPE s_write_lock = portMUX_INITIALIZER_UNLOCKED; -void esp_usb_console_write_char(char c); -#define ISR_FLAG ESP_INTR_FLAG_IRAM -#else -#define ISR_FLAG 0 -#endif // CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF - - -/* Optional write lock routines; used only if esp_rom_printf output via CDC is enabled */ -static inline void write_lock_acquire(void); -static inline void write_lock_release(void); - -/* The two functions below need to be revisited in the multicore case TODO ESP32-S3 IDF-2048*/ -_Static_assert(SOC_CPU_CORES_NUM == 1, "usb_osglue_*_int is not multicore capable"); - -/* Called by ROM to disable the interrupts - * Non-static to allow placement into IRAM by ldgen. - */ -void esp_usb_console_osglue_dis_int(void) -{ - if (s_usb_int_handle) { - esp_intr_disable(s_usb_int_handle); - } -} - -/* Called by ROM to enable the interrupts - * Non-static to allow placement into IRAM by ldgen. - */ -void esp_usb_console_osglue_ena_int(void) -{ - if (s_usb_int_handle) { - esp_intr_enable(s_usb_int_handle); - } -} - -/* Delay function called by ROM USB driver. - * Non-static to allow placement into IRAM by ldgen. - */ -int esp_usb_console_osglue_wait_proc(int delay_us) -{ - if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING || - !xPortCanYield()) { - esp_rom_delay_us(delay_us); - return delay_us; - } - if (delay_us == 0) { - /* We should effectively yield */ - vPortYield(); - return 1; - } else { - /* Just delay */ - int ticks = MAX(delay_us / (portTICK_PERIOD_MS * 1000), 1); - vTaskDelay(ticks); - return ticks * portTICK_PERIOD_MS * 1000; - } -} - -/* Called by ROM CDC ACM driver from interrupt context./ - * Non-static to allow placement into IRAM by ldgen. - */ -void esp_usb_console_cdc_acm_cb(cdc_acm_device *dev, int status) -{ - if (status == USB_DC_RESET || status == USB_DC_CONNECTED) { - s_prev_rts_state = 0; - } else if (status == ACM_STATUS_LINESTATE_CHANGED) { - uint32_t rts, dtr; - cdc_acm_line_ctrl_get(dev, LINE_CTRL_RTS, &rts); - cdc_acm_line_ctrl_get(dev, LINE_CTRL_DTR, &dtr); - if (!rts && s_prev_rts_state) { - if (dtr) { - s_queue_reboot = REBOOT_BOOTLOADER; - } else { - s_queue_reboot = REBOOT_NORMAL; - } - } - s_prev_rts_state = rts; - } else if (status == ACM_STATUS_RX && s_rx_cb) { - (*s_rx_cb)(s_cb_arg); - } else if (status == ACM_STATUS_TX && s_tx_cb) { - (*s_tx_cb)(s_cb_arg); - } -} - -/* Non-static to allow placement into IRAM by ldgen. */ -void esp_usb_console_dfu_detach_cb(int timeout) -{ - s_queue_reboot = REBOOT_BOOTLOADER_DFU; -} - -/* USB interrupt handler, forward the call to the ROM driver. - * Non-static to allow placement into IRAM by ldgen. - */ -void esp_usb_console_interrupt(void *arg) -{ - usb_dc_check_poll_for_interrupts(); - /* Restart can be requested from esp_usb_console_cdc_acm_cb or esp_usb_console_dfu_detach_cb */ - if (s_queue_reboot != REBOOT_NONE) { - esp_restart(); - } -} - -/* Call the USB interrupt handler while any interrupts are pending, - * but not more than a few times. - * Non-static to allow placement into IRAM by ldgen. - */ -void esp_usb_console_poll_interrupts(void) -{ - const int max_poll_count = 10; - for (int i = 0; (USB0.gintsts & USB0.gintmsk) != 0 && i < max_poll_count; i++) { - usb_dc_check_poll_for_interrupts(); - } -} - -/* This function gets registered as a restart handler. - * Prepares USB peripheral for restart and sets up persistence. - * Non-static to allow placement into IRAM by ldgen. - */ -void esp_usb_console_before_restart(void) -{ - esp_usb_console_poll_interrupts(); - usb_dc_prepare_persist(); - if (s_queue_reboot == REBOOT_BOOTLOADER) { - chip_usb_set_persist_flags(USBDC_PERSIST_ENA); - REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT); - } else if (s_queue_reboot == REBOOT_BOOTLOADER_DFU) { - chip_usb_set_persist_flags(USBDC_BOOT_DFU); - REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT); - } else { - chip_usb_set_persist_flags(USBDC_PERSIST_ENA); - esp_usb_console_poll_interrupts(); - } -} - -/* Reset some static state in ROM, which survives when going from the - * 2nd stage bootloader into the app. This cleans some variables which - * indicates that the driver is already initialized, allowing us to - * initialize it again, in the app. - */ -static void esp_usb_console_rom_cleanup(void) -{ - /* TODO ESP32-S3 IDF-2987 */ - // extern char rom_usb_dev, rom_usb_dev_end; - // extern char rom_usb_dw_ctrl, rom_usb_dw_ctrl_end; - - // uart_acm_dev = NULL; - // memset((void *) &rom_usb_dev, 0, &rom_usb_dev_end - &rom_usb_dev); - // memset((void *) &rom_usb_dw_ctrl, 0, &rom_usb_dw_ctrl_end - &rom_usb_dw_ctrl); -} - -esp_err_t esp_usb_console_init(void) -{ - esp_err_t err; - err = esp_register_shutdown_handler(esp_usb_console_before_restart); - if (err != ESP_OK) { - return err; - } - - esp_usb_console_rom_cleanup(); - - /* Install OS hooks */ - s_usb_osglue.int_dis_proc = esp_usb_console_osglue_dis_int; - s_usb_osglue.int_ena_proc = esp_usb_console_osglue_ena_int; - s_usb_osglue.wait_proc = esp_usb_console_osglue_wait_proc; - - /* Install interrupt. - * In case of ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF: - * Note that this the interrupt handler has to be placed into IRAM because - * the interrupt handler can also be called in polling mode, when - * interrupts are disabled, and a write to USB is performed with cache disabled. - * Since the handler function is in IRAM, we can register the interrupt as IRAM capable. - * It is not because we actually need the interrupt to work with cache disabled! - */ - err = esp_intr_alloc(ETS_USB_INTR_SOURCE, ISR_FLAG | ESP_INTR_FLAG_INTRDISABLED, - esp_usb_console_interrupt, NULL, &s_usb_int_handle); - if (err != ESP_OK) { - esp_unregister_shutdown_handler(esp_usb_console_before_restart); - return err; - } - - /* Initialize USB / CDC */ - s_cdc_acm_device = cdc_acm_init(cdcmem, CDC_WORK_BUF_SIZE); - usb_dc_check_poll_for_interrupts(); - - /* Set callback for handling DTR/RTS lines and TX/RX events */ - cdc_acm_irq_callback_set(s_cdc_acm_device, esp_usb_console_cdc_acm_cb); - cdc_acm_irq_state_enable(s_cdc_acm_device); - - /* Set callback for handling DFU detach */ - usb_dfu_set_detach_cb(esp_usb_console_dfu_detach_cb); - - /* Enable interrupts on USB peripheral side */ - USB0.gahbcfg |= USB_GLBLLNTRMSK_M; - - /* Enable the interrupt handler */ - esp_intr_enable(s_usb_int_handle); - -#ifdef CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF - /* Install esp_rom_printf handler */ - ets_install_putc1(&esp_usb_console_write_char); -#endif // CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF - - return ESP_OK; -} - -/* Non-static to allow placement into IRAM by ldgen. - * Must be called with the write lock held. - */ -ssize_t esp_usb_console_flush_internal(size_t last_write_size) -{ - if (s_usb_tx_buf_pos == 0) { - return 0; - } - assert(s_usb_tx_buf_pos >= last_write_size); - ssize_t ret; - size_t tx_buf_pos_before = s_usb_tx_buf_pos - last_write_size; - int sent = cdc_acm_fifo_fill(s_cdc_acm_device, (const uint8_t*) s_usb_tx_buf, s_usb_tx_buf_pos); - if (sent == last_write_size) { - /* everything was sent */ - ret = last_write_size; - s_usb_tx_buf_pos = 0; - } else if (sent == 0) { - /* nothing was sent, roll back to the original state */ - ret = 0; - s_usb_tx_buf_pos = tx_buf_pos_before; - } else { - /* Some data was sent, but not all of the buffer. - * We can still tell the caller that all the new data - * was "sent" since it is in the buffer now. - */ - ret = last_write_size; - memmove(s_usb_tx_buf, s_usb_tx_buf + sent, s_usb_tx_buf_pos - sent); - s_usb_tx_buf_pos = s_usb_tx_buf_pos - sent; - } - return ret; -} - -ssize_t esp_usb_console_flush(void) -{ - if (s_cdc_acm_device == NULL) { - return -1; - } - write_lock_acquire(); - int ret = esp_usb_console_flush_internal(0); - write_lock_release(); - return ret; -} - -ssize_t esp_usb_console_write_buf(const char* buf, size_t size) -{ - if (s_cdc_acm_device == NULL) { - return -1; - } - if (size == 0) { - return 0; - } - write_lock_acquire(); - ssize_t tx_buf_available = ACM_BYTES_PER_TX - s_usb_tx_buf_pos; - ssize_t will_write = MIN(size, tx_buf_available); - memcpy(s_usb_tx_buf + s_usb_tx_buf_pos, buf, will_write); - s_usb_tx_buf_pos += will_write; - - ssize_t ret; - if (s_usb_tx_buf_pos == ACM_BYTES_PER_TX || buf[size - 1] == '\n') { - /* Buffer is full, or a newline is found. - * For binary streams, we probably shouldn't do line buffering, - * but text streams are likely going to be the most common case. - */ - ret = esp_usb_console_flush_internal(will_write); - } else { - /* nothing sent out yet, but all the new data is in the buffer now */ - ret = will_write; - } - write_lock_release(); - return ret; -} - -ssize_t esp_usb_console_read_buf(char *buf, size_t buf_size) -{ - if (s_cdc_acm_device == NULL) { - return -1; - } - if (!esp_usb_console_read_available()) { - return 0; - } - int bytes_read = cdc_acm_fifo_read(s_cdc_acm_device, (uint8_t*) buf, buf_size); - return bytes_read; -} - -esp_err_t esp_usb_console_set_cb(esp_usb_console_cb_t rx_cb, esp_usb_console_cb_t tx_cb, void *arg) -{ - if (s_cdc_acm_device == NULL) { - return ESP_ERR_INVALID_STATE; - } - s_rx_cb = rx_cb; - if (s_rx_cb) { - cdc_acm_irq_rx_enable(s_cdc_acm_device); - } else { - cdc_acm_irq_rx_disable(s_cdc_acm_device); - } - s_tx_cb = tx_cb; - if (s_tx_cb) { - cdc_acm_irq_tx_enable(s_cdc_acm_device); - } else { - cdc_acm_irq_tx_disable(s_cdc_acm_device); - } - s_cb_arg = arg; - return ESP_OK; -} - -bool esp_usb_console_read_available(void) -{ - if (s_cdc_acm_device == NULL) { - return false; - } - return cdc_acm_rx_fifo_cnt(s_cdc_acm_device) > 0; -} - -bool esp_usb_console_write_available(void) -{ - if (s_cdc_acm_device == NULL) { - return false; - } - return cdc_acm_irq_tx_ready(s_cdc_acm_device) != 0; -} - - -#ifdef CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF -/* Used as an output function by esp_rom_printf. - * The LF->CRLF replacement logic replicates the one in esp_rom_uart_putc. - * Not static to allow placement into IRAM by ldgen. - */ -void esp_usb_console_write_char(char c) -{ - char cr = '\r'; - char lf = '\n'; - - if (c == lf) { - esp_usb_console_write_buf(&cr, 1); - esp_usb_console_write_buf(&lf, 1); - } else if (c == '\r') { - } else { - esp_usb_console_write_buf(&c, 1); - } -} -static inline void write_lock_acquire(void) -{ - portENTER_CRITICAL_SAFE(&s_write_lock); -} -static inline void write_lock_release(void) -{ - portEXIT_CRITICAL_SAFE(&s_write_lock); -} - -#else // CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF - -static inline void write_lock_acquire(void) -{ -} - -static inline void write_lock_release(void) -{ -} -#endif // CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF diff --git a/components/esp_system/port/soc/esp32s2/usb_console.c b/components/esp_system/port/usb_console.c similarity index 91% rename from components/esp_system/port/soc/esp32s2/usb_console.c rename to components/esp_system/port/usb_console.c index 16a6360762..7e5dc5b7a7 100644 --- a/components/esp_system/port/soc/esp32s2/usb_console.c +++ b/components/esp_system/port/usb_console.c @@ -27,6 +27,8 @@ #include "hal/soc_hal.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" +#include "esp_rom_caps.h" +#ifdef CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/usb/usb_dc.h" #include "esp32s2/rom/usb/cdc_acm.h" #include "esp32s2/rom/usb/usb_dfu.h" @@ -34,7 +36,15 @@ #include "esp32s2/rom/usb/usb_os_glue.h" #include "esp32s2/rom/usb/usb_persist.h" #include "esp32s2/rom/usb/chip_usb_dw_wrapper.h" - +#elif CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/usb/usb_dc.h" +#include "esp32s3/rom/usb/cdc_acm.h" +#include "esp32s3/rom/usb/usb_dfu.h" +#include "esp32s3/rom/usb/usb_device.h" +#include "esp32s3/rom/usb/usb_os_glue.h" +#include "esp32s3/rom/usb/usb_persist.h" +#include "esp32s3/rom/usb/chip_usb_dw_wrapper.h" +#endif #define CDC_WORK_BUF_SIZE (ESP_ROM_CDC_ACM_WORK_BUF_MIN + CONFIG_ESP_CONSOLE_USB_CDC_RX_BUF_SIZE) @@ -60,8 +70,17 @@ static esp_timer_handle_t s_restart_timer; static const char* TAG = "usb_console"; +/* This lock is used for two purposes: + * - To protect functions which write something to USB, e.g. esp_usb_console_write_buf. + * This is necessary since these functions may be called by esp_rom_printf, so the calls + * may preempt each other or happen concurrently. + * (The calls coming from regular 'printf', i.e. via VFS layer, are already protected + * by a mutex in the VFS driver.) + * - To implement "osglue" functions of the USB stack. These normally require interrupts + * to be disabled. However on multi-core chips a critical section is necessary. + */ +static portMUX_TYPE s_lock = portMUX_INITIALIZER_UNLOCKED; #ifdef CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF -static portMUX_TYPE s_write_lock = portMUX_INITIALIZER_UNLOCKED; void esp_usb_console_write_char(char c); #define ISR_FLAG ESP_INTR_FLAG_IRAM #else @@ -73,8 +92,6 @@ void esp_usb_console_write_char(char c); static inline void write_lock_acquire(void); static inline void write_lock_release(void); -/* The two functions below need to be revisited in the multicore case */ -_Static_assert(SOC_CPU_CORES_NUM == 1, "usb_osglue_*_int is not multicore capable"); /* Other forward declarations */ void esp_usb_console_before_restart(void); @@ -84,9 +101,7 @@ void esp_usb_console_before_restart(void); */ void esp_usb_console_osglue_dis_int(void) { - if (s_usb_int_handle) { - esp_intr_disable(s_usb_int_handle); - } + portENTER_CRITICAL_SAFE(&s_lock); } /* Called by ROM to enable the interrupts @@ -94,9 +109,7 @@ void esp_usb_console_osglue_dis_int(void) */ void esp_usb_console_osglue_ena_int(void) { - if (s_usb_int_handle) { - esp_intr_enable(s_usb_int_handle); - } + portEXIT_CRITICAL_SAFE(&s_lock); } /* Delay function called by ROM USB driver. @@ -231,12 +244,9 @@ void esp_usb_console_before_restart(void) */ static void esp_usb_console_rom_cleanup(void) { - extern char rom_usb_dev, rom_usb_dev_end; - extern char rom_usb_dw_ctrl, rom_usb_dw_ctrl_end; - + usb_dev_deinit(); + usb_dw_ctrl_deinit(); uart_acm_dev = NULL; - memset((void *) &rom_usb_dev, 0, &rom_usb_dev_end - &rom_usb_dev); - memset((void *) &rom_usb_dw_ctrl, 0, &rom_usb_dw_ctrl_end - &rom_usb_dw_ctrl); } esp_err_t esp_usb_console_init(void) @@ -288,7 +298,8 @@ esp_err_t esp_usb_console_init(void) #ifdef CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF /* Install esp_rom_printf handler */ - ets_install_putc1(&esp_usb_console_write_char); + esp_rom_uart_set_as_console(ESP_ROM_USB_OTG_NUM); + esp_rom_install_channel_putc(1, &esp_usb_console_write_char); #endif // CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF return ESP_OK; @@ -451,11 +462,11 @@ void esp_usb_console_write_char(char c) } static inline void write_lock_acquire(void) { - portENTER_CRITICAL_SAFE(&s_write_lock); + portENTER_CRITICAL_SAFE(&s_lock); } static inline void write_lock_release(void) { - portEXIT_CRITICAL_SAFE(&s_write_lock); + portEXIT_CRITICAL_SAFE(&s_lock); } #else // CONFIG_ESP_CONSOLE_USB_CDC_SUPPORT_ETS_PRINTF diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index 4f1b39532a..f6c9292c5e 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,6 +27,7 @@ #include "esp_newlib.h" #include "esp_timer.h" #include "esp_efuse.h" +#include "esp_efuse_table.h" #include "esp_flash_encrypt.h" #include "esp_secure_boot.h" #include "esp_xt_wdt.h" @@ -37,7 +38,7 @@ /***********************************************/ // Headers for other components init functions #if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #endif #if __has_include("esp_app_desc.h") @@ -69,6 +70,10 @@ #include "esp_rom_caps.h" #include "esp_rom_sys.h" +#if SOC_BOD_SUPPORTED +#include "hal/brownout_ll.h" +#endif + #if CONFIG_SPIRAM #include "esp_psram.h" #include "esp_private/esp_psram_extram.h" @@ -292,7 +297,11 @@ static void do_core_init(void) // [refactor-todo] leads to call chain rtc_is_register (driver) -> esp_intr_alloc (esp32/esp32s2) -> // malloc (newlib) -> heap_caps_malloc (heap), so heap must be at least initialized esp_brownout_init(); -#endif +#else +#if SOC_CAPS_NO_RESET_BY_ANA_BOD + brownout_ll_ana_reset_enable(false); +#endif // SOC_CAPS_NO_RESET_BY_ANA_BOD +#endif // CONFIG_ESP_BROWNOUT_DET esp_newlib_time_init(); @@ -355,6 +364,29 @@ static void do_core_init(void) #endif #endif +#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK + // For anti-rollback case, recheck security version before we boot-up the current application + assert(esp_efuse_check_secure_version(esp_app_get_description()->secure_version) == true && "Incorrect secure version of app"); +#endif + +#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED + esp_flash_encryption_init_checks(); +#endif + +#if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT) + // Note: in some configs this may read flash, so placed after flash init + esp_secure_boot_init_checks(); +#endif + +#if SOC_EFUSE_ECDSA_USE_HARDWARE_K + if (esp_efuse_find_purpose(ESP_EFUSE_KEY_PURPOSE_ECDSA_KEY, NULL)) { + // ECDSA key purpose block is present and hence permanently enable + // the hardware TRNG supplied k mode (most secure mode) + err = esp_efuse_write_field_bit(ESP_EFUSE_ECDSA_FORCE_USE_HARDWARE_K); + assert(err == ESP_OK && "Failed to enable ECDSA hardware k mode"); + } +#endif + #if CONFIG_SECURE_DISABLE_ROM_DL_MODE err = esp_efuse_disable_rom_download_mode(); assert(err == ESP_OK && "Failed to disable ROM download mode"); @@ -369,15 +401,6 @@ static void do_core_init(void) esp_efuse_disable_basic_rom_console(); #endif -#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED - esp_flash_encryption_init_checks(); -#endif - -#if defined(CONFIG_SECURE_BOOT) || defined(CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT) - // Note: in some configs this may read flash, so placed after flash init - esp_secure_boot_init_checks(); -#endif - #ifdef ROM_LOG_MODE esp_efuse_set_rom_log_scheme(ROM_LOG_MODE); #endif diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index 93c6687425..0818eedf84 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -31,7 +31,7 @@ # usb_console needs to create an esp_timer at startup. # This can be done only after esp_timer initialization, which is now in init_components0. -220: esp_usb_console_init_restart_timer in components/esp_system/port/soc/esp32s2/usb_console.c on BIT(0) +220: esp_usb_console_init_restart_timer in components/esp_system/port/usb_console.c on BIT(0) # usb_serial_jtag needs to create and acquire a PM clock at startup. # This makes more sense to be done after esp_pm_impl_init, which is initialized in init_components0. diff --git a/components/esp_system/task_wdt/task_wdt.c b/components/esp_system/task_wdt/task_wdt.c index 9bd7770ca2..f61db4ff6a 100644 --- a/components/esp_system/task_wdt/task_wdt.c +++ b/components/esp_system/task_wdt/task_wdt.c @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include #include #include @@ -331,6 +332,33 @@ static void subscribe_idle(uint32_t core_mask) * */ +static UBaseType_t get_task_affinity(const TaskHandle_t xTask) +{ + if (xTask == NULL) { + /* User entry, we cannot predict on which core it is scheduled to run, + * so let's mark all cores as failing */ +#if configNUM_CORES > 1 + return BIT(1) | BIT(0); +#else + return BIT(0); +#endif + } + +#if CONFIG_FREERTOS_SMP + #if configNUM_CORES > 1 + return vTaskCoreAffinityGet(xTask); + #else + return BIT(0); + #endif +#else + BaseType_t task_affinity = xTaskGetAffinity(xTask); + if (task_affinity == 0 || task_affinity == 1) { + return BIT(task_affinity); + } + return BIT(1) | BIT(0); +#endif +} + #if CONFIG_IDF_TARGET_ARCH_RISCV static void task_wdt_timeout_handling(int cores_fail, bool panic) @@ -505,65 +533,17 @@ static void task_wdt_isr(void *arg) portENTER_CRITICAL_ISR(&spinlock); esp_task_wdt_impl_timeout_triggered(p_twdt_obj->impl_ctx); - // If there are no entries, there's nothing to do. - if (SLIST_EMPTY(&p_twdt_obj->entries_slist)) { - portEXIT_CRITICAL_ISR(&spinlock); - return; - } - // Find what entries triggered the TWDT timeout (i.e., which entries have not been reset) - /* - Note: We are currently in a critical section, thus under normal circumstances, logging should not be allowed. - However, TWDT timeouts count as fatal errors, thus reporting the fatal error is considered more important than - minimizing interrupt latency. Thus we allow logging in critical sections in this narrow case. - */ - ESP_EARLY_LOGE(TAG, "Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:"); - twdt_entry_t *entry; /* Keep a bitmap of CPU cores having tasks that have not reset TWDT. * Bit 0 represents core 0, bit 1 represents core 1, and so on. */ int cpus_fail = 0; bool panic = p_twdt_obj->panic; - SLIST_FOREACH(entry, &p_twdt_obj->entries_slist, slist_entry) { - if (!entry->has_reset) { - if (entry->task_handle) { -#if CONFIG_FREERTOS_SMP -#if configNUM_CORES > 1 - // Log the task's name and its affinity - const UBaseType_t affinity = vTaskCoreAffinityGet(entry->task_handle); - ESP_EARLY_LOGE(TAG, " - %s (0x%x)", pcTaskGetName(entry->task_handle), affinity); - cpus_fail |= affinity; -#else // configNUM_CORES > 1 - // Log the task's name - ESP_EARLY_LOGE(TAG, " - %s", pcTaskGetName(entry->task_handle)); - cpus_fail |= BIT(0); -#endif // configNUM_CORES > 1 -#else // CONFIG_FREERTOS_SMP - BaseType_t task_affinity = xTaskGetAffinity(entry->task_handle); - const char *cpu; - if (task_affinity == 0) { - cpu = DRAM_STR("CPU 0"); - cpus_fail |= BIT(0); - } else if (task_affinity == 1) { - cpu = DRAM_STR("CPU 1"); - cpus_fail |= BIT(1); - } else { - cpu = DRAM_STR("CPU 0/1"); - cpus_fail |= BIT(1) | BIT(0); - } - ESP_EARLY_LOGE(TAG, " - %s (%s)", pcTaskGetName(entry->task_handle), cpu); -#endif // CONFIG_FREERTOS_SMP - } else { - /* User entry, we cannot predict on which core it is scheduled to run, - * so let's mark all cores as failing */ -#if configNUM_CORES > 1 - cpus_fail = BIT(1) | BIT(0); -#else // configNUM_CORES > 1 - cpus_fail = BIT(0); -#endif // configNUM_CORES > 1 - ESP_EARLY_LOGE(TAG, " - %s", entry->user_name); - } - } - } + if (esp_task_wdt_print_triggered_tasks(NULL, NULL, &cpus_fail) != ESP_OK) { + // If there are no entries, there's nothing to do. + portEXIT_CRITICAL_ISR(&spinlock); + return; + } + ESP_EARLY_LOGE(TAG, "%s", DRAM_STR("Tasks currently running:")); for (int x = 0; x < portNUM_PROCESSORS; x++) { ESP_EARLY_LOGE(TAG, "CPU %d: %s", x, pcTaskGetName(xTaskGetCurrentTaskHandleForCPU(x))); @@ -855,3 +835,47 @@ esp_err_t esp_task_wdt_status(TaskHandle_t task_handle) return ret; } + +esp_err_t esp_task_wdt_print_triggered_tasks(task_wdt_msg_handler msg_handler, void *opaque, int *cpus_fail) +{ + if (SLIST_EMPTY(&p_twdt_obj->entries_slist)) { + return ESP_FAIL; + } + + twdt_entry_t *entry; + const char *caption = "Task watchdog got triggered. " + "The following tasks/users did not reset the watchdog in time:"; + + if (msg_handler == NULL) { + ESP_EARLY_LOGE(TAG, "%s", caption); + } else { + msg_handler(opaque, caption); + } + + // Find what entries triggered the TWDT timeout (i.e., which entries have not been reset) + SLIST_FOREACH(entry, &p_twdt_obj->entries_slist, slist_entry) { + if (!entry->has_reset) { + const char *cpu; + const char *name = entry->task_handle ? pcTaskGetName(entry->task_handle) : entry->user_name; + const UBaseType_t affinity = get_task_affinity(entry->task_handle); + if (cpus_fail) { + *cpus_fail |= affinity; + } + if (affinity == BIT(0)) { + cpu = " (CPU 0)"; + } else if (affinity == BIT(1)) { + cpu = " (CPU 1)"; + } else { + cpu = " (CPU 0/1)"; + } + if (msg_handler == NULL) { + ESP_EARLY_LOGE(TAG, " - %s%s", name, cpu); + } else { + msg_handler(opaque, "\n - "); + msg_handler(opaque, name); + msg_handler(opaque, cpu); + } + } + } + return ESP_OK; +} diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_ipc.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_ipc.c index da09e90107..78214b2ff2 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_ipc.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_ipc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ #include "unity.h" #if !CONFIG_FREERTOS_UNICORE #include "esp_ipc.h" +#include "esp_private/esp_ipc.h" #endif #include "esp_log.h" #include "esp_rom_sys.h" @@ -162,4 +163,50 @@ TEST_CASE("Test ipc_task can not wake up blocking task early", "[ipc]") TEST_ASSERT_EQUAL(31, val2); } +TEST_CASE("Test ipc call nonblocking", "[ipc]") +{ + int val_for_1_call = 20; + TEST_ESP_OK(esp_ipc_call_nonblocking(1, test_func_ipc_cb2, (void*)&val_for_1_call)); + TEST_ASSERT_EQUAL(20, val_for_1_call); + + int val_for_2_call = 30; + TEST_ESP_ERR(ESP_FAIL, esp_ipc_call_nonblocking(1, test_func_ipc_cb3, (void*)&val_for_2_call)); + + vTaskDelay(150 / portTICK_PERIOD_MS); + TEST_ASSERT_EQUAL(21, val_for_1_call); + + TEST_ESP_OK(esp_ipc_call_nonblocking(1, test_func_ipc_cb3, (void*)&val_for_2_call)); + + vTaskDelay(550 / portTICK_PERIOD_MS); + TEST_ASSERT_EQUAL(31, val_for_2_call); +} + +static void test_func_ipc_cb4(void *arg) +{ + int *val = (int *)arg; + *val = *val + 1; +} + +TEST_CASE("Test ipc call nonblocking when FreeRTOS Scheduler is suspended", "[ipc]") +{ + #ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionDisable(NULL); + #else + // Disable scheduler on the current CPU + vTaskSuspendAll(); + #endif // CONFIG_FREERTOS_SMP + + volatile int value = 20; + TEST_ESP_OK(esp_ipc_call_nonblocking(1, test_func_ipc_cb4, (void*)&value)); + while (value == 20) { }; + TEST_ASSERT_EQUAL(21, value); + + #ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionEnable(NULL); + #else + xTaskResumeAll(); + #endif +} #endif /* !CONFIG_FREERTOS_UNICORE */ diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c index 2d53aeeb52..c7dc181a52 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -41,7 +41,6 @@ __attribute__((unused)) static struct timeval tv_start, tv_stop; -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2) static void check_sleep_reset(void) { @@ -411,7 +410,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep][ig { // This test needs external pulldown ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); - ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH)); + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH)); esp_deep_sleep_start(); } @@ -419,7 +418,11 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep][ign { // This test needs external pullup ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); - ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW)); +#if CONFIG_IDF_TARGET_ESP32 + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW)); +#else + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_LOW)); +#endif esp_deep_sleep_start(); } @@ -429,7 +432,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 high)", "[deepsleep][ign ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13)); ESP_ERROR_CHECK(gpio_pulldown_en(GPIO_NUM_13)); ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)); - ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH)); + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH)); esp_deep_sleep_start(); } @@ -439,7 +442,11 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep][igno ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13)); ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13)); ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)); - ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW)); +#if CONFIG_IDF_TARGET_ESP32 + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW)); +#else + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_LOW)); +#endif esp_deep_sleep_start(); } #endif // SOC_PM_SUPPORT_EXT1_WAKEUP @@ -658,4 +665,3 @@ TEST_CASE("wake up using GPIO (2 or 4 low)", "[deepsleep][ignore]") esp_deep_sleep_start(); } #endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2) TODO: IDF-6268 diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c index a3c41d0b13..08fbb40a4f 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_task_wdt.c @@ -13,10 +13,11 @@ #include "esp_rom_sys.h" #include "esp_task_wdt.h" #include "test_utils.h" +#include "soc/rtc.h" #define TASK_WDT_TIMEOUT_MS 1000 -static bool timeout_flag; +static volatile bool timeout_flag; void esp_task_wdt_isr_user_handler(void) { @@ -40,6 +41,41 @@ TEST_CASE("Task WDT task timeout", "[task_wdt]") TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit()); } +#if SOC_MWDT_SUPPORT_XTAL + +#if CONFIG_IDF_TARGET_ESP32H2 +#define TEST_CPU_FREQUENCY_MHZ 48 +#else +#define TEST_CPU_FREQUENCY_MHZ 40 +#endif + +TEST_CASE("Task WDT task timeout - CPU Frequency changed", "[task_wdt]") +{ + rtc_cpu_freq_config_t old_config, new_config; + rtc_clk_cpu_freq_get_config(&old_config); + + TEST_ASSERT(rtc_clk_cpu_freq_mhz_to_config(TEST_CPU_FREQUENCY_MHZ, &new_config)); + rtc_clk_cpu_freq_set_config(&new_config); + + timeout_flag = false; + esp_task_wdt_config_t twdt_config = { + .timeout_ms = TASK_WDT_TIMEOUT_MS, + .idle_core_mask = 0, + .trigger_panic = false, + }; + TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_init(&twdt_config)); + TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_add(NULL)); + /* Short delay to allow timeout to occur, if WDT depends on any of the clocks changed + then the timeout should be slower and test will fail */ + esp_rom_delay_us(TASK_WDT_TIMEOUT_MS * 1000); + TEST_ASSERT_EQUAL(true, timeout_flag); + TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_delete(NULL)); + TEST_ASSERT_EQUAL(ESP_OK, esp_task_wdt_deinit()); + + rtc_clk_cpu_freq_set_config(&old_config); +} +#endif //SOC_MWDT_SUPPORT_XTAL + TEST_CASE("Task WDT inactive when no task to watch", "[task_wdt]") { /* Make sure a timeout is NOT trigger when we have no task to watch */ diff --git a/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.pd_vddsdio b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.pd_vddsdio new file mode 100644 index 0000000000..42890166e9 --- /dev/null +++ b/components/esp_system/test_apps/esp_system_unity_tests/sdkconfig.ci.pd_vddsdio @@ -0,0 +1,3 @@ +CONFIG_PM_SLP_IRAM_OPT=y +CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y +CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION=y diff --git a/components/esp_timer/CMakeLists.txt b/components/esp_timer/CMakeLists.txt index f644d63f43..d81776311b 100644 --- a/components/esp_timer/CMakeLists.txt +++ b/components/esp_timer/CMakeLists.txt @@ -2,7 +2,8 @@ idf_build_get_property(target IDF_TARGET) set(srcs "src/esp_timer.c" "src/ets_timer_legacy.c" - "src/system_time.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") diff --git a/components/esp_timer/private_include/esp_timer_impl.h b/components/esp_timer/private_include/esp_timer_impl.h index a6a502ad9c..ad2db51066 100644 --- a/components/esp_timer/private_include/esp_timer_impl.h +++ b/components/esp_timer/private_include/esp_timer_impl.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -143,3 +143,12 @@ uint64_t esp_timer_impl_get_alarm_reg(void); */ void esp_timer_impl_init_system_time(void); #endif + +#if CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD +/** + * @brief Set the next alarm if there is such an alarm in the cached array. + * + * @note Available only when CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is enabled. + */ +void esp_timer_impl_try_to_set_next_alarm(void); +#endif diff --git a/components/esp_timer/src/esp_timer.c b/components/esp_timer/src/esp_timer.c index dba90e9f12..3be0bfcec7 100644 --- a/components/esp_timer/src/esp_timer.c +++ b/components/esp_timer/src/esp_timer.c @@ -503,6 +503,7 @@ static void IRAM_ATTR timer_alarm_handler(void* arg) bool isr_timers_processed = false; #ifdef CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD + esp_timer_impl_try_to_set_next_alarm(); // process timers with ISR dispatch method isr_timers_processed = timer_process_alarm(ESP_TIMER_ISR); s_isr_dispatch_need_yield = pdFALSE; diff --git a/components/esp_timer/src/esp_timer_impl_common.c b/components/esp_timer/src/esp_timer_impl_common.c new file mode 100644 index 0000000000..d0c86f685d --- /dev/null +++ b/components/esp_timer/src/esp_timer_impl_common.c @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_timer_impl.h" +#include "esp_timer.h" +#include "esp_err.h" +#include "esp_task.h" +#include "esp_attr.h" + +/* Spinlock used to protect access to the hardware registers. */ +portMUX_TYPE s_time_update_lock = portMUX_INITIALIZER_UNLOCKED; + +/* Alarm values to generate interrupt on match + * [0] - for ESP_TIMER_TASK alarms, + * [1] - for ESP_TIMER_ISR alarms. +*/ +uint64_t timestamp_id[2] = { UINT64_MAX, UINT64_MAX }; + +void esp_timer_impl_lock(void) +{ + portENTER_CRITICAL(&s_time_update_lock); +} + +void esp_timer_impl_unlock(void) +{ + portEXIT_CRITICAL(&s_time_update_lock); +} + +void esp_timer_private_lock(void) __attribute__((alias("esp_timer_impl_lock"))); +void esp_timer_private_unlock(void) __attribute__((alias("esp_timer_impl_unlock"))); + +void IRAM_ATTR esp_timer_impl_set_alarm(uint64_t timestamp) +{ + esp_timer_impl_set_alarm_id(timestamp, 0); +} + +#ifdef CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD +void IRAM_ATTR esp_timer_impl_try_to_set_next_alarm(void) { + portENTER_CRITICAL_ISR(&s_time_update_lock); + unsigned now_alarm_idx; // ISR is called due to this current alarm + unsigned next_alarm_idx; // The following alarm after now_alarm_idx + if (timestamp_id[0] < timestamp_id[1]) { + now_alarm_idx = 0; + next_alarm_idx = 1; + } else { + now_alarm_idx = 1; + next_alarm_idx = 0; + } + + if (timestamp_id[next_alarm_idx] != UINT64_MAX) { + // The following alarm is valid and can be used. + // Remove the current alarm from consideration. + esp_timer_impl_set_alarm_id(UINT64_MAX, now_alarm_idx); + } else { + // There is no the following alarm. + // Remove the current alarm from consideration as well. + timestamp_id[now_alarm_idx] = UINT64_MAX; + } + portEXIT_CRITICAL_ISR(&s_time_update_lock); +} +#endif + +/* FIXME: This value is safe for 80MHz APB frequency, should be modified to depend on clock frequency. */ +uint64_t IRAM_ATTR esp_timer_impl_get_min_period_us(void) +{ + return 50; +} diff --git a/components/esp_timer/src/esp_timer_impl_lac.c b/components/esp_timer/src/esp_timer_impl_lac.c index 9d4feedf34..7ced67087f 100644 --- a/components/esp_timer/src/esp_timer_impl_lac.c +++ b/components/esp_timer/src/esp_timer_impl_lac.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -105,7 +105,6 @@ static alarm_intr_handler_t s_alarm_handler; /* Spinlock used to protect access to the hardware registers. */ static unsigned int s_time_update_lock; - void esp_timer_impl_lock(void) { s_time_update_lock = irq_lock(); @@ -280,12 +279,6 @@ void esp_timer_impl_deinit(void) s_alarm_handler = NULL; } -/* FIXME: This value is safe for 80MHz APB frequency, should be modified to depend on clock frequency. */ -uint64_t IRAM_ATTR esp_timer_impl_get_min_period_us(void) -{ - return 50; -} - uint64_t esp_timer_impl_get_alarm_reg(void) { s_time_update_lock = irq_lock(); @@ -300,5 +293,3 @@ uint64_t esp_timer_impl_get_alarm_reg(void) void esp_timer_private_update_apb_freq(uint32_t apb_ticks_per_us) __attribute__((alias("esp_timer_impl_update_apb_freq"))); void esp_timer_private_set(uint64_t new_us) __attribute__((alias("esp_timer_impl_set"))); void esp_timer_private_advance(int64_t time_diff_us) __attribute__((alias("esp_timer_impl_advance"))); -void esp_timer_private_lock(void) __attribute__((alias("esp_timer_impl_lock"))); -void esp_timer_private_unlock(void) __attribute__((alias("esp_timer_impl_unlock"))); diff --git a/components/esp_timer/src/esp_timer_impl_systimer.c b/components/esp_timer/src/esp_timer_impl_systimer.c index 4d780ad524..aa6648ba2b 100644 --- a/components/esp_timer/src/esp_timer_impl_systimer.c +++ b/components/esp_timer/src/esp_timer_impl_systimer.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -149,6 +149,10 @@ esp_err_t esp_timer_impl_early_init(void) systimer_hal_select_alarm_mode(&systimer_hal, SYSTIMER_ALARM_ESPTIMER, SYSTIMER_ALARM_MODE_ONESHOT); systimer_hal_connect_alarm_counter(&systimer_hal, SYSTIMER_ALARM_ESPTIMER, SYSTIMER_COUNTER_ESPTIMER); + for (unsigned cpuid = 0; cpuid < SOC_CPU_CORES_NUM; ++cpuid) { + systimer_hal_counter_can_stall_by_cpu(&systimer_hal, SYSTIMER_COUNTER_ESPTIMER, cpuid, (cpuid < portNUM_PROCESSORS) ? true : false); + } + return ESP_OK; } @@ -189,11 +193,6 @@ void esp_timer_impl_deinit(void) s_alarm_handler = NULL; } -uint64_t IRAM_ATTR esp_timer_impl_get_min_period_us(void) -{ - return 50; -} - uint64_t esp_timer_impl_get_alarm_reg(void) { s_time_update_lock = irq_lock(); @@ -205,5 +204,3 @@ uint64_t esp_timer_impl_get_alarm_reg(void) void esp_timer_private_update_apb_freq(uint32_t apb_ticks_per_us) __attribute__((alias("esp_timer_impl_update_apb_freq"))); void esp_timer_private_set(uint64_t new_us) __attribute__((alias("esp_timer_impl_set"))); void esp_timer_private_advance(int64_t time_diff_us) __attribute__((alias("esp_timer_impl_advance"))); -void esp_timer_private_lock(void) __attribute__((alias("esp_timer_impl_lock"))); -void esp_timer_private_unlock(void) __attribute__((alias("esp_timer_impl_unlock"))); diff --git a/components/esp_timer/test_apps/main/test_esp_timer.c b/components/esp_timer/test_apps/main/test_esp_timer.c index ddb6849ea6..9f11a39376 100644 --- a/components/esp_timer/test_apps/main/test_esp_timer.c +++ b/components/esp_timer/test_apps/main/test_esp_timer.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -84,6 +84,7 @@ TEST_CASE("esp_timer orders timers correctly", "[esp_timer]") } fclose(stream); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } static const int test_time_sec = 10; @@ -160,6 +161,7 @@ TEST_CASE("esp_timer produces correct delay", "[esp_timer]") TEST_ESP_OK( esp_timer_dump(stdout) ); esp_timer_delete(timer1); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } // no, we can't make this a const size_t (§6.7.5.2) @@ -218,6 +220,7 @@ TEST_CASE("periodic esp_timer produces correct delays", "[esp_timer]") TEST_ESP_OK( esp_timer_delete(timer1) ); vSemaphoreDelete(args.done); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } #undef NUM_INTERVALS @@ -342,6 +345,7 @@ TEST_CASE("multiple timers are ordered correctly", "[esp_timer]") TEST_ESP_OK( esp_timer_delete(args1.timer) ); TEST_ESP_OK( esp_timer_delete(args2.timer) ); TEST_ESP_OK( esp_timer_delete(args3.timer) ); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } #undef N @@ -384,6 +388,7 @@ TEST_CASE("esp_timer for very short intervals", "[esp_timer]") vSemaphoreDelete(semaphore); TEST_ESP_OK(esp_timer_delete(timer1)); TEST_ESP_OK(esp_timer_delete(timer2)); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } TEST_CASE("esp_timer_get_time call takes less than 1us", "[esp_timer]") @@ -633,6 +638,7 @@ TEST_CASE("after esp_timer_impl_advance, timers run when expected", "[esp_timer] ref_clock_deinit(); TEST_ESP_OK(esp_timer_delete(timer)); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } static esp_timer_handle_t timer1; @@ -670,6 +676,7 @@ TEST_CASE("Can start/stop timer from ISR context", "[esp_timer]") esp_deregister_freertos_tick_hook(test_tick_hook); TEST_ESP_OK( esp_timer_delete(timer1) ); vSemaphoreDelete(sem); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } #if !defined(CONFIG_FREERTOS_UNICORE) && SOC_DPORT_WORKAROUND @@ -861,6 +868,7 @@ TEST_CASE("Test a latency between a call of callback and real event", "[esp_time TEST_ESP_OK(esp_timer_dump(stdout)); TEST_ESP_OK(esp_timer_stop(periodic_timer)); TEST_ESP_OK(esp_timer_delete(periodic_timer)); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } static void test_timer_triggered(void* timer1_trig) @@ -909,6 +917,7 @@ TEST_CASE("periodic esp_timer can be restarted", "[esp_timer]") TEST_ESP_OK( esp_timer_stop(timer1) ); TEST_ESP_OK( esp_timer_delete(timer1) ); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } TEST_CASE("one-shot esp_timer can be restarted", "[esp_timer]") @@ -943,6 +952,7 @@ TEST_CASE("one-shot esp_timer can be restarted", "[esp_timer]") TEST_ASSERT_EQUAL(0, timer_trig); TEST_ESP_OK( esp_timer_delete(timer1) ); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } @@ -1002,6 +1012,7 @@ TEST_CASE("Test ESP_TIMER_ISR dispatch method", "[esp_timer]") TEST_ESP_OK(esp_timer_delete(periodic_timer2)); printf("timers deleted\n"); TEST_ESP_OK(esp_timer_dump(stdout)); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } static void dump_task(void* arg) @@ -1062,6 +1073,7 @@ TEST_CASE("Test ESP_TIMER_ISR dispatch method is not blocked", "[esp_timer]") TEST_ESP_OK(esp_timer_delete(periodic_timer1)); TEST_ESP_OK(esp_timer_delete(periodic_timer2)); printf("timer deleted\n"); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } static void isr_callback1(void* arg) @@ -1121,6 +1133,7 @@ TEST_CASE("Test ESP_TIMER_ISR, stop API cleans alarm reg if TASK timer list is e TEST_ESP_OK(esp_timer_delete(timer2)); vSemaphoreDelete(done); printf("timer deleted\n"); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } static void isr_callback2(void* arg) @@ -1176,6 +1189,7 @@ TEST_CASE("Test ESP_TIMER_ISR, stop API cleans alarm reg if ISR timer list is em TEST_ESP_OK(esp_timer_delete(timer2)); vSemaphoreDelete(done); printf("timer deleted\n"); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } #ifndef CONFIG_FREERTOS_UNICORE @@ -1214,6 +1228,77 @@ TEST_CASE("Test that CPU1 can handle esp_timer ISR even when CPU0 is blocked", " TEST_ESP_OK(esp_timer_dump(stdout)); TEST_ASSERT_INT_WITHIN(3, 10, data); TEST_ESP_OK(esp_timer_delete(timer)); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } #endif // not CONFIG_FREERTOS_UNICORE + +volatile uint64_t task_t1; +volatile uint64_t isr_t1; +const uint64_t period_task_ms = 200; +const uint64_t period_isr_ms = 20; + +void task_timer_cb(void *arg) { + uint64_t t2 = esp_timer_get_time(); + uint64_t dt_task_ms = (t2 - task_t1) / 1000; + task_t1 = t2; + printf("task callback, %d msec\n", (int)dt_task_ms); + vTaskDelay((period_task_ms / 2) / portTICK_PERIOD_MS); // very long callback in timer task + static bool first_run = true; + if (first_run) { + first_run = false; + } else { + TEST_ASSERT_INT_WITHIN(period_task_ms / 3, period_task_ms, dt_task_ms); + } +} + +void IRAM_ATTR isr_timer_cb(void *arg) { + uint64_t t2 = esp_timer_get_time(); + uint64_t dt_isr_ms = (t2 - isr_t1) / 1000; + isr_t1 = t2; + esp_rom_printf("isr callback, %d msec\n", (int)dt_isr_ms); + static bool first_run = true; + if (first_run) { + first_run = false; + } else { + TEST_ASSERT_INT_WITHIN(period_isr_ms / 3, period_isr_ms, dt_isr_ms); + } +} + +TEST_CASE("Test ISR dispatch callbacks are not blocked even if TASK callbacks take more time", "[esp_timer][isr_dispatch]") +{ + esp_timer_handle_t task_timer_handle; + esp_timer_handle_t isr_timer_handle; + + const esp_timer_create_args_t task_timer_args = { + .callback = &task_timer_cb, + .arg = NULL, + .dispatch_method = ESP_TIMER_TASK, + .name = "task_timer", + .skip_unhandled_events = true, + }; + + const esp_timer_create_args_t isr_timer_args = { + .callback = &isr_timer_cb, + .arg = NULL, + .dispatch_method = ESP_TIMER_ISR, + .name = "isr_timer", + .skip_unhandled_events = true, + }; + + ESP_ERROR_CHECK(esp_timer_create(&task_timer_args, &task_timer_handle)); + ESP_ERROR_CHECK(esp_timer_create(&isr_timer_args, &isr_timer_handle)); + ESP_ERROR_CHECK(esp_timer_start_periodic(task_timer_handle, period_task_ms * 1000)); + task_t1 = esp_timer_get_time(); + ESP_ERROR_CHECK(esp_timer_start_periodic(isr_timer_handle, period_isr_ms * 1000)); + isr_t1 = esp_timer_get_time(); + + vTaskDelay(period_task_ms * 5 / portTICK_PERIOD_MS); + + TEST_ESP_OK(esp_timer_stop(task_timer_handle)); + TEST_ESP_OK(esp_timer_stop(isr_timer_handle)); + TEST_ESP_OK(esp_timer_delete(task_timer_handle)); + TEST_ESP_OK(esp_timer_delete(isr_timer_handle)); + vTaskDelay(3); // wait for the esp_timer task to delete all timers +} + #endif // CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD diff --git a/components/esp_timer/test_apps/main/test_esp_timer_light_sleep.c b/components/esp_timer/test_apps/main/test_esp_timer_light_sleep.c index 41a1a8e381..33db6460a7 100644 --- a/components/esp_timer/test_apps/main/test_esp_timer_light_sleep.c +++ b/components/esp_timer/test_apps/main/test_esp_timer_light_sleep.c @@ -8,6 +8,8 @@ #include #include #include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" #include "esp_timer.h" #include "unity.h" #include "esp_rom_sys.h" @@ -35,22 +37,26 @@ TEST_CASE("Test the periodic timer does not handle lost events during light slee int period_cb_ms = 10; int interval_ms = 50; - TEST_ESP_OK(esp_timer_start_periodic(periodic_timer, period_cb_ms * 1000)); - TEST_ESP_OK(esp_sleep_enable_timer_wakeup(interval_ms * 1000)); printf("Run light sleep\n"); printf("count_calls should be around = %d\n", interval_ms / period_cb_ms); + TEST_ESP_OK(esp_sleep_enable_timer_wakeup(interval_ms * 1000)); + TEST_ESP_OK(esp_timer_start_periodic(periodic_timer, period_cb_ms * 1000)); for (int i = 0; i < 3; i++) { - count_calls = 0; - TEST_ESP_OK(esp_light_sleep_start()); + do { + count_calls = 0; + } while (esp_light_sleep_start() != ESP_OK); esp_rom_delay_us(interval_ms * 1000); - printf("count_calls = %d\n", count_calls); - TEST_ASSERT_INT_WITHIN(2, interval_ms / period_cb_ms, count_calls); + vTaskDelay(1); // wait for the esp_timer task to start on another core processing period_timer after sleep + int saved_count_calls = count_calls; + printf("count_calls = %d\n", saved_count_calls); TEST_ESP_OK(esp_timer_dump(stdout)); + TEST_ASSERT_INT_WITHIN(2, interval_ms / period_cb_ms, saved_count_calls); } TEST_ESP_OK(esp_timer_stop(periodic_timer)); // times_skipped is about 12 (4 from each sleep time). TEST_ESP_OK(esp_timer_dump(stdout)); TEST_ESP_OK(esp_timer_delete(periodic_timer)); + vTaskDelay(3); // wait for the esp_timer task to delete all timers } #endif //#!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6) diff --git a/components/esp_timer/test_apps/pytest_esp_timer_ut.py b/components/esp_timer/test_apps/pytest_esp_timer_ut.py index d61c52a630..83afa36388 100644 --- a/components/esp_timer/test_apps/pytest_esp_timer_ut.py +++ b/components/esp_timer/test_apps/pytest_esp_timer_ut.py @@ -10,6 +10,7 @@ pytest.param('single_core', marks=[pytest.mark.esp32]), pytest.param('freertos_compliance', marks=[pytest.mark.esp32]), pytest.param('isr_dispatch_esp32', marks=[pytest.mark.esp32]), + pytest.param('isr_dispatch_esp32c3', marks=[pytest.mark.esp32c3]), pytest.param('cpu1_esp32', marks=[pytest.mark.esp32]), pytest.param('any_cpu_esp32', marks=[pytest.mark.esp32]), pytest.param('cpu1_esp32s3', marks=[pytest.mark.esp32s3]), diff --git a/components/esp_timer/test_apps/sdkconfig.ci.isr_dispatch_esp32c3 b/components/esp_timer/test_apps/sdkconfig.ci.isr_dispatch_esp32c3 new file mode 100644 index 0000000000..9ef18709ca --- /dev/null +++ b/components/esp_timer/test_apps/sdkconfig.ci.isr_dispatch_esp32c3 @@ -0,0 +1,2 @@ +CONFIG_IDF_TARGET="esp32c3" +CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD=y diff --git a/components/esp_wifi/CMakeLists.txt b/components/esp_wifi/CMakeLists.txt index bcd442eeb8..0844b89578 100644 --- a/components/esp_wifi/CMakeLists.txt +++ b/components/esp_wifi/CMakeLists.txt @@ -66,4 +66,8 @@ if(CONFIG_ESP_WIFI_ENABLED) endforeach() endif() + if(CONFIG_SPIRAM) + idf_component_optional_requires(PRIVATE esp_psram) + endif() + endif() diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index bc42da9f2d..b173d31f5c 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -113,6 +113,40 @@ menu "Wi-Fi" can deliver frames faster than WiFi layer can transmit. In these cases, we may run out of TX buffers. + choice ESP_WIFI_MGMT_RX_BUFFER + prompt "Type of WiFi RX MGMT buffers" + default ESP_WIFI_STATIC_RX_MGMT_BUFFER + help + Select type of WiFi RX MGMT buffers: + + If "Static" is selected, WiFi RX MGMT buffers are allocated when WiFi is initialized and released + when WiFi is de-initialized. The size of each static RX MGMT buffer is fixed to about 500 Bytes. + + If "Dynamic" is selected, each WiFi RX MGMT buffer is allocated as needed when a MGMT data frame is + received. The MGMT buffer is freed after the MGMT data frame has been processed by the WiFi driver. + + + config ESP_WIFI_STATIC_RX_MGMT_BUFFER + bool "Static" + config ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER + bool "Dynamic" + endchoice + + config ESP_WIFI_DYNAMIC_RX_MGMT_BUF + int + default 0 if ESP_WIFI_STATIC_RX_MGMT_BUFFER + default 1 if ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER + + config ESP_WIFI_RX_MGMT_BUF_NUM_DEF + int "Max number of WiFi RX MGMT buffers" + range 1 10 + default 5 + help + Set the number of WiFi RX_MGMT buffers. + + For Management buffers, the number of dynamic and static management buffers is the same. + In order to prevent memory fragmentation, the management buffer type should be set to static first. + config ESP_WIFI_CSI_ENABLED bool "WiFi CSI(Channel State Information)" depends on SOC_WIFI_CSI_SUPPORT @@ -226,6 +260,15 @@ menu "Wi-Fi" When this option is disabled, more than 10Kbytes of IRAM memory will be saved but Wi-Fi throughput will be reduced. + config ESP_WIFI_EXTRA_IRAM_OPT + bool "WiFi EXTRA IRAM speed optimization" + default y if IDF_TARGET_ESP32C6 + default n + help + Select this option to place additional frequently called Wi-Fi library functions + in IRAM. When this option is disabled, more than 5Kbytes of IRAM memory will be saved + but Wi-Fi throughput will be reduced. + config ESP_WIFI_RX_IRAM_OPT bool "WiFi RX IRAM speed optimization" default n if (BT_ENABLED && SPIRAM && IDF_TARGET_ESP32) @@ -238,7 +281,7 @@ menu "Wi-Fi" config ESP_WIFI_ENABLE_WPA3_SAE bool "Enable WPA3-Personal" default y - depends on ESP_WIFI_MBEDTLS_CRYPTO + select ESP_WIFI_MBEDTLS_CRYPTO help Select this option to allow the device to establish a WPA3-Personal connection with eligible AP's. PMF (Protected Management Frames) is a prerequisite feature for a WPA3 connection, it needs to be @@ -284,17 +327,30 @@ menu "Wi-Fi" int "Minimum active time" range 8 60 default 50 - depends on ESP_WIFI_SLP_IRAM_OPT help - The minimum timeout for waiting to receive data, unit: milliseconds. + Only for station in WIFI_PS_MIN_MODEM or WIFI_PS_MAX_MODEM. When the station enters the active state, + it will work for at least ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME. If a data packet is received or sent + during this period, the time will be refreshed. If the time is up, but the station still has packets + to receive or send, the time will also be refreshed. unit: milliseconds. config ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME int "Maximum keep alive time" range 10 60 default 10 - depends on ESP_WIFI_SLP_IRAM_OPT help - The maximum time that wifi keep alive, unit: seconds. + Only for station in WIFI_PS_MIN_MODEM or WIFI_PS_MAX_MODEM. If no packet has been + sent within ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME, a null data packet will be sent + to maintain the connection with the AP. unit: seconds. + + config ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME + int "Minimum wait broadcast data time" + range 10 30 + default 15 + help + Only for station in WIFI_PS_MIN_MODEM or WIFI_PS_MAX_MODEM. When the station knows through the beacon + that AP will send broadcast packet, it will wait for ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME + before entering the sleep process. If a broadcast packet is received with more data bits, the time + will refreshed. unit: milliseconds. config ESP_WIFI_FTM_ENABLE bool "WiFi FTM" @@ -329,7 +385,7 @@ menu "Wi-Fi" config ESP_WIFI_GMAC_SUPPORT bool "WiFi GMAC Support(GMAC128 and GMAC256)" - default n + default y help Select this option to enable GMAC support. GMAC support is compulsory for WiFi 192 bit certification. @@ -422,13 +478,21 @@ menu "Wi-Fi" select MBEDTLS_ECP_C select MBEDTLS_ECDH_C select MBEDTLS_ECDSA_C - select MBEDTLS_TLS_ENABLED + select MBEDTLS_CMAC_C + select MBEDTLS_ECP_DP_SECP256R1_ENABLED help - Select this option to use MbedTLS crypto APIs which utilize hardware acceleration. + Select this option to enable the use of MbedTLS crypto APIs. + The internal crypto support within the supplicant is limited + and may not suffice for all new security features, including WPA3. + + It is recommended to always keep this option enabled. Additionally, + note that MbedTLS can leverage hardware acceleration if available, + resulting in significantly faster cryptographic operations. if ESP_WIFI_MBEDTLS_CRYPTO config ESP_WIFI_MBEDTLS_TLS_CLIENT bool "Use MbedTLS TLS client for WiFi Enterprise connection" + depends on ESP_WIFI_ENTERPRISE_SUPPORT default y select MBEDTLS_TLS_ENABLED help @@ -450,6 +514,7 @@ menu "Wi-Fi" config ESP_WIFI_SUITE_B_192 bool "Enable NSA suite B support with 192 bit key" default n + depends on SOC_WIFI_GCMP_SUPPORT select ESP_WIFI_GCMP_SUPPORT select ESP_WIFI_GMAC_SUPPORT help @@ -563,4 +628,22 @@ menu "Wi-Fi" help Select this to enable unity test for DPP. + config ESP_WIFI_ENTERPRISE_SUPPORT + bool "Enable enterprise option" + default y + help + Select this to enable/disable enterprise connection support. + + disabling this will reduce binary size. + disabling this will disable the use of any esp_wifi_sta_wpa2_ent_* (as APIs will be meaningless) + + config ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER + bool "Free dynamic buffers during WiFi enterprise connection" + depends on ESP_WIFI_ENTERPRISE_SUPPORT + default y if IDF_TARGET_ESP32C2 + default n if !IDF_TARGET_ESP32C2 + help + Select this configuration to free dynamic buffers during WiFi enterprise connection. + This will enable chip to reduce heap consumption during WiFi enterprise connection. + endmenu # Wi-Fi diff --git a/components/esp_wifi/esp32/esp_adapter.c b/components/esp_wifi/esp32/esp_adapter.c index ba9974ef5c..726255c2a3 100644 --- a/components/esp_wifi/esp32/esp_adapter.c +++ b/components/esp_wifi/esp32/esp_adapter.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ #include "freertos/event_groups.h" #include "freertos/portmacro.h" #include "freertos/xtensa_api.h" +#include "freertos/idf_additions.h" #include "esp_types.h" #include "esp_random.h" #include "esp_mac.h" @@ -39,11 +40,11 @@ #include "nvs.h" #include "os.h" #include "esp_smartconfig.h" -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #include "dport_access.h" #include "esp_rom_sys.h" #include "esp32/rom/ets_sys.h" -#include "esp_modem_wrapper.h" +#include "private/esp_modem_wrapper.h" #define TAG "esp_adapter" @@ -117,6 +118,7 @@ wifi_static_queue_t* wifi_create_queue( int queue_len, int item_size) } #if CONFIG_SPIRAM_USE_MALLOC + /* Wi-Fi still use internal RAM */ queue->storage = heap_caps_calloc(1, sizeof(StaticQueue_t) + (queue_len*item_size), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); if (!queue->storage) { @@ -254,7 +256,37 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) + /* + * Since release/v5.1, FreeRTOS has been updated to always use internal memory (i.e., DRAM) + * for dynamic memory allocation. Calling FreeRTOS creation functions (e.g., xTaskCreate(), xQueueCreate()) + * will guarantee that the memory allocated for those tasks/objects is from internal memory. + * For more details, please refer to the Migration Guide in release/v5.1. + */ +#if CONFIG_SPIRAM_USE_MALLOC + /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ + return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); +#else + return (void *)xQueueCreate(queue_len, item_size); +#endif +#else return (void *)xQueueCreate(queue_len, item_size); +#endif +} + +static void queue_delete_wrapper(void *queue) +{ + if (queue) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) +#if CONFIG_SPIRAM_USE_MALLOC + vQueueDeleteWithCaps(queue); +#else + vQueueDelete(queue); +#endif +#else + vQueueDelete(queue); +#endif + } } static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) @@ -542,11 +574,41 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { } +static void esp_phy_enable_wrapper(void) +{ + esp_phy_enable(PHY_MODEM_WIFI); + phy_wifi_enable_set(1); +} + +static void esp_phy_disable_wrapper(void) +{ + phy_wifi_enable_set(0); + esp_phy_disable(PHY_MODEM_WIFI); +} + wifi_osi_funcs_t g_wifi_osi_funcs = { ._version = ESP_WIFI_OS_ADAPTER_VERSION, ._env_is_chip = esp_coex_common_env_is_chip_wrapper, @@ -572,7 +634,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._mutex_lock = mutex_lock_wrapper, ._mutex_unlock = mutex_unlock_wrapper, ._queue_create = queue_create_wrapper, - ._queue_delete = (void(*)(void *))vQueueDelete, + ._queue_delete = queue_delete_wrapper, ._queue_send = queue_send_wrapper, ._queue_send_from_isr = queue_send_from_isr_wrapper, ._queue_send_to_back = queue_send_to_back_wrapper, @@ -600,8 +662,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._dport_access_stall_other_cpu_end_wrap = s_esp_dport_access_stall_other_cpu_end, ._wifi_apb80m_request = wifi_apb80m_request_wrapper, ._wifi_apb80m_release = wifi_apb80m_release_wrapper, - ._phy_disable = esp_phy_disable, - ._phy_enable = esp_phy_enable, + ._phy_disable = esp_phy_disable_wrapper, + ._phy_enable = esp_phy_enable_wrapper, ._phy_common_clock_enable = esp_phy_common_clock_enable, ._phy_common_clock_disable = esp_phy_common_clock_disable, ._phy_update_country_info = esp_phy_update_country_info, @@ -664,5 +726,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32c2/esp_adapter.c b/components/esp_wifi/esp32c2/esp_adapter.c index f2c6a41e1b..22aadef0c2 100644 --- a/components/esp_wifi/esp32c2/esp_adapter.c +++ b/components/esp_wifi/esp32c2/esp_adapter.c @@ -40,9 +40,9 @@ #include "nvs.h" #include "os.h" #include "esp_smartconfig.h" -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #include "esp32c2/rom/ets_sys.h" -#include "esp_modem_wrapper.h" +#include "private/esp_modem_wrapper.h" #define TAG "esp_adapter" @@ -512,11 +512,41 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { } +static void esp_phy_enable_wrapper(void) +{ + esp_phy_enable(PHY_MODEM_WIFI); + phy_wifi_enable_set(1); +} + +static void esp_phy_disable_wrapper(void) +{ + phy_wifi_enable_set(0); + esp_phy_disable(PHY_MODEM_WIFI); +} + wifi_osi_funcs_t g_wifi_osi_funcs = { ._version = ESP_WIFI_OS_ADAPTER_VERSION, ._env_is_chip = esp_coex_common_env_is_chip_wrapper, @@ -570,8 +600,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper, ._wifi_apb80m_request = wifi_apb80m_request_wrapper, ._wifi_apb80m_release = wifi_apb80m_release_wrapper, - ._phy_disable = esp_phy_disable, - ._phy_enable = esp_phy_enable, + ._phy_disable = esp_phy_disable_wrapper, + ._phy_enable = esp_phy_enable_wrapper, ._phy_update_country_info = esp_phy_update_country_info, ._read_mac = esp_read_mac_wrapper, ._timer_arm = timer_arm_wrapper, @@ -633,5 +663,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32c3/esp_adapter.c b/components/esp_wifi/esp32c3/esp_adapter.c index 0e17296bdc..d08b7467ed 100644 --- a/components/esp_wifi/esp32c3/esp_adapter.c +++ b/components/esp_wifi/esp32c3/esp_adapter.c @@ -41,9 +41,9 @@ #include "nvs.h" #include "os.h" #include "esp_smartconfig.h" -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #include "esp32c3/rom/ets_sys.h" -#include "esp_modem_wrapper.h" +#include "private/esp_modem_wrapper.h" #define TAG "esp_adapter" @@ -529,11 +529,41 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { } +static void esp_phy_enable_wrapper(void) +{ + esp_phy_enable(PHY_MODEM_WIFI); + phy_wifi_enable_set(1); +} + +static void esp_phy_disable_wrapper(void) +{ + phy_wifi_enable_set(0); + esp_phy_disable(PHY_MODEM_WIFI); +} + wifi_osi_funcs_t g_wifi_osi_funcs = { ._version = ESP_WIFI_OS_ADAPTER_VERSION, ._env_is_chip = esp_coex_common_env_is_chip_wrapper, @@ -587,8 +617,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper, ._wifi_apb80m_request = wifi_apb80m_request_wrapper, ._wifi_apb80m_release = wifi_apb80m_release_wrapper, - ._phy_disable = esp_phy_disable, - ._phy_enable = esp_phy_enable, + ._phy_disable = esp_phy_disable_wrapper, + ._phy_enable = esp_phy_enable_wrapper, ._phy_update_country_info = esp_phy_update_country_info, ._read_mac = esp_read_mac_wrapper, ._timer_arm = timer_arm_wrapper, @@ -650,5 +680,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32c6/esp_adapter.c b/components/esp_wifi/esp32c6/esp_adapter.c index 8478ace8f7..e6e5cbf711 100644 --- a/components/esp_wifi/esp32c6/esp_adapter.c +++ b/components/esp_wifi/esp32c6/esp_adapter.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,9 +40,9 @@ #include "nvs.h" #include "os.h" #include "esp_smartconfig.h" -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #include "esp32c6/rom/ets_sys.h" -#include "esp_modem_wrapper.h" +#include "private/esp_modem_wrapper.h" #include "esp_private/esp_modem_clock.h" #if SOC_PM_MODEM_RETENTION_BY_REGDMA @@ -518,11 +518,53 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { } +static void esp_phy_enable_wrapper(void) +{ + esp_phy_enable(PHY_MODEM_WIFI); + phy_wifi_enable_set(1); +} + +static void esp_phy_disable_wrapper(void) +{ + phy_wifi_enable_set(0); + esp_phy_disable(PHY_MODEM_WIFI); +} + +#if SOC_PM_MODEM_RETENTION_BY_REGDMA +static void regdma_link_set_write_wait_content_wrapper(void *addr, uint32_t value, uint32_t mask) +{ + regdma_link_set_write_wait_content(addr, value, mask); +} + +static void *sleep_retention_find_link_by_id_wrapper(int id) +{ + return sleep_retention_find_link_by_id(id); +} +#endif + wifi_osi_funcs_t g_wifi_osi_funcs = { ._version = ESP_WIFI_OS_ADAPTER_VERSION, ._env_is_chip = esp_coex_common_env_is_chip_wrapper, @@ -576,8 +618,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper, ._wifi_apb80m_request = wifi_apb80m_request_wrapper, ._wifi_apb80m_release = wifi_apb80m_release_wrapper, - ._phy_disable = esp_phy_disable, - ._phy_enable = esp_phy_enable, + ._phy_disable = esp_phy_disable_wrapper, + ._phy_enable = esp_phy_enable_wrapper, ._phy_update_country_info = esp_phy_update_country_info, ._read_mac = esp_read_mac_wrapper, ._timer_arm = timer_arm_wrapper, @@ -638,12 +680,12 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper, ._coex_register_start_cb = coex_register_start_cb_wrapper, #if SOC_PM_MODEM_RETENTION_BY_REGDMA - ._regdma_link_set_write_wait_content = regdma_link_set_write_wait_content, - ._sleep_retention_find_link_by_id = sleep_retention_find_link_by_id, - ._sleep_retention_entries_create = (int (*)(const void *, int, int, int))sleep_retention_entries_create, - ._sleep_retention_entries_destroy = sleep_retention_entries_destroy, + ._regdma_link_set_write_wait_content = regdma_link_set_write_wait_content_wrapper, + ._sleep_retention_find_link_by_id = sleep_retention_find_link_by_id_wrapper, #endif ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32s2/esp_adapter.c b/components/esp_wifi/esp32s2/esp_adapter.c index a0966d2c83..347ac0c94f 100644 --- a/components/esp_wifi/esp32s2/esp_adapter.c +++ b/components/esp_wifi/esp32s2/esp_adapter.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ #include "freertos/event_groups.h" #include "freertos/portmacro.h" #include "freertos/xtensa_api.h" +#include "freertos/idf_additions.h" #include "esp_types.h" #include "esp_random.h" #include "esp_mac.h" @@ -41,10 +42,10 @@ #include "nvs.h" #include "os.h" #include "esp_smartconfig.h" -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #include "esp_rom_sys.h" #include "esp32s2/rom/ets_sys.h" -#include "esp_modem_wrapper.h" +#include "private/esp_modem_wrapper.h" #define TAG "esp_adapter" @@ -108,6 +109,7 @@ wifi_static_queue_t* wifi_create_queue( int queue_len, int item_size) } #if CONFIG_SPIRAM_USE_MALLOC + /* Wi-Fi still use internal RAM */ queue->storage = heap_caps_calloc(1, sizeof(StaticQueue_t) + (queue_len*item_size), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); if (!queue->storage) { @@ -245,7 +247,37 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) + /* + * Since release/v5.1, FreeRTOS has been updated to always use internal memory (i.e., DRAM) + * for dynamic memory allocation. Calling FreeRTOS creation functions (e.g., xTaskCreate(), xQueueCreate()) + * will guarantee that the memory allocated for those tasks/objects is from internal memory. + * For more details, please refer to the Migration Guide in release/v5.1. + */ +#if CONFIG_SPIRAM_USE_MALLOC + /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ + return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); +#else + return (void *)xQueueCreate(queue_len, item_size); +#endif +#else return (void *)xQueueCreate(queue_len, item_size); +#endif +} + +static void queue_delete_wrapper(void *queue) +{ + if (queue) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) +#if CONFIG_SPIRAM_USE_MALLOC + vQueueDeleteWithCaps(queue); +#else + vQueueDelete(queue); +#endif +#else + vQueueDelete(queue); +#endif + } } static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) @@ -537,11 +569,39 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { } +static void esp_phy_enable_wrapper(void) +{ + esp_phy_enable(PHY_MODEM_WIFI); +} + +static void esp_phy_disable_wrapper(void) +{ + esp_phy_disable(PHY_MODEM_WIFI); +} + wifi_osi_funcs_t g_wifi_osi_funcs = { ._version = ESP_WIFI_OS_ADAPTER_VERSION, ._env_is_chip = esp_coex_common_env_is_chip_wrapper, @@ -567,7 +627,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._mutex_lock = mutex_lock_wrapper, ._mutex_unlock = mutex_unlock_wrapper, ._queue_create = queue_create_wrapper, - ._queue_delete = (void(*)(void *))vQueueDelete, + ._queue_delete = queue_delete_wrapper, ._queue_send = queue_send_wrapper, ._queue_send_from_isr = queue_send_from_isr_wrapper, ._queue_send_to_back = queue_send_to_back_wrapper, @@ -595,8 +655,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper, ._wifi_apb80m_request = wifi_apb80m_request_wrapper, ._wifi_apb80m_release = wifi_apb80m_release_wrapper, - ._phy_disable = esp_phy_disable, - ._phy_enable = esp_phy_enable, + ._phy_disable = esp_phy_disable_wrapper, + ._phy_enable = esp_phy_enable_wrapper, ._phy_common_clock_enable = esp_phy_common_clock_enable, ._phy_common_clock_disable = esp_phy_common_clock_disable, ._phy_update_country_info = esp_phy_update_country_info, @@ -660,6 +720,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, - + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/esp32s3/esp_adapter.c b/components/esp_wifi/esp32s3/esp_adapter.c index 169af254f2..d565b3ba3d 100644 --- a/components/esp_wifi/esp32s3/esp_adapter.c +++ b/components/esp_wifi/esp32s3/esp_adapter.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ #include "freertos/event_groups.h" #include "freertos/portmacro.h" #include "freertos/xtensa_api.h" +#include "freertos/idf_additions.h" #include "esp_types.h" #include "esp_random.h" #include "esp_mac.h" @@ -42,10 +43,10 @@ #include "nvs.h" #include "os.h" #include "esp_smartconfig.h" -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #include "esp_rom_sys.h" #include "esp32s3/rom/ets_sys.h" -#include "esp_modem_wrapper.h" +#include "private/esp_modem_wrapper.h" #define TAG "esp_adapter" @@ -111,6 +112,7 @@ wifi_static_queue_t* wifi_create_queue( int queue_len, int item_size) } #if CONFIG_SPIRAM_USE_MALLOC + /* Wi-Fi still use internal RAM */ queue->storage = heap_caps_calloc(1, sizeof(StaticQueue_t) + (queue_len*item_size), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); if (!queue->storage) { @@ -248,7 +250,37 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) + /* + * Since release/v5.1, FreeRTOS has been updated to always use internal memory (i.e., DRAM) + * for dynamic memory allocation. Calling FreeRTOS creation functions (e.g., xTaskCreate(), xQueueCreate()) + * will guarantee that the memory allocated for those tasks/objects is from internal memory. + * For more details, please refer to the Migration Guide in release/v5.1. + */ +#if CONFIG_SPIRAM_USE_MALLOC + /* Use xQueueCreateWithCaps() to allocate from SPIRAM */ + return (void *)xQueueCreateWithCaps(queue_len, item_size, MALLOC_CAP_SPIRAM); +#else + return (void *)xQueueCreate(queue_len, item_size); +#endif +#else return (void *)xQueueCreate(queue_len, item_size); +#endif +} + +static void queue_delete_wrapper(void *queue) +{ + if (queue) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0) +#if CONFIG_SPIRAM_USE_MALLOC + vQueueDeleteWithCaps(queue); +#else + vQueueDelete(queue); +#endif +#else + vQueueDelete(queue); +#endif + } } static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) @@ -554,11 +586,42 @@ static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) #endif } +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + static void IRAM_ATTR esp_empty_wrapper(void) { } + +static void esp_phy_enable_wrapper(void) +{ + esp_phy_enable(PHY_MODEM_WIFI); + phy_wifi_enable_set(1); +} + +static void esp_phy_disable_wrapper(void) +{ + phy_wifi_enable_set(0); + esp_phy_disable(PHY_MODEM_WIFI); +} + wifi_osi_funcs_t g_wifi_osi_funcs = { ._version = ESP_WIFI_OS_ADAPTER_VERSION, ._env_is_chip = esp_coex_common_env_is_chip_wrapper, @@ -584,7 +647,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._mutex_lock = mutex_lock_wrapper, ._mutex_unlock = mutex_unlock_wrapper, ._queue_create = queue_create_wrapper, - ._queue_delete = (void(*)(void *))vQueueDelete, + ._queue_delete = queue_delete_wrapper, ._queue_send = queue_send_wrapper, ._queue_send_from_isr = queue_send_from_isr_wrapper, ._queue_send_to_back = queue_send_to_back_wrapper, @@ -612,8 +675,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper, ._wifi_apb80m_request = wifi_apb80m_request_wrapper, ._wifi_apb80m_release = wifi_apb80m_release_wrapper, - ._phy_disable = esp_phy_disable, - ._phy_enable = esp_phy_enable, + ._phy_disable = esp_phy_disable_wrapper, + ._phy_enable = esp_phy_enable_wrapper, ._phy_update_country_info = esp_phy_update_country_info, ._read_mac = esp_read_mac, ._timer_arm = timer_arm_wrapper, @@ -675,5 +738,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._coex_register_start_cb = coex_register_start_cb_wrapper, ._coex_schm_process_restart = coex_schm_process_restart_wrapper, ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; diff --git a/components/esp_wifi/include/esp_mesh.h b/components/esp_wifi/include/esp_mesh.h index 5ba707b527..ee5bac24e4 100644 --- a/components/esp_wifi/include/esp_mesh.h +++ b/components/esp_wifi/include/esp_mesh.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -136,10 +136,13 @@ extern "C" { /** * @brief Flag of mesh networking IE */ -#define MESH_ASSOC_FLAG_VOTE_IN_PROGRESS (0x02) /**< vote in progress */ +#define MESH_ASSOC_FLAG_MAP_ASSOC (0x01) /**< Mesh AP doesn't detect children leave yet */ +#define MESH_ASSOC_FLAG_VOTE_IN_PROGRESS (0x02) /**< station in vote, set when root vote start, clear when connect to router or when root switch*/ +#define MESH_ASSOC_FLAG_STA_VOTED (0x04) /**< station vote done, set when connect to router */ #define MESH_ASSOC_FLAG_NETWORK_FREE (0x08) /**< no root in current network */ -#define MESH_ASSOC_FLAG_ROOTS_FOUND (0x20) /**< root conflict is found */ -#define MESH_ASSOC_FLAG_ROOT_FIXED (0x40) /**< fixed root */ +#define MESH_ASSOC_FLAG_STA_VOTE_EXPIRE (0x10) /**< the voted address is expired, means the voted device lose the chance to be root */ +#define MESH_ASSOC_FLAG_ROOTS_FOUND (0x20) /**< roots conflict is found, means that there are at least two roots in the mesh network */ +#define MESH_ASSOC_FLAG_ROOT_FIXED (0x40) /**< the root is fixed in the mesh network */ /** @@ -214,7 +217,7 @@ typedef enum { MESH_ROOT, /**< the only sink of the mesh network. Has the ability to access external IP network */ MESH_NODE, /**< intermediate device. Has the ability to forward packets over the mesh network */ MESH_LEAF, /**< has no forwarding ability */ - MESH_STA, /**< connect to router with a standlone Wi-Fi station mode, no network expansion capability */ + MESH_STA, /**< connect to router with a standalone Wi-Fi station mode, no network expansion capability */ } mesh_type_t; /** @@ -640,14 +643,16 @@ esp_err_t esp_mesh_stop(void); * - Field size should not exceed MESH_MPS. Note that the size of one mesh packet should not exceed MESH_MTU. * - Field proto should be set to data protocol in use (default is MESH_PROTO_BIN for binary). * - Field tos should be set to transmission tos (type of service) in use (default is MESH_TOS_P2P for point-to-point reliable). + * - If the packet is to the root, MESH_TOS_P2P must be set to ensure reliable transmission. + * - As long as the MESH_TOS_P2P is set, the API is blocking, even if the flag is set with MESH_DATA_NONBLOCK. + * - As long as the MESH_TOS_DEF is set, the API is non-blocking. * @param[in] flag bitmap for data sent + * - Flag is at least one of the three MESH_DATA_P2P/MESH_DATA_FROMDS/MESH_DATA_TODS, which represents the direction of packet sending. * - Speed up the route search - * - If the packet is to the root and "to" parameter is NULL, set this parameter to 0. * - If the packet is to an internal device, MESH_DATA_P2P should be set. * - If the packet is to the root ("to" parameter isn't NULL) or to external IP network, MESH_DATA_TODS should be set. * - If the packet is from the root to an internal device, MESH_DATA_FROMDS should be set. - * - Specify whether this API is block or non-block, block by default - * - If needs non-blocking, MESH_DATA_NONBLOCK should be set. Otherwise, may use esp_mesh_send_block_time() to specify a blocking time. + * - Specify whether this API is blocking or non-blocking, blocking by default. * - In the situation of the root change, MESH_DATA_DROP identifies this packet can be dropped by the new root * for upstream data to external IP network, we try our best to avoid data loss caused by the root change, but * there is a risk that the new root is running out of memory because most of memory is occupied by the pending data which @@ -682,6 +687,7 @@ esp_err_t esp_mesh_send(const mesh_addr_t *to, const mesh_data_t *data, int flag, const mesh_opt_t opt[], int opt_count); /** * @brief Set blocking time of esp_mesh_send() + * - Suggest to set the blocking time to at least 5s when the environment is poor. Otherwise, esp_mesh_send() may timeout frequently. * * @attention This API shall be called before mesh is started. * @@ -1200,6 +1206,7 @@ int esp_mesh_get_xon_qsize(void); /** * @brief Set whether allow more than one root existing in one network + * - The default value is true, that is, multiple roots are allowed. * * @param[in] allowed allow or not * @@ -1291,7 +1298,7 @@ int esp_mesh_get_capacity_num(void); /** * @brief Set mesh IE crypto functions * - * @attention This API can be called at any time after mesh is initialized. + * @attention This API can be called at any time after mesh is configured. * * @param[in] crypto_funcs crypto functions for mesh IE * - If crypto_funcs is set to NULL, mesh IE is no longer encrypted. @@ -1303,7 +1310,7 @@ esp_err_t esp_mesh_set_ie_crypto_funcs(const mesh_crypto_funcs_t *crypto_funcs); /** * @brief Set mesh IE crypto key * - * @attention This API can be called at any time after mesh is initialized. + * @attention This API can be called at any time after mesh is configured. * * @param[in] key ASCII crypto key * @param[in] len length in bytes, range:8~64 @@ -1400,7 +1407,7 @@ esp_err_t esp_mesh_set_parent(const wifi_config_t *parent, const mesh_addr_t *pa * @return * - ESP_OK * - ESP_ERR_WIFI_NOT_INIT - * - ESP_ERR_WIFI_ARG + * - ESP_ERR_INVALID_ARG * - ESP_ERR_WIFI_FAIL */ esp_err_t esp_mesh_scan_get_ap_ie_len(int *len); @@ -1417,7 +1424,7 @@ esp_err_t esp_mesh_scan_get_ap_ie_len(int *len); * @return * - ESP_OK * - ESP_ERR_WIFI_NOT_INIT - * - ESP_ERR_WIFI_ARG + * - ESP_ERR_INVALID_ARG * - ESP_ERR_WIFI_FAIL */ esp_err_t esp_mesh_scan_get_ap_record(wifi_ap_record_t *ap_record, void *buffer); @@ -1506,7 +1513,7 @@ esp_err_t esp_mesh_switch_channel(const uint8_t *new_bssid, int csa_newchan, int * @return * - ESP_OK * - ESP_ERR_WIFI_NOT_INIT - * - ESP_ERR_WIFI_ARG + * - ESP_ERR_INVALID_ARG */ esp_err_t esp_mesh_get_router_bssid(uint8_t *router_bssid); diff --git a/components/esp_wifi/include/esp_mesh_internal.h b/components/esp_wifi/include/esp_mesh_internal.h index af602bb548..4c6a998ecc 100644 --- a/components/esp_wifi/include/esp_mesh_internal.h +++ b/components/esp_wifi/include/esp_mesh_internal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -25,6 +25,9 @@ extern "C" { /******************************************************* * Structures *******************************************************/ +/** + * @brief Mesh attempts + */ typedef struct { int scan; /**< minimum scan times before being a root, default:10 */ int vote; /**< max vote times in self-healing, default:1000 */ @@ -33,20 +36,28 @@ typedef struct { int monitor_ie; /**< acceptable times of parent networking IE change before update its own networking IE. default:3 */ } mesh_attempts_t; +/** + * @brief Mesh switch parent + */ typedef struct { - int duration_ms; /* parent weak RSSI monitor duration, if the RSSI continues to be weak during this duration_ms, + int duration_ms; /**< parent weak RSSI monitor duration, if the RSSI continues to be weak during this duration_ms, device will search for a new parent. */ - int cnx_rssi; /* RSSI threshold for keeping a good connection with parent. + int cnx_rssi; /**< RSSI threshold for keeping a good connection with parent. If set a value greater than -120 dBm, a timer will be armed to monitor parent RSSI at a period time of duration_ms. */ - int select_rssi; /* RSSI threshold for parent selection. It should be a value greater than switch_rssi. */ - int switch_rssi; /* Disassociate with current parent and switch to a new parent when the RSSI is greater than this set threshold. */ - int backoff_rssi; /* RSSI threshold for connecting to the root */ + int select_rssi; /**< RSSI threshold for parent selection. It should be a value greater than switch_rssi. */ + int switch_rssi; /**< Disassociate with current parent and switch to a new parent when the RSSI is greater than this set threshold. */ + int backoff_rssi; /**< RSSI threshold for connecting to the root */ } mesh_switch_parent_t; +/** + * @brief Mesh RSSI threshold + */ typedef struct { - int high; - int medium; - int low; + int high; /**< high RSSI threshold, used to determine whether the new parent and the current parent are in the same RSSI range */ + int medium; /**< medium RSSI threshold, used to determine whether the new parent and the current parent are in the same RSSI range */ + int low; /**< low RSSI threshold. If the parent's RSSI is lower than low for a period time of duration_ms, + then the mesh node will post MESH_WEAK_RSSI event. + Also used to determine whether the new parent and the current parent are in the same RSSI range */ } mesh_rssi_threshold_t; /** @@ -54,65 +65,71 @@ typedef struct { */ typedef struct { /**< mesh networking IE head */ - uint8_t eid; /**< element ID */ - uint8_t len; /**< element length */ - uint8_t oui[3]; /**< organization identifier */ - /**< mesh networking IE content */ - uint8_t type; /** ESP defined IE type */ + uint8_t eid; /**< element ID, vendor specific, 221 */ + uint8_t len; /**< element length, the length after this member */ + uint8_t oui[3]; /**< organization identifier, 0x18fe34 */ + uint8_t type; /**< ESP defined IE type, include Assoc IE, SSID IE, Ext Assoc IE, Roots IE, etc. */ uint8_t encrypted : 1; /**< whether mesh networking IE is encrypted */ - uint8_t version : 7; /**< mesh networking IE version */ + uint8_t version : 7; /**< mesh networking IE version, equal to 2 if mesh PS is enabled, equal to 1 otherwise */ /**< content */ - uint8_t mesh_type; /**< mesh device type */ - uint8_t mesh_id[6]; /**< mesh ID */ - uint8_t layer_cap; /**< max layer */ - uint8_t layer; /**< current layer */ - uint8_t assoc_cap; /**< max connections of mesh AP */ - uint8_t assoc; /**< current connections */ - uint8_t leaf_cap; /**< leaf capacity */ - uint8_t leaf_assoc; /**< the number of current connected leaf */ - uint16_t root_cap; /**< root capacity */ - uint16_t self_cap; /**< self capacity */ - uint16_t layer2_cap; /**< layer2 capacity */ - uint16_t scan_ap_num; /**< the number of scanning APs */ - int8_t rssi; /**< RSSI of the parent */ - int8_t router_rssi; /**< RSSI of the router */ - uint8_t flag; /**< flag of networking */ - uint8_t rc_addr[6]; /**< root address */ - int8_t rc_rssi; /**< root RSSI */ - uint8_t vote_addr[6]; /**< voter address */ - int8_t vote_rssi; /**< vote RSSI of the router */ - uint8_t vote_ttl; /**< vote ttl */ - uint16_t votes; /**< votes */ - uint16_t my_votes; /**< my votes */ - uint8_t reason; /**< reason */ - uint8_t child[6]; /**< child address */ - uint8_t toDS; /**< toDS state */ + uint8_t mesh_type; /**< mesh device type, include idle, root, node, etc, refer to mesh_type_t */ + uint8_t mesh_id[6]; /**< mesh ID, only the same mesh id can form a unified mesh network */ + uint8_t layer_cap; /**< layer_cap = max_layer - layer, indicates the number of remaining available layers of the mesh network */ + uint8_t layer; /**< the current layer of this node */ + uint8_t assoc_cap; /**< the maximum connections of this mesh AP */ + uint8_t assoc; /**< current connections of this mesh AP */ + uint8_t leaf_cap; /**< the maximum number of leaves in the mesh network */ + uint8_t leaf_assoc; /**< the number of current connected leaves */ + uint16_t root_cap; /**< the capacity of the root, equal to the total child numbers plus 1, root node updates root_cap and self_cap */ + uint16_t self_cap; /**< the capacity of myself, total child numbers plus 1, all nodes update this member */ + uint16_t layer2_cap; /**< the capacity of layer2 node, total child numbers plus 1, layer2 node updates layer2_cap and self_cap, root sets this to 0 */ + uint16_t scan_ap_num; /**< the number of mesh APs around */ + int8_t rssi; /**< RSSI of the connected parent, default value is -120, root node will not update this */ + int8_t router_rssi; /**< RSSI of the router, default value is -120 */ + uint8_t flag; /**< flag of networking, indicates the status of the network, refer to MESH_ASSOC_FLAG_XXX */ + /**< vote related */ + uint8_t rc_addr[6]; /**< the address of the root candidate, i.e. the voted addesss before connection, root node will update this with self address */ + int8_t rc_rssi; /**< the router RSSI of the root candidate */ + uint8_t vote_addr[6]; /**< the voted address after connection */ + int8_t vote_rssi; /**< the router RSSI of the voted address */ + uint8_t vote_ttl; /**< vote ttl, indicate the voting is from myself or from other nodes */ + uint16_t votes; /**< the number of all voting nodes */ + uint16_t my_votes; /**< the number of nodes that voted for me */ + uint8_t reason; /**< the reason why the voting happens, root initiated or child initiated, refer to mesh_vote_reason_t */ + uint8_t child[6]; /**< child address, not used currently */ + uint8_t toDS; /**< state represents whether the root is able to access external IP network */ } __attribute__((packed)) mesh_assoc_t; +/** + * @brief Mesh chain layer + */ typedef struct { - uint16_t layer_cap; - uint16_t layer; + uint16_t layer_cap; /**< max layer of the network */ + uint16_t layer; /**< current layer of this node */ } mesh_chain_layer_t; +/** + * @brief Mesh chain assoc + */ typedef struct { - mesh_assoc_t tree; - mesh_chain_layer_t chain; + mesh_assoc_t tree; /**< tree top, mesh_assoc IE */ + mesh_chain_layer_t chain; /**< chain top, mesh_assoc IE */ } __attribute__((packed)) mesh_chain_assoc_t; /* mesh max connections */ #define MESH_MAX_CONNECTIONS (10) /** - * @brief Mesh PS duties + * @brief Mesh power save duties */ typedef struct { - uint8_t device; - uint8_t parent; + uint8_t device; /**< device power save duty*/ + uint8_t parent; /**< parent power save duty*/ struct { - bool used; - uint8_t duty; - uint8_t mac[6]; - } child[MESH_MAX_CONNECTIONS]; + bool used; /**< whether the child is joined */ + uint8_t duty; /**< power save duty of the child */ + uint8_t mac[6]; /**< mac address of the child */ + } child[MESH_MAX_CONNECTIONS]; /**< child */ } esp_mesh_ps_duties_t; /******************************************************* @@ -121,19 +138,19 @@ typedef struct { /** * @brief Set mesh softAP beacon interval * - * @param[in] interval beacon interval (msecs) (100 msecs ~ 60000 msecs) + * @param[in] interval_ms beacon interval (msecs) (100 msecs ~ 60000 msecs) * * @return * - ESP_OK * - ESP_FAIL - * - ESP_ERR_WIFI_ARG + * - ESP_ERR_INVALID_ARG */ esp_err_t esp_mesh_set_beacon_interval(int interval_ms); /** * @brief Get mesh softAP beacon interval * - * @param[out] interval beacon interval (msecs) + * @param[out] interval_ms beacon interval (msecs) * * @return * - ESP_OK @@ -185,7 +202,7 @@ esp_err_t esp_mesh_set_switch_parent_paras(mesh_switch_parent_t *paras); esp_err_t esp_mesh_get_switch_parent_paras(mesh_switch_parent_t *paras); /** - * @brief Set RSSI threshold + * @brief Set RSSI threshold of current parent * - The default high RSSI threshold value is -78 dBm. * - The default medium RSSI threshold value is -82 dBm. * - The default low RSSI threshold value is -85 dBm. @@ -199,7 +216,7 @@ esp_err_t esp_mesh_get_switch_parent_paras(mesh_switch_parent_t *paras); esp_err_t esp_mesh_set_rssi_threshold(const mesh_rssi_threshold_t *threshold); /** - * @brief Get RSSI threshold + * @brief Get RSSI threshold of current parent * * @param[out] threshold RSSI threshold * @@ -242,7 +259,7 @@ esp_err_t esp_mesh_print_rxQ_waiting(void); /** * @brief Set passive scan time * - * @param[in] interval_ms passive scan time (msecs) + * @param[in] time_ms passive scan time (msecs) * * @return * - ESP_OK @@ -283,7 +300,9 @@ esp_err_t esp_mesh_set_announce_interval(int short_ms, int long_ms); esp_err_t esp_mesh_get_announce_interval(int *short_ms, int *long_ms); /** - * @brief Get the running duties of device, parent and children + * @brief Get the running duties of device, parent and children + * + * @param[out] ps_duties ps duties * * @return * - ESP_OK diff --git a/components/esp_wifi/include/esp_now.h b/components/esp_wifi/include/esp_now.h index 2a39856601..3e8e8e299d 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; /** @@ -264,7 +265,9 @@ esp_err_t esp_now_mod_peer(const esp_now_peer_info_t *peer); * - ESP_OK: succeed * - others: failed */ -esp_err_t esp_wifi_config_espnow_rate(wifi_interface_t ifx, wifi_phy_rate_t rate); +esp_err_t esp_wifi_config_espnow_rate(wifi_interface_t ifx, wifi_phy_rate_t rate) + __attribute__((deprecated("This API can be only used when rate is non-HE rate, \ + please use esp_now_set_peer_rate_config if you want full support of the rate."))); /** * @brief Set ESPNOW rate config for each peer diff --git a/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h b/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h index f807cd60aa..4aa855fbda 100644 --- a/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h +++ b/components/esp_wifi/include/esp_private/esp_wifi_he_types_private.h @@ -235,10 +235,10 @@ typedef struct { int64_t tx_start_time; int64_t tx_seqno_time; int64_t tx_muedca_time; - int64_t tx_max_muedca_time; - int64_t tx_min_muedca_time; - int64_t tx_tot_muedca_time; - int64_t muedca_times; + uint32_t tx_max_muedca_time; + uint32_t tx_min_muedca_time; + uint32_t tx_tot_muedca_time; + uint32_t muedca_times; uint32_t tx_muedca_enable; /* count TX times within mu-timer working */ uint32_t collision; uint32_t timeout; diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index 2ed887e9b4..f4338c2d3a 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -73,7 +73,7 @@ typedef enum { #define WIFI_LOG_SUBMODULE_INIT (1) /*logs related to initialization*/ #define WIFI_LOG_SUBMODULE_IOCTL (1<<1) /*logs related to API calling*/ #define WIFI_LOG_SUBMODULE_CONN (1<<2) /*logs related to connecting*/ -#define WIFI_LOG_SUBMODULE_SCAN (1<<3) /*logs related to scaning*/ +#define WIFI_LOG_SUBMODULE_SCAN (1<<3) /*logs related to scanning*/ /** @@ -133,7 +133,7 @@ void esp_wifi_internal_free_rx_buffer(void* buffer); * @return * - ESP_OK : Successfully transmit the buffer to wifi driver * - ESP_ERR_NO_MEM: out of memory - * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: invalid argument * - ESP_ERR_WIFI_IF : WiFi interface is invalid * - ESP_ERR_WIFI_CONN : WiFi interface is not created, e.g. send the data to STA while WiFi mode is AP mode * - ESP_ERR_WIFI_NOT_STARTED : WiFi is not started @@ -165,14 +165,14 @@ typedef void (*wifi_netstack_buf_free_cb_t)(void *netstack_buf); * supports reference counter. * * @param wifi_if : wifi interface id - * @param buffer : the buffer to be tansmit + * @param buffer : the buffer to be transmit * @param len : the length of buffer - * @param netstack_buf : the netstack buffer related to bufffer + * @param netstack_buf : the netstack buffer related to buffer * * @return * - ESP_OK : Successfully transmit the buffer to wifi driver * - ESP_ERR_NO_MEM: out of memory - * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: invalid argument * - ESP_ERR_WIFI_IF : WiFi interface is invalid * - ESP_ERR_WIFI_CONN : WiFi interface is not created, e.g. send the data to STA while WiFi mode is AP mode * - ESP_ERR_WIFI_NOT_STARTED : WiFi is not started @@ -440,7 +440,7 @@ esp_err_t esp_wifi_internal_set_log_level(wifi_log_level_t level); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init - * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: invalid argument */ esp_err_t esp_wifi_internal_set_log_mod(wifi_log_module_t module, uint32_t submodule, bool enable); @@ -540,6 +540,18 @@ void esp_wifi_power_domain_on(void); */ void esp_wifi_power_domain_off(void); + +#if (CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_MODEM_RETENTION_BY_REGDMA) +/** + * @brief Get wifi mac sleep retention hardware context configuration and size + * + * @param config_size: the wifi mac hardware context configuration size + * + * @return A pointer that point to wifi mac sleep renteiton hardware context configuration table + */ +void * esp_wifi_internal_mac_retention_context_get(int *config_size); +#endif + #if CONFIG_MAC_BB_PD /** * @brief Enable or disable powering down MAC and baseband when Wi-Fi is sleeping. @@ -563,12 +575,12 @@ void pm_mac_wakeup(void); #endif /** - * @breif TxDone callback function type. Should be registered using esp_wifi_set_tx_done_cb() + * @brief TxDone callback function type. Should be registered using esp_wifi_set_tx_done_cb() * * @param ifidx The interface id that the tx callback has been triggered from * @param data Pointer to the data transmitted * @param data_len Length of the data transmitted - * @param txStatus True:if the data was transmitted sucessfully False: if data transmission failed + * @param txStatus True:if the data was transmitted successfully False: if data transmission failed */ typedef void (* wifi_tx_done_cb_t)(uint8_t ifidx, uint8_t *data, uint16_t *data_len, bool txStatus); @@ -607,13 +619,13 @@ esp_err_t esp_wifi_internal_set_spp_amsdu(wifi_interface_t ifidx, bool spp_cap, void esp_wifi_internal_update_light_sleep_default_params(int min_freq_mhz, int max_freq_mhz); /** - * @brief Set the delay time for wifi to enter the sleep state when light sleep + * @brief Set the min active time for wifi to enter the sleep state when light sleep * - * @param return_to_sleep_delay: minimum timeout time for waiting to receive + * @param min_active_time: minimum timeout time for waiting to receive * data, when no data is received during the timeout period, * the wifi enters the sleep process. */ -void esp_wifi_set_sleep_delay_time(uint32_t return_to_sleep_delay); +void esp_wifi_set_sleep_min_active_time(uint32_t min_active_time); /** * @brief Set wifi keep alive time @@ -622,6 +634,17 @@ void esp_wifi_set_sleep_delay_time(uint32_t return_to_sleep_delay); */ void esp_wifi_set_keep_alive_time(uint32_t keep_alive_time); +/** + * @brief Set the min broadcast data wait time for wifi to enter the sleep state + * + * @attention Default sleep wait broadcast data time is 15000, Uint µs. + * + * @param time: When the station knows through the beacon that the AP + * will send broadcast packet, it will wait for a minimum of + * wait_broadcast_data_time before entering the sleep process. + */ +void esp_wifi_set_sleep_wait_broadcast_data_time(uint32_t time); + /** * @brief Configure wifi beacon montior default parameters * @@ -630,15 +653,23 @@ void esp_wifi_set_keep_alive_time(uint32_t keep_alive_time); void esp_wifi_beacon_monitor_configure(wifi_beacon_monitor_config_t *config); /** - * @brief Require WiFi to enable or disable Advanced DTIM sleep function + * @brief Set modem state mode to require WiFi to enable or disable Advanced DTIM sleep function * - * @param light_sleep_enable: true for light sleep mode is enabled, false for light sleep mode is disabled. - * @param modem_state_enable: true for require WiFi to enable Advanced DTIM sleep function, + * @param require_modem_state: true for require WiFi to enable Advanced DTIM sleep function, * false for require WiFi to disable Advanced DTIM sleep function. * @return * - ESP_OK: succeed */ -void esp_wifi_internal_mac_sleep_configure(bool light_sleep_enable, bool modem_state_enable); +void esp_wifi_internal_modem_state_configure(bool require_modem_state); + +/** + * @brief Set light sleep mode to require WiFi to enable or disable Advanced DTIM sleep function + * + * @param light_sleep_enable: true for light sleep mode is enabled, false for light sleep mode is disabled. + * @return + * - ESP_OK: succeed + */ +void esp_wifi_internal_light_sleep_configure(bool light_sleep_enable); /** * @brief Start Publishing a service in the NAN cluster diff --git a/components/esp_wifi/include/esp_private/wifi_os_adapter.h b/components/esp_wifi/include/esp_private/wifi_os_adapter.h index 4b55b9c6b4..0016eb2ba0 100644 --- a/components/esp_wifi/include/esp_private/wifi_os_adapter.h +++ b/components/esp_wifi/include/esp_private/wifi_os_adapter.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,6 +8,10 @@ #define ESP_WIFI_OS_ADAPTER_H_ #include +#include +#include +#include +#include "sdkconfig.h" #ifdef __cplusplus extern "C" { @@ -148,9 +152,9 @@ typedef struct { #if CONFIG_IDF_TARGET_ESP32C6 void (* _regdma_link_set_write_wait_content)(void *, uint32_t, uint32_t); void * (* _sleep_retention_find_link_by_id)(int); - int (* _sleep_retention_entries_create)(const void *, int, int, int); - void (* _sleep_retention_entries_destroy)(int); #endif + int (*_coex_schm_flexible_period_set)(uint8_t); + uint8_t (*_coex_schm_flexible_period_get)(void); int32_t _magic; } wifi_osi_funcs_t; diff --git a/components/esp_wifi/include/esp_smartconfig.h b/components/esp_wifi/include/esp_smartconfig.h index 9f7a80a4a8..ac995d4b7e 100644 --- a/components/esp_wifi/include/esp_smartconfig.h +++ b/components/esp_wifi/include/esp_smartconfig.h @@ -56,7 +56,7 @@ typedef struct { .enable_log = false, \ .esp_touch_v2_enable_crypt = false,\ .esp_touch_v2_key = NULL \ -}; +} /** * @brief Get the version of SmartConfig. diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 97d8a8ec56..d517c380e8 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -88,6 +88,7 @@ extern "C" { #define ESP_ERR_WIFI_TWT_SETUP_TIMEOUT (ESP_ERR_WIFI_BASE + 24) /*!< Timeout of receiving twt setup response frame, timeout times can be set during twt setup */ #define ESP_ERR_WIFI_TWT_SETUP_TXFAIL (ESP_ERR_WIFI_BASE + 25) /*!< TWT setup frame tx failed */ #define ESP_ERR_WIFI_TWT_SETUP_REJECT (ESP_ERR_WIFI_BASE + 26) /*!< The twt setup request was rejected by the AP */ +#define ESP_ERR_WIFI_DISCARD (ESP_ERR_WIFI_BASE + 27) /*!< Discard frame */ /** * @brief WiFi stack configuration parameters passed to esp_wifi_init call. @@ -100,6 +101,8 @@ typedef struct { int tx_buf_type; /**< WiFi TX buffer type */ int static_tx_buf_num; /**< WiFi static TX buffer number */ int dynamic_tx_buf_num; /**< WiFi dynamic TX buffer number */ + int rx_mgmt_buf_type; /**< WiFi RX MGMT buffer type */ + int rx_mgmt_buf_num; /**< WiFi RX MGMT buffer number */ int cache_tx_buf_num; /**< WiFi TX cache buffer number */ int csi_enable; /**< WiFi channel state information enable flag */ int ampdu_rx_enable; /**< WiFi AMPDU RX feature enable flag */ @@ -135,6 +138,12 @@ typedef struct { #define WIFI_DYNAMIC_TX_BUFFER_NUM 0 #endif +#ifdef CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF +#define WIFI_RX_MGMT_BUF_NUM_DEF CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF +#else +#define WIFI_RX_MGMT_BUF_NUM_DEF 0 +#endif + #if CONFIG_ESP_WIFI_CSI_ENABLED #define WIFI_CSI_ENABLED 1 #else @@ -172,7 +181,6 @@ typedef struct { #endif extern const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs; -extern uint64_t g_wifi_feature_caps; #define WIFI_INIT_CONFIG_MAGIC 0x1F2F3F4F @@ -206,10 +214,72 @@ extern uint64_t g_wifi_feature_caps; #define WIFI_STA_DISCONNECTED_PM_ENABLED false #endif +#if CONFIG_ESP_WIFI_ENABLE_WPA3_SAE +#define WIFI_ENABLE_WPA3_SAE (1<<0) +#else +#define WIFI_ENABLE_WPA3_SAE 0 +#endif + +#if CONFIG_SPIRAM +#define WIFI_ENABLE_SPIRAM (1<<1) +#else +#define WIFI_ENABLE_SPIRAM 0 +#endif + +#if CONFIG_ESP_WIFI_FTM_INITIATOR_SUPPORT +#define WIFI_FTM_INITIATOR (1<<2) +#else +#define WIFI_FTM_INITIATOR 0 +#endif + +#if CONFIG_ESP_WIFI_FTM_RESPONDER_SUPPORT +#define WIFI_FTM_RESPONDER (1<<3) +#else +#define WIFI_FTM_RESPONDER 0 +#endif + +#if CONFIG_ESP_WIFI_GCMP_SUPPORT +#define WIFI_ENABLE_GCMP (1<<4) +#else +#define WIFI_ENABLE_GCMP 0 +#endif + +#if CONFIG_ESP_WIFI_GMAC_SUPPORT +#define WIFI_ENABLE_GMAC (1<<5) +#else +#define WIFI_ENABLE_GMAC 0 +#endif + +#if CONFIG_ESP_WIFI_11R_SUPPORT +#define WIFI_ENABLE_11R (1<<6) +#else +#define WIFI_ENABLE_11R 0 +#endif + +#if CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT +#define WIFI_ENABLE_ENTERPRISE (1<<7) +#else +#define WIFI_ENABLE_ENTERPRISE 0 +#endif + #define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0) #define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1) #define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2) #define CONFIG_FEATURE_FTM_RESPONDER_BIT (1<<3) +#define CONFIG_FEATURE_GCMP_BIT (1<<4) +#define CONFIG_FEATURE_GMAC_BIT (1<<5) +#define CONFIG_FEATURE_11R_BIT (1<<6) +#define CONFIG_FEATURE_WIFI_ENT_BIT (1<<7) + +/* Set additional WiFi features and capabilities */ +#define WIFI_FEATURE_CAPS (WIFI_ENABLE_WPA3_SAE | \ + WIFI_ENABLE_SPIRAM | \ + WIFI_FTM_INITIATOR | \ + WIFI_FTM_RESPONDER | \ + WIFI_ENABLE_GCMP | \ + WIFI_ENABLE_GMAC | \ + WIFI_ENABLE_11R | \ + WIFI_ENABLE_ENTERPRISE) #define WIFI_INIT_CONFIG_DEFAULT() { \ .osi_funcs = &g_wifi_osi_funcs, \ @@ -219,6 +289,8 @@ extern uint64_t g_wifi_feature_caps; .tx_buf_type = CONFIG_ESP_WIFI_TX_BUFFER_TYPE,\ .static_tx_buf_num = WIFI_STATIC_TX_BUFFER_NUM,\ .dynamic_tx_buf_num = WIFI_DYNAMIC_TX_BUFFER_NUM,\ + .rx_mgmt_buf_type = CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF,\ + .rx_mgmt_buf_num = WIFI_RX_MGMT_BUF_NUM_DEF,\ .cache_tx_buf_num = WIFI_CACHE_TX_BUFFER_NUM,\ .csi_enable = WIFI_CSI_ENABLED,\ .ampdu_rx_enable = WIFI_AMPDU_RX_ENABLED,\ @@ -230,7 +302,7 @@ extern uint64_t g_wifi_feature_caps; .wifi_task_core_id = WIFI_TASK_CORE_ID,\ .beacon_max_len = WIFI_SOFTAP_BEACON_MAX_LEN, \ .mgmt_sbuf_num = WIFI_MGMT_SBUF_NUM, \ - .feature_caps = g_wifi_feature_caps, \ + .feature_caps = WIFI_FEATURE_CAPS, \ .sta_disconnected_pm = WIFI_STA_DISCONNECTED_PM_ENABLED, \ .espnow_max_encrypt_num = 2, \ .magic = WIFI_INIT_CONFIG_MAGIC\ @@ -307,7 +379,7 @@ esp_err_t esp_wifi_get_mode(wifi_mode_t *mode); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init - * - ESP_ERR_INVALID_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: It doesn't normally happen, the function called inside the API was passed invalid argument, user should check if the wifi related config is correct * - ESP_ERR_NO_MEM: out of memory * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong * - ESP_FAIL: other WiFi internal errors @@ -350,14 +422,15 @@ esp_err_t esp_wifi_restore(void); * @attention 3. The scanning triggered by esp_wifi_scan_start() will not be effective until connection between device and the AP is established. * If device is scanning and connecting at the same time, it will abort scanning and return a warning message and error * number ESP_ERR_WIFI_STATE. - * If you want to do reconnection after device received disconnect event, remember to add the maximum retry time, otherwise the called - * scan will not work. This is especially true when the AP doesn't exist, and you still try reconnection after device received disconnect - * event with the reason code WIFI_REASON_NO_AP_FOUND. + * @attention 4. This API attempts to connect to an Access Point (AP) only once. To enable reconnection in case of a connection failure, please use + * the 'failure_retry_cnt' feature in the 'wifi_sta_config_t'. Users are suggested to implement reconnection logic in their application + * for scenarios where the specified AP does not exist, or reconnection is desired after the device has received a disconnect event. * * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_WIFI_MODE: WiFi mode error * - ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block wrong * - ESP_ERR_WIFI_SSID: SSID of AP which station connects is invalid */ @@ -401,13 +474,16 @@ esp_err_t esp_wifi_deauth_sta(uint16_t aid); /** * @brief Scan all available APs. * - * @attention If this API is called, the found APs are stored in WiFi driver dynamic allocated memory and the - * will be freed in esp_wifi_scan_get_ap_records, so generally, call esp_wifi_scan_get_ap_records to cause - * the memory to be freed once the scan is done + * @attention If this API is called, the found APs are stored in WiFi driver dynamic allocated memory. And then + * can be freed in esp_wifi_scan_get_ap_records(), esp_wifi_scan_get_ap_record() or esp_wifi_clear_ap_list(), + * so call any one to free the memory once the scan is done. * @attention The values of maximum active scan time and passive scan time per channel are limited to 1500 milliseconds. * Values above 1500ms may cause station to disconnect from AP and are not recommended. * - * @param config configuration of scanning + * @param config configuration settings for scanning, if set to NULL default settings will be used + * of which default values are show_hidden:false, scan_type:active, scan_time.active.min:0, + * scan_time.active.max:120 miliseconds, scan_time.passive:360 miliseconds + * * @param block if block is true, this API will block the caller until the scan is done, otherwise * it will return immediately * @@ -434,7 +510,7 @@ esp_err_t esp_wifi_scan_stop(void); /** * @brief Get number of APs found in last scan * - * @param[out] number store number of APIs found in last scan + * @param[out] number store number of APs found in last scan * * @attention This API can only be called when the scan is completed, otherwise it may get wrong value. * @@ -447,7 +523,9 @@ esp_err_t esp_wifi_scan_stop(void); esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number); /** - * @brief Get AP list found in last scan + * @brief Get AP list found in last scan. + * + * @attention This API will free all memory occupied by scanned AP list. * * @param[inout] number As input param, it stores max AP number ap_records can hold. * As output param, it receives the actual AP number this API returns. @@ -462,18 +540,37 @@ esp_err_t esp_wifi_scan_get_ap_num(uint16_t *number); */ esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_records); +/** + * @brief Get one AP record from the scanned AP list. + * + * @attention Different from esp_wifi_scan_get_ap_records(), this API only gets one AP record + * from the scanned AP list each time. This API will free the memory of one AP record, + * if the user doesn't get all records in the scannned AP list, then needs to call esp_wifi_clear_ap_list() + * to free the remaining memory. + * + * @param[out] ap_record pointer to one AP record + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + * - ESP_ERR_INVALID_ARG: invalid argument + * - ESP_FAIL: scan APs is NULL, means all AP records fetched or no AP found + */ +esp_err_t esp_wifi_scan_get_ap_record(wifi_ap_record_t *ap_record); /** * @brief Clear AP list found in last scan * - * @attention When the obtained ap list fails,bss info must be cleared,otherwise it may cause memory leakage. + * @attention This API will free all memory occupied by scanned AP list. + * When the obtained AP list fails, AP records must be cleared,otherwise it may cause memory leakage. * * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start * - ESP_ERR_WIFI_MODE: WiFi mode is wrong - * - ESP_ERR_INVALID_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: It doesn't normally happen, the function called inside the API was passed invalid argument, user should check if the wifi related config is correct */ esp_err_t esp_wifi_clear_ap_list(void); @@ -792,7 +889,7 @@ esp_err_t esp_wifi_set_promiscuous_ctrl_filter(const wifi_promiscuous_filter_t * * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init - * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: invalid argument */ esp_err_t esp_wifi_get_promiscuous_ctrl_filter(wifi_promiscuous_filter_t *filter); @@ -816,7 +913,7 @@ esp_err_t esp_wifi_get_promiscuous_ctrl_filter(wifi_promiscuous_filter_t *filter * - ESP_ERR_WIFI_MODE: invalid mode * - ESP_ERR_WIFI_PASSWORD: invalid password * - ESP_ERR_WIFI_NVS: WiFi internal NVS error - * - others: refer to the erro code in esp_err.h + * - others: refer to the error code in esp_err.h */ esp_err_t esp_wifi_set_config(wifi_interface_t interface, wifi_config_t *conf); @@ -939,7 +1036,7 @@ esp_err_t esp_wifi_set_vendor_ie_cb(esp_vendor_ie_cb_t cb, void *ctx); * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start - * - ESP_ERR_WIFI_ARG: invalid argument, e.g. parameter is out of range + * - ESP_ERR_INVALID_ARG: invalid argument, e.g. parameter is out of range */ esp_err_t esp_wifi_set_max_tx_power(int8_t power); @@ -952,7 +1049,7 @@ esp_err_t esp_wifi_set_max_tx_power(int8_t power); * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start - * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: invalid argument */ esp_err_t esp_wifi_get_max_tx_power(int8_t *power); @@ -981,7 +1078,7 @@ esp_err_t esp_wifi_set_event_mask(uint32_t mask); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init - * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: invalid argument */ esp_err_t esp_wifi_get_event_mask(uint32_t *mask); @@ -1001,7 +1098,7 @@ esp_err_t esp_wifi_get_event_mask(uint32_t *mask); * the system sequence number. * Generally, if esp_wifi_80211_tx is called before the Wi-Fi connection has been set up, both * en_sys_seq==true and en_sys_seq==false are fine. However, if the API is called after the Wi-Fi - * connection has been set up, en_sys_seq must be true, otherwise ESP_ERR_WIFI_ARG is returned. + * connection has been set up, en_sys_seq must be true, otherwise ESP_ERR_INVALID_ARG is returned. * * @return * - ESP_OK: success @@ -1073,7 +1170,7 @@ esp_err_t esp_wifi_set_csi(bool en); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init - * - ESP_ERR_WIFI_ARG: Invalid argument, e.g. parameter is NULL, invalid GPIO number etc + * - ESP_ERR_INVALID_ARG: Invalid argument, e.g. parameter is NULL, invalid GPIO number etc */ esp_err_t esp_wifi_set_ant_gpio(const wifi_ant_gpio_config_t *config); @@ -1085,7 +1182,7 @@ esp_err_t esp_wifi_set_ant_gpio(const wifi_ant_gpio_config_t *config); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init - * - ESP_ERR_WIFI_ARG: invalid argument, e.g. parameter is NULL + * - ESP_ERR_INVALID_ARG: invalid argument, e.g. parameter is NULL */ esp_err_t esp_wifi_get_ant_gpio(wifi_ant_gpio_config_t *config); @@ -1098,7 +1195,7 @@ esp_err_t esp_wifi_get_ant_gpio(wifi_ant_gpio_config_t *config); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init - * - ESP_ERR_WIFI_ARG: Invalid argument, e.g. parameter is NULL, invalid antenna mode or invalid GPIO number + * - ESP_ERR_INVALID_ARG: Invalid argument, e.g. parameter is NULL, invalid antenna mode or invalid GPIO number */ esp_err_t esp_wifi_set_ant(const wifi_ant_config_t *config); @@ -1110,7 +1207,7 @@ esp_err_t esp_wifi_set_ant(const wifi_ant_config_t *config); * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init - * - ESP_ERR_WIFI_ARG: invalid argument, e.g. parameter is NULL + * - ESP_ERR_INVALID_ARG: invalid argument, e.g. parameter is NULL */ esp_err_t esp_wifi_get_ant(wifi_ant_config_t *config); @@ -1143,7 +1240,7 @@ int64_t esp_wifi_get_tsf_time(wifi_interface_t interface); * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start - * - ESP_ERR_WIFI_ARG: invalid argument, For Station, if sec is less than 3. For SoftAP, if sec is less than 10. + * - ESP_ERR_INVALID_ARG: invalid argument, For Station, if sec is less than 3. For SoftAP, if sec is less than 10. */ esp_err_t esp_wifi_set_inactive_time(wifi_interface_t ifx, uint16_t sec); @@ -1157,7 +1254,7 @@ esp_err_t esp_wifi_set_inactive_time(wifi_interface_t ifx, uint16_t sec); * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start - * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: invalid argument */ esp_err_t esp_wifi_get_inactive_time(wifi_interface_t ifx, uint16_t *sec); @@ -1173,16 +1270,18 @@ esp_err_t esp_wifi_get_inactive_time(wifi_interface_t ifx, uint16_t *sec); esp_err_t esp_wifi_statis_dump(uint32_t modules); /** - * @brief Set RSSI threshold below which APP will get an event + * @brief Set RSSI threshold, if average rssi gets lower than threshold, WiFi task will post event WIFI_EVENT_STA_BSS_RSSI_LOW. * - * @attention This API needs to be called every time after WIFI_EVENT_STA_BSS_RSSI_LOW event is received. + * @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 * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init - * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_INVALID_ARG: invalid argument */ esp_err_t esp_wifi_set_rssi_threshold(int32_t rssi); @@ -1227,6 +1326,26 @@ esp_err_t esp_wifi_ftm_end_session(void); */ esp_err_t esp_wifi_ftm_resp_set_offset(int16_t offset_cm); +/** + * @brief Get FTM measurements report copied into a user provided buffer. + * + * @attention 1. To get the FTM report, user first needs to allocate a buffer of size + * (sizeof(wifi_ftm_report_entry_t) * num_entries) where the API will fill up to num_entries + * valid FTM measurements in the buffer. Total number of entries can be found in the event + * WIFI_EVENT_FTM_REPORT as ftm_report_num_entries + * @attention 2. The internal FTM report is freed upon use of this API which means the API can only be used + * once afer every FTM session initiated + * @attention 3. Passing the buffer as NULL merely frees the FTM report + * + * @param report Pointer to the buffer for receiving the FTM report + * @param num_entries Number of FTM report entries to be filled in the report + * + * @return + * - ESP_OK: succeed + * - others: failed + */ +esp_err_t esp_wifi_ftm_get_report(wifi_ftm_report_entry_t *report, uint8_t num_entries); + /** * @brief Enable or disable 11b rate of specified interface * @@ -1257,6 +1376,32 @@ esp_err_t esp_wifi_config_11b_rate(wifi_interface_t ifx, bool disable); */ esp_err_t esp_wifi_connectionless_module_set_wake_interval(uint16_t wake_interval); +/** + * @brief Request extra reference of Wi-Fi radio. + * Wi-Fi keep active state(RF opened) to be able to receive packets. + * + * @attention Please pair the use of `esp_wifi_force_wakeup_acquire` with `esp_wifi_force_wakeup_release`. + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + */ +esp_err_t esp_wifi_force_wakeup_acquire(void); + +/** + * @brief Release extra reference of Wi-Fi radio. + * Wi-Fi go to sleep state(RF closed) if no more use of radio. + * + * @attention Please pair the use of `esp_wifi_force_wakeup_acquire` with `esp_wifi_force_wakeup_release`. + * + * @return + * - ESP_OK: succeed + * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init + * - ESP_ERR_WIFI_NOT_STARTED: WiFi is not started by esp_wifi_start + */ +esp_err_t esp_wifi_force_wakeup_release(void); + /** * @brief configure country * @@ -1347,8 +1492,6 @@ esp_err_t esp_wifi_sta_get_aid(uint16_t *aid); * * @param[out] phymode store the negotiated phymode. * - * @attention Operation phy mode, BIT[5]: indicate whether LR enabled, BIT[0-4]: wifi_phy_mode_t - * * @return * - ESP_OK: succeed */ @@ -1368,9 +1511,10 @@ esp_err_t esp_wifi_sta_get_negotiated_phymode(wifi_phy_mode_t *phymode); esp_err_t esp_wifi_set_dynamic_cs(bool enabled); /** - * @brief Get the rssi info after station connected to AP + * @brief Get the rssi information of AP to which the device is associated with * - * @attention This API should be called after station connected to AP. + * @attention 1. This API should be called after station connected to AP. + * @attention 2. Use this API only in WIFI_MODE_STA or WIFI_MODE_APSTA mode. * * @param rssi store the rssi info received from last beacon. * @@ -1381,6 +1525,21 @@ esp_err_t esp_wifi_set_dynamic_cs(bool enabled); */ esp_err_t esp_wifi_sta_get_rssi(int *rssi); +#if CONFIG_ESP_COEX_POWER_MANAGEMENT +/** + * @brief Enable Wi-Fi coexistence power management + * + * @attention This API should be called after esp_wifi_init(). + * + * @param enabled Wi-Fi coexistence power management is enabled or not. + * + * @return + * - ESP_OK: succeed + * - others: failed + */ +esp_err_t esp_wifi_coex_pwr_configure(bool enabled); +#endif + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/include/esp_wifi_ap_get_sta_list.h b/components/esp_wifi/include/esp_wifi_ap_get_sta_list.h index c804ad1536..7a4d167b64 100644 --- a/components/esp_wifi/include/esp_wifi_ap_get_sta_list.h +++ b/components/esp_wifi/include/esp_wifi_ap_get_sta_list.h @@ -29,7 +29,7 @@ typedef struct { * @warning This API works only for the default Wi-Fi AP interface, i.e. esp-netif with key="WIFI_AP_DEF" * * @param[in] wifi_sta_list Wi-Fi station info list, returned from esp_wifi_ap_get_sta_list() - * @param[out] netif_sta_list IP layer station info list, corresponding to MAC addresses provided in wifi_sta_list + * @param[out] wifi_sta_ip_mac_list IP layer station info list, corresponding to MAC addresses provided in wifi_sta_list * * @return * - ESP_OK @@ -38,10 +38,6 @@ typedef struct { */ esp_err_t esp_wifi_ap_get_sta_list_with_ip(const wifi_sta_list_t *wifi_sta_list, wifi_sta_mac_ip_list_t *wifi_sta_ip_mac_list); -/** - * @} - */ - #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/include/esp_wifi_crypto_types.h b/components/esp_wifi/include/esp_wifi_crypto_types.h index 9eded75a76..6b41cc524a 100644 --- a/components/esp_wifi/include/esp_wifi_crypto_types.h +++ b/components/esp_wifi/include/esp_wifi_crypto_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,9 @@ During normal operation, you don't need to use any of these types or functions in this header. See esp_wifi.h & esp_wifi_types.h instead. */ +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -55,7 +58,7 @@ typedef struct crypto_hash esp_crypto_hash_t; typedef struct crypto_cipher esp_crypto_cipher_t; /** - * @brief The AES callback function when do WPS connect. + * @brief The AES 128 encrypt callback function used by esp_wifi. * * @param key Encryption key. * @param iv Encryption IV for CBC mode (16 bytes). @@ -65,7 +68,7 @@ typedef struct crypto_cipher esp_crypto_cipher_t; typedef int (*esp_aes_128_encrypt_t)(const unsigned char *key, const unsigned char *iv, unsigned char *data, int data_len); /** - * @brief The AES callback function when do WPS connect. + * @brief The AES 128 decrypt callback function used by esp_wifi. * * @param key Decryption key. * @param iv Decryption IV for CBC mode (16 bytes). @@ -76,7 +79,7 @@ typedef int (*esp_aes_128_encrypt_t)(const unsigned char *key, const unsigned ch typedef int (*esp_aes_128_decrypt_t)(const unsigned char *key, const unsigned char *iv, unsigned char *data, int data_len); /** - * @brief The AES callback function when do STA connect. + * @brief The AES wrap callback function used by esp_wifi. * * @param kek 16-octet Key encryption key (KEK). * @param n Length of the plaintext key in 64-bit units; @@ -87,7 +90,7 @@ typedef int (*esp_aes_128_decrypt_t)(const unsigned char *key, const unsigned ch typedef int (*esp_aes_wrap_t)(const unsigned char *kek, int n, const unsigned char *plain, unsigned char *cipher); /** - * @brief The AES callback function when do STA connect. + * @brief The AES unwrap callback function used by esp_wifi. * * @param kek 16-octet Key decryption key (KEK). * @param n Length of the plaintext key in 64-bit units; @@ -98,7 +101,7 @@ typedef int (*esp_aes_wrap_t)(const unsigned char *kek, int n, const unsigned ch typedef int (*esp_aes_unwrap_t)(const unsigned char *kek, int n, const unsigned char *cipher, unsigned char *plain); /** - * @brief The SHA256 callback function when do WPS connect. + * @brief The SHA256 callback function used by esp_wifi. * * @param key Key for HMAC operations. * @param key_len Length of the key in bytes. @@ -112,7 +115,7 @@ typedef int (*esp_hmac_sha256_vector_t)(const unsigned char *key, int key_len, i const unsigned char *addr[], const int *len, unsigned char *mac); /** - * @brief The AES callback function when do STA connect. + * @brief The SHA256 PRF callback function used by esp_wifi. * * @param key Key for PRF. * @param key_len Length of the key in bytes. @@ -127,69 +130,69 @@ typedef int (*esp_sha256_prf_t)(const unsigned char *key, int key_len, const cha const unsigned char *data, int data_len, unsigned char *buf, int buf_len); /** - * @brief HMAC-MD5 over data buffer (RFC 2104)' + * @brief HMAC-MD5 callback function over data buffer (RFC 2104)' * - * @key: Key for HMAC operations - * @key_len: Length of the key in bytes - * @data: Pointers to the data area - * @data_len: Length of the data area - * @mac: Buffer for the hash (16 bytes) + * @param key Key for HMAC operations + * @param key_len Length of the key in bytes + * @param data Pointers to the data area + * @param data_len Length of the data area + * @param mac Buffer for the hash (16 bytes) * Returns: 0 on success, -1 on failure */ typedef int (*esp_hmac_md5_t)(const unsigned char *key, unsigned int key_len, const unsigned char *data, unsigned int data_len, unsigned char *mac); /** - * @brief HMAC-MD5 over data vector (RFC 2104) + * @brief HMAC-MD5 callback function over data vector (RFC 2104) * - * @key: Key for HMAC operations - * @key_len: Length of the key in bytes - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash (16 bytes) + * @param key Key for HMAC operations + * @param key_len Length of the key in bytes + * @param num_elem Number of elements in the data vector + * @param addr Pointers to the data areas + * @param len Lengths of the data blocks + * @param mac Buffer for the hash (16 bytes) * Returns: 0 on success, -1 on failure */ typedef int (*esp_hmac_md5_vector_t)(const unsigned char *key, unsigned int key_len, unsigned int num_elem, const unsigned char *addr[], const unsigned int *len, unsigned char *mac); /** - * @brief HMAC-SHA1 over data buffer (RFC 2104) + * @brief HMAC-SHA1 callback function over data buffer (RFC 2104) * - * @key: Key for HMAC operations - * @key_len: Length of the key in bytes - * @data: Pointers to the data area - * @data_len: Length of the data area - * @mac: Buffer for the hash (20 bytes) + * @param key Key for HMAC operations + * @param key_len Length of the key in bytes + * @param data Pointers to the data area + * @param data_len Length of the data area + * @param mac Buffer for the hash (20 bytes) * Returns: 0 on success, -1 of failure */ typedef int (*esp_hmac_sha1_t)(const unsigned char *key, unsigned int key_len, const unsigned char *data, unsigned int data_len, unsigned char *mac); /** - * @brief HMAC-SHA1 over data vector (RFC 2104) + * @brief HMAC-SHA1 callback function over data vector (RFC 2104) * - * @key: Key for HMAC operations - * @key_len: Length of the key in bytes - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash (20 bytes) + * @param key Key for HMAC operations + * @param key_len Length of the key in bytes + * @param num_elem Number of elements in the data vector + * @param addr Pointers to the data areas + * @param len Lengths of the data blocks + * @param mac Buffer for the hash (20 bytes) * Returns: 0 on success, -1 on failure */ typedef int (*esp_hmac_sha1_vector_t)(const unsigned char *key, unsigned int key_len, unsigned int num_elem, const unsigned char *addr[], const unsigned int *len, unsigned char *mac); /** - * @brief SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) + * @brief SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) callback function * - * @key: Key for PRF - * @key_len: Length of the key in bytes - * @label: A unique label for each purpose of the PRF - * @data: Extra data to bind into the key - * @data_len: Length of the data - * @buf: Buffer for the generated pseudo-random key - * @buf_len: Number of bytes of key to generate + * @param key Key for PRF + * @param key_len Length of the key in bytes + * @param label A unique label for each purpose of the PRF + * @param data Extra data to bind into the key + * @param data_len Length of the data + * @param buf Buffer for the generated pseudo-random key + * @param buf_len Number of bytes of key to generate * Returns: 0 on success, -1 of failure * * This function is used to derive new, cryptographically separate keys from a @@ -199,26 +202,26 @@ typedef int (*esp_sha1_prf_t)(const unsigned char *key, unsigned int key_len, co const unsigned char *data, unsigned int data_len, unsigned char *buf, unsigned int buf_len); /** - * @brief SHA-1 hash for data vector + * @brief SHA-1 hash callback function for data vector * - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash + * @param num_elem Number of elements in the data vector + * @param addr Pointers to the data areas + * @param len Lengths of the data blocks + * @param mac Buffer for the hash * Returns: 0 on success, -1 on failure */ typedef int (*esp_sha1_vector_t)(unsigned int num_elem, const unsigned char *addr[], const unsigned int *len, unsigned char *mac); /** - * @brief SHA1-based key derivation function (PBKDF2) for IEEE 802.11i + * @brief SHA1-based key derivation function (PBKDF2) callback function for IEEE 802.11i * - * @passphrase: ASCII passphrase - * @ssid: SSID - * @ssid_len: SSID length in bytes - * @iterations: Number of iterations to run - * @buf: Buffer for the generated key - * @buflen: Length of the buffer in bytes + * @param passphrase ASCII passphrase + * @param ssid SSID + * @param ssid_len SSID length in bytes + * @param iterations Number of iterations to run + * @param buf Buffer for the generated key + * @param buflen Length of the buffer in bytes * Returns: 0 on success, -1 of failure * * This function is used to derive PSK for WPA-PSK. For this protocol, @@ -229,13 +232,13 @@ typedef int (*esp_pbkdf2_sha1_t)(const char *passphrase, const char *ssid, unsig int iterations, unsigned char *buf, unsigned int buflen); /** - * @brief XOR RC4 stream to given data with skip-stream-start + * @brief XOR RC4 stream callback function to given data with skip-stream-start * - * @key: RC4 key - * @keylen: RC4 key length - * @skip: number of bytes to skip from the beginning of the RC4 stream - * @data: data to be XOR'ed with RC4 stream - * @data_len: buf length + * @param key RC4 key + * @param keylen RC4 key length + * @param skip number of bytes to skip from the beginning of the RC4 stream + * @param data data to be XOR'ed with RC4 stream + * @param data_len buf length * Returns: 0 on success, -1 on failure * * Generate RC4 pseudo random stream for the given key, skip beginning of the @@ -246,89 +249,89 @@ typedef int (*esp_rc4_skip_t)(const unsigned char *key, unsigned int keylen, uns unsigned char *data, unsigned int data_len); /** - * @brief MD5 hash for data vector + * @brief MD5 hash callback function for data vector * - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash + * @param num_elem Number of elements in the data vector + * @param addr Pointers to the data areas + * @param len Lengths of the data blocks + * @param mac Buffer for the hash * Returns: 0 on success, -1 on failure */ typedef int (*esp_md5_vector_t)(unsigned int num_elem, const unsigned char *addr[], const unsigned int *len, unsigned char *mac); /** - * @brief Encrypt one AES block + * @brief Encrypt one AES block callback function * - * @ctx: Context pointer from aes_encrypt_init() - * @plain: Plaintext data to be encrypted (16 bytes) - * @crypt: Buffer for the encrypted data (16 bytes) + * @param ctx Context pointer from aes_encrypt_init() + * @param plain Plaintext data to be encrypted (16 bytes) + * @param crypt Buffer for the encrypted data (16 bytes) */ typedef void (*esp_aes_encrypt_t)(void *ctx, const unsigned char *plain, unsigned char *crypt); /** - * @brief Initialize AES for encryption + * @brief Initialize AES callback function for encryption * - * @key: Encryption key - * @len: Key length in bytes (usually 16, i.e., 128 bits) + * @param key Encryption key + * @param len Key length in bytes (usually 16, i.e., 128 bits) * Returns: Pointer to context data or %NULL on failure */ typedef void * (*esp_aes_encrypt_init_t)(const unsigned char *key, unsigned int len); /** - * @brief Deinitialize AES encryption + * @brief Deinitialize AES encryption callback function * - * @ctx: Context pointer from aes_encrypt_init() + * @param ctx Context pointer from aes_encrypt_init() */ typedef void (*esp_aes_encrypt_deinit_t)(void *ctx); /** - * @brief Decrypt one AES block + * @brief Decrypt one AES block callback function * - * @ctx: Context pointer from aes_encrypt_init() - * @crypt: Encrypted data (16 bytes) - * @plain: Buffer for the decrypted data (16 bytes) + * @param ctx Context pointer from aes_encrypt_init() + * @param crypt Encrypted data (16 bytes) + * @param plain Buffer for the decrypted data (16 bytes) */ typedef void (*esp_aes_decrypt_t)(void *ctx, const unsigned char *crypt, unsigned char *plain); /** - * @brief Initialize AES for decryption + * @brief Initialize AES callback function for decryption * - * @key: Decryption key - * @len: Key length in bytes (usually 16, i.e., 128 bits) + * @param key Decryption key + * @param len Key length in bytes (usually 16, i.e., 128 bits) * Returns: Pointer to context data or %NULL on failure */ typedef void * (*esp_aes_decrypt_init_t)(const unsigned char *key, unsigned int len); /** - * @brief Deinitialize AES decryption + * @brief Deinitialize AES decryption callback function * - * @ctx: Context pointer from aes_encrypt_init() + * @param ctx Context pointer from aes_encrypt_init() */ typedef void (*esp_aes_decrypt_deinit_t)(void *ctx); /** - * @brief One-Key CBC MAC (OMAC1) hash with AES-128 for MIC computation + * @brief One-Key CBC MAC (OMAC1) hash with AES-128 callback function for MIC computation * - * @key: 128-bit key for the hash operation - * @data: Data buffer for which a MIC is computed - * @data_len: Length of data buffer in bytes - * @mic: Buffer for MIC (128 bits, i.e., 16 bytes) + * @param key 128-bit key for the hash operation + * @param data Data buffer for which a MIC is computed + * @param data_len Length of data buffer in bytes + * @param mic Buffer for MIC (128 bits, i.e., 16 bytes) * Returns: 0 on success, -1 on failure */ typedef int (*esp_omac1_aes_128_t)(const uint8_t *key, const uint8_t *data, size_t data_len, uint8_t *mic); /** - * @brief Decrypt data using CCMP (Counter Mode CBC-MAC Protocol OR + * @brief Decrypt data callback function using CCMP (Counter Mode CBC-MAC Protocol OR * Counter Mode Cipher Block Chaining Message Authentication * Code Protocol) which is used in IEEE 802.11i RSN standard. - * @tk: 128-bit Temporal Key for obtained during 4-way handshake - * @hdr: Pointer to IEEE802.11 frame headeri needed for AAD - * @data: Pointer to encrypted data buffer - * @data_len: Encrypted data length in bytes - * @decrypted_len: Length of decrypted data - * @espnow_pkt: Indicates if it's an ESPNOW packet + * @param tk 128-bit Temporal Key for obtained during 4-way handshake + * @param ieee80211_hdr Pointer to IEEE802.11 frame headeri needed for AAD + * @param data Pointer to encrypted data buffer + * @param data_len Encrypted data length in bytes + * @param decrypted_len Length of decrypted data + * @param espnow_pkt Indicates if it's an ESPNOW packet * Returns: Pointer to decrypted data on success, NULL on failure */ typedef uint8_t * (*esp_ccmp_decrypt_t)(const uint8_t *tk, const uint8_t *ieee80211_hdr, @@ -336,90 +339,90 @@ typedef uint8_t * (*esp_ccmp_decrypt_t)(const uint8_t *tk, const uint8_t *ieee80 size_t *decrypted_len, bool espnow_pkt); /** - * @brief Encrypt data using CCMP (Counter Mode CBC-MAC Protocol OR + * @brief Encrypt data callback function using CCMP (Counter Mode CBC-MAC Protocol OR * Counter Mode Cipher Block Chaining Message Authentication * Code Protocol) which is used in IEEE 802.11i RSN standard. - * @tk: 128-bit Temporal Key for obtained during 4-way handshake - * @frame: Pointer to IEEE802.11 frame including header - * @len: Length of the frame including header - * @hdrlen: Length of the header - * @pn: Packet Number counter - * @keyid: Key ID to be mentioned in CCMP Vector - * @encrypted_len: Length of the encrypted frame including header + * @param tk 128-bit Temporal Key for obtained during 4-way handshake + * @param frame Pointer to IEEE802.11 frame including header + * @param len Length of the frame including header + * @param hdrlen Length of the header + * @param pn Packet Number counter + * @param keyid Key ID to be mentioned in CCMP Vector + * @param encrypted_len Length of the encrypted frame including header */ typedef uint8_t * (*esp_ccmp_encrypt_t)(const uint8_t *tk, uint8_t *frame, size_t len, size_t hdrlen, uint8_t *pn, int keyid, size_t *encrypted_len); /** - * @brief One-Key GMAC hash with AES for MIC computation + * @brief One-Key GMAC hash callback function with AES for MIC computation * - * @key: key for the hash operation - * @keylen: key length - * @iv: initialization vector - * @iv_len: initialization vector length - * @aad: aad - * @aad_len: aad length - * @mic: Buffer for MIC (128 bits, i.e., 16 bytes) + * @param key key for the hash operation + * @param keylen key length + * @param iv initialization vector + * @param iv_len initialization vector length + * @param aad aad + * @param aad_len aad length + * @param mic Buffer for MIC (128 bits, i.e., 16 bytes) * Returns: 0 on success, -1 on failure */ typedef int (*esp_aes_gmac_t)(const uint8_t *key, size_t keylen, const uint8_t *iv, size_t iv_len, const uint8_t *aad, size_t aad_len, uint8_t *mic); /** - * @brief SHA256 hash for data vector - * @num_elem: Number of elements in the data vector - * @addr: Pointers to the data areas - * @len: Lengths of the data blocks - * @mac: Buffer for the hash + * @brief SHA256 hash callback function for data vector + * @param num_elem Number of elements in the data vector + * @param addr Pointers to the data areas + * @param len Lengths of the data blocks + * @param buf Buffer for the hash * Returns: 0 on success, -1 on failure */ typedef int (*esp_sha256_vector_t)(size_t num_elem, const uint8_t *addr[], const size_t *len, uint8_t *buf); /** - * @brief CRC32 value in little endian. + * @brief CRC32 value callback function in little endian. * - * @param crc: Initial CRC value (result of last calculation or 0 for the first time) - * @param buf: Data buffer that used to calculate the CRC value - * @param len: Length of the data buffer + * @param crc Initial CRC value (result of last calculation or 0 for the first time) + * @param buf Data buffer that used to calculate the CRC value + * @param len Length of the data buffer * @return CRC32 value */ typedef uint32_t (*esp_crc32_le_t)(uint32_t crc, uint8_t const *buf, uint32_t len); /** - * @brief The crypto callback function structure used when do station security connect. + * @brief The crypto callback function structure used by esp_wifi. * The structure can be set as software crypto or the crypto optimized by device's * hardware. */ typedef struct { - uint32_t size; - uint32_t version; - esp_aes_wrap_t aes_wrap; /**< station connect function used when send EAPOL frame */ - esp_aes_unwrap_t aes_unwrap; /**< station connect function used when decrypt key data */ - esp_hmac_sha256_vector_t hmac_sha256_vector; /**< station connect function used when check MIC */ - esp_sha256_prf_t sha256_prf; /**< station connect function used when check MIC */ - esp_hmac_md5_t hmac_md5; - esp_hmac_md5_vector_t hamc_md5_vector; - esp_hmac_sha1_t hmac_sha1; - esp_hmac_sha1_vector_t hmac_sha1_vector; - esp_sha1_prf_t sha1_prf; - esp_sha1_vector_t sha1_vector; - esp_pbkdf2_sha1_t pbkdf2_sha1; - esp_rc4_skip_t rc4_skip; - esp_md5_vector_t md5_vector; - esp_aes_encrypt_t aes_encrypt; - esp_aes_encrypt_init_t aes_encrypt_init; - esp_aes_encrypt_deinit_t aes_encrypt_deinit; - esp_aes_decrypt_t aes_decrypt; - esp_aes_decrypt_init_t aes_decrypt_init; - esp_aes_decrypt_deinit_t aes_decrypt_deinit; - esp_aes_128_encrypt_t aes_128_encrypt; - esp_aes_128_decrypt_t aes_128_decrypt; - esp_omac1_aes_128_t omac1_aes_128; - esp_ccmp_decrypt_t ccmp_decrypt; - esp_ccmp_encrypt_t ccmp_encrypt; - esp_aes_gmac_t aes_gmac; - esp_sha256_vector_t sha256_vector; - esp_crc32_le_t crc32; + uint32_t size; /**< The crypto callback function structure size */ + uint32_t version; /**< The crypto callback function structure version */ + esp_aes_wrap_t aes_wrap; /**< The AES wrap callback function used by esp_wifi */ + esp_aes_unwrap_t aes_unwrap; /**< The AES unwrap callback function used by esp_wifi */ + esp_hmac_sha256_vector_t hmac_sha256_vector; /**< The SHA256 callback function used by esp_wifi */ + esp_sha256_prf_t sha256_prf; /**< The SHA256 PRF callback function used by esp_wifi */ + esp_hmac_md5_t hmac_md5; /**< HMAC-MD5 callback function over data buffer (RFC 2104) */ + esp_hmac_md5_vector_t hamc_md5_vector; /**< HMAC-MD5 callback function over data vector (RFC 2104) */ + esp_hmac_sha1_t hmac_sha1; /**< HMAC-SHA1 callback function over data buffer (RFC 2104) */ + esp_hmac_sha1_vector_t hmac_sha1_vector; /**< HMAC-SHA1 callback function over data vector (RFC 2104) */ + esp_sha1_prf_t sha1_prf; /**< SHA1-based Pseudo-Random Function (PRF) (IEEE 802.11i, 8.5.1.1) callback function */ + esp_sha1_vector_t sha1_vector; /**< SHA-1 hash callback function for data vector */ + esp_pbkdf2_sha1_t pbkdf2_sha1; /**< SHA1-based key derivation function (PBKDF2) callback function for IEEE 802.11i */ + esp_rc4_skip_t rc4_skip; /**< XOR RC4 stream callback function to given data with skip-stream-start */ + esp_md5_vector_t md5_vector; /**< MD5 hash callback function for data vector */ + esp_aes_encrypt_t aes_encrypt; /**< Encrypt one AES block callback function */ + esp_aes_encrypt_init_t aes_encrypt_init; /**< Initialize AES callback function for encryption */ + esp_aes_encrypt_deinit_t aes_encrypt_deinit; /**< Deinitialize AES encryption callback function */ + esp_aes_decrypt_t aes_decrypt; /**< Decrypt one AES block callback function */ + esp_aes_decrypt_init_t aes_decrypt_init; /**< Initialize AES callback function for decryption */ + esp_aes_decrypt_deinit_t aes_decrypt_deinit; /**< Deinitialize AES decryption callback function */ + esp_aes_128_encrypt_t aes_128_encrypt; /**< The AES 128 encrypt callback function used by esp_wifi */ + esp_aes_128_decrypt_t aes_128_decrypt; /**< The AES 128 decrypt callback function used by esp_wifi */ + esp_omac1_aes_128_t omac1_aes_128; /**< One-Key CBC MAC (OMAC1) hash with AES-128 callback function for MIC computation */ + esp_ccmp_decrypt_t ccmp_decrypt; /**< Decrypt data callback function using CCMP */ + esp_ccmp_encrypt_t ccmp_encrypt; /**< Encrypt data callback function using CCMP */ + esp_aes_gmac_t aes_gmac; /**< One-Key GMAC hash callback function with AES for MIC computation */ + esp_sha256_vector_t sha256_vector; /**< SHA256 hash callback function for data vector */ + esp_crc32_le_t crc32; /**< CRC32 value callback function in little endian */ }wpa_crypto_funcs_t; /** @@ -428,8 +431,8 @@ typedef struct { * hardware. */ typedef struct{ - esp_aes_128_encrypt_t aes_128_encrypt; /**< function used in mesh vendor IE encryption */ - esp_aes_128_decrypt_t aes_128_decrypt; /**< function used in mesh vendor IE decryption */ + esp_aes_128_encrypt_t aes_128_encrypt; /**< Callback function used in mesh vendor IE encryption */ + esp_aes_128_decrypt_t aes_128_decrypt; /**< Callback function used in mesh vendor IE decryption */ } mesh_crypto_funcs_t; #ifdef __cplusplus diff --git a/components/esp_wifi/include/esp_wifi_default.h b/components/esp_wifi/include/esp_wifi_default.h index b1e1c24d91..d30d512e35 100644 --- a/components/esp_wifi/include/esp_wifi_default.h +++ b/components/esp_wifi/include/esp_wifi_default.h @@ -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 */ @@ -8,6 +8,7 @@ #define _ESP_WIFI_DEFAULT_H #include "esp_netif.h" +#include "esp_wifi_types.h" #ifdef __cplusplus extern "C" { @@ -73,7 +74,9 @@ esp_err_t esp_wifi_clear_default_wifi_driver_and_handlers(void *esp_netif); * @brief Creates default WIFI AP. In case of any init error this API aborts. * * @note The API creates esp_netif object with default WiFi access point config, - * attaches the netif to wifi and registers default wifi handlers. + * attaches the netif to wifi and registers wifi handlers to the default event loop. + * This API uses assert() to check for potential errors, so it could abort the program. + * (Note that the default event loop needs to be created prior to calling this API) * * @return pointer to esp-netif instance */ @@ -83,7 +86,9 @@ esp_netif_t* esp_netif_create_default_wifi_ap(void); * @brief Creates default WIFI STA. In case of any init error this API aborts. * * @note The API creates esp_netif object with default WiFi station config, - * attaches the netif to wifi and registers default wifi handlers. + * attaches the netif to wifi and registers wifi handlers to the default event loop. + * This API uses assert() to check for potential errors, so it could abort the program. + * (Note that the default event loop needs to be created prior to calling this API) * * @return pointer to esp-netif instance */ @@ -93,7 +98,8 @@ esp_netif_t* esp_netif_create_default_wifi_sta(void); * @brief Creates default WIFI NAN. In case of any init error this API aborts. * * @note The API creates esp_netif object with default WiFi station config, - * attaches the netif to wifi and registers default wifi handlers. + * attaches the netif to wifi and registers wifi handlers to the default event loop. + * (Note that the default event loop needs to be created prior to calling this API) * * @return pointer to esp-netif instance */ diff --git a/components/esp_wifi/include/esp_wifi_he.h b/components/esp_wifi/include/esp_wifi_he.h index a318d36d2b..67880654ab 100644 --- a/components/esp_wifi/include/esp_wifi_he.h +++ b/components/esp_wifi/include/esp_wifi_he.h @@ -25,7 +25,7 @@ extern "C" { * @attention Support at most 8 TWT agreements, otherwise ESP_ERR_WIFI_TWT_FULL will be returned. * Support sleep time up to (1 << 35) us. * - * @param[in/out] setup_config pointer to itwt setup config structure. + * @param[in,out] setup_config pointer to itwt setup config structure. * * @return * - ESP_OK: succeed diff --git a/components/esp_wifi/include/esp_wifi_he_types.h b/components/esp_wifi/include/esp_wifi_he_types.h index f7c1b9a59e..397cd088f5 100644 --- a/components/esp_wifi/include/esp_wifi_he_types.h +++ b/components/esp_wifi/include/esp_wifi_he_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -54,7 +54,8 @@ typedef struct { 1- acquire the complete HE-LTF2 2- sample evenly among the HE-LTF1 and HE-LTF2 */ uint32_t val_scale_cfg : 2; /**< value 0-3 */ - uint32_t reserved : 20; /**< reserved */ + uint32_t dump_ack_en : 1; /**< enable to dump 802.11 ACK frame, default disabled */ + uint32_t reserved : 19; /**< reserved */ } wifi_csi_acquire_config_t; /** @@ -157,13 +158,12 @@ typedef struct { unsigned : 15; /**< reserved */ unsigned : 15; /**< reserved */ unsigned : 2; /**< reserved */ - unsigned noise_floor : 8; /**< the noise floor of the reception frame */ - signed data_rssi : 8; /**< the RSSI of the DATA field */ - unsigned : 8; /**< reserved */ - unsigned : 8; /**< reserved */ + 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 : 24; /**< reserved */ + unsigned : 8; /**< reserved */ + unsigned : 8; /**< reserved */ + unsigned : 32; /**< reserved */ unsigned : 32; /**< reserved */ unsigned : 2; /**< reserved */ unsigned : 4; /**< reserved */ @@ -240,6 +240,26 @@ typedef struct { uint32_t actual_suspend_time_ms[8]; /**< the actual suspend time for each flow id, unit: ms */ } wifi_event_sta_itwt_suspend_t; +/** + * @brief TWT types + */ +typedef enum { + TWT_TYPE_INDIVIDUAL, /**< individual twt */ + TWT_TYPE_BROADCAST, /**< broadcast twt */ + TWT_TYPE_MAX, /**< the max value */ +} wifi_twt_type_t; + +/** Argument structure for twt configuration */ +typedef struct { + bool post_wakeup_event; /**< post twt wakeup event */ +} wifi_twt_config_t; + +/** Argument structure for WIFI_EVENT_TWT_WAKEUP event */ +typedef struct { + wifi_twt_type_t twt_type; /**< twt type */ + uint8_t flow_id; /**< flow id */ +} wifi_event_sta_twt_wakeup_t; + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/include/esp_wifi_netif.h b/components/esp_wifi/include/esp_wifi_netif.h index c25c52edd9..7dfa724b06 100644 --- a/components/esp_wifi/include/esp_wifi_netif.h +++ b/components/esp_wifi/include/esp_wifi_netif.h @@ -1,11 +1,17 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include +#include +#include "esp_err.h" +#include "esp_wifi_types.h" +#include "esp_netif_types.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index 2d555c36c1..da626fdb9b 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -56,18 +56,20 @@ typedef struct { } wifi_country_t; /* Strength of authmodes */ -/* OPEN < WEP < WPA_PSK < OWE < WPA2_PSK = WPA_WPA2_PSK < WAPI_PSK < WPA2_ENTERPRISE < WPA3_PSK = WPA2_WPA3_PSK */ +/* OPEN < WEP < WPA_PSK < OWE < WPA2_PSK = WPA_WPA2_PSK < WAPI_PSK < WPA3_PSK = WPA2_WPA3_PSK */ typedef enum { WIFI_AUTH_OPEN = 0, /**< authenticate mode : open */ WIFI_AUTH_WEP, /**< authenticate mode : WEP */ WIFI_AUTH_WPA_PSK, /**< authenticate mode : WPA_PSK */ WIFI_AUTH_WPA2_PSK, /**< authenticate mode : WPA2_PSK */ WIFI_AUTH_WPA_WPA2_PSK, /**< authenticate mode : WPA_WPA2_PSK */ - WIFI_AUTH_WPA2_ENTERPRISE, /**< authenticate mode : WPA2_ENTERPRISE */ + WIFI_AUTH_ENTERPRISE, /**< authenticate mode : WiFi EAP security */ + WIFI_AUTH_WPA2_ENTERPRISE = WIFI_AUTH_ENTERPRISE, /**< authenticate mode : WiFi EAP security */ WIFI_AUTH_WPA3_PSK, /**< authenticate mode : WPA3_PSK */ WIFI_AUTH_WPA2_WPA3_PSK, /**< authenticate mode : WPA2_WPA3_PSK */ WIFI_AUTH_WAPI_PSK, /**< authenticate mode : WAPI_PSK */ WIFI_AUTH_OWE, /**< authenticate mode : OWE */ + WIFI_AUTH_WPA3_ENT_192, /**< authenticate mode : WPA3_ENT_SUITE_B_192_BIT */ WIFI_AUTH_MAX } wifi_auth_mode_t; @@ -208,7 +210,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 */ @@ -291,6 +293,8 @@ typedef struct { uint8_t ssid_hidden; /**< Broadcast SSID or not, default 0, broadcast the SSID */ uint8_t max_connection; /**< Max number of stations allowed to connect in */ uint16_t beacon_interval; /**< Beacon interval which should be multiples of 100. Unit: TU(time unit, 1 TU = 1024 us). Range: 100 ~ 60000. Default value: 100 */ + uint8_t csa_count; /**< Channel Switch Announcement Count. Notify the station that the channel will switch after the csa_count beacon intervals. Default value: 3 */ + uint8_t dtim_period; /**< Dtim period of soft-AP. Default value: 2 */ wifi_cipher_type_t pairwise_cipher; /**< Pairwise cipher of SoftAP, group cipher will be derived using this. Cipher values are valid starting from WIFI_CIPHER_TYPE_TKIP, enum values before that will be considered as invalid and default cipher suites(TKIP+CCMP) will be used. Valid cipher suites in softAP mode are WIFI_CIPHER_TYPE_TKIP, WIFI_CIPHER_TYPE_CCMP and WIFI_CIPHER_TYPE_TKIP_CCMP. */ bool ftm_responder; /**< Enable FTM Responder mode */ wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame */ @@ -308,7 +312,7 @@ typedef struct { uint8_t channel; /**< channel of target AP. Set to 1~13 to scan starting from the specified channel before connecting to AP. If the channel of AP is unknown, set it to 0.*/ uint16_t listen_interval; /**< Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. */ wifi_sort_method_t sort_method; /**< sort the connect AP in the list by rssi or security mode */ - wifi_scan_threshold_t threshold; /**< When sort_method is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. */ + wifi_scan_threshold_t threshold; /**< When scan_threshold is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. */ wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame. Will be advertised in RSN Capabilities in RSN IE. */ uint32_t rm_enabled:1; /**< Whether Radio Measurements are enabled for the connection */ uint32_t btm_enabled:1; /**< Whether BSS Transition Management is enabled for the connection */ @@ -447,24 +451,26 @@ typedef struct { signed rssi:8; /**< Received Signal Strength Indicator(RSSI) of packet. unit: dBm */ unsigned rate:5; /**< PHY rate encoding of the packet. Only valid for non HT(11bg) packet */ unsigned :1; /**< reserved */ - unsigned sig_mode:2; /**< 0: non HT(11bg) packet; 1: HT(11n) packet; 3: VHT(11ac) packet */ + unsigned sig_mode:2; /**< Protocol of the reveived packet, 0: non HT(11bg) packet; 1: HT(11n) packet; 3: VHT(11ac) packet */ unsigned :16; /**< reserved */ unsigned mcs:7; /**< Modulation Coding Scheme. If is HT(11n) packet, shows the modulation, range from 0 to 76(MSC0 ~ MCS76) */ unsigned cwb:1; /**< Channel Bandwidth of the packet. 0: 20MHz; 1: 40MHz */ unsigned :16; /**< reserved */ - unsigned smoothing:1; /**< reserved */ - unsigned not_sounding:1; /**< reserved */ + unsigned smoothing:1; /**< Set to 1 indicates that channel estimate smoothing is recommended. + Set to 0 indicates that only per-carrierindependent (unsmoothed) channel estimate is recommended. */ + unsigned not_sounding:1; /**< Set to 0 indicates that PPDU is a sounding PPDU. Set to 1indicates that the PPDU is not a sounding PPDU. + sounding PPDU is used for channel estimation by the request receiver */ unsigned :1; /**< reserved */ unsigned aggregation:1; /**< Aggregation. 0: MPDU packet; 1: AMPDU packet */ unsigned stbc:2; /**< Space Time Block Code(STBC). 0: non STBC packet; 1: STBC packet */ - unsigned fec_coding:1; /**< Flag is set for 11n packets which are LDPC */ + unsigned fec_coding:1; /**< Forward Error Correction(FEC). Flag is set for 11n packets which are LDPC */ unsigned sgi:1; /**< Short Guide Interval(SGI). 0: Long GI; 1: Short GI */ #if CONFIG_IDF_TARGET_ESP32 signed noise_floor:8; /**< noise floor of Radio Frequency Module(RF). unit: dBm*/ #elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 unsigned :8; /**< reserved */ #endif - unsigned ampdu_cnt:8; /**< ampdu cnt */ + unsigned ampdu_cnt:8; /**< the number of subframes aggregated in AMPDU */ unsigned channel:4; /**< primary channel on which this packet is received */ unsigned secondary_channel:4; /**< secondary channel on which this packet is received. 0: none; 1: above; 2: below */ unsigned :8; /**< reserved */ @@ -558,6 +564,7 @@ typedef struct { bool channel_filter_en; /**< enable to turn on channel filter to smooth adjacent sub-carrier. Disable it to keep independence of adjacent sub-carrier. Default enabled */ bool manu_scale; /**< manually scale the CSI data by left shifting or automatically scale the CSI data. If set true, please set the shift bits. false: automatically. true: manually. Default false */ uint8_t shift; /**< manually left shift bits of the scale of the CSI data. The range of the left shift bits is 0~15 */ + bool dump_ack_en; /**< enable to dump 802.11 ACK frame, default disabled */ } wifi_csi_config_t; #endif @@ -569,9 +576,13 @@ typedef struct { wifi_pkt_rx_ctrl_t rx_ctrl;/**< received packet radio metadata header of the CSI data */ uint8_t mac[6]; /**< source MAC address of the CSI data */ uint8_t dmac[6]; /**< destination MAC address of the CSI data */ - bool first_word_invalid; /**< first four bytes of the CSI data is invalid or not */ - int8_t *buf; /**< buffer of CSI data */ - uint16_t len; /**< length of CSI data */ + bool first_word_invalid; /**< first four bytes of the CSI data is invalid or not, true indicates the first four bytes is invalid due to hardware limition */ + int8_t *buf; /**< valid buffer of CSI data */ + uint16_t len; /**< valid length of CSI data */ + uint8_t *hdr; /**< header of the wifi packet */ + uint8_t *payload; /**< payload of the wifi packet */ + uint16_t payload_len; /**< payload len of the wifi packet */ + uint16_t rx_seq; /**< rx sequence number of the wifi packet */ } wifi_csi_info_t; /** @@ -648,7 +659,9 @@ typedef struct { uint8_t resp_mac[6]; /**< MAC address of the FTM Responder */ uint8_t channel; /**< Primary channel of the FTM Responder */ uint8_t frm_count; /**< No. of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0(No pref), 16, 24, 32, 64) */ - uint16_t burst_period; /**< Requested time period between consecutive FTM bursts in 100's of milliseconds (0 - No pref) */ + uint16_t burst_period; /**< Requested period between FTM bursts in 100's of milliseconds (allowed values 0(No pref) - 100) */ + bool use_get_report_api; /**< True - Using esp_wifi_ftm_get_report to get FTM report, False - Using ftm_report_data from + WIFI_EVENT_FTM_REPORT to get FTM report */ } wifi_ftm_initiator_cfg_t; /** @@ -882,6 +895,7 @@ typedef enum { WIFI_EVENT_ITWT_TEARDOWN, /**< iTWT teardown */ WIFI_EVENT_ITWT_PROBE, /**< iTWT probe */ WIFI_EVENT_ITWT_SUSPEND, /**< iTWT suspend */ + WIFI_EVENT_TWT_WAKEUP, /**< TWT wakeup */ WIFI_EVENT_NAN_STARTED, /**< NAN Discovery has started */ WIFI_EVENT_NAN_STOPPED, /**< NAN Discovery has stopped */ @@ -941,6 +955,7 @@ typedef struct { typedef enum { WPS_FAIL_REASON_NORMAL = 0, /**< WPS normal fail reason */ WPS_FAIL_REASON_RECV_M2D, /**< WPS receive M2D frame */ + WPS_FAIL_REASON_RECV_DEAUTH, /**< Recv deauth from AP while wps handshake */ WPS_FAIL_REASON_MAX } wifi_event_sta_wps_fail_reason_t; @@ -993,6 +1008,8 @@ typedef enum { FTM_STATUS_CONF_REJECTED, /**< Peer rejected FTM configuration in FTM Request */ FTM_STATUS_NO_RESPONSE, /**< Peer did not respond to FTM Requests */ FTM_STATUS_FAIL, /**< Unknown error during FTM exchange */ + FTM_STATUS_NO_VALID_MSMT, /**< FTM session did not result in any valid measurements */ + FTM_STATUS_USER_TERM, /**< User triggered termination */ } wifi_ftm_status_t; /** Argument structure for */ @@ -1013,7 +1030,8 @@ typedef struct { uint32_t rtt_raw; /**< Raw average Round-Trip-Time with peer in Nano-Seconds */ uint32_t rtt_est; /**< Estimated Round-Trip-Time with peer in Nano-Seconds */ uint32_t dist_est; /**< Estimated one-way distance in Centi-Meters */ - wifi_ftm_report_entry_t *ftm_report_data; /**< Pointer to FTM Report with multiple entries, should be freed after use */ + wifi_ftm_report_entry_t *ftm_report_data; /**< Pointer to FTM Report, should be freed after use. Note: Highly recommended + to use API esp_wifi_ftm_get_report to get the report instead of using this */ uint8_t ftm_report_num_entries; /**< Number of entries in the FTM Report data */ } wifi_event_ftm_report_t; diff --git a/components/esp_wifi/include/smartconfig_ack.h b/components/esp_wifi/include/smartconfig_ack.h index abfada3ffa..ea2cee5943 100644 --- a/components/esp_wifi/include/smartconfig_ack.h +++ b/components/esp_wifi/include/smartconfig_ack.h @@ -1,20 +1,16 @@ -// Copyright 2010-2017 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: 2010-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef SMARTCONFIG_ACK_H #define SMARTCONFIG_ACK_H +#include "esp_smartconfig.h" +#include "esp_err.h" +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index e3e15870cb..6020d3b9b2 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit e3e15870cb5d199a59867f66dd236e0d9ff5a127 +Subproject commit 6020d3b9b22eeb4fa94a95a15555d0da699fbdf3 diff --git a/components/esp_wifi/linker.lf b/components/esp_wifi/linker.lf index 99c7a0482e..f0ff4efb82 100644 --- a/components/esp_wifi/linker.lf +++ b/components/esp_wifi/linker.lf @@ -18,6 +18,10 @@ entries: entries: .wifislprxiram+ +[sections:wifi_extra_iram] +entries: + .wifiextrairam+ + [scheme:wifi_iram] entries: wifi_iram -> iram0_text @@ -43,6 +47,10 @@ entries: entries: wifi_slp_rx_iram -> iram0_text +[scheme:wifi_extra_iram] +entries: + wifi_extra_iram -> iram0_text + [sections:wifi_log_error] entries: .rodata_wlog_error+ @@ -70,6 +78,7 @@ entries: wifi_slp_rx_iram -> flash_text wifi_iram -> flash_text wifi_rx_iram -> flash_text + wifi_extra_iram -> flash_text if LOG_MAXIMUM_LEVEL <= 0: wifi_log_error -> rodata_noload else: @@ -117,6 +126,9 @@ entries: if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: * (extram_bss) + if ESP_WIFI_EXTRA_IRAM_OPT = y: + * (wifi_extra_iram) + [mapping:net80211] archive: libnet80211.a entries: @@ -135,9 +147,16 @@ entries: if ESP_WIFI_RX_IRAM_OPT || ESP_WIFI_SLP_IRAM_OPT: * (wifi_slp_rx_iram) + if ESP_WIFI_EXTRA_IRAM_OPT = y: + * (wifi_extra_iram) + [mapping:esp_wifi] archive: libesp_wifi.a entries: + if ESP_WIFI_IRAM_OPT = y: + esp_adapter:coex_pti_get_wrapper (noflash) + wifi_netif:wifi_sta_receive (noflash) + wifi_netif:wifi_transmit_wrap (noflash) if ESP_WIFI_SLP_IRAM_OPT =y: esp_adapter:wifi_clock_enable_wrapper (noflash) esp_adapter:wifi_clock_disable_wrapper (noflash) diff --git a/components/esp_wifi/src/wifi_default.c b/components/esp_wifi/src/wifi_default.c index 2279eb04c9..9b8d06bd9d 100644 --- a/components/esp_wifi/src/wifi_default.c +++ b/components/esp_wifi/src/wifi_default.c @@ -373,8 +373,8 @@ esp_netif_t* esp_netif_create_default_wifi_ap(void) esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_AP(); esp_netif_t *netif = esp_netif_new(&cfg); assert(netif); - esp_netif_attach_wifi_ap(netif); - esp_wifi_set_default_wifi_ap_handlers(); + ESP_ERROR_CHECK(esp_netif_attach_wifi_ap(netif)); + ESP_ERROR_CHECK(esp_wifi_set_default_wifi_ap_handlers()); return netif; } #endif @@ -387,8 +387,8 @@ esp_netif_t* esp_netif_create_default_wifi_sta(void) esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_STA(); esp_netif_t *netif = esp_netif_new(&cfg); assert(netif); - esp_netif_attach_wifi_station(netif); - esp_wifi_set_default_wifi_sta_handlers(); + ESP_ERROR_CHECK(esp_netif_attach_wifi_station(netif)); + ESP_ERROR_CHECK(esp_wifi_set_default_wifi_sta_handlers()); return netif; } diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index b6b9785868..7361f366fd 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,16 +12,29 @@ #include "esp_private/sleep_modem.h" #include "esp_pm.h" #include "esp_sleep.h" +#include "esp_check.h" #include "esp_private/pm_impl.h" #include "esp_private/esp_clk.h" #include "esp_wpa.h" #include "esp_netif.h" -#include "esp_coexist_internal.h" +#include "private/esp_coexist_internal.h" #include "esp_phy_init.h" #include "esp_private/phy.h" +#if __has_include("esp_psram.h") +#include "esp_psram.h" +#endif #ifdef CONFIG_ESP_WIFI_NAN_ENABLE #include "apps_private/wifi_apps_private.h" #endif +#ifdef CONFIG_ESP_WIFI_FTM_ENABLE +#include "esp_chip_info.h" +#endif + +#if SOC_PM_MODEM_RETENTION_BY_REGDMA +#include "esp_private/sleep_retention.h" +#endif + +static bool s_wifi_inited = false; #if (CONFIG_ESP_WIFI_RX_BA_WIN > CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM) #error "WiFi configuration check: WARNING, WIFI_RX_BA_WIN should not be larger than WIFI_DYNAMIC_RX_BUFFER_NUM!" @@ -43,22 +56,6 @@ static esp_pm_lock_handle_t s_wifi_modem_sleep_lock; wifi_mac_time_update_cb_t s_wifi_mac_time_update_cb = NULL; #endif -/* Set additional WiFi features and capabilities */ -uint64_t g_wifi_feature_caps = -#if CONFIG_ESP_WIFI_ENABLE_WPA3_SAE - CONFIG_FEATURE_WPA3_SAE_BIT | -#endif -#if CONFIG_SPIRAM - CONFIG_FEATURE_CACHE_TX_BUF_BIT | -#endif -#if CONFIG_ESP_WIFI_FTM_INITIATOR_SUPPORT - CONFIG_FEATURE_FTM_INITIATOR_BIT | -#endif -#if CONFIG_ESP_WIFI_FTM_RESPONDER_SUPPORT - CONFIG_FEATURE_FTM_RESPONDER_BIT | -#endif -0; - #if SOC_PM_SUPPORT_PMU_MODEM_STATE # define WIFI_BEACON_MONITOR_CONFIG_DEFAULT(ena) { \ .enable = (ena), \ @@ -116,7 +113,42 @@ static void esp_wifi_set_log_level(void) esp_wifi_internal_set_log_level(wifi_log_level); } -esp_err_t esp_wifi_deinit(void) +#if (CONFIG_FREERTOS_USE_TICKLESS_IDLE && SOC_PM_MODEM_RETENTION_BY_REGDMA) +static esp_err_t init_wifi_mac_sleep_retention(void *arg) +{ + int config_size; + sleep_retention_entries_config_t *config = esp_wifi_internal_mac_retention_context_get(&config_size); + esp_err_t err = sleep_retention_entries_create(config, config_size, 3, SLEEP_RETENTION_MODULE_WIFI_MAC); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (%s) retention", "WiFi MAC"); + ESP_LOGD(TAG, "WiFi MAC sleep retention initialization"); + return ESP_OK; +} +#endif + +#if CONFIG_MAC_BB_PD +static void esp_wifi_mac_pd_mem_init(void) +{ +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + esp_err_t err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_WIFI_MAC); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for wifi mac retention"); + } +#endif + esp_wifi_internal_set_mac_sleep(true); +} +static void esp_wifi_mac_pd_mem_deinit(void) +{ + esp_wifi_internal_set_mac_sleep(false); +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_WIFI_MAC); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to free sleep retention linked list for wifi mac retention"); + } +#endif +} +#endif + +static esp_err_t wifi_deinit_internal(void) { esp_err_t err = ESP_OK; @@ -134,12 +166,24 @@ esp_err_t esp_wifi_deinit(void) esp_nan_app_deinit(); #endif +#if CONFIG_MAC_BB_PD + esp_wifi_mac_pd_mem_deinit(); + esp_mac_bb_pd_mem_deinit(); +#endif + esp_supplicant_deinit(); err = esp_wifi_deinit_internal(); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to deinit Wi-Fi driver (0x%x)", err); return err; } +#ifdef CONFIG_PM_ENABLE + if (s_wifi_modem_sleep_lock) { + esp_pm_lock_delete(s_wifi_modem_sleep_lock); + s_wifi_modem_sleep_lock = NULL; + } +#endif + esp_wifi_power_domain_off(); #if CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT wifi_beacon_monitor_config_t monitor_config = WIFI_BEACON_MONITOR_CONFIG_DEFAULT(false); @@ -158,20 +202,37 @@ esp_err_t esp_wifi_deinit(void) esp_sleep_disable_wifi_beacon_wakeup(); # endif #endif /* SOC_WIFI_HW_TSF */ +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_WIFI_MAC); + if (err != ESP_OK) { + ESP_LOGW(TAG, "WiFi MAC sleep retention deinit failed"); + } +#endif /* SOC_PM_MODEM_RETENTION_BY_REGDMA */ #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ #if CONFIG_MAC_BB_PD esp_unregister_mac_bb_pd_callback(pm_mac_sleep); esp_unregister_mac_bb_pu_callback(pm_mac_wakeup); #endif - esp_wifi_power_domain_off(); -#if CONFIG_MAC_BB_PD - esp_mac_bb_pd_mem_deinit(); +#if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP + esp_wifi_internal_modem_state_configure(false); + esp_pm_unregister_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep); #endif esp_phy_modem_deinit(); + s_wifi_inited = false; + return err; } +esp_err_t esp_wifi_deinit(void) +{ + if (s_wifi_inited == false) { + return ESP_ERR_WIFI_NOT_INIT; + } + + return wifi_deinit_internal(); +} + static void esp_wifi_config_info(void) { #ifdef CONFIG_ESP_WIFI_RX_BA_WIN @@ -211,39 +272,77 @@ static void esp_wifi_config_info(void) #endif } -esp_err_t esp_wifi_init(const wifi_init_config_t *config) +#if CONFIG_SPIRAM +static esp_err_t esp_wifi_psram_check(const wifi_init_config_t *config) { - if ((config->feature_caps & CONFIG_FEATURE_CACHE_TX_BUF_BIT) && (WIFI_CACHE_TX_BUFFER_NUM == 0)) - { +#if CONFIG_SPIRAM_IGNORE_NOTFOUND + if (!esp_psram_is_initialized()) { + if (config->feature_caps & CONFIG_FEATURE_CACHE_TX_BUF_BIT) { + ESP_LOGW(TAG, "WiFi cache TX buffers should be disabled when initialize SPIRAM failed"); + } + if (config->tx_buf_type == 0) { + ESP_LOGW(TAG, "TX buffers type should be changed from static to dynamic when initialize SPIRAM failed"); + } +#ifdef CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP + ESP_LOGW(TAG, "WiFi/LWIP prefer SPIRAM should be disabled when initialize SPIRAM failed"); +#endif + if (config->amsdu_tx_enable) { + ESP_LOGW(TAG, "WiFi AMSDU TX should be disabled when initialize SPIRAM failed"); + } + } +#endif + if ((config->feature_caps & CONFIG_FEATURE_CACHE_TX_BUF_BIT) && (WIFI_CACHE_TX_BUFFER_NUM == 0)) { ESP_LOGE(TAG, "Number of WiFi cache TX buffers should not equal 0 when enable SPIRAM"); return ESP_ERR_NOT_SUPPORTED; } - esp_wifi_power_domain_on(); -#ifdef CONFIG_PM_ENABLE - if (s_wifi_modem_sleep_lock == NULL) { - esp_err_t err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "wifi", - &s_wifi_modem_sleep_lock); - if (err != ESP_OK) { - return err; - } + return ESP_OK; +} +#endif + +esp_err_t esp_wifi_init(const wifi_init_config_t *config) +{ + if (s_wifi_inited) { + return ESP_OK; + } + + esp_err_t result = ESP_OK; +#ifdef CONFIG_SPIRAM + result = esp_wifi_psram_check(config); + if (result != ESP_OK) { + return result; } #endif #if CONFIG_ESP_WIFI_SLP_IRAM_OPT - esp_pm_register_light_sleep_default_params_config_callback(esp_wifi_internal_update_light_sleep_default_params); - int min_freq_mhz = esp_pm_impl_get_cpu_freq(PM_MODE_LIGHT_SLEEP); int max_freq_mhz = esp_pm_impl_get_cpu_freq(PM_MODE_CPU_MAX); esp_wifi_internal_update_light_sleep_default_params(min_freq_mhz, max_freq_mhz); - uint32_t sleep_delay_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME * 1000; - esp_wifi_set_sleep_delay_time(sleep_delay_us); + esp_pm_register_light_sleep_default_params_config_callback(esp_wifi_internal_update_light_sleep_default_params); + +#endif + + uint32_t min_active_time_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME * 1000; + esp_wifi_set_sleep_min_active_time(min_active_time_us); uint32_t keep_alive_time_us = CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME * 1000 * 1000; esp_wifi_set_keep_alive_time(keep_alive_time_us); -#endif + + uint32_t wait_broadcast_data_time_us = CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME * 1000; + esp_wifi_set_sleep_wait_broadcast_data_time(wait_broadcast_data_time_us); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if SOC_PM_MODEM_RETENTION_BY_REGDMA + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = init_wifi_mac_sleep_retention, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_WIFI_BB) | BIT(SLEEP_RETENTION_MODULE_CLOCK_MODEM) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_WIFI_MAC, &init_param); + if (err != ESP_OK) { + ESP_LOGW(TAG, "WiFi MAC sleep retention init failed"); + } +#endif + #if CONFIG_MAC_BB_PD if (esp_register_mac_bb_pd_callback(pm_mac_sleep) != ESP_OK || esp_register_mac_bb_pu_callback(pm_mac_wakeup) != ESP_OK) { @@ -283,27 +382,49 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) coex_init(); #endif esp_wifi_set_log_level(); - esp_err_t result = esp_wifi_init_internal(config); + esp_wifi_power_domain_on(); +#ifdef CONFIG_ESP_WIFI_FTM_ENABLE + esp_chip_info_t info = {0}; + esp_chip_info(&info); + if (info.model == CHIP_ESP32C6 && info.revision <= 1) { + ((wifi_init_config_t *)config)->feature_caps &= ~(CONFIG_FEATURE_FTM_INITIATOR_BIT); + } +#endif + result = esp_wifi_init_internal(config); if (result == ESP_OK) { #if CONFIG_MAC_BB_PD esp_mac_bb_pd_mem_init(); - esp_wifi_internal_set_mac_sleep(true); + esp_wifi_mac_pd_mem_init(); #endif esp_phy_modem_init(); +#if CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP + if (sleep_modem_wifi_modem_state_enabled()) { + esp_pm_register_skip_light_sleep_callback(sleep_modem_wifi_modem_state_skip_light_sleep); + esp_wifi_internal_modem_state_configure(true); /* require WiFi to enable automatically receives the beacon */ + } +#endif #if CONFIG_IDF_TARGET_ESP32 s_wifi_mac_time_update_cb = esp_wifi_internal_update_mac_time; #endif +#ifdef CONFIG_PM_ENABLE + if (s_wifi_modem_sleep_lock == NULL) { + result = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "wifi", + &s_wifi_modem_sleep_lock); + if (result != ESP_OK) { + ESP_LOGE(TAG, "Failed to create pm lock (0x%x)", result); + goto _deinit; + } + } +#endif + result = esp_supplicant_init(); if (result != ESP_OK) { ESP_LOGE(TAG, "Failed to init supplicant (0x%x)", result); - esp_err_t deinit_ret = esp_wifi_deinit(); - if (deinit_ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to deinit Wi-Fi (0x%x)", deinit_ret); - } - - return result; + goto _deinit; } + } else { + goto _deinit; } #if CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT wifi_beacon_monitor_config_t monitor_config = WIFI_BEACON_MONITOR_CONFIG_DEFAULT(true); @@ -317,6 +438,17 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) esp_nan_app_init(); #endif + s_wifi_inited = true; + + return result; + +_deinit: + ; + esp_err_t deinit_ret = wifi_deinit_internal(); + if (deinit_ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to deinit Wi-Fi (0x%x)", deinit_ret); + } + return result; } @@ -325,6 +457,9 @@ void wifi_apb80m_request(void) { assert(s_wifi_modem_sleep_lock); esp_pm_lock_acquire(s_wifi_modem_sleep_lock); + if (esp_clk_apb_freq() != APB_CLK_FREQ) { + ESP_LOGE(__func__, "WiFi needs 80MHz APB frequency to work, but got %dHz", esp_clk_apb_freq()); + } } void wifi_apb80m_release(void) @@ -335,16 +470,87 @@ void wifi_apb80m_release(void) #endif //CONFIG_PM_ENABLE #ifndef CONFIG_ESP_WIFI_FTM_ENABLE -void ieee80211_ftm_attach(void) +esp_err_t ieee80211_ftm_attach(void) { /* Do not remove, stub to overwrite weak link in Wi-Fi Lib */ + return ESP_OK; } #endif #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 diff --git a/components/esp_wifi/test_apps/wifi_connect/main/test_wifi_conn.c b/components/esp_wifi/test_apps/wifi_connect/main/test_wifi_conn.c index 991a03df47..eb28343a11 100644 --- a/components/esp_wifi/test_apps/wifi_connect/main/test_wifi_conn.c +++ b/components/esp_wifi/test_apps/wifi_connect/main/test_wifi_conn.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 * @@ -31,8 +31,8 @@ #define TEST_DEFAULT_SSID "SSID_" CONFIG_IDF_TARGET TEST_SUFFIX_STR #define TEST_DEFAULT_PWD "PASS_" CONFIG_IDF_TARGET TEST_SUFFIX_STR -#define TEST_DEFAULT_CHANNEL (1) -#define CONNECT_TIMEOUT_MS (7000) +#define TEST_DEFAULT_CHANNEL (6) +#define CONNECT_TIMEOUT_MS (8000) #define GOT_IP_EVENT (1) @@ -67,11 +67,13 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, case WIFI_EVENT_STA_CONNECTED: ESP_LOGI(TAG, "WIFI_EVENT_STA_CONNECTED"); if (wifi_events) { - xEventGroupSetBits(wifi_events, WIFI_AP_STA_CONNECTED); + xEventGroupSetBits(wifi_events, WIFI_STA_CONNECTED); } break; case WIFI_EVENT_STA_DISCONNECTED: ESP_LOGI(TAG, "WIFI_EVENT_STA_DISCONNECTED"); + wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data; + ESP_LOGI(TAG, "disconnect reason: %u", event->reason); if (! (EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT & wifi_event_handler_flag) ) { TEST_ESP_OK(esp_wifi_connect()); } @@ -266,3 +268,87 @@ static void test_wifi_connection_softap(void) } TEST_CASE_MULTIPLE_DEVICES("test wifi retain connection for 60s", "[wifi][timeout=90]", test_wifi_connection_sta, test_wifi_connection_softap); + +// single core have issue as WIFIBUG-92 +#if !CONFIG_FREERTOS_UNICORE +static void esp_wifi_connect_first_time(void) +{ + start_wifi_as_sta(); + // make sure softap has started + vTaskDelay(1000/portTICK_PERIOD_MS); + + wifi_config_t w_config; + memset(&w_config, 0, sizeof(w_config)); + memcpy(w_config.sta.ssid, TEST_DEFAULT_SSID, strlen(TEST_DEFAULT_SSID)); + memcpy(w_config.sta.password, TEST_DEFAULT_PWD, strlen(TEST_DEFAULT_PWD)); + w_config.sta.channel = 1; + + wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT; + + TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_STA, &w_config)); + ESP_LOGI(TAG, "start esp_wifi_connect first time: %s", TEST_DEFAULT_SSID); + TEST_ESP_OK(esp_wifi_connect()); +} + +static void test_wifi_connect_at_scan_phase(void) +{ + + esp_wifi_connect_first_time(); + + // connect when first connect in scan + vTaskDelay(300/portTICK_PERIOD_MS); + ESP_LOGI(TAG, "connect when first connect in scan"); + TEST_ESP_ERR(ESP_ERR_WIFI_CONN, esp_wifi_connect()); + wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT; + + stop_wifi(); +} + +static void test_wifi_connect_before_connected_phase(void) +{ + + esp_wifi_connect_first_time(); + + // connect before connected + vTaskDelay(730/portTICK_PERIOD_MS); + ESP_LOGI(TAG, "connect when first connect after scan before connected"); + TEST_ESP_ERR(ESP_ERR_WIFI_CONN, esp_wifi_connect()); + wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT; + + stop_wifi(); +} + +static void test_wifi_connect_after_connected_phase(void) +{ + EventBits_t bits; + + start_wifi_as_sta(); + wifi_event_handler_flag = 0; + wifi_connect(); + xEventGroupClearBits(wifi_events, WIFI_STA_CONNECTED | WIFI_DISCONNECT_EVENT); + ESP_LOGI(TAG, "connect after connected"); + TEST_ESP_OK(esp_wifi_connect()); + bits = xEventGroupWaitBits(wifi_events, WIFI_STA_CONNECTED | WIFI_DISCONNECT_EVENT, pdTRUE, pdFALSE, CONNECT_TIMEOUT_MS/portTICK_PERIOD_MS); + // shouldn't reconnect + TEST_ASSERT((bits & WIFI_AP_STA_CONNECTED) == 0); + // shouldn't disconnect + TEST_ASSERT((bits & WIFI_DISCONNECT_EVENT) == 0); + + wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT; + + stop_wifi(); +} + +static void set_wifi_softap(void) +{ + start_wifi_as_softap(); + + // wait for sta connect + vTaskDelay(20000/portTICK_PERIOD_MS); + stop_wifi(); +} + +TEST_CASE_MULTIPLE_DEVICES("test wifi connect at scan", "[wifi]", test_wifi_connect_at_scan_phase, set_wifi_softap); +TEST_CASE_MULTIPLE_DEVICES("test wifi connect before connected", "[wifi]", test_wifi_connect_before_connected_phase, set_wifi_softap); +TEST_CASE_MULTIPLE_DEVICES("test wifi connect after connected", "[wifi]", test_wifi_connect_after_connected_phase, set_wifi_softap); +#endif diff --git a/components/esp_wifi/test_apps/wifi_function/main/test_wifi_init.c b/components/esp_wifi/test_apps/wifi_function/main/test_wifi_init.c index adf2863602..9b85dfbbd6 100644 --- a/components/esp_wifi/test_apps/wifi_function/main/test_wifi_init.c +++ b/components/esp_wifi/test_apps/wifi_function/main/test_wifi_init.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: Unlicense OR CC0-1.0 */ @@ -139,3 +139,26 @@ TEST_CASE("Calling esp_wifi_deinit() without stop", "[wifi_init]") TEST_ESP_OK(event_deinit()); ESP_LOGI(TAG, "test passed..."); } + +TEST_CASE("Calling esp_wifi_connect() without start", "[wifi_init]") +{ + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_LOGI(TAG, EMPH_STR("event_init")); + TEST_ESP_OK(event_init()); + ESP_LOGI(TAG, EMPH_STR("esp_wifi_init")); + TEST_ESP_OK(esp_wifi_init(&cfg)); + ESP_LOGI(TAG, EMPH_STR("esp_wifi_connect")); + TEST_ESP_ERR(ESP_ERR_WIFI_NOT_STARTED, esp_wifi_connect()); + ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit")); + TEST_ESP_OK(esp_wifi_deinit()); + ESP_LOGI(TAG, EMPH_STR("event_deinit")); + TEST_ESP_OK(event_deinit()); + ESP_LOGI(TAG, "test passed..."); +} + +TEST_CASE("Calling esp_wifi_connect() without init", "[wifi_init]") +{ + ESP_LOGI(TAG, EMPH_STR("esp_wifi_connect")); + TEST_ESP_ERR(ESP_ERR_WIFI_NOT_INIT, esp_wifi_connect()); + ESP_LOGI(TAG, "test passed..."); +} diff --git a/components/esp_wifi/wifi_apps/include/esp_nan.h b/components/esp_wifi/wifi_apps/include/esp_nan.h index ae0ae46352..e0e9d90d81 100644 --- a/components/esp_wifi/wifi_apps/include/esp_nan.h +++ b/components/esp_wifi/wifi_apps/include/esp_nan.h @@ -26,8 +26,8 @@ extern "C" { #define NDP_STATUS_REJECTED 2 #define NAN_MAX_PEERS_RECORD 15 -#define ESP_NAN_PUBLISH 1 -#define ESP_NAN_SUBSCRIBE 2 +#define ESP_NAN_PUBLISH 2 +#define ESP_NAN_SUBSCRIBE 1 /** Parameters of a peer service record */ struct nan_peer_record { @@ -128,7 +128,7 @@ uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req); /** * @brief Respond to a NAN Datapath request with Accept or Reject * - * @attention This API should be called if ndp_auto_accept is not set True by the Publisher and + * @attention This API should be called if ndp_resp_needed is set True by the Publisher and * a WIFI_EVENT_NDP_INDICATION event is received due to an incoming NDP request. * * @param resp NAN Datapath Response parameters. diff --git a/components/esp_wifi/wifi_apps/src/nan_app.c b/components/esp_wifi/wifi_apps/src/nan_app.c index cc4025cd60..c3eb2f0673 100644 --- a/components/esp_wifi/wifi_apps/src/nan_app.c +++ b/components/esp_wifi/wifi_apps/src/nan_app.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,18 +28,23 @@ #define NDP_REJECTED BIT5 /* Macros */ -#define MACADDR_LEN 6 +#define MACADDR_LEN 6 #define MACADDR_EQUAL(a1, a2) (memcmp(a1, a2, MACADDR_LEN)) #define MACADDR_COPY(dst, src) (memcpy(dst, src, MACADDR_LEN)) -#define NAN_DW_INTVL_MS 524 /* NAN DW interval (512 TU's ~= 524 mSec) */ -#define NAN_NDP_RESP_TIMEOUT_DW 4 +#define NAN_DW_INTVL_MS 524 /* NAN DW interval (512 TU's ~= 524 mSec) */ +#define NAN_NDP_RESP_TIMEOUT_DW 8 #define NAN_NDP_RESP_TIMEOUT NAN_NDP_RESP_TIMEOUT_DW*NAN_DW_INTVL_MS +#define NAN_NDP_TERM_TIMEOUT 2*NAN_DW_INTVL_MS /* NDP Termination Timeout - 2 DW*/ /* Global Variables */ static const char *TAG = "nan_app"; static EventGroupHandle_t nan_event_group; static bool s_app_default_handlers_set = false; static uint8_t null_mac[MACADDR_LEN] = {0}; +static void *s_nan_data_lock = NULL; + +#define NAN_DATA_LOCK() os_mutex_lock(s_nan_data_lock) +#define NAN_DATA_UNLOCK() os_mutex_unlock(s_nan_data_lock) struct peer_svc_info { SLIST_ENTRY(peer_svc_info) next; @@ -182,16 +187,6 @@ static struct peer_svc_info *nan_find_peer_svc(uint8_t own_svc_id, uint8_t peer_ return p_peer_svc; } -static bool nan_update_peer_svc(uint8_t own_svc_id, uint8_t peer_svc_id, uint8_t peer_nmi[]) -{ - struct peer_svc_info *peer_info = nan_find_peer_svc(own_svc_id, 0, peer_nmi); - if (peer_info) { - peer_info->svc_id = peer_svc_id; - return true; - } - return false; -} - static bool nan_record_peer_svc(uint8_t own_svc_id, uint8_t peer_svc_id, uint8_t peer_nmi[]) { struct own_svc_info *p_own_svc; @@ -216,10 +211,23 @@ static bool nan_record_peer_svc(uint8_t own_svc_id, uint8_t peer_svc_id, uint8_t SLIST_INSERT_HEAD(&(p_own_svc->peer_list), p_peer_svc, next); p_own_svc->num_peer_records++; } else { - struct peer_svc_info *temp; - temp = SLIST_FIRST(&(p_own_svc->peer_list)); - SLIST_REMOVE_HEAD(&(p_own_svc->peer_list), next); - os_free(temp); + /* Remove the oldest peer service entry */ + struct peer_svc_info *prev_ele = NULL, *cur_ele = NULL; + + SLIST_FOREACH(cur_ele, &(p_own_svc->peer_list), next) { + if (SLIST_NEXT(cur_ele, next) == NULL) { + if (SLIST_FIRST(&(p_own_svc->peer_list)) == cur_ele) { + SLIST_REMOVE_HEAD(&(p_own_svc->peer_list), next); + } else { + SLIST_REMOVE_AFTER(prev_ele, next); + } + break; + } + prev_ele = cur_ele; + } + /* Insert new peer service entry */ + SLIST_INSERT_HEAD(&(p_own_svc->peer_list), p_peer_svc, next); + os_free(cur_ele); } return true; @@ -362,6 +370,19 @@ static bool nan_is_datapath_active(void) return false; } +static void nan_update_peer_svc(uint8_t own_svc_id, uint8_t peer_svc_id, uint8_t peer_nmi[]) +{ + struct peer_svc_info *peer_info = nan_find_peer_svc(own_svc_id, 0, peer_nmi); + if (peer_info) { + peer_info->svc_id = peer_svc_id; + } + + struct ndl_info *ndl = nan_find_ndl(0, peer_nmi); + if (ndl) { + ndl->publisher_id = peer_svc_id; + } +} + static void nan_fill_params_from_event(void *evt_data, uint8_t event) { switch (event) { @@ -401,10 +422,9 @@ static void nan_fill_params_from_event(void *evt_data, uint8_t event) wifi_event_nan_svc_match_t *evt = (wifi_event_nan_svc_match_t *)evt_data; if (evt->update_pub_id) { - if (nan_update_peer_svc(evt->subscribe_id, evt->publish_id, evt->pub_if_mac)) { - break; - } + nan_update_peer_svc(evt->subscribe_id, evt->publish_id, evt->pub_if_mac); } + if (!nan_find_peer_svc(evt->subscribe_id, evt->publish_id, evt->pub_if_mac)) { nan_record_peer_svc(evt->subscribe_id, evt->publish_id, evt->pub_if_mac); } @@ -424,7 +444,10 @@ static void nan_app_action_service_match(void *arg, esp_event_base_t event_base, ESP_LOGI(TAG, "Service matched with "MACSTR" [Peer Publish id - %d]", MAC2STR(evt->pub_if_mac), evt->publish_id); + + NAN_DATA_LOCK(); nan_fill_params_from_event(evt, WIFI_EVENT_NAN_SVC_MATCH); + NAN_DATA_UNLOCK(); } static void nan_app_action_replied(void *arg, esp_event_base_t event_base, int32_t event_id, void *data) @@ -436,7 +459,10 @@ static void nan_app_action_replied(void *arg, esp_event_base_t event_base, int32 ESP_LOGD(TAG, "Sent Publish to Peer "MACSTR" [Peer Subscribe id - %d]", MAC2STR(evt->sub_if_mac), evt->subscribe_id); + + NAN_DATA_LOCK(); nan_fill_params_from_event(evt, WIFI_EVENT_NAN_REPLIED); + NAN_DATA_UNLOCK(); } static void nan_app_action_receive(void *arg, esp_event_base_t event_base, int32_t event_id, void *data) @@ -448,7 +474,10 @@ static void nan_app_action_receive(void *arg, esp_event_base_t event_base, int32 ESP_LOGI(TAG, "Received message '%s' from Peer "MACSTR" [Peer Service id - %d]", evt->peer_svc_info, MAC2STR(evt->peer_if_mac), evt->peer_inst_id); + + NAN_DATA_LOCK(); nan_fill_params_from_event(evt, WIFI_EVENT_NAN_RECEIVE); + NAN_DATA_UNLOCK(); } static void nan_app_action_ndp_indication(void *arg, esp_event_base_t event_base, int32_t event_id, void *data) @@ -457,15 +486,17 @@ static void nan_app_action_ndp_indication(void *arg, esp_event_base_t event_base return; } wifi_event_ndp_indication_t *evt = (wifi_event_ndp_indication_t *)data; + + NAN_DATA_LOCK(); struct own_svc_info *p_own_svc = nan_find_own_svc(evt->publish_id); if (!p_own_svc) { ESP_LOGE(TAG, "No Publish found with id %d", evt->publish_id); - return; + goto done; } if (ndl_limit_reached()) { ESP_LOGE(TAG, "NDP limit reached"); - return; + goto done; } nan_fill_params_from_event(evt, WIFI_EVENT_NDP_INDICATION); @@ -481,6 +512,9 @@ static void nan_app_action_ndp_indication(void *arg, esp_event_base_t event_base esp_nan_internal_datapath_resp(&ndp_resp); } + +done: + NAN_DATA_UNLOCK(); } static void nan_app_action_ndp_confirm(void *arg, esp_event_base_t event_base, int32_t event_id, void *data) @@ -489,29 +523,31 @@ static void nan_app_action_ndp_confirm(void *arg, esp_event_base_t event_base, i return; } wifi_event_ndp_confirm_t *evt = (wifi_event_ndp_confirm_t *)data; + + NAN_DATA_LOCK(); wifi_netif_driver_t driver = esp_netif_get_io_driver(s_nan_ctx.nan_netif); ip_addr_t target_addr = {0}; if (!s_nan_ctx.nan_netif) { ESP_LOGE(TAG, "%s: NAN netif is NULL", __func__); - return; + goto done; } if (nan_find_ndl(evt->ndp_id, NULL) == NULL) { /* As ndl isn't found, timeout has occured for NDP response and datapath request is rejected */ - return; + goto done; } if (evt->status == NDP_STATUS_REJECTED) { ESP_LOGE(TAG, "NDP request to Peer "MACSTR" rejected [NDP ID - %d]", MAC2STR(evt->peer_nmi), evt->ndp_id); nan_reset_ndl(evt->ndp_id, false); os_event_group_set_bits(nan_event_group, NDP_REJECTED); - return; + goto done; } /* If interface not ready when started, rxcb to be registered on connection */ if (esp_wifi_register_if_rxcb(driver, esp_netif_receive, s_nan_ctx.nan_netif) != ESP_OK) { ESP_LOGE(TAG, "%s: esp_wifi_register_if_rxcb failed", __func__); - return; + goto done; } nan_fill_params_from_event(evt, WIFI_EVENT_NDP_CONFIRM); @@ -519,11 +555,17 @@ static void nan_app_action_ndp_confirm(void *arg, esp_event_base_t event_base, i esp_netif_action_connected(s_nan_ctx.nan_netif, event_base, event_id, data); esp_netif_create_ip6_linklocal(s_nan_ctx.nan_netif); + NAN_DATA_UNLOCK(); esp_wifi_nan_get_ipv6_linklocal_from_mac(&target_addr.u_addr.ip6, evt->peer_ndi); target_addr.type = IPADDR_TYPE_V6; ESP_LOGI(TAG, "NDP confirmed with Peer "MACSTR" [NDP ID - %d, Peer IPv6 - %s]", MAC2STR(evt->peer_nmi), evt->ndp_id, inet6_ntoa(*ip_2_ip6(&target_addr))); os_event_group_set_bits(nan_event_group, NDP_ACCEPTED); + return; + +done: + NAN_DATA_UNLOCK(); + return; } static void nan_app_action_ndp_terminated(void *arg, esp_event_base_t event_base, int32_t event_id, void *data) @@ -533,6 +575,7 @@ static void nan_app_action_ndp_terminated(void *arg, esp_event_base_t event_base } wifi_event_ndp_terminated_t *evt = (wifi_event_ndp_terminated_t *)data; + NAN_DATA_LOCK(); if (s_nan_ctx.nan_netif && !nan_is_datapath_active()) { esp_netif_action_disconnected(s_nan_ctx.nan_netif, event_base, event_id, data); } @@ -540,6 +583,7 @@ static void nan_app_action_ndp_terminated(void *arg, esp_event_base_t event_base nan_reset_ndl(evt->ndp_id, false); s_nan_ctx.event &= ~(NDP_INDICATION); + NAN_DATA_UNLOCK(); os_event_group_set_bits(nan_event_group, NDP_TERMINATED); } @@ -560,11 +604,13 @@ static void nan_app_action_got_ipv6(void *arg, esp_event_base_t event_base, int3 } ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)data; + NAN_DATA_LOCK(); if (event->esp_netif == s_nan_ctx.nan_netif) { esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); ESP_LOGD(TAG, "NAN Data Interface ready [IPv6 - "IPV6STR", type - %s]", IPV62STR(event->ip6_info.ip), s_ipv6_addr_types[ipv6_type]); } + NAN_DATA_UNLOCK(); } static esp_err_t nan_clear_app_default_handlers(void) @@ -618,21 +664,32 @@ static esp_err_t nan_set_app_default_handlers(void) return ESP_FAIL; } -void esp_nan_app_init(void) +void esp_nan_app_deinit(void) { if (nan_event_group) { os_event_group_delete(nan_event_group); nan_event_group = NULL; } - nan_event_group = os_event_group_create(); + + if (s_nan_data_lock) { + os_semphr_delete(s_nan_data_lock); + s_nan_data_lock = NULL; + } } -void esp_nan_app_deinit(void) +void esp_nan_app_init(void) { if (nan_event_group) { os_event_group_delete(nan_event_group); nan_event_group = NULL; } + nan_event_group = os_event_group_create(); + + s_nan_data_lock = os_recursive_mutex_create(); + if (!s_nan_data_lock) { + ESP_LOGE(TAG, "Failed to create NAN data lock"); + esp_nan_app_deinit(); + } } void esp_nan_action_start(esp_netif_t *nan_netif) @@ -642,9 +699,11 @@ void esp_nan_action_start(esp_netif_t *nan_netif) return; } + NAN_DATA_LOCK(); s_nan_ctx.nan_netif = nan_netif; - s_nan_ctx.state = NAN_STARTED_BIT; + NAN_DATA_UNLOCK(); + ESP_LOGI(TAG, "NAN Discovery started."); os_event_group_set_bits(nan_event_group, NAN_STARTED_BIT); } @@ -653,6 +712,7 @@ void esp_nan_action_stop(void) { nan_clear_app_default_handlers(); + NAN_DATA_LOCK(); if (nan_is_datapath_active()) { nan_reset_ndl(0, true); esp_wifi_internal_reg_rxcb(WIFI_IF_NAN, NULL); @@ -661,6 +721,8 @@ void esp_nan_action_stop(void) nan_reset_service(0, true); s_nan_ctx.state &= ~NAN_STARTED_BIT; s_nan_ctx.state |= NAN_STOPPED_BIT; + NAN_DATA_UNLOCK(); + os_event_group_set_bits(nan_event_group, NAN_STOPPED_BIT); } @@ -678,10 +740,19 @@ esp_err_t esp_wifi_nan_start(const wifi_nan_config_t *nan_cfg) ESP_LOGE(TAG, "Unable to get mode"); return ret; } + + if (!s_nan_data_lock) { + ESP_LOGE(TAG, "NAN Data lock doesn't exist"); + return ESP_FAIL; + } + + NAN_DATA_LOCK(); if (s_nan_ctx.state & NAN_STARTED_BIT) { ESP_LOGI(TAG, "NAN already started"); + NAN_DATA_UNLOCK(); return ESP_OK; } + NAN_DATA_UNLOCK(); ESP_RETURN_ON_ERROR(esp_wifi_set_mode(WIFI_MODE_NAN), TAG, "Set mode NAN failed"); @@ -690,13 +761,17 @@ esp_err_t esp_wifi_nan_start(const wifi_nan_config_t *nan_cfg) if (esp_wifi_start() != ESP_OK) { ESP_LOGE(TAG, "Starting wifi failed"); + NAN_DATA_LOCK(); s_nan_ctx.nan_netif = NULL; + NAN_DATA_UNLOCK(); return ESP_FAIL; } EventBits_t bits = os_event_group_wait_bits(nan_event_group, NAN_STARTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY); if (!(bits & NAN_STARTED_BIT)) { + NAN_DATA_LOCK(); s_nan_ctx.nan_netif = NULL; + NAN_DATA_UNLOCK(); return ESP_FAIL; } return ESP_OK; @@ -704,8 +779,10 @@ esp_err_t esp_wifi_nan_start(const wifi_nan_config_t *nan_cfg) esp_err_t esp_wifi_nan_stop(void) { + NAN_DATA_LOCK(); if (!(s_nan_ctx.state & NAN_STARTED_BIT)) { ESP_LOGE(TAG, "NAN isn't started"); + NAN_DATA_UNLOCK(); return ESP_FAIL; } @@ -721,11 +798,14 @@ esp_err_t esp_wifi_nan_stop(void) } nan_reset_ndl(0, true); + NAN_DATA_UNLOCK(); os_event_group_clear_bits(nan_event_group, NDP_TERMINATED); - os_event_group_wait_bits(nan_event_group, NDP_TERMINATED, pdFALSE, pdFALSE, portMAX_DELAY); + os_event_group_wait_bits(nan_event_group, NDP_TERMINATED, pdFALSE, pdFALSE, pdMS_TO_TICKS(NAN_NDP_TERM_TIMEOUT)); os_event_group_clear_bits(nan_event_group, NDP_TERMINATED); /* Wait for 1 NAN DW interval (512 TU's ~= 524 mSec) for successful termination */ g_wifi_osi_funcs._task_delay(NAN_DW_INTVL_MS/portTICK_PERIOD_MS); + } else { + NAN_DATA_UNLOCK(); } ESP_RETURN_ON_ERROR(esp_wifi_stop(), TAG, "Stopping NAN failed"); @@ -735,7 +815,9 @@ esp_err_t esp_wifi_nan_stop(void) return ESP_FAIL; } + NAN_DATA_LOCK(); memset(&s_nan_ctx, 0, sizeof(nan_ctx_t)); + NAN_DATA_UNLOCK(); return ESP_OK; } @@ -743,78 +825,94 @@ uint8_t esp_wifi_nan_publish_service(const wifi_nan_publish_cfg_t *publish_cfg, { uint8_t pub_id; + NAN_DATA_LOCK(); if (!(s_nan_ctx.state & NAN_STARTED_BIT)) { ESP_LOGE(TAG, "NAN not started!"); - return 0; + goto fail; } if (nan_services_limit_reached()) { ESP_LOGE(TAG, "Maximum services limit reached"); - return 0; + goto fail; } if (nan_find_own_svc_by_name(publish_cfg->service_name)) { - ESP_LOGE(TAG, "Service name already used!"); - return 0; + ESP_LOGE(TAG, "Service name %s already used!", publish_cfg->service_name); + goto fail; } if (esp_nan_internal_publish_service(publish_cfg, &pub_id, false) != ESP_OK) { ESP_LOGE(TAG, "Failed to publish service '%s'", publish_cfg->service_name); - return 0; + goto fail; } ESP_LOGI(TAG, "Started Publishing %s [Service ID - %u]", publish_cfg->service_name, pub_id); nan_record_own_svc(pub_id, ESP_NAN_PUBLISH, publish_cfg->service_name, ndp_resp_needed); + NAN_DATA_UNLOCK(); return pub_id; +fail: + NAN_DATA_UNLOCK(); + return 0; } uint8_t esp_wifi_nan_subscribe_service(const wifi_nan_subscribe_cfg_t *subscribe_cfg) { uint8_t sub_id; + NAN_DATA_LOCK(); if (!(s_nan_ctx.state & NAN_STARTED_BIT)) { ESP_LOGE(TAG, "NAN not started!"); - return 0; + goto fail; } if (nan_services_limit_reached()) { ESP_LOGE(TAG, "Maximum services limit reached"); - return 0; + goto fail; } if (nan_find_own_svc_by_name(subscribe_cfg->service_name)) { ESP_LOGE(TAG, "Service name already used!"); - return 0; + goto fail; } if (esp_nan_internal_subscribe_service(subscribe_cfg, &sub_id, false) != ESP_OK) { ESP_LOGE(TAG, "Failed to subscribe to service '%s'", subscribe_cfg->service_name); - return 0; + goto fail; } ESP_LOGI(TAG, "Started Subscribing to %s [Service ID - %u]", subscribe_cfg->service_name, sub_id); nan_record_own_svc(sub_id, ESP_NAN_SUBSCRIBE, subscribe_cfg->service_name, false); + NAN_DATA_UNLOCK(); return sub_id; +fail: + NAN_DATA_UNLOCK(); + return 0; } esp_err_t esp_wifi_nan_send_message(wifi_nan_followup_params_t *fup_params) { struct peer_svc_info *p_peer_svc; + NAN_DATA_LOCK(); p_peer_svc = nan_find_peer_svc(fup_params->inst_id, fup_params->peer_inst_id, fup_params->peer_mac); if (!p_peer_svc) { ESP_LOGE(TAG, "Cannot send Follow-up, peer not found!"); + NAN_DATA_UNLOCK(); return ESP_FAIL; } if (!fup_params->inst_id) { fup_params->inst_id = p_peer_svc->own_svc_id; } + if (!fup_params->peer_inst_id) { + fup_params->peer_inst_id = p_peer_svc->svc_id; + } if (!MACADDR_EQUAL(fup_params->peer_mac, null_mac)) { MACADDR_COPY(fup_params->peer_mac, p_peer_svc->peer_nmi); } + NAN_DATA_UNLOCK(); if (esp_nan_internal_send_followup(fup_params) != ESP_OK) { ESP_LOGE(TAG, "Failed to send Follow-up message!"); return ESP_FAIL; @@ -826,18 +924,19 @@ esp_err_t esp_wifi_nan_send_message(wifi_nan_followup_params_t *fup_params) esp_err_t esp_wifi_nan_cancel_service(uint8_t service_id) { + NAN_DATA_LOCK(); struct own_svc_info *p_own_svc = nan_find_own_svc(service_id); if (!p_own_svc) { ESP_LOGE(TAG, "Cannot find own service with id %d!", service_id); - return ESP_FAIL; + goto fail; } if (p_own_svc->type == ESP_NAN_PUBLISH) { if (esp_nan_internal_publish_service(NULL, &service_id, true) == ESP_OK) { nan_reset_service(service_id, false); ESP_LOGI(TAG, "Cancelled Publish with Service ID %d", service_id); - return ESP_OK; + goto done; } } @@ -845,32 +944,40 @@ esp_err_t esp_wifi_nan_cancel_service(uint8_t service_id) if (esp_nan_internal_subscribe_service(NULL, &service_id, true) == ESP_OK) { nan_reset_service(service_id, false); ESP_LOGI(TAG, "Cancelled Subscribe with Service ID %d", service_id); - return ESP_OK; + goto done; } } +fail: + NAN_DATA_UNLOCK(); return ESP_FAIL; + +done: + NAN_DATA_UNLOCK(); + return ESP_OK; } uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req) { uint8_t ndp_id = 0; + + NAN_DATA_LOCK(); struct peer_svc_info *p_peer_svc = nan_find_peer_svc(0, req->pub_id, req->peer_mac); if (!p_peer_svc) { ESP_LOGE(TAG, "Cannot send NDP Req, peer not found!"); - return 0; + goto fail; } if (req->pub_id == 0) req->pub_id = p_peer_svc->svc_id; if (p_peer_svc->type != ESP_NAN_PUBLISH) { ESP_LOGE(TAG, "Only subscriber can send an NDP Req to a Publisher"); - return 0; + goto fail; } if (ndl_limit_reached()) { ESP_LOGE(TAG, "Cannot establish new datapath, limit reached!"); - return 0; + goto fail; } if (!MACADDR_EQUAL(req->peer_mac, null_mac)) { @@ -879,9 +986,12 @@ uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req) if (esp_nan_internal_datapath_req(req, &ndp_id) != ESP_OK) { ESP_LOGE(TAG, "Failed to initiate NDP req"); - return 0; + goto fail; } + nan_record_new_ndl(ndp_id, req->pub_id, req->peer_mac, ESP_WIFI_NDP_ROLE_INITIATOR); + NAN_DATA_UNLOCK(); + ESP_LOGD(TAG, "Requested NDP with "MACSTR" [NDP ID - %d]", MAC2STR(req->peer_mac), ndp_id); EventBits_t bits = os_event_group_wait_bits(nan_event_group, NDP_ACCEPTED | NDP_REJECTED, pdFALSE, pdFALSE, pdMS_TO_TICKS(NAN_NDP_RESP_TIMEOUT)); @@ -892,22 +1002,28 @@ uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req) os_event_group_clear_bits(nan_event_group, NDP_REJECTED); return 0; } else { + NAN_DATA_LOCK(); nan_reset_ndl(ndp_id, false); + NAN_DATA_UNLOCK(); return 0; } +fail: + NAN_DATA_UNLOCK(); + return 0; } esp_err_t esp_wifi_nan_datapath_resp(wifi_nan_datapath_resp_t *resp) { + NAN_DATA_LOCK(); struct ndl_info *ndl = nan_find_ndl(resp->ndp_id, NULL); if (!ndl) { ESP_LOGE(TAG, "No NDL with ndp id %d", resp->ndp_id); - return ESP_FAIL; + goto fail; } if (!(s_nan_ctx.event & NDP_INDICATION)) { //INDICATION of specific peer ESP_LOGE(TAG, "Need NDP Indication before NDP Response can be sent"); - return ESP_FAIL; + goto fail; } if (!MACADDR_EQUAL(resp->peer_mac, null_mac)) { @@ -916,9 +1032,12 @@ esp_err_t esp_wifi_nan_datapath_resp(wifi_nan_datapath_resp_t *resp) if (esp_nan_internal_datapath_resp(resp) == ESP_OK) { s_nan_ctx.event &= ~NDP_INDICATION; + NAN_DATA_UNLOCK(); return ESP_OK; } +fail: + NAN_DATA_UNLOCK(); return ESP_FAIL; } @@ -926,20 +1045,25 @@ esp_err_t esp_wifi_nan_datapath_end(wifi_nan_datapath_end_req_t *req) { struct ndl_info *ndl = NULL; + NAN_DATA_LOCK(); if (!nan_is_datapath_active()) { ESP_LOGE(TAG, "No Datapath active"); + NAN_DATA_UNLOCK(); return ESP_FAIL; } ndl = nan_find_ndl(req->ndp_id, NULL); if (!ndl) { ESP_LOGE(TAG, "No NDL with ndp id %d", req->ndp_id); + NAN_DATA_UNLOCK(); return ESP_FAIL; } + if (!MACADDR_EQUAL(req->peer_mac, null_mac)) { MACADDR_COPY(req->peer_mac, ndl->peer_nmi); } + NAN_DATA_UNLOCK(); if (esp_nan_internal_datapath_end(req) == ESP_OK) { return ESP_OK; } @@ -956,25 +1080,30 @@ esp_err_t esp_wifi_nan_get_own_svc_info(uint8_t *own_svc_id, char *svc_name, int return ESP_FAIL; } + NAN_DATA_LOCK(); if (*own_svc_id == 0) { own_svc = nan_find_own_svc_by_name(svc_name); if (!own_svc) { ESP_LOGE(TAG, "No record found for given service name %s", svc_name); - return ESP_FAIL; + goto fail; } *own_svc_id = own_svc->svc_id; } else { own_svc = nan_find_own_svc(*own_svc_id); if (!own_svc) { ESP_LOGE(TAG, "No record found for given service ID %d", *own_svc_id); - return ESP_FAIL; + goto fail; } strlcpy(svc_name, own_svc->svc_name, ESP_WIFI_MAX_SVC_NAME_LEN); } *num_peer_records = own_svc->num_peer_records; - + NAN_DATA_UNLOCK(); return ESP_OK; + +fail: + NAN_DATA_UNLOCK(); + return ESP_FAIL; } esp_err_t esp_wifi_nan_get_peer_records(int *num_peer_records, uint8_t own_svc_id, struct nan_peer_record *peer_record) @@ -996,6 +1125,7 @@ esp_err_t esp_wifi_nan_get_peer_records(int *num_peer_records, uint8_t own_svc_i return ESP_FAIL; } + NAN_DATA_LOCK(); own_record = nan_find_own_svc(own_svc_id); if (own_record) { SLIST_FOREACH(temp, &(own_record->peer_list), next) { @@ -1031,10 +1161,13 @@ esp_err_t esp_wifi_nan_get_peer_records(int *num_peer_records, uint8_t own_svc_i if (*num_peer_records > peer_num) { *num_peer_records = peer_num; } + + NAN_DATA_UNLOCK(); return ESP_OK; } else { *num_peer_records = 0; ESP_LOGD(TAG, "No record found for own service id %d", own_svc_id); + NAN_DATA_UNLOCK(); return ESP_FAIL; } } @@ -1049,10 +1182,12 @@ esp_err_t esp_wifi_nan_get_peer_info(char *svc_name, uint8_t *peer_mac, struct n return ESP_FAIL; } + NAN_DATA_LOCK(); if (svc_name) { struct own_svc_info *own_svc = nan_find_own_svc_by_name(svc_name); if (!own_svc) { ESP_LOGE(TAG, "No record found for given service name %s", svc_name); + NAN_DATA_UNLOCK(); return ESP_FAIL; } own_svc_id = own_svc->svc_id; @@ -1073,9 +1208,11 @@ esp_err_t esp_wifi_nan_get_peer_info(char *svc_name, uint8_t *peer_mac, struct n peer_info->ndp_id = 0; MACADDR_COPY(peer_info->peer_ndi, null_mac); } + NAN_DATA_UNLOCK(); return ESP_OK; } else { ESP_LOGD(TAG, "No record found for Peer "MACSTR, MAC2STR(peer_mac)); + NAN_DATA_UNLOCK(); return ESP_FAIL; } } diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 4f3aebebc3..d509a02642 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -19,10 +19,14 @@ endif() if(NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) list(APPEND srcs "mmu_hal.c") -endif() -if(NOT ${target} STREQUAL "esp32" AND NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) - list(APPEND srcs "cache_hal.c") + # We wrap Cache ROM APIs as Cache HAL APIs for: 1. internal ram ; 2. unified APIs + # ESP32 cache structure / ROM APIs are different and we have a patch `cache_hal_esp32.c` for it. + if(${target} STREQUAL "esp32") + list(APPEND srcs "esp32/cache_hal_esp32.c") + else() + list(APPEND srcs "cache_hal.c") + endif() endif() if(CONFIG_SOC_LP_TIMER_SUPPORTED) @@ -54,7 +58,7 @@ if(NOT BOOTLOADER_BUILD) endif() if(CONFIG_SOC_GPTIMER_SUPPORTED) - list(APPEND srcs "timer_hal.c" "timer_hal_iram.c") + list(APPEND srcs "timer_hal.c") endif() if(CONFIG_SOC_LEDC_SUPPORTED) @@ -175,6 +179,16 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "ds_hal.c") endif() + if(CONFIG_SOC_USB_SERIAL_JTAG_SUPPORTED) + list(APPEND srcs "usb_serial_jtag_hal.c") + endif() + + if(CONFIG_SOC_USB_OTG_SUPPORTED) + list(APPEND srcs + "usb_dwc_hal.c" + "usb_wrap_hal.c") + endif() + if(${target} STREQUAL "esp32") list(APPEND srcs "touch_sensor_hal.c" @@ -186,24 +200,18 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "spi_flash_hal_gpspi.c" "touch_sensor_hal.c" - "usb_hal.c" - "usb_phy_hal.c" "xt_wdt_hal.c" "esp32s2/cp_dma_hal.c" - "esp32s2/touch_sensor_hal.c" - "usb_dwc_hal.c") + "esp32s2/touch_sensor_hal.c") endif() if(${target} STREQUAL "esp32s3") list(APPEND srcs "spi_flash_hal_gpspi.c" "touch_sensor_hal.c" - "usb_hal.c" - "usb_phy_hal.c" "xt_wdt_hal.c" "esp32s3/touch_sensor_hal.c" - "esp32s3/rtc_cntl_hal.c" - "usb_dwc_hal.c") + "esp32s3/rtc_cntl_hal.c") endif() if(${target} STREQUAL "esp32c3") diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 053cc5f712..fe8c01683b 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -358,3 +358,10 @@ void adc_hal_digi_stop(adc_hal_dma_ctx_t *hal) //disconnect DMA and peripheral adc_ll_digi_dma_disable(); } + +#if ADC_LL_WORKAROUND_CLEAR_EOF_COUNTER +void adc_hal_digi_clr_eof(void) +{ + adc_ll_digi_dma_clr_eof(); +} +#endif diff --git a/components/hal/adc_oneshot_hal.c b/components/hal/adc_oneshot_hal.c index a51bbeaa66..cb2d4073b1 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 */ @@ -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) { @@ -79,43 +81,52 @@ void adc_oneshot_hal_setup(adc_oneshot_hal_ctx_t *hal, adc_channel_t chan) #endif //#if SOC_ADC_ARBITER_SUPPORTED } -static void adc_hal_onetime_start(adc_unit_t unit, uint32_t clk_src_freq_hz) +static void adc_hal_onetime_start(adc_unit_t unit, uint32_t clk_src_freq_hz, uint32_t *read_delay_us) { #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: %d, digi_clk: %d, delay: %d", 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: %d", 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; + *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); +#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) { bool valid = true; uint32_t event = 0; + uint32_t read_delay_us = 0; if (hal->unit == ADC_UNIT_1) { event = ADC_LL_EVENT_ADC1_ONESHOT_DONE; } else { @@ -126,10 +137,11 @@ bool adc_oneshot_hal_convert(adc_oneshot_hal_ctx_t *hal, int *out_raw) adc_oneshot_ll_disable_all_unit(); adc_oneshot_ll_enable(hal->unit); - adc_hal_onetime_start(hal->unit, hal->clk_src_freq_hz); + adc_hal_onetime_start(hal->unit, hal->clk_src_freq_hz, &read_delay_us); while (!adc_oneshot_ll_get_event(event)) { ; } + esp_rom_delay_us(read_delay_us); *out_raw = adc_oneshot_ll_get_raw_result(hal->unit); #if (SOC_ADC_PERIPH_NUM == 2) if (hal->unit == ADC_UNIT_2) { @@ -144,6 +156,7 @@ bool adc_oneshot_hal_convert(adc_oneshot_hal_ctx_t *hal, int *out_raw) return valid; } + /*--------------------------------------------------------------- Workarounds ---------------------------------------------------------------*/ diff --git a/components/hal/brownout_hal.c b/components/hal/brownout_hal.c index c46dd2e091..b755bdb4fc 100644 --- a/components/hal/brownout_hal.c +++ b/components/hal/brownout_hal.c @@ -15,6 +15,7 @@ void brownout_hal_config(const brownout_hal_config_t *cfg) brownout_ll_set_intr_wait_cycles(2); brownout_ll_enable_flash_power_down(cfg->flash_power_down); brownout_ll_enable_rf_power_down(cfg->rf_power_down); + brownout_ll_clear_count(); brownout_ll_reset_config(cfg->reset_enabled, 0x3ff, 1); brownout_ll_set_threshold(cfg->threshold); brownout_ll_bod_enable(cfg->enabled); diff --git a/components/hal/cache_hal.c b/components/hal/cache_hal.c index e21564fce1..6447225740 100644 --- a/components/hal/cache_hal.c +++ b/components/hal/cache_hal.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 */ @@ -43,6 +43,10 @@ typedef struct { uint32_t data_autoload_flag; uint32_t inst_autoload_flag; +#if CACHE_LL_ENABLE_DISABLE_STATE_SW + // There's no register indicating if cache is enabled on these chips, use sw flag to save this state. + volatile bool cache_enabled; +#endif } cache_hal_context_t; static cache_hal_context_t ctx; @@ -66,6 +70,10 @@ void cache_hal_init(void) cache_ll_l1_enable_bus(1, CACHE_LL_DEFAULT_DBUS_MASK); cache_ll_l1_enable_bus(1, CACHE_LL_DEFAULT_IBUS_MASK); #endif + +#if CACHE_LL_ENABLE_DISABLE_STATE_SW + ctx.cache_enabled = 1; +#endif } void cache_hal_disable(cache_type_t type) @@ -82,6 +90,10 @@ void cache_hal_disable(cache_type_t type) Cache_Disable_DCache(); } #endif + +#if CACHE_LL_ENABLE_DISABLE_STATE_SW + ctx.cache_enabled = 0; +#endif } void cache_hal_enable(cache_type_t type) @@ -98,6 +110,59 @@ void cache_hal_enable(cache_type_t type) Cache_Enable_DCache(ctx.data_autoload_flag); } #endif + +#if CACHE_LL_ENABLE_DISABLE_STATE_SW + ctx.cache_enabled = 1; +#endif +} + +void cache_hal_suspend(cache_type_t type) +{ +#if SOC_SHARED_IDCACHE_SUPPORTED + Cache_Suspend_ICache(); +#else + if (type == CACHE_TYPE_DATA) { + Cache_Suspend_DCache(); + } else if (type == CACHE_TYPE_INSTRUCTION) { + Cache_Suspend_ICache(); + } else { + Cache_Suspend_ICache(); + Cache_Suspend_DCache(); + } +#endif + +#if CACHE_LL_ENABLE_DISABLE_STATE_SW + ctx.cache_enabled = 0; +#endif +} + +void cache_hal_resume(cache_type_t type) +{ +#if SOC_SHARED_IDCACHE_SUPPORTED + Cache_Resume_ICache(ctx.inst_autoload_flag); +#else + if (type == CACHE_TYPE_DATA) { + Cache_Resume_DCache(ctx.data_autoload_flag); + } else if (type == CACHE_TYPE_INSTRUCTION) { + Cache_Resume_ICache(ctx.inst_autoload_flag); + } else { + Cache_Resume_ICache(ctx.inst_autoload_flag); + Cache_Resume_DCache(ctx.data_autoload_flag); + } +#endif + +#if CACHE_LL_ENABLE_DISABLE_STATE_SW + ctx.cache_enabled = 1; +#endif +} + +bool cache_hal_is_cache_enabled(cache_type_t type) +{ +#if CACHE_LL_ENABLE_DISABLE_STATE_SW + return ctx.cache_enabled; +#else + return cache_ll_l1_is_cache_enabled(0, type); +#endif } void cache_hal_invalidate_addr(uint32_t vaddr, uint32_t size) diff --git a/components/hal/ecdsa_hal.c b/components/hal/ecdsa_hal.c index 3d8e8696e5..6d495d5279 100644 --- a/components/hal/ecdsa_hal.c +++ b/components/hal/ecdsa_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -18,21 +18,21 @@ static void configure_ecdsa_periph(ecdsa_hal_config_t *conf) ecdsa_ll_set_mode(conf->mode); ecdsa_ll_set_curve(conf->curve); - ecdsa_ll_set_k_mode(conf->k_mode); ecdsa_ll_set_z_mode(conf->sha_mode); } -void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *k, const uint8_t *hash, +bool ecdsa_hal_get_operation_result(void) +{ + return ecdsa_ll_get_operation_result(); +} + +void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *hash, uint8_t *r_out, uint8_t *s_out, uint16_t len) { if (len != ECDSA_HAL_P192_COMPONENT_LEN && len != ECDSA_HAL_P256_COMPONENT_LEN) { HAL_ASSERT(false && "Incorrect length"); } - if (conf->k_mode == ECDSA_K_USER_PROVIDED && k == NULL) { - HAL_ASSERT(false && "Mismatch in K configuration"); - } - if (conf->sha_mode == ECDSA_Z_USER_PROVIDED && hash == NULL) { HAL_ASSERT(false && "Mismatch in SHA configuration"); } @@ -98,7 +98,7 @@ int ecdsa_hal_verify_signature(ecdsa_hal_config_t *conf, const uint8_t *hash, co ; } - int res = ecdsa_ll_get_verification_result(); + bool res = ecdsa_hal_get_operation_result(); return (res ? 0 : -1); } diff --git a/components/hal/efuse_hal.c b/components/hal/efuse_hal.c index 8d94e82641..68e06d530a 100644 --- a/components/hal/efuse_hal.c +++ b/components/hal/efuse_hal.c @@ -24,7 +24,7 @@ IRAM_ATTR uint32_t efuse_hal_chip_revision(void) return efuse_hal_get_major_chip_version() * 100 + efuse_hal_get_minor_chip_version(); } -uint32_t efuse_hal_blk_version(void) +IRAM_ATTR uint32_t efuse_hal_blk_version(void) { return efuse_ll_get_blk_version_major() * 100 + efuse_ll_get_blk_version_minor(); } diff --git a/components/hal/esp32/cache_hal_esp32.c b/components/hal/esp32/cache_hal_esp32.c new file mode 100644 index 0000000000..fdfdfde6e6 --- /dev/null +++ b/components/hal/esp32/cache_hal_esp32.c @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "hal/cache_ll.h" +#include "hal/cache_hal.h" + +static uint32_t s_cache_status[2]; + +void cache_hal_suspend(cache_type_t type) +{ + s_cache_status[0] = cache_ll_l1_get_enabled_bus(0); + cache_ll_l1_disable_cache(0); +#if !CONFIG_FREERTOS_UNICORE + s_cache_status[1] = cache_ll_l1_get_enabled_bus(1); + cache_ll_l1_disable_cache(1); +#endif +} + + +void cache_hal_resume(cache_type_t type) +{ + cache_ll_l1_enable_cache(0); + cache_ll_l1_enable_bus(0, s_cache_status[0]); +#if !CONFIG_FREERTOS_UNICORE + cache_ll_l1_enable_cache(1); + cache_ll_l1_enable_bus(1, s_cache_status[1]); +#endif +} + + +bool cache_hal_is_cache_enabled(cache_type_t type) +{ + bool result = cache_ll_l1_is_cache_enabled(0, CACHE_TYPE_ALL); +#if !CONFIG_FREERTOS_UNICORE + result = result && cache_ll_l1_is_cache_enabled(1, CACHE_TYPE_ALL); +#endif + return result; +} diff --git a/components/hal/esp32/include/hal/adc_ll.h b/components/hal/esp32/include/hal/adc_ll.h index 6e5ef9bbcc..08e93a0c6d 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/esp32/include/hal/brownout_ll.h b/components/hal/esp32/include/hal/brownout_ll.h index d18fcfd245..3ebdd8ec8e 100644 --- a/components/hal/esp32/include/hal/brownout_ll.h +++ b/components/hal/esp32/include/hal/brownout_ll.h @@ -112,6 +112,15 @@ static inline void brownout_ll_intr_clear(void) RTCCNTL.int_clr.rtc_brown_out = 1; } +/** + * @brief Clear BOD internal count. + */ +static inline void brownout_ll_clear_count(void) +{ + // Not supported on esp32 +} + + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32/include/hal/cache_ll.h b/components/hal/esp32/include/hal/cache_ll.h index 6255d48a1d..2927ec941c 100644 --- a/components/hal/esp32/include/hal/cache_ll.h +++ b/components/hal/esp32/include/hal/cache_ll.h @@ -19,6 +19,66 @@ extern "C" { #endif +/** + * @brief enable a cache unit + * + * @param cache_id cache ID (when l1 cache is per core) + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_enable_cache(uint32_t cache_id) +{ + HAL_ASSERT(cache_id == 0 || cache_id == 1); + + if (cache_id == 0) { + DPORT_REG_SET_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE); + } else { + DPORT_REG_SET_BIT(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_CACHE_ENABLE); + } +} + +/** + * @brief disable a cache unit + * + * @param cache_id cache ID (when l1 cache is per core) + */ +__attribute__((always_inline)) +static inline void cache_ll_l1_disable_cache(uint32_t cache_id) +{ + if (cache_id == 0) { + while (DPORT_GET_PERI_REG_BITS2(DPORT_PRO_DCACHE_DBUG0_REG, DPORT_PRO_CACHE_STATE, DPORT_PRO_CACHE_STATE_S) != 1){ + ; + } + DPORT_REG_CLR_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE); + } else { + while (DPORT_GET_PERI_REG_BITS2(DPORT_APP_DCACHE_DBUG0_REG, DPORT_APP_CACHE_STATE, DPORT_APP_CACHE_STATE_S) != 1){ + ; + } + DPORT_REG_CLR_BIT(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_CACHE_ENABLE); + } +} + +/** + * @brief Get the status of cache if it is enabled or not + * + * @param cache_id cache ID (when l1 cache is per core) + * @param type see `cache_type_t` + * @return enabled or not + */ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_cache_enabled(uint32_t cache_id, cache_type_t type) +{ + HAL_ASSERT(cache_id == 0 || cache_id == 1); + (void) type; //On 32 it shares between I and D cache + + bool enabled; + if (cache_id == 0) { + enabled = DPORT_REG_GET_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE); + } else { + enabled = DPORT_REG_GET_BIT(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_CACHE_ENABLE); + } + return enabled; +} + /** * @brief Get the buses of a particular cache that are mapped to a virtual address range * diff --git a/components/hal/esp32/include/hal/clk_gate_ll.h b/components/hal/esp32/include/hal/clk_gate_ll.h index 8944c22ba2..799bc09b2b 100644 --- a/components/hal/esp32/include/hal/clk_gate_ll.h +++ b/components/hal/esp32/include/hal/clk_gate_ll.h @@ -228,16 +228,14 @@ static inline void periph_ll_disable_clk_set_rst(periph_module_t periph) DPORT_SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); } -static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk_clear_rst(void) +static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk(void) { DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_BT_COMMON_M); - DPORT_CLEAR_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, 0); } -static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk_set_rst(void) +static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk(void) { DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_BT_COMMON_M); - DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, 0); } static inline void periph_ll_reset(periph_module_t periph) diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index b81842de75..fecc054aaf 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.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 */ @@ -39,6 +39,39 @@ extern const uint8_t GPIO_PIN_MUX_REG_OFFSET[SOC_GPIO_PIN_COUNT]; #define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(3)) #define GPIO_LL_SDIO_EXT_INTR_ENA (BIT(4)) +/** + * @brief Get the configuration for an IO + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param pu Pull-up enabled or not + * @param pd Pull-down enabled or not + * @param ie Input enabled or not + * @param oe Output enabled or not + * @param od Open-drain enabled or not + * @param drv Drive strength value + * @param fun_sel IOMUX function selection value + * @param sig_out Outputting peripheral signal index + * @param slp_sel Pin sleep mode enabled or not + */ +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, + bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) +{ + uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); + uint32_t bit_mask = 1 << bit_shift; + uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); + *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; + *od = hw->pin[gpio_num].pad_driver; + *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; + *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; +} + /** * @brief Enable pull-up on GPIO. * @@ -669,6 +702,23 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], func); } +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + typeof(hw->func_in_sel_cfg[in_sig_idx]) reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.func_sel : -1); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32/include/hal/mcpwm_ll.h b/components/hal/esp32/include/hal/mcpwm_ll.h index 5192d7291d..9a32845e31 100644 --- a/components/hal/esp32/include/hal/mcpwm_ll.h +++ b/components/hal/esp32/include/hal/mcpwm_ll.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 */ @@ -43,8 +43,12 @@ extern "C" { #define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27)) // Maximum values due to limited register bit width +#define MCPWM_LL_MAX_GROUP_PRESCALE 256 +#define MCPWM_LL_MAX_TIMER_PRESCALE 256 +#define MCPWM_LL_MAX_CARRIER_PRESCALE 16 #define MCPWM_LL_MAX_CARRIER_ONESHOT 16 #define MCPWM_LL_MAX_CAPTURE_PRESCALE 256 +#define MCPWM_LL_MAX_CAPTURE_TIMER_PRESCALE 1 #define MCPWM_LL_MAX_DEAD_DELAY 65536 #define MCPWM_LL_MAX_COUNT_VALUE 65536 @@ -95,10 +99,11 @@ static inline void mcpwm_ll_group_enable_clock(mcpwm_dev_t *mcpwm, bool en) * @param mcpwm Peripheral instance address * @param pre_scale Prescale value */ -static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int pre_scale) +static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale) { - // group clock: PWM_clk = CLK_160M / (prescale + 1) - HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->clk_cfg, clk_prescale, pre_scale - 1); + // group clock: PWM_clk = CLK_160M / (prescale) + HAL_ASSERT(prescale <= 256 && prescale > 0); + HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->clk_cfg, clk_prescale, prescale - 1); } /** @@ -202,13 +207,12 @@ static inline void mcpwm_ll_timer_set_clock_prescale(mcpwm_dev_t *mcpwm, int tim * @param peak Peak value * @param symmetric True to set symmetric peak value, False to set asymmetric peak value */ +__attribute__((always_inline)) static inline void mcpwm_ll_timer_set_peak(mcpwm_dev_t *mcpwm, int timer_id, uint32_t peak, bool symmetric) { if (!symmetric) { // in asymmetric mode, period = [0,peak-1] - HAL_ASSERT(peak > 0 && peak <= MCPWM_LL_MAX_COUNT_VALUE); HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period, peak - 1); } else { // in symmetric mode, period = [0,peak-1] + [peak,1] - HAL_ASSERT(peak < MCPWM_LL_MAX_COUNT_VALUE); HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period, peak); } } @@ -692,20 +696,20 @@ static inline void mcpwm_ll_operator_stop_update_action(mcpwm_dev_t *mcpwm, int * @param trig_id Trigger ID, index from 0 to 1 * @param fault_gpio_id Fault GPIO ID, index from 0 to 3 */ -static inline void mcpwm_ll_operator_set_trigger_from_gpio(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_gpio_id) +static inline void mcpwm_ll_operator_set_trigger_from_gpio_fault(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_gpio_id) { mcpwm->operators[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id)); mcpwm->operators[operator_id].gen_cfg0.val |= (fault_gpio_id << (4 + 3 * trig_id)); } /** - * @brief Set trigger from timer sync event (when the timer taken the sync signal) + * @brief Set trigger from sync event (when the timer/gpio/soft taken the sync signal) * * @param mcpwm Peripheral instance address * @param operator_id Operator ID, index from 0 to 2 * @param trig_id Trigger ID, index from 0 to 1 */ -static inline void mcpwm_ll_operator_set_trigger_from_timer_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id) +static inline void mcpwm_ll_operator_set_trigger_from_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id) { // the timer here is not selectable, must be the one connected with the operator mcpwm->operators[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id)); diff --git a/components/hal/esp32/include/hal/rmt_ll.h b/components/hal/esp32/include/hal/rmt_ll.h index 68de11d8d1..0344cd7242 100644 --- a/components/hal/esp32/include/hal/rmt_ll.h +++ b/components/hal/esp32/include/hal/rmt_ll.h @@ -52,14 +52,33 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->conf_ch[0].conf0.mem_pd = enable; // Only conf0 register of channel0 has `mem_pd` + (void)dev; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->conf_ch[0].conf0.mem_pd = 1; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->conf_ch[0].conf0.mem_pd = 0; } /** @@ -84,7 +103,7 @@ static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable) * @param divider_numerator Numerator part of the divider */ static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src, - uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) + uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) { (void)divider_integral; (void)divider_denominator; @@ -368,6 +387,7 @@ static inline void rmt_ll_rx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, ui * @param channel RMT RX channel number * @param thres Time length threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->conf_ch[channel].conf0, idle_thres, thres); @@ -393,6 +413,7 @@ static inline void rmt_ll_rx_set_mem_owner(rmt_dev_t *dev, uint32_t channel, rmt * @param channel RMT RX chanenl number * @param enable True to enable, False to disable */ +__attribute__((always_inline)) static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable) { dev->conf_ch[channel].conf1.rx_filter_en = enable; @@ -405,6 +426,7 @@ static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, boo * @param channel RMT RX channel number * @param thres Filter threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->conf_ch[channel].conf1, rx_filter_thres, thres); @@ -592,7 +614,7 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->conf_ch[channel].conf1.idle_out_lv; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { // Only conf0 register of channel0 has `mem_pd` return dev->conf_ch[0].conf0.mem_pd; diff --git a/components/hal/esp32/include/hal/rtc_cntl_ll.h b/components/hal/esp32/include/hal/rtc_cntl_ll.h index 7e87d1d2ab..3c495752d3 100644 --- a/components/hal/esp32/include/hal/rtc_cntl_ll.h +++ b/components/hal/esp32/include/hal/rtc_cntl_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 */ @@ -11,6 +11,7 @@ #include "esp_attr.h" #include "clk_tree_ll.h" #include "esp_rom_sys.h" +#include "hal/assert.h" #ifdef __cplusplus extern "C" { @@ -32,11 +33,18 @@ FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_status(void) return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS); } -FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) +FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t io_mask, uint32_t mode_mask) { - REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, mask); - SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, - mode, RTC_CNTL_EXT_WAKEUP1_LV_S); + // The target only supports a unified trigger mode among all EXT1 wakeup IOs + HAL_ASSERT((io_mask & mode_mask) == io_mask || (io_mask & mode_mask) == 0); + REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, io_mask); + if ((io_mask & mode_mask) == io_mask) { + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + 1, RTC_CNTL_EXT_WAKEUP1_LV_S); + } else { + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + 0, RTC_CNTL_EXT_WAKEUP1_LV_S); + } } FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_pins(void) diff --git a/components/hal/esp32/include/hal/spi_ll.h b/components/hal/esp32/include/hal/spi_ll.h index c1fd641379..b5cad9a92a 100644 --- a/components/hal/esp32/include/hal/spi_ll.h +++ b/components/hal/esp32/include/hal/spi_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 */ @@ -41,6 +41,7 @@ extern "C" { #define SPI_LL_DMA_MAX_BIT_LEN (1 << 24) //reg len: 24 bits #define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words +#define SPI_LL_MOSI_FREE_LEVEL 0 //Default level after bus initialized /** * The data structure holding calculated clock configuration. Since the @@ -123,21 +124,21 @@ static inline bool spi_ll_usr_is_done(spi_dev_t *hw) } /** - * Trigger start of user-defined transaction for master. + * Apply the register configurations and wait until it's done * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_master_user_start(spi_dev_t *hw) +static inline void spi_ll_apply_config(spi_dev_t *hw) { - hw->cmd.usr = 1; + // 32 don't need this option } /** - * Trigger start of user-defined transaction for slave. + * Trigger start of user-defined transaction. * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_slave_user_start(spi_dev_t *hw) +static inline void spi_ll_user_start(spi_dev_t *hw) { hw->cmd.usr = 1; } diff --git a/components/hal/esp32/include/hal/timer_ll.h b/components/hal/esp32/include/hal/timer_ll.h index 63ba28801a..98cf9038f7 100644 --- a/components/hal/esp32/include/hal/timer_ll.h +++ b/components/hal/esp32/include/hal/timer_ll.h @@ -193,6 +193,7 @@ static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, * @param timer_num Timer number in the group * @return reload count value */ +__attribute__((always_inline)) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num) { return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo); @@ -204,6 +205,7 @@ static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_ * @param hw Timer Group register base address * @param timer_num Timer number in the group */ +__attribute__((always_inline)) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num) { hw->hw_timer[timer_num].load.tx_load = 1; diff --git a/components/hal/esp32/include/hal/uart_ll.h b/components/hal/esp32/include/hal/uart_ll.h index ec389a2468..3303f57093 100644 --- a/components/hal/esp32/include/hal/uart_ll.h +++ b/components/hal/esp32/include/hal/uart_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,7 +28,7 @@ extern "C" { // The timeout calibration factor when using ref_tick #define UART_LL_TOUT_REF_FACTOR_DEFAULT (8) -#define UART_LL_MIN_WAKEUP_THRESH (2) +#define UART_LL_MIN_WAKEUP_THRESH (3) #define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask // Define UART interrupts @@ -597,7 +597,9 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) */ FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) { - hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; + // System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+2) + // Note: On ESP32, the minimum UART wakeup threshold is 2 + 1 = 3 (UART_ACTIVE_THRESHOLD set to 0 leads to consecutive triggering wakeup) + hw->sleep_conf.active_threshold = wakeup_thrd - (UART_LL_MIN_WAKEUP_THRESH - 1); } /** @@ -751,7 +753,7 @@ FORCE_INLINE_ATTR void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char */ FORCE_INLINE_ATTR uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) { - return hw->sleep_conf.active_threshold + UART_LL_MIN_WAKEUP_THRESH; + return hw->sleep_conf.active_threshold + (UART_LL_MIN_WAKEUP_THRESH - 1); } /** diff --git a/components/hal/esp32c2/include/hal/adc_ll.h b/components/hal/esp32c2/include/hal/adc_ll.h index bf783bf660..4280a1adda 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/esp32c2/include/hal/brownout_ll.h b/components/hal/esp32c2/include/hal/brownout_ll.h index f44f5228c7..77b77a6968 100644 --- a/components/hal/esp32c2/include/hal/brownout_ll.h +++ b/components/hal/esp32c2/include/hal/brownout_ll.h @@ -115,6 +115,16 @@ static inline void brownout_ll_intr_clear(void) RTCCNTL.int_clr.rtc_brown_out = 1; } +/** + * @brief Clear BOD internal count. + */ +static inline void brownout_ll_clear_count(void) +{ + RTCCNTL.brown_out.cnt_clr = 1; + RTCCNTL.brown_out.cnt_clr = 0; +} + + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c2/include/hal/cache_ll.h b/components/hal/esp32c2/include/hal/cache_ll.h index b65b9d47d9..dc059bd36c 100644 --- a/components/hal/esp32c2/include/hal/cache_ll.h +++ b/components/hal/esp32c2/include/hal/cache_ll.h @@ -8,6 +8,7 @@ #pragma once +#include #include "soc/extmem_reg.h" #include "soc/ext_mem_defs.h" #include "hal/cache_types.h" @@ -34,6 +35,21 @@ extern "C" { #define CACHE_LL_L1_ILG_EVENT_PRELOAD_OP_FAULT (1<<1) #define CACHE_LL_L1_ILG_EVENT_SYNC_OP_FAULT (1<<0) +/** + * @brief Get the status of cache if it is enabled or not + * + * @param cache_id cache ID (when l1 cache is per core) + * @param type see `cache_type_t` + * @return enabled or not + */ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_cache_enabled(uint32_t cache_id, cache_type_t type) +{ + HAL_ASSERT(cache_id == 0); + (void) type; // On C2 there's only ICache + return REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); +} + /** * @brief Get the buses of a particular cache that are mapped to a virtual address range * diff --git a/components/hal/esp32c2/include/hal/clk_gate_ll.h b/components/hal/esp32c2/include/hal/clk_gate_ll.h index 522efa77ff..6a9eb68880 100644 --- a/components/hal/esp32c2/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c2/include/hal/clk_gate_ll.h @@ -166,16 +166,14 @@ static inline void periph_ll_disable_clk_set_rst(periph_module_t periph) DPORT_SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); } -static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk_clear_rst(void) +static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk(void) { DPORT_SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M); - DPORT_CLEAR_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } -static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk_set_rst(void) +static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk(void) { DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M); - DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } static inline void periph_ll_reset(periph_module_t periph) diff --git a/components/hal/esp32c2/include/hal/ecc_ll.h b/components/hal/esp32c2/include/hal/ecc_ll.h index 8a7c57a04a..214dd8e676 100644 --- a/components/hal/esp32c2/include/hal/ecc_ll.h +++ b/components/hal/esp32c2/include/hal/ecc_ll.h @@ -20,6 +20,9 @@ typedef enum { ECC_PARAM_K, } ecc_ll_param_t; +static inline void ecc_ll_power_up(void) {} +static inline void ecc_ll_power_down(void) {} + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32c2/include/hal/gpio_ll.h b/components/hal/esp32c2/include/hal/gpio_ll.h index 9672ac9679..3954fb31ff 100644 --- a/components/hal/esp32c2/include/hal/gpio_ll.h +++ b/components/hal/esp32c2/include/hal/gpio_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 */ @@ -31,6 +31,39 @@ extern "C" { #define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0)) #define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1)) + +/** + * @brief Get the configuration for an IO + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param pu Pull-up enabled or not + * @param pd Pull-down enabled or not + * @param ie Input enabled or not + * @param oe Output enabled or not + * @param od Open-drain enabled or not + * @param drv Drive strength value + * @param fun_sel IOMUX function selection value + * @param sig_out Outputting peripheral signal index + * @param slp_sel Pin sleep mode enabled or not + */ +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, + bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) +{ + uint32_t bit_mask = 1 << gpio_num; + uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); + *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + *oe = (hw->enable.val & bit_mask) >> gpio_num; + *od = hw->pin[gpio_num].pad_driver; + *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; + *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; +} + /** * @brief Enable pull-up on GPIO. * @@ -475,6 +508,23 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], func); } +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.func_sel : -1); +} + /** * @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32c2/include/hal/spi_ll.h b/components/hal/esp32c2/include/hal/spi_ll.h index f1da30f627..b4671f252c 100644 --- a/components/hal/esp32c2/include/hal/spi_ll.h +++ b/components/hal/esp32c2/include/hal/spi_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 */ @@ -40,6 +40,7 @@ extern "C" { #define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits #define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words +#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized /** * The data structure holding calculated clock configuration. Since the @@ -186,36 +187,44 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw) } /** - * Check whether user-defined transaction is done. + * Determine and unify the default level of mosi line when bus free * * @param hw Beginning address of the peripheral registers. - * - * @return True if transaction is done, otherwise false. */ -static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level) { - return hw->dma_int_raw.trans_done; + hw->ctrl.d_pol = level; //set default level for MOSI only on IDLE state } /** - * Trigger start of user-defined transaction for master. - * The synchronization between two clock domains is required in ESP32-S3 + * Apply the register configurations and wait until it's done * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_master_user_start(spi_dev_t *hw) +static inline void spi_ll_apply_config(spi_dev_t *hw) { hw->cmd.update = 1; - while (hw->cmd.update); - hw->cmd.usr = 1; + while (hw->cmd.update); //waiting config applied +} + +/** + * Check whether user-defined transaction is done. + * + * @param hw Beginning address of the peripheral registers. + * + * @return True if transaction is done, otherwise false. + */ +static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +{ + return hw->dma_int_raw.trans_done; } /** - * Trigger start of user-defined transaction for slave. + * Trigger start of user-defined transaction. * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_slave_user_start(spi_dev_t *hw) +static inline void spi_ll_user_start(spi_dev_t *hw) { hw->cmd.usr = 1; } diff --git a/components/hal/esp32c2/include/hal/timer_ll.h b/components/hal/esp32c2/include/hal/timer_ll.h index f77d5fc641..7336306f71 100644 --- a/components/hal/esp32c2/include/hal/timer_ll.h +++ b/components/hal/esp32c2/include/hal/timer_ll.h @@ -193,6 +193,7 @@ static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, * @param timer_num Timer number in the group * @return reload count value */ +__attribute__((always_inline)) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num) { return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo); @@ -204,6 +205,7 @@ static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_ * @param hw Timer Group register base address * @param timer_num Timer number in the group */ +__attribute__((always_inline)) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num) { hw->hw_timer[timer_num].load.tx_load = 1; diff --git a/components/hal/esp32c2/include/hal/uart_ll.h b/components/hal/esp32c2/include/hal/uart_ll.h index 1526b5f7cf..1db9fbaca4 100644 --- a/components/hal/esp32c2/include/hal/uart_ll.h +++ b/components/hal/esp32c2/include/hal/uart_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 */ @@ -7,12 +7,13 @@ // The LL layer for UART register operations. // Note that most of the register operations in this layer are non-atomic operations. - #pragma once +#include #include "hal/uart_types.h" #include "soc/uart_periph.h" #include "hal/clk_tree_ll.h" +#include "hal/misc.h" #include "esp_attr.h" #include "hal/misc.h" #include "soc/system_struct.h" @@ -28,7 +29,7 @@ extern "C" { // Get UART hardware instance with giving uart num #define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1)) -#define UART_LL_MIN_WAKEUP_THRESH (2) +#define UART_LL_MIN_WAKEUP_THRESH (3) #define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask #define UART_LL_FSM_IDLE (0x0) @@ -178,14 +179,16 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint3 { #define DIV_UP(a, b) (((a) + (b) - 1) / (b)) const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits - int sclk_div = DIV_UP(sclk_freq, max_div * baud); + uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud); + + if (sclk_div == 0) abort(); uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div); // The baud rate configuration register is divided into // an integer part and a fractional part. hw->clk_div.div_int = clk_div >> 4; - hw->clk_div.div_frag = clk_div & 0xf; - hw->clk_conf.sclk_div_num = sclk_div - 1; + hw->clk_div.div_frag = clk_div & 0xf; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1); #undef DIV_UP } @@ -201,7 +204,8 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_fr { typeof(hw->clk_div) div_reg; div_reg.val = hw->clk_div.val; - return ((sclk_freq << 4)) / (((div_reg.div_int << 4) | div_reg.div_frag) * (hw->clk_conf.sclk_div_num + 1)); + return ((sclk_freq << 4)) / + (((div_reg.div_int << 4) | div_reg.div_frag) * (HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1)); } /** @@ -486,7 +490,7 @@ FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num FORCE_INLINE_ATTR void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) { if (break_num > 0) { - hw->txbrk_conf.tx_brk_num = break_num; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->txbrk_conf, tx_brk_num, break_num); hw->conf0.txd_brk = 1; } else { hw->conf0.txd_brk = 0; @@ -553,8 +557,8 @@ FORCE_INLINE_ATTR void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl hw->flow_conf.sw_flow_con_en = 1; hw->swfc_conf1.xon_threshold = flow_ctrl->xon_thrd; hw->swfc_conf0.xoff_threshold = flow_ctrl->xoff_thrd; - hw->swfc_conf1.xon_char = flow_ctrl->xon_char; - hw->swfc_conf0.xoff_char = flow_ctrl->xoff_char; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf1, xon_char, flow_ctrl->xon_char); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0, xoff_char, flow_ctrl->xoff_char); } else { hw->flow_conf.sw_flow_con_en = 0; hw->flow_conf.xonoff_del = 0; @@ -576,11 +580,11 @@ FORCE_INLINE_ATTR void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl */ FORCE_INLINE_ATTR void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char) { - hw->at_cmd_char.data = cmd_char->cmd_char; - hw->at_cmd_char.char_num = cmd_char->char_num; - hw->at_cmd_postcnt.post_idle_num = cmd_char->post_idle; - hw->at_cmd_precnt.pre_idle_num = cmd_char->pre_idle; - hw->at_cmd_gaptout.rx_gap_tout = cmd_char->gap_tout; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char, data, cmd_char->cmd_char); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char, char_num, cmd_char->char_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_postcnt, post_idle_num, cmd_char->post_idle); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_precnt, pre_idle_num, cmd_char->pre_idle); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_gaptout, rx_gap_tout, cmd_char->gap_tout); } /** @@ -633,6 +637,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) */ FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) { + // System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3) hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; } @@ -781,8 +786,8 @@ FORCE_INLINE_ATTR void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) */ FORCE_INLINE_ATTR void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num) { - *cmd_char = hw->at_cmd_char.data; - *char_num = hw->at_cmd_char.char_num; + *cmd_char = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char, data); + *char_num = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char, char_num); } /** diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index 717cfa4563..4fb9a95b47 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -38,6 +38,7 @@ extern "C" { Oneshot ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (0) /*--------------------------------------------------------------- DMA @@ -55,6 +56,13 @@ extern "C" { #define ADC_LL_DEFAULT_CONV_LIMIT_EN 0 #define ADC_LL_DEFAULT_CONV_LIMIT_NUM 10 +/** + * Workaround: on ESP32C3, the internal hardware counter that counts ADC samples will not be automatically cleared, + * and there is no dedicated register to manually clear it. (see section 3.2 of the errata document). + * Therefore, traverse from 0 to the value configured last time, so as to clear the ADC sample counter. + */ +#define ADC_LL_WORKAROUND_CLEAR_EOF_COUNTER (1) + /*--------------------------------------------------------------- PWDET (Power Detect) ---------------------------------------------------------------*/ @@ -436,6 +444,18 @@ static inline void adc_ll_digi_dma_set_eof_num(uint32_t num) HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.dma_conf, apb_adc_eof_num, num); } +/** + * Clear ADC sample counter of adc digital controller. + */ +static inline void adc_ll_digi_dma_clr_eof(void) +{ + uint32_t eof_num = HAL_FORCE_READ_U32_REG_FIELD(APB_SARADC.dma_conf, apb_adc_eof_num); + for (int i = 0; i <= eof_num; i++) + { + HAL_FORCE_MODIFY_U32_REG_FIELD(APB_SARADC.dma_conf, apb_adc_eof_num, i); + } +} + /** * Enable output data to DMA from adc digital controller. */ diff --git a/components/hal/esp32c3/include/hal/brownout_ll.h b/components/hal/esp32c3/include/hal/brownout_ll.h index d415ebed53..4a60eb4424 100644 --- a/components/hal/esp32c3/include/hal/brownout_ll.h +++ b/components/hal/esp32c3/include/hal/brownout_ll.h @@ -115,6 +115,15 @@ static inline void brownout_ll_intr_clear(void) RTCCNTL.int_clr.rtc_brown_out = 1; } +/** + * @brief Clear BOD internal count. + */ +static inline void brownout_ll_clear_count(void) +{ + RTCCNTL.brown_out.cnt_clr = 1; + RTCCNTL.brown_out.cnt_clr = 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c3/include/hal/cache_ll.h b/components/hal/esp32c3/include/hal/cache_ll.h index 8ba372d3af..a2bea9ef6e 100644 --- a/components/hal/esp32c3/include/hal/cache_ll.h +++ b/components/hal/esp32c3/include/hal/cache_ll.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 */ @@ -8,6 +8,7 @@ #pragma once +#include #include "soc/extmem_reg.h" #include "soc/ext_mem_defs.h" #include "hal/cache_types.h" @@ -35,6 +36,21 @@ extern "C" { #define CACHE_LL_L1_ILG_EVENT_SYNC_OP_FAULT (1<<0) +/** + * @brief Get the status of cache if it is enabled or not + * + * @param cache_id cache ID (when l1 cache is per core) + * @param type see `cache_type_t` + * @return enabled or not + */ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_cache_enabled(uint32_t cache_id, cache_type_t type) +{ + HAL_ASSERT(cache_id == 0); + (void) type; // On C3 there's only ICache + return REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); +} + /** * @brief Get the buses of a particular cache that are mapped to a virtual address range * diff --git a/components/hal/esp32c3/include/hal/clk_gate_ll.h b/components/hal/esp32c3/include/hal/clk_gate_ll.h index 8f8526e1a9..f3cbf17567 100644 --- a/components/hal/esp32c3/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c3/include/hal/clk_gate_ll.h @@ -215,16 +215,14 @@ static inline void periph_ll_disable_clk_set_rst(periph_module_t periph) DPORT_SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); } -static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk_clear_rst(void) +static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk(void) { DPORT_SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M); - DPORT_CLEAR_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } -static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk_set_rst(void) +static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk(void) { DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M); - DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } static inline void periph_ll_reset(periph_module_t periph) diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index e14d5d4cc6..726207f105 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,6 +33,39 @@ extern "C" { #define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0)) #define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1)) + +/** + * @brief Get the configuration for an IO + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param pu Pull-up enabled or not + * @param pd Pull-down enabled or not + * @param ie Input enabled or not + * @param oe Output enabled or not + * @param od Open-drain enabled or not + * @param drv Drive strength value + * @param fun_sel IOMUX function selection value + * @param sig_out Outputting peripheral signal index + * @param slp_sel Pin sleep mode enabled or not + */ +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, + bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) +{ + uint32_t bit_mask = 1 << gpio_num; + uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); + *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + *oe = (hw->enable.val & bit_mask) >> gpio_num; + *od = hw->pin[gpio_num].pad_driver; + *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; + *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; +} + /** * @brief Enable pull-up on GPIO. * @@ -347,7 +380,12 @@ static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength) { - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, strength, FUN_DRV_S); + uint32_t drv_cap = (uint32_t)strength; + // DRV = 1 and DRV = 2 register bits are flipped for IO2, IO3, IO4, IO5, IO18, IO19 on the target + if (gpio_num == 2 || gpio_num == 3 || gpio_num == 4 || gpio_num == 5 || gpio_num == 18 || gpio_num == 19) { + drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1 + } + SET_PERI_REG_BITS(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, drv_cap, FUN_DRV_S); } /** @@ -359,7 +397,12 @@ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu */ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength) { - *strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, FUN_DRV_S); + uint32_t drv_cap = GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S); + // DRV = 1 and DRV = 2 register bits are flipped for IO2, IO3, IO4, IO5, IO18, IO19 on the target + if (gpio_num == 2 || gpio_num == 3 || gpio_num == 4 || gpio_num == 5 || gpio_num == 18 || gpio_num == 19) { + drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1 + } + *strength = (gpio_drive_cap_t)drv_cap; } /** @@ -491,6 +534,23 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], func); } +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + typeof(hw->func_in_sel_cfg[in_sig_idx]) reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.func_sel : -1); +} + /** * @brief Force hold all digital(VDD3P3_CPU) and rtc(VDD3P3_RTC) gpio pads. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32c3/include/hal/mwdt_ll.h b/components/hal/esp32c3/include/hal/mwdt_ll.h index 89b441c47d..35bb23c587 100644 --- a/components/hal/esp32c3/include/hal/mwdt_ll.h +++ b/components/hal/esp32c3/include/hal/mwdt_ll.h @@ -24,7 +24,7 @@ extern "C" { #include "hal/misc.h" /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ -#define MWDT_LL_DEFAULT_CLK_PRESCALER 40000 +#define MWDT_LL_DEFAULT_CLK_PRESCALER 20000 //Type check wdt_stage_action_t ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); diff --git a/components/hal/esp32c3/include/hal/rmt_ll.h b/components/hal/esp32c3/include/hal/rmt_ll.h index 1c3c4c907f..121a9758fe 100644 --- a/components/hal/esp32c3/include/hal/rmt_ll.h +++ b/components/hal/esp32c3/include/hal/rmt_ll.h @@ -54,15 +54,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -438,6 +459,7 @@ static inline void rmt_ll_rx_set_channel_clock_div(rmt_dev_t *dev, uint32_t chan * @param dev Peripheral instance address * @param channel RMT RX channel number */ +__attribute__((always_inline)) static inline void rmt_ll_rx_reset_pointer(rmt_dev_t *dev, uint32_t channel) { dev->rx_conf[channel].conf1.mem_wr_rst = 1; @@ -480,6 +502,7 @@ static inline void rmt_ll_rx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, ui * @param channel RMT RX channel number * @param thres Time length threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { dev->rx_conf[channel].conf0.idle_thres = thres; @@ -505,6 +528,7 @@ static inline void rmt_ll_rx_set_mem_owner(rmt_dev_t *dev, uint32_t channel, rmt * @param channel RMT RX chanenl number * @param enable True to enable, False to disable */ +__attribute__((always_inline)) static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable) { dev->rx_conf[channel].conf1.rx_filter_en = enable; @@ -517,6 +541,7 @@ static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, boo * @param channel RMT RX channel number * @param thres Filter threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rx_conf[channel].conf1, rx_filter_thres, thres); @@ -775,12 +800,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->tx_conf[channel].idle_out_lv; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32c3/include/hal/spi_ll.h b/components/hal/esp32c3/include/hal/spi_ll.h index 140795c5f0..abaa821049 100644 --- a/components/hal/esp32c3/include/hal/spi_ll.h +++ b/components/hal/esp32c3/include/hal/spi_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 */ @@ -40,6 +40,7 @@ extern "C" { #define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits #define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words +#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized /** * The data structure holding calculated clock configuration. Since the @@ -186,36 +187,44 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw) } /** - * Check whether user-defined transaction is done. + * Determine and unify the default level of mosi line when bus free * * @param hw Beginning address of the peripheral registers. - * - * @return True if transaction is done, otherwise false. */ -static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level) { - return hw->dma_int_raw.trans_done; + hw->ctrl.d_pol = level; //set default level for MOSI only on IDLE state } /** - * Trigger start of user-defined transaction for master. - * The synchronization between two clock domains is required in ESP32-S3 + * Apply the register configurations and wait until it's done * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_master_user_start(spi_dev_t *hw) +static inline void spi_ll_apply_config(spi_dev_t *hw) { hw->cmd.update = 1; - while (hw->cmd.update); - hw->cmd.usr = 1; + while (hw->cmd.update); //waiting config applied +} + +/** + * Check whether user-defined transaction is done. + * + * @param hw Beginning address of the peripheral registers. + * + * @return True if transaction is done, otherwise false. + */ +static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +{ + return hw->dma_int_raw.trans_done; } /** - * Trigger start of user-defined transaction for slave. + * Trigger start of user-defined transaction. * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_slave_user_start(spi_dev_t *hw) +static inline void spi_ll_user_start(spi_dev_t *hw) { hw->cmd.usr = 1; } diff --git a/components/hal/esp32c3/include/hal/temperature_sensor_ll.h b/components/hal/esp32c3/include/hal/temperature_sensor_ll.h index 45d653212c..4dac4061ae 100644 --- a/components/hal/esp32c3/include/hal/temperature_sensor_ll.h +++ b/components/hal/esp32c3/include/hal/temperature_sensor_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 */ diff --git a/components/hal/esp32c3/include/hal/timer_ll.h b/components/hal/esp32c3/include/hal/timer_ll.h index 2c9ed9395d..817387ceba 100644 --- a/components/hal/esp32c3/include/hal/timer_ll.h +++ b/components/hal/esp32c3/include/hal/timer_ll.h @@ -193,6 +193,7 @@ static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, * @param timer_num Timer number in the group * @return reload count value */ +__attribute__((always_inline)) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num) { return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo); @@ -204,6 +205,7 @@ static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_ * @param hw Timer Group register base address * @param timer_num Timer number in the group */ +__attribute__((always_inline)) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num) { hw->hw_timer[timer_num].load.tx_load = 1; diff --git a/components/hal/esp32c3/include/hal/uart_ll.h b/components/hal/esp32c3/include/hal/uart_ll.h index 6efda04762..f39b0ba948 100644 --- a/components/hal/esp32c3/include/hal/uart_ll.h +++ b/components/hal/esp32c3/include/hal/uart_ll.h @@ -10,6 +10,7 @@ #pragma once +#include #include "hal/misc.h" #include "hal/uart_types.h" #include "soc/uart_periph.h" @@ -28,7 +29,7 @@ extern "C" { // Get UART hardware instance with giving uart num #define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1)) -#define UART_LL_MIN_WAKEUP_THRESH (2) +#define UART_LL_MIN_WAKEUP_THRESH (3) #define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask #define UART_LL_FSM_IDLE (0x0) @@ -178,13 +179,15 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint3 { #define DIV_UP(a, b) (((a) + (b) - 1) / (b)) const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits - int sclk_div = DIV_UP(sclk_freq, max_div * baud); + uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud); + + if (sclk_div == 0) abort(); uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div); // The baud rate configuration register is divided into // an integer part and a fractional part. hw->clk_div.div_int = clk_div >> 4; - hw->clk_div.div_frag = clk_div & 0xf; + hw->clk_div.div_frag = clk_div & 0xf; HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1); #undef DIV_UP } @@ -633,6 +636,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) */ FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) { + // System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3) hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; } diff --git a/components/hal/esp32c3/include/hal/usb_phy_ll.h b/components/hal/esp32c3/include/hal/usb_phy_ll.h deleted file mode 100644 index 40d4cd1800..0000000000 --- a/components/hal/esp32c3/include/hal/usb_phy_ll.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include "soc/usb_serial_jtag_struct.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configures the internal PHY for USB_Serial_JTAG - * - * @param hw Start address of the USB Serial_JTAG registers - */ -static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) -{ - // USB_Serial_JTAG use internal PHY - hw->conf0.phy_sel = 0; - // Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1) - hw->conf0.pad_pull_override = 0; - // Enable USB D+ pullup - hw->conf0.dp_pullup = 1; - // Enable USB pad function - hw->conf0.usb_pad_enable = 1; -} - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h index 0a6e382efd..ac5cd14865 100644 --- a/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32c3/include/hal/usb_serial_jtag_ll.h @@ -1,23 +1,21 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -// The LL layer of the USB-serial-jtag controller - #pragma once + +#include +#include "esp_attr.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" +#include "soc/system_struct.h" +#include "hal/usb_serial_jtag_types.h" -#ifdef __cplusplus -extern "C" { -#endif - -//The in and out endpoints are this long. -#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64 +/* ----------------------------- Macros & Types ----------------------------- */ -#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask +#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging @@ -31,6 +29,13 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_ll_intr_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------- USJ Peripheral ----------------------------- */ + /** * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @@ -120,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len) * is room in the buffer. * * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return Amount of bytes actually written. May be less than wr_len. */ @@ -158,8 +163,14 @@ static inline int usb_serial_jtag_ll_txfifo_writable(void) * @brief Flushes the TX buffer, that is, make it available for the * host to pick up. * - * @note When fifo is full (with 64 byte), HW will flush the buffer automatically. - * It won't be executed if there is nothing in the fifo. + * @note When fifo is full (with 64 byte), HW will flush the buffer automatically, + * if this function is called directly after, this effectively turns into a + * no-op. Because a 64-byte packet will be interpreted as a not-complete USB + * transaction, you need to transfer either more data or a zero-length packet + * for the data to actually end up at the program listening to the CDC-ACM + * serial port. To send a zero-length packet, call + * usb_serial_jtag_ll_txfifo_flush() again when + * usb_serial_jtag_ll_txfifo_writable() returns true. * * @return na */ @@ -168,6 +179,141 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) USB_SERIAL_JTAG.ep1_conf.wr_done=1; } +/* ---------------------------- USB PHY Control ---------------------------- */ + +/** + * @brief Sets PHY defaults + * + * Some PHY register fields/features of the USJ are redundant on the ESP32-C3. + * This function those fields are set to the appropriate default values. + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void) +{ + // External FSLS PHY is not supported + USB_SERIAL_JTAG.conf0.phy_sel = 0; + USB_SERIAL_JTAG.conf0.usb_pad_enable = 1; +} + +/** + * @brief Enables/disables exchanging of the D+/D- pins USB PHY + * + * @param enable Enables pin exchange, disabled otherwise + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable) +{ + if (enable) { + USB_SERIAL_JTAG.conf0.exchg_pins = 1; + USB_SERIAL_JTAG.conf0.exchg_pins_override = 1; + } else { + USB_SERIAL_JTAG.conf0.exchg_pins_override = 0; + USB_SERIAL_JTAG.conf0.exchg_pins = 0; + } +} + +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_vref_override(unsigned int vrefh_step, unsigned int vrefl_step) +{ + USB_SERIAL_JTAG.conf0.vrefh = vrefh_step; + USB_SERIAL_JTAG.conf0.vrefl = vrefl_step; + USB_SERIAL_JTAG.conf0.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) +{ + USB_SERIAL_JTAG.conf0.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param vals Override values to set + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals) +{ + USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd; + USB_SERIAL_JTAG.conf0.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_pull_override(void) +{ + USB_SERIAL_JTAG.conf0.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_pullup_strength(bool strong) +{ + USB_SERIAL_JTAG.conf0.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_phy_is_pad_enabled(void) +{ + return USB_SERIAL_JTAG.conf0.usb_pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + +/** + * @brief Enable the bus clock for USJ module + * @param clk_en True if enable the clock of USJ module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) +{ + SYSTEM.perip_clk_en0.reg_usb_device_clk_en = clk_en; +} + +/** + * @brief Reset the USJ module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.reg_usb_device_rst = 1; + SYSTEM.perip_rst_en0.reg_usb_device_rst = 0; +} + +/** + * Get the enable status of the USJ module + * + * @return Return true if USJ module is enabled + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void) +{ + return (SYSTEM.perip_clk_en0.reg_usb_device_clk_en && !SYSTEM.perip_rst_en0.reg_usb_device_rst); +} #ifdef __cplusplus } diff --git a/components/hal/esp32c6/include/hal/adc_ll.h b/components/hal/esp32c6/include/hal/adc_ll.h index 2d95138380..afb3934dd1 100644 --- a/components/hal/esp32c6/include/hal/adc_ll.h +++ b/components/hal/esp32c6/include/hal/adc_ll.h @@ -39,6 +39,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/brownout_ll.h b/components/hal/esp32c6/include/hal/brownout_ll.h index e0614583a4..bf3edeb49a 100644 --- a/components/hal/esp32c6/include/hal/brownout_ll.h +++ b/components/hal/esp32c6/include/hal/brownout_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -115,6 +115,15 @@ static inline void brownout_ll_intr_clear(void) LP_ANA_PERI.int_clr.bod_mode0 = 1; } +/** + * @brief Clear BOD internal count. + */ +static inline void brownout_ll_clear_count(void) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 1; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/cache_ll.h b/components/hal/esp32c6/include/hal/cache_ll.h index c135c5a8d4..82769b32d9 100644 --- a/components/hal/esp32c6/include/hal/cache_ll.h +++ b/components/hal/esp32c6/include/hal/cache_ll.h @@ -16,7 +16,7 @@ #ifdef __cplusplus extern "C" { #endif - +#define CACHE_LL_ENABLE_DISABLE_STATE_SW 1 //There's no register indicating cache enable/disable state, we need to use software way for this state. #define CACHE_LL_DEFAULT_IBUS_MASK CACHE_BUS_IBUS0 #define CACHE_LL_DEFAULT_DBUS_MASK CACHE_BUS_DBUS0 diff --git a/components/hal/esp32c6/include/hal/clk_gate_ll.h b/components/hal/esp32c6/include/hal/clk_gate_ll.h index e3a1e18248..27dfd48160 100644 --- a/components/hal/esp32c6/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c6/include/hal/clk_gate_ll.h @@ -97,7 +97,7 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en switch (periph) { case PERIPH_SARADC_MODULE: - return PCR_SARADC_RST_EN; + return PCR_SARADC_REG_RST_EN; case PERIPH_RMT_MODULE: return PCR_RMT_RST_EN; case PERIPH_PCNT_MODULE: diff --git a/components/hal/esp32c6/include/hal/ecc_ll.h b/components/hal/esp32c6/include/hal/ecc_ll.h index 9df9655e5d..8e58e7b05b 100644 --- a/components/hal/esp32c6/include/hal/ecc_ll.h +++ b/components/hal/esp32c6/include/hal/ecc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,8 @@ #include #include "hal/assert.h" #include "soc/ecc_mult_reg.h" +#include "soc/pcr_struct.h" +#include "soc/pcr_reg.h" #ifdef __cplusplus extern "C" { @@ -20,6 +22,18 @@ typedef enum { ECC_PARAM_K, } ecc_ll_param_t; +static inline void ecc_ll_power_up(void) +{ + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD); +} + +static inline void ecc_ll_power_down(void) +{ + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PU); + REG_SET_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); +} + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32c6/include/hal/efuse_ll.h b/components/hal/esp32c6/include/hal/efuse_ll.h index d9a10ba584..62db27f6d1 100644 --- a/components/hal/esp32c6/include/hal/efuse_ll.h +++ b/components/hal/esp32c6/include/hal/efuse_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,15 @@ extern "C" { #endif +typedef enum { + EFUSE_CONTROLLER_STATE_RESET = 0, ///< efuse_controllerid is on reset state. + EFUSE_CONTROLLER_STATE_IDLE = 1, ///< efuse_controllerid is on idle state. + EFUSE_CONTROLLER_STATE_READ_INIT = 2, ///< efuse_controllerid is on read init state. + EFUSE_CONTROLLER_STATE_READ_BLK0 = 3, ///< efuse_controllerid is on reading block0 state. + EFUSE_CONTROLLER_STATE_BLK0_CRC_CHECK = 4, ///< efuse_controllerid is on checking block0 crc state. + EFUSE_CONTROLLER_STATE_READ_RS_BLK = 5, ///< efuse_controllerid is on reading RS block state. +} efuse_controller_state_t; + // Always inline these functions even no gcc optimization is applied. /******************* eFuse fields *************************/ @@ -62,6 +71,41 @@ __attribute__((always_inline)) static inline bool efuse_ll_get_disable_wafer_ver return EFUSE.rd_repeat_data4.disable_wafer_version_major; } +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_active_hp_dbias(void) +{ + return EFUSE.rd_mac_spi_sys_2.active_hp_dbias; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_active_lp_dbias(void) +{ + return EFUSE.rd_mac_spi_sys_2.active_lp_dbias; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_lslp_dbg(void) +{ + return EFUSE.rd_mac_spi_sys_2.lslp_hp_dbg; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_lslp_hp_dbias(void) +{ + return EFUSE.rd_mac_spi_sys_2.lslp_hp_dbias; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_dslp_dbg(void) +{ + return EFUSE.rd_mac_spi_sys_2.dslp_lp_dbg; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_dslp_lp_dbias(void) +{ + return EFUSE.rd_mac_spi_sys_2.dslp_lp_dbias; +} + +__attribute__((always_inline)) static inline int32_t efuse_ll_get_dbias_vol_gap(void) +{ + return EFUSE.rd_mac_spi_sys_2.dbias_vol_gap; +} + __attribute__((always_inline)) static inline uint32_t efuse_ll_get_blk_version_major(void) { return EFUSE.rd_mac_spi_sys_3.blk_version_major; @@ -140,6 +184,11 @@ __attribute__((always_inline)) static inline void efuse_ll_set_pwr_off_num(uint1 EFUSE.wr_tim_conf2.pwr_off_num = value; } +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_state(void) +{ + return EFUSE.status.state; +} + /******************* eFuse control functions *************************/ #ifdef __cplusplus diff --git a/components/hal/esp32c6/include/hal/etm_ll.h b/components/hal/esp32c6/include/hal/etm_ll.h index 9d95b485c2..535a94eb2e 100644 --- a/components/hal/esp32c6/include/hal/etm_ll.h +++ b/components/hal/esp32c6/include/hal/etm_ll.h @@ -11,6 +11,7 @@ #include #include "hal/assert.h" #include "hal/misc.h" +#include "hal/lp_aon_ll.h" #include "soc/soc_etm_struct.h" #ifdef __cplusplus @@ -98,6 +99,10 @@ static inline void etm_ll_channel_set_task(soc_etm_dev_t *hw, uint32_t chan, uin hw->channel[chan].task_id.task_id = task; } +#define etm_ll_is_lpcore_wakeup_triggered() lp_aon_ll_get_lpcore_etm_wakeup_flag() + +#define etm_ll_clear_lpcore_wakeup_status() lp_aon_ll_clear_lpcore_etm_wakeup_flag() + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/gdma_ll.h b/components/hal/esp32c6/include/hal/gdma_ll.h index 57969ca513..71fc0e58e5 100644 --- a/components/hal/esp32c6/include/hal/gdma_ll.h +++ b/components/hal/esp32c6/include/hal/gdma_ll.h @@ -17,6 +17,8 @@ extern "C" { #endif +#define GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 + (SOC_GDMA_PAIRS_PER_GROUP * group_id) + pair_id) + #define GDMA_LL_GET_HW(id) (((id) == 0) ? (&GDMA) : NULL) #define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5] diff --git a/components/hal/esp32c6/include/hal/gpio_etm_ll.h b/components/hal/esp32c6/include/hal/gpio_etm_ll.h index 6d380b27ae..0f9f42ffff 100644 --- a/components/hal/esp32c6/include/hal/gpio_etm_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_etm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,15 +22,20 @@ #define GPIO_LL_ETM_TASK_ID_CLR(ch) (GPIO_TASK_CH0_CLEAR + (ch)) #define GPIO_LL_ETM_TASK_ID_TOG(ch) (GPIO_TASK_CH0_TOGGLE + (ch)) +#define GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP 8 +#define GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP 8 + #ifdef __cplusplus extern "C" { #endif /** - * @brief Set which GPIO to be bounded to the event channel + * @brief Set which GPIO to be bound to the event channel + * + * @note Different channels can be bound to one GPIO * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Event channel number * @param gpio_num GPIO number */ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint32_t chan, uint32_t gpio_num) @@ -39,10 +44,10 @@ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint3 } /** - * @brief Wether to enable the event channel + * @brief Whether to enable the event channel * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Event channel number * @param enable True to enable, false to disable */ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_t chan, bool enable) @@ -51,12 +56,24 @@ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_ } /** - * @brief Set which GPIO to be bounded to the task channel + * @brief Get which GPIO is bound to the event channel + * + * @param dev Register base address + * @param chan GPIO ETM Event channel number + * @return GPIO number + */ +static inline uint32_t gpio_ll_etm_event_channel_get_gpio(gpio_etm_dev_t *dev, uint32_t chan) +{ + return dev->event_chn_cfg[chan].etm_ch0_event_sel; +} + +/** + * @brief Set which GPIO to be bound to the task channel * - * @note One channel can be bounded to multiple different GPIOs + * @note One channel can be bound to multiple different GPIOs * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Task channel number * @param gpio_num GPIO number */ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num, uint32_t chan) @@ -70,7 +87,7 @@ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32 } /** - * @brief Wether to enable the GPIO to be managed by the task channel + * @brief Whether to enable the GPIO to be managed by the task channel * * @param dev Register base address * @param gpio_num GPIO number @@ -101,7 +118,7 @@ static inline bool gpio_ll_etm_is_task_gpio_enabled(gpio_etm_dev_t *dev, uint32_ } /** - * @brief Get the channel number that the GPIO is bounded to + * @brief Get the channel number that the GPIO is bound to * * @param dev Register base address * @param gpio_num GPIO number diff --git a/components/hal/esp32c6/include/hal/gpio_ll.h b/components/hal/esp32c6/include/hal/gpio_ll.h index e92c1bc332..0ff9b15722 100644 --- a/components/hal/esp32c6/include/hal/gpio_ll.h +++ b/components/hal/esp32c6/include/hal/gpio_ll.h @@ -38,6 +38,39 @@ extern "C" { #define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0)) #define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1)) + +/** + * @brief Get the configuration for an IO + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param pu Pull-up enabled or not + * @param pd Pull-down enabled or not + * @param ie Input enabled or not + * @param oe Output enabled or not + * @param od Open-drain enabled or not + * @param drv Drive strength value + * @param fun_sel IOMUX function selection value + * @param sig_out Outputting peripheral signal index + * @param slp_sel Pin sleep mode enabled or not + */ +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, + bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) +{ + uint32_t bit_mask = 1 << gpio_num; + uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); + *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + *oe = (hw->enable.val & bit_mask) >> gpio_num; + *od = hw->pin[gpio_num].pad_driver; + *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; + *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + *sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; + *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; +} + /** * @brief Enable pull-up on GPIO. * @@ -477,6 +510,23 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) } } +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.in_sel : -1); +} + /** * @brief Force hold digital io pad. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32c6/include/hal/i2c_ll.h b/components/hal/esp32c6/include/hal/i2c_ll.h index 83c73a3e03..76aa53949d 100644 --- a/components/hal/esp32c6/include/hal/i2c_ll.h +++ b/components/hal/esp32c6/include/hal/i2c_ll.h @@ -656,6 +656,20 @@ static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw) hw->ctr.conf_upgate = 1; } +/** + * @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value. + * ack_level: 1 (NACK) + * ack_level: 0 (ACK) + * + * @param hw Beginning address of the peripheral registers + * + * @return None + */ +static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level) +{ + hw->ctr.rx_full_ack_level = ack_level; +} + /** * @brief Set I2C source clock * diff --git a/components/hal/esp32c6/include/hal/ieee802154_ll.h b/components/hal/esp32c6/include/hal/ieee802154_ll.h index eec479e96a..14e548a1d3 100644 --- a/components/hal/esp32c6/include/hal/ieee802154_ll.h +++ b/components/hal/esp32c6/include/hal/ieee802154_ll.h @@ -12,3 +12,5 @@ #define IEEE802154_TXPOWER_VALUE_MAX 20 #define IEEE802154_TXPOWER_VALUE_MIN -15 #define IEEE802154_TXPOWER_INDEX_MIN 3 + +#define IEEE802154_RSSI_COMPENSATION_VALUE 0 diff --git a/components/hal/esp32c6/include/hal/lp_aon_hal.h b/components/hal/esp32c6/include/hal/lp_aon_hal.h index c619dc0a6d..c38f6da831 100644 --- a/components/hal/esp32c6/include/hal/lp_aon_hal.h +++ b/components/hal/esp32c6/include/hal/lp_aon_hal.h @@ -8,17 +8,10 @@ #include "hal/lp_aon_ll.h" -#define rtc_hal_ext1_get_wakeup_status() lp_aon_hal_ext1_get_wakeup_status() -#define rtc_hal_ext1_clear_wakeup_status() lp_aon_hal_ext1_clear_wakeup_status() -#define rtc_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_hal_ext1_set_wakeup_pins(mask, mode) -#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_hal_ext1_clear_wakeup_pins() -#define rtc_hal_ext1_get_wakeup_pins() lp_aon_hal_ext1_get_wakeup_pins() +#define rtc_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status() +#define rtc_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status() +#define rtc_hal_ext1_set_wakeup_pins(io_mask, mode_mask) lp_aon_ll_ext1_set_wakeup_pins(io_mask, mode_mask) +#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins() +#define rtc_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins() - -#define lp_aon_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status() -#define lp_aon_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status() -#define lp_aon_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_ll_ext1_set_wakeup_pins(mask, mode) -#define lp_aon_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins() -#define lp_aon_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins() - -#define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp) +#define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp) diff --git a/components/hal/esp32c6/include/hal/lp_aon_ll.h b/components/hal/esp32c6/include/hal/lp_aon_ll.h index db08715964..c212d33b9a 100644 --- a/components/hal/esp32c6/include/hal/lp_aon_ll.h +++ b/components/hal/esp32c6/include/hal/lp_aon_ll.h @@ -39,29 +39,22 @@ static inline void lp_aon_ll_ext1_clear_wakeup_status(void) /** * @brief Set the wake-up LP_IO of the ext1 wake-up source - * @param mask wakeup LP_IO bitmap, bit 0~7 corresponds to LP_IO 0~7 - * @param mode 0: Wake the chip when all selected GPIOs go low - * 1: Wake the chip when any of the selected GPIOs go high + * @param io_mask wakeup LP_IO bitmap, bit 0~7 corresponds to LP_IO 0~7 + * @param level_mask LP_IO wakeup level bitmap, bit 0~7 corresponds to LP_IO 0~7 wakeup level + * each bit's corresponding position is set to 0, the wakeup level will be low + * on the contrary, each bit's corresponding position is set to 1, the wakeup + * level will be high */ -static inline void lp_aon_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) +static inline void lp_aon_ll_ext1_set_wakeup_pins(uint32_t io_mask, uint32_t level_mask) { - uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel); - wakeup_sel_mask |= mask; - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, wakeup_sel_mask); - - uint32_t wakeup_level_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv); - if (mode) { - wakeup_level_mask |= mask; - } else { - wakeup_level_mask &= ~mask; - } - HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv, wakeup_level_mask); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, io_mask); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv, level_mask); } /** * @brief Clear all ext1 wakup-source setting */ -static inline void lp_aon_ll_ext1_clear_wakeup_pins(void) +static inline void lp_aon_ll_ext1_clear_wakeup_pins(void) { HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, 0); } @@ -92,6 +85,24 @@ static inline void lp_aon_ll_inform_wakeup_type(bool dslp) } } +/** + * @brief Get the flag that marks whether LP CPU is awakened by ETM + * + * @return Return true if lpcore is woken up by soc_etm + */ +static inline bool lp_aon_ll_get_lpcore_etm_wakeup_flag(void) +{ + return REG_GET_BIT(LP_AON_LPCORE_REG, LP_AON_LPCORE_ETM_WAKEUP_FLAG); +} + +/** + * @brief Clear the flag that marks whether LP CPU is awakened by soc_etm + */ +static inline void lp_aon_ll_clear_lpcore_etm_wakeup_flag(void) +{ + REG_SET_BIT(LP_AON_LPCORE_REG, LP_AON_LPCORE_ETM_WAKEUP_FLAG_CLR); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/lp_timer_ll.h b/components/hal/esp32c6/include/hal/lp_timer_ll.h index a99349240b..c045cc3bc4 100644 --- a/components/hal/esp32c6/include/hal/lp_timer_ll.h +++ b/components/hal/esp32c6/include/hal/lp_timer_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,8 +12,10 @@ #include "soc/soc.h" #include "soc/rtc.h" #include "soc/lp_timer_struct.h" +#include "soc/lp_timer_reg.h" #include "soc/lp_aon_reg.h" #include "hal/lp_timer_types.h" +#include "hal/misc.h" #include "esp_attr.h" #ifdef __cplusplus @@ -22,8 +24,8 @@ extern "C" { FORCE_INLINE_ATTR void lp_timer_ll_set_alarm_target(lp_timer_dev_t *dev, uint8_t timer_id, uint64_t value) { - dev->target[timer_id].hi.target_hi = (value >> 32) & 0xFFFF; - dev->target[timer_id].lo.target_lo = value & 0xFFFFFFFF; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].hi, target_hi, (value >> 32) & 0xFFFF); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].lo, target_lo, value & 0xFFFFFFFF); } FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_t timer_id, bool en) @@ -33,12 +35,12 @@ FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_ FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_low(lp_timer_dev_t *dev, uint8_t buffer_id) { - return dev->counter[buffer_id].lo.counter_lo; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[buffer_id].lo, counter_lo); } FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_high(lp_timer_dev_t *dev, uint8_t buffer_id) { - return dev->counter[buffer_id].hi.counter_hi; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[buffer_id].hi, counter_hi); } FORCE_INLINE_ATTR void lp_timer_ll_counter_snapshot(lp_timer_dev_t *dev) @@ -61,6 +63,16 @@ FORCE_INLINE_ATTR void lp_timer_ll_clear_lp_alarm_intr_status(lp_timer_dev_t *de dev->lp_int_clr.alarm = 1; } +FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_lp_intr_raw(lp_timer_dev_t *dev) +{ + return dev->lp_int_raw.val; +} + +FORCE_INLINE_ATTR void lp_timer_ll_clear_lp_intsts_mask(lp_timer_dev_t *dev, uint32_t mask) +{ + dev->lp_int_clr.val = mask; +} + FORCE_INLINE_ATTR uint64_t lp_timer_ll_time_to_count(uint64_t time_in_us) { uint32_t slow_clk_value = REG_READ(LP_AON_STORE1_REG); diff --git a/components/hal/esp32c6/include/hal/lpwdt_ll.h b/components/hal/esp32c6/include/hal/lpwdt_ll.h index a8131c0234..caa3cfb12d 100644 --- a/components/hal/esp32c6/include/hal/lpwdt_ll.h +++ b/components/hal/esp32c6/include/hal/lpwdt_ll.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 */ @@ -24,22 +24,42 @@ extern "C" { #include "esp32c6/rom/ets_sys.h" -// TODO: IDF-5717 +/* The value that needs to be written to LP_WDT_WPROTECT_REG to write-enable the wdt registers */ +#define LP_WDT_WKEY_VALUE 0x50D83AA1 +/* The value that needs to be written to LP_WDT_SWD_WPROTECT_REG to write-enable the swd registers */ +#define LP_WDT_SWD_WKEY_VALUE 0x50D83AA1 + +/* Possible values for RTC_CNTL_WDT_CPU_RESET_LENGTH and RTC_CNTL_WDT_SYS_RESET_LENGTH */ +#define LP_WDT_RESET_LENGTH_100_NS 0 +#define LP_WDT_RESET_LENGTH_200_NS 1 +#define LP_WDT_RESET_LENGTH_300_NS 2 +#define LP_WDT_RESET_LENGTH_400_NS 3 +#define LP_WDT_RESET_LENGTH_500_NS 4 +#define LP_WDT_RESET_LENGTH_800_NS 5 +#define LP_WDT_RESET_LENGTH_1600_NS 6 +#define LP_WDT_RESET_LENGTH_3200_NS 7 + +#define LP_WDT_STG_SEL_OFF 0 +#define LP_WDT_STG_SEL_INT 1 +#define LP_WDT_STG_SEL_RESET_CPU 2 +#define LP_WDT_STG_SEL_RESET_SYSTEM 3 +#define LP_WDT_STG_SEL_RESET_RTC 4 + //Type check wdt_stage_action_t -ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == RTC_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); -ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == RTC_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); -ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_CPU == RTC_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); -ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_SYSTEM == RTC_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); -ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_RTC == RTC_WDT_STG_SEL_RESET_RTC, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == LP_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == LP_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_CPU == LP_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_SYSTEM == LP_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_RTC == LP_WDT_STG_SEL_RESET_RTC, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); //Type check wdt_reset_sig_length_t -ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_100ns == RTC_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); -ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_200ns == RTC_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); -ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_300ns == RTC_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); -ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_400ns == RTC_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); -ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_500ns == RTC_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); -ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_800ns == RTC_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); -ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_1_6us == RTC_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); -ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == RTC_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_100ns == LP_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_200ns == LP_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_300ns == LP_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_400ns == LP_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_500ns == LP_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_800ns == LP_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_1_6us == LP_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == LP_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); /** * @brief Enable the RWDT @@ -268,7 +288,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_write_protect_enable(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_write_protect_disable(lp_wdt_dev_t *hw) { - hw->wprotect.val = RTC_CNTL_WDT_WKEY_VALUE; + hw->wprotect.val = LP_WDT_WKEY_VALUE; } /** diff --git a/components/hal/esp32c6/include/hal/mcpwm_ll.h b/components/hal/esp32c6/include/hal/mcpwm_ll.h index 3a94ff3cfb..a928a928e4 100644 --- a/components/hal/esp32c6/include/hal/mcpwm_ll.h +++ b/components/hal/esp32c6/include/hal/mcpwm_ll.h @@ -45,8 +45,12 @@ extern "C" { #define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27)) // Maximum values due to limited register bit width +#define MCPWM_LL_MAX_GROUP_PRESCALE 256 +#define MCPWM_LL_MAX_TIMER_PRESCALE 256 +#define MCPWM_LL_MAX_CARRIER_PRESCALE 16 #define MCPWM_LL_MAX_CARRIER_ONESHOT 16 #define MCPWM_LL_MAX_CAPTURE_PRESCALE 256 +#define MCPWM_LL_MAX_CAPTURE_TIMER_PRESCALE 1 #define MCPWM_LL_MAX_DEAD_DELAY 65536 #define MCPWM_LL_MAX_COUNT_VALUE 65536 @@ -103,13 +107,14 @@ static inline void mcpwm_ll_group_enable_clock(mcpwm_dev_t *mcpwm, bool en) * @brief Set the MCPWM group clock prescale * * @param mcpwm Peripheral instance address - * @param pre_scale Prescale value + * @param prescale Prescale value */ -static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int pre_scale) +static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale) { (void)mcpwm; // only one MCPWM instance - // group clock: PWM_clk = source_clock / (prescale + 1) - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.pwm_clk_conf, pwm_div_num, pre_scale - 1); + // group clock: PWM_clk = source_clock / (prescale) + HAL_ASSERT(prescale <= 256 && prescale > 0); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.pwm_clk_conf, pwm_div_num, prescale - 1); } /** @@ -213,13 +218,12 @@ static inline void mcpwm_ll_timer_set_clock_prescale(mcpwm_dev_t *mcpwm, int tim * @param peak Peak value * @param symmetric True to set symmetric peak value, False to set asymmetric peak value */ +__attribute__((always_inline)) static inline void mcpwm_ll_timer_set_peak(mcpwm_dev_t *mcpwm, int timer_id, uint32_t peak, bool symmetric) { if (!symmetric) { // in asymmetric mode, period = [0,peak-1] - HAL_ASSERT(peak > 0 && peak <= MCPWM_LL_MAX_COUNT_VALUE); HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period, peak - 1); } else { // in symmetric mode, period = [0,peak-1] + [peak,1] - HAL_ASSERT(peak < MCPWM_LL_MAX_COUNT_VALUE); HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period, peak); } } @@ -715,20 +719,20 @@ static inline void mcpwm_ll_operator_stop_update_action(mcpwm_dev_t *mcpwm, int * @param trig_id Trigger ID, index from 0 to 1 * @param fault_gpio_id Fault GPIO ID, index from 0 to 3 */ -static inline void mcpwm_ll_operator_set_trigger_from_gpio(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_gpio_id) +static inline void mcpwm_ll_operator_set_trigger_from_gpio_fault(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_gpio_id) { mcpwm->operators[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id)); mcpwm->operators[operator_id].gen_cfg0.val |= (fault_gpio_id << (4 + 3 * trig_id)); } /** - * @brief Set trigger from timer sync event (when the timer taken the sync signal) + * @brief Set trigger from sync event (when the timer/gpio/soft taken the sync signal) * * @param mcpwm Peripheral instance address * @param operator_id Operator ID, index from 0 to 2 * @param trig_id Trigger ID, index from 0 to 1 */ -static inline void mcpwm_ll_operator_set_trigger_from_timer_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id) +static inline void mcpwm_ll_operator_set_trigger_from_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id) { // the timer here is not selectable, must be the one connected with the operator mcpwm->operators[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id)); diff --git a/components/hal/esp32c6/include/hal/mmu_ll.h b/components/hal/esp32c6/include/hal/mmu_ll.h index 89096800fb..2e224ec6a3 100644 --- a/components/hal/esp32c6/include/hal/mmu_ll.h +++ b/components/hal/esp32c6/include/hal/mmu_ll.h @@ -102,7 +102,7 @@ static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t { (void)mmu_id; (void)type; - uint32_t vaddr_end = vaddr_start + len; + uint32_t vaddr_end = vaddr_start + len - 1; return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); } diff --git a/components/hal/esp32c6/include/hal/mwdt_ll.h b/components/hal/esp32c6/include/hal/mwdt_ll.h index 4f447dbd79..c77ee9ee3d 100644 --- a/components/hal/esp32c6/include/hal/mwdt_ll.h +++ b/components/hal/esp32c6/include/hal/mwdt_ll.h @@ -25,7 +25,7 @@ extern "C" { #include "hal/misc.h" /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ -#define MWDT_LL_DEFAULT_CLK_PRESCALER 40000 +#define MWDT_LL_DEFAULT_CLK_PRESCALER 20000 //Type check wdt_stage_action_t ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); diff --git a/components/hal/esp32c6/include/hal/parlio_ll.h b/components/hal/esp32c6/include/hal/parlio_ll.h index a260d03521..55c1226702 100644 --- a/components/hal/esp32c6/include/hal/parlio_ll.h +++ b/components/hal/esp32c6/include/hal/parlio_ll.h @@ -87,7 +87,7 @@ static inline void parlio_ll_rx_set_clock_div(parl_io_dev_t *dev, uint32_t div) { (void)dev; HAL_ASSERT(div > 0 && div <= PARLIO_LL_RX_MAX_CLOCK_DIV); - PCR.parl_clk_rx_conf.parl_clk_rx_div_num = div - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.parl_clk_rx_conf, parl_clk_rx_div_num, div - 1); } /** @@ -369,7 +369,7 @@ static inline void parlio_ll_tx_set_clock_div(parl_io_dev_t *dev, uint32_t div) { (void)dev; HAL_ASSERT(div > 0 && div <= PARLIO_LL_TX_MAX_CLOCK_DIV); - PCR.parl_clk_tx_conf.parl_clk_tx_div_num = div - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.parl_clk_tx_conf, parl_clk_tx_div_num, div - 1); } /** diff --git a/components/hal/esp32c6/include/hal/pmu_ll.h b/components/hal/esp32c6/include/hal/pmu_ll.h index 32f399b39b..c79a4809b0 100644 --- a/components/hal/esp32c6/include/hal/pmu_ll.h +++ b/components/hal/esp32c6/include/hal/pmu_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include "hal/assert.h" #include "soc/pmu_struct.h" #include "hal/pmu_types.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -488,7 +489,7 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode) FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.hp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, hp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw) @@ -531,29 +532,39 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_reject_cause(pmu_dev_t *hw) return hw->wakeup.status1; } +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_interrupt_raw(pmu_dev_t *hw) +{ + return hw->lp_ext.int_raw.val; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_clear_intsts_mask(pmu_dev_t *hw, uint32_t mask) +{ + hw->lp_ext.int_clr.val = mask; +} + FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, lp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.modify_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.switch_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -578,12 +589,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target, slow_clk_cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl5.lp_ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_set_modem_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -598,22 +609,22 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_get_modem_wait_target_cycle(pmu_dev_t *hw) FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_xtal_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_xtal_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable); } FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_pll_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_pll_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable); } FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -638,12 +649,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t * FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->wakeup.cntl7.ana_wait_target = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl7.ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -666,7 +677,7 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_up_wait_cycle(pmu_dev_t * return hw->power.wait_timer0.powerup_timer; } -static inline uint32_t pmu_ll_get_sysclk_sleep_select_state(pmu_dev_t *hw) +FORCE_INLINE_ATTR uint32_t pmu_ll_get_sysclk_sleep_select_state(pmu_dev_t *hw) { return hw->clk_state0.sysclk_slp_sel; } diff --git a/components/hal/esp32c6/include/hal/rmt_ll.h b/components/hal/esp32c6/include/hal/rmt_ll.h index 7f7f24f9be..42477f373c 100644 --- a/components/hal/esp32c6/include/hal/rmt_ll.h +++ b/components/hal/esp32c6/include/hal/rmt_ll.h @@ -55,15 +55,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -453,6 +474,7 @@ static inline void rmt_ll_rx_set_channel_clock_div(rmt_dev_t *dev, uint32_t chan * @param dev Peripheral instance address * @param channel RMT RX channel number */ +__attribute__((always_inline)) static inline void rmt_ll_rx_reset_pointer(rmt_dev_t *dev, uint32_t channel) { dev->chmconf[channel].conf1.mem_wr_rst_chm = 1; @@ -495,6 +517,7 @@ static inline void rmt_ll_rx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, ui * @param channel RMT RX channel number * @param thres Time length threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { dev->chmconf[channel].conf0.idle_thres_chm = thres; @@ -520,6 +543,7 @@ static inline void rmt_ll_rx_set_mem_owner(rmt_dev_t *dev, uint32_t channel, rmt * @param channel RMT RX chanenl number * @param enable True to enable, False to disable */ +__attribute__((always_inline)) static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable) { dev->chmconf[channel].conf1.rx_filter_en_chm = enable; @@ -532,6 +556,7 @@ static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, boo * @param channel RMT RX channel number * @param thres Filter threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chmconf[channel].conf1, rx_filter_thres_chm, thres); @@ -790,12 +815,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32c6/include/hal/spi_ll.h b/components/hal/esp32c6/include/hal/spi_ll.h index b43d43859d..a7886ea8dc 100644 --- a/components/hal/esp32c6/include/hal/spi_ll.h +++ b/components/hal/esp32c6/include/hal/spi_ll.h @@ -41,6 +41,7 @@ extern "C" { #define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits #define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words +#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized /** * The data structure holding calculated clock configuration. Since the @@ -190,36 +191,44 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw) } /** - * Check whether user-defined transaction is done. + * Determine and unify the default level of mosi line when bus free * * @param hw Beginning address of the peripheral registers. - * - * @return True if transaction is done, otherwise false. */ -static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level) { - return hw->dma_int_raw.trans_done; + hw->ctrl.d_pol = level; //set default level for MOSI only on IDLE state } /** - * Trigger start of user-defined transaction for master. - * The synchronization between two clock domains is required in ESP32-S3 + * Apply the register configurations and wait until it's done * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_master_user_start(spi_dev_t *hw) +static inline void spi_ll_apply_config(spi_dev_t *hw) { hw->cmd.update = 1; - while (hw->cmd.update); - hw->cmd.usr = 1; + while (hw->cmd.update); //waiting config applied +} + +/** + * Check whether user-defined transaction is done. + * + * @param hw Beginning address of the peripheral registers. + * + * @return True if transaction is done, otherwise false. + */ +static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +{ + return hw->dma_int_raw.trans_done; } /** - * Trigger start of user-defined transaction for slave. + * Trigger start of user-defined transaction. * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_slave_user_start(spi_dev_t *hw) +static inline void spi_ll_user_start(spi_dev_t *hw) { hw->cmd.usr = 1; } diff --git a/components/hal/esp32c6/include/hal/timer_ll.h b/components/hal/esp32c6/include/hal/timer_ll.h index a9403c4bd4..592cf60e6c 100644 --- a/components/hal/esp32c6/include/hal/timer_ll.h +++ b/components/hal/esp32c6/include/hal/timer_ll.h @@ -235,6 +235,7 @@ static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, * @param timer_num Timer number in the group * @return reload count value */ +__attribute__((always_inline)) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num) { return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo); @@ -246,6 +247,7 @@ static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_ * @param hw Timer Group register base address * @param timer_num Timer number in the group */ +__attribute__((always_inline)) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num) { hw->hw_timer[timer_num].load.tx_load = 1; diff --git a/components/hal/esp32c6/include/hal/uart_ll.h b/components/hal/esp32c6/include/hal/uart_ll.h index 8f4c38f35e..10ca0834cb 100644 --- a/components/hal/esp32c6/include/hal/uart_ll.h +++ b/components/hal/esp32c6/include/hal/uart_ll.h @@ -7,19 +7,16 @@ // The LL layer for UART register operations. // Note that most of the register operations in this layer are non-atomic operations. + #pragma once +#include #include "esp_attr.h" #include "hal/misc.h" #include "hal/uart_types.h" -#include "soc/uart_reg.h" +#include "soc/uart_periph.h" #include "soc/uart_struct.h" -#include "soc/lp_uart_reg.h" #include "soc/pcr_struct.h" -#include "soc/pcr_reg.h" -#include "soc/lp_clkrst_struct.h" -#include "soc/lpperi_struct.h" -#include "hal/assert.h" #ifdef __cplusplus extern "C" { @@ -27,13 +24,10 @@ extern "C" { // The default fifo depth #define UART_LL_FIFO_DEF_LEN (SOC_UART_FIFO_LEN) -#define LP_UART_LL_FIFO_DEF_LEN (SOC_LP_UART_FIFO_LEN) // Get UART hardware instance with giving uart num -#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&LP_UART))) - -#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0) +#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1)) -#define UART_LL_MIN_WAKEUP_THRESH (2) +#define UART_LL_MIN_WAKEUP_THRESH (3) #define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask #define UART_LL_FSM_IDLE (0x0) @@ -98,171 +92,17 @@ FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw) while (hw->reg_update.reg_update); } -/****************************************** LP_UART Specific ********************************************/ -/** - * @brief Get the LP_UART source clock. - * - * @param hw Beginning address of the peripheral registers. - * @param source_clk Current LP_UART clock source, one in soc_periph_lp_uart_clk_src_t. - */ -FORCE_INLINE_ATTR void lp_uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk) -{ - (void)hw; - switch (LP_CLKRST.lpperi.lp_uart_clk_sel) { - default: - case 0: - *source_clk = (uart_sclk_t)LP_UART_SCLK_LP_FAST; - break; - case 1: - *source_clk = (uart_sclk_t)LP_UART_SCLK_XTAL_D2; - break; - } -} - -/** - * @brief Set LP UART source clock - * - * @param hw Address offset of the LP UART peripheral registers - * @param src_clk Source clock for the LP UART peripheral - */ -static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_clk_src_t src_clk) -{ - (void)hw; - switch (src_clk) { - case LP_UART_SCLK_LP_FAST: - LP_CLKRST.lpperi.lp_uart_clk_sel = 0; - break; - case LP_UART_SCLK_XTAL_D2: - LP_CLKRST.lpperi.lp_uart_clk_sel = 1; - break; - default: - // Invalid LP_UART clock source - HAL_ASSERT(false); - } -} - -/// LP_CLKRST.lpperi is a shared register, so this function must be used in an atomic way -#define lp_uart_ll_set_source_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_set_source_clk(__VA_ARGS__) - /** - * @brief Configure the lp uart baud-rate. + * @brief Configure the UART core reset. * * @param hw Beginning address of the peripheral registers. - * @param baud The baud rate to be set. - * @param sclk_freq Frequency of the clock source of UART, in Hz. + * @param core_rst_en True to enable the core reset, otherwise set it false. * - * @return None - */ -FORCE_INLINE_ATTR void lp_uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq) -{ -#define DIV_UP(a, b) (((a) + (b) - 1) / (b)) - const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits - uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud); - - if (sclk_div == 0) abort(); - - uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div); - // The baud rate configuration register is divided into - // an integer part and a fractional part. - hw->clkdiv_sync.clkdiv_int = clk_div >> 4; - hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf; - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1); - uart_ll_update(hw); -} - -/** - * @brief Enable bus clock for the LP UART module - * - * @param hw_id LP UART instance ID - * @param enable True to enable, False to disable - */ -static inline void lp_uart_ll_enable_bus_clock(int hw_id, bool enable) -{ - (void)hw_id; - LPPERI.clk_en.lp_uart_ck_en = enable; -} - -/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way -#define lp_uart_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_enable_bus_clock(__VA_ARGS__) - -/** - * @brief Reset LP UART module - * - * @param hw_id LP UART instance ID - */ -static inline void lp_uart_ll_reset_register(int hw_id) -{ - (void)hw_id; - LPPERI.reset_en.lp_uart_reset_en = 1; - LPPERI.reset_en.lp_uart_reset_en = 0; -} - -/// LPPERI.reset_en is a shared register, so this function must be used in an atomic way -#define lp_uart_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_reset_register(__VA_ARGS__) - -/*************************************** General LL functions ******************************************/ - -/** - * @brief Check if UART is enabled or disabled. - * - * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). - * - * @return true: enabled; false: disabled - */ -FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num) -{ - HAL_ASSERT(uart_num < SOC_UART_HP_NUM); - uint32_t uart_clk_config_reg = ((uart_num == 0) ? PCR_UART0_CONF_REG : - (uart_num == 1) ? PCR_UART1_CONF_REG : 0); - uint32_t uart_rst_bit = ((uart_num == 0) ? PCR_UART0_RST_EN : - (uart_num == 1) ? PCR_UART1_RST_EN : 0); - uint32_t uart_en_bit = ((uart_num == 0) ? PCR_UART0_CLK_EN : - (uart_num == 1) ? PCR_UART1_CLK_EN : 0); - return REG_GET_BIT(uart_clk_config_reg, uart_rst_bit) == 0 && - REG_GET_BIT(uart_clk_config_reg, uart_en_bit) != 0; -} - -/** - * @brief Enable the bus clock for uart - * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). - * @param enable true to enable, false to disable - */ -static inline void uart_ll_enable_bus_clock(uart_port_t uart_num, bool enable) -{ - switch (uart_num) { - case 0: - PCR.uart0_conf.uart0_clk_en = enable; - break; - case 1: - PCR.uart1_conf.uart1_clk_en = enable; - break; - default: - // LP_UART - abort(); - break; - } -} - -/** - * @brief Reset UART module - * @param uart_num UART port number, the max port number is (UART_NUM_MAX -1). + * @return None. */ -static inline void uart_ll_reset_register(uart_port_t uart_num) +FORCE_INLINE_ATTR void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) { - switch (uart_num) { - case 0: - PCR.uart0_conf.uart0_rst_en = 1; - PCR.uart0_conf.uart0_rst_en = 0; - break; - case 1: - PCR.uart1_conf.uart1_rst_en = 1; - PCR.uart1_conf.uart1_rst_en = 0; - break; - default: - // LP_UART - abort(); - break; - } + UART_LL_PCR_REG_SET(hw, conf, rst_en, core_rst_en); } /** @@ -274,13 +114,7 @@ static inline void uart_ll_reset_register(uart_port_t uart_num) */ FORCE_INLINE_ATTR void uart_ll_sclk_enable(uart_dev_t *hw) { - if ((hw) != &LP_UART) { - UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1); - } else { - // LP_UART clk_en shares the same register with other LP peripherals - // Needs to be protected with a lock, therefore, it has its unique LL function - abort(); - } + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1); } /** @@ -292,13 +126,7 @@ FORCE_INLINE_ATTR void uart_ll_sclk_enable(uart_dev_t *hw) */ FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw) { - if ((hw) != &LP_UART) { - UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0); - } else { - // LP_UART clk_en shares the same register with other LP peripherals - // Needs to be protected with a lock, therefore, it has its unique LL function - abort(); - } + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0); } /** @@ -310,29 +138,19 @@ FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw) * * @return None. */ -FORCE_INLINE_ATTR void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_clk) +FORCE_INLINE_ATTR void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) { - if ((hw) != &LP_UART) { - uint32_t sel_value = 0; - switch (source_clk) { + switch (source_clk) { + default: case UART_SCLK_PLL_F80M: - sel_value = 1; + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 1); break; case UART_SCLK_RTC: - sel_value = 2; + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 2); break; case UART_SCLK_XTAL: - sel_value = 3; + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 3); break; - default: - // Invalid HP_UART clock source - abort(); - } - UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, sel_value); - } else { - // LP_UART clk_sel shares the same register with other LP peripherals - // Needs to be protected with a lock, therefore, it has its unique LL function - abort(); } } @@ -346,21 +164,17 @@ FORCE_INLINE_ATTR void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_ */ FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk) { - if ((hw) != &LP_UART) { - switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) { + switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) { default: case 1: - *source_clk = (uart_sclk_t)UART_SCLK_PLL_F80M; + *source_clk = UART_SCLK_PLL_F80M; break; case 2: - *source_clk = (uart_sclk_t)UART_SCLK_RTC; + *source_clk = UART_SCLK_RTC; break; case 3: - *source_clk = (uart_sclk_t)UART_SCLK_XTAL; + *source_clk = UART_SCLK_XTAL; break; - } - } else { - lp_uart_ll_get_sclk(hw, source_clk); } } @@ -386,11 +200,7 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint3 // an integer part and a fractional part. hw->clkdiv_sync.clkdiv_int = clk_div >> 4; hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf; - if ((hw) == &LP_UART) { - abort(); - } else { - UART_LL_PCR_REG_U32_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1); - } + UART_LL_PCR_REG_U32_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1); #undef DIV_UP uart_ll_update(hw); } @@ -407,13 +217,7 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_fr { typeof(hw->clkdiv_sync) div_reg; div_reg.val = hw->clkdiv_sync.val; - int sclk_div; - if ((hw) == &LP_UART) { - sclk_div = HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1; - } else { - sclk_div = UART_LL_PCR_REG_U32_GET(hw, sclk_conf, sclk_div_num) + 1; - } - return ((sclk_freq << 4)) / (((div_reg.clkdiv_int << 4) | div_reg.clkdiv_frag) * sclk_div); + return ((sclk_freq << 4)) / (((div_reg.clkdiv_int << 4) | div_reg.clkdiv_frag) * (UART_LL_PCR_REG_U32_GET(hw, sclk_conf, sclk_div_num) + 1)); } /** @@ -426,7 +230,7 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_fr */ FORCE_INLINE_ATTR void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) { - hw->int_ena.val = hw->int_ena.val | mask; + hw->int_ena.val |= mask; } /** @@ -439,7 +243,7 @@ FORCE_INLINE_ATTR void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) */ FORCE_INLINE_ATTR void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) { - hw->int_ena.val = hw->int_ena.val & (~mask); + hw->int_ena.val &= (~mask); } /** @@ -562,7 +366,7 @@ FORCE_INLINE_ATTR void uart_ll_txfifo_rst(uart_dev_t *hw) */ FORCE_INLINE_ATTR uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) { - return (hw->status.rxfifo_cnt) >> UART_LL_REG_FIELD_BIT_SHIFT(hw); + return hw->status.rxfifo_cnt; } /** @@ -574,9 +378,7 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) */ FORCE_INLINE_ATTR uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) { - uint32_t total_fifo_len = ((hw) == &LP_UART) ? LP_UART_LL_FIFO_DEF_LEN : UART_LL_FIFO_DEF_LEN; - uint32_t txfifo_len = (hw->status.txfifo_cnt) >> UART_LL_REG_FIELD_BIT_SHIFT(hw); - return (total_fifo_len - txfifo_len); + return UART_LL_FIFO_DEF_LEN - hw->status.txfifo_cnt; } /** @@ -645,13 +447,13 @@ FORCE_INLINE_ATTR void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_ * it will produce rxfifo_full_int_raw interrupt. * * @param hw Beginning address of the peripheral registers. - * @param full_thrhd The full threshold value of the rxfifo. `full_thrhd` should be less than `(LP_)UART_LL_FIFO_DEF_LEN`. + * @param full_thrhd The full threshold value of the rxfifo. `full_thrhd` should be less than `UART_LL_FIFO_DEF_LEN`. * * @return None. */ FORCE_INLINE_ATTR void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) { - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->conf1, rxfifo_full_thrhd, full_thrhd << UART_LL_REG_FIELD_BIT_SHIFT(hw)); + hw->conf1.rxfifo_full_thrhd = full_thrhd; } /** @@ -665,7 +467,7 @@ FORCE_INLINE_ATTR void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full */ FORCE_INLINE_ATTR void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) { - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->conf1, txfifo_empty_thrhd, empty_thrhd << UART_LL_REG_FIELD_BIT_SHIFT(hw)); + hw->conf1.txfifo_empty_thrhd = empty_thrhd; } /** @@ -729,7 +531,7 @@ FORCE_INLINE_ATTR void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont { //only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. if (flow_ctrl & UART_HW_FLOWCTRL_RTS) { - hw->hwfc_conf_sync.rx_flow_thrhd = rx_thrs << UART_LL_REG_FIELD_BIT_SHIFT(hw); + hw->hwfc_conf_sync.rx_flow_thrhd = rx_thrs; hw->hwfc_conf_sync.rx_flow_en = 1; } else { hw->hwfc_conf_sync.rx_flow_en = 0; @@ -775,8 +577,8 @@ FORCE_INLINE_ATTR void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl if (sw_flow_ctrl_en) { hw->swfc_conf0_sync.xonoff_del = 1; hw->swfc_conf0_sync.sw_flow_con_en = 1; - hw->swfc_conf1.xon_threshold = (flow_ctrl->xon_thrd) << UART_LL_REG_FIELD_BIT_SHIFT(hw); - hw->swfc_conf1.xoff_threshold = (flow_ctrl->xoff_thrd) << UART_LL_REG_FIELD_BIT_SHIFT(hw); + hw->swfc_conf1.xon_threshold = flow_ctrl->xon_thrd; + hw->swfc_conf1.xoff_threshold = flow_ctrl->xoff_thrd; HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xon_char, flow_ctrl->xon_char); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xoff_char, flow_ctrl->xoff_char); } else { @@ -861,6 +663,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) */ FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) { + // System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3) hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; } @@ -873,10 +676,6 @@ FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_t */ FORCE_INLINE_ATTR void uart_ll_set_mode_normal(uart_dev_t *hw) { - // This function is only for HP_UART use - // LP_UART can only work in normal mode - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - hw->rs485_conf_sync.rs485_en = 0; hw->rs485_conf_sync.rs485tx_rx_en = 0; hw->rs485_conf_sync.rs485rxby_tx_en = 0; @@ -893,10 +692,6 @@ FORCE_INLINE_ATTR void uart_ll_set_mode_normal(uart_dev_t *hw) */ FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) { - // This function is only for HP_UART use - // LP_UART can only work in normal mode - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - // Application software control, remove echo hw->rs485_conf_sync.rs485rxby_tx_en = 1; hw->conf0_sync.irda_en = 0; @@ -917,10 +712,6 @@ FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) */ FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) { - // This function is only for HP_UART use - // LP_UART can only work in normal mode - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - // Enable receiver, sw_rts = 1 generates low level on RTS pin hw->conf0_sync.sw_rts = 1; // Half duplex mode @@ -935,18 +726,6 @@ FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) uart_ll_update(hw); } -/** - * @brief Get the rs485_half_duplex mode. - * - * @param hw Beginning address of the peripheral registers. - * - * @return True if RS485 half duplex mode enabled. - */ -static inline bool uart_ll_is_mode_rs485_half_duplex(uart_dev_t *hw) -{ - return (!hw->rs485_conf_sync.rs485rxby_tx_en && hw->rs485_conf_sync.rs485_en); -} - /** * @brief Configure the UART work in collision_detect mode. * @@ -956,10 +735,6 @@ static inline bool uart_ll_is_mode_rs485_half_duplex(uart_dev_t *hw) */ FORCE_INLINE_ATTR void uart_ll_set_mode_collision_detect(uart_dev_t *hw) { - // This function is only for HP_UART use - // LP_UART can only work in normal mode - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - hw->conf0_sync.irda_en = 0; // Enable full-duplex mode hw->rs485_conf_sync.rs485tx_rx_en = 1; @@ -981,10 +756,6 @@ FORCE_INLINE_ATTR void uart_ll_set_mode_collision_detect(uart_dev_t *hw) */ FORCE_INLINE_ATTR void uart_ll_set_mode_irda(uart_dev_t *hw) { - // This function is only for HP_UART use - // LP_UART can only work in normal mode - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - hw->rs485_conf_sync.rs485_en = 0; hw->rs485_conf_sync.rs485tx_rx_en = 0; hw->rs485_conf_sync.rs485rxby_tx_en = 0; @@ -1009,19 +780,15 @@ FORCE_INLINE_ATTR void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) uart_ll_set_mode_normal(hw); break; case UART_MODE_RS485_COLLISION_DETECT: - // Only HP_UART support this mode uart_ll_set_mode_collision_detect(hw); break; case UART_MODE_RS485_APP_CTRL: - // Only HP_UART support this mode uart_ll_set_mode_rs485_app_ctrl(hw); break; case UART_MODE_RS485_HALF_DUPLEX: - // Only HP_UART support this mode uart_ll_set_mode_rs485_half_duplex(hw); break; case UART_MODE_IRDA: - // Only HP_UART support this mode uart_ll_set_mode_irda(hw); break; } @@ -1076,7 +843,7 @@ FORCE_INLINE_ATTR void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length */ FORCE_INLINE_ATTR bool uart_ll_is_tx_idle(uart_dev_t *hw) { - return ((((hw->status.txfifo_cnt) >> UART_LL_REG_FIELD_BIT_SHIFT(hw)) == 0) && (hw->fsm_status.st_utx_out == 0)); + return ((hw->status.txfifo_cnt == 0) && (hw->fsm_status.st_utx_out == 0)); } /** @@ -1121,7 +888,7 @@ FORCE_INLINE_ATTR void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) { hw->swfc_conf0_sync.force_xon = 1; uart_ll_update(hw); - if (!always_on) { + if(!always_on) { hw->swfc_conf0_sync.force_xon = 0; uart_ll_update(hw); } @@ -1138,9 +905,6 @@ FORCE_INLINE_ATTR void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) */ FORCE_INLINE_ATTR void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) { - // LP_UART does not support UART_SIGNAL_IRDA_TX_INV and UART_SIGNAL_IRDA_RX_INV - // lp_uart_dev_t has no these fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - typeof(hw->conf0_sync) conf0_reg; conf0_reg.val = hw->conf0_sync.val; conf0_reg.irda_tx_inv = (inv_mask & UART_SIGNAL_IRDA_TX_INV) ? 1 : 0; @@ -1170,7 +934,7 @@ FORCE_INLINE_ATTR void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) { uint16_t tout_val = tout_thrd; - if (tout_thrd > 0) { + if(tout_thrd > 0) { hw->tout_conf_sync.rx_tout_thrhd = tout_val; hw->tout_conf_sync.rx_tout_en = 1; } else { @@ -1189,7 +953,7 @@ FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) FORCE_INLINE_ATTR uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) { uint16_t tout_thrd = 0; - if (hw->tout_conf_sync.rx_tout_en > 0) { + if(hw->tout_conf_sync.rx_tout_en > 0) { tout_thrd = hw->tout_conf_sync.rx_tout_thrhd; } return tout_thrd; @@ -1204,7 +968,7 @@ FORCE_INLINE_ATTR uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) */ FORCE_INLINE_ATTR uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) { - return ((hw) == &LP_UART) ? LP_UART_RX_TOUT_THRHD_V : UART_RX_TOUT_THRHD_V; + return UART_RX_TOUT_THRHD_V; } /** @@ -1215,9 +979,6 @@ FORCE_INLINE_ATTR uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) */ FORCE_INLINE_ATTR void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) { - // LP_UART does not support autobaud - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - hw->conf0_sync.autobaud_en = enable ? 1 : 0; uart_ll_update(hw); } @@ -1229,9 +990,6 @@ FORCE_INLINE_ATTR void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) */ FORCE_INLINE_ATTR uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) { - // LP_UART does not support this feature - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - return hw->rxd_cnt.rxd_edge_cnt; } @@ -1242,9 +1000,6 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) */ FORCE_INLINE_ATTR uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) { - // LP_UART does not support this feature - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - return hw->pospulse.posedge_min_cnt; } @@ -1255,9 +1010,6 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) */ FORCE_INLINE_ATTR uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) { - // LP_UART does not support this feature - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - return hw->negpulse.negedge_min_cnt; } @@ -1268,9 +1020,6 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) */ FORCE_INLINE_ATTR uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) { - // LP_UART does not support this feature - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - return hw->highpulse.highpulse_min_cnt; } @@ -1281,9 +1030,6 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) */ FORCE_INLINE_ATTR uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) { - // LP_UART does not support this feature - // lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct - return hw->lowpulse.lowpulse_min_cnt; } @@ -1296,11 +1042,9 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) */ FORCE_INLINE_ATTR void uart_ll_force_xoff(uart_port_t uart_num) { - uart_dev_t *hw = UART_LL_GET_HW(uart_num); - hw->swfc_conf0_sync.force_xon = 0; - hw->swfc_conf0_sync.sw_flow_con_en = 1; - hw->swfc_conf0_sync.force_xoff = 1; - uart_ll_update(hw); + REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); + REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); + uart_ll_update(UART_LL_GET_HW(uart_num)); } /** @@ -1312,12 +1056,10 @@ FORCE_INLINE_ATTR void uart_ll_force_xoff(uart_port_t uart_num) */ FORCE_INLINE_ATTR void uart_ll_force_xon(uart_port_t uart_num) { - uart_dev_t *hw = UART_LL_GET_HW(uart_num); - hw->swfc_conf0_sync.force_xoff = 0; - hw->swfc_conf0_sync.force_xon = 1; - hw->swfc_conf0_sync.sw_flow_con_en = 0; - hw->swfc_conf0_sync.force_xon = 0; - uart_ll_update(hw); + REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XOFF); + REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); + REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XON); + uart_ll_update(UART_LL_GET_HW(uart_num)); } /** @@ -1327,10 +1069,9 @@ FORCE_INLINE_ATTR void uart_ll_force_xon(uart_port_t uart_num) * * @return UART module FSM status. */ -FORCE_INLINE_ATTR uint32_t uart_ll_get_tx_fsm_status(uart_port_t uart_num) +FORCE_INLINE_ATTR uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) { - uart_dev_t *hw = UART_LL_GET_HW(uart_num); - return hw->fsm_status.st_utx_out; + return REG_GET_FIELD(UART_FSM_STATUS_REG(uart_num), UART_ST_UTX_OUT); } /** diff --git a/components/hal/esp32c6/include/hal/uhci_ll.h b/components/hal/esp32c6/include/hal/uhci_ll.h index 59b799234a..07d4a40a68 100644 --- a/components/hal/esp32c6/include/hal/uhci_ll.h +++ b/components/hal/esp32c6/include/hal/uhci_ll.h @@ -1,24 +1,11 @@ -// 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. - -// The LL layer for UHCI register operations. -// Note that most of the register operations in this layer are non-atomic operations. - +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include -#include "hal/misc.h" #include "hal/uhci_types.h" #include "soc/uhci_struct.h" @@ -54,7 +41,9 @@ static inline void uhci_ll_attach_uart_port(uhci_dev_t *hw, int uart_num) static inline void uhci_ll_set_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_char) { if (seper_char->sub_chr_en) { - typeof(hw->esc_conf0) esc_conf0_reg = hw->esc_conf0; + typeof(hw->esc_conf0) esc_conf0_reg; + esc_conf0_reg.val = hw->esc_conf0.val; + esc_conf0_reg.seper_char = seper_char->seper_chr; esc_conf0_reg.seper_esc_char0 = seper_char->sub_chr1; esc_conf0_reg.seper_esc_char1 = seper_char->sub_chr2; @@ -75,10 +64,15 @@ static inline void uhci_ll_get_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper static inline void uhci_ll_set_swflow_ctrl_sub_chr(uhci_dev_t *hw, uhci_swflow_ctrl_sub_chr_t *sub_ctr) { - typeof(hw->escape_conf) escape_conf_reg = hw->escape_conf; + typeof(hw->escape_conf) escape_conf_reg; + escape_conf_reg.val = hw->escape_conf.val; + if (sub_ctr->flow_en == 1) { - typeof(hw->esc_conf2) esc_conf2_reg = hw->esc_conf2; - typeof(hw->esc_conf3) esc_conf3_reg = hw->esc_conf3; + typeof(hw->esc_conf2) esc_conf2_reg; + esc_conf2_reg.val = hw->esc_conf2.val; + typeof(hw->esc_conf3) esc_conf3_reg; + esc_conf3_reg.val = hw->esc_conf3.val; + esc_conf2_reg.esc_seq1 = sub_ctr->xon_chr; esc_conf2_reg.esc_seq1_char0 = sub_ctr->xon_sub1; esc_conf2_reg.esc_seq1_char1 = sub_ctr->xon_sub2; diff --git a/components/hal/esp32c6/include/hal/usb_phy_ll.h b/components/hal/esp32c6/include/hal/usb_phy_ll.h deleted file mode 100644 index 312ff236cd..0000000000 --- a/components/hal/esp32c6/include/hal/usb_phy_ll.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include "soc/usb_serial_jtag_struct.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configures the internal PHY for USB_Serial_JTAG - * - * @param hw Start address of the USB Serial_JTAG registers - */ -static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) -{ - // USB_Serial_JTAG use internal PHY - hw->conf0.phy_sel = 0; - // Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1) - hw->conf0.pad_pull_override = 0; - // Enable USB D+ pullup - hw->conf0.dp_pullup = 1; - // Enable USB pad function - hw->conf0.usb_pad_enable = 1; -} - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/esp32c6/modem_clock_hal.c b/components/hal/esp32c6/modem_clock_hal.c index 553c7cbfac..ed242febec 100644 --- a/components/hal/esp32c6/modem_clock_hal.c +++ b/components/hal/esp32c6/modem_clock_hal.c @@ -19,7 +19,7 @@ typedef enum { MODEM_CLOCK_EXT32K_CODE = 2 } modem_clock_32k_clk_src_code_t; -void modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain, uint32_t bitmap) +void IRAM_ATTR modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain, uint32_t bitmap) { HAL_ASSERT(domain < MODEM_CLOCK_DOMAIN_MAX); switch (domain) @@ -36,7 +36,7 @@ void modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, case MODEM_CLOCK_DOMAIN_BT: modem_syscon_ll_set_bt_icg_bitmap(hal->syscon_dev, bitmap); break; - case MODEM_CLOCK_DOMAIN_FE: + case MODEM_CLOCK_DOMAIN_MODEM_FE: modem_syscon_ll_set_fe_icg_bitmap(hal->syscon_dev, bitmap); break; case MODEM_CLOCK_DOMAIN_IEEE802154: @@ -55,11 +55,11 @@ void modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_lpcon_ll_set_wifipwr_icg_bitmap(hal->lpcon_dev, bitmap); break; default: - break; + HAL_ASSERT(0); } } -uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain) +uint32_t IRAM_ATTR modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain) { HAL_ASSERT(domain < MODEM_CLOCK_DOMAIN_MAX); uint32_t bitmap = 0; @@ -77,7 +77,7 @@ uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t * case MODEM_CLOCK_DOMAIN_BT: bitmap = modem_syscon_ll_get_bt_icg_bitmap(hal->syscon_dev); break; - case MODEM_CLOCK_DOMAIN_FE: + case MODEM_CLOCK_DOMAIN_MODEM_FE: bitmap = modem_syscon_ll_get_fe_icg_bitmap(hal->syscon_dev); break; case MODEM_CLOCK_DOMAIN_IEEE802154: @@ -96,18 +96,24 @@ uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t * bitmap = modem_lpcon_ll_get_wifipwr_icg_bitmap(hal->lpcon_dev); break; default: - break; + HAL_ASSERT(0); } return bitmap; } -void modem_clock_hal_enable_fe_clock(modem_clock_hal_context_t *hal, bool enable) +void IRAM_ATTR modem_clock_hal_enable_modem_adc_common_fe_clock(modem_clock_hal_context_t *hal, bool enable) { if (enable) { modem_syscon_ll_enable_fe_apb_clock(hal->syscon_dev, enable); + modem_syscon_ll_enable_fe_80m_clock(hal->syscon_dev, enable); + } +} + +void IRAM_ATTR modem_clock_hal_enable_modem_private_fe_clock(modem_clock_hal_context_t *hal, bool enable) +{ + if (enable) { modem_syscon_ll_enable_fe_cal_160m_clock(hal->syscon_dev, enable); modem_syscon_ll_enable_fe_160m_clock(hal->syscon_dev, enable); - modem_syscon_ll_enable_fe_80m_clock(hal->syscon_dev, enable); } } @@ -157,7 +163,7 @@ void modem_clock_hal_select_ble_rtc_timer_lpclk_source(modem_clock_hal_context_t modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_EXT32K_CODE); break; default: - break; + HAL_ASSERT(0); } } @@ -197,7 +203,7 @@ void modem_clock_hal_select_coex_lpclk_source(modem_clock_hal_context_t *hal, mo modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_EXT32K_CODE); break; default: - break; + HAL_ASSERT(0); } } @@ -237,7 +243,7 @@ void modem_clock_hal_select_wifi_lpclk_source(modem_clock_hal_context_t *hal, mo modem_lpcon_ll_select_modem_32k_clock_source(hal->lpcon_dev, MODEM_CLOCK_EXT32K_CODE); break; default: - break; + HAL_ASSERT(0); } } diff --git a/components/hal/esp32c6/pau_hal.c b/components/hal/esp32c6/pau_hal.c index 1000b66a2c..53be6120c3 100644 --- a/components/hal/esp32c6/pau_hal.c +++ b/components/hal/esp32c6/pau_hal.c @@ -20,7 +20,7 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_ * REGDMA link 3 */ } -void pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_set_regdma_select_wifimac_link(hal->dev); @@ -30,14 +30,14 @@ void pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_rest while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); } -void pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) +void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) { pau_ll_set_regdma_wifimac_link_backup_start_disable(hal->dev); pau_ll_set_regdma_deselect_wifimac_link(hal->dev); pau_ll_clear_regdma_backup_done_intr_state(hal->dev); } -void pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) +void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); /* The link 3 of REGDMA is reserved, we use it as an extra linked list to @@ -50,7 +50,7 @@ void pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_rest while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); } -void pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) +void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) { pau_ll_set_regdma_entry_link_backup_start_disable(hal->dev); pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */ diff --git a/components/hal/esp32c6/pmu_hal.c b/components/hal/esp32c6/pmu_hal.c index 4997eacce6..1d0dfc49bb 100644 --- a/components/hal/esp32c6/pmu_hal.c +++ b/components/hal/esp32c6/pmu_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,26 +11,26 @@ #include "hal/pmu_hal.h" #include "hal/pmu_types.h" -void IRAM_ATTR pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) { pmu_ll_hp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); pmu_ll_hp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); } -uint32_t IRAM_ATTR pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) { uint32_t power_supply_wait_cycle = pmu_ll_hp_get_digital_power_supply_wait_cycle(hal->dev); uint32_t power_up_wait_cycle = pmu_ll_hp_get_digital_power_up_wait_cycle(hal->dev); return power_supply_wait_cycle + power_up_wait_cycle; } -void IRAM_ATTR pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) { pmu_ll_lp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); pmu_ll_lp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); } -uint32_t IRAM_ATTR pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) { uint32_t power_supply_wait_cycle = pmu_ll_lp_get_digital_power_supply_wait_cycle(hal->dev); uint32_t power_up_wait_cycle = pmu_ll_lp_get_digital_power_up_wait_cycle(hal->dev); diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index 0a5e0b544b..0794b7886b 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -39,6 +39,7 @@ extern "C" { Oneshot ---------------------------------------------------------------*/ #define ADC_LL_DATA_INVERT_DEFAULT(PERIPH_NUM) (0) +#define ADC_LL_DELAY_CYCLE_AFTER_DONE_SIGNAL (5) /*--------------------------------------------------------------- DMA @@ -543,6 +544,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/hal/esp32h2/include/hal/brownout_ll.h b/components/hal/esp32h2/include/hal/brownout_ll.h index 7885decbfd..f0b3d63263 100644 --- a/components/hal/esp32h2/include/hal/brownout_ll.h +++ b/components/hal/esp32h2/include/hal/brownout_ll.h @@ -115,6 +115,15 @@ static inline void brownout_ll_intr_clear(void) LP_ANA_PERI.int_clr.bod_mode0_int_clr = 1; } +/** + * @brief Clear BOD internal count. + */ +static inline void brownout_ll_clear_count(void) +{ + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 1; + LP_ANA_PERI.bod_mode0_cntl.bod_mode0_cnt_clr = 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/cache_ll.h b/components/hal/esp32h2/include/hal/cache_ll.h index 7b50600dd3..88d7dbbd0c 100644 --- a/components/hal/esp32h2/include/hal/cache_ll.h +++ b/components/hal/esp32h2/include/hal/cache_ll.h @@ -16,7 +16,7 @@ #ifdef __cplusplus extern "C" { #endif - +#define CACHE_LL_ENABLE_DISABLE_STATE_SW 1 //There's no register indicating cache enable/disable state, we need to use software way for this state. #define CACHE_LL_DEFAULT_IBUS_MASK CACHE_BUS_IBUS0 #define CACHE_LL_DEFAULT_DBUS_MASK CACHE_BUS_DBUS0 diff --git a/components/hal/esp32h2/include/hal/clk_gate_ll.h b/components/hal/esp32h2/include/hal/clk_gate_ll.h index 7a8cf3b84d..64fb1475b7 100644 --- a/components/hal/esp32h2/include/hal/clk_gate_ll.h +++ b/components/hal/esp32h2/include/hal/clk_gate_ll.h @@ -101,7 +101,7 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en switch (periph) { case PERIPH_SARADC_MODULE: - return PCR_SARADC_RST_EN; + return PCR_SARADC_REG_RST_EN; case PERIPH_RMT_MODULE: return PCR_RMT_RST_EN; case PERIPH_PCNT_MODULE: @@ -347,16 +347,14 @@ static inline void periph_ll_disable_clk_set_rst(periph_module_t periph) SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); } -static inline void periph_ll_wifi_bt_module_enable_clk_clear_rst(void) +static inline void periph_ll_wifi_bt_module_enable_clk(void) { // DPORT_SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M);// ESP32H2-TODO: IDF-6400 - // DPORT_CLEAR_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } -static inline void periph_ll_wifi_bt_module_disable_clk_set_rst(void) +static inline void periph_ll_wifi_bt_module_disable_clk(void) { // DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M);// ESP32H2-TODO: IDF-6400 - // DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } static inline void periph_ll_reset(periph_module_t periph) diff --git a/components/hal/esp32h2/include/hal/ecc_ll.h b/components/hal/esp32h2/include/hal/ecc_ll.h index 967d9857ef..6b5c0be4c4 100644 --- a/components/hal/esp32h2/include/hal/ecc_ll.h +++ b/components/hal/esp32h2/include/hal/ecc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,7 +8,10 @@ #include #include #include "hal/assert.h" +#include "hal/ecc_types.h" #include "soc/ecc_mult_reg.h" +#include "soc/pcr_struct.h" +#include "soc/pcr_reg.h" #ifdef __cplusplus extern "C" { @@ -23,6 +26,18 @@ typedef enum { ECC_PARAM_QZ, } ecc_ll_param_t; +static inline void ecc_ll_power_up(void) +{ + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD); +} + +static inline void ecc_ll_power_down(void) +{ + REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PU); + REG_SET_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD); +} + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32h2/include/hal/ecdsa_ll.h b/components/hal/esp32h2/include/hal/ecdsa_ll.h index a6931b741a..95861185b6 100644 --- a/components/hal/esp32h2/include/hal/ecdsa_ll.h +++ b/components/hal/esp32h2/include/hal/ecdsa_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,6 @@ typedef enum { ECDSA_PARAM_R, ECDSA_PARAM_S, ECDSA_PARAM_Z, - ECDSA_PARAM_K, ECDSA_PARAM_QAX, ECDSA_PARAM_QAY } ecdsa_ll_param_t; @@ -170,26 +169,6 @@ static inline void ecdsa_ll_set_curve(ecdsa_curve_t curve) } } -/** - * @brief Set the source of `K` - * - * @param mode Mode of K generation - */ -static inline void ecdsa_ll_set_k_mode(ecdsa_k_mode_t mode) -{ - switch (mode) { - case ECDSA_K_USE_TRNG: - REG_CLR_BIT(ECDSA_CONF_REG, ECDSA_SOFTWARE_SET_K); - break; - case ECDSA_K_USER_PROVIDED: - REG_SET_BIT(ECDSA_CONF_REG, ECDSA_SOFTWARE_SET_K); - break; - default: - HAL_ASSERT(false && "Unsupported curve"); - break; - } -} - /** * @brief Set the source of `Z` (SHA message) * @@ -297,7 +276,7 @@ static inline bool ecdsa_ll_sha_is_busy(void) /** * @brief Write the ECDSA parameter * - * @param param Parameter to be writen + * @param param Parameter to be written * @param buf Buffer containing data * @param len Length of buffer */ @@ -315,7 +294,6 @@ static inline void ecdsa_ll_write_param(ecdsa_ll_param_t param, const uint8_t *b case ECDSA_PARAM_Z: reg = ECDSA_Z_MEM; break; - case ECDSA_PARAM_K: case ECDSA_PARAM_QAX: reg = ECDSA_QAX_MEM; break; @@ -353,7 +331,6 @@ static inline void ecdsa_ll_read_param(ecdsa_ll_param_t param, uint8_t *buf, uin case ECDSA_PARAM_Z: reg = ECDSA_Z_MEM; break; - case ECDSA_PARAM_K: case ECDSA_PARAM_QAX: reg = ECDSA_QAX_MEM; break; @@ -369,14 +346,12 @@ static inline void ecdsa_ll_read_param(ecdsa_ll_param_t param, uint8_t *buf, uin } /** - * @brief Get result of ECDSA verification operation - * - * This is only valid for ECDSA verify mode + * @brief Check if the ECDSA operation is successful * - * @return - 1, if signature verification succeeds + * @return - 1, if ECDSA operation succeeds * - 0, otherwise */ -static inline int ecdsa_ll_get_verification_result(void) +static inline int ecdsa_ll_get_operation_result(void) { return REG_GET_BIT(ECDSA_RESULT_REG, ECDSA_OPERATION_RESULT); } diff --git a/components/hal/esp32h2/include/hal/efuse_ll.h b/components/hal/esp32h2/include/hal/efuse_ll.h index 8adf2a4ce1..d2aa40fcb3 100644 --- a/components/hal/esp32h2/include/hal/efuse_ll.h +++ b/components/hal/esp32h2/include/hal/efuse_ll.h @@ -40,6 +40,26 @@ __attribute__((always_inline)) static inline uint32_t efuse_ll_get_mac1(void) return EFUSE.rd_mac_sys_1.mac_1; } +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_active_hp_dbias(void) +{ + return EFUSE.rd_mac_sys_2.active_hp_dbias; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_active_lp_dbias(void) +{ + return EFUSE.rd_mac_sys_2.active_lp_dbias; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_dslp_dbias(void) +{ + return EFUSE.rd_mac_sys_2.dslp_dbias; +} + +__attribute__((always_inline)) static inline int32_t efuse_ll_get_dbias_vol_gap(void) +{ + return (EFUSE.rd_mac_sys_3.dbias_vol_gap_sign << 4)|(EFUSE.rd_mac_sys_3.dbias_vol_gap_value2 << 1)|EFUSE.rd_mac_sys_2.dbias_vol_gap_value1; +} + __attribute__((always_inline)) static inline bool efuse_ll_get_secure_boot_v2_en(void) { return EFUSE.rd_repeat_data2.secure_boot_en; diff --git a/components/hal/esp32h2/include/hal/gdma_ll.h b/components/hal/esp32h2/include/hal/gdma_ll.h index 57969ca513..71fc0e58e5 100644 --- a/components/hal/esp32h2/include/hal/gdma_ll.h +++ b/components/hal/esp32h2/include/hal/gdma_ll.h @@ -17,6 +17,8 @@ extern "C" { #endif +#define GDMA_CH_RETENTION_GET_MODULE_ID(group_id, pair_id) (SLEEP_RETENTION_MODULE_GDMA_CH0 + (SOC_GDMA_PAIRS_PER_GROUP * group_id) + pair_id) + #define GDMA_LL_GET_HW(id) (((id) == 0) ? (&GDMA) : NULL) #define GDMA_LL_CHANNEL_MAX_PRIORITY 5 // supported priority levels: [0,5] diff --git a/components/hal/esp32h2/include/hal/gpio_etm_ll.h b/components/hal/esp32h2/include/hal/gpio_etm_ll.h index 49da6692ba..7b4e1138a6 100644 --- a/components/hal/esp32h2/include/hal/gpio_etm_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_etm_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,15 +22,20 @@ #define GPIO_LL_ETM_TASK_ID_CLR(ch) (GPIO_TASK_CH0_CLEAR + (ch)) #define GPIO_LL_ETM_TASK_ID_TOG(ch) (GPIO_TASK_CH0_TOGGLE + (ch)) +#define GPIO_LL_ETM_EVENT_CHANNELS_PER_GROUP 8 +#define GPIO_LL_ETM_TASK_CHANNELS_PER_GROUP 8 + #ifdef __cplusplus extern "C" { #endif /** - * @brief Set which GPIO to be bounded to the event channel + * @brief Set which GPIO to be bound to the event channel + * + * @note Different channels can be bound to one GPIO * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Event channel number * @param gpio_num GPIO number */ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint32_t chan, uint32_t gpio_num) @@ -39,10 +44,10 @@ static inline void gpio_ll_etm_event_channel_set_gpio(gpio_etm_dev_t *dev, uint3 } /** - * @brief Wether to enable the event channel + * @brief Whether to enable the event channel * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Event channel number * @param enable True to enable, false to disable */ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_t chan, bool enable) @@ -51,12 +56,24 @@ static inline void gpio_ll_etm_enable_event_channel(gpio_etm_dev_t *dev, uint32_ } /** - * @brief Set which GPIO to be bounded to the task channel + * @brief Get which GPIO is bound to the event channel + * + * @param dev Register base address + * @param chan GPIO ETM Event channel number + * @return GPIO number + */ +static inline uint32_t gpio_ll_etm_event_channel_get_gpio(gpio_etm_dev_t *dev, uint32_t chan) +{ + return dev->etm_event_chn_cfg[chan].etm_ch0_event_sel; +} + +/** + * @brief Set which GPIO to be bound to the task channel * - * @note One channel can be bounded to multiple different GPIOs + * @note One channel can be bound to multiple different GPIOs * * @param dev Register base address - * @param chan Channel number + * @param chan GPIO ETM Task channel number * @param gpio_num GPIO number */ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32_t gpio_num, uint32_t chan) @@ -70,7 +87,7 @@ static inline void gpio_ll_etm_gpio_set_task_channel(gpio_etm_dev_t *dev, uint32 } /** - * @brief Wether to enable the GPIO to be managed by the task channel + * @brief Whether to enable the GPIO to be managed by the task channel * * @param dev Register base address * @param gpio_num GPIO number @@ -101,7 +118,7 @@ static inline bool gpio_ll_etm_is_task_gpio_enabled(gpio_etm_dev_t *dev, uint32_ } /** - * @brief Get the channel number that the GPIO is bounded to + * @brief Get the channel number that the GPIO is bound to * * @param dev Register base address * @param gpio_num GPIO number diff --git a/components/hal/esp32h2/include/hal/gpio_ll.h b/components/hal/esp32h2/include/hal/gpio_ll.h index e999d4e9f8..70d5e1a477 100644 --- a/components/hal/esp32h2/include/hal/gpio_ll.h +++ b/components/hal/esp32h2/include/hal/gpio_ll.h @@ -37,6 +37,39 @@ extern "C" { #define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0)) #define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1)) + +/** + * @brief Get the configuration for an IO + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param pu Pull-up enabled or not + * @param pd Pull-down enabled or not + * @param ie Input enabled or not + * @param oe Output enabled or not + * @param od Open-drain enabled or not + * @param drv Drive strength value + * @param fun_sel IOMUX function selection value + * @param sig_out Outputting peripheral signal index + * @param slp_sel Pin sleep mode enabled or not + */ +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, + bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) +{ + uint32_t bit_mask = 1 << gpio_num; + uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); + *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + *oe = (hw->enable.val & bit_mask) >> gpio_num; + *od = hw->pin[gpio_num].pad_driver; + *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; + *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + *sig_out = hw->func_out_sel_cfg[gpio_num].out_sel; + *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; +} + /** * @brief Enable pull-up on GPIO. * @@ -502,6 +535,23 @@ static inline void gpio_ll_iomux_set_clk_src(soc_module_clk_t src) } } +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + gpio_func_in_sel_cfg_reg_t reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.in_sel : -1); +} + /** * @brief Force hold all digital(VDDPST2) and lp(VDDPST1) io pads. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32h2/include/hal/ieee802154_ll.h b/components/hal/esp32h2/include/hal/ieee802154_ll.h index fdc212b582..c873c5515e 100644 --- a/components/hal/esp32h2/include/hal/ieee802154_ll.h +++ b/components/hal/esp32h2/include/hal/ieee802154_ll.h @@ -12,3 +12,5 @@ #define IEEE802154_TXPOWER_VALUE_MAX 20 #define IEEE802154_TXPOWER_VALUE_MIN -24 #define IEEE802154_TXPOWER_INDEX_MIN 0 + +#define IEEE802154_RSSI_COMPENSATION_VALUE 10 diff --git a/components/hal/esp32h2/include/hal/lp_aon_hal.h b/components/hal/esp32h2/include/hal/lp_aon_hal.h new file mode 100644 index 0000000000..c38f6da831 --- /dev/null +++ b/components/hal/esp32h2/include/hal/lp_aon_hal.h @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "hal/lp_aon_ll.h" + +#define rtc_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status() +#define rtc_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status() +#define rtc_hal_ext1_set_wakeup_pins(io_mask, mode_mask) lp_aon_ll_ext1_set_wakeup_pins(io_mask, mode_mask) +#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins() +#define rtc_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins() + +#define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp) diff --git a/components/hal/esp32h2/include/hal/lp_aon_ll.h b/components/hal/esp32h2/include/hal/lp_aon_ll.h new file mode 100644 index 0000000000..53e1f1fa5d --- /dev/null +++ b/components/hal/esp32h2/include/hal/lp_aon_ll.h @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-H2 LP_AON register operations + +#pragma once + +#include +#include "soc/soc.h" +#include "soc/lp_aon_struct.h" +#include "hal/misc.h" +#include "esp32h2/rom/rtc.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Get ext1 wakeup source status + * @return The lower 8 bits of the returned value are the bitmap of + * the wakeup source status, bit 0~7 corresponds to LP_IO 0~7 + */ +static inline uint32_t lp_aon_ll_ext1_get_wakeup_status(void) +{ + return HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_status); +} + +/** + * @brief Clear the ext1 wakeup source status + */ +static inline void lp_aon_ll_ext1_clear_wakeup_status(void) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_status_clr, 1); +} + +/** + * @brief Set the wake-up LP_IO of the ext1 wake-up source + * @param io_mask wakeup LP_IO bitmap, bit 0~7 corresponds to LP_IO 0~7 + * @param level_mask LP_IO wakeup level bitmap, bit 0~7 corresponds to LP_IO 0~7 wakeup level + * each bit's corresponding position is set to 0, the wakeup level will be low + * on the contrary, each bit's corresponding position is set to 1, the wakeup + * level will be high + */ +static inline void lp_aon_ll_ext1_set_wakeup_pins(uint32_t io_mask, uint32_t level_mask) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, io_mask); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv, level_mask); +} + +/** + * @brief Clear all ext1 wakup-source setting + */ +static inline void lp_aon_ll_ext1_clear_wakeup_pins(void) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, 0); +} + +/** + * @brief Get ext1 wakeup source setting + * @return The lower 8 bits of the returned value are the bitmap of + * the wakeup source status, bit 0~7 corresponds to LP_IO 0~7 + */ +static inline uint32_t lp_aon_ll_ext1_get_wakeup_pins(void) +{ + return HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel); +} + + +/** + * @brief ROM obtains the wake-up type through LP_AON_STORE9_REG[0]. + * Set the flag to inform + * @param true: deepsleep false: lightsleep + */ +static inline void lp_aon_ll_inform_wakeup_type(bool dslp) +{ + if (dslp) { + REG_SET_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */ + + } else { + REG_CLR_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */ + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32h2/include/hal/lp_timer_ll.h b/components/hal/esp32h2/include/hal/lp_timer_ll.h index c57588c78f..46ed66c7df 100644 --- a/components/hal/esp32h2/include/hal/lp_timer_ll.h +++ b/components/hal/esp32h2/include/hal/lp_timer_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,8 @@ #include "soc/lp_timer_struct.h" #include "soc/lp_aon_reg.h" #include "hal/lp_timer_types.h" +#include "hal/misc.h" +#include "esp_attr.h" #ifdef __cplusplus extern "C" { @@ -21,8 +23,8 @@ extern "C" { FORCE_INLINE_ATTR void lp_timer_ll_set_alarm_target(lp_timer_dev_t *dev, uint8_t timer_id, uint64_t value) { - dev->target[timer_id].hi.target_hi = (value >> 32) & 0xFFFF; - dev->target[timer_id].lo.target_lo = value & 0xFFFFFFFF; + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].hi, target_hi, (value >> 32) & 0xFFFF); + HAL_FORCE_MODIFY_U32_REG_FIELD(dev->target[timer_id].lo, target_lo, value & 0xFFFFFFFF); } FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_t timer_id, bool en) @@ -32,12 +34,12 @@ FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_ FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_low(lp_timer_dev_t *dev, uint8_t timer_id) { - return dev->counter[timer_id].lo.counter_lo; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[timer_id].lo, counter_lo); } FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_high(lp_timer_dev_t *dev, uint8_t timer_id) { - return dev->counter[timer_id].hi.counter_hi; + return HAL_FORCE_READ_U32_REG_FIELD(dev->counter[timer_id].hi, counter_hi); } FORCE_INLINE_ATTR void lp_timer_ll_counter_snapshot(lp_timer_dev_t *dev) diff --git a/components/hal/esp32h2/include/hal/lpwdt_ll.h b/components/hal/esp32h2/include/hal/lpwdt_ll.h index b6009dbc7b..01c7751f2e 100644 --- a/components/hal/esp32h2/include/hal/lpwdt_ll.h +++ b/components/hal/esp32h2/include/hal/lpwdt_ll.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 */ @@ -23,6 +23,43 @@ extern "C" { #include "esp32h2/rom/ets_sys.h" +/* The value that needs to be written to LP_WDT_WKEY to write-enable the wdt registers */ +#define LP_WDT_WKEY_VALUE 0x50D83AA1 +/* The value that needs to be written to LP_WDT_SWD_WPROTECT_REG to write-enable the swd registers */ +#define LP_WDT_SWD_WKEY_VALUE 0x50D83AA1 + +/* Possible values for LP_WDT_CPU_RESET_LENGTH and LP_WDT_SYS_RESET_LENGTH */ +#define LP_WDT_RESET_LENGTH_100_NS 0 +#define LP_WDT_RESET_LENGTH_200_NS 1 +#define LP_WDT_RESET_LENGTH_300_NS 2 +#define LP_WDT_RESET_LENGTH_400_NS 3 +#define LP_WDT_RESET_LENGTH_500_NS 4 +#define LP_WDT_RESET_LENGTH_800_NS 5 +#define LP_WDT_RESET_LENGTH_1600_NS 6 +#define LP_WDT_RESET_LENGTH_3200_NS 7 + +#define LP_WDT_STG_SEL_OFF 0 +#define LP_WDT_STG_SEL_INT 1 +#define LP_WDT_STG_SEL_RESET_CPU 2 +#define LP_WDT_STG_SEL_RESET_SYSTEM 3 +#define LP_WDT_STG_SEL_RESET_RTC 4 + +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_OFF == LP_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_INT == LP_WDT_STG_SEL_INT, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_CPU == LP_WDT_STG_SEL_RESET_CPU, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_SYSTEM == LP_WDT_STG_SEL_RESET_SYSTEM, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +ESP_STATIC_ASSERT(WDT_STAGE_ACTION_RESET_RTC == LP_WDT_STG_SEL_RESET_RTC, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); +//Type check wdt_reset_sig_length_t +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_100ns == LP_WDT_RESET_LENGTH_100_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_200ns == LP_WDT_RESET_LENGTH_200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_300ns == LP_WDT_RESET_LENGTH_300_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_400ns == LP_WDT_RESET_LENGTH_400_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_500ns == LP_WDT_RESET_LENGTH_500_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_800ns == LP_WDT_RESET_LENGTH_800_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_1_6us == LP_WDT_RESET_LENGTH_1600_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); +ESP_STATIC_ASSERT(WDT_RESET_SIG_LENGTH_3_2us == LP_WDT_RESET_LENGTH_3200_NS, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_reset_sig_length_t"); + + /** * @brief Enable the RWDT * @@ -30,7 +67,7 @@ extern "C" { */ FORCE_INLINE_ATTR void lpwdt_ll_enable(lp_wdt_dev_t *hw) { - // hw->config0.en = 1; + hw->config0.wdt_en = 1; } /** @@ -43,7 +80,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_enable(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_disable(lp_wdt_dev_t *hw) { - // hw->config0.en = 0; + hw->config0.wdt_en = 0; } /** @@ -54,7 +91,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_disable(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR bool lpwdt_ll_check_if_enabled(lp_wdt_dev_t *hw) { - return false;//(hw->config0.en) ? true : false; + return (hw->config0.wdt_en) ? true : false; } /** @@ -77,27 +114,27 @@ FORCE_INLINE_ATTR bool lpwdt_ll_check_if_enabled(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_config_stage(lp_wdt_dev_t *hw, wdt_stage_t stage, uint32_t timeout_ticks, wdt_stage_action_t behavior) { - // switch (stage) { - // case WDT_STAGE0: - // hw->config0.stg0 = behavior; - // //Account of implicty multiplier applied to stage 0 timeout tick config value - // hw->config1 = timeout_ticks >> (1 + REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_WDT_DELAY_SEL)); - // break; - // case WDT_STAGE1: - // hw->config0.stg1 = behavior; - // hw->config2 = timeout_ticks; - // break; - // case WDT_STAGE2: - // hw->config0.stg2 = behavior; - // hw->config3 = timeout_ticks; - // break; - // case WDT_STAGE3: - // hw->config0.stg3 = behavior; - // hw->config4 = timeout_ticks; - // break; - // default: - // abort(); - // } + switch (stage) { + case WDT_STAGE0: + hw->config0.wdt_stg0 = behavior; + //Account of implicty multiplier applied to stage 0 timeout tick config value + hw->config1.val = timeout_ticks >> (1 + REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, EFUSE_WDT_DELAY_SEL)); + break; + case WDT_STAGE1: + hw->config0.wdt_stg1 = behavior; + hw->config2.val = timeout_ticks; + break; + case WDT_STAGE2: + hw->config0.wdt_stg2 = behavior; + hw->config3.val = timeout_ticks; + break; + case WDT_STAGE3: + hw->config0.wdt_stg3 = behavior; + hw->config4.val = timeout_ticks; + break; + default: + abort(); + } } /** @@ -108,22 +145,22 @@ FORCE_INLINE_ATTR void lpwdt_ll_config_stage(lp_wdt_dev_t *hw, wdt_stage_t stage */ FORCE_INLINE_ATTR void lpwdt_ll_disable_stage(lp_wdt_dev_t *hw, wdt_stage_t stage) { - // switch (stage) { - // case WDT_STAGE0: - // hw->config0.stg0 = WDT_STAGE_ACTION_OFF; - // break; - // case WDT_STAGE1: - // hw->config0.stg1 = WDT_STAGE_ACTION_OFF; - // break; - // case WDT_STAGE2: - // hw->config0.stg2 = WDT_STAGE_ACTION_OFF; - // break; - // case WDT_STAGE3: - // hw->config0.stg3 = WDT_STAGE_ACTION_OFF; - // break; - // default: - // abort(); - // } + switch (stage) { + case WDT_STAGE0: + hw->config0.wdt_stg0 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE1: + hw->config0.wdt_stg1 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE2: + hw->config0.wdt_stg2 = WDT_STAGE_ACTION_OFF; + break; + case WDT_STAGE3: + hw->config0.wdt_stg3 = WDT_STAGE_ACTION_OFF; + break; + default: + abort(); + } } /** @@ -134,7 +171,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_disable_stage(lp_wdt_dev_t *hw, wdt_stage_t stag */ FORCE_INLINE_ATTR void lpwdt_ll_set_cpu_reset_length(lp_wdt_dev_t *hw, wdt_reset_sig_length_t length) { - // hw->config0.cpu_reset_length = length; + hw->config0.wdt_cpu_reset_length = length; } /** @@ -145,7 +182,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_cpu_reset_length(lp_wdt_dev_t *hw, wdt_reset */ FORCE_INLINE_ATTR void lpwdt_ll_set_sys_reset_length(lp_wdt_dev_t *hw, wdt_reset_sig_length_t length) { - // hw->config0.sys_reset_length = length; + hw->config0.wdt_sys_reset_length = length; } /** @@ -160,7 +197,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_sys_reset_length(lp_wdt_dev_t *hw, wdt_reset */ FORCE_INLINE_ATTR void lpwdt_ll_set_flashboot_en(lp_wdt_dev_t *hw, bool enable) { - // hw->config0.flashboot_mod_en = (enable) ? 1 : 0; + hw->config0.wdt_flashboot_mod_en = (enable) ? 1 : 0; } /** @@ -171,7 +208,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_flashboot_en(lp_wdt_dev_t *hw, bool enable) */ FORCE_INLINE_ATTR void lpwdt_ll_set_procpu_reset_en(lp_wdt_dev_t *hw, bool enable) { - // hw->config0.procpu_reset_en = (enable) ? 1 : 0; + hw->config0.wdt_procpu_reset_en = (enable) ? 1 : 0; } /** @@ -182,7 +219,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_procpu_reset_en(lp_wdt_dev_t *hw, bool enabl */ FORCE_INLINE_ATTR void lpwdt_ll_set_appcpu_reset_en(lp_wdt_dev_t *hw, bool enable) { - // hw->config0.appcpu_reset_en = (enable) ? 1 : 0; + hw->config0.wdt_appcpu_reset_en = (enable) ? 1 : 0; } /** @@ -193,7 +230,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_appcpu_reset_en(lp_wdt_dev_t *hw, bool enabl */ FORCE_INLINE_ATTR void lpwdt_ll_set_pause_in_sleep_en(lp_wdt_dev_t *hw, bool enable) { - // hw->config0.pause_in_slp = (enable) ? 1 : 0; + hw->config0.wdt_pause_in_slp = (enable) ? 1 : 0; } /** @@ -207,19 +244,17 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_pause_in_sleep_en(lp_wdt_dev_t *hw, bool ena */ FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_en(lp_wdt_dev_t *hw, bool enable) { - // hw->config5.chip_reset_en = (enable) ? 1 : 0; + hw->config5.chip_reset_en = (enable) ? 1 : 0; } /** - * @brief Set width of chip reset signal - * - * @param hw Start address of the peripheral registers. - * @param width Width of chip reset signal in terms of number of RTC_SLOW_CLK cycles + * @brief No register for setting reset width on H2, we keep an empty function to + * provide the same HAL interface as other targets. */ FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_width(lp_wdt_dev_t *hw, uint32_t width) { - // ESP32H2-TODO: IDF-6402 - // HAL_FORCE_MODIFY_U32_REG_FIELD(hw->config0, chip_reset_width, width); + (void)hw; + (void)width; } /** @@ -231,8 +266,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_chip_reset_width(lp_wdt_dev_t *hw, uint32_t */ FORCE_INLINE_ATTR void lpwdt_ll_feed(lp_wdt_dev_t *hw) { - // ESP32H2-TODO: IDF-6402 - // hw->feed.rtc_wdt_feed = 1; + hw->feed.rtc_wdt_feed = 1; } /** @@ -242,8 +276,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_feed(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_write_protect_enable(lp_wdt_dev_t *hw) { - // ESP32H2-TODO: IDF-6402 - // hw->wprotect = 0; + hw->wprotect.val = 0; } /** @@ -253,8 +286,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_write_protect_enable(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_write_protect_disable(lp_wdt_dev_t *hw) { - // ESP32H2-TODO: IDF-6402 - // hw->wprotect = RTC_CNTL_WDT_WKEY_VALUE; + hw->wprotect.val = LP_WDT_WKEY_VALUE; } /** @@ -265,8 +297,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_write_protect_disable(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_set_intr_enable(lp_wdt_dev_t *hw, bool enable) { - // ESP32H2-TODO: IDF-6402 - // hw->int_ena.lp_wdt_int_ena = (enable) ? 1 : 0; + hw->int_ena.lp_wdt_int_ena = (enable) ? 1 : 0; } /** @@ -277,7 +308,7 @@ FORCE_INLINE_ATTR void lpwdt_ll_set_intr_enable(lp_wdt_dev_t *hw, bool enable) */ FORCE_INLINE_ATTR bool lpwdt_ll_check_intr_status(lp_wdt_dev_t *hw) { - return false;//(hw->int_st.lp_wdt_int_st) ? true : false; // ESP32H2-TODO: IDF-6402 + return (hw->int_st.lp_wdt_int_st) ? true : false; } /** @@ -287,8 +318,7 @@ FORCE_INLINE_ATTR bool lpwdt_ll_check_intr_status(lp_wdt_dev_t *hw) */ FORCE_INLINE_ATTR void lpwdt_ll_clear_intr_status(lp_wdt_dev_t *hw) { - // ESP32H2-TODO: IDF-6402 - // hw->int_clr.lp_wdt_int_clr = 1; + hw->int_clr.lp_wdt_int_clr = 1; } #ifdef __cplusplus diff --git a/components/hal/esp32h2/include/hal/mcpwm_ll.h b/components/hal/esp32h2/include/hal/mcpwm_ll.h index 1023d11531..c4e52ab197 100644 --- a/components/hal/esp32h2/include/hal/mcpwm_ll.h +++ b/components/hal/esp32h2/include/hal/mcpwm_ll.h @@ -43,8 +43,12 @@ extern "C" { #define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27)) // Maximum values due to limited register bit width +#define MCPWM_LL_MAX_GROUP_PRESCALE 256 +#define MCPWM_LL_MAX_TIMER_PRESCALE 256 +#define MCPWM_LL_MAX_CARRIER_PRESCALE 16 #define MCPWM_LL_MAX_CARRIER_ONESHOT 16 #define MCPWM_LL_MAX_CAPTURE_PRESCALE 256 +#define MCPWM_LL_MAX_CAPTURE_TIMER_PRESCALE 1 #define MCPWM_LL_MAX_DEAD_DELAY 65536 #define MCPWM_LL_MAX_COUNT_VALUE 65536 @@ -101,13 +105,14 @@ static inline void mcpwm_ll_group_enable_clock(mcpwm_dev_t *mcpwm, bool en) * @brief Set the MCPWM group clock prescale * * @param mcpwm Peripheral instance address - * @param pre_scale Prescale value + * @param prescale Prescale value */ -static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int pre_scale) +static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale) { (void)mcpwm; // only one MCPWM instance - // group clock: PWM_clk = source_clock / (prescale + 1) - HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.pwm_clk_conf, pwm_div_num, pre_scale - 1); + // group clock: PWM_clk = source_clock / (prescale) + HAL_ASSERT(prescale <= 256 && prescale > 0); + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.pwm_clk_conf, pwm_div_num, prescale - 1); } /** @@ -211,13 +216,12 @@ static inline void mcpwm_ll_timer_set_clock_prescale(mcpwm_dev_t *mcpwm, int tim * @param peak Peak value * @param symmetric True to set symmetric peak value, False to set asymmetric peak value */ +__attribute__((always_inline)) static inline void mcpwm_ll_timer_set_peak(mcpwm_dev_t *mcpwm, int timer_id, uint32_t peak, bool symmetric) { if (!symmetric) { // in asymmetric mode, period = [0,peak-1] - HAL_ASSERT(peak > 0 && peak <= MCPWM_LL_MAX_COUNT_VALUE); HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period, peak - 1); } else { // in symmetric mode, period = [0,peak-1] + [peak,1] - HAL_ASSERT(peak < MCPWM_LL_MAX_COUNT_VALUE); HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period, peak); } } @@ -713,20 +717,20 @@ static inline void mcpwm_ll_operator_stop_update_action(mcpwm_dev_t *mcpwm, int * @param trig_id Trigger ID, index from 0 to 1 * @param fault_gpio_id Fault GPIO ID, index from 0 to 3 */ -static inline void mcpwm_ll_operator_set_trigger_from_gpio(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_gpio_id) +static inline void mcpwm_ll_operator_set_trigger_from_gpio_fault(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_gpio_id) { mcpwm->operators[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id)); mcpwm->operators[operator_id].gen_cfg0.val |= (fault_gpio_id << (4 + 3 * trig_id)); } /** - * @brief Set trigger from timer sync event (when the timer taken the sync signal) + * @brief Set trigger from sync event (when the timer/gpio/soft taken the sync signal) * * @param mcpwm Peripheral instance address * @param operator_id Operator ID, index from 0 to 2 * @param trig_id Trigger ID, index from 0 to 1 */ -static inline void mcpwm_ll_operator_set_trigger_from_timer_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id) +static inline void mcpwm_ll_operator_set_trigger_from_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id) { // the timer here is not selectable, must be the one connected with the operator mcpwm->operators[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id)); diff --git a/components/hal/esp32h2/include/hal/mmu_ll.h b/components/hal/esp32h2/include/hal/mmu_ll.h index c4c17d7bb7..169ae88103 100644 --- a/components/hal/esp32h2/include/hal/mmu_ll.h +++ b/components/hal/esp32h2/include/hal/mmu_ll.h @@ -105,7 +105,7 @@ static inline bool mmu_ll_check_valid_ext_vaddr_region(uint32_t mmu_id, uint32_t { (void)mmu_id; (void)type; - uint32_t vaddr_end = vaddr_start + len; + uint32_t vaddr_end = vaddr_start + len - 1; return (ADDRESS_IN_IRAM0_CACHE(vaddr_start) && ADDRESS_IN_IRAM0_CACHE(vaddr_end)) || (ADDRESS_IN_DRAM0_CACHE(vaddr_start) && ADDRESS_IN_DRAM0_CACHE(vaddr_end)); } diff --git a/components/hal/esp32h2/include/hal/mwdt_ll.h b/components/hal/esp32h2/include/hal/mwdt_ll.h index e25f377240..49a1238be1 100644 --- a/components/hal/esp32h2/include/hal/mwdt_ll.h +++ b/components/hal/esp32h2/include/hal/mwdt_ll.h @@ -24,7 +24,7 @@ extern "C" { #include "hal/misc.h" /* Pre-calculated prescaler to achieve 500 ticks/us (MWDT1_TICKS_PER_US) when using default clock (MWDT_CLK_SRC_DEFAULT ) */ -#define MWDT_LL_DEFAULT_CLK_PRESCALER 24000 +#define MWDT_LL_DEFAULT_CLK_PRESCALER 16000 //Type check wdt_stage_action_t _Static_assert(WDT_STAGE_ACTION_OFF == TIMG_WDT_STG_SEL_OFF, "Add mapping to LL watchdog timeout behavior, since it's no longer naturally compatible with wdt_stage_action_t"); diff --git a/components/hal/esp32h2/include/hal/parlio_ll.h b/components/hal/esp32h2/include/hal/parlio_ll.h index ddf7946b99..b594f02add 100644 --- a/components/hal/esp32h2/include/hal/parlio_ll.h +++ b/components/hal/esp32h2/include/hal/parlio_ll.h @@ -87,7 +87,7 @@ static inline void parlio_ll_rx_set_clock_div(parl_io_dev_t *dev, uint32_t div) { (void)dev; HAL_ASSERT(div > 0 && div <= PARLIO_LL_RX_MAX_CLOCK_DIV); - PCR.parl_clk_rx_conf.parl_clk_rx_div_num = div - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.parl_clk_rx_conf, parl_clk_rx_div_num, div - 1); } /** @@ -373,7 +373,7 @@ static inline void parlio_ll_tx_set_clock_div(parl_io_dev_t *dev, uint32_t div) { (void)dev; HAL_ASSERT(div > 0 && div <= PARLIO_LL_TX_MAX_CLOCK_DIV); - PCR.parl_clk_tx_conf.parl_clk_tx_div_num = div - 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.parl_clk_tx_conf, parl_clk_tx_div_num, div - 1); } /** diff --git a/components/hal/esp32h2/include/hal/pmu_ll.h b/components/hal/esp32h2/include/hal/pmu_ll.h index d666973e2f..1272e2fb24 100644 --- a/components/hal/esp32h2/include/hal/pmu_ll.h +++ b/components/hal/esp32h2/include/hal/pmu_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,7 @@ #include "hal/assert.h" #include "soc/pmu_struct.h" #include "hal/pmu_types.h" +#include "hal/misc.h" #ifdef __cplusplus extern "C" { @@ -446,7 +447,7 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode) FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->wakeup.cntl3.hp_min_slp_val = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, hp_min_slp_val, cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw) @@ -486,27 +487,27 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_reject_cause(pmu_dev_t *hw) FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, lp_min_slp_val, slow_clk_cycle); } FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.modify_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, modify_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw) { - return hw->hp_ext.clk_cntl.switch_icg_cntl_wait; + return HAL_FORCE_READ_U32_REG_FIELD(hw->hp_ext.clk_cntl, switch_icg_cntl_wait); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -531,32 +532,32 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) { - hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target, slow_clk_cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl5.lp_ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl5, lp_ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_xtal_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_xtal_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_xtal_stable); } FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->power.clk_wait.wait_pll_stable = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw) { - return hw->power.clk_wait.wait_pll_stable; + return HAL_FORCE_READ_U32_REG_FIELD(hw->power.clk_wait, wait_pll_stable); } FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) @@ -581,12 +582,12 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t * FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) { - hw->wakeup.cntl7.ana_wait_target = cycle; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target, cycle); } FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw) { - return hw->wakeup.cntl7.ana_wait_target; + return HAL_FORCE_READ_U32_REG_FIELD(hw->wakeup.cntl7, ana_wait_target); } FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) diff --git a/components/hal/esp32h2/include/hal/rmt_ll.h b/components/hal/esp32h2/include/hal/rmt_ll.h index d290163f59..ebd4615bfb 100644 --- a/components/hal/esp32h2/include/hal/rmt_ll.h +++ b/components/hal/esp32h2/include/hal/rmt_ll.h @@ -55,15 +55,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -450,6 +471,7 @@ static inline void rmt_ll_rx_set_channel_clock_div(rmt_dev_t *dev, uint32_t chan * @param dev Peripheral instance address * @param channel RMT RX channel number */ +__attribute__((always_inline)) static inline void rmt_ll_rx_reset_pointer(rmt_dev_t *dev, uint32_t channel) { dev->chmconf[channel].conf1.mem_wr_rst_chm = 1; @@ -492,6 +514,7 @@ static inline void rmt_ll_rx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, ui * @param channel RMT RX channel number * @param thres Time length threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { dev->chmconf[channel].conf0.idle_thres_chm = thres; @@ -517,6 +540,7 @@ static inline void rmt_ll_rx_set_mem_owner(rmt_dev_t *dev, uint32_t channel, rmt * @param channel RMT RX chanenl number * @param enable True to enable, False to disable */ +__attribute__((always_inline)) static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable) { dev->chmconf[channel].conf1.rx_filter_en_chm = enable; @@ -529,6 +553,7 @@ static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, boo * @param channel RMT RX channel number * @param thres Filter threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chmconf[channel].conf1, rx_filter_thres_chm, thres); @@ -784,12 +809,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32h2/include/hal/rtc_io_ll.h b/components/hal/esp32h2/include/hal/rtc_io_ll.h new file mode 100644 index 0000000000..1205098a85 --- /dev/null +++ b/components/hal/esp32h2/include/hal/rtc_io_ll.h @@ -0,0 +1,104 @@ +/* + * 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/readme.md + ******************************************************************************/ + +#pragma once + +#include "soc/lp_aon_struct.h" +#include "soc/pmu_struct.h" +#include "hal/misc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTCIO_LL_GPIO_NUM_OFFSET 7 // rtcio 0-7 correspond to gpio 7-14 + +typedef enum { + RTCIO_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */ + RTCIO_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */ +} rtcio_ll_func_t; + +/** + * @brief Select the rtcio function. + * + * @note The RTC function must be selected before the pad analog function is enabled. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + * @param func Select pin function. + */ +static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) +{ + if (func == RTCIO_FUNC_RTC) { + // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. + uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); + sel_mask |= BIT(rtcio_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); + } else if (func == RTCIO_FUNC_DIGITAL) { + // Clear the bit to use digital GPIO module + uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel); + sel_mask &= ~BIT(rtcio_num); + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask); + } +} + +/** + * Enable force hold function for an RTC IO pad. + * + * Enabling HOLD function will cause the pad to lock current status, such as, + * input/output enable, input/output value, function, drive strength values. + * This function is useful when going into light or deep sleep mode to prevent + * the pin configuration from changing. + * + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_force_hold_enable(int rtcio_num) +{ + LP_AON.gpio_hold0.gpio_hold0 |= BIT(rtcio_num + RTCIO_LL_GPIO_NUM_OFFSET); +} + +/** + * Disable hold function on an RTC IO pad + * + * @note If disable the pad hold, the status of pad maybe changed in sleep mode. + * @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio). + */ +static inline void rtcio_ll_force_hold_disable(int rtcio_num) +{ + LP_AON.gpio_hold0.gpio_hold0 &= ~BIT(rtcio_num + RTCIO_LL_GPIO_NUM_OFFSET); +} + +/** + * Enable force hold function for all RTC IO pads + * + * Enabling HOLD function will cause the pad to lock current status, such as, + * input/output enable, input/output value, function, drive strength values. + * This function is useful when going into light or deep sleep mode to prevent + * the pin configuration from changing. + */ +static inline void rtcio_ll_force_hold_all(void) +{ + PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1; +} + +/** + * Disable hold function fon all RTC IO pads + * + * @note If disable the pad hold, the status of pad maybe changed in sleep mode. + */ +static inline void rtcio_ll_force_unhold_all(void) +{ + PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32h2/include/hal/spi_ll.h b/components/hal/esp32h2/include/hal/spi_ll.h index 64de7c12fe..2e835e7552 100644 --- a/components/hal/esp32h2/include/hal/spi_ll.h +++ b/components/hal/esp32h2/include/hal/spi_ll.h @@ -43,6 +43,7 @@ extern "C" { #define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits #define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words +#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized /** * The data structure holding calculated clock configuration. Since the @@ -192,36 +193,44 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw) } /** - * Check whether user-defined transaction is done. + * Determine and unify the default level of mosi line when bus free * * @param hw Beginning address of the peripheral registers. - * - * @return True if transaction is done, otherwise false. */ -static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level) { - return hw->dma_int_raw.trans_done_int_raw; + hw->ctrl.d_pol = level; //set default level for MOSI only on IDLE state } /** - * Trigger start of user-defined transaction for master. - * The synchronization between two clock domains is required in ESP32-S3 + * Apply the register configurations and wait until it's done * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_master_user_start(spi_dev_t *hw) +static inline void spi_ll_apply_config(spi_dev_t *hw) { hw->cmd.update = 1; - while (hw->cmd.update); - hw->cmd.usr = 1; + while (hw->cmd.update); //waiting config applied +} + +/** + * Check whether user-defined transaction is done. + * + * @param hw Beginning address of the peripheral registers. + * + * @return True if transaction is done, otherwise false. + */ +static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +{ + return hw->dma_int_raw.trans_done_int_raw; } /** - * Trigger start of user-defined transaction for slave. + * Trigger start of user-defined transaction. * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_slave_user_start(spi_dev_t *hw) +static inline void spi_ll_user_start(spi_dev_t *hw) { hw->cmd.usr = 1; } diff --git a/components/hal/esp32h2/include/hal/timer_ll.h b/components/hal/esp32h2/include/hal/timer_ll.h index 70d0e4f8da..17574d6457 100644 --- a/components/hal/esp32h2/include/hal/timer_ll.h +++ b/components/hal/esp32h2/include/hal/timer_ll.h @@ -235,6 +235,7 @@ static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, * @param timer_num Timer number in the group * @return reload count value */ +__attribute__((always_inline)) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num) { return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo); @@ -246,6 +247,7 @@ static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_ * @param hw Timer Group register base address * @param timer_num Timer number in the group */ +__attribute__((always_inline)) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num) { hw->hw_timer[timer_num].load.tx_load = 1; diff --git a/components/hal/esp32h2/include/hal/uart_ll.h b/components/hal/esp32h2/include/hal/uart_ll.h index 909bbb5d62..504fd4a47a 100644 --- a/components/hal/esp32h2/include/hal/uart_ll.h +++ b/components/hal/esp32h2/include/hal/uart_ll.h @@ -29,7 +29,7 @@ extern "C" { // Get UART hardware instance with giving uart num #define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1)) -#define UART_LL_MIN_WAKEUP_THRESH (2) +#define UART_LL_MIN_WAKEUP_THRESH (3) #define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask #define UART_LL_FSM_IDLE (0x0) @@ -121,7 +121,7 @@ FORCE_INLINE_ATTR void uart_ll_update(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) +FORCE_INLINE_ATTR void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) { UART_LL_PCR_REG_SET(hw, conf, rst_en, core_rst_en); } @@ -133,7 +133,7 @@ static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) * * @return None. */ -static inline void uart_ll_sclk_enable(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_sclk_enable(uart_dev_t *hw) { UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1); } @@ -145,7 +145,7 @@ static inline void uart_ll_sclk_enable(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_sclk_disable(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_sclk_disable(uart_dev_t *hw) { UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0); } @@ -159,7 +159,7 @@ static inline void uart_ll_sclk_disable(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) +FORCE_INLINE_ATTR void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) { switch (source_clk) { default: @@ -183,7 +183,7 @@ static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) * * @return None. */ -static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk) +FORCE_INLINE_ATTR void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk) { switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) { default: @@ -208,11 +208,13 @@ static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk) * * @return None */ -static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq) +FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t sclk_freq) { #define DIV_UP(a, b) (((a) + (b) - 1) / (b)) const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits - int sclk_div = DIV_UP(sclk_freq, max_div * baud); + uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud); + + if (sclk_div == 0) abort(); uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div); // The baud rate configuration register is divided into @@ -232,7 +234,7 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t * * @return The current baudrate */ -static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) +FORCE_INLINE_ATTR uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) { typeof(hw->clkdiv_sync) div_reg; div_reg.val = hw->clkdiv_sync.val; @@ -247,7 +249,7 @@ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) * * @return None */ -static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) +FORCE_INLINE_ATTR void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) { hw->int_ena.val |= mask; } @@ -260,7 +262,7 @@ static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) * * @return None */ -static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) +FORCE_INLINE_ATTR void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) { hw->int_ena.val &= (~mask); } @@ -272,7 +274,7 @@ static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) * * @return The UART interrupt status. */ -static inline uint32_t uart_ll_get_intraw_mask(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_intraw_mask(uart_dev_t *hw) { return hw->int_raw.val; } @@ -284,7 +286,7 @@ static inline uint32_t uart_ll_get_intraw_mask(uart_dev_t *hw) * * @return The UART interrupt status. */ -static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) { return hw->int_st.val; } @@ -297,7 +299,7 @@ static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) * * @return None */ -static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) +FORCE_INLINE_ATTR void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) { hw->int_clr.val = mask; } @@ -309,7 +311,7 @@ static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) * * @return interrupt enable value */ -static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) { return hw->int_ena.val; } @@ -323,7 +325,7 @@ static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len) +FORCE_INLINE_ATTR void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len) { for (int i = 0; i < (int)rd_len; i++) { buf[i] = hw->fifo.rxfifo_rd_byte; @@ -339,7 +341,7 @@ static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd * * @return None */ -static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len) +FORCE_INLINE_ATTR void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len) { for (int i = 0; i < (int)wr_len; i++) { hw->fifo.rxfifo_rd_byte = buf[i]; @@ -353,7 +355,7 @@ static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint * * @return None */ -static inline void uart_ll_rxfifo_rst(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_rxfifo_rst(uart_dev_t *hw) { hw->conf0_sync.rxfifo_rst = 1; uart_ll_update(hw); @@ -368,7 +370,7 @@ static inline void uart_ll_rxfifo_rst(uart_dev_t *hw) * * @return None */ -static inline void uart_ll_txfifo_rst(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_txfifo_rst(uart_dev_t *hw) { hw->conf0_sync.txfifo_rst = 1; uart_ll_update(hw); @@ -383,7 +385,7 @@ static inline void uart_ll_txfifo_rst(uart_dev_t *hw) * * @return The readable data length in rxfifo. */ -static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) { return hw->status.rxfifo_cnt; } @@ -395,7 +397,7 @@ static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) * * @return The data length of txfifo can be written. */ -static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) { return UART_LL_FIFO_DEF_LEN - hw->status.txfifo_cnt; } @@ -408,7 +410,7 @@ static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit) +FORCE_INLINE_ATTR void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit) { hw->conf0_sync.stop_bit_num = stop_bit; uart_ll_update(hw); @@ -422,7 +424,7 @@ static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_b * * @return None. */ -static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit) +FORCE_INLINE_ATTR void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_bit) { *stop_bit = (uart_stop_bits_t)hw->conf0_sync.stop_bit_num; } @@ -435,7 +437,7 @@ static inline void uart_ll_get_stop_bits(uart_dev_t *hw, uart_stop_bits_t *stop_ * * @return None. */ -static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) +FORCE_INLINE_ATTR void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) { if (parity_mode != UART_PARITY_DISABLE) { hw->conf0_sync.parity = parity_mode & 0x1; @@ -452,7 +454,7 @@ static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) * * @return None. */ -static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode) +FORCE_INLINE_ATTR void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode) { if (hw->conf0_sync.parity_en) { *parity_mode = (uart_parity_t)(0x2 | hw->conf0_sync.parity); @@ -470,7 +472,7 @@ static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode * * @return None. */ -static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) +FORCE_INLINE_ATTR void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) { hw->conf1.rxfifo_full_thrhd = full_thrhd; } @@ -484,7 +486,7 @@ static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thr * * @return None. */ -static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) +FORCE_INLINE_ATTR void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) { hw->conf1.txfifo_empty_thrhd = empty_thrhd; } @@ -498,7 +500,7 @@ static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_t * * @return None. */ -static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) +FORCE_INLINE_ATTR void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) { hw->idle_conf_sync.rx_idle_thrhd = rx_idle_thr; uart_ll_update(hw); @@ -512,7 +514,7 @@ static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) * * @return None. */ -static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) +FORCE_INLINE_ATTR void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) { hw->idle_conf_sync.tx_idle_num = idle_num; uart_ll_update(hw); @@ -526,7 +528,7 @@ static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) * * @return None. */ -static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) +FORCE_INLINE_ATTR void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) { if (break_num > 0) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->txbrk_conf_sync, tx_brk_num, break_num); @@ -546,7 +548,7 @@ static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) * * @return None. */ -static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs) +FORCE_INLINE_ATTR void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t flow_ctrl, uint32_t rx_thrs) { //only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. if (flow_ctrl & UART_HW_FLOWCTRL_RTS) { @@ -571,7 +573,7 @@ static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_ * * @return None. */ -static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl) +FORCE_INLINE_ATTR void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_t *flow_ctrl) { *flow_ctrl = UART_HW_FLOWCTRL_DISABLE; if (hw->hwfc_conf_sync.rx_flow_en) { @@ -591,7 +593,7 @@ static inline void uart_ll_get_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_ * * @return None. */ -static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en) +FORCE_INLINE_ATTR void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *flow_ctrl, bool sw_flow_ctrl_en) { if (sw_flow_ctrl_en) { hw->swfc_conf0_sync.xonoff_del = 1; @@ -620,7 +622,7 @@ static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t * * * @return None. */ -static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char) +FORCE_INLINE_ATTR void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, data, cmd_char->cmd_char); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, char_num, cmd_char->char_num); @@ -638,7 +640,7 @@ static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_ch * * @return None. */ -static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit) +FORCE_INLINE_ATTR void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit) { hw->conf0_sync.bit_num = data_bit; uart_ll_update(hw); @@ -652,7 +654,7 @@ static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t d * * @return None. */ -static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) +FORCE_INLINE_ATTR void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) { hw->conf0_sync.sw_rts = level & 0x1; uart_ll_update(hw); @@ -666,7 +668,7 @@ static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) * * @return None. */ -static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) +FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) { hw->conf1.sw_dtr = level & 0x1; } @@ -680,8 +682,9 @@ static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) * * @return None. */ -static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) +FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) { + // System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3) hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; } @@ -692,7 +695,7 @@ static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) * * @return None. */ -static inline void uart_ll_set_mode_normal(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_normal(uart_dev_t *hw) { hw->rs485_conf_sync.rs485_en = 0; hw->rs485_conf_sync.rs485tx_rx_en = 0; @@ -708,7 +711,7 @@ static inline void uart_ll_set_mode_normal(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) { // Application software control, remove echo hw->rs485_conf_sync.rs485rxby_tx_en = 1; @@ -728,7 +731,7 @@ static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) { // Enable receiver, sw_rts = 1 generates low level on RTS pin hw->conf0_sync.sw_rts = 1; @@ -751,7 +754,7 @@ static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_collision_detect(uart_dev_t *hw) { hw->conf0_sync.irda_en = 0; // Enable full-duplex mode @@ -772,7 +775,7 @@ static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode_irda(uart_dev_t *hw) +FORCE_INLINE_ATTR void uart_ll_set_mode_irda(uart_dev_t *hw) { hw->rs485_conf_sync.rs485_en = 0; hw->rs485_conf_sync.rs485tx_rx_en = 0; @@ -790,7 +793,7 @@ static inline void uart_ll_set_mode_irda(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) +FORCE_INLINE_ATTR void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) { switch (mode) { default: @@ -821,7 +824,7 @@ static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) * * @return None. */ -static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num) +FORCE_INLINE_ATTR void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num) { *cmd_char = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, data); *char_num = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, char_num); @@ -834,7 +837,7 @@ static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, ui * * @return The UART wakeup threshold value. */ -static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) { return hw->sleep_conf2.active_threshold + UART_LL_MIN_WAKEUP_THRESH; } @@ -847,7 +850,7 @@ static inline uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw) * * @return The bit mode. */ -static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit) +FORCE_INLINE_ATTR void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *data_bit) { *data_bit = (uart_word_length_t)hw->conf0_sync.bit_num; } @@ -859,7 +862,7 @@ static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t * * * @return True if the state machine is in the IDLE state, otherwise false is returned. */ -static inline bool uart_ll_is_tx_idle(uart_dev_t *hw) +FORCE_INLINE_ATTR bool uart_ll_is_tx_idle(uart_dev_t *hw) { return ((hw->status.txfifo_cnt == 0) && (hw->fsm_status.st_utx_out == 0)); } @@ -871,7 +874,7 @@ static inline bool uart_ll_is_tx_idle(uart_dev_t *hw) * * @return True if hw rts flow control is enabled, otherwise false is returned. */ -static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw) +FORCE_INLINE_ATTR bool uart_ll_is_hw_rts_en(uart_dev_t *hw) { return hw->hwfc_conf_sync.rx_flow_en; } @@ -883,7 +886,7 @@ static inline bool uart_ll_is_hw_rts_en(uart_dev_t *hw) * * @return True if hw cts flow control is enabled, otherwise false is returned. */ -static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw) +FORCE_INLINE_ATTR bool uart_ll_is_hw_cts_en(uart_dev_t *hw) { return hw->conf0_sync.tx_flow_en; } @@ -896,13 +899,13 @@ static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw) * * @return None */ -static inline void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en) +FORCE_INLINE_ATTR void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en) { hw->conf0_sync.loopback = loop_back_en; uart_ll_update(hw); } -static inline void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) +FORCE_INLINE_ATTR void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) { hw->swfc_conf0_sync.force_xon = 1; uart_ll_update(hw); @@ -921,7 +924,7 @@ static inline void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) * * @return None. */ -static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) +FORCE_INLINE_ATTR void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) { typeof(hw->conf0_sync) conf0_reg; conf0_reg.val = hw->conf0_sync.val; @@ -949,7 +952,7 @@ static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) * * @return None. */ -static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) +FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) { uint16_t tout_val = tout_thrd; if(tout_thrd > 0) { @@ -968,7 +971,7 @@ static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) * * @return tout_thr The timeout threshold value. If timeout feature is disabled returns 0. */ -static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) +FORCE_INLINE_ATTR uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) { uint16_t tout_thrd = 0; if(hw->tout_conf_sync.rx_tout_en > 0) { @@ -984,7 +987,7 @@ static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) * * @return maximum timeout threshold. */ -static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) +FORCE_INLINE_ATTR uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) { return UART_RX_TOUT_THRHD_V; } @@ -995,7 +998,7 @@ static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) * @param hw Beginning address of the peripheral registers. * @param enable Boolean marking whether the auto baudrate should be enabled or not. */ -static inline void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) +FORCE_INLINE_ATTR void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) { hw->conf0_sync.autobaud_en = enable ? 1 : 0; uart_ll_update(hw); @@ -1006,7 +1009,7 @@ static inline void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) { return hw->rxd_cnt.rxd_edge_cnt; } @@ -1016,7 +1019,7 @@ static inline uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) { return hw->pospulse.posedge_min_cnt; } @@ -1026,7 +1029,7 @@ static inline uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) { return hw->negpulse.negedge_min_cnt; } @@ -1036,7 +1039,7 @@ static inline uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) { return hw->highpulse.highpulse_min_cnt; } @@ -1046,7 +1049,7 @@ static inline uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw) * * @param hw Beginning address of the peripheral registers. */ -static inline uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) +FORCE_INLINE_ATTR uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) { return hw->lowpulse.lowpulse_min_cnt; } @@ -1058,7 +1061,7 @@ static inline uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) * * @return None. */ -static inline void uart_ll_force_xoff(uart_port_t uart_num) +FORCE_INLINE_ATTR void uart_ll_force_xoff(uart_port_t uart_num) { REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); @@ -1087,7 +1090,7 @@ FORCE_INLINE_ATTR void uart_ll_force_xon(uart_port_t uart_num) * * @return UART module FSM status. */ -static inline uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) +FORCE_INLINE_ATTR uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) { return REG_GET_FIELD(UART_FSM_STATUS_REG(uart_num), UART_ST_UTX_OUT); } @@ -1099,7 +1102,7 @@ static inline uint32_t uart_ll_get_fsm_status(uart_port_t uart_num) * @param discard true: Receiver stops storing data into FIFO when data is wrong * false: Receiver continue storing data into FIFO when data is wrong */ -static inline void uart_ll_discard_error_data(uart_dev_t *hw, bool discard) +FORCE_INLINE_ATTR void uart_ll_discard_error_data(uart_dev_t *hw, bool discard) { hw->conf0_sync.err_wr_mask = discard ? 1 : 0; uart_ll_update(hw); diff --git a/components/hal/esp32h2/include/hal/uhci_ll.h b/components/hal/esp32h2/include/hal/uhci_ll.h new file mode 100644 index 0000000000..07d4a40a68 --- /dev/null +++ b/components/hal/esp32h2/include/hal/uhci_ll.h @@ -0,0 +1,133 @@ +/* + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include +#include "hal/uhci_types.h" +#include "soc/uhci_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UHCI_LL_GET_HW(num) (((num) == 0) ? (&UHCI0) : (NULL)) + +typedef enum { + UHCI_RX_BREAK_CHR_EOF = 0x1, + UHCI_RX_IDLE_EOF = 0x2, + UHCI_RX_LEN_EOF = 0x4, + UHCI_RX_EOF_MAX = 0x7, +} uhci_rxeof_cfg_t; + +static inline void uhci_ll_init(uhci_dev_t *hw) +{ + typeof(hw->conf0) conf0_reg; + hw->conf0.clk_en = 1; + conf0_reg.val = 0; + conf0_reg.clk_en = 1; + hw->conf0.val = conf0_reg.val; + hw->conf1.val = 0; +} + +static inline void uhci_ll_attach_uart_port(uhci_dev_t *hw, int uart_num) +{ + hw->conf0.uart0_ce = (uart_num == 0)? 1: 0; + hw->conf0.uart1_ce = (uart_num == 1)? 1: 0; +} + +static inline void uhci_ll_set_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_char) +{ + if (seper_char->sub_chr_en) { + typeof(hw->esc_conf0) esc_conf0_reg; + esc_conf0_reg.val = hw->esc_conf0.val; + + esc_conf0_reg.seper_char = seper_char->seper_chr; + esc_conf0_reg.seper_esc_char0 = seper_char->sub_chr1; + esc_conf0_reg.seper_esc_char1 = seper_char->sub_chr2; + hw->esc_conf0.val = esc_conf0_reg.val; + hw->escape_conf.tx_c0_esc_en = 1; + hw->escape_conf.rx_c0_esc_en = 1; + } else { + hw->escape_conf.tx_c0_esc_en = 0; + hw->escape_conf.rx_c0_esc_en = 0; + } +} + +static inline void uhci_ll_get_seper_chr(uhci_dev_t *hw, uhci_seper_chr_t *seper_chr) +{ + (void)hw; + (void)seper_chr; +} + +static inline void uhci_ll_set_swflow_ctrl_sub_chr(uhci_dev_t *hw, uhci_swflow_ctrl_sub_chr_t *sub_ctr) +{ + typeof(hw->escape_conf) escape_conf_reg; + escape_conf_reg.val = hw->escape_conf.val; + + if (sub_ctr->flow_en == 1) { + typeof(hw->esc_conf2) esc_conf2_reg; + esc_conf2_reg.val = hw->esc_conf2.val; + typeof(hw->esc_conf3) esc_conf3_reg; + esc_conf3_reg.val = hw->esc_conf3.val; + + esc_conf2_reg.esc_seq1 = sub_ctr->xon_chr; + esc_conf2_reg.esc_seq1_char0 = sub_ctr->xon_sub1; + esc_conf2_reg.esc_seq1_char1 = sub_ctr->xon_sub2; + esc_conf3_reg.esc_seq2 = sub_ctr->xoff_chr; + esc_conf3_reg.esc_seq2_char0 = sub_ctr->xoff_sub1; + esc_conf3_reg.esc_seq2_char1 = sub_ctr->xoff_sub2; + escape_conf_reg.tx_11_esc_en = 1; + escape_conf_reg.tx_13_esc_en = 1; + escape_conf_reg.rx_11_esc_en = 1; + escape_conf_reg.rx_13_esc_en = 1; + hw->esc_conf2.val = esc_conf2_reg.val; + hw->esc_conf3.val = esc_conf3_reg.val; + } else { + escape_conf_reg.tx_11_esc_en = 0; + escape_conf_reg.tx_13_esc_en = 0; + escape_conf_reg.rx_11_esc_en = 0; + escape_conf_reg.rx_13_esc_en = 0; + } + hw->escape_conf.val = escape_conf_reg.val; +} + +static inline void uhci_ll_enable_intr(uhci_dev_t *hw, uint32_t intr_mask) +{ + hw->int_ena.val |= intr_mask; +} + +static inline void uhci_ll_disable_intr(uhci_dev_t *hw, uint32_t intr_mask) +{ + hw->int_ena.val &= (~intr_mask); +} + +static inline void uhci_ll_clear_intr(uhci_dev_t *hw, uint32_t intr_mask) +{ + hw->int_clr.val = intr_mask; +} + +static inline uint32_t uhci_ll_get_intr(uhci_dev_t *hw) +{ + return hw->int_st.val; +} + + +static inline void uhci_ll_set_eof_mode(uhci_dev_t *hw, uint32_t eof_mode) +{ + if (eof_mode & UHCI_RX_BREAK_CHR_EOF) { + hw->conf0.uart_rx_brk_eof_en = 1; + } + if (eof_mode & UHCI_RX_IDLE_EOF) { + hw->conf0.uart_idle_eof_en = 1; + } + if (eof_mode & UHCI_RX_LEN_EOF) { + hw->conf0.len_eof_en = 1; + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32h2/include/hal/usb_phy_ll.h b/components/hal/esp32h2/include/hal/usb_phy_ll.h deleted file mode 100644 index 9713aae330..0000000000 --- a/components/hal/esp32h2/include/hal/usb_phy_ll.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include "soc/usb_serial_jtag_struct.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configures the internal PHY for USB_Serial_JTAG - * - * @param hw Start address of the USB Serial_JTAG registers - */ -static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) -{ - // USB_Serial_JTAG use internal PHY - hw->conf0.phy_sel = 0; - // Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1) - hw->conf0.pad_pull_override = 0; - // Enable USB D+ pullup - hw->conf0.dp_pullup = 1; - // Enable USB pad function - hw->conf0.usb_pad_enable = 1; -} - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h index 0ad3980213..bacbf3d3fb 100644 --- a/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32h2/include/hal/usb_serial_jtag_ll.h @@ -1,23 +1,21 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -// The LL layer of the USB-serial-jtag controller - #pragma once + +#include +#include "esp_attr.h" +#include "soc/pcr_struct.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" +#include "hal/usb_serial_jtag_types.h" -#ifdef __cplusplus -extern "C" { -#endif - -//The in and out endpoints are this long. -#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64 +/* ----------------------------- Macros & Types ----------------------------- */ -#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask +#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging @@ -31,6 +29,13 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_ll_intr_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------- USJ Peripheral ----------------------------- */ + /** * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @@ -120,7 +125,7 @@ static inline int usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_len) * is room in the buffer. * * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return Amount of bytes actually written. May be less than wr_len. */ @@ -158,8 +163,14 @@ static inline int usb_serial_jtag_ll_txfifo_writable(void) * @brief Flushes the TX buffer, that is, make it available for the * host to pick up. * - * @note When fifo is full (with 64 byte), HW will flush the buffer automatically. - * It won't be executed if there is nothing in the fifo. + * @note When fifo is full (with 64 byte), HW will flush the buffer automatically, + * if this function is called directly after, this effectively turns into a + * no-op. Because a 64-byte packet will be interpreted as a not-complete USB + * transaction, you need to transfer either more data or a zero-length packet + * for the data to actually end up at the program listening to the CDC-ACM + * serial port. To send a zero-length packet, call + * usb_serial_jtag_ll_txfifo_flush() again when + * usb_serial_jtag_ll_txfifo_writable() returns true. * * @return na */ @@ -168,6 +179,154 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) USB_SERIAL_JTAG.ep1_conf.wr_done=1; } +/** + * @brief Enable USJ JTAG bridge + * + * If enabled, USJ is disconnected from internal JTAG interface. JTAG interface + * is routed through GPIO matrix instead. + * + * @param enable Enable USJ JTAG bridge + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_jtag_bridge_en = enable; +} + +/* ---------------------------- USB PHY Control ---------------------------- */ + +/** + * @brief Sets PHY defaults + * + * Some PHY register fields/features of the USJ are redundant on the ESP32-H2. + * This function those fields are set to the appropriate default values. + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_defaults(void) +{ + // External FSLS PHY is not supported + USB_SERIAL_JTAG.conf0.phy_sel = 0; + USB_SERIAL_JTAG.conf0.usb_pad_enable = 1; +} + +/** + * @brief Enables/disables exchanging of the D+/D- pins USB PHY + * + * @param enable Enables pin exchange, disabled otherwise + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable) +{ + if (enable) { + USB_SERIAL_JTAG.conf0.exchg_pins = 1; + USB_SERIAL_JTAG.conf0.exchg_pins_override = 1; + } else { + USB_SERIAL_JTAG.conf0.exchg_pins_override = 0; + USB_SERIAL_JTAG.conf0.exchg_pins = 0; + } +} + +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_vref_override(unsigned int vrefh_step, unsigned int vrefl_step) +{ + USB_SERIAL_JTAG.conf0.vrefh = vrefh_step; + USB_SERIAL_JTAG.conf0.vrefl = vrefl_step; + USB_SERIAL_JTAG.conf0.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) +{ + USB_SERIAL_JTAG.conf0.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param vals Override values to set + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals) +{ + USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd; + USB_SERIAL_JTAG.conf0.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_pull_override(void) +{ + USB_SERIAL_JTAG.conf0.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_pullup_strength(bool strong) +{ + USB_SERIAL_JTAG.conf0.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_phy_is_pad_enabled(void) +{ + return USB_SERIAL_JTAG.conf0.usb_pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + +/** + * @brief Enable the bus clock for USJ module + * @param clk_en True if enable the clock of USJ module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) +{ + PCR.usb_device_conf.usb_device_clk_en = clk_en; +} + +/** + * @brief Reset the USJ module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) +{ + PCR.usb_device_conf.usb_device_rst_en = 1; + PCR.usb_device_conf.usb_device_rst_en = 0; +} + +/** + * Get the enable status of the USJ module + * + * @return Return true if USJ module is enabled + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void) +{ + return (PCR.usb_device_conf.usb_device_clk_en && !PCR.usb_device_conf.usb_device_rst_en); +} #ifdef __cplusplus } diff --git a/components/hal/esp32h2/modem_clock_hal.c b/components/hal/esp32h2/modem_clock_hal.c index eb77e7b45b..879e694d2a 100644 --- a/components/hal/esp32h2/modem_clock_hal.c +++ b/components/hal/esp32h2/modem_clock_hal.c @@ -19,13 +19,17 @@ typedef enum { MODEM_CLOCK_EXT32K_CODE = 2 } modem_clock_32k_clk_src_code_t; -void modem_clock_hal_enable_fe_clock(modem_clock_hal_context_t *hal, bool enable) +void IRAM_ATTR modem_clock_hal_enable_modem_adc_common_fe_clock(modem_clock_hal_context_t *hal, bool enable) +{ + modem_syscon_ll_enable_fe_apb_clock(hal->syscon_dev, enable); + modem_syscon_ll_enable_fe_32m_clock(hal->syscon_dev, enable); +} + +void IRAM_ATTR modem_clock_hal_enable_modem_private_fe_clock(modem_clock_hal_context_t *hal, bool enable) { modem_lpcon_ll_enable_fe_mem_clock(hal->lpcon_dev, enable); modem_syscon_ll_enable_fe_sdm_clock(hal->syscon_dev, enable); modem_syscon_ll_enable_fe_adc_clock(hal->syscon_dev, enable); - modem_syscon_ll_enable_fe_apb_clock(hal->syscon_dev, enable); - modem_syscon_ll_enable_fe_32m_clock(hal->syscon_dev, enable); modem_syscon_ll_enable_fe_16m_clock(hal->syscon_dev, enable); } @@ -75,7 +79,7 @@ void modem_clock_hal_select_ble_rtc_timer_lpclk_source(modem_clock_hal_context_t lp_clkrst_ll_select_modem_32k_clock_source(&LP_CLKRST, MODEM_CLOCK_EXT32K_CODE); break; default: - break; + HAL_ASSERT(0); } } @@ -115,6 +119,6 @@ void modem_clock_hal_select_coex_lpclk_source(modem_clock_hal_context_t *hal, mo lp_clkrst_ll_select_modem_32k_clock_source(&LP_CLKRST, MODEM_CLOCK_EXT32K_CODE); break; default: - break; + HAL_ASSERT(0); } } diff --git a/components/hal/esp32h2/pau_hal.c b/components/hal/esp32h2/pau_hal.c index cbfecc77e6..6eeaaef002 100644 --- a/components/hal/esp32h2/pau_hal.c +++ b/components/hal/esp32h2/pau_hal.c @@ -15,11 +15,7 @@ void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_addr_t *link_addr) { - /* ESP32H2 does not have PMU HP_AON power domain. because the registers - * of PAU REGDMA is included to PMU TOP power domain, cause the contents - * of PAU REGDMA registers will be lost when the TOP domain is powered down - * during light sleep, so we does not need to enable REGDMA backup here. - * We will use the software to trigger REGDMA to backup or restore. */ + pau_ll_set_regdma_link0_addr(hal->dev, (*link_addr)[0]); } void IRAM_ATTR pau_hal_start_regdma_system_link(pau_hal_context_t *hal, bool backup_or_restore) @@ -40,26 +36,6 @@ void IRAM_ATTR pau_hal_stop_regdma_system_link(pau_hal_context_t *hal) pau_ll_clear_regdma_backup_done_intr_state(hal->dev); } -void pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) -{ - pau_ll_clear_regdma_backup_done_intr_state(hal->dev); - /* The link 3 of REGDMA is reserved, we use it as an extra linked list to - * provide backup and restore services for BLE, IEEE802.15.4 and possibly - * other modules */ - pau_ll_select_regdma_entry_link(hal->dev, 3); - pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); - pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); - - while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); -} - -void pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) -{ - pau_ll_set_regdma_entry_link_backup_start_disable(hal->dev); - pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */ - pau_ll_clear_regdma_backup_done_intr_state(hal->dev); -} - void IRAM_ATTR pau_hal_regdma_clock_configure(pau_hal_context_t *hal, bool enable) { HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.regdma_conf, regdma_rst_en, !enable); diff --git a/components/hal/esp32h2/pmu_hal.c b/components/hal/esp32h2/pmu_hal.c index 9da9eaed80..4e710ca103 100644 --- a/components/hal/esp32h2/pmu_hal.c +++ b/components/hal/esp32h2/pmu_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,26 +11,26 @@ #include "hal/pmu_hal.h" #include "hal/pmu_types.h" -void IRAM_ATTR pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) { pmu_ll_hp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); pmu_ll_hp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); } -uint32_t IRAM_ATTR pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) { uint32_t power_supply_wait_cycle = pmu_ll_hp_get_digital_power_supply_wait_cycle(hal->dev); uint32_t power_up_wait_cycle = pmu_ll_hp_get_digital_power_up_wait_cycle(hal->dev); return power_supply_wait_cycle + power_up_wait_cycle; } -void IRAM_ATTR pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) { pmu_ll_lp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); pmu_ll_lp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); } -uint32_t IRAM_ATTR pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) { uint32_t power_supply_wait_cycle = pmu_ll_lp_get_digital_power_supply_wait_cycle(hal->dev); uint32_t power_up_wait_cycle = pmu_ll_lp_get_digital_power_up_wait_cycle(hal->dev); diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index 0a29bee900..556abf7514 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.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 */ @@ -35,6 +35,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 @@ -804,19 +805,19 @@ 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) + * - 12dB 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.) * - * @note At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage. + * @note At 12dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage. * * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges: * * - 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 + * - 12dB 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/esp32s2/include/hal/brownout_ll.h b/components/hal/esp32s2/include/hal/brownout_ll.h index 6a8b7cfe57..fc13a382e9 100644 --- a/components/hal/esp32s2/include/hal/brownout_ll.h +++ b/components/hal/esp32s2/include/hal/brownout_ll.h @@ -116,6 +116,16 @@ static inline void brownout_ll_intr_clear(void) RTCCNTL.int_clr.rtc_brown_out = 1; } +/** + * @brief Clear BOD internal count. + */ +static inline void brownout_ll_clear_count(void) +{ + RTCCNTL.brown_out.cnt_clr = 1; + RTCCNTL.brown_out.cnt_clr = 0; +} + + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s2/include/hal/cache_ll.h b/components/hal/esp32s2/include/hal/cache_ll.h index d704aae45b..73db4611f2 100644 --- a/components/hal/esp32s2/include/hal/cache_ll.h +++ b/components/hal/esp32s2/include/hal/cache_ll.h @@ -22,6 +22,29 @@ extern "C" { #define CACHE_LL_DEFAULT_IBUS_MASK CACHE_BUS_IBUS0 #define CACHE_LL_DEFAULT_DBUS_MASK CACHE_BUS_IBUS2 +/** + * @brief Get the status of cache if it is enabled or not + * + * @param cache_id cache ID (when l1 cache is per core) + * @param type see `cache_type_t` + * @return enabled or not + */ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_cache_enabled(uint32_t cache_id, cache_type_t type) +{ + HAL_ASSERT(cache_id == 0); + + bool enabled; + if (type == CACHE_TYPE_INSTRUCTION) { + enabled = REG_GET_BIT(EXTMEM_PRO_ICACHE_CTRL_REG, EXTMEM_PRO_ICACHE_ENABLE); + } else if (type == CACHE_TYPE_DATA) { + enabled = REG_GET_BIT(EXTMEM_PRO_DCACHE_CTRL_REG, EXTMEM_PRO_DCACHE_ENABLE); + } else { + enabled = REG_GET_BIT(EXTMEM_PRO_ICACHE_CTRL_REG, EXTMEM_PRO_ICACHE_ENABLE); + enabled = enabled && REG_GET_BIT(EXTMEM_PRO_DCACHE_CTRL_REG, EXTMEM_PRO_DCACHE_ENABLE); + } + return enabled; +} /** * @brief Get the buses of a particular cache that are mapped to a virtual address range diff --git a/components/hal/esp32s2/include/hal/clk_gate_ll.h b/components/hal/esp32s2/include/hal/clk_gate_ll.h index a1ef5be97a..accef40f19 100644 --- a/components/hal/esp32s2/include/hal/clk_gate_ll.h +++ b/components/hal/esp32s2/include/hal/clk_gate_ll.h @@ -241,16 +241,14 @@ static inline void periph_ll_disable_clk_set_rst(periph_module_t periph) DPORT_SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); } -static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk_clear_rst(void) +static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk(void) { DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_BT_COMMON_M); - DPORT_CLEAR_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, 0); } -static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk_set_rst(void) +static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk(void) { DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_BT_COMMON_M); - DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, 0); } static inline void periph_ll_reset(periph_module_t periph) diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index bb8a381598..9ffb8cc4d1 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.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 */ @@ -33,6 +33,39 @@ extern "C" { #define GPIO_LL_PRO_CPU_INTR_ENA (BIT(0)) #define GPIO_LL_PRO_CPU_NMI_INTR_ENA (BIT(1)) +/** + * @brief Get the configuration for an IO + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param pu Pull-up enabled or not + * @param pd Pull-down enabled or not + * @param ie Input enabled or not + * @param oe Output enabled or not + * @param od Open-drain enabled or not + * @param drv Drive strength value + * @param fun_sel IOMUX function selection value + * @param sig_out Outputting peripheral signal index + * @param slp_sel Pin sleep mode enabled or not + */ +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, + bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) +{ + uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); + uint32_t bit_mask = 1 << bit_shift; + uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); + *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; + *od = hw->pin[gpio_num].pad_driver; + *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; + *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; +} + /** * @brief Enable pull-up on GPIO. * @@ -490,6 +523,23 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], func); } +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + typeof(hw->func_in_sel_cfg[in_sig_idx]) reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.func_sel : -1); +} + /** * @brief Force hold digital gpio pad. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32s2/include/hal/rmt_ll.h b/components/hal/esp32s2/include/hal/rmt_ll.h index fe8028802c..2d9a3389ce 100644 --- a/components/hal/esp32s2/include/hal/rmt_ll.h +++ b/components/hal/esp32s2/include/hal/rmt_ll.h @@ -55,15 +55,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->apb_conf.mem_force_pu = !enable; - dev->apb_conf.mem_force_pd = enable; + dev->apb_conf.mem_force_pu = 1; + dev->apb_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->apb_conf.mem_force_pd = 1; + dev->apb_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->apb_conf.mem_force_pd = 0; + dev->apb_conf.mem_force_pu = 0; } /** @@ -88,7 +109,7 @@ static inline void rmt_ll_enable_mem_access_nonfifo(rmt_dev_t *dev, bool enable) * @param divider_numerator Numerator part of the divider */ static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel, rmt_clock_source_t src, - uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) + uint32_t divider_integral, uint32_t divider_denominator, uint32_t divider_numerator) { (void)divider_integral; (void)divider_denominator; @@ -473,6 +494,7 @@ static inline void rmt_ll_rx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, ui * @param channel RMT RX channel number * @param thres Time length threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->conf_ch[channel].conf0, idle_thres_chn, thres); @@ -498,6 +520,7 @@ static inline void rmt_ll_rx_set_mem_owner(rmt_dev_t *dev, uint32_t channel, rmt * @param channel RMT RX chanenl number * @param enable True to enable, False to disable */ +__attribute__((always_inline)) static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable) { dev->conf_ch[channel].conf1.rx_filter_en_chn = enable; @@ -510,6 +533,7 @@ static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, boo * @param channel RMT RX channel number * @param thres Filter threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->conf_ch[channel].conf1, rx_filter_thres_chn, thres); @@ -736,12 +760,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->conf_ch[channel].conf1.idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->apb_conf.mem_force_pd) || !(dev->apb_conf.mem_force_pu); + return dev->apb_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32s2/include/hal/rtc_cntl_ll.h b/components/hal/esp32s2/include/hal/rtc_cntl_ll.h index 0ccdedc879..754e9bcf11 100644 --- a/components/hal/esp32s2/include/hal/rtc_cntl_ll.h +++ b/components/hal/esp32s2/include/hal/rtc_cntl_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 */ @@ -10,6 +10,7 @@ #include "soc/rtc.h" #include "soc/rtc_cntl_reg.h" #include "esp_attr.h" +#include "hal/assert.h" #ifdef __cplusplus extern "C" { @@ -34,11 +35,18 @@ FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_status(void) return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS); } -FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) +FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t io_mask, uint32_t mode_mask) { - REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, mask); - SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, - mode, RTC_CNTL_EXT_WAKEUP1_LV_S); + // The target only supports a unified trigger mode among all EXT1 wakeup IOs + HAL_ASSERT((io_mask & mode_mask) == io_mask || (io_mask & mode_mask) == 0); + REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, io_mask); + if ((io_mask & mode_mask) == io_mask) { + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + 1, RTC_CNTL_EXT_WAKEUP1_LV_S); + } else { + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + 0, RTC_CNTL_EXT_WAKEUP1_LV_S); + } } FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_pins(void) diff --git a/components/hal/esp32s2/include/hal/spi_ll.h b/components/hal/esp32s2/include/hal/spi_ll.h index 7b09ae2a2b..f51e2a1964 100644 --- a/components/hal/esp32s2/include/hal/spi_ll.h +++ b/components/hal/esp32s2/include/hal/spi_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 */ @@ -43,6 +43,7 @@ extern "C" { #define SPI_LL_DMA_MAX_BIT_LEN (1 << 23) //reg len: 23 bits #define SPI_LL_CPU_MAX_BIT_LEN (18 * 32) //Fifo len: 18 words +#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized /** * The data structure holding calculated clock configuration. Since the @@ -176,33 +177,43 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw) } /** - * Check whether user-defined transaction is done. + * Determine and unify the default level of mosi line when bus free * * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level) +{ + hw->ctrl.d_pol = level; //set default level for MOSI only on IDLE state +} + +/** + * Apply the register configurations and wait until it's done * - * @return true if transaction is done, otherwise false. + * @param hw Beginning address of the peripheral registers. */ -static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +static inline void spi_ll_apply_config(spi_dev_t *hw) { - return hw->slave.trans_done; + // S2 don't need this option } /** - * Trigger start of user-defined transaction for master. + * Check whether user-defined transaction is done. * * @param hw Beginning address of the peripheral registers. + * + * @return true if transaction is done, otherwise false. */ -static inline void spi_ll_master_user_start(spi_dev_t *hw) +static inline bool spi_ll_usr_is_done(spi_dev_t *hw) { - hw->cmd.usr = 1; + return hw->slave.trans_done; } /** - * Trigger start of user-defined transaction for slave. + * Trigger start of user-defined transaction. * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_slave_user_start(spi_dev_t *hw) +static inline void spi_ll_user_start(spi_dev_t *hw) { hw->cmd.usr = 1; } diff --git a/components/hal/esp32s2/include/hal/timer_ll.h b/components/hal/esp32s2/include/hal/timer_ll.h index 42daa564e3..f50a27cb2b 100644 --- a/components/hal/esp32s2/include/hal/timer_ll.h +++ b/components/hal/esp32s2/include/hal/timer_ll.h @@ -197,6 +197,7 @@ static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, * @param timer_num Timer number in the group * @return reload count value */ +__attribute__((always_inline)) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num) { return ((uint64_t)hw->hw_timer[timer_num].loadhi.tx_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tx_load_lo); @@ -208,6 +209,7 @@ static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_ * @param hw Timer Group register base address * @param timer_num Timer number in the group */ +__attribute__((always_inline)) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num) { hw->hw_timer[timer_num].load.tx_load = 1; diff --git a/components/hal/esp32s2/include/hal/uart_ll.h b/components/hal/esp32s2/include/hal/uart_ll.h index f8dcc66204..5c2b2a16c6 100644 --- a/components/hal/esp32s2/include/hal/uart_ll.h +++ b/components/hal/esp32s2/include/hal/uart_ll.h @@ -28,7 +28,7 @@ extern "C" { // Get UART hardware instance with giving uart num #define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1)) -#define UART_LL_MIN_WAKEUP_THRESH (2) +#define UART_LL_MIN_WAKEUP_THRESH (3) #define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask // Define UART interrupts @@ -567,6 +567,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) */ FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) { + // System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3) hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; } diff --git a/components/hal/esp32s2/include/hal/usb_ll.h b/components/hal/esp32s2/include/hal/usb_ll.h deleted file mode 100644 index 2be637f55c..0000000000 --- a/components/hal/esp32s2/include/hal/usb_ll.h +++ /dev/null @@ -1,42 +0,0 @@ -// 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. - - -#include "soc/soc.h" -#include "soc/system_reg.h" -#include "soc/gpio_sig_map.h" -#include "soc/usb_periph.h" - -static inline void usb_ll_int_phy_enable(void) -{ - USB_WRAP.otg_conf.pad_enable = 1; - USB_WRAP.otg_conf.phy_sel = 0; -} - -static inline void usb_ll_ext_phy_enable(void) -{ - USB_WRAP.otg_conf.pad_enable = 1; - USB_WRAP.otg_conf.phy_sel = 1; -} - -static inline void usb_ll_int_phy_pullup_conf(bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd) -{ - usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; - conf.pad_pull_override = 1; - conf.dp_pullup = dp_pu; - conf.dp_pulldown = dp_pd; - conf.dm_pullup = dm_pu; - conf.dm_pulldown = dm_pd; - USB_WRAP.otg_conf = conf; -} diff --git a/components/hal/esp32s2/include/hal/usb_phy_ll.h b/components/hal/esp32s2/include/hal/usb_phy_ll.h deleted file mode 100644 index ed175cf9ce..0000000000 --- a/components/hal/esp32s2/include/hal/usb_phy_ll.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include "soc/soc.h" -#include "soc/system_reg.h" -#include "soc/usb_wrap_struct.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configures the internal PHY for USB_OTG - * - * @param hw Start address of the USB Wrap registers - */ -static inline void usb_phy_ll_int_otg_enable(usb_wrap_dev_t *hw) -{ - //Enable internal PHY - hw->otg_conf.pad_enable = 1; - hw->otg_conf.phy_sel = 0; -} - -/** - * @brief Configures the external PHY for USB_OTG - * - * @param hw Start address of the USB Wrap registers - */ -static inline void usb_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw) -{ - //Enable external PHY - hw->otg_conf.phy_sel = 1; -} - -/** - * @brief Configures port loads for the internal PHY - * - * @param hw Start address of the USB Wrap registers - * @param dp_pu D+ pullup load - * @param dp_pd D+ pulldown load - * @param dm_pu D- pullup load - * @param dm_pd D- pulldown load - */ -static inline void usb_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd) -{ - usb_wrap_otg_conf_reg_t conf = hw->otg_conf; - conf.pad_pull_override = 1; - conf.dp_pullup = dp_pu; - conf.dp_pulldown = dp_pd; - conf.dm_pullup = dm_pu; - conf.dm_pulldown = dm_pd; - hw->otg_conf = conf; -} - -/** - * @brief Enable the internal PHY's test mode - * - * @param hw Start address of the USB Wrap registers - * @param en Whether to enable the internal PHY's test mode - */ -static inline void usb_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en) -{ - if (en) { - // Clear USB_WRAP_TEST_CONF_REG - hw->test_conf.val = 0; - // Set USB test pad oen - hw->test_conf.test_usb_wrap_oe = 1; - // Enable USB test mode - hw->test_conf.test_enable = 1; - } else { - hw->test_conf.test_enable = 0; - } -} - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/esp32s2/include/hal/usb_wrap_ll.h b/components/hal/esp32s2/include/hal/usb_wrap_ll.h new file mode 100644 index 0000000000..858a236cd3 --- /dev/null +++ b/components/hal/esp32s2/include/hal/usb_wrap_ll.h @@ -0,0 +1,226 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_attr.h" +#include "soc/soc.h" +#include "soc/system_reg.h" +#include "soc/usb_wrap_struct.h" +#include "hal/usb_wrap_types.h" + +/* ----------------------------- Macros & Types ----------------------------- */ + +#define USB_WRAP_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY + + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------- USB PHY Control ---------------------------- */ + +/** + * @brief Enables and sets the override value for the session end signal + * + * @param hw Start address of the USB Wrap registers + * @param sessend Session end override value. True means VBus < 0.2V, false means VBus > 0.8V + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_srp_sessend_override(usb_wrap_dev_t *hw, bool sessend) +{ + hw->otg_conf.srp_sessend_value = sessend; + hw->otg_conf.srp_sessend_override = 1; +} + +/** + * @brief Disable session end override + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_srp_sessend_override(usb_wrap_dev_t *hw) +{ + hw->otg_conf.srp_sessend_override = 0; +} + +/** + * @brief Sets whether the USB Wrap's FSLS PHY interface routes to an internal or external PHY + * + * @param hw Start address of the USB Wrap registers + * @param enable Enables external PHY, internal otherwise + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_external(usb_wrap_dev_t *hw, bool enable) +{ + hw->otg_conf.phy_sel = enable; +} + +/** + * @brief Enables/disables exchanging of the D+/D- pins USB PHY + * + * @param hw Start address of the USB Wrap registers + * @param enable Enables pin exchange, disabled otherwise + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pin_exchg(usb_wrap_dev_t *hw, bool enable) +{ + if (enable) { + hw->otg_conf.exchg_pins = 1; + hw->otg_conf.exchg_pins_override = 1; + } else { + hw->otg_conf.exchg_pins_override = 0; + hw->otg_conf.exchg_pins = 0; + } +} + +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param hw Start address of the USB Wrap registers + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_vref_override(usb_wrap_dev_t *hw, unsigned int vrefh_step, unsigned int vrefl_step) +{ + hw->otg_conf.vrefh = vrefh_step; + hw->otg_conf.vrefl = vrefl_step; + hw->otg_conf.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_vref_override(usb_wrap_dev_t *hw) +{ + hw->otg_conf.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param hw Start address of the USB Wrap registers + * @param vals Override values to set + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, const usb_wrap_pull_override_vals_t *vals) +{ + hw->otg_conf.dp_pullup = vals->dp_pu; + hw->otg_conf.dp_pulldown = vals->dp_pd; + hw->otg_conf.dm_pullup = vals->dm_pu; + hw->otg_conf.dm_pulldown = vals->dm_pd; + hw->otg_conf.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_pull_override(usb_wrap_dev_t *hw) +{ + hw->otg_conf.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param hw Start address of the USB Wrap registers + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_pullup_strength(usb_wrap_dev_t *hw, bool strong) +{ + hw->otg_conf.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @param hw Start address of the USB Wrap registers + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_wrap_ll_phy_is_pad_enabled(usb_wrap_dev_t *hw) +{ + return hw->otg_conf.pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param hw Start address of the USB Wrap registers + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pad(usb_wrap_dev_t *hw, bool enable) +{ + hw->otg_conf.pad_enable = enable; +} + +/** + * @brief Set USB FSLS PHY TX output clock edge + * + * @param hw Start address of the USB Wrap registers + * @param clk_neg_edge True if TX output at negedge, posedge otherwise + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_tx_edge(usb_wrap_dev_t *hw, bool clk_neg_edge) +{ + hw->otg_conf.phy_tx_edge_sel = clk_neg_edge; +} + +/* ------------------------------ USB PHY Test ------------------------------ */ + +/** + * @brief Enable the USB FSLS PHY's test mode + * + * @param hw Start address of the USB Wrap registers + * @param enable Whether to enable the USB FSLS PHY's test mode + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_test_mode(usb_wrap_dev_t *hw, bool enable) +{ + hw->test_conf.test_enable = enable; +} + +/** + * @brief Set the USB FSLS PHY's signal test values + * + * @param hw Start address of the USB Wrap registers + * @param vals Test values to set + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, const usb_wrap_test_mode_vals_t *vals) +{ + usb_wrap_test_conf_reg_t test_conf; + test_conf.val = hw->test_conf.val; + + test_conf.test_usb_wrap_oe = vals->tx_enable_n; + test_conf.test_tx_dp = vals->tx_dp; + test_conf.test_tx_dm = vals->tx_dm; + test_conf.test_rx_rcv = vals->rx_rcv; + test_conf.test_rx_dp = vals->rx_dp; + test_conf.test_rx_dm = vals->rx_dm; + + hw->test_conf.val = test_conf.val; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + +/** + * Enable the bus clock for USB Wrap module + * @param clk_en True if enable the clock of USB Wrap module + */ +FORCE_INLINE_ATTR void usb_wrap_ll_enable_bus_clock(bool clk_en) +{ + REG_SET_FIELD(DPORT_PERIP_CLK_EN0_REG, DPORT_USB_CLK_EN, clk_en); +} + +/** + * @brief Reset the USB Wrap module + */ +FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void) +{ + REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 1); + REG_SET_FIELD(DPORT_PERIP_RST_EN0_REG, DPORT_USB_RST, 0); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s3/include/hal/adc_ll.h b/components/hal/esp32s3/include/hal/adc_ll.h index 05df0a5fd1..5cdf6a3f0d 100644 --- a/components/hal/esp32s3/include/hal/adc_ll.h +++ b/components/hal/esp32s3/include/hal/adc_ll.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 */ @@ -35,6 +35,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 @@ -1055,19 +1056,19 @@ 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) + * - 12dB 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.) * - * @note At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage. + * @note At 12dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage. * * Due to ADC characteristics, most accurate results are obtained within the following approximate voltage ranges: * * - 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 + * - 12dB 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/brownout_ll.h b/components/hal/esp32s3/include/hal/brownout_ll.h index 37a2020c12..4cc8d95f67 100644 --- a/components/hal/esp32s3/include/hal/brownout_ll.h +++ b/components/hal/esp32s3/include/hal/brownout_ll.h @@ -115,6 +115,15 @@ static inline void brownout_ll_intr_clear(void) RTCCNTL.int_clr.rtc_brown_out = 1; } +/** + * @brief Clear BOD internal count. + */ +static inline void brownout_ll_clear_count(void) +{ + RTCCNTL.brown_out.cnt_clr = 1; + RTCCNTL.brown_out.cnt_clr = 0; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s3/include/hal/cache_ll.h b/components/hal/esp32s3/include/hal/cache_ll.h index 9b0ce94b13..a5439ca4ff 100644 --- a/components/hal/esp32s3/include/hal/cache_ll.h +++ b/components/hal/esp32s3/include/hal/cache_ll.h @@ -8,6 +8,7 @@ #pragma once +#include #include "soc/extmem_reg.h" #include "soc/ext_mem_defs.h" #include "hal/cache_types.h" @@ -37,6 +38,29 @@ extern "C" { #define CACHE_LL_L1_ILG_EVENT_ICACHE_PRELOAD_OP_FAULT (1<<1) #define CACHE_LL_L1_ILG_EVENT_ICACHE_SYNC_OP_FAULT (1<<0) +/** + * @brief Get the status of cache if it is enabled or not + * + * @param cache_id cache ID (when l1 cache is per core) + * @param type see `cache_type_t` + * @return enabled or not + */ +__attribute__((always_inline)) +static inline bool cache_ll_l1_is_cache_enabled(uint32_t cache_id, cache_type_t type) +{ + HAL_ASSERT(cache_id == 0 || cache_id == 1); + + bool enabled; + if (type == CACHE_TYPE_INSTRUCTION) { + enabled = REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); + } else if (type == CACHE_TYPE_DATA) { + enabled = REG_GET_BIT(EXTMEM_DCACHE_CTRL_REG, EXTMEM_DCACHE_ENABLE); + } else { + enabled = REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE); + enabled = enabled && REG_GET_BIT(EXTMEM_DCACHE_CTRL_REG, EXTMEM_DCACHE_ENABLE); + } + return enabled; +} /** * @brief Get the buses of a particular cache that are mapped to a virtual address range diff --git a/components/hal/esp32s3/include/hal/clk_gate_ll.h b/components/hal/esp32s3/include/hal/clk_gate_ll.h index d3bd68d085..9f3dfd474d 100644 --- a/components/hal/esp32s3/include/hal/clk_gate_ll.h +++ b/components/hal/esp32s3/include/hal/clk_gate_ll.h @@ -262,16 +262,14 @@ static inline void periph_ll_disable_clk_set_rst(periph_module_t periph) DPORT_SET_PERI_REG_MASK(periph_ll_get_rst_en_reg(periph), periph_ll_get_rst_en_mask(periph, false)); } -static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk_clear_rst(void) +static inline void IRAM_ATTR periph_ll_wifi_bt_module_enable_clk(void) { DPORT_SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M); - DPORT_CLEAR_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } -static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk_set_rst(void) +static inline void IRAM_ATTR periph_ll_wifi_bt_module_disable_clk(void) { DPORT_CLEAR_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M); - DPORT_SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG, 0); } static inline void periph_ll_reset(periph_module_t periph) diff --git a/components/hal/esp32s3/include/hal/clk_tree_ll.h b/components/hal/esp32s3/include/hal/clk_tree_ll.h index 88a54624b6..4de0d26099 100644 --- a/components/hal/esp32s3/include/hal/clk_tree_ll.h +++ b/components/hal/esp32s3/include/hal/clk_tree_ll.h @@ -309,7 +309,7 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32 uint8_t dr3; uint8_t dchgp; uint8_t dcur; - uint8_t dbias; + uint8_t dbias = 3; if (pll_freq_mhz == CLK_LL_PLL_480M_FREQ_MHZ) { /* Configure 480M PLL */ @@ -321,7 +321,6 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32 dr3 = 0; dchgp = 5; dcur = 3; - dbias = 2; break; case RTC_XTAL_FREQ_32M: div_ref = 1; @@ -330,7 +329,6 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32 dr3 = 1; dchgp = 4; dcur = 0; - dbias = 2; break; default: div_ref = 0; @@ -339,7 +337,6 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32 dr3 = 0; dchgp = 5; dcur = 3; - dbias = 2; break; } REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B); @@ -353,7 +350,6 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32 dr3 = 0; dchgp = 5; dcur = 3; - dbias = 2; break; case RTC_XTAL_FREQ_32M: div_ref = 1; @@ -362,7 +358,6 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32 dr3 = 0; dchgp = 5; dcur = 3; - dbias = 2; break; default: div_ref = 0; @@ -371,7 +366,6 @@ static inline __attribute__((always_inline)) void clk_ll_bbpll_set_config(uint32 dr3 = 0; dchgp = 5; dcur = 3; - dbias = 2; break; } REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69); diff --git a/components/hal/esp32s3/include/hal/efuse_ll.h b/components/hal/esp32s3/include/hal/efuse_ll.h index e4bd38cb9c..0ef1ab7b9d 100644 --- a/components/hal/esp32s3/include/hal/efuse_ll.h +++ b/components/hal/esp32s3/include/hal/efuse_ll.h @@ -84,7 +84,7 @@ __attribute__((always_inline)) static inline bool efuse_ll_get_disable_blk_versi __attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_ver_pkg(void) { - return 0; + return EFUSE.rd_mac_spi_sys_3.pkg_version; } __attribute__((always_inline)) static inline uint32_t efuse_ll_get_ocode(void) diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index 513d0829a9..00b8cc9c78 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,6 +34,39 @@ extern "C" { #define GPIO_LL_INTR_ENA (BIT(0)) #define GPIO_LL_NMI_INTR_ENA (BIT(1)) +/** + * @brief Get the configuration for an IO + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @param pu Pull-up enabled or not + * @param pd Pull-down enabled or not + * @param ie Input enabled or not + * @param oe Output enabled or not + * @param od Open-drain enabled or not + * @param drv Drive strength value + * @param fun_sel IOMUX function selection value + * @param sig_out Outputting peripheral signal index + * @param slp_sel Pin sleep mode enabled or not + */ +static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, + bool *pu, bool *pd, bool *ie, bool *oe, bool *od, uint32_t *drv, + uint32_t *fun_sel, uint32_t *sig_out, bool *slp_sel) +{ + uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32); + uint32_t bit_mask = 1 << bit_shift; + uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]); + *pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S; + *pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S; + *ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S; + *oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift; + *od = hw->pin[gpio_num].pad_driver; + *drv = (iomux_reg_val & FUN_DRV_M) >> FUN_DRV_S; + *fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S; + *sig_out = hw->func_out_sel_cfg[gpio_num].func_sel; + *slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S; +} + /** * @brief Enable pull-up on GPIO. * @@ -374,7 +407,12 @@ static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength) { - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, strength, FUN_DRV_S); + uint32_t drv_cap = (uint32_t)strength; + // DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target + if (gpio_num == 17 || gpio_num == 18) { + drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1 + } + SET_PERI_REG_BITS(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, drv_cap, FUN_DRV_S); } /** @@ -386,7 +424,12 @@ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu */ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength) { - *strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, FUN_DRV_S); + uint32_t drv_cap = GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S); + // DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target + if (gpio_num == 17 || gpio_num == 18) { + drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1 + } + *strength = (gpio_drive_cap_t)drv_cap; } /** @@ -509,6 +552,23 @@ static inline void gpio_ll_iomux_out(gpio_dev_t *hw, uint8_t gpio_num, int func, gpio_ll_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], func); } +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix. + * + * @param hw Peripheral GPIO hardware instance address. + * @param in_sig_idx Peripheral signal index (tagged as input attribute). + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx) +{ + typeof(hw->func_in_sel_cfg[in_sig_idx]) reg; + reg.val = hw->func_in_sel_cfg[in_sig_idx].val; + return (reg.sig_in_sel ? reg.func_sel : -1); +} + /** * @brief Force hold digital gpio pad. * @note GPIO force hold, whether the chip in sleep mode or wakeup mode. diff --git a/components/hal/esp32s3/include/hal/lcd_ll.h b/components/hal/esp32s3/include/hal/lcd_ll.h index f2cc1487be..2aa760714c 100644 --- a/components/hal/esp32s3/include/hal/lcd_ll.h +++ b/components/hal/esp32s3/include/hal/lcd_ll.h @@ -27,6 +27,7 @@ extern "C" { #define LCD_LL_CLK_FRAC_DIV_N_MAX 256 // LCD_CLK = LCD_CLK_S / (N + b/a), the N register is 8 bit-width #define LCD_LL_CLK_FRAC_DIV_AB_MAX 64 // LCD_CLK = LCD_CLK_S / (N + b/a), the a/b register is 6 bit-width #define LCD_LL_PCLK_DIV_MAX 64 // LCD_PCLK = LCD_CLK / MO, the MO register is 6 bit-width +#define LCD_LL_FIFO_DEPTH 16 // Async FIFO depth #define LCD_LL_COLOR_RANGE_TO_REG(range) (uint8_t[]){0,1}[(range)] #define LCD_LL_CONV_STD_TO_REG(std) (uint8_t[]){0,1}[(std)] diff --git a/components/hal/esp32s3/include/hal/mcpwm_ll.h b/components/hal/esp32s3/include/hal/mcpwm_ll.h index 0111b62261..c42e7298a4 100644 --- a/components/hal/esp32s3/include/hal/mcpwm_ll.h +++ b/components/hal/esp32s3/include/hal/mcpwm_ll.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 */ @@ -43,8 +43,12 @@ extern "C" { #define MCPWM_LL_EVENT_CAPTURE(cap) (1 << ((cap) + 27)) // Maximum values due to limited register bit width +#define MCPWM_LL_MAX_GROUP_PRESCALE 256 +#define MCPWM_LL_MAX_TIMER_PRESCALE 256 +#define MCPWM_LL_MAX_CARRIER_PRESCALE 16 #define MCPWM_LL_MAX_CARRIER_ONESHOT 16 #define MCPWM_LL_MAX_CAPTURE_PRESCALE 256 +#define MCPWM_LL_MAX_CAPTURE_TIMER_PRESCALE 1 #define MCPWM_LL_MAX_DEAD_DELAY 65536 #define MCPWM_LL_MAX_COUNT_VALUE 65536 @@ -93,12 +97,13 @@ static inline void mcpwm_ll_group_enable_clock(mcpwm_dev_t *mcpwm, bool en) * @brief Set the MCPWM group clock prescale * * @param mcpwm Peripheral instance address - * @param pre_scale Prescale value + * @param prescale Prescale value */ -static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int pre_scale) +static inline void mcpwm_ll_group_set_clock_prescale(mcpwm_dev_t *mcpwm, int prescale) { - // group clock: PWM_clk = CLK_160M / (prescale + 1) - HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->clk_cfg, clk_prescale, pre_scale - 1); + // group clock: PWM_clk = CLK_160M / (prescale) + HAL_ASSERT(prescale <= 256 && prescale > 0); + HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->clk_cfg, clk_prescale, prescale - 1); } /** @@ -202,13 +207,12 @@ static inline void mcpwm_ll_timer_set_clock_prescale(mcpwm_dev_t *mcpwm, int tim * @param peak Peak value * @param symmetric True to set symmetric peak value, False to set asymmetric peak value */ +__attribute__((always_inline)) static inline void mcpwm_ll_timer_set_peak(mcpwm_dev_t *mcpwm, int timer_id, uint32_t peak, bool symmetric) { if (!symmetric) { // in asymmetric mode, period = [0,peak-1] - HAL_ASSERT(peak > 0 && peak <= MCPWM_LL_MAX_COUNT_VALUE); HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period, peak - 1); } else { // in symmetric mode, period = [0,peak-1] + [peak,1] - HAL_ASSERT(peak < MCPWM_LL_MAX_COUNT_VALUE); HAL_FORCE_MODIFY_U32_REG_FIELD(mcpwm->timer[timer_id].timer_cfg0, timer_period, peak); } } @@ -704,20 +708,20 @@ static inline void mcpwm_ll_operator_stop_update_action(mcpwm_dev_t *mcpwm, int * @param trig_id Trigger ID, index from 0 to 1 * @param fault_gpio_id Fault GPIO ID, index from 0 to 3 */ -static inline void mcpwm_ll_operator_set_trigger_from_gpio(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_gpio_id) +static inline void mcpwm_ll_operator_set_trigger_from_gpio_fault(mcpwm_dev_t *mcpwm, int operator_id, int trig_id, int fault_gpio_id) { mcpwm->operators[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id)); mcpwm->operators[operator_id].gen_cfg0.val |= (fault_gpio_id << (4 + 3 * trig_id)); } /** - * @brief Set trigger from timer sync event (when the timer taken the sync signal) + * @brief Set trigger from sync event (when the timer/gpio/soft taken the sync signal) * * @param mcpwm Peripheral instance address * @param operator_id Operator ID, index from 0 to 2 * @param trig_id Trigger ID, index from 0 to 1 */ -static inline void mcpwm_ll_operator_set_trigger_from_timer_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id) +static inline void mcpwm_ll_operator_set_trigger_from_sync(mcpwm_dev_t *mcpwm, int operator_id, int trig_id) { // the timer here is not selectable, must be the one connected with the operator mcpwm->operators[operator_id].gen_cfg0.val &= ~(0x07 << (4 + 3 * trig_id)); diff --git a/components/hal/esp32s3/include/hal/rmt_ll.h b/components/hal/esp32s3/include/hal/rmt_ll.h index 70812539f0..bb7e568066 100644 --- a/components/hal/esp32s3/include/hal/rmt_ll.h +++ b/components/hal/esp32s3/include/hal/rmt_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -54,15 +54,36 @@ static inline void rmt_ll_enable_periph_clock(rmt_dev_t *dev, bool enable) } /** - * @brief Power down memory + * @brief Force power on the RMT memory block, regardless of the outside PMU logic * * @param dev Peripheral instance address - * @param enable True to power down, False to power up */ -static inline void rmt_ll_power_down_mem(rmt_dev_t *dev, bool enable) +static inline void rmt_ll_mem_force_power_on(rmt_dev_t *dev) { - dev->sys_conf.mem_force_pu = !enable; - dev->sys_conf.mem_force_pd = enable; + dev->sys_conf.mem_force_pu = 1; + dev->sys_conf.mem_force_pd = 0; +} + +/** + * @brief Force power off the RMT memory block, regardless of the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_force_power_off(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 1; + dev->sys_conf.mem_force_pu = 0; +} + +/** + * @brief Power control the RMT memory block by the outside PMU logic + * + * @param dev Peripheral instance address + */ +static inline void rmt_ll_mem_power_by_pmu(rmt_dev_t *dev) +{ + dev->sys_conf.mem_force_pd = 0; + dev->sys_conf.mem_force_pu = 0; } /** @@ -463,6 +484,7 @@ static inline void rmt_ll_rx_set_channel_clock_div(rmt_dev_t *dev, uint32_t chan * @param dev Peripheral instance address * @param channel RMT RX channel number */ +__attribute__((always_inline)) static inline void rmt_ll_rx_reset_pointer(rmt_dev_t *dev, uint32_t channel) { dev->chmconf[channel].conf1.mem_wr_rst_chm = 1; @@ -518,6 +540,7 @@ static inline void rmt_ll_rx_set_mem_blocks(rmt_dev_t *dev, uint32_t channel, ui * @param channel RMT RX channel number * @param thres Time length threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_idle_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { dev->chmconf[channel].conf0.idle_thres_chm = thres; @@ -543,6 +566,7 @@ static inline void rmt_ll_rx_set_mem_owner(rmt_dev_t *dev, uint32_t channel, rmt * @param channel RMT RX chanenl number * @param enable True to enable, False to disable */ +__attribute__((always_inline)) static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, bool enable) { dev->chmconf[channel].conf1.rx_filter_en_chm = enable; @@ -555,6 +579,7 @@ static inline void rmt_ll_rx_enable_filter(rmt_dev_t *dev, uint32_t channel, boo * @param channel RMT RX channel number * @param thres Filter threshold */ +__attribute__((always_inline)) static inline void rmt_ll_rx_set_filter_thres(rmt_dev_t *dev, uint32_t channel, uint32_t thres) { HAL_FORCE_MODIFY_U32_REG_FIELD(dev->chmconf[channel].conf1, rx_filter_thres_chm, thres); @@ -813,12 +838,9 @@ static inline uint32_t rmt_ll_tx_get_idle_level(rmt_dev_t *dev, uint32_t channel return dev->chnconf0[channel].idle_out_lv_chn; } -static inline bool rmt_ll_is_mem_powered_down(rmt_dev_t *dev) +static inline bool rmt_ll_is_mem_force_powered_down(rmt_dev_t *dev) { - // the RTC domain can also power down RMT memory - // so it's probably not enough to detect whether it's powered down or not - // mem_force_pd has higher priority than mem_force_pu - return (dev->sys_conf.mem_force_pd) || !(dev->sys_conf.mem_force_pu); + return dev->sys_conf.mem_force_pd; } __attribute__((always_inline)) diff --git a/components/hal/esp32s3/include/hal/rtc_cntl_ll.h b/components/hal/esp32s3/include/hal/rtc_cntl_ll.h index 464aa99cd6..34d4cb8e34 100644 --- a/components/hal/esp32s3/include/hal/rtc_cntl_ll.h +++ b/components/hal/esp32s3/include/hal/rtc_cntl_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 */ @@ -11,6 +11,7 @@ #include "soc/rtc_cntl_reg.h" #include "soc/apb_ctrl_reg.h" #include "esp_attr.h" +#include "hal/assert.h" #ifdef __cplusplus extern "C" { @@ -38,11 +39,18 @@ FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_status(void) return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS); } -FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) +FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t io_mask, uint32_t mode_mask) { - REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, mask); - SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, - mode, RTC_CNTL_EXT_WAKEUP1_LV_S); + // The target only supports a unified trigger mode among all EXT1 wakeup IOs + HAL_ASSERT((io_mask & mode_mask) == io_mask || (io_mask & mode_mask) == 0); + REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, io_mask); + if ((io_mask & mode_mask) == io_mask) { + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + 1, RTC_CNTL_EXT_WAKEUP1_LV_S); + } else { + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + 0, RTC_CNTL_EXT_WAKEUP1_LV_S); + } } FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_pins(void) diff --git a/components/hal/esp32s3/include/hal/rtc_io_ll.h b/components/hal/esp32s3/include/hal/rtc_io_ll.h index 0494cf4819..6f52f0ff44 100644 --- a/components/hal/esp32s3/include/hal/rtc_io_ll.h +++ b/components/hal/esp32s3/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -143,7 +143,12 @@ static inline uint32_t rtcio_ll_get_level(int rtcio_num) static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strength) { if (rtc_io_desc[rtcio_num].drv_v) { - SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, strength, rtc_io_desc[rtcio_num].drv_s); + uint32_t drv_cap = strength; + // DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target + if (rtcio_num == RTCIO_GPIO17_CHANNEL || rtcio_num == RTCIO_GPIO18_CHANNEL) { + drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1 + } + SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, drv_cap, rtc_io_desc[rtcio_num].drv_s); } } @@ -155,7 +160,12 @@ static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strengt */ static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num) { - return GET_PERI_REG_BITS2(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, rtc_io_desc[rtcio_num].drv_s); + uint32_t strength = GET_PERI_REG_BITS2(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, rtc_io_desc[rtcio_num].drv_s); + // DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target + if (rtcio_num == RTCIO_GPIO17_CHANNEL || rtcio_num == RTCIO_GPIO18_CHANNEL) { + strength = ((strength & 0x1) << 1) | ((strength & 0x2) >> 1); // swap bit0 and bit1 + } + return strength; } /** diff --git a/components/hal/esp32s3/include/hal/spi_ll.h b/components/hal/esp32s3/include/hal/spi_ll.h index a5e1fdab29..a6785d1fe4 100644 --- a/components/hal/esp32s3/include/hal/spi_ll.h +++ b/components/hal/esp32s3/include/hal/spi_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 */ @@ -42,6 +42,7 @@ extern "C" { #define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits #define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words +#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized /** * The data structure holding calculated clock configuration. Since the @@ -188,36 +189,44 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw) } /** - * Check whether user-defined transaction is done. + * Determine and unify the default level of mosi line when bus free * * @param hw Beginning address of the peripheral registers. - * - * @return True if transaction is done, otherwise false. */ -static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level) { - return hw->dma_int_raw.trans_done; + hw->ctrl.d_pol = level; //set default level for MOSI only on IDLE state } /** - * Trigger start of user-defined transaction for master. - * The synchronization between two clock domains is required in ESP32-S3 + * Apply the register configurations and wait until it's done * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_master_user_start(spi_dev_t *hw) +static inline void spi_ll_apply_config(spi_dev_t *hw) { hw->cmd.update = 1; - while (hw->cmd.update); - hw->cmd.usr = 1; + while (hw->cmd.update); //waiting config applied +} + +/** + * Check whether user-defined transaction is done. + * + * @param hw Beginning address of the peripheral registers. + * + * @return True if transaction is done, otherwise false. + */ +static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +{ + return hw->dma_int_raw.trans_done; } /** - * Trigger start of user-defined transaction for slave. + * Trigger start of user-defined transaction. * * @param hw Beginning address of the peripheral registers. */ -static inline void spi_ll_slave_user_start(spi_dev_t *hw) +static inline void spi_ll_user_start(spi_dev_t *hw) { hw->cmd.usr = 1; } diff --git a/components/hal/esp32s3/include/hal/timer_ll.h b/components/hal/esp32s3/include/hal/timer_ll.h index f6bebcceea..f72a67efe6 100644 --- a/components/hal/esp32s3/include/hal/timer_ll.h +++ b/components/hal/esp32s3/include/hal/timer_ll.h @@ -196,6 +196,7 @@ static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, * @param timer_num Timer number in the group * @return reload count value */ +__attribute__((always_inline)) static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_num) { return ((uint64_t)hw->hw_timer[timer_num].loadhi.tn_load_hi << 32) | (hw->hw_timer[timer_num].loadlo.tn_load_lo); @@ -207,6 +208,7 @@ static inline uint64_t timer_ll_get_reload_value(timg_dev_t *hw, uint32_t timer_ * @param hw Timer Group register base address * @param timer_num Timer number in the group */ +__attribute__((always_inline)) static inline void timer_ll_trigger_soft_reload(timg_dev_t *hw, uint32_t timer_num) { hw->hw_timer[timer_num].load.tn_load = 1; diff --git a/components/hal/esp32s3/include/hal/uart_ll.h b/components/hal/esp32s3/include/hal/uart_ll.h index f7b9417916..5e86507013 100644 --- a/components/hal/esp32s3/include/hal/uart_ll.h +++ b/components/hal/esp32s3/include/hal/uart_ll.h @@ -29,7 +29,7 @@ extern "C" { // Get UART hardware instance with giving uart num #define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (((num) == 1) ? (&UART1) : (&UART2))) -#define UART_LL_MIN_WAKEUP_THRESH (2) +#define UART_LL_MIN_WAKEUP_THRESH (3) #define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask #define UART_LL_FSM_IDLE (0x0) @@ -153,13 +153,15 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint3 { #define DIV_UP(a, b) (((a) + (b) - 1) / (b)) const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits - int sclk_div = DIV_UP(sclk_freq, max_div * baud); + uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud); + + if (sclk_div == 0) abort(); uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div); // The baud rate configuration register is divided into // an integer part and a fractional part. hw->clkdiv.clkdiv = clk_div >> 4; - hw->clkdiv.clkdiv_frag = clk_div & 0xf; + hw->clkdiv.clkdiv_frag = clk_div & 0xf; HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1); #undef DIV_UP } @@ -609,6 +611,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) */ FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) { + // System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3) hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; } diff --git a/components/hal/esp32s3/include/hal/usb_ll.h b/components/hal/esp32s3/include/hal/usb_ll.h deleted file mode 100644 index 81950021d2..0000000000 --- a/components/hal/esp32s3/include/hal/usb_ll.h +++ /dev/null @@ -1,53 +0,0 @@ -// 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. - - -#include "soc/soc.h" -#include "soc/system_reg.h" -#include "soc/gpio_sig_map.h" -#include "soc/usb_periph.h" -#include "soc/rtc_cntl_struct.h" - -static inline void usb_ll_int_phy_enable(void) -{ - USB_WRAP.otg_conf.pad_enable = 1; - // USB_OTG use internal PHY - USB_WRAP.otg_conf.phy_sel = 0; - // phy_sel is controlled by the following register value - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // phy_sel=sw_usb_phy_sel=1, USB_OTG is connected with internal PHY - RTCCNTL.usb_conf.sw_usb_phy_sel = 1; -} - -static inline void usb_ll_ext_phy_enable(void) -{ - USB_WRAP.otg_conf.pad_enable = 1; - // USB_OTG use external PHY - USB_WRAP.otg_conf.phy_sel = 1; - // phy_sel is controlled by the following register value - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // phy_sel=sw_usb_phy_sel=0, USB_OTG is connected with external PHY through GPIO Matrix - RTCCNTL.usb_conf.sw_usb_phy_sel = 0; -} - -static inline void usb_ll_int_phy_pullup_conf(bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd) -{ - usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; - conf.pad_pull_override = 1; - conf.dp_pullup = dp_pu; - conf.dp_pulldown = dp_pd; - conf.dm_pullup = dm_pu; - conf.dm_pulldown = dm_pd; - USB_WRAP.otg_conf = conf; -} diff --git a/components/hal/esp32s3/include/hal/usb_phy_ll.h b/components/hal/esp32s3/include/hal/usb_phy_ll.h deleted file mode 100644 index acf6eed102..0000000000 --- a/components/hal/esp32s3/include/hal/usb_phy_ll.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#include "soc/soc.h" -#include "soc/system_reg.h" -#include "soc/usb_wrap_struct.h" -#include "soc/rtc_cntl_struct.h" -#include "soc/usb_serial_jtag_struct.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configures the internal PHY for USB_OTG - * - * @param hw Start address of the USB Wrap registers - */ -static inline void usb_phy_ll_int_otg_enable(usb_wrap_dev_t *hw) -{ - hw->otg_conf.pad_enable = 1; - // USB_OTG use internal PHY - hw->otg_conf.phy_sel = 0; - // phy_sel is controlled by the following register value - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // phy_sel=sw_usb_phy_sel=1, USB_OTG is connected with internal PHY - RTCCNTL.usb_conf.sw_usb_phy_sel = 1; -} - -/** - * @brief Configures the external PHY for USB_OTG - * - * @param hw Start address of the USB Wrap registers - */ -static inline void usb_phy_ll_ext_otg_enable(usb_wrap_dev_t *hw) -{ - // USB_OTG use external PHY - hw->otg_conf.phy_sel = 1; - // phy_sel is controlled by the following register value - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // phy_sel=sw_usb_phy_sel=0, USB_OTG is connected with external PHY through GPIO Matrix - RTCCNTL.usb_conf.sw_usb_phy_sel = 0; -} - -/** - * @brief Configures the internal PHY for USB_Serial_JTAG - * - * @param hw Start address of the USB Serial_JTAG registers - */ -static inline void usb_phy_ll_int_jtag_enable(usb_serial_jtag_dev_t *hw) -{ - // USB_Serial_JTAG use internal PHY - hw->conf0.phy_sel = 0; - // Disable software control USB D+ D- pullup pulldown (Device FS: dp_pullup = 1) - hw->conf0.pad_pull_override = 0; - // Enable USB D+ pullup - hw->conf0.dp_pullup = 1; - // Enable USB pad function - hw->conf0.usb_pad_enable = 1; - // phy_sel is controlled by the following register value - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // phy_sel=sw_usb_phy_sel=0, USB_Serial_JTAG is connected with internal PHY - RTCCNTL.usb_conf.sw_usb_phy_sel = 0; -} - -/** - * @brief Configures the external PHY for USB_Serial_JTAG - * - * @param hw Start address of the USB Serial_JTAG registers - */ -static inline void usb_phy_ll_ext_jtag_enable(usb_serial_jtag_dev_t *hw) -{ - // USB_Serial_JTAG use external PHY - hw->conf0.phy_sel = 1; - // phy_sel is controlled by the following register value - RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; - // phy_sel=sw_usb_phy_sel=1, USB_Serial_JTAG is connected with external PHY - RTCCNTL.usb_conf.sw_usb_phy_sel = 1; -} - -/** - * @brief Configures port loads for the internal PHY - * - * @param hw Start address of the USB Wrap registers - * @param dp_pu D+ pullup load - * @param dp_pd D+ pulldown load - * @param dm_pu D- pullup load - * @param dm_pd D- pulldown load - */ -static inline void usb_phy_ll_int_load_conf(usb_wrap_dev_t *hw, bool dp_pu, bool dp_pd, bool dm_pu, bool dm_pd) -{ - usb_wrap_otg_conf_reg_t conf = hw->otg_conf; - conf.pad_pull_override = 1; - conf.dp_pullup = dp_pu; - conf.dp_pulldown = dp_pd; - conf.dm_pullup = dm_pu; - conf.dm_pulldown = dm_pd; - hw->otg_conf = conf; -} - -/** - * @brief Enable the internal PHY's test mode - * - * @param hw Start address of the USB Wrap registers - * @param en Whether to enable the internal PHY's test mode - */ -static inline void usb_phy_ll_int_enable_test_mode(usb_wrap_dev_t *hw, bool en) -{ - if (en) { - // Clear USB_WRAP_TEST_CONF_REG - hw->test_conf.val = 0; - // Set USB test pad oen - hw->test_conf.test_usb_wrap_oe = 1; - // Enable USB test mode - hw->test_conf.test_enable = 1; - } else { - hw->test_conf.test_enable = 0; - } -} - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h index 3c0053385c..f8a867eb1f 100644 --- a/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h +++ b/components/hal/esp32s3/include/hal/usb_serial_jtag_ll.h @@ -1,23 +1,23 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -// The LL layer of the USB-serial-jtag controller - #pragma once + +#include +#include "esp_attr.h" +#include "soc/system_struct.h" +#include "soc/rtc_cntl_struct.h" #include "soc/usb_serial_jtag_reg.h" #include "soc/usb_serial_jtag_struct.h" +#include "hal/usb_serial_jtag_types.h" -#ifdef __cplusplus -extern "C" { -#endif - -//The in and out endpoints are this long. -#define USB_SERIAL_JTAG_PACKET_SZ_BYTES 64 +/* ----------------------------- Macros & Types ----------------------------- */ -#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) //All interrupt mask +#define USB_SERIAL_JTAG_LL_INTR_MASK (0x7ffff) // All interrupts mask +#define USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY // Define USB_SERIAL_JTAG interrupts // Note the hardware has more interrupts, but they're only useful for debugging @@ -31,6 +31,13 @@ typedef enum { USB_SERIAL_JTAG_INTR_EP1_ZERO_PAYLOAD = (1 << 10), } usb_serial_jtag_intr_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/* ----------------------------- USJ Peripheral ----------------------------- */ + /** * @brief Enable the USB_SERIAL_JTAG interrupt based on the given mask. * @@ -120,7 +127,7 @@ static inline uint32_t usb_serial_jtag_ll_read_rxfifo(uint8_t *buf, uint32_t rd_ * is room in the buffer. * * @param buf The data buffer. - * @param wr_len The data length needs to be writen. + * @param wr_len The data length needs to be written. * * @return Amount of bytes actually written. May be less than wr_len. */ @@ -158,6 +165,15 @@ static inline int usb_serial_jtag_ll_txfifo_writable(void) * @brief Flushes the TX buffer, that is, make it available for the * host to pick up. * + * @note When fifo is full (with 64 byte), HW will flush the buffer automatically, + * if this function is called directly after, this effectively turns into a + * no-op. Because a 64-byte packet will be interpreted as a not-complete USB + * transaction, you need to transfer either more data or a zero-length packet + * for the data to actually end up at the program listening to the CDC-ACM + * serial port. To send a zero-length packet, call + * usb_serial_jtag_ll_txfifo_flush() again when + * usb_serial_jtag_ll_txfifo_writable() returns true. + * * @return na */ static inline void usb_serial_jtag_ll_txfifo_flush(void) @@ -165,6 +181,167 @@ static inline void usb_serial_jtag_ll_txfifo_flush(void) USB_SERIAL_JTAG.ep1_conf.wr_done=1; } +/** + * @brief Enable USJ JTAG bridge + * + * If enabled, USJ is disconnected from internal JTAG interface. JTAG interface + * is routed through GPIO matrix instead. + * + * @param enable Enable USJ JTAG bridge + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_jtag_bridge(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_jtag_bridge_en = enable; +} + +/* ---------------------------- USB PHY Control ---------------------------- */ + +/** + * @brief Sets whether the USJ's FSLS PHY interface routes to an internal or external PHY + * + * @param enable Enables external PHY, internal otherwise + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_external(bool enable) +{ + USB_SERIAL_JTAG.conf0.phy_sel = enable; + // Enable SW control of muxing USB OTG vs USJ to the internal USB FSLS PHY + RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; + /* + For 'sw_usb_phy_sel': + 0 - Internal USB FSLS PHY is mapped to the USJ. USB Wrap mapped to external PHY + 1 - Internal USB FSLS PHY is mapped to the USB Wrap. USJ mapped to external PHY + */ + RTCCNTL.usb_conf.sw_usb_phy_sel = enable; +} + +/** + * @brief Enables/disables exchanging of the D+/D- pins USB PHY + * + * @param enable Enables pin exchange, disabled otherwise + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pin_exchg(bool enable) +{ + if (enable) { + USB_SERIAL_JTAG.conf0.exchg_pins = 1; + USB_SERIAL_JTAG.conf0.exchg_pins_override = 1; + } else { + USB_SERIAL_JTAG.conf0.exchg_pins_override = 0; + USB_SERIAL_JTAG.conf0.exchg_pins = 0; + } +} + +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_vref_override(unsigned int vrefh_step, unsigned int vrefl_step) +{ + USB_SERIAL_JTAG.conf0.vrefh = vrefh_step; + USB_SERIAL_JTAG.conf0.vrefl = vrefl_step; + USB_SERIAL_JTAG.conf0.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_vref_override(void) +{ + USB_SERIAL_JTAG.conf0.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param vals Override values to set + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pull_override(const usb_serial_jtag_pull_override_vals_t *vals) +{ + USB_SERIAL_JTAG.conf0.dp_pullup = vals->dp_pu; + USB_SERIAL_JTAG.conf0.dp_pulldown = vals->dp_pd; + USB_SERIAL_JTAG.conf0.dm_pullup = vals->dm_pu; + USB_SERIAL_JTAG.conf0.dm_pulldown = vals->dm_pd; + USB_SERIAL_JTAG.conf0.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_disable_pull_override(void) +{ + USB_SERIAL_JTAG.conf0.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_pullup_strength(bool strong) +{ + USB_SERIAL_JTAG.conf0.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_phy_is_pad_enabled(void) +{ + return USB_SERIAL_JTAG.conf0.usb_pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_enable_pad(bool enable) +{ + USB_SERIAL_JTAG.conf0.usb_pad_enable = enable; +} + +/** + * @brief Set USB FSLS PHY TX output clock edge + * + * @param clk_neg_edge True if TX output at negedge, posedge otherwise + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_phy_set_tx_edge(bool clk_neg_edge) +{ + USB_SERIAL_JTAG.conf0.phy_tx_edge_sel = clk_neg_edge; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + +/** + * @brief Enable the bus clock for USJ module + * @param clk_en True if enable the clock of USJ module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_enable_bus_clock(bool clk_en) +{ + SYSTEM.perip_clk_en1.usb_device_clk_en = clk_en; +} + +/** + * @brief Reset the USJ module + */ +FORCE_INLINE_ATTR void usb_serial_jtag_ll_reset_register(void) +{ + SYSTEM.perip_rst_en1.usb_device_rst = 1; + SYSTEM.perip_rst_en1.usb_device_rst = 0; +} + +/** + * Get the enable status of the USJ module + * + * @return Return true if USJ module is enabled + */ +FORCE_INLINE_ATTR bool usb_serial_jtag_ll_module_is_enabled(void) +{ + return (SYSTEM.perip_clk_en1.usb_device_clk_en && !SYSTEM.perip_rst_en1.usb_device_rst); +} #ifdef __cplusplus } diff --git a/components/hal/esp32s3/include/hal/usb_wrap_ll.h b/components/hal/esp32s3/include/hal/usb_wrap_ll.h new file mode 100644 index 0000000000..8fcd4177ed --- /dev/null +++ b/components/hal/esp32s3/include/hal/usb_wrap_ll.h @@ -0,0 +1,235 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_attr.h" +#include "soc/soc.h" +#include "soc/system_struct.h" +#include "soc/usb_wrap_struct.h" +#include "soc/rtc_cntl_struct.h" +#include "hal/usb_wrap_types.h" + +/* ----------------------------- Macros & Types ----------------------------- */ + +#define USB_WRAP_LL_EXT_PHY_SUPPORTED 1 // Can route to an external FSLS PHY + + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------- USB PHY Control ---------------------------- */ + +/** + * @brief Enables and sets the override value for the session end signal + * + * @param hw Start address of the USB Wrap registers + * @param sessend Session end override value. True means VBus < 0.2V, false means VBus > 0.8V + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_srp_sessend_override(usb_wrap_dev_t *hw, bool sessend) +{ + hw->otg_conf.srp_sessend_value = sessend; + hw->otg_conf.srp_sessend_override = 1; +} + +/** + * @brief Disable session end override + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_srp_sessend_override(usb_wrap_dev_t *hw) +{ + hw->otg_conf.srp_sessend_override = 0; +} + +/** + * @brief Sets whether the USB Wrap's FSLS PHY interface routes to an internal or external PHY + * + * @param hw Start address of the USB Wrap registers + * @param enable Enables external PHY, internal otherwise + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_external(usb_wrap_dev_t *hw, bool enable) +{ + hw->otg_conf.phy_sel = enable; + // Enable SW control of muxing USB OTG vs USJ to the internal USB FSLS PHY + RTCCNTL.usb_conf.sw_hw_usb_phy_sel = 1; + /* + For 'sw_usb_phy_sel': + 0 - Internal USB FSLS PHY is mapped to the USJ. USB Wrap mapped to external PHY + 1 - Internal USB FSLS PHY is mapped to the USB Wrap. USJ mapped to external PHY + */ + RTCCNTL.usb_conf.sw_usb_phy_sel = !enable; +} + +/** + * @brief Enables/disables exchanging of the D+/D- pins USB PHY + * + * @param hw Start address of the USB Wrap registers + * @param enable Enables pin exchange, disabled otherwise + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pin_exchg(usb_wrap_dev_t *hw, bool enable) +{ + if (enable) { + hw->otg_conf.exchg_pins = 1; + hw->otg_conf.exchg_pins_override = 1; + } else { + hw->otg_conf.exchg_pins_override = 0; + hw->otg_conf.exchg_pins = 0; + } +} + +/** + * @brief Enables and sets voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param hw Start address of the USB Wrap registers + * @param vrefh_step High voltage threshold. 0 to 3 indicating 80mV steps from 1.76V to 2V. + * @param vrefl_step Low voltage threshold. 0 to 3 indicating 80mV steps from 0.8V to 1.04V. + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_vref_override(usb_wrap_dev_t *hw, unsigned int vrefh_step, unsigned int vrefl_step) +{ + hw->otg_conf.vrefh = vrefh_step; + hw->otg_conf.vrefl = vrefl_step; + hw->otg_conf.vref_override = 1; +} + +/** + * @brief Disables voltage threshold overrides for USB FSLS PHY single-ended inputs + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_vref_override(usb_wrap_dev_t *hw) +{ + hw->otg_conf.vref_override = 0; +} + +/** + * @brief Enable override of USB FSLS PHY's pull up/down resistors + * + * @param hw Start address of the USB Wrap registers + * @param vals Override values to set + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pull_override(usb_wrap_dev_t *hw, const usb_wrap_pull_override_vals_t *vals) +{ + hw->otg_conf.dp_pullup = vals->dp_pu; + hw->otg_conf.dp_pulldown = vals->dp_pd; + hw->otg_conf.dm_pullup = vals->dm_pu; + hw->otg_conf.dm_pulldown = vals->dm_pd; + hw->otg_conf.pad_pull_override = 1; +} + +/** + * @brief Disable override of USB FSLS PHY pull up/down resistors + * + * @param hw Start address of the USB Wrap registers + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_disable_pull_override(usb_wrap_dev_t *hw) +{ + hw->otg_conf.pad_pull_override = 0; +} + +/** + * @brief Sets the strength of the pullup resistor + * + * @param hw Start address of the USB Wrap registers + * @param strong True is a ~1.4K pullup, false is a ~2.4K pullup + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_pullup_strength(usb_wrap_dev_t *hw, bool strong) +{ + hw->otg_conf.pullup_value = strong; +} + +/** + * @brief Check if USB FSLS PHY pads are enabled + * + * @param hw Start address of the USB Wrap registers + * @return True if enabled, false otherwise + */ +FORCE_INLINE_ATTR bool usb_wrap_ll_phy_is_pad_enabled(usb_wrap_dev_t *hw) +{ + return hw->otg_conf.pad_enable; +} + +/** + * @brief Enable the USB FSLS PHY pads + * + * @param hw Start address of the USB Wrap registers + * @param enable Whether to enable the USB FSLS PHY pads + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_pad(usb_wrap_dev_t *hw, bool enable) +{ + hw->otg_conf.pad_enable = enable; +} + +/** + * @brief Set USB FSLS PHY TX output clock edge + * + * @param hw Start address of the USB Wrap registers + * @param clk_neg_edge True if TX output at negedge, posedge otherwise + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_set_tx_edge(usb_wrap_dev_t *hw, bool clk_neg_edge) +{ + hw->otg_conf.phy_tx_edge_sel = clk_neg_edge; +} + +/* ------------------------------ USB PHY Test ------------------------------ */ + +/** + * @brief Enable the USB FSLS PHY's test mode + * + * @param hw Start address of the USB Wrap registers + * @param enable Whether to enable the USB FSLS PHY's test mode + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_enable_test_mode(usb_wrap_dev_t *hw, bool enable) +{ + hw->test_conf.test_enable = enable; +} + +/** + * @brief Set the USB FSLS PHY's signal test values + * + * @param hw Start address of the USB Wrap registers + * @param vals Test values to set + */ +FORCE_INLINE_ATTR void usb_wrap_ll_phy_test_mode_set_signals(usb_wrap_dev_t *hw, const usb_wrap_test_mode_vals_t *vals) +{ + usb_wrap_test_conf_reg_t test_conf; + test_conf.val = hw->test_conf.val; + + test_conf.test_usb_wrap_oe = vals->tx_enable_n; + test_conf.test_tx_dp = vals->tx_dp; + test_conf.test_tx_dm = vals->tx_dm; + test_conf.test_rx_rcv = vals->rx_rcv; + test_conf.test_rx_dp = vals->rx_dp; + test_conf.test_rx_dm = vals->rx_dm; + + hw->test_conf.val = test_conf.val; +} + +/* ----------------------------- RCC Functions ----------------------------- */ + +/** + * Enable the bus clock for USB Wrap module + * @param clk_en True if enable the clock of USB Wrap module + */ +FORCE_INLINE_ATTR void usb_wrap_ll_enable_bus_clock(bool clk_en) +{ + SYSTEM.perip_clk_en0.usb_clk_en = clk_en; +} + +/** + * @brief Reset the USB Wrap module + */ +FORCE_INLINE_ATTR void usb_wrap_ll_reset_register(void) +{ + SYSTEM.perip_rst_en0.usb_rst = 1; + SYSTEM.perip_rst_en0.usb_rst = 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32s3/rtc_cntl_hal.c b/components/hal/esp32s3/rtc_cntl_hal.c index 27d3c605be..94c74908b7 100644 --- a/components/hal/esp32s3/rtc_cntl_hal.c +++ b/components/hal/esp32s3/rtc_cntl_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 */ @@ -68,6 +68,14 @@ void rtc_cntl_hal_enable_cpu_retention(void *addr) ); rtc_cntl_ll_enable_cpu_retention_clock(); rtc_cntl_ll_enable_cpu_retention(); +#if SOC_PM_SUPPORT_TAGMEM_PD + if (!retent->tagmem.dcache.enable) { + // Here we only need to care for the safety of the PSRAM data in the DCache. + // Since only rodata, bss, heap data may be placed in PSRAM, and these data won't be + // modified in the sleep process code after now, so it is safe to writeback here. + Cache_WriteBack_All(); + } +#endif } } } diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index d023ff7dd6..d26efea69d 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -207,6 +207,13 @@ void adc_hal_digi_dis_intr(adc_hal_dma_ctx_t *hal, uint32_t mask); */ void adc_hal_digi_stop(adc_hal_dma_ctx_t *hal); +#if ADC_LL_WORKAROUND_CLEAR_EOF_COUNTER +/** + * @brief Clear the ADC sample counter + */ +void adc_hal_digi_clr_eof(void); +#endif + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index 16dfa20d19..d16c05cd80 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 */ @@ -41,9 +41,10 @@ typedef enum { */ typedef enum { ADC_ATTEN_DB_0 = 0, /// #include "hal/cache_types.h" #ifdef __cplusplus @@ -39,6 +40,35 @@ void cache_hal_disable(cache_type_t type); */ void cache_hal_enable(cache_type_t type); +/** + * @brief Suspend cache + * + * Suspend the ICache or DCache or both,suspends the CPU access to cache for a while, without invalidation. + * + * @param type see `cache_type_t` + * + * @return Current status of corresponding Cache(s) + */ +void cache_hal_suspend(cache_type_t type); + +/** + * @brief Resume cache + * + * Resume the ICache or DCache or both. + * + * @param type see `cache_type_t` + */ +void cache_hal_resume(cache_type_t type); + +/** + * @brief Check if corresponding cache is enabled or not + * + * @param type see `cache_type_t` + * + * @return true: enabled; false: disabled + */ +bool cache_hal_is_cache_enabled(cache_type_t type); + /** * @brief Invalidate cache supported addr * diff --git a/components/hal/include/hal/ecdsa_hal.h b/components/hal/include/hal/ecdsa_hal.h index 02bad6092b..2e60642b7c 100644 --- a/components/hal/include/hal/ecdsa_hal.h +++ b/components/hal/include/hal/ecdsa_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ #pragma once +#include #include #include "hal/ecdsa_types.h" @@ -25,7 +26,6 @@ extern "C" { typedef struct { ecdsa_mode_t mode; /* Mode of operation */ ecdsa_curve_t curve; /* Curve to use for operation */ - ecdsa_k_mode_t k_mode; /* Source of K */ ecdsa_sha_mode_t sha_mode; /* Source of SHA that needs to be signed */ int efuse_key_blk; /* Efuse block to use as ECDSA key (The purpose of the efuse block must be ECDSA_KEY) */ } ecdsa_hal_config_t; @@ -34,13 +34,12 @@ typedef struct { * @brief Generate ECDSA signature * * @param conf Configuration for ECDSA operation, see ``ecdsa_hal_config_t`` - * @param k Value of K used internally. Set this to NULL if K is generated by hardware * @param hash Hash that is to be signed * @param r_out Buffer that will contain `R` component of ECDSA signature * @param s_out Buffer that will contain `S` component of ECDSA signature * @param len Length of the r_out and s_out buffer (32 bytes for SECP256R1, 24 for SECP192R1) */ -void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *k, const uint8_t *hash, +void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *hash, uint8_t *r_out, uint8_t *s_out, uint16_t len); /** @@ -59,6 +58,15 @@ void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *k, const u */ int ecdsa_hal_verify_signature(ecdsa_hal_config_t *conf, const uint8_t *hash, const uint8_t *r, const uint8_t *s, const uint8_t *pub_x, const uint8_t *pub_y, uint16_t len); + +/** + * @brief Check if the ECDSA operation is successful + * + * @return - true, if the ECDSA operation is successful + * - false, if the ECDSA operation fails + */ +bool ecdsa_hal_get_operation_result(void); + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/ecdsa_types.h b/components/hal/include/hal/ecdsa_types.h index fdb2f3d3cf..a296f665b6 100644 --- a/components/hal/include/hal/ecdsa_types.h +++ b/components/hal/include/hal/ecdsa_types.h @@ -25,14 +25,6 @@ typedef enum { ECDSA_CURVE_SECP256R1, } ecdsa_curve_t; -/** - * @brief Source of 'K' used internally for generating signature - */ -typedef enum { - ECDSA_K_USE_TRNG, - ECDSA_K_USER_PROVIDED, -} ecdsa_k_mode_t; - /** * @brief Source of SHA message that is to be signed/verified */ diff --git a/components/hal/include/hal/gpio_hal.h b/components/hal/include/hal/gpio_hal.h index 22fba943f7..9b10653de8 100644 --- a/components/hal/include/hal/gpio_hal.h +++ b/components/hal/include/hal/gpio_hal.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 */ @@ -32,9 +32,26 @@ extern "C" { typedef struct { gpio_dev_t *dev; - uint32_t version; } gpio_hal_context_t; +/** + * @brief Get the configuration for an IO + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + * @param pu Pointer to accept the status of pull-up enabled or not + * @param pd Pointer to accept the status of pull-down enabled or not + * @param ie Pointer to accept the status of input enabled or not + * @param oe Pointer to accept the status of output enabled or not + * @param od Pointer to accept the status of open-drain enabled or not + * @param drv Pointer to accept the value of drive strength + * @param fun_sel Pointer to accept the value of IOMUX function selection + * @param sig_out Pointer to accept the index of outputting peripheral signal + * @param slp_sel Pointer to accept the status of pin sleep mode enabled or not + */ +#define gpio_hal_get_io_config(hal, gpio_num, pu, pd, ie, oe, od, drv, fun_sel, sig_out, slp_sel) \ + gpio_ll_get_io_config((hal)->dev, gpio_num, pu, pd, ie, oe, od, drv, fun_sel, sig_out, slp_sel) + /** * @brief Enable pull-up on GPIO. * @@ -171,12 +188,24 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, uint32_t gpio_num); /** * @brief Select a function for the pin in the IOMUX * - * @param hw Peripheral GPIO hardware instance address. + * @param hal Context of the HAL layer * @param gpio_num GPIO number * @param func Function to assign to the pin */ #define gpio_hal_func_sel(hal, gpio_num, func) gpio_ll_func_sel((hal)->dev, gpio_num, func) +/** + * @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix + * + * @param hal Context of the HAL layer + * @param in_sig_idx Peripheral signal index (tagged as input attribute) + * + * @return + * - -1 Signal bypassed GPIO matrix + * - Others GPIO number + */ +#define gpio_hal_get_in_signal_connected_io(hal, in_sig_idx) gpio_ll_get_in_signal_connected_io((hal)->dev, in_sig_idx) + /** * @brief GPIO set output level * diff --git a/components/hal/include/hal/ieee802154_common_ll.h b/components/hal/include/hal/ieee802154_common_ll.h index 45f077bb4a..86ac495ac4 100644 --- a/components/hal/include/hal/ieee802154_common_ll.h +++ b/components/hal/include/hal/ieee802154_common_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -89,6 +89,7 @@ typedef enum { } ieee802154_ll_rx_abort_reason_t; typedef uint32_t ieee802154_ll_rx_abort_events; +#define IEEE802154_RX_ABORT_ALL 0x7fffffff /** * @brief IEEE802154 transmission failed reason. @@ -112,6 +113,7 @@ typedef enum { } ieee802154_ll_tx_abort_reason_t; typedef uint32_t ieee802154_ll_tx_abort_events; +#define IEEE802154_TX_ABORT_ALL 0x7fffffff /** * @brief IEEE802154 CCA mode. @@ -162,6 +164,8 @@ typedef enum { IEEE802154_ED_SAMPLE_AVG = 0x01, } ieee802154_ll_ed_sample_mode_t; +#define IEEE802154_RX_STATUS_RECEIVE_SFD 0x1 + FORCE_INLINE_ATTR void ieee802154_ll_set_cmd(ieee802154_ll_cmd_t cmd) { IEEE802154.cmd.cmd = cmd; @@ -187,6 +191,11 @@ FORCE_INLINE_ATTR ieee802154_ll_events ieee802154_ll_get_events(void) return IEEE802154.event_status.events; } +FORCE_INLINE_ATTR bool ieee802154_ll_is_current_rx_frame(void) +{ + return (IEEE802154.rx_status.rx_state > IEEE802154_RX_STATUS_RECEIVE_SFD); +} + static inline void ieee802154_ll_enable_rx_abort_events(ieee802154_ll_rx_abort_events events) { IEEE802154.rx_abort_event_en.rx_abort_en |= events; @@ -449,6 +458,86 @@ static inline void ieee802154_ll_disable_coex(void) IEEE802154.pti.hw_ack_pti = 1; } +static inline void ieee802154_ll_clear_debug_cnt(uint32_t clear_bits) +{ + IEEE802154.debug_cnt_clr.val = clear_bits; +} + +static inline uint32_t ieee802154_ll_get_sfd_timeout_cnt(void) +{ + return IEEE802154.debug_sfd_timeout_cnt; +} + +static inline uint32_t ieee802154_ll_get_crc_error_cnt(void) +{ + return IEEE802154.debug_crc_error_cnt; +} + +static inline uint32_t ieee802154_ll_get_ed_abort_cnt(void) +{ + return IEEE802154.debug_ed_abort_cnt; +} + +static inline uint32_t ieee802154_ll_get_cca_fail_cnt(void) +{ + return IEEE802154.debug_cca_fail_cnt; +} + +static inline uint32_t ieee802154_ll_get_rx_fliter_fail_cnt(void) +{ + return IEEE802154.debug_rx_filter_fail_cnt; +} + +static inline uint32_t ieee802154_ll_get_no_rss_detect_cnt(void) +{ + return IEEE802154.debug_no_rss_detect_cnt; +} + +static inline uint32_t ieee802154_ll_get_rx_abort_coex_cnt(void) +{ + return IEEE802154.debug_rx_abort_coex_cnt; +} + +static inline uint32_t ieee802154_ll_get_rx_restart_cnt(void) +{ + return IEEE802154.debug_rx_restart_cnt; +} + +static inline uint32_t ieee802154_ll_get_tx_ack_abort_coex_cnt(void) +{ + return IEEE802154.debug_tx_ack_abort_coex_cnt; +} + +static inline uint32_t ieee802154_ll_get_ed_scan_coex_cnt(void) +{ + return IEEE802154.debug_ed_scan_break_coex_cnt; +} + +static inline uint32_t ieee802154_ll_get_rx_ack_abort_coex_cnt(void) +{ + return IEEE802154.debug_rx_ack_abort_coex_cnt; +} + +static inline uint32_t ieee802154_ll_get_rx_ack_timeout_cnt(void) +{ + return IEEE802154.debug_rx_ack_timeout_cnt; +} + +static inline uint32_t ieee802154_ll_get_tx_break_coex_cnt(void) +{ + return IEEE802154.debug_tx_break_coex_cnt; +} + +static inline uint32_t ieee802154_ll_get_tx_security_error_cnt(void) +{ + return IEEE802154.debug_tx_security_error_cnt; +} + +static inline uint32_t ieee802154_ll_get_cca_busy_cnt(void) +{ + return IEEE802154.debug_cca_busy_cnt; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/lcd_types.h b/components/hal/include/hal/lcd_types.h index 0bf2b412bd..1993e45173 100644 --- a/components/hal/include/hal/lcd_types.h +++ b/components/hal/include/hal/lcd_types.h @@ -24,9 +24,17 @@ typedef soc_periph_lcd_clk_src_t lcd_clock_source_t; * @brief RGB color endian */ typedef enum { - LCD_RGB_ENDIAN_RGB, /*!< RGB data endian: RGB */ - LCD_RGB_ENDIAN_BGR, /*!< RGB data endian: BGR */ -} lcd_color_rgb_endian_t; + LCD_RGB_ELEMENT_ORDER_RGB, /*!< RGB element order: RGB */ + LCD_RGB_ELEMENT_ORDER_BGR, /*!< RGB element order: BGR */ +} lcd_rgb_element_order_t; + +/** + * @brief RGB data endian + */ +typedef enum { + LCD_RGB_DATA_ENDIAN_BIG = 0, /*!< RGB data endian: MSB first */ + LCD_RGB_DATA_ENDIAN_LITTLE, /*!< RGB data endian: LSB first */ +} lcd_rgb_data_endian_t; /** * @brief LCD color space diff --git a/components/hal/include/hal/mcpwm_types.h b/components/hal/include/hal/mcpwm_types.h index 7ee1beb495..2490a04e0c 100644 --- a/components/hal/include/hal/mcpwm_types.h +++ b/components/hal/include/hal/mcpwm_types.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 */ @@ -31,6 +31,15 @@ typedef soc_periph_mcpwm_capture_clk_src_t mcpwm_capture_clock_source_t; typedef int mcpwm_capture_clock_source_t; #endif // SOC_MCPWM_SUPPORTED +/** + * @brief MCPWM carrier clock source + */ +#if SOC_MCPWM_SUPPORTED +typedef soc_periph_mcpwm_carrier_clk_src_t mcpwm_carrier_clock_source_t; +#else +typedef int mcpwm_carrier_clock_source_t; +#endif // SOC_MCPWM_SUPPORTED + /** * @brief MCPWM timer count direction */ @@ -84,7 +93,7 @@ typedef enum { */ typedef enum { MCPWM_OPER_BRAKE_MODE_CBC, /*!< Brake mode: CBC (cycle by cycle)*/ - MCPWM_OPER_BRAKE_MODE_OST, /*!< Brake mode, OST (one shot) */ + MCPWM_OPER_BRAKE_MODE_OST, /*!< Brake mode: OST (one shot) */ MCPWM_OPER_BRAKE_MODE_INVALID, /*!< MCPWM operator invalid brake mode */ } mcpwm_operator_brake_mode_t; diff --git a/components/hal/include/hal/modem_clock_hal.h b/components/hal/include/hal/modem_clock_hal.h index 9e74e37d22..e3cb2b8e05 100644 --- a/components/hal/include/hal/modem_clock_hal.h +++ b/components/hal/include/hal/modem_clock_hal.h @@ -27,7 +27,8 @@ void modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain); #endif -void modem_clock_hal_enable_fe_clock(modem_clock_hal_context_t *hal, bool enable); +void modem_clock_hal_enable_modem_adc_common_fe_clock(modem_clock_hal_context_t *hal, bool enable); +void modem_clock_hal_enable_modem_private_fe_clock(modem_clock_hal_context_t *hal, bool enable); #if SOC_BT_SUPPORTED void modem_clock_hal_set_ble_rtc_timer_divisor_value(modem_clock_hal_context_t *hal, uint32_t divider); diff --git a/components/hal/include/hal/modem_clock_types.h b/components/hal/include/hal/modem_clock_types.h index ed435be226..bb972f7a7f 100644 --- a/components/hal/include/hal/modem_clock_types.h +++ b/components/hal/include/hal/modem_clock_types.h @@ -15,13 +15,12 @@ typedef enum { MODEM_CLOCK_DOMAIN_MODEM_PERIPH, MODEM_CLOCK_DOMAIN_WIFI, MODEM_CLOCK_DOMAIN_BT, - MODEM_CLOCK_DOMAIN_FE, + MODEM_CLOCK_DOMAIN_MODEM_FE, MODEM_CLOCK_DOMAIN_IEEE802154, MODEM_CLOCK_DOMAIN_LP_APB, MODEM_CLOCK_DOMAIN_I2C_MASTER, MODEM_CLOCK_DOMAIN_COEX, MODEM_CLOCK_DOMAIN_WIFIPWR, - MODEM_CLOCK_DOMAIN_MAX } modem_clock_domain_t; diff --git a/components/hal/include/hal/pau_hal.h b/components/hal/include/hal/pau_hal.h index 5aae8900f5..7a8456cf38 100644 --- a/components/hal/include/hal/pau_hal.h +++ b/components/hal/include/hal/pau_hal.h @@ -53,7 +53,7 @@ void pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_rest void pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal); #endif -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA /** * @brief Set regdma system link address * @@ -100,7 +100,7 @@ void pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_rest */ void pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal); -#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA /** * @brief Enable or disable PAU module clock * diff --git a/components/hal/include/hal/rtc_hal.h b/components/hal/include/hal/rtc_hal.h index 6848d559d8..c889a2ad07 100644 --- a/components/hal/include/hal/rtc_hal.h +++ b/components/hal/include/hal/rtc_hal.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 */ @@ -41,15 +41,15 @@ typedef struct rtc_cntl_sleep_retent { #if SOC_PM_SUPPORT_EXT1_WAKEUP -#define rtc_hal_ext1_get_wakeup_status() rtc_cntl_ll_ext1_get_wakeup_status() +#define rtc_hal_ext1_get_wakeup_status() rtc_cntl_ll_ext1_get_wakeup_status() -#define rtc_hal_ext1_clear_wakeup_status() rtc_cntl_ll_ext1_clear_wakeup_status() +#define rtc_hal_ext1_clear_wakeup_status() rtc_cntl_ll_ext1_clear_wakeup_status() -#define rtc_hal_ext1_set_wakeup_pins(mask, mode) rtc_cntl_ll_ext1_set_wakeup_pins(mask, mode) +#define rtc_hal_ext1_set_wakeup_pins(io_mask, mode_mask) rtc_cntl_ll_ext1_set_wakeup_pins(io_mask, mode_mask) -#define rtc_hal_ext1_clear_wakeup_pins() rtc_cntl_ll_ext1_clear_wakeup_pins() +#define rtc_hal_ext1_clear_wakeup_pins() rtc_cntl_ll_ext1_clear_wakeup_pins() -#define rtc_hal_ext1_get_wakeup_pins() rtc_cntl_ll_ext1_get_wakeup_pins() +#define rtc_hal_ext1_get_wakeup_pins() rtc_cntl_ll_ext1_get_wakeup_pins() #endif // SOC_PM_SUPPORT_EXT1_WAKEUP diff --git a/components/hal/include/hal/rtc_io_hal.h b/components/hal/include/hal/rtc_io_hal.h index 1763d0f92b..a2422480aa 100644 --- a/components/hal/include/hal/rtc_io_hal.h +++ b/components/hal/include/hal/rtc_io_hal.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 */ @@ -18,16 +18,18 @@ #include "sdkconfig.h" #include "soc/soc_caps.h" -#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED +#if SOC_RTCIO_PIN_COUNT > 0 #include "hal/rtc_io_ll.h" +#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED #include "hal/rtc_io_types.h" #endif +#endif //SOC_RTCIO_PIN_COUNT > 0 #ifdef __cplusplus extern "C" { #endif -#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED +#if SOC_RTCIO_PIN_COUNT > 0 /** * Select the rtcio function. * @@ -37,6 +39,7 @@ extern "C" { */ #define rtcio_hal_function_select(rtcio_num, func) rtcio_ll_function_select(rtcio_num, func) +#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED /** * Enable rtcio output. * @@ -235,7 +238,7 @@ void rtcio_hal_set_direction_in_sleep(int rtcio_num, rtc_gpio_mode_t mode); #endif -#if SOC_RTCIO_HOLD_SUPPORTED || SOC_RTCIO_INPUT_OUTPUT_SUPPORTED +#if SOC_RTCIO_HOLD_SUPPORTED && SOC_RTCIO_INPUT_OUTPUT_SUPPORTED /** * Helper function to disconnect internal circuits from an RTC IO @@ -254,6 +257,8 @@ void rtcio_hal_isolate(int rtc_num); #endif +#endif //SOC_RTCIO_PIN_COUNT > 0 + #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT > 0) #define gpio_hal_deepsleep_wakeup_enable(hal, gpio_num, intr_type) rtcio_hal_wakeup_enable(gpio_num, intr_type) @@ -283,7 +288,8 @@ void rtcio_hal_isolate(int rtc_num); */ #define rtcio_hal_clear_interrupt_status() rtcio_ll_clear_interrupt_status() -#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT > 0) + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/usb_dwc_hal.h b/components/hal/include/hal/usb_dwc_hal.h index d52e882cb9..33ac57be75 100644 --- a/components/hal/include/hal/usb_dwc_hal.h +++ b/components/hal/include/hal/usb_dwc_hal.h @@ -1,36 +1,57 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - +#include "soc/soc_caps.h" /* -NOTE: Thread safety is the responsibility fo the HAL user. All USB Host HAL - functions must be called from critical sections unless specified otherwise +This header is shared across all targets. Resolve to an empty header for targets +that don't support USB OTG. */ - -#include -#include -#include "soc/usb_dwc_struct.h" +#if SOC_USB_OTG_SUPPORTED +#include +#include #include "hal/usb_dwc_ll.h" -#include "hal/usb_types_private.h" +#include "hal/usb_dwc_types.h" #include "hal/assert.h" +#endif // SOC_USB_OTG_SUPPORTED + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_USB_OTG_SUPPORTED // ------------------------------------------------ Macros and Types --------------------------------------------------- -// ------------------ Constants/Configs -------------------- +// ----------------------- Configs ------------------------- + +/** + * @brief Possible FIFO biases + */ +typedef enum { + USB_HAL_FIFO_BIAS_DEFAULT, /**< Default (balanced) FIFO sizes */ + USB_HAL_FIFO_BIAS_RX, /**< Bigger RX FIFO for IN transfers */ + USB_HAL_FIFO_BIAS_PTX, /**< Bigger periodic TX FIFO for ISOC OUT transfers */ +} usb_hal_fifo_bias_t; -#define USB_DWC_HAL_DMA_MEM_ALIGN 512 -#define USB_DWC_HAL_FRAME_LIST_MEM_ALIGN 512 //The frame list needs to be 512 bytes aligned (contrary to the databook) -#define USB_DWC_HAL_NUM_CHAN 8 -#define USB_DWC_HAL_XFER_DESC_SIZE (sizeof(usb_dwc_ll_dma_qtd_t)) -#define USB_DWC_HAL_FIFO_TOTAL_USABLE_LINES 200 //Although we have a 256 lines, only 200 lines are usuable due to EPINFO_CTL +/** + * @brief MPS limits based on FIFO configuration + * + * In bytes + * + * The resulting values depend on + * 1. FIFO total size (chip specific) + * 2. Set FIFO bias + */ +typedef struct { + unsigned int in_mps; /**< Maximum packet size of IN packet */ + unsigned int non_periodic_out_mps; /**< Maximum packet size of BULK and CTRL OUT packets */ + unsigned int periodic_out_mps; /**< Maximum packet size of INTR and ISOC OUT packets */ +} usb_hal_fifo_mps_limits_t; /** * @brief FIFO size configuration structure @@ -108,7 +129,7 @@ typedef enum { typedef struct { union { struct { - usb_priv_xfer_type_t type: 2; /**< The type of endpoint */ + usb_dwc_xfer_type_t type: 2; /**< The type of endpoint */ uint32_t bEndpointAddress: 8; /**< Endpoint address (containing endpoint number and direction) */ uint32_t mps: 11; /**< Maximum Packet Size */ uint32_t dev_addr: 8; /**< Device Address */ @@ -119,8 +140,9 @@ typedef struct { uint32_t val; }; struct { - usb_hal_interval_t interval; /**< The interval of the endpoint */ - uint32_t phase_offset_frames; /**< Phase offset in number of frames */ + unsigned int interval; /**< The interval of the endpoint in frames (FS) or microframes (HS) */ + uint32_t offset; /**< Offset of this channel in the periodic scheduler */ + bool is_hs; /**< This endpoint is HighSpeed. Needed for Periodic Frame List (HAL layer) scheduling */ } periodic; /**< Characteristic for periodic (interrupt/isochronous) endpoints only */ } usb_dwc_hal_ep_char_t; @@ -139,9 +161,9 @@ typedef struct { }; uint32_t val; } flags; /**< Flags regarding channel's status and information */ - usb_dwc_host_chan_regs_t *regs; /**< Pointer to the channel's register set */ - usb_dwc_hal_chan_error_t error; /**< The last error that occurred on the channel */ - usb_priv_xfer_type_t type; /**< The transfer type of the channel */ + usb_dwc_host_chan_regs_t *regs; /**< Pointer to the channel's register set */ + usb_dwc_hal_chan_error_t error; /**< The last error that occurred on the channel */ + usb_dwc_xfer_type_t type; /**< The transfer type of the channel */ void *chan_ctx; /**< Context variable for the owner of the channel */ } usb_dwc_hal_chan_t; @@ -152,8 +174,10 @@ typedef struct { //Context usb_dwc_dev_t *dev; /**< Pointer to base address of DWC_OTG registers */ //Host Port related - uint32_t *periodic_frame_list; /**< Pointer to scheduling frame list */ - usb_hal_frame_list_len_t frame_list_len; /**< Length of the periodic scheduling frame list */ + uint32_t *periodic_frame_list; /**< Pointer to scheduling frame list */ + usb_hal_frame_list_len_t frame_list_len; /**< Length of the periodic scheduling frame list */ + //FIFO related + usb_dwc_hal_fifo_config_t fifo_config; /**< FIFO sizes configuration */ union { struct { uint32_t dbnc_lock_enabled: 1; /**< Debounce lock enabled */ @@ -168,7 +192,7 @@ typedef struct { struct { int num_allocd; /**< Number of channels currently allocated */ uint32_t chan_pend_intrs_msk; /**< Bit mask of channels with pending interrupts */ - usb_dwc_hal_chan_t *hdls[USB_DWC_HAL_NUM_CHAN]; /**< Handles of each channel. Set to NULL if channel has not been allocated */ + usb_dwc_hal_chan_t *hdls[OTG_NUM_HOST_CHAN]; /**< Handles of each channel. Set to NULL if channel has not been allocated */ } channels; } usb_dwc_hal_context_t; @@ -181,7 +205,7 @@ typedef struct { * - The peripheral must have been reset and clock un-gated * - The USB PHY (internal or external) and associated GPIOs must already be configured * - GPIO pins configured - * - Interrupt allocated but DISABLED (in case of an unknown interupt state) + * - Interrupt allocated but DISABLED (in case of an unknown interrupt state) * Exit: * - Checks to see if DWC_OTG is alive, and if HW version/config is correct * - HAl context initialized @@ -222,21 +246,28 @@ void usb_dwc_hal_deinit(usb_dwc_hal_context_t *hal); void usb_dwc_hal_core_soft_reset(usb_dwc_hal_context_t *hal); /** - * @brief Set FIFO sizes + * @brief Set FIFO bias * * This function will set the sizes of each of the FIFOs (RX FIFO, Non-periodic TX FIFO, Periodic TX FIFO) and must be - * called at least once before allocating the channel. Based on the type of endpoints (and the endpionts' MPS), there + * called at least once before allocating the channel. Based on the type of endpoints (and the endpoints' MPS), there * may be situations where this function may need to be called again to resize the FIFOs. If resizing FIFOs dynamically, * it is the user's responsibility to ensure there are no active channels when this function is called. * - * @note The totol size of all the FIFOs must be less than or equal to USB_DWC_HAL_FIFO_TOTAL_USABLE_LINES * @note After a port reset, the FIFO size registers will reset to their default values, so this function must be called * again post reset. * - * @param hal Context of the HAL layer - * @param fifo_config FIFO configuration + * @param[in] hal Context of the HAL layer + * @param[in] fifo_bias FIFO bias configuration + */ +void usb_dwc_hal_set_fifo_bias(usb_dwc_hal_context_t *hal, const usb_hal_fifo_bias_t fifo_bias); + +/** + * @brief Get MPS limits + * + * @param[in] hal Context of the HAL layer + * @param[out] mps_limits MPS limits */ -void usb_dwc_hal_set_fifo_size(usb_dwc_hal_context_t *hal, const usb_dwc_hal_fifo_config_t *fifo_config); +void usb_dwc_hal_get_mps_limits(usb_dwc_hal_context_t *hal, usb_hal_fifo_mps_limits_t *mps_limits); // ---------------------------------------------------- Host Port ------------------------------------------------------ @@ -259,7 +290,7 @@ static inline void usb_dwc_hal_port_init(usb_dwc_hal_context_t *hal) /** * @brief Deinitialize the host port * - * - Will disable the host port's interrupts preventing further port aand channel events from ocurring + * - Will disable the host port's interrupts preventing further port aand channel events from occurring * * @param hal Context of the HAL layer */ @@ -302,7 +333,6 @@ static inline void usb_dwc_hal_port_toggle_power(usb_dwc_hal_context_t *hal, boo */ static inline void usb_dwc_hal_port_toggle_reset(usb_dwc_hal_context_t *hal, bool enable) { - HAL_ASSERT(hal->channels.num_allocd == 0); //Cannot reset if there are still allocated channels usb_dwc_ll_hprt_set_port_reset(hal->dev, enable); } @@ -395,17 +425,6 @@ static inline void usb_dwc_hal_port_set_frame_list(usb_dwc_hal_context_t *hal, u hal->frame_list_len = len; } -/** - * @brief Get the pointer to the periodic scheduling frame list - * - * @param hal Context of the HAL layer - * @return uint32_t* Base address of the periodic scheduling frame list - */ -static inline uint32_t *usb_dwc_hal_port_get_frame_list(usb_dwc_hal_context_t *hal) -{ - return hal->periodic_frame_list; -} - /** * @brief Enable periodic scheduling * @@ -427,7 +446,7 @@ static inline void usb_dwc_hal_port_periodic_enable(usb_dwc_hal_context_t *hal) /** * @brief Disable periodic scheduling * - * Disabling periodic scheduling will save a bit of DMA bandwith (as the controller will no longer fetch the schedule + * Disabling periodic scheduling will save a bit of DMA bandwidth (as the controller will no longer fetch the schedule * from the frame list). * * @note Before disabling periodic scheduling, it is the user's responsibility to ensure that all periodic channels have @@ -469,14 +488,14 @@ static inline bool usb_dwc_hal_port_check_if_connected(usb_dwc_hal_context_t *ha } /** - * @brief Check the speed (LS/FS) of the device connected to the host port + * @brief Check the speed of the device connected to the host port * * @note This function should only be called after confirming that a device is connected to the host port * * @param hal Context of the HAL layer - * @return usb_priv_speed_t Speed of the connected device (FS or LS only on the esp32-s2 and esp32-s3) + * @return usb_dwc_speed_t Speed of the connected device */ -static inline usb_priv_speed_t usb_dwc_hal_port_get_conn_speed(usb_dwc_hal_context_t *hal) +static inline usb_dwc_speed_t usb_dwc_hal_port_get_conn_speed(usb_dwc_hal_context_t *hal) { return usb_dwc_ll_hprt_get_speed(hal->dev); } @@ -485,17 +504,17 @@ static inline usb_priv_speed_t usb_dwc_hal_port_get_conn_speed(usb_dwc_hal_conte * @brief Disable the debounce lock * * This function must be called after calling usb_dwc_hal_port_check_if_connected() and will allow connection/disconnection - * events to occur again. Any pending connection or disconenction interrupts are cleared. + * events to occur again. Any pending connection or disconnection interrupts are cleared. * * @param hal Context of the HAL layer */ static inline void usb_dwc_hal_disable_debounce_lock(usb_dwc_hal_context_t *hal) { hal->flags.dbnc_lock_enabled = 0; - //Clear Conenction and disconenction interrupt in case it triggered again + //Clear Connection and disconnection interrupt in case it triggered again usb_dwc_ll_gintsts_clear_intrs(hal->dev, USB_DWC_LL_INTR_CORE_DISCONNINT); usb_dwc_ll_hprt_intr_clear(hal->dev, USB_DWC_LL_INTR_HPRT_PRTCONNDET); - //Reenable the hprt (connection) and disconnection interrupts + //Re-enable the hprt (connection) and disconnection interrupts usb_dwc_ll_gintmsk_en_intrs(hal->dev, USB_DWC_LL_INTR_CORE_PRTINT | USB_DWC_LL_INTR_CORE_DISCONNINT); } @@ -652,10 +671,10 @@ bool usb_dwc_hal_chan_request_halt(usb_dwc_hal_chan_t *chan_obj); /** * @brief Indicate that a channel is halted after a port error * - * When a port error occurs (e.g., discconect, overcurrent): + * When a port error occurs (e.g., disconnect, overcurrent): * - Any previously active channels will remain active (i.e., they will not receive a channel interrupt) * - Attempting to disable them using usb_dwc_hal_chan_request_halt() will NOT generate an interrupt for ISOC channels - * (probalby something to do with the periodic scheduling) + * (probably something to do with the periodic scheduling) * * However, the channel's enable bit can be left as 1 since after a port error, a soft reset will be done anyways. * This function simply updates the channels internal state variable to indicate it is halted (thus allowing it to be @@ -785,6 +804,8 @@ usb_dwc_hal_chan_t *usb_dwc_hal_get_chan_pending_intr(usb_dwc_hal_context_t *hal */ usb_dwc_hal_chan_event_t usb_dwc_hal_chan_decode_intr(usb_dwc_hal_chan_t *chan_obj); +#endif // SOC_USB_OTG_SUPPORTED + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/usb_dwc_ll.h b/components/hal/include/hal/usb_dwc_ll.h index 3bbaeca4c2..5f5d5b0b8d 100644 --- a/components/hal/include/hal/usb_dwc_ll.h +++ b/components/hal/include/hal/usb_dwc_ll.h @@ -1,21 +1,37 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - +#include "soc/soc_caps.h" +/* +This header is shared across all targets. Resolve to an empty header for targets +that don't support USB OTG. +*/ +#if SOC_USB_OTG_SUPPORTED #include #include #include "soc/usb_dwc_struct.h" -#include "hal/usb_types_private.h" +#include "soc/usb_dwc_cfg.h" +#include "hal/usb_dwc_types.h" #include "hal/misc.h" +#endif // SOC_USB_OTG_SUPPORTED + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_USB_OTG_SUPPORTED +/* ----------------------------------------------------------------------------- +--------------------------------- DWC Constants -------------------------------- +----------------------------------------------------------------------------- */ + +#define USB_DWC_QTD_LIST_MEM_ALIGN 512 +#define USB_DWC_FRAME_LIST_MEM_ALIGN 512 // The frame list needs to be 512 bytes aligned (contrary to the databook) /* ----------------------------------------------------------------------------- ------------------------------- Global Registers ------------------------------- @@ -418,7 +434,7 @@ static inline void usb_dwc_ll_hcfg_set_fsls_pclk_sel(usb_dwc_dev_t *hw) * @param hw Start address of the DWC_OTG registers * @param speed Speed to initialize the host port at */ -static inline void usb_dwc_ll_hcfg_set_defaults(usb_dwc_dev_t *hw, usb_priv_speed_t speed) +static inline void usb_dwc_ll_hcfg_set_defaults(usb_dwc_dev_t *hw, usb_dwc_speed_t speed) { hw->hcfg_reg.descdma = 1; //Enable scatt/gatt hw->hcfg_reg.fslssupp = 1; //FS/LS support only @@ -427,13 +443,13 @@ static inline void usb_dwc_ll_hcfg_set_defaults(usb_dwc_dev_t *hw, usb_priv_spee Note: It seems like our PHY has an implicit 8 divider applied when in LS mode, so the values of FSLSPclkSel and FrInt have to be adjusted accordingly. */ - hw->hcfg_reg.fslspclksel = (speed == USB_PRIV_SPEED_FULL) ? 1 : 2; //PHY clock on esp32-sx for FS/LS-only + hw->hcfg_reg.fslspclksel = (speed == USB_DWC_SPEED_FULL) ? 1 : 2; //PHY clock on esp32-sx for FS/LS-only hw->hcfg_reg.perschedena = 0; //Disable perio sched } // ----------------------------- HFIR Register --------------------------------- -static inline void usb_dwc_ll_hfir_set_defaults(usb_dwc_dev_t *hw, usb_priv_speed_t speed) +static inline void usb_dwc_ll_hfir_set_defaults(usb_dwc_dev_t *hw, usb_dwc_speed_t speed) { usb_dwc_hfir_reg_t hfir; hfir.val = hw->hfir_reg.val; @@ -443,7 +459,7 @@ static inline void usb_dwc_ll_hfir_set_defaults(usb_dwc_dev_t *hw, usb_priv_spee Note: It seems like our PHY has an implicit 8 divider applied when in LS mode, so the values of FSLSPclkSel and FrInt have to be adjusted accordingly. */ - hfir.frint = (speed == USB_PRIV_SPEED_FULL) ? 48000 : 6000; //esp32-sx targets only support FS or LS + hfir.frint = (speed == USB_DWC_SPEED_FULL) ? 48000 : 6000; //esp32-sx targets only support FS or LS hw->hfir_reg.val = hfir.val; } @@ -526,19 +542,9 @@ static inline uint32_t usb_dwc_ll_hflbaddr_get_base_addr(usb_dwc_dev_t *hw) // ----------------------------- HPRT Register --------------------------------- -static inline usb_priv_speed_t usb_dwc_ll_hprt_get_speed(usb_dwc_dev_t *hw) +static inline usb_dwc_speed_t usb_dwc_ll_hprt_get_speed(usb_dwc_dev_t *hw) { - usb_priv_speed_t speed; - //esp32-s2 and esp32-s3 only support FS or LS - switch (hw->hprt_reg.prtspd) { - case 1: - speed = USB_PRIV_SPEED_FULL; - break; - default: - speed = USB_PRIV_SPEED_LOW; - break; - } - return speed; + return (usb_dwc_speed_t)hw->hprt_reg.prtspd; } static inline uint32_t usb_dwc_ll_hprt_get_test_ctl(usb_dwc_dev_t *hw) @@ -697,24 +703,9 @@ static inline void usb_dwc_ll_hcchar_set_dev_addr(volatile usb_dwc_host_chan_reg chan->hcchar_reg.devaddr = addr; } -static inline void usb_dwc_ll_hcchar_set_ep_type(volatile usb_dwc_host_chan_regs_t *chan, usb_priv_xfer_type_t type) +static inline void usb_dwc_ll_hcchar_set_ep_type(volatile usb_dwc_host_chan_regs_t *chan, usb_dwc_xfer_type_t type) { - uint32_t ep_type; - switch (type) { - case USB_PRIV_XFER_TYPE_CTRL: - ep_type = 0; - break; - case USB_PRIV_XFER_TYPE_ISOCHRONOUS: - ep_type = 1; - break; - case USB_PRIV_XFER_TYPE_BULK: - ep_type = 2; - break; - default: //USB_PRIV_XFER_TYPE_INTR - ep_type = 3; - break; - } - chan->hcchar_reg.eptype = ep_type; + chan->hcchar_reg.eptype = (uint32_t)type; } //Indicates whether channel is commuunicating with a LS device connected via a FS hub. Setting this bit to 1 will cause @@ -739,7 +730,7 @@ static inline void usb_dwc_ll_hcchar_set_mps(volatile usb_dwc_host_chan_regs_t * chan->hcchar_reg.mps = mps; } -static inline void usb_dwc_ll_hcchar_init(volatile usb_dwc_host_chan_regs_t *chan, int dev_addr, int ep_num, int mps, usb_priv_xfer_type_t type, bool is_in, bool is_ls) +static inline void usb_dwc_ll_hcchar_init(volatile usb_dwc_host_chan_regs_t *chan, int dev_addr, int ep_num, int mps, usb_dwc_xfer_type_t type, bool is_in, bool is_ls) { //Sets all persistent fields of the channel over its lifetimez usb_dwc_ll_hcchar_set_dev_addr(chan, dev_addr); @@ -789,28 +780,82 @@ static inline uint32_t usb_dwc_ll_hctsiz_get_pid(volatile usb_dwc_host_chan_regs static inline void usb_dwc_ll_hctsiz_set_qtd_list_len(volatile usb_dwc_host_chan_regs_t *chan, int qtd_list_len) { - HAL_FORCE_MODIFY_U32_REG_FIELD(chan->hctsiz_reg, ntd, qtd_list_len - 1); //Set the length of the descriptor list + usb_dwc_hctsiz_reg_t hctsiz; + hctsiz.val = chan->hctsiz_reg.val; + //Set the length of the descriptor list. NTD occupies xfersize[15:8] + hctsiz.xfersize &= ~(0xFF << 8); + hctsiz.xfersize |= ((qtd_list_len - 1) & 0xFF) << 8; + chan->hctsiz_reg.val = hctsiz.val; } static inline void usb_dwc_ll_hctsiz_init(volatile usb_dwc_host_chan_regs_t *chan) { - chan->hctsiz_reg.dopng = 0; //Don't do ping - HAL_FORCE_MODIFY_U32_REG_FIELD(chan->hctsiz_reg, sched_info, 0xFF); //Schedinfo is always 0xFF for fullspeed. Not used in Bulk/Ctrl channels + usb_dwc_hctsiz_reg_t hctsiz; + hctsiz.val = chan->hctsiz_reg.val; + hctsiz.dopng = 0; //Don't do ping + /* + Set SCHED_INFO which occupies xfersize[7:0] + It is always set to 0xFF for full speed and not used in Bulk/Ctrl channels + */ + hctsiz.xfersize |= 0xFF; + chan->hctsiz_reg.val = hctsiz.val; +} + +static inline void usb_dwc_ll_hctsiz_set_sched_info(volatile usb_dwc_host_chan_regs_t *chan, int tokens_per_frame, int offset) +{ + // @see USB-OTG databook: Table 5-47 + // This function is relevant only for HS + usb_dwc_hctsiz_reg_t hctsiz; + hctsiz.val = chan->hctsiz_reg.val; + uint8_t sched_info_val; + switch (tokens_per_frame) { + case 1: + offset %= 8; // If the required offset > 8, we must wrap around to SCHED_INFO size = 8 + sched_info_val = 0b00000001; + break; + case 2: + offset %= 4; + sched_info_val = 0b00010001; + break; + case 4: + offset %= 2; + sched_info_val = 0b01010101; + break; + case 8: + offset = 0; + sched_info_val = 0b11111111; + break; + default: + abort(); + break; + } + sched_info_val <<= offset; + hctsiz.xfersize &= ~(0xFF); + hctsiz.xfersize |= sched_info_val; + chan->hctsiz_reg.val = hctsiz.val; } // ---------------------------- HCDMAi Register -------------------------------- static inline void usb_dwc_ll_hcdma_set_qtd_list_addr(volatile usb_dwc_host_chan_regs_t *chan, void *dmaaddr, uint32_t qtd_idx) { - //Set HCDMAi - chan->hcdma_reg.val = 0; - chan->hcdma_reg.non_iso.dmaaddr = (((uint32_t)dmaaddr) >> 9) & 0x7FFFFF; //MSB of 512 byte aligned address - chan->hcdma_reg.non_iso.ctd = qtd_idx; + usb_dwc_hcdma_reg_t hcdma; + /* + Set the base address portion of the field which is dmaaddr[31:9]. This is + the based address of the QTD list and must be 512 bytes aligned + */ + hcdma.dmaaddr = ((uint32_t)dmaaddr) & 0xFFFFFE00; + //Set the current QTD index in the QTD list which is dmaaddr[8:3] + hcdma.dmaaddr |= (qtd_idx & 0x3F) << 3; + //dmaaddr[2:0] is reserved thus doesn't not need to be set + + chan->hcdma_reg.val = hcdma.val; } static inline int usb_dwc_ll_hcdam_get_cur_qtd_idx(usb_dwc_host_chan_regs_t *chan) { - return chan->hcdma_reg.non_iso.ctd; + //The current QTD index is dmaaddr[8:3] + return (chan->hcdma_reg.dmaaddr >> 3) & 0x3F; } // ---------------------------- HCDMABi Register ------------------------------- @@ -930,6 +975,8 @@ static inline void usb_dwc_ll_qtd_get_status(usb_dwc_ll_dma_qtd_t *qtd, int *rem qtd->buffer_status_val = 0; } +#endif // SOC_USB_OTG_SUPPORTED + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/usb_dwc_types.h b/components/hal/include/hal/usb_dwc_types.h new file mode 100644 index 0000000000..22018953bc --- /dev/null +++ b/components/hal/include/hal/usb_dwc_types.h @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* +Note: This header file contains USB2.0 related types and macros that can be used by code specific to the DWC_OTG +controller (i.e., the HW specific layers of the USB host stack). Thus, this header is only meant to be used below (and +including) the HAL layer. For types and macros that are HW implementation agnostic (i.e., HCD layer and above), add them +to the "usb/usb_types_ch9.h" header instead. +*/ + +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief USB speeds supported by the DWC OTG controller + * + * @note usb_dwc_speed_t enum values must match the values of the DWC_OTG prtspd register field + */ +typedef enum { + USB_DWC_SPEED_HIGH = 0, + USB_DWC_SPEED_FULL = 1, + USB_DWC_SPEED_LOW = 2, +} usb_dwc_speed_t; + +/** + * @brief USB transfer types supported by the DWC OTG controller + * + * @note usb_dwc_xfer_type_t enum values must match the values of the DWC_OTG hcchar register field + */ +typedef enum { + USB_DWC_XFER_TYPE_CTRL = 0, + USB_DWC_XFER_TYPE_ISOCHRONOUS = 1, + USB_DWC_XFER_TYPE_BULK = 2, + USB_DWC_XFER_TYPE_INTR = 3, +} usb_dwc_xfer_type_t; + +/** + * @brief Enumeration of different possible lengths of the periodic frame list + */ +typedef enum { + USB_HAL_FRAME_LIST_LEN_8 = 8, + USB_HAL_FRAME_LIST_LEN_16 = 16, + USB_HAL_FRAME_LIST_LEN_32 = 32, + USB_HAL_FRAME_LIST_LEN_64 = 64, +} usb_hal_frame_list_len_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/usb_hal.h b/components/hal/include/hal/usb_hal.h deleted file mode 100644 index b79740932f..0000000000 --- a/components/hal/include/hal/usb_hal.h +++ /dev/null @@ -1,31 +0,0 @@ -// 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. - - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - bool use_external_phy; -} usb_hal_context_t; - -void usb_hal_init(usb_hal_context_t *usb); - - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/include/hal/usb_phy_hal.h b/components/hal/include/hal/usb_phy_hal.h deleted file mode 100644 index fe77eb8744..0000000000 --- a/components/hal/include/hal/usb_phy_hal.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include "usb_types_private.h" -#include "usb_phy_types.h" -#include "soc/soc_caps.h" -#include "soc/usb_wrap_struct.h" -#if SOC_USB_SERIAL_JTAG_SUPPORTED -#include "soc/usb_serial_jtag_struct.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Context that should be maintained by both the driver and the HAL - */ -typedef struct { - usb_wrap_dev_t *wrap_dev; /**< Pointer to base address of USB Wrapper registers */ -#if SOC_USB_SERIAL_JTAG_SUPPORTED - usb_serial_jtag_dev_t *jtag_dev; /**< Pointer to base address of USB Serial JTAG registers */ -#endif -} usb_phy_hal_context_t; - -/** - * @brief Init the USB PHY hal. This function should be called first before other hal layer function is called - * - * @param hal Context of the HAL layer - */ -void usb_phy_hal_init(usb_phy_hal_context_t *hal); - -/** - * @brief Configure internal/external PHY for USB_OTG - * - * @param hal Context of the HAL layer - * @param phy_target USB PHY target - */ -void usb_phy_hal_otg_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_target); - -#if SOC_USB_SERIAL_JTAG_SUPPORTED -/** - * @brief Configure internal/external PHY for USB_Serial_JTAG - * - * @param hal Context of the HAL layer - * @param phy_target USB PHY target - */ -void usb_phy_hal_jtag_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_target); -#endif - -/** - * @brief Configure pullup/pulldown loads for the D+/D- as a host - * - * @param hal Context of the HAL layer - */ -void usb_phy_hal_int_load_conf_host(usb_phy_hal_context_t *hal); - -/** - * @brief Configure pullup/pulldown loads for the D+/D- as a device - * - * @param hal Context of the HAL layer - * @param speed USB speed - */ -void usb_phy_hal_int_load_conf_dev(usb_phy_hal_context_t *hal, usb_priv_speed_t speed); - -/** - * @brief Enable/Disable test mode for internal PHY to mimick host-device disconnection - * - * @param hal Context of the HAL layer - * @param disconn Whether to disconnect - */ -void usb_phy_hal_int_mimick_disconn(usb_phy_hal_context_t *hal, bool disconn); - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/include/hal/usb_phy_types.h b/components/hal/include/hal/usb_phy_types.h index 1f5ac431ef..50636a64dd 100644 --- a/components/hal/include/hal/usb_phy_types.h +++ b/components/hal/include/hal/usb_phy_types.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 */ @@ -55,6 +55,7 @@ typedef enum { USB_PHY_SPEED_UNDEFINED, USB_PHY_SPEED_LOW, /**< USB Low Speed (1.5 Mbit/s) */ USB_PHY_SPEED_FULL, /**< USB Full Speed (12 Mbit/s) */ + USB_PHY_SPEED_HIGH, /**< USB High Speed (480 Mbit/s) */ USB_PHY_SPEED_MAX, } usb_phy_speed_t; diff --git a/components/hal/include/hal/usb_serial_jtag_hal.h b/components/hal/include/hal/usb_serial_jtag_hal.h new file mode 100644 index 0000000000..410ed66355 --- /dev/null +++ b/components/hal/include/hal/usb_serial_jtag_hal.h @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/soc_caps.h" +#if SOC_USB_SERIAL_JTAG_SUPPORTED +#include "hal/usb_serial_jtag_ll.h" +#endif +#include "hal/usb_serial_jtag_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_USB_SERIAL_JTAG_SUPPORTED + +/** + * @brief HAL context type of USJ driver + */ +typedef struct { + usb_serial_jtag_dev_t *dev; +} usb_serial_jtag_hal_context_t; + +/** + * @brief Initialize the USJ HAL driver + * + * @param hal USJ HAL context + */ +void usb_serial_jtag_hal_init(usb_serial_jtag_hal_context_t *hal); + +/* ---------------------------- USB PHY Control ---------------------------- */ + +#if USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED +/** + * @brief Configure whether USJ is routed to internal/external FSLS PHY + * + * @param hal USJ HAL context + * @param external True if external, False if internal + */ +void usb_serial_jtag_hal_phy_set_external(usb_serial_jtag_hal_context_t *hal, bool external); +#endif // USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED + +#endif // SOC_USB_SERIAL_JTAG_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/usb_types_private.h b/components/hal/include/hal/usb_types_private.h deleted file mode 100644 index 5cce6b66af..0000000000 --- a/components/hal/include/hal/usb_types_private.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2015-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. - -/* -Note: This header file contains USB2.0 related types and macros that can be used by code specific to the DWC_OTG -controller (i.e., the HW specific layers of the USB host stack). Thus, this header is only meant to be used below (and -including) the HAL layer. For types and macros that are HW implementation agnostic (i.e., HCD layer and above), add them -to the "usb/usb_types_ch9.h" header instead. -*/ - -#pragma once - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @brief USB speeds supported by the DWC OTG controller - */ -typedef enum { - USB_PRIV_SPEED_FULL, - USB_PRIV_SPEED_LOW, -} usb_priv_speed_t; - -/** - * @brief USB transfer types supported by the DWC OTG controller - */ -typedef enum { - USB_PRIV_XFER_TYPE_CTRL, - USB_PRIV_XFER_TYPE_ISOCHRONOUS, - USB_PRIV_XFER_TYPE_BULK, - USB_PRIV_XFER_TYPE_INTR, -} usb_priv_xfer_type_t; - -/** - * @brief Enumeration of different possible lengths of the periodic frame list - */ -typedef enum { - USB_HAL_FRAME_LIST_LEN_8 = 8, - USB_HAL_FRAME_LIST_LEN_16 = 16, - USB_HAL_FRAME_LIST_LEN_32 = 32, - USB_HAL_FRAME_LIST_LEN_64 = 64, -} usb_hal_frame_list_len_t; - -/** - * @brief Support intervals in number of USB frames (i.e., 1ms) - */ -typedef enum { - USB_HAL_INTERVAL_1 = 1, - USB_HAL_INTERVAL_2 = 2, - USB_HAL_INTERVAL_4 = 4, - USB_HAL_INTERVAL_8 = 8, - USB_HAL_INTERVAL_16 = 16, - USB_HAL_INTERVAL_32 = 32, - USB_HAL_INTERVAL_64 = 64, -} usb_hal_interval_t; - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/include/hal/usb_wrap_hal.h b/components/hal/include/hal/usb_wrap_hal.h new file mode 100644 index 0000000000..ceb69f3652 --- /dev/null +++ b/components/hal/include/hal/usb_wrap_hal.h @@ -0,0 +1,96 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" +#if SOC_USB_OTG_SUPPORTED +#include "soc/usb_wrap_struct.h" +#include "hal/usb_wrap_ll.h" +#endif +#include "hal/usb_wrap_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_USB_OTG_SUPPORTED + +/** + * @brief HAL context type of USB WRAP driver + */ +typedef struct { + usb_wrap_dev_t *dev; +} usb_wrap_hal_context_t; + +/** + * @brief Initialize the USB WRAP HAL driver + * + * @param hal USB WRAP HAL context + */ +void usb_wrap_hal_init(usb_wrap_hal_context_t *hal); + +/* ---------------------------- USB PHY Control ---------------------------- */ + +#if USB_WRAP_LL_EXT_PHY_SUPPORTED +/** + * @brief Configure whether USB WRAP is routed to internal/external FSLS PHY + * + * @param hal USB WRAP HAL context + * @param external True if external, False if internal + */ +void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external); +#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED + +/** + * @brief Enables and sets override of pull up/down resistors + * + * @param hal USB WRAP HAL context + * @param vals Override values + */ +static inline void usb_wrap_hal_phy_enable_pull_override(usb_wrap_hal_context_t *hal, const usb_wrap_pull_override_vals_t *vals) +{ + usb_wrap_ll_phy_enable_pull_override(hal->dev, vals); +} + +/** + * @brief Disables pull up/down resistor override + * + * @param hal USB WRAP HAL context + */ +static inline void usb_wrap_hal_phy_disable_pull_override(usb_wrap_hal_context_t *hal) +{ + usb_wrap_ll_phy_disable_pull_override(hal->dev); +} + +/** + * @brief Enables/disables the USB FSLS PHY's test mode + * + * @param hal USB WRAP HAL context + * @param enable Whether to enable test mode + */ +static inline void usb_wrap_hal_phy_enable_test_mode(usb_wrap_hal_context_t *hal, bool enable) +{ + usb_wrap_ll_phy_enable_test_mode(hal->dev, enable); +} + +/** + * @brief Set the USB FSLS PHY's signal test values + * + * @param hal USB WRAP HAL context + * @param vals Test values + */ +static inline void usb_wrap_hal_phy_test_mode_set_signals(usb_wrap_hal_context_t *hal, const usb_wrap_test_mode_vals_t *vals) +{ + usb_wrap_ll_phy_test_mode_set_signals(hal->dev, vals); +} + +#endif // SOC_USB_OTG_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/usb_wrap_types.h b/components/hal/include/hal/usb_wrap_types.h new file mode 100644 index 0000000000..9d3310fb06 --- /dev/null +++ b/components/hal/include/hal/usb_wrap_types.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_USB_OTG_SUPPORTED + +/** + * @brief USB WRAP pull up/down resistor override values + * + * Specifies whether each pull up/down resistor should be enabled/disabled when + * overriding connected USB PHY's pull resistors. + */ +typedef struct { + bool dp_pu; /**< D+ pull-up resistor enable/disable */ + bool dm_pu; /**< D- pull-up resistor enable/disable */ + bool dp_pd; /**< D+ pull-down resistor enable/disable */ + bool dm_pd; /**< D- pull-down resistor enable/disable */ +} usb_wrap_pull_override_vals_t; + +/** + * @brief USB WRAP test mode values + * + * Specifies the logic values of each of the USB FSLS Serial PHY interface + * signals when in test mode. + * + * @note See section "2.2.1.13 FsLsSerialMode" of UTMI+ specification for more + * details of each signal. + */ +typedef struct { + bool tx_enable_n; /**< Active low output enable signal */ + bool tx_dp; /**< Single-ended D+ line driver */ + bool tx_dm; /**< Single-ended D- line driver */ + bool rx_dp; /**< Single-ended D+ signal from the transceiver */ + bool rx_dm; /**< Single-ended D- signal from the transceiver */ + bool rx_rcv; /**< Differential receive data from D+ and D- lines */ +} usb_wrap_test_mode_vals_t; + +#endif // SOC_USB_OTG_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/linker.lf b/components/hal/linker.lf index 6c9a303f13..3287d444a0 100644 --- a/components/hal/linker.lf +++ b/components/hal/linker.lf @@ -5,8 +5,10 @@ entries: mmu_hal (noflash) spi_flash_hal_iram (noflash) spi_flash_encrypt_hal_iram (noflash) - if IDF_TARGET_ESP32 = n && APP_BUILD_TYPE_PURE_RAM_APP = n: - cache_hal (noflash) + if IDF_TARGET_ESP32 = y: + cache_hal_esp32 (noflash) + else: + cache_hal (noflash) if SOC_GPSPI_SUPPORTED = y: if HAL_SPI_MASTER_FUNC_IN_IRAM = y: spi_hal_iram (noflash) @@ -28,29 +30,9 @@ entries: twai_hal_iram (noflash) if IDF_TARGET_ESP32 = n: spi_flash_hal_gpspi (noflash) - if GPTIMER_CTRL_FUNC_IN_IRAM = y: - timer_hal_iram (noflash) if GPIO_CTRL_FUNC_IN_IRAM = y: gpio_hal: gpio_hal_intr_disable (noflash) if LCD_RGB_ISR_IRAM_SAFE = y: lcd_hal: lcd_hal_cal_pclk_freq (noflash) - if ADC_ONESHOT_CTRL_FUNC_IN_IRAM = y: - adc_oneshot_hal (noflash) - if COMPILER_OPTIMIZATION_DEFAULT = y: - adc_hal_common: get_controller (noflash) - adc_hal_common: adc_hal_set_controller (noflash) - if SOC_ADC_ARBITER_SUPPORTED = y: - adc_hal_common: adc_hal_arbiter_config (noflash) - if SOC_ADC_CALIBRATION_V1_SUPPORTED = y: - adc_hal_common: adc_hal_set_calibration_param (noflash) - adc_hal_common: adc_hal_calibration_init (noflash) - if ADC_CONTINUOUS_ISR_IRAM_SAFE = y: - adc_hal: adc_hal_get_reading_result (noflash) - adc_hal: adc_hal_digi_start (noflash) - if COMPILER_OPTIMIZATION_DEFAULT = y: - adc_hal: adc_hal_digi_dma_link_descriptors (noflash) - adc_hal: adc_hal_digi_stop (noflash) - if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y: - adc_hal: adc_hal_check_event (noflash) - adc_hal: adc_hal_digi_clr_intr (noflash) - adc_hal: adc_hal_get_desc_addr (noflash) + if SOC_PMU_SUPPORTED = y: + pmu_hal (noflash) diff --git a/components/hal/parlio_hal.c b/components/hal/parlio_hal.c index d443008829..af8b9bb7c6 100644 --- a/components/hal/parlio_hal.c +++ b/components/hal/parlio_hal.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include "hal/parlio_hal.h" #include "hal/parlio_ll.h" diff --git a/components/hal/platform_port/include/hal/misc.h b/components/hal/platform_port/include/hal/misc.h index ab32fe455d..dbe00ac4e9 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 */ @@ -68,11 +68,7 @@ * @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 @@ -84,8 +80,4 @@ __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);})) diff --git a/components/hal/rmt_hal.c b/components/hal/rmt_hal.c index c14c8501cc..7fac79078b 100644 --- a/components/hal/rmt_hal.c +++ b/components/hal/rmt_hal.c @@ -10,7 +10,7 @@ void rmt_hal_init(rmt_hal_context_t *hal) { hal->regs = &RMT; - rmt_ll_power_down_mem(hal->regs, false); // turn on RMTMEM power domain + rmt_ll_mem_power_by_pmu(hal->regs); rmt_ll_enable_mem_access_nonfifo(hal->regs, true); // APB access the RMTMEM in nonfifo mode rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interupt events rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events @@ -24,7 +24,7 @@ void rmt_hal_deinit(rmt_hal_context_t *hal) { rmt_ll_enable_interrupt(hal->regs, UINT32_MAX, false); // disable all interupt events rmt_ll_clear_interrupt_status(hal->regs, UINT32_MAX); // clear all pending events - rmt_ll_power_down_mem(hal->regs, true); // turn off RMTMEM power domain + rmt_ll_mem_force_power_off(hal->regs); // power off RMTMEM power domain forcefully rmt_ll_enable_group_clock(hal->regs, false); // disable clock source hal->regs = NULL; } diff --git a/components/hal/rtc_io_hal.c b/components/hal/rtc_io_hal.c index ef59c9ac25..586a3c8f51 100644 --- a/components/hal/rtc_io_hal.c +++ b/components/hal/rtc_io_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 */ @@ -49,15 +49,6 @@ void rtcio_hal_set_direction(int rtcio_num, rtc_gpio_mode_t mode) } } -void rtcio_hal_isolate(int rtcio_num) -{ - rtcio_ll_pullup_disable(rtcio_num); - rtcio_ll_pulldown_disable(rtcio_num); - rtcio_ll_output_disable(rtcio_num); - rtcio_ll_input_disable(rtcio_num); - rtcio_ll_force_hold_enable(rtcio_num); -} - void rtcio_hal_set_direction_in_sleep(int rtcio_num, rtc_gpio_mode_t mode) { switch (mode) { @@ -86,4 +77,15 @@ void rtcio_hal_set_direction_in_sleep(int rtcio_num, rtc_gpio_mode_t mode) } } +#if SOC_RTCIO_HOLD_SUPPORTED +void rtcio_hal_isolate(int rtcio_num) +{ + rtcio_ll_pullup_disable(rtcio_num); + rtcio_ll_pulldown_disable(rtcio_num); + rtcio_ll_output_disable(rtcio_num); + rtcio_ll_input_disable(rtcio_num); + rtcio_ll_force_hold_enable(rtcio_num); +} #endif + +#endif //SOC_RTCIO_INPUT_OUTPUT_SUPPORTED diff --git a/components/hal/spi_hal.c b/components/hal/spi_hal.c index 159b6ec599..3c983dabc0 100644 --- a/components/hal/spi_hal.c +++ b/components/hal/spi_hal.c @@ -56,8 +56,14 @@ void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id, const spi_hal_config hal->rx_dma_chan = config->rx_dma_chan; hal->dmadesc_n = config->dmadesc_n; +#if SPI_LL_MOSI_FREE_LEVEL + // Change default data line level to low which same as esp32 + 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 @@ -66,6 +72,7 @@ void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id, const spi_hal_config spi_ll_enable_int(hw); spi_ll_set_int_stat(hw); spi_ll_set_mosi_delay(hw, 0, 0); + spi_ll_apply_config(hw); } void spi_hal_deinit(spi_hal_context_t *hal) diff --git a/components/hal/spi_hal_iram.c b/components/hal/spi_hal_iram.c index 8a9e38f122..b10ffcdc75 100644 --- a/components/hal/spi_hal_iram.c +++ b/components/hal/spi_hal_iram.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 */ @@ -186,7 +186,8 @@ void spi_hal_prepare_data(spi_hal_context_t *hal, const spi_hal_dev_config_t *de void spi_hal_user_start(const spi_hal_context_t *hal) { - spi_ll_master_user_start(hal->hw); + spi_ll_apply_config(hal->hw); + spi_ll_user_start(hal->hw); } bool spi_hal_usr_is_done(const spi_hal_context_t *hal) diff --git a/components/hal/spi_slave_hal.c b/components/hal/spi_slave_hal.c index 04982f1a7e..8ac605affd 100644 --- a/components/hal/spi_slave_hal.c +++ b/components/hal/spi_slave_hal.c @@ -31,7 +31,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_hal_iram.c b/components/hal/spi_slave_hal_iram.c index 56288e134f..505de92723 100644 --- a/components/hal/spi_slave_hal_iram.c +++ b/components/hal/spi_slave_hal_iram.c @@ -27,7 +27,7 @@ bool spi_slave_hal_usr_is_done(spi_slave_hal_context_t* hal) void spi_slave_hal_user_start(const spi_slave_hal_context_t *hal) { spi_ll_clear_int_stat(hal->hw); //clear int bit - spi_ll_slave_user_start(hal->hw); + spi_ll_user_start(hal->hw); } void spi_slave_hal_prepare_data(const spi_slave_hal_context_t *hal) diff --git a/components/hal/spi_slave_hd_hal.c b/components/hal/spi_slave_hd_hal.c index 306cf8c072..11b380dfd7 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); diff --git a/components/hal/test_apps/ecc/main/test_ecc.c b/components/hal/test_apps/ecc/main/test_ecc.c index a42ca80fe4..9b8997b107 100644 --- a/components/hal/test_apps/ecc/main/test_ecc.c +++ b/components/hal/test_apps/ecc/main/test_ecc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -12,6 +12,7 @@ #include "test_params.h" #include "soc/soc_caps.h" #include "hal/ecc_hal.h" +#include "hal/ecc_ll.h" #include "hal/clk_gate_ll.h" #include "unity.h" @@ -43,6 +44,7 @@ static void ecc_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t len static void ecc_enable_and_reset(void) { periph_ll_enable_clk_clear_rst(PERIPH_ECC_MODULE); + ecc_ll_power_up(); } #if SOC_ECC_SUPPORT_POINT_MULT diff --git a/components/hal/timer_hal.c b/components/hal/timer_hal.c index ae4e55467d..39f466bca9 100644 --- a/components/hal/timer_hal.c +++ b/components/hal/timer_hal.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 */ @@ -38,3 +38,25 @@ void timer_hal_deinit(timer_hal_context_t *hal) #endif hal->dev = NULL; } + +void timer_hal_set_counter_value(timer_hal_context_t *hal, uint64_t load_val) +{ + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // - `timer_ll_set_reload_value()` will only indicate the `reload_value` + // - `timer_ll_set_reload_value()` + ``timer_ll_trigger_soft_reload()` can update the HW counter value by software + // Therefore, after updating the HW counter value, we need to restore the previous `reload_value`. + // Attention: The following process should be protected by a lock in the driver layer. + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // save current reload value + uint64_t old_reload = timer_ll_get_reload_value(hal->dev, hal->timer_id); + timer_ll_set_reload_value(hal->dev, hal->timer_id, load_val); + timer_ll_trigger_soft_reload(hal->dev, hal->timer_id); + // restore the previous reload value + timer_ll_set_reload_value(hal->dev, hal->timer_id, old_reload); +} + +uint64_t timer_hal_capture_and_get_counter_value(timer_hal_context_t *hal) +{ + timer_ll_trigger_soft_capture(hal->dev, hal->timer_id); + return timer_ll_get_counter_value(hal->dev, hal->timer_id); +} diff --git a/components/hal/timer_hal_iram.c b/components/hal/timer_hal_iram.c deleted file mode 100644 index 43bac81e72..0000000000 --- a/components/hal/timer_hal_iram.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "hal/timer_hal.h" -#include "hal/timer_ll.h" - -void timer_hal_set_counter_value(timer_hal_context_t *hal, uint64_t load_val) -{ - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - `timer_ll_set_reload_value()` will only indicate the `reload_value` - // - `timer_ll_set_reload_value()` + ``timer_ll_trigger_soft_reload()` can update the HW counter value by software - // Therefore, after updating the HW counter value, we need to restore the previous `reload_value`. - // Attention: The following process should be protected by a lock in the driver layer. - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // save current reload value - uint64_t old_reload = timer_ll_get_reload_value(hal->dev, hal->timer_id); - timer_ll_set_reload_value(hal->dev, hal->timer_id, load_val); - timer_ll_trigger_soft_reload(hal->dev, hal->timer_id); - // restore the previous reload value - timer_ll_set_reload_value(hal->dev, hal->timer_id, old_reload); -} - -uint64_t timer_hal_capture_and_get_counter_value(timer_hal_context_t *hal) -{ - timer_ll_trigger_soft_capture(hal->dev, hal->timer_id); - return timer_ll_get_counter_value(hal->dev, hal->timer_id); -} diff --git a/components/hal/usb_dwc_hal.c b/components/hal/usb_dwc_hal.c index 8e26371275..9088112203 100644 --- a/components/hal/usb_dwc_hal.c +++ b/components/hal/usb_dwc_hal.c @@ -1,15 +1,18 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include -#include +#include // For memset() +#include // For abort() #include "sdkconfig.h" +#include "soc/chip_revision.h" #include "hal/usb_dwc_hal.h" #include "hal/usb_dwc_ll.h" +#include "hal/efuse_hal.h" #include "hal/assert.h" // ------------------------------------------------ Macros and Types --------------------------------------------------- @@ -19,11 +22,7 @@ #define BENDPOINTADDRESS_NUM_MSK 0x0F //Endpoint number mask of the bEndpointAddress field of an endpoint descriptor #define BENDPOINTADDRESS_DIR_MSK 0x80 //Endpoint direction mask of the bEndpointAddress field of an endpoint descriptor -#define CORE_REG_GSNPSID 0x4F54400A -#define CORE_REG_GHWCFG1 0x00000000 -#define CORE_REG_GHWCFG2 0x224DD930 -#define CORE_REG_GHWCFG3 0x00C804B5 -#define CORE_REG_GHWCFG4 0xD3F0A030 +#define CORE_REG_GSNPSID 0x4F54400A //Release number of USB_DWC used in Espressif's SoCs // -------------------- Configurable ----------------------- @@ -86,11 +85,27 @@ static void set_defaults(usb_dwc_hal_context_t *hal) { //GAHBCFG register usb_dwc_ll_gahbcfg_en_dma_mode(hal->dev); -#ifdef CONFIG_IDF_TARGET_ESP32S2 - usb_dwc_ll_gahbcfg_set_hbstlen(hal->dev, 1); //Use INCR AHB burst. See the ESP32-S2 and later chip ERRATA. -#elif CONFIG_IDF_TARGET_ESP32S3 - usb_dwc_ll_gahbcfg_set_hbstlen(hal->dev, 0); //Do not use USB burst INCR mode for the ESP32-S3, to avoid interference with other peripherals. -#endif + int hbstlen = 0; //Use AHB burst SINGLE by default +#if CONFIG_IDF_TARGET_ESP32S2 && CONFIG_ESP32S2_REV_MIN_FULL < 100 + /* + Hardware errata workaround for the ESP32-S2 ECO0 (see ESP32-S2 Errata Document section 4.0 for full details). + + ESP32-S2 ECO0 has a hardware errata where the AHB bus arbiter may generate incorrect arbitration signals leading to + the DWC_OTG corrupting the DMA transfers of other peripherals (or vice versa) on the same bus. The peripherals that + share the same bus with DWC_OTG include I2C and SPI (see ESP32-S2 Errata Document for more details). To workaround + this, the DWC_OTG's AHB should use INCR mode to prevent change of arbitration during a burst operation, thus + avoiding this errata. + + Note: Setting AHB burst to INCR increases the likeliness of DMA underruns on other peripherals sharing the same bus + arbiter as the DWC_OTG (e.g., I2C and SPI) as change of arbitration during the burst operation is not permitted. + Users should keep this limitation in mind when the DWC_OTG transfers large data payloads (e.g., 512 MPS transfers) + while this workaround is enabled. + */ + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100)) { + hbstlen = 1; //Set AHB burst to INCR to workaround hardware errata + } +#endif //CONFIG_IDF_TARGET_ESP32S2 && CONFIG_ESP32S2_REV_MIN_FULL < 100 + usb_dwc_ll_gahbcfg_set_hbstlen(hal->dev, hbstlen); //Set AHB burst mode //GUSBCFG register usb_dwc_ll_gusbcfg_dis_hnp_cap(hal->dev); //Disable HNP usb_dwc_ll_gusbcfg_dis_srp_cap(hal->dev); //Disable SRP @@ -141,29 +156,83 @@ void usb_dwc_hal_core_soft_reset(usb_dwc_hal_context_t *hal) hal->flags.val = 0; hal->channels.num_allocd = 0; hal->channels.chan_pend_intrs_msk = 0; - memset(hal->channels.hdls, 0, sizeof(usb_dwc_hal_chan_t *) * USB_DWC_HAL_NUM_CHAN); + memset(hal->channels.hdls, 0, sizeof(usb_dwc_hal_chan_t *) * OTG_NUM_HOST_CHAN); } -void usb_dwc_hal_set_fifo_size(usb_dwc_hal_context_t *hal, const usb_dwc_hal_fifo_config_t *fifo_config) +void usb_dwc_hal_set_fifo_bias(usb_dwc_hal_context_t *hal, const usb_hal_fifo_bias_t fifo_bias) { - HAL_ASSERT((fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines + fifo_config->ptx_fifo_lines) <= USB_DWC_HAL_FIFO_TOTAL_USABLE_LINES); + /* + * EPINFO_CTL is located at the end of FIFO, its size is fixed in HW. + * The reserved size is always the worst-case, which is device mode that requires 4 locations per EP direction (including EP0). + * Here we just read the FIFO size from HW register, to avoid any ambivalence + */ + uint32_t ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4; + usb_dwc_ll_ghwcfg_get_hw_config(hal->dev, &ghwcfg1, &ghwcfg2, &ghwcfg3, &ghwcfg4); + const uint16_t fifo_size_lines = ((usb_dwc_ghwcfg3_reg_t)ghwcfg3).dfifodepth; + + /* + * Recommended FIFO sizes (see 2.1.2.4 for programming guide) + * + * RXFIFO: ((LPS/4) * 2) + 2 + * NPTXFIFO: (LPS/4) * 2 + * PTXFIFO: (LPS/4) * 2 + * + * Recommended sizes fit 2 packets of each type. For S2 and S3 we can't fit even one MPS ISOC packet (1023 FS and 1024 HS). + * So the calculations below are compromises between the available FIFO size and optimal performance. + */ + usb_dwc_hal_fifo_config_t fifo_config; + switch (fifo_bias) { + // Define minimum viable (fits at least 1 MPS) FIFO sizes for non-biased FIFO types + // Allocate the remaining size to the biased FIFO type + case USB_HAL_FIFO_BIAS_DEFAULT: + fifo_config.nptx_fifo_lines = OTG_DFIFO_DEPTH / 4; + fifo_config.ptx_fifo_lines = OTG_DFIFO_DEPTH / 8; + fifo_config.rx_fifo_lines = fifo_size_lines - fifo_config.ptx_fifo_lines - fifo_config.nptx_fifo_lines; + break; + case USB_HAL_FIFO_BIAS_RX: + fifo_config.nptx_fifo_lines = OTG_DFIFO_DEPTH / 16; + fifo_config.ptx_fifo_lines = OTG_DFIFO_DEPTH / 8; + fifo_config.rx_fifo_lines = fifo_size_lines - fifo_config.ptx_fifo_lines - fifo_config.nptx_fifo_lines; + break; + case USB_HAL_FIFO_BIAS_PTX: + fifo_config.rx_fifo_lines = OTG_DFIFO_DEPTH / 8 + 2; // 2 extra lines are allocated for status information. See USB-OTG Programming Guide, chapter 2.1.2.1 + fifo_config.nptx_fifo_lines = OTG_DFIFO_DEPTH / 16; + fifo_config.ptx_fifo_lines = fifo_size_lines - fifo_config.nptx_fifo_lines - fifo_config.rx_fifo_lines; + break; + default: + abort(); + } + + HAL_ASSERT((fifo_config.rx_fifo_lines + fifo_config.nptx_fifo_lines + fifo_config.ptx_fifo_lines) <= fifo_size_lines); //Check that none of the channels are active - for (int i = 0; i < USB_DWC_HAL_NUM_CHAN; i++) { + for (int i = 0; i < OTG_NUM_HOST_CHAN; i++) { if (hal->channels.hdls[i] != NULL) { HAL_ASSERT(!hal->channels.hdls[i]->flags.active); } } //Set the new FIFO lengths - usb_dwc_ll_grxfsiz_set_fifo_size(hal->dev, fifo_config->rx_fifo_lines); - usb_dwc_ll_gnptxfsiz_set_fifo_size(hal->dev, fifo_config->rx_fifo_lines, fifo_config->nptx_fifo_lines); - usb_dwc_ll_hptxfsiz_set_ptx_fifo_size(hal->dev, fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines, fifo_config->ptx_fifo_lines); + usb_dwc_ll_grxfsiz_set_fifo_size(hal->dev, fifo_config.rx_fifo_lines); + usb_dwc_ll_gnptxfsiz_set_fifo_size(hal->dev, fifo_config.rx_fifo_lines, fifo_config.nptx_fifo_lines); + usb_dwc_ll_hptxfsiz_set_ptx_fifo_size(hal->dev, fifo_config.rx_fifo_lines + fifo_config.nptx_fifo_lines, fifo_config.ptx_fifo_lines); //Flush the FIFOs usb_dwc_ll_grstctl_flush_nptx_fifo(hal->dev); usb_dwc_ll_grstctl_flush_ptx_fifo(hal->dev); usb_dwc_ll_grstctl_flush_rx_fifo(hal->dev); + hal->fifo_config = fifo_config; // Implicit struct copy hal->flags.fifo_sizes_set = 1; } +void usb_dwc_hal_get_mps_limits(usb_dwc_hal_context_t *hal, usb_hal_fifo_mps_limits_t *mps_limits) +{ + HAL_ASSERT(hal && mps_limits); + HAL_ASSERT(hal->flags.fifo_sizes_set); + + const usb_dwc_hal_fifo_config_t *fifo_config = &(hal->fifo_config); + mps_limits->in_mps = (fifo_config->rx_fifo_lines - 2) * 4; // Two lines are reserved for status quadlets internally by USB_DWC + mps_limits->non_periodic_out_mps = fifo_config->nptx_fifo_lines * 4; + mps_limits->periodic_out_mps = fifo_config->ptx_fifo_lines * 4; +} + // ---------------------------------------------------- Host Port ------------------------------------------------------ static inline void debounce_lock_enable(usb_dwc_hal_context_t *hal) @@ -175,7 +244,7 @@ static inline void debounce_lock_enable(usb_dwc_hal_context_t *hal) void usb_dwc_hal_port_enable(usb_dwc_hal_context_t *hal) { - usb_priv_speed_t speed = usb_dwc_ll_hprt_get_speed(hal->dev); + usb_dwc_speed_t speed = usb_dwc_ll_hprt_get_speed(hal->dev); //Host Configuration usb_dwc_ll_hcfg_set_defaults(hal->dev, speed); //Configure HFIR @@ -190,11 +259,11 @@ bool usb_dwc_hal_chan_alloc(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan { HAL_ASSERT(hal->flags.fifo_sizes_set); //FIFO sizes should be set befor attempting to allocate a channel //Attempt to allocate channel - if (hal->channels.num_allocd == USB_DWC_HAL_NUM_CHAN) { + if (hal->channels.num_allocd == OTG_NUM_HOST_CHAN) { return false; //Out of free channels } int chan_idx = -1; - for (int i = 0; i < USB_DWC_HAL_NUM_CHAN; i++) { + for (int i = 0; i < OTG_NUM_HOST_CHAN; i++) { if (hal->channels.hdls[i] == NULL) { hal->channels.hdls[i] = chan_obj; chan_idx = i; @@ -220,7 +289,7 @@ bool usb_dwc_hal_chan_alloc(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan void usb_dwc_hal_chan_free(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan_obj) { - if (chan_obj->type == USB_PRIV_XFER_TYPE_INTR || chan_obj->type == USB_PRIV_XFER_TYPE_ISOCHRONOUS) { + if (chan_obj->type == USB_DWC_XFER_TYPE_INTR || chan_obj->type == USB_DWC_XFER_TYPE_ISOCHRONOUS) { //Unschedule this channel for (int i = 0; i < hal->frame_list_len; i++) { hal->periodic_frame_list[i] &= ~(1 << chan_obj->flags.chan_idx); @@ -253,13 +322,49 @@ void usb_dwc_hal_chan_set_ep_char(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t //Save channel type chan_obj->type = ep_char->type; //If this is a periodic endpoint/channel, set its schedule in the frame list - if (ep_char->type == USB_PRIV_XFER_TYPE_ISOCHRONOUS || ep_char->type == USB_PRIV_XFER_TYPE_INTR) { - HAL_ASSERT((int)ep_char->periodic.interval <= (int)hal->frame_list_len); //Interval cannot exceed the length of the frame list - //Find the effective offset in the frame list (in case the phase_offset_frames > interval) - int offset = ep_char->periodic.phase_offset_frames % ep_char->periodic.interval; - //Schedule the channel in the frame list - for (int i = offset; i < hal->frame_list_len; i+= ep_char->periodic.interval) { - hal->periodic_frame_list[i] |= 1 << chan_obj->flags.chan_idx; + if (ep_char->type == USB_DWC_XFER_TYPE_ISOCHRONOUS || ep_char->type == USB_DWC_XFER_TYPE_INTR) { + unsigned int interval_frame_list = ep_char->periodic.interval; + unsigned int offset_frame_list = ep_char->periodic.offset; + // Periodic Frame List works with USB frames. For HS endpoints we must divide interval[microframes] by 8 to get interval[frames] + if (ep_char->periodic.is_hs) { + interval_frame_list /= 8; + offset_frame_list /= 8; + } + // Interval in Periodic Frame List must be power of 2. + // This is not a HW restriction. It is just a lot easier to schedule channels like this. + if (interval_frame_list >= (int)hal->frame_list_len) { // Upper limits is Periodic Frame List length + interval_frame_list = (int)hal->frame_list_len; + } else if (interval_frame_list >= 32) { + interval_frame_list = 32; + } else if (interval_frame_list >= 16) { + interval_frame_list = 16; + } else if (interval_frame_list >= 8) { + interval_frame_list = 8; + } else if (interval_frame_list >= 4) { + interval_frame_list = 4; + } else if (interval_frame_list >= 2) { + interval_frame_list = 2; + } else { // Lower limit is 1 + interval_frame_list = 1; + } + // Schedule the channel in the frame list + for (int i = 0; i < hal->frame_list_len; i+= interval_frame_list) { + int index = (offset_frame_list + i) % hal->frame_list_len; + hal->periodic_frame_list[index] |= 1 << chan_obj->flags.chan_idx; + } + // For HS endpoints we must write to sched_info field of HCTSIZ register to schedule microframes + if (ep_char->periodic.is_hs) { + unsigned int tokens_per_frame; + if (ep_char->periodic.interval >= 8) { + tokens_per_frame = 1; // 1 token every 8 microframes + } else if (ep_char->periodic.interval >= 4) { + tokens_per_frame = 2; // 1 token every 4 microframes + } else if (ep_char->periodic.interval >= 2) { + tokens_per_frame = 4; // 1 token every 2 microframes + } else { + tokens_per_frame = 8; // 1 token every microframe + } + usb_dwc_ll_hctsiz_set_sched_info(chan_obj->regs, tokens_per_frame, ep_char->periodic.offset); } } } @@ -409,7 +514,7 @@ usb_dwc_hal_chan_event_t usb_dwc_hal_chan_decode_intr(usb_dwc_hal_chan_t *chan_o */ chan_event = USB_DWC_HAL_CHAN_EVENT_NONE; } else { - abort(); //Should never reach this point + abort(); } return chan_event; } diff --git a/components/hal/usb_hal.c b/components/hal/usb_hal.c deleted file mode 100644 index 359f50d68a..0000000000 --- a/components/hal/usb_hal.c +++ /dev/null @@ -1,26 +0,0 @@ -// 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. - - -#include "hal/usb_ll.h" -#include "hal/usb_hal.h" - -void usb_hal_init(usb_hal_context_t *usb) -{ - if (usb->use_external_phy) { - usb_ll_ext_phy_enable(); - } else { - usb_ll_int_phy_enable(); - } -} diff --git a/components/hal/usb_phy_hal.c b/components/hal/usb_phy_hal.c deleted file mode 100644 index 16a8f60d81..0000000000 --- a/components/hal/usb_phy_hal.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "hal/usb_phy_ll.h" -#include "hal/usb_phy_hal.h" - -void usb_phy_hal_init(usb_phy_hal_context_t *hal) -{ - hal->wrap_dev = &USB_WRAP; -#if SOC_USB_SERIAL_JTAG_SUPPORTED - hal->jtag_dev = &USB_SERIAL_JTAG; -#endif -} - -void usb_phy_hal_otg_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_target) -{ - if (phy_target == USB_PHY_TARGET_EXT) { - usb_phy_ll_ext_otg_enable(hal->wrap_dev); - } else if (phy_target == USB_PHY_TARGET_INT) { - usb_phy_ll_int_otg_enable(hal->wrap_dev); - } -} - -#if SOC_USB_SERIAL_JTAG_SUPPORTED -void usb_phy_hal_jtag_conf(usb_phy_hal_context_t *hal, usb_phy_target_t phy_target) -{ - if (phy_target == USB_PHY_TARGET_EXT) { - usb_phy_ll_ext_jtag_enable(hal->jtag_dev); - } else if (phy_target == USB_PHY_TARGET_INT) { - usb_phy_ll_int_jtag_enable(hal->jtag_dev); - } -} -#endif - -void usb_phy_hal_int_load_conf_host(usb_phy_hal_context_t *hal) -{ - // HOST - upstream: dp_pd = 1, dm_pd = 1 - usb_phy_ll_int_load_conf(hal->wrap_dev, false, true, false, true); -} - -void usb_phy_hal_int_load_conf_dev(usb_phy_hal_context_t *hal, usb_priv_speed_t speed) -{ - // DEVICE - downstream - if (speed == USB_PRIV_SPEED_LOW) { - // LS: dm_pu = 1 - usb_phy_ll_int_load_conf(hal->wrap_dev, false, false, true, false); - } else { - // FS: dp_pu = 1 - usb_phy_ll_int_load_conf(hal->wrap_dev, true, false, false, false); - } -} - -void usb_phy_hal_int_mimick_disconn(usb_phy_hal_context_t *hal, bool disconn) -{ - /* - We mimick a disconnect by enabling the internal PHY's test mode, then forcing the output_enable to HIGH. This will: - A HIGH output_enable will cause the received VP and VM to be zero, thus mimicking a disconnection. - */ - usb_phy_ll_int_enable_test_mode(hal->wrap_dev, disconn); -} diff --git a/components/hal/usb_serial_jtag_hal.c b/components/hal/usb_serial_jtag_hal.c new file mode 100644 index 0000000000..094ff81763 --- /dev/null +++ b/components/hal/usb_serial_jtag_hal.c @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/usb_serial_jtag_ll.h" +#include "hal/usb_serial_jtag_hal.h" + +void usb_serial_jtag_hal_init(usb_serial_jtag_hal_context_t *hal) +{ + hal->dev = &USB_SERIAL_JTAG; +#if !USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED + usb_serial_jtag_ll_phy_set_defaults(); +#endif +} + +#if USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED +void usb_serial_jtag_hal_phy_set_external(usb_serial_jtag_hal_context_t *hal, bool external) +{ + if (external) { + usb_serial_jtag_ll_phy_enable_external(true); + } else { + usb_serial_jtag_ll_phy_enable_external(false); + usb_serial_jtag_ll_phy_enable_pad(true); + } +} +#endif // USB_SERIAL_JTAG_LL_EXT_PHY_SUPPORTED diff --git a/components/hal/usb_wrap_hal.c b/components/hal/usb_wrap_hal.c new file mode 100644 index 0000000000..52d6933bce --- /dev/null +++ b/components/hal/usb_wrap_hal.c @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc_caps.h" +#include "hal/usb_wrap_ll.h" +#include "hal/usb_wrap_hal.h" + +void usb_wrap_hal_init(usb_wrap_hal_context_t *hal) +{ + hal->dev = &USB_WRAP; +#if !USB_WRAP_LL_EXT_PHY_SUPPORTED + usb_wrap_ll_phy_set_defaults(hal->dev); +#endif +} + +#if USB_WRAP_LL_EXT_PHY_SUPPORTED +void usb_wrap_hal_phy_set_external(usb_wrap_hal_context_t *hal, bool external) +{ + if (external) { + usb_wrap_ll_phy_enable_external(hal->dev, true); + } else { + usb_wrap_ll_phy_enable_external(hal->dev, false); + usb_wrap_ll_phy_enable_pad(hal->dev, true); + } +} +#endif // USB_WRAP_LL_EXT_PHY_SUPPORTED diff --git a/components/log/host_test/log_test/main/log_test.cpp b/components/log/host_test/log_test/main/log_test.cpp index a4befc9a24..cf4a77fb6c 100644 --- a/components/log/host_test/log_test/main/log_test.cpp +++ b/components/log/host_test/log_test/main/log_test.cpp @@ -205,6 +205,31 @@ TEST_CASE("log buffer") CHECK(regex_search(fix.get_print_buffer_string(), buffer_regex)); } +TEST_CASE("log bytes > 127") +{ + PrintFixture fix(ESP_LOG_INFO); + const uint8_t buffer[] = { + 0xff, 0x80, + }; + ESP_LOG_BUFFER_HEX(TEST_TAG, buffer, sizeof(buffer)); + const std::regex buffer_regex("I \\([0-9]*\\) test: ff 80", std::regex::ECMAScript); + CHECK(regex_search(fix.get_print_buffer_string(), buffer_regex)); +} + +TEST_CASE("log buffer dump") +{ + PrintFixture fix(ESP_LOG_INFO); + const uint8_t buffer[] = { + 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x08, + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8 + }; + ESP_LOG_BUFFER_HEXDUMP(TEST_TAG, buffer, sizeof(buffer), ESP_LOG_INFO); + const std::regex buffer_regex("I \\([0-9]*\\) test: 0x[0-9a-f]+\\s+" + "00 00 00 00 05 06 07 08 ff fe fd fc fb fa f9 f8 " + "\\s+|[\\.]{16}|", std::regex::ECMAScript); + CHECK(regex_search(fix.get_print_buffer_string(), buffer_regex)); +} + TEST_CASE("rom printf") { PutcFixture fix; diff --git a/components/log/log.c b/components/log/log.c index 72497f7599..e0eb03df63 100644 --- a/components/log/log.c +++ b/components/log/log.c @@ -21,11 +21,6 @@ * After that, bubble-down operation is performed to fix ordering in the * min-heap. * - * The potential problem with wrap-around of cache generation counter is - * ignored for now. This will happen if someone happens to output more - * than 4 billion log entries, at which point wrap-around will not be - * the biggest problem. - * */ #include @@ -49,11 +44,12 @@ // Number of tags to be cached. Must be 2**n - 1, n >= 2. #define TAG_CACHE_SIZE 31 +#define MAX_GENERATION ((1 << 29) - 1) typedef struct { const char *tag; uint32_t level : 3; - uint32_t generation : 29; + uint32_t generation : 29; // this size should be the same in MAX_GENERATION } cached_tag_entry_t; typedef struct uncached_tag_entry_ { @@ -81,6 +77,7 @@ static void heap_bubble_down(int index); static inline void heap_swap(int i, int j); static inline bool should_output(esp_log_level_t level_for_message, esp_log_level_t level_for_tag); static inline void clear_log_level_list(void); +static void fix_cache_generation_overflow(void); vprintf_like_t esp_log_set_vprintf(vprintf_like_t func) { @@ -238,6 +235,10 @@ static inline bool get_cached_log_level(const char *tag, esp_log_level_t *level) s_log_cache[i].generation = s_log_cache_max_generation++; // Restore heap ordering heap_bubble_down(i); + // Check for generation count wrap and fix if necessary + if (s_log_cache_max_generation == MAX_GENERATION) { + fix_cache_generation_overflow(); + } } return true; } @@ -255,18 +256,30 @@ static inline void add_to_cache(const char *tag, esp_log_level_t level) .tag = tag }; ++s_log_cache_entry_count; - return; + } else { + // Cache is full, so we replace the oldest entry (which is at index 0 + // because this is a min-heap) with the new one, and do bubble-down + // operation to restore min-heap ordering. + s_log_cache[0] = (cached_tag_entry_t) { + .tag = tag, + .level = level, + .generation = generation + }; + heap_bubble_down(0); } + // Check for generation count wrap and fix if necessary + if (s_log_cache_max_generation == MAX_GENERATION) { + fix_cache_generation_overflow(); + } +} - // Cache is full, so we replace the oldest entry (which is at index 0 - // because this is a min-heap) with the new one, and do bubble-down - // operation to restore min-heap ordering. - s_log_cache[0] = (cached_tag_entry_t) { - .tag = tag, - .level = level, - .generation = generation - }; - heap_bubble_down(0); +static void fix_cache_generation_overflow(void) +{ + // Fix generation count wrap + for (uint32_t i = 0; i < s_log_cache_entry_count; ++i) { + s_log_cache[i].generation = i; + } + s_log_cache_max_generation = s_log_cache_entry_count; } static inline bool get_uncached_log_level(const char *tag, esp_log_level_t *level) diff --git a/components/log/log_buffers.c b/components/log/log_buffers.c index 2fcef1b2b6..87db8f549c 100644 --- a/components/log/log_buffers.c +++ b/components/log/log_buffers.c @@ -48,7 +48,7 @@ void esp_log_buffer_hex_internal(const char *tag, const void *buffer, uint16_t b } for (int i = 0; i < bytes_cur_line; i ++) { - sprintf(hex_buffer + 3 * i, "%02x ", ptr_line[i]); + sprintf(hex_buffer + 3 * i, "%02x ", (unsigned char) ptr_line[i]); } ESP_LOG_LEVEL(log_level, tag, "%s", hex_buffer); buffer += bytes_cur_line; @@ -100,7 +100,7 @@ void esp_log_buffer_hexdump_internal(const char *tag, const void *buffer, uint16 const char *ptr_line; //format: field[length] // ADDR[10]+" "+DATA_HEX[8*3]+" "+DATA_HEX[8*3]+" |"+DATA_CHAR[8]+"|" - char hd_buffer[10 + 3 + BYTES_PER_LINE * 3 + 3 + BYTES_PER_LINE + 1 + 1]; + char hd_buffer[2 + sizeof(void *) * 2 + 3 + BYTES_PER_LINE * 3 + 1 + 3 + BYTES_PER_LINE + 1 + 1]; char *ptr_hd; int bytes_cur_line; @@ -125,7 +125,7 @@ void esp_log_buffer_hexdump_internal(const char *tag, const void *buffer, uint16 ptr_hd += sprintf(ptr_hd, " "); } if (i < bytes_cur_line) { - ptr_hd += sprintf(ptr_hd, " %02x", ptr_line[i]); + ptr_hd += sprintf(ptr_hd, " %02x", (unsigned char) ptr_line[i]); } else { ptr_hd += sprintf(ptr_hd, " "); } diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 692d9d6d21..9cb83d4445 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -110,9 +110,13 @@ list(REMOVE_ITEM src_x509 x509_crt.c) set_property(TARGET mbedx509 PROPERTY SOURCES ${src_x509}) endif() +# Core libraries from the mbedTLS project set(mbedtls_targets mbedtls mbedcrypto mbedx509) +# 3rd party libraries from the mbedTLS project +list(APPEND mbedtls_targets everest p256m) -set(mbedtls_target_sources "${COMPONENT_DIR}/port/mbedtls_debug.c") +set(mbedtls_target_sources "${COMPONENT_DIR}/port/mbedtls_debug.c" + "${COMPONENT_DIR}/port/esp_platform_time.c") if(CONFIG_MBEDTLS_DYNAMIC_BUFFER) set(mbedtls_target_sources ${mbedtls_target_sources} @@ -232,7 +236,7 @@ if(CONFIG_MBEDTLS_HARDWARE_SHA) ) endif() -if(CONFIG_MBEDTLS_HARDWARE_GCM OR (NOT CONFIG_SOC_AES_SUPPORT_GCM AND CONFIG_MBEDTLS_HARDWARE_AES)) +if(CONFIG_MBEDTLS_HARDWARE_GCM OR CONFIG_MBEDTLS_HARDWARE_AES) target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_gcm.c") endif() @@ -246,6 +250,9 @@ if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY) if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN) target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign") + target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign_restartable") + target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_write_signature") + target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_write_signature_restartable") endif() if(CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY) @@ -257,6 +264,11 @@ if(CONFIG_MBEDTLS_ROM_MD5) target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/md/esp_md.c") endif() +if(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL) + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/mbedtls_rom/mbedtls_rom_osi.c") + target_link_libraries(${COMPONENT_LIB} PRIVATE "-u mbedtls_rom_osi_functions_init") +endif() + foreach(target ${mbedtls_targets}) target_compile_definitions(${target} PUBLIC -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h") endforeach() diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index b76e29a4d9..a50c6a1441 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -123,7 +123,7 @@ menu "mbedTLS" The option will decrease heap cost when handshake, but also lead to problem: - Becasue all certificate, private key and DHM data are freed so users should register + Because all certificate, private key and DHM data are freed so users should register certificate and private key to ssl config object again. config MBEDTLS_DYNAMIC_FREE_CA_CERT @@ -239,7 +239,6 @@ menu "mbedTLS" config MBEDTLS_SSL_KEEP_PEER_CERTIFICATE bool "Keep peer certificate after handshake completion" default y - depends on !MBEDTLS_DYNAMIC_FREE_PEER_CERT help Keep the peer's certificate after completion of the handshake. Disabling this option will save about 4kB of heap and some code size. @@ -253,6 +252,22 @@ menu "mbedTLS" help Enable PKCS #7 core for using PKCS #7-formatted signatures. + config MBEDTLS_SSL_CID_PADDING_GRANULARITY + int "Record plaintext padding" + default 16 + range 0 32 + depends on MBEDTLS_SSL_PROTO_TLS1_3 || MBEDTLS_SSL_DTLS_CONNECTION_ID + help + Controls the use of record plaintext padding in TLS 1.3 and + when using the Connection ID extension in DTLS 1.2. + + The padding will always be chosen so that the length of the + padded plaintext is a multiple of the value of this option. + + Notes: + A value of 1 means that no padding will be used for outgoing records. + On systems lacking division instructions, a power of two should be preferred. + menu "DTLS-based configurations" depends on MBEDTLS_SSL_PROTO_DTLS @@ -279,22 +294,6 @@ menu "mbedTLS" help Maximum length of CIDs used for outgoing DTLS messages - config MBEDTLS_SSL_CID_PADDING_GRANULARITY - int "Record plaintext padding (for DTLS 1.2)" - default 16 - range 0 32 - depends on MBEDTLS_SSL_DTLS_CONNECTION_ID - help - Controls the use of record plaintext padding when - using the Connection ID extension in DTLS 1.2. - - The padding will always be chosen so that the length of the - padded plaintext is a multiple of the value of this option. - - Notes: - A value of 1 means that no padding will be used for outgoing records. - On systems lacking division instructions, a power of two should be preferred. - config MBEDTLS_SSL_DTLS_SRTP bool "Enable support for negotiation of DTLS-SRTP (RFC 5764)" default n @@ -403,6 +402,29 @@ menu "mbedTLS" mbedTLS will still use the hardware accelerated AES block operation, but on a single block at a time. + config MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER + bool "Enable support for non-AES ciphers in GCM operation" + depends on MBEDTLS_HARDWARE_AES + default n + help + Enable this config to support fallback to software definitions for a non-AES + cipher GCM operation as we support hardware acceleration only for AES cipher. + Some of the non-AES ciphers used in a GCM operation are DES, ARIA, CAMELLIA, + CHACHA20, BLOWFISH. + + If this config is disabled, performing a non-AES cipher GCM operation with + the config MBEDTLS_HARDWARE_AES enabled will result in calculation of an + AES-GCM operation instead for the given input values and thus could lead + to failure in certificate validation which would ultimately lead to a SSL + handshake failure. + + This config being by-default enabled leads to an increase in binary size + footprint of ~2.5KB. + In case you are sure that your use case (for example, client and server + configurations in case of a TLS handshake) would not involve any GCM + operations using a non-AES cipher, you can safely disable this config, + leading to reduction in binary size footprint. + config MBEDTLS_HARDWARE_MPI bool "Enable hardware MPI (bignum) acceleration" default y @@ -415,6 +437,17 @@ menu "mbedTLS" These operations are used by RSA. + config MBEDTLS_LARGE_KEY_SOFTWARE_MPI + bool "Fallback to software implementation for larger MPI values" + depends on MBEDTLS_HARDWARE_MPI + default y if SOC_RSA_MAX_BIT_LEN <= 3072 # HW max 3072 bits + default n + help + Fallback to software implementation for RSA key lengths + larger than SOC_RSA_MAX_BIT_LEN. If this is not active + then the ESP will be unable to process keys greater + than SOC_RSA_MAX_BIT_LEN. + config MBEDTLS_MPI_USE_INTERRUPT bool "Use interrupt for MPI exp-mod operations" depends on !IDF_TARGET_ESP32 && MBEDTLS_HARDWARE_MPI @@ -844,13 +877,13 @@ menu "mbedTLS" bool "X.509 CRL parsing" default y help - Support for parsing X.509 Certifificate Revocation Lists. + Support for parsing X.509 Certificate Revocation Lists. config MBEDTLS_X509_CSR_PARSE_C bool "X.509 CSR parsing" default y help - Support for parsing X.509 Certifificate Signing Requests + Support for parsing X.509 Certificate Signing Requests endmenu # Certificates @@ -982,6 +1015,16 @@ menu "mbedTLS" Disabling this option saves some code size. + config MBEDTLS_ECP_FIXED_POINT_OPTIM + bool "Enable fixed-point multiplication optimisations" + depends on MBEDTLS_ECP_C + default y + help + This configuration option enables optimizations to speedup (about 3 ~ 4 times) the ECP + fixed point multiplication using pre-computed tables in the flash memory. + Disabling this configuration option saves flash footprint (about 29KB if all Elliptic Curve selected) + in the application binary. + # end of Elliptic Curve options config MBEDTLS_POLY1305_C @@ -1031,27 +1074,33 @@ menu "mbedTLS" help Enable the pthread wrapper layer for the threading layer. - config MBEDTLS_LARGE_KEY_SOFTWARE_MPI - bool "Fallback to software implementation for larger MPI values" - depends on MBEDTLS_HARDWARE_MPI - default y if SOC_RSA_MAX_BIT_LEN <= 3072 # HW max 3072 bits - default n - help - Fallback to software implementation for RSA key lengths - larger than SOC_RSA_MAX_BIT_LEN. If this is not active - then the ESP will be unable to process keys greater - than SOC_RSA_MAX_BIT_LEN. - - menuconfig MBEDTLS_SECURITY_RISKS - bool "Show configurations with potential security risks" - default n - - config MBEDTLS_ALLOW_UNSUPPORTED_CRITICAL_EXT - bool "X.509 CRT parsing with unsupported critical extensions" - depends on MBEDTLS_SECURITY_RISKS - default n + config MBEDTLS_ERROR_STRINGS + bool "Enable error code to error string conversion" + default y help - Allow the X.509 certificate parser to load certificates - with unsupported critical extensions + Enables mbedtls_strerror() for converting error codes to error strings. + Disabling this config can save some code/rodata size as the error + string conversion implementation is replaced with an empty stub. + + config MBEDTLS_USE_CRYPTO_ROM_IMPL + bool "Use ROM implementation of the crypto algorithm" + depends on ESP_ROM_HAS_MBEDTLS_CRYPTO_LIB && IDF_EXPERIMENTAL_FEATURES + default "n" + select MBEDTLS_SHA512_C + select MBEDTLS_AES_C + select MBEDTLS_CCM_C + select MBEDTLS_ROM_MD5 + select MBEDTLS_HARDWARE_SHA + help + Enable this flag to use mbedtls crypto algorithm from ROM instead of ESP-IDF. + + This configuration option saves flash footprint in the application binary. + Note that the version of mbedtls crypto algorithm library in ROM is v2.16.12. + We have done the security analysis of the mbedtls revision in ROM (v2.16.12) + and ensured that affected symbols have been patched (removed). If in the future + mbedtls revisions there are security issues that also affects the version in + ROM (v2.16.12) then we shall patch the relevant symbols. This would increase + the flash footprint and hence care must be taken to keep some reserved space + for the application binary in flash layout. endmenu # mbedTLS diff --git a/components/mbedtls/mbedtls b/components/mbedtls/mbedtls index 65b3c0857c..72aa687352 160000 --- a/components/mbedtls/mbedtls +++ b/components/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit 65b3c0857c9f207dcb0b646f2b4ebd8e5edf83c1 +Subproject commit 72aa687352a469044cbb946f3fdb261430e41ce1 diff --git a/components/mbedtls/port/aes/dma/esp_aes.c b/components/mbedtls/port/aes/dma/esp_aes.c index 2e3e61942a..1dd9401861 100644 --- a/components/mbedtls/port/aes/dma/esp_aes.c +++ b/components/mbedtls/port/aes/dma/esp_aes.c @@ -53,10 +53,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#if SOC_AES_SUPPORT_GCM -#include "aes/esp_aes_gcm.h" -#endif - #if SOC_AES_GDMA #define AES_LOCK() esp_crypto_sha_aes_lock_acquire() #define AES_RELEASE() esp_crypto_sha_aes_lock_release() @@ -177,23 +173,30 @@ static IRAM_ATTR void esp_aes_complete_isr(void *arg) } } -static esp_err_t esp_aes_isr_initialise( void ) +void esp_aes_intr_alloc(void) { - aes_hal_interrupt_clear(); - aes_hal_interrupt_enable(true); if (op_complete_sem == NULL) { - op_complete_sem = xSemaphoreCreateBinary(); - - if (op_complete_sem == NULL) { - ESP_LOGE(TAG, "Failed to create intr semaphore"); - return ESP_FAIL; - } esp_err_t ret = esp_intr_alloc(ETS_AES_INTR_SOURCE, 0, esp_aes_complete_isr, NULL, NULL); if (ret != ESP_OK) { - return ret; + ESP_LOGE(TAG, "Failed to allocate AES interrupt %d", ret); + // This should be treated as fatal error as this API would mostly + // be invoked within mbedTLS interface. There is no way for the system + // to proceed if the AES interrupt allocation fails here. + abort(); } + + static StaticSemaphore_t op_sem_buf; + op_complete_sem = xSemaphoreCreateBinaryStatic(&op_sem_buf); + // Static semaphore creation is unlikley to fail but still basic sanity + assert(op_complete_sem != NULL); } +} + +static esp_err_t esp_aes_isr_initialise( void ) +{ + aes_hal_interrupt_clear(); + aes_hal_interrupt_enable(true); /* AES is clocked proportionally to CPU clock, take power management lock */ #ifdef CONFIG_PM_ENABLE @@ -400,6 +403,10 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, //Limit max inlink descriptor length to be 16 byte aligned, require for EDMA lldesc_setup_link_constrained(block_out_desc, output, block_bytes, LLDESC_MAX_NUM_PER_DESC_16B_ALIGNED, 0); + /* Setup in/out start descriptors */ + lldesc_append(&in_desc_head, block_in_desc); + lldesc_append(&out_desc_head, block_out_desc); + out_desc_tail = &block_out_desc[lldesc_num - 1]; } @@ -417,25 +424,18 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, lldesc_setup_link(&s_stream_in_desc, s_stream_in, AES_BLOCK_BYTES, 0); lldesc_setup_link(&s_stream_out_desc, s_stream_out, AES_BLOCK_BYTES, 0); - if (block_bytes > 0) { - /* Link with block descriptors*/ - block_in_desc[lldesc_num - 1].empty = (uint32_t)&s_stream_in_desc; - block_out_desc[lldesc_num - 1].empty = (uint32_t)&s_stream_out_desc; - } + /* Link with block descriptors */ + lldesc_append(&in_desc_head, &s_stream_in_desc); + lldesc_append(&out_desc_head, &s_stream_out_desc); out_desc_tail = &s_stream_out_desc; } - // block buffers are sent to DMA first, unless there aren't any - in_desc_head = (block_bytes > 0) ? block_in_desc : &s_stream_in_desc; - out_desc_head = (block_bytes > 0) ? block_out_desc : &s_stream_out_desc; - - #if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT) /* Only use interrupt for long AES operations */ if (len > AES_DMA_INTR_TRIG_LEN) { use_intr = true; - if (esp_aes_isr_initialise() == ESP_FAIL) { + if (esp_aes_isr_initialise() != ESP_OK) { ESP_LOGE(TAG, "ESP-AES ISR initialisation failed"); ret = -1; goto cleanup; @@ -483,7 +483,7 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, } -#if SOC_AES_SUPPORT_GCM +#if CONFIG_MBEDTLS_HARDWARE_GCM /* Encrypt/decrypt with AES-GCM the input using DMA * The function esp_aes_process_dma_gcm zeroises the output buffer in the case of following conditions: @@ -495,6 +495,7 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, int esp_aes_process_dma_gcm(esp_aes_context *ctx, const unsigned char *input, unsigned char *output, size_t len, lldesc_t *aad_desc, size_t aad_len) { lldesc_t *in_desc_head = NULL, *out_desc_head = NULL, *len_desc = NULL; + lldesc_t *out_desc_tail = NULL; /* pointer to the final output descriptor */ lldesc_t stream_in_desc, stream_out_desc; lldesc_t *block_desc = NULL, *block_in_desc = NULL, *block_out_desc = NULL; size_t lldesc_num; @@ -544,6 +545,8 @@ int esp_aes_process_dma_gcm(esp_aes_context *ctx, const unsigned char *input, un lldesc_append(&in_desc_head, block_in_desc); lldesc_append(&out_desc_head, block_out_desc); + + out_desc_tail = &block_out_desc[lldesc_num - 1]; } /* Any leftover bytes which are appended as an additional DMA list */ @@ -555,6 +558,8 @@ int esp_aes_process_dma_gcm(esp_aes_context *ctx, const unsigned char *input, un lldesc_append(&in_desc_head, &stream_in_desc); lldesc_append(&out_desc_head, &stream_out_desc); + + out_desc_tail = &stream_out_desc; } @@ -573,7 +578,7 @@ int esp_aes_process_dma_gcm(esp_aes_context *ctx, const unsigned char *input, un /* Only use interrupt for long AES operations */ if (len > AES_DMA_INTR_TRIG_LEN) { use_intr = true; - if (esp_aes_isr_initialise() == ESP_FAIL) { + if (esp_aes_isr_initialise() != ESP_OK) { ESP_LOGE(TAG, "ESP-AES ISR initialisation failed"); ret = -1; goto cleanup; @@ -593,7 +598,7 @@ int esp_aes_process_dma_gcm(esp_aes_context *ctx, const unsigned char *input, un aes_hal_transform_dma_gcm_start(blocks); - if (esp_aes_dma_wait_complete(use_intr, out_desc_head) < 0) { + if (esp_aes_dma_wait_complete(use_intr, out_desc_tail) < 0) { ESP_LOGE(TAG, "esp_aes_dma_wait_complete failed"); ret = -1; goto cleanup; @@ -613,7 +618,7 @@ int esp_aes_process_dma_gcm(esp_aes_context *ctx, const unsigned char *input, un return ret; } -#endif //SOC_AES_SUPPORT_GCM +#endif //CONFIG_MBEDTLS_HARDWARE_GCM static int esp_aes_validate_input(esp_aes_context *ctx, const unsigned char *input, unsigned char *output ) diff --git a/components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h b/components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h index 7880f18806..d8ddac8d28 100644 --- a/components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.h +++ b/components/mbedtls/port/aes/dma/include/esp_aes_dma_priv.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 + */ #pragma once @@ -43,6 +35,11 @@ esp_err_t esp_aes_dma_start(const lldesc_t *input, const lldesc_t *output); */ bool esp_aes_dma_done(const lldesc_t *output); +/** + * @brief Allocate AES peripheral interrupt handler + */ +void esp_aes_intr_alloc(void); + #ifdef __cplusplus } #endif diff --git a/components/mbedtls/port/aes/esp_aes_common.c b/components/mbedtls/port/aes/esp_aes_common.c index 5af90a8003..578ec6656c 100644 --- a/components/mbedtls/port/aes/esp_aes_common.c +++ b/components/mbedtls/port/aes/esp_aes_common.c @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD */ /* * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. @@ -14,6 +14,7 @@ * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf */ +#include "sdkconfig.h" #include "aes/esp_aes_internal.h" #include "mbedtls/aes.h" #include "hal/aes_hal.h" @@ -24,7 +25,7 @@ #include #include "mbedtls/platform.h" -#if SOC_AES_GDMA +#if SOC_AES_SUPPORT_DMA #include "esp_aes_dma_priv.h" #endif @@ -39,10 +40,12 @@ bool valid_key_length(const esp_aes_context *ctx) return valid_len; } - -void esp_aes_init( esp_aes_context *ctx ) +void esp_aes_init(esp_aes_context *ctx) { - bzero( ctx, sizeof( esp_aes_context ) ); + bzero(ctx, sizeof(esp_aes_context)); +#if SOC_AES_SUPPORT_DMA && CONFIG_MBEDTLS_AES_USE_INTERRUPT + esp_aes_intr_alloc(); +#endif } void esp_aes_free( esp_aes_context *ctx ) diff --git a/components/mbedtls/port/aes/esp_aes_gcm.c b/components/mbedtls/port/aes/esp_aes_gcm.c index 80a3871146..9798fe475c 100644 --- a/components/mbedtls/port/aes/esp_aes_gcm.c +++ b/components/mbedtls/port/aes/esp_aes_gcm.c @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2016-2024 Espressif Systems (Shanghai) CO LTD */ /* * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. @@ -14,22 +14,27 @@ * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf */ -#include "soc/soc_caps.h" - +#include #include "aes/esp_aes.h" #include "aes/esp_aes_gcm.h" #include "aes/esp_aes_internal.h" #include "hal/aes_hal.h" -#include "esp_log.h" #include "mbedtls/aes.h" +#include "mbedtls/error.h" #include "mbedtls/gcm.h" + #include "esp_heap_caps.h" +#include "esp_log.h" +#include "soc/soc_caps.h" #include "soc/soc_memory_layout.h" -#include "mbedtls/error.h" -#include +#include "sdkconfig.h" + +#if SOC_AES_SUPPORT_DMA +#include "esp_aes_dma_priv.h" +#endif #define ESP_PUT_BE64(a, val) \ do { \ @@ -246,6 +251,27 @@ int esp_aes_gcm_setkey( esp_gcm_context *ctx, const unsigned char *key, unsigned int keybits ) { + /* Fallback to software implementation of GCM operation when a non-AES + * cipher is selected, as we support hardware acceleration only for a + * GCM operation using AES cipher. + */ +#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) + if (ctx->ctx_soft != NULL) { + mbedtls_gcm_free_soft(ctx->ctx_soft); + free(ctx->ctx_soft); + ctx->ctx_soft = NULL; + } + + if (cipher != MBEDTLS_CIPHER_ID_AES) { + ctx->ctx_soft = (mbedtls_gcm_context_soft*) malloc(sizeof(mbedtls_gcm_context_soft)); + if (ctx->ctx_soft == NULL) { + return MBEDTLS_ERR_CIPHER_ALLOC_FAILED; + } + mbedtls_gcm_init_soft(ctx->ctx_soft); + return mbedtls_gcm_setkey_soft(ctx->ctx_soft, cipher, key, keybits); + } +#endif + #if !SOC_AES_SUPPORT_AES_192 if (keybits == 192) { return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED; @@ -314,6 +340,10 @@ void esp_aes_gcm_init( esp_gcm_context *ctx) bzero(ctx, sizeof(esp_gcm_context)); +#if SOC_AES_SUPPORT_DMA && CONFIG_MBEDTLS_AES_USE_INTERRUPT + esp_aes_intr_alloc(); +#endif + ctx->gcm_state = ESP_AES_GCM_STATE_INIT; } @@ -323,6 +353,14 @@ void esp_aes_gcm_free( esp_gcm_context *ctx) if (ctx == NULL) { return; } +#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) + if (ctx->ctx_soft != NULL) { + mbedtls_gcm_free_soft(ctx->ctx_soft); + free(ctx->ctx_soft); + /* Note that the value of ctx->ctx_soft should be NULL'ed out + and here it is taken care by the bzero call below */ + } +#endif bzero(ctx, sizeof(esp_gcm_context)); } @@ -332,6 +370,17 @@ int esp_aes_gcm_starts( esp_gcm_context *ctx, const unsigned char *iv, size_t iv_len ) { + if (!ctx) { + ESP_LOGE(TAG, "No AES context supplied"); + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + +#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) + if (ctx->ctx_soft != NULL) { + return mbedtls_gcm_starts_soft(ctx->ctx_soft, mode, iv, iv_len); + } +#endif + /* IV is limited to 2^32 bits, so 2^29 bytes */ /* IV is not allowed to be zero length */ if ( iv_len == 0 || @@ -339,11 +388,6 @@ int esp_aes_gcm_starts( esp_gcm_context *ctx, return ( MBEDTLS_ERR_GCM_BAD_INPUT ); } - if (!ctx) { - ESP_LOGE(TAG, "No AES context supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; - } - if (!iv) { ESP_LOGE(TAG, "No IV supplied"); return MBEDTLS_ERR_GCM_BAD_INPUT; @@ -362,7 +406,7 @@ int esp_aes_gcm_starts( esp_gcm_context *ctx, /* H and the lookup table are only generated once per ctx */ if (ctx->gcm_state == ESP_AES_GCM_STATE_INIT) { /* Lock the AES engine to calculate ghash key H in hardware */ -#if SOC_AES_SUPPORT_GCM +#if CONFIG_MBEDTLS_HARDWARE_GCM esp_aes_acquire_hardware(); ctx->aes_ctx.key_in_hardware = aes_hal_setkey(ctx->aes_ctx.key, ctx->aes_ctx.key_bytes, mode); aes_hal_mode_init(ESP_AES_BLOCK_MODE_GCM); @@ -398,16 +442,22 @@ int esp_aes_gcm_update_ad( esp_gcm_context *ctx, const unsigned char *aad, size_t aad_len ) { - /* AD are limited to 2^32 bits, so 2^29 bytes */ - if ( ( (uint32_t) aad_len ) >> 29 != 0 ) { - return ( MBEDTLS_ERR_GCM_BAD_INPUT ); - } - if (!ctx) { ESP_LOGE(TAG, "No AES context supplied"); return MBEDTLS_ERR_GCM_BAD_INPUT; } +#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) + if (ctx->ctx_soft != NULL) { + return mbedtls_gcm_update_ad_soft(ctx->ctx_soft, aad, aad_len); + } +#endif + + /* AD are limited to 2^32 bits, so 2^29 bytes */ + if ( ( (uint32_t) aad_len ) >> 29 != 0 ) { + return ( MBEDTLS_ERR_GCM_BAD_INPUT ); + } + if ( (aad_len > 0) && !aad) { ESP_LOGE(TAG, "No aad supplied"); return MBEDTLS_ERR_GCM_BAD_INPUT; @@ -433,6 +483,17 @@ int esp_aes_gcm_update( esp_gcm_context *ctx, unsigned char *output, size_t output_size, size_t *output_length ) { + if (!ctx) { + ESP_LOGE(TAG, "No GCM context supplied"); + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + +#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) + if (ctx->ctx_soft != NULL) { + return mbedtls_gcm_update_soft(ctx->ctx_soft, input, input_length, output, output_size, output_length); + } +#endif + size_t nc_off = 0; uint8_t nonce_counter[AES_BLOCK_BYTES] = {0}; uint8_t stream[AES_BLOCK_BYTES] = {0}; @@ -443,10 +504,6 @@ int esp_aes_gcm_update( esp_gcm_context *ctx, } *output_length = input_length; - if (!ctx) { - ESP_LOGE(TAG, "No GCM context supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; - } if (!input) { ESP_LOGE(TAG, "No input supplied"); return MBEDTLS_ERR_GCM_BAD_INPUT; @@ -503,6 +560,11 @@ int esp_aes_gcm_finish( esp_gcm_context *ctx, size_t *output_length, unsigned char *tag, size_t tag_len ) { +#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) + if (ctx->ctx_soft != NULL) { + return mbedtls_gcm_finish_soft(ctx->ctx_soft, output, output_size, output_length, tag, tag_len); + } +#endif size_t nc_off = 0; uint8_t len_block[AES_BLOCK_BYTES] = {0}; uint8_t stream[AES_BLOCK_BYTES] = {0}; @@ -520,7 +582,7 @@ int esp_aes_gcm_finish( esp_gcm_context *ctx, return esp_aes_crypt_ctr(&ctx->aes_ctx, tag_len, &nc_off, ctx->ori_j0, stream, ctx->ghash, tag); } -#if SOC_AES_SUPPORT_GCM +#if CONFIG_MBEDTLS_HARDWARE_GCM /* Due to restrictions in the hardware (e.g. need to do the whole conversion in one go), some combinations of inputs are not supported */ static bool esp_aes_gcm_input_support_hw_accel(size_t length, const unsigned char *aad, size_t aad_len, @@ -598,7 +660,17 @@ int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx, size_t tag_len, unsigned char *tag ) { -#if SOC_AES_SUPPORT_GCM + if (!ctx) { + ESP_LOGE(TAG, "No AES context supplied"); + return MBEDTLS_ERR_GCM_BAD_INPUT; + } + +#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) + if (ctx->ctx_soft != NULL) { + return mbedtls_gcm_crypt_and_tag_soft(ctx->ctx_soft, mode, length, iv, iv_len, aad, aad_len, input, output, tag_len, tag); + } +#endif +#if CONFIG_MBEDTLS_HARDWARE_GCM int ret; lldesc_t aad_desc[2] = {}; lldesc_t *aad_head_desc = NULL; @@ -626,11 +698,6 @@ int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx, return ( MBEDTLS_ERR_GCM_BAD_INPUT ); } - if (!ctx) { - ESP_LOGE(TAG, "No AES context supplied"); - return MBEDTLS_ERR_GCM_BAD_INPUT; - } - if (!iv) { ESP_LOGE(TAG, "No IV supplied"); return MBEDTLS_ERR_GCM_BAD_INPUT; @@ -718,6 +785,11 @@ int esp_aes_gcm_auth_decrypt( esp_gcm_context *ctx, const unsigned char *input, unsigned char *output ) { +#if defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) + if (ctx->ctx_soft != NULL) { + return mbedtls_gcm_auth_decrypt_soft(ctx->ctx_soft, length, iv, iv_len, aad, aad_len, tag, tag_len, input, output); + } +#endif int ret; unsigned char check_tag[16]; size_t i; diff --git a/components/mbedtls/port/dynamic/esp_ssl_cli.c b/components/mbedtls/port/dynamic/esp_ssl_cli.c index 9fb224419c..0ea78df59d 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_cli.c +++ b/components/mbedtls/port/dynamic/esp_ssl_cli.c @@ -185,6 +185,11 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) case MBEDTLS_SSL_FLUSH_BUFFERS: break; case MBEDTLS_SSL_HANDSHAKE_WRAPUP: +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if (add && ssl->MBEDTLS_PRIVATE(renego_status)) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } +#endif break; default: break; diff --git a/components/mbedtls/port/dynamic/esp_ssl_tls.c b/components/mbedtls/port/dynamic/esp_ssl_tls.c index e242b2ced6..f12bc2bf7e 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_tls.c +++ b/components/mbedtls/port/dynamic/esp_ssl_tls.c @@ -283,6 +283,8 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl ) int __wrap_mbedtls_ssl_setup(mbedtls_ssl_context *ssl, const mbedtls_ssl_config *conf) { ssl->conf = conf; + ssl->tls_version = ssl->conf->max_tls_version; + CHECK_OK(ssl_handshake_init(ssl)); mbedtls_free(ssl->MBEDTLS_PRIVATE(out_buf)); diff --git a/components/mbedtls/port/ecc/ecc_alt.c b/components/mbedtls/port/ecc/ecc_alt.c index ad3c1d63e9..ef0b76fe05 100644 --- a/components/mbedtls/port/ecc/ecc_alt.c +++ b/components/mbedtls/port/ecc/ecc_alt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,11 +11,6 @@ #include "mbedtls/ecp.h" #include "mbedtls/platform_util.h" -#define ECP_VALIDATE_RET( cond ) \ - MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA ) -#define ECP_VALIDATE( cond ) \ - MBEDTLS_INTERNAL_VALIDATE( cond ) - #if defined(MBEDTLS_ECP_MUL_ALT) || defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) #define MAX_SIZE 32 // 256 bits @@ -94,8 +89,9 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, #endif } - ECP_VALIDATE_RET( grp != NULL ); - ECP_VALIDATE_RET( pt != NULL ); + if (grp == NULL || pt == NULL) { + return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + } /* Must use affine coordinates */ if( mbedtls_mpi_cmp_int( &pt->MBEDTLS_PRIVATE(Z), 1 ) != 0 ) diff --git a/components/mbedtls/port/ecc/esp_ecc.c b/components/mbedtls/port/ecc/esp_ecc.c index a9100b7e0d..ecd87a2567 100644 --- a/components/mbedtls/port/ecc/esp_ecc.c +++ b/components/mbedtls/port/ecc/esp_ecc.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 */ @@ -7,24 +7,26 @@ #include #include +#include "esp_crypto_lock.h" #include "esp_private/periph_ctrl.h" #include "ecc_impl.h" #include "hal/ecc_hal.h" - -static _lock_t s_crypto_ecc_lock; +#include "hal/ecc_ll.h" static void esp_ecc_acquire_hardware(void) { - _lock_acquire(&s_crypto_ecc_lock); + esp_crypto_ecc_lock_acquire(); periph_module_enable(PERIPH_ECC_MODULE); + ecc_ll_power_up(); } static void esp_ecc_release_hardware(void) { periph_module_disable(PERIPH_ECC_MODULE); + ecc_ll_power_down(); - _lock_release(&s_crypto_ecc_lock); + esp_crypto_ecc_lock_release(); } int esp_ecc_point_multiply(const ecc_point_t *point, const uint8_t *scalar, ecc_point_t *result, bool verify_first) diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index e098b5e9e3..25048afc82 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -1,37 +1,41 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include "hal/ecdsa_hal.h" +#include "esp_crypto_lock.h" #include "esp_efuse.h" #include "mbedtls/ecp.h" +#include "mbedtls/error.h" #include "mbedtls/ecdsa.h" +#include "mbedtls/asn1write.h" #include "mbedtls/platform_util.h" #include "esp_private/periph_ctrl.h" #include "ecdsa/ecdsa_alt.h" +#include "hal/ecc_ll.h" -#define ECDSA_KEY_MAGIC 0xECD5A +#define ECDSA_KEY_MAGIC (short) 0xECD5A #define ECDSA_SHA_LEN 32 #define MAX_ECDSA_COMPONENT_LEN 32 __attribute__((unused)) static const char *TAG = "ecdsa_alt"; -static _lock_t s_crypto_ecdsa_lock; - static void esp_ecdsa_acquire_hardware(void) { - _lock_acquire(&s_crypto_ecdsa_lock); + esp_crypto_ecdsa_lock_acquire(); periph_module_enable(PERIPH_ECDSA_MODULE); + ecc_ll_power_up(); } static void esp_ecdsa_release_hardware(void) { periph_module_disable(PERIPH_ECDSA_MODULE); + ecc_ll_power_down(); - _lock_release(&s_crypto_ecdsa_lock); + esp_crypto_ecdsa_lock_release(); } static void ecdsa_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t len) @@ -134,17 +138,23 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s esp_ecdsa_acquire_hardware(); + bool process_again = false; + do { ecdsa_hal_config_t conf = { .mode = ECDSA_MODE_SIGN_GEN, .curve = curve, - .k_mode = ECDSA_K_USE_TRNG, .sha_mode = ECDSA_Z_USER_PROVIDED, .efuse_key_blk = d->MBEDTLS_PRIVATE(n), }; - ecdsa_hal_gen_signature(&conf, NULL, sha_le, r_le, s_le, len); - } while (!memcmp(r_le, zeroes, len) || !memcmp(s_le, zeroes, len)); + ecdsa_hal_gen_signature(&conf, sha_le, r_le, s_le, len); + + process_again = !ecdsa_hal_get_operation_result() + || !memcmp(r_le, zeroes, len) + || !memcmp(s_le, zeroes, len); + + } while (process_again); esp_ecdsa_release_hardware(); @@ -179,6 +189,137 @@ int __wrap_mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mp return __real_mbedtls_ecdsa_sign(grp, r, s, d, buf, blen, f_rng, p_rng); } } + +extern int __real_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + int (*f_rng_blind)(void *, unsigned char *, size_t), void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +int __wrap_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + int (*f_rng_blind)(void *, unsigned char *, size_t), void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +int __wrap_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + int (*f_rng_blind)(void *, unsigned char *, size_t), void *p_rng_blind, + mbedtls_ecdsa_restart_ctx *rs_ctx) +{ + /* + * Check `d` whether it contains the hardware key + */ + if (d->MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) { + // Use hardware ECDSA peripheral + return esp_ecdsa_sign(grp, r, s, d, buf, blen); + } else { + return __real_mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, f_rng, p_rng, f_rng_blind, p_rng_blind, rs_ctx); + } +} + +int __real_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t sig_size, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t sig_size, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecdsa_restart_ctx *rs_ctx); + +/* + * Convert a signature (given by context) to ASN.1 + */ +static int ecdsa_signature_to_asn1(const mbedtls_mpi *r, const mbedtls_mpi *s, + unsigned char *sig, size_t sig_size, + size_t *slen) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = { 0 }; + // Setting the pointer p to the end of the buffer as the functions used afterwards write in backwards manner in the given buffer. + unsigned char *p = buf + sizeof(buf); + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, s)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_mpi(&p, buf, r)); + + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&p, buf, len)); + MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&p, buf, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE)); + + if (len > sig_size) { + return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + } + + memcpy(sig, p, len); + *slen = len; + + return 0; +} + +int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t sig_size, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + mbedtls_ecdsa_restart_ctx *rs_ctx) +{ + if (ctx->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) != ECDSA_KEY_MAGIC) { + return __real_mbedtls_ecdsa_write_signature_restartable(ctx, md_alg, hash, hlen, sig, sig_size, slen, f_rng, p_rng, rs_ctx); + } + + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + mbedtls_mpi r, s; + + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + + /* + * Check `d` whether it contains the hardware key + */ + if (ctx->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) { + // Use hardware ECDSA peripheral + + MBEDTLS_MPI_CHK(esp_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen)); + } + + MBEDTLS_MPI_CHK(ecdsa_signature_to_asn1(&r, &s, sig, sig_size, slen)); + +cleanup: + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + + return ret; +} + +int __wrap_mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t sig_size, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng); + +int __wrap_mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx, + mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t sig_size, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng) +{ + return __wrap_mbedtls_ecdsa_write_signature_restartable( + ctx, md_alg, hash, hlen, sig, sig_size, slen, + f_rng, p_rng, NULL); +} #endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN */ #ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY @@ -232,7 +373,6 @@ static int esp_ecdsa_verify(mbedtls_ecp_group *grp, ecdsa_hal_config_t conf = { .mode = ECDSA_MODE_SIGN_VERIFY, .curve = curve, - .k_mode = ECDSA_K_USE_TRNG, .sha_mode = ECDSA_Z_USER_PROVIDED, }; diff --git a/components/mbedtls/port/esp_bignum.c b/components/mbedtls/port/esp_bignum.c index cf86beaf7c..e9596bec8f 100644 --- a/components/mbedtls/port/esp_bignum.c +++ b/components/mbedtls/port/esp_bignum.c @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD */ #include #include @@ -79,14 +79,23 @@ static esp_err_t esp_mpi_isr_initialise(void) esp_mpi_interrupt_clear(); esp_mpi_interrupt_enable(true); if (op_complete_sem == NULL) { - op_complete_sem = xSemaphoreCreateBinary(); - + static StaticSemaphore_t op_sem_buf; + op_complete_sem = xSemaphoreCreateBinaryStatic(&op_sem_buf); if (op_complete_sem == NULL) { ESP_LOGE(TAG, "Failed to create intr semaphore"); return ESP_FAIL; } - esp_intr_alloc(ETS_RSA_INTR_SOURCE, 0, esp_mpi_complete_isr, NULL, NULL); + esp_err_t ret; + ret = esp_intr_alloc(ETS_RSA_INTR_SOURCE, 0, esp_mpi_complete_isr, NULL, NULL); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to allocate RSA interrupt %d", ret); + + // This should be treated as fatal error as this API would mostly + // be invoked within mbedTLS interface. There is no way for the system + // to proceed if the MPI interrupt allocation fails here. + abort(); + } } /* MPI is clocked proportionally to CPU clock, take power management lock */ @@ -398,7 +407,7 @@ static int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_ esp_mpi_enable_hardware_hw_op(); #if defined (CONFIG_MBEDTLS_MPI_USE_INTERRUPT) - if (esp_mpi_isr_initialise() == ESP_FAIL) { + if (esp_mpi_isr_initialise() != ESP_OK) { ret = -1; esp_mpi_disable_hardware_hw_op(); goto cleanup; diff --git a/components/mbedtls/port/esp_platform_time.c b/components/mbedtls/port/esp_platform_time.c new file mode 100644 index 0000000000..541b664ab9 --- /dev/null +++ b/components/mbedtls/port/esp_platform_time.c @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "mbedtls/build_info.h" +#include "mbedtls/platform_time.h" + +#ifdef MBEDTLS_PLATFORM_MS_TIME_ALT +mbedtls_ms_time_t mbedtls_ms_time() +{ + int ret; + struct timespec tv = {}; + mbedtls_ms_time_t current_ms; + + ret = clock_gettime(CLOCK_MONOTONIC, &tv); + if (ret) { + return time(NULL) * 1000L; + } + + current_ms = tv.tv_sec; + return current_ms * 1000L + tv.tv_nsec / 1000000L; +} +#endif // MBEDTLS_PLATFORM_MS_TIME_ALT diff --git a/components/mbedtls/port/include/aes/esp_aes_gcm.h b/components/mbedtls/port/include/aes/esp_aes_gcm.h index 192f251b73..8efb87f403 100644 --- a/components/mbedtls/port/include/aes/esp_aes_gcm.h +++ b/components/mbedtls/port/include/aes/esp_aes_gcm.h @@ -42,6 +42,8 @@ typedef struct { const unsigned char *aad; /*!< The additional data. */ esp_aes_context aes_ctx; esp_aes_gcm_state gcm_state; + /* Software context needed for soft fallback for non-AES ciphers */ + void *ctx_soft; } esp_gcm_context; diff --git a/components/mbedtls/port/include/ecdsa/ecdsa_alt.h b/components/mbedtls/port/include/ecdsa/ecdsa_alt.h index 0326795f8d..f4b7af6a03 100644 --- a/components/mbedtls/port/include/ecdsa/ecdsa_alt.h +++ b/components/mbedtls/port/include/ecdsa/ecdsa_alt.h @@ -14,7 +14,7 @@ extern "C" { #endif -#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN +#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || __DOXYGEN__ /** * @brief Initialize MPI to notify mbedtls_ecdsa_sign to use the private key in efuse @@ -46,7 +46,8 @@ int esp_ecdsa_privkey_load_mpi(mbedtls_mpi *key, int efuse_blk); * - -1 otherwise */ int esp_ecdsa_privkey_load_pk_context(mbedtls_pk_context *key_ctx, int efuse_blk); -#endif + +#endif // CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || __DOXYGEN__ #ifdef __cplusplus } diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 4cc3b2d4a7..5e7717a3a5 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -56,15 +56,22 @@ */ #ifdef CONFIG_MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME +/** + * \def MBEDTLS_PLATFORM_MS_TIME_ALT + * + * Define platform specific function to get time since bootup in milliseconds. + */ +#define MBEDTLS_PLATFORM_MS_TIME_ALT #else #undef MBEDTLS_HAVE_TIME +#undef MBEDTLS_PLATFORM_MS_TIME_ALT #endif /** * \def MBEDTLS_HAVE_TIME_DATE * * System has time.h and time(), gmtime() and the clock is correct. - * The time needs to be correct (not necesarily very accurate, but at least + * The time needs to be correct (not necessarily very accurate, but at least * the date should be correct). This is used to verify the validity period of * X.509 certificates. * @@ -148,6 +155,12 @@ #ifdef CONFIG_MBEDTLS_HARDWARE_AES #define MBEDTLS_GCM_ALT +#ifdef CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER + /* Prefer hardware and fallback to software */ + #define MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK +#else + #undef MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK +#endif #endif /* MBEDTLS_SHAxx_ALT to enable hardware SHA support @@ -488,6 +501,19 @@ #undef MBEDTLS_ECP_NIST_OPTIM #endif +/** + * \def MBEDTLS_ECP_FIXED_POINT_OPTIM + * + * Enable speed up fixed-point multiplication. + * + * Comment this macro to disable FIXED POINT curves optimisation. + */ +#ifdef CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 +#else +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 +#endif + /** * \def MBEDTLS_ECDSA_DETERMINISTIC * @@ -966,7 +992,7 @@ * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load(). * * This pair of functions allows one side of a connection to serialize the - * context associated with the connection, then free or re-use that context + * context associated with the connection, then free or reuse that context * while the serialized state is persisted elsewhere, and finally deserialize * that state to a live context for resuming read/write operations on the * connection. From a protocol perspective, the state of the connection is @@ -1464,7 +1490,7 @@ * \def MBEDTLS_SSL_SESSION_TICKETS * * Enable support for RFC 5077 session tickets in SSL. - * Client-side, provides full support for session tickets (maintainance of a + * Client-side, provides full support for session tickets (maintenance of a * session store remains the responsibility of the application, though). * Server-side, you also need to provide callbacks for writing and parsing * tickets, including authenticated encryption and key management. Example @@ -2046,7 +2072,11 @@ * * This module enables mbedtls_strerror(). */ +#if CONFIG_MBEDTLS_ERROR_STRINGS #define MBEDTLS_ERROR_C +#else +#undef MBEDTLS_ERROR_C +#endif /** * \def MBEDTLS_GCM_C @@ -2096,7 +2126,7 @@ * * Requires: MBEDTLS_MD_C * - * Uncomment to enable the HMAC_DRBG random number geerator. + * Uncomment to enable the HMAC_DRBG random number generator. */ #define MBEDTLS_HMAC_DRBG_C @@ -2718,25 +2748,6 @@ */ #define MBEDTLS_X509_CRT_WRITE_C -/** - * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION - * - * Alow the X509 parser to not break-off when parsing an X509 certificate - * and encountering an unknown critical extension. - * - * Module: library/x509_crt.c - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - * - * This module is supports loading of certificates with extensions that - * may not be supported by mbedtls. - */ -#ifdef CONFIG_MBEDTLS_ALLOW_UNSUPPORTED_CRITICAL_EXT -#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION -#else -#undef MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION -#endif - /** * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK * @@ -2807,7 +2818,7 @@ /* SSL options */ #ifndef CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN -#define MBEDTLS_SSL_MAX_CONTENT_LEN CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ +#define MBEDTLS_SSL_MAX_CONTENT_LEN CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN /**< Maximum fragment length in bytes, determines the size of each of the two internal I/O buffers */ #else @@ -2843,10 +2854,10 @@ #undef MBEDTLS_SSL_CID_OUT_LEN_MAX #endif -/** \def MBEDTLS_SSL_CID_PADDING_GRANULARITY +/** \def MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY * * This option controls the use of record plaintext padding - * when using the Connection ID extension in DTLS 1.2. + * in TLS 1.3 and when using the Connection ID extension in DTLS 1.2. * * The padding will always be chosen so that the length of the * padded plaintext is a multiple of the value of this option. @@ -2858,10 +2869,10 @@ * a power of two should be preferred. * */ -#ifdef CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID -#define MBEDTLS_SSL_CID_PADDING_GRANULARITY CONFIG_MBEDTLS_SSL_CID_PADDING_GRANULARITY +#ifdef CONFIG_MBEDTLS_SSL_CID_PADDING_GRANULARITY +#define MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY CONFIG_MBEDTLS_SSL_CID_PADDING_GRANULARITY #else -#undef MBEDTLS_SSL_CID_PADDING_GRANULARITY +#undef MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY #endif diff --git a/components/mbedtls/port/include/mbedtls/gcm.h b/components/mbedtls/port/include/mbedtls/gcm.h new file mode 100644 index 0000000000..d50527d4df --- /dev/null +++ b/components/mbedtls/port/include/mbedtls/gcm.h @@ -0,0 +1,81 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include_next "mbedtls/gcm.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(MBEDTLS_GCM_ALT) && defined(MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK) + +/** + * When the MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK is defined, for non-AES GCM + * operations we need to fallback to the software function definitions of the + * mbedtls GCM layer. + * Thus in this case we need declarations for the software funtions. + * Please refer mbedtls/include/mbedtls/gcm.h for function documentations + */ + +void mbedtls_gcm_init_soft(mbedtls_gcm_context_soft *ctx); + + +int mbedtls_gcm_setkey_soft(mbedtls_gcm_context_soft *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits); + +int mbedtls_gcm_starts_soft(mbedtls_gcm_context_soft *ctx, + int mode, + const unsigned char *iv, size_t iv_len); + +int mbedtls_gcm_update_ad_soft(mbedtls_gcm_context_soft *ctx, + const unsigned char *add, size_t add_len); + +int mbedtls_gcm_update_soft(mbedtls_gcm_context_soft *ctx, + const unsigned char *input, size_t input_length, + unsigned char *output, size_t output_size, + size_t *output_length); + +int mbedtls_gcm_finish_soft(mbedtls_gcm_context_soft *ctx, + unsigned char *output, size_t output_size, + size_t *output_length, + unsigned char *tag, size_t tag_len); + + +int mbedtls_gcm_crypt_and_tag_soft(mbedtls_gcm_context_soft *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag); + + +int mbedtls_gcm_auth_decrypt_soft(mbedtls_gcm_context_soft *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output); + +void mbedtls_gcm_free_soft(mbedtls_gcm_context_soft *ctx); + +#endif /* MBEDTLS_GCM_ALT && MBEDTLS_GCM_NON_AES_CIPHER_SOFT_FALLBACK*/ + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/include/sha1_alt.h b/components/mbedtls/port/include/sha1_alt.h index 530eb5319c..26039378b4 100644 --- a/components/mbedtls/port/include/sha1_alt.h +++ b/components/mbedtls/port/include/sha1_alt.h @@ -50,6 +50,24 @@ typedef struct { esp_mbedtls_sha1_mode mode; } mbedtls_sha1_context; +/** + * \brief Set the SHA-1 mode for a mbedtls_sha1_context. + * + * \param ctx The SHA-1 context structure. + * \param mode The SHA-1 mode to be set. It can be one of the following: + * - ESP_MBEDTLS_SHA1_UNUSED: Indicates that the first block hasn't been processed yet. + * - ESP_MBEDTLS_SHA1_HARDWARE: Specifies the use of hardware SHA engine for SHA-1 calculations. + * - ESP_MBEDTLS_SHA1_SOFTWARE: Specifies the use of software-based SHA-1 calculations. + * + * \return None. + */ +static inline void esp_mbedtls_set_sha1_mode(mbedtls_sha1_context *ctx, esp_mbedtls_sha1_mode mode) +{ + if (ctx) { + ctx->mode = mode; + } +} + #elif SOC_SHA_SUPPORT_DMA || SOC_SHA_SUPPORT_RESUME typedef enum { diff --git a/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.c b/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.c new file mode 100644 index 0000000000..78fb4d479e --- /dev/null +++ b/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.c @@ -0,0 +1,187 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/platform.h" +#include "mbedtls_rom_osi.h" + +void mbedtls_rom_osi_functions_init(void); + +static void mbedtls_rom_mutex_init( mbedtls_threading_mutex_t *mutex ) +{ +#if (!defined(CONFIG_MBEDTLS_THREADING_C)) + ((void) mutex); + return; +#else + mbedtls_mutex_init(mutex); +#endif +} + +static void mbedtls_rom_mutex_free( mbedtls_threading_mutex_t *mutex ) +{ +#if (!defined(CONFIG_MBEDTLS_THREADING_C)) + ((void) mutex); + return; +#else + mbedtls_mutex_free(mutex); +#endif +} + +static int mbedtls_rom_mutex_lock( mbedtls_threading_mutex_t *mutex ) +{ +#if (!defined(CONFIG_MBEDTLS_THREADING_C)) + ((void) mutex); + return 0; +#else + return mbedtls_mutex_lock(mutex); +#endif +} + +static int mbedtls_rom_mutex_unlock( mbedtls_threading_mutex_t *mutex ) +{ +#if (!defined(CONFIG_MBEDTLS_THREADING_C)) + ((void) mutex); + return 0; +#else + return mbedtls_mutex_unlock(mutex); +#endif +} + +/* This structure can be automatically generated by the script with rom.mbedtls.ld. */ +static const mbedtls_rom_funcs_t mbedtls_rom_funcs_table = { + /* Fill the ROM functions into mbedtls rom function table. */ + /* aes module */ + ._rom_mbedtls_aes_init = mbedtls_aes_init, + ._rom_mbedtls_aes_free = mbedtls_aes_free, + ._rom_mbedtls_aes_setkey_enc = mbedtls_aes_setkey_enc, + ._rom_mbedtls_aes_setkey_dec = mbedtls_aes_setkey_dec, + ._rom_mbedtls_aes_crypt_ecb = mbedtls_aes_crypt_ecb, + ._rom_mbedtls_aes_crypt_cbc = mbedtls_aes_crypt_cbc, + ._rom_mbedtls_internal_aes_encrypt = mbedtls_internal_aes_encrypt, + ._rom_mbedtls_internal_aes_decrypt = mbedtls_internal_aes_decrypt, + /* asn1 module */ + ._rom_mbedtls_asn1_get_len = mbedtls_asn1_get_len, + ._rom_mbedtls_asn1_get_tag = mbedtls_asn1_get_tag, + ._rom_mbedtls_asn1_get_bool = mbedtls_asn1_get_bool, + ._rom_mbedtls_asn1_get_int = mbedtls_asn1_get_int, + ._rom_mbedtls_asn1_get_bitstring = mbedtls_asn1_get_bitstring, + ._rom_mbedtls_asn1_get_bitstring_null = mbedtls_asn1_get_bitstring_null, + ._rom_mbedtls_asn1_get_sequence_of = mbedtls_asn1_get_sequence_of, + ._rom_mbedtls_asn1_get_mpi = mbedtls_asn1_get_mpi, + ._rom_mbedtls_asn1_get_alg = mbedtls_asn1_get_alg, + ._rom_mbedtls_asn1_get_alg_null = mbedtls_asn1_get_alg_null, + ._rom_mbedtls_asn1_write_len = mbedtls_asn1_write_len, + ._rom_mbedtls_asn1_write_tag = mbedtls_asn1_write_tag, + ._rom_mbedtls_asn1_write_mpi = mbedtls_asn1_write_mpi, + /* base64 moudle */ + ._rom_mbedtls_base64_decode = mbedtls_base64_decode, + /* bignum module */ + ._rom_mbedtls_mpi_init = mbedtls_mpi_init, + ._rom_mbedtls_mpi_free = mbedtls_mpi_free, + ._rom_mbedtls_mpi_grow = mbedtls_mpi_grow, + ._rom_mbedtls_mpi_shrink = mbedtls_mpi_shrink, + ._rom_mbedtls_mpi_copy = mbedtls_mpi_copy, + ._rom_mbedtls_mpi_safe_cond_assign = mbedtls_mpi_safe_cond_assign, + ._rom_mbedtls_mpi_safe_cond_swap = mbedtls_mpi_safe_cond_swap, + ._rom_mbedtls_mpi_lset = mbedtls_mpi_lset, + ._rom_mbedtls_mpi_get_bit = mbedtls_mpi_get_bit, + ._rom_mbedtls_mpi_set_bit = mbedtls_mpi_set_bit, + ._rom_mbedtls_mpi_lsb = mbedtls_mpi_lsb, + ._rom_mbedtls_mpi_bitlen = mbedtls_mpi_bitlen, + ._rom_mbedtls_mpi_size = mbedtls_mpi_size, + ._rom_mbedtls_mpi_read_binary = mbedtls_mpi_read_binary, + ._rom_mbedtls_mpi_write_binary = mbedtls_mpi_write_binary, + ._rom_mbedtls_mpi_shift_l = mbedtls_mpi_shift_l, + ._rom_mbedtls_mpi_shift_r = mbedtls_mpi_shift_r, + ._rom_mbedtls_mpi_cmp_abs = mbedtls_mpi_cmp_abs, + ._rom_mbedtls_mpi_cmp_mpi = mbedtls_mpi_cmp_mpi, + ._rom_mbedtls_mpi_lt_mpi_ct = mbedtls_mpi_lt_mpi_ct, + ._rom_mbedtls_mpi_cmp_int = mbedtls_mpi_cmp_int, + ._rom_mbedtls_mpi_add_abs = mbedtls_mpi_add_abs, + ._rom_mbedtls_mpi_sub_abs = mbedtls_mpi_sub_abs, + ._rom_mbedtls_mpi_add_mpi = mbedtls_mpi_add_mpi, + ._rom_mbedtls_mpi_sub_mpi = mbedtls_mpi_sub_mpi, + ._rom_mbedtls_mpi_add_int = mbedtls_mpi_add_int, + ._rom_mbedtls_mpi_sub_int = mbedtls_mpi_sub_int, + ._rom_mbedtls_mpi_mul_mpi = mbedtls_mpi_mul_mpi, + ._rom_mbedtls_mpi_mul_int = mbedtls_mpi_mul_int, + ._rom_mbedtls_mpi_div_mpi = mbedtls_mpi_div_mpi, + ._rom_mbedtls_mpi_div_int = mbedtls_mpi_div_int, + ._rom_mbedtls_mpi_mod_mpi = mbedtls_mpi_mod_mpi, + ._rom_mbedtls_mpi_mod_int = mbedtls_mpi_mod_int, + ._rom_mbedtls_mpi_exp_mod = mbedtls_mpi_exp_mod, + ._rom_mbedtls_mpi_fill_random = mbedtls_mpi_fill_random, + ._rom_mbedtls_mpi_gcd = mbedtls_mpi_gcd, + ._rom_mbedtls_mpi_inv_mod = mbedtls_mpi_inv_mod, + ._rom_mbedtls_mpi_is_prime_ext = mbedtls_mpi_is_prime_ext, + /* ccm module */ + ._rom_mbedtls_ccm_star_encrypt_and_tag = mbedtls_ccm_star_encrypt_and_tag, + ._rom_mbedtls_ccm_star_auth_decrypt = mbedtls_ccm_star_auth_decrypt, + /* cipher module */ + ._rom_mbedtls_cipher_init = mbedtls_cipher_init, + ._rom_mbedtls_cipher_set_padding_mode = mbedtls_cipher_set_padding_mode, + ._rom_mbedtls_cipher_reset = mbedtls_cipher_reset, + ._rom_mbedtls_cipher_finish = mbedtls_cipher_finish, + ._rom_mbedtls_cipher_crypt = mbedtls_cipher_crypt, + ._rom_mbedtls_cipher_cmac_starts = mbedtls_cipher_cmac_starts, + ._rom_mbedtls_cipher_cmac_update = mbedtls_cipher_cmac_update, + ._rom_mbedtls_cipher_cmac_finish = mbedtls_cipher_cmac_finish, + /* ctr drbg module */ + ._rom_mbedtls_ctr_drbg_init = mbedtls_ctr_drbg_init, + ._rom_mbedtls_ctr_drbg_seed = mbedtls_ctr_drbg_seed, + ._rom_mbedtls_ctr_drbg_free = mbedtls_ctr_drbg_free, + ._rom_mbedtls_ctr_drbg_reseed = mbedtls_ctr_drbg_reseed, + ._rom_mbedtls_ctr_drbg_random_with_add = mbedtls_ctr_drbg_random_with_add, + ._rom_mbedtls_ctr_drbg_random = mbedtls_ctr_drbg_random, + /* sha1 module */ + ._rom_mbedtls_sha1_init = mbedtls_sha1_init, + ._rom_mbedtls_sha1_free = mbedtls_sha1_free, + ._rom_mbedtls_sha1_clone = mbedtls_sha1_clone, + ._rom_mbedtls_sha1_starts = mbedtls_sha1_starts, + ._rom_mbedtls_sha1_finish = mbedtls_sha1_finish, + /* sha256 module */ + ._rom_mbedtls_sha256_init = mbedtls_sha256_init, + ._rom_mbedtls_sha256_free = mbedtls_sha256_free, + ._rom_mbedtls_sha256_clone = mbedtls_sha256_clone, + ._rom_mbedtls_sha256_starts = mbedtls_sha256_starts, + ._rom_mbedtls_sha256_finish = mbedtls_sha256_finish, + ._rom_mbedtls_sha256 = mbedtls_sha256, + /* sha512 module */ + ._rom_mbedtls_sha512_init = mbedtls_sha512_init, + ._rom_mbedtls_sha512_free = mbedtls_sha512_free, + ._rom_mbedtls_sha512_clone = mbedtls_sha512_clone, + ._rom_mbedtls_sha512_starts = mbedtls_sha512_starts, + ._rom_mbedtls_sha512_update = mbedtls_sha512_update, + ._rom_mbedtls_sha512_finish = mbedtls_sha512_finish, + ._rom_mbedtls_internal_sha512_process = mbedtls_internal_sha512_process, + ._rom_mbedtls_sha512 = mbedtls_sha512, + + /* Fill the platform functions into mbedtls rom function table. */ + ._mbedtls_mutex_init = mbedtls_rom_mutex_init, + ._mbedtls_mutex_free = mbedtls_rom_mutex_free, + ._mbedtls_mutex_lock = mbedtls_rom_mutex_lock, + ._mbedtls_mutex_unlock = mbedtls_rom_mutex_unlock, + ._mbedtls_calloc = MBEDTLS_PLATFORM_STD_CALLOC, + ._mbedtls_free = MBEDTLS_PLATFORM_STD_FREE, + + /* Fill the SHA functions into mbedtls rom function table, since these functions are not exported in the ROM interface. */ + ._mbedtls_sha1_update = mbedtls_sha1_update, + ._mbedtls_internal_sha1_process = mbedtls_internal_sha1_process, + ._mbedtls_sha256_update = mbedtls_sha256_update, + ._mbedtls_internal_sha256_process = mbedtls_internal_sha256_process, +}; + +__attribute__((constructor)) void mbedtls_rom_osi_functions_init(void) +{ + /* Initialize the pointer of mbedtls rom osi function table. */ + extern mbedtls_rom_funcs_t *mbedtls_rom_osi_funcs_ptr; + mbedtls_rom_osi_funcs_ptr = (mbedtls_rom_funcs_t *)&mbedtls_rom_funcs_table; +} diff --git a/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.h b/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.h new file mode 100644 index 0000000000..42dddc325c --- /dev/null +++ b/components/mbedtls/port/mbedtls_rom/mbedtls_rom_osi.h @@ -0,0 +1,538 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "mbedtls/aes.h" +#include "mbedtls/asn1.h" +#include "mbedtls/asn1write.h" +#include "mbedtls/base64.h" +#include "mbedtls/bignum.h" +#include "mbedtls/ccm.h" +#include "mbedtls/cipher.h" +#include "mbedtls/cmac.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/dhm.h" +#include "mbedtls/ecdh.h" +#include "mbedtls/ecdsa.h" +#include "mbedtls/ecjpake.h" +#include "mbedtls/ecp.h" +#include "mbedtls/entropy.h" +#include "mbedtls/hmac_drbg.h" +#include "mbedtls/md.h" +#include "mbedtls/oid.h" +#include "mbedtls/pem.h" +#include "mbedtls/pkcs12.h" +#include "mbedtls/pkcs5.h" +#include "mbedtls/pk.h" +#include "mbedtls/platform.h" +#include "mbedtls/rsa.h" +#include "mbedtls/sha1.h" +#include "mbedtls/sha256.h" +#include "mbedtls/sha512.h" +#include "mbedtls/ssl_ciphersuites.h" +#include "mbedtls/ssl.h" +#include "mbedtls/x509_crt.h" +#include "mbedtls/x509.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if (!defined(CONFIG_MBEDTLS_THREADING_C)) +typedef struct mbedtls_threading_mutex_t { + int dummy; +} mbedtls_threading_mutex_t; +#endif + +typedef struct mbedtls_rom_funcs { + void (*_rom_mbedtls_aes_init)( mbedtls_aes_context *ctx ); + int (*_rom_ssl_write_client_hello)( mbedtls_ssl_context *ssl ); + int (*_rom_ssl_parse_server_hello)( mbedtls_ssl_context *ssl ); + int (*_rom_ssl_parse_server_key_exchange)( mbedtls_ssl_context *ssl ); + int (*_rom_ssl_parse_certificate_request)( mbedtls_ssl_context *ssl ); + int (*_rom_ssl_parse_server_hello_done)( mbedtls_ssl_context *ssl ); + int (*_rom_ssl_write_client_key_exchange)( mbedtls_ssl_context *ssl ); + int (*_rom_ssl_write_certificate_verify)( mbedtls_ssl_context *ssl ); + int (*_rom_ssl_parse_new_session_ticket)( mbedtls_ssl_context *ssl ); + void (*_rom_mbedtls_aes_free)( mbedtls_aes_context *ctx ); + int (*_rom_mbedtls_aes_setkey_enc)( mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits ); + int (*_rom_mbedtls_aes_setkey_dec)( mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits ); + int (*_rom_mbedtls_aes_crypt_ecb)( mbedtls_aes_context *ctx, int mode, const unsigned char input[16], unsigned char output[16] ); + int (*_rom_mbedtls_aes_crypt_cbc)( mbedtls_aes_context *ctx, int mode, size_t length, unsigned char iv[16], const unsigned char *input, unsigned char *output ); + int (*_rom_mbedtls_internal_aes_encrypt)( mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ); + int (*_rom_mbedtls_internal_aes_decrypt)( mbedtls_aes_context *ctx, const unsigned char input[16], unsigned char output[16] ); + int (*_rom_mbedtls_asn1_get_len)( unsigned char **p, const unsigned char *end, size_t *len ); + int (*_rom_mbedtls_asn1_get_tag)( unsigned char **p, const unsigned char *end, size_t *len, int tag ); + int (*_rom_mbedtls_asn1_get_bool)( unsigned char **p, const unsigned char *end, int *val ); + int (*_rom_mbedtls_asn1_get_int)( unsigned char **p, const unsigned char *end, int *val ); + int (*_rom_mbedtls_asn1_get_bitstring)( unsigned char **p, const unsigned char *end, mbedtls_asn1_bitstring *bs); + int (*_rom_mbedtls_asn1_get_bitstring_null)( unsigned char **p, const unsigned char *end, size_t *len ); + int (*_rom_mbedtls_asn1_get_sequence_of)( unsigned char **p, const unsigned char *end, mbedtls_asn1_sequence *cur, int tag); + int (*_rom_mbedtls_asn1_get_mpi)( unsigned char **p, const unsigned char *end, mbedtls_mpi *X ); + int (*_rom_mbedtls_asn1_get_alg)( unsigned char **p, const unsigned char *end, mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ); + int (*_rom_mbedtls_asn1_get_alg_null)( unsigned char **p, const unsigned char *end, mbedtls_asn1_buf *alg ); + int (*_rom_mbedtls_asn1_write_len)( unsigned char **p, const unsigned char *start, size_t len ); + int (*_rom_mbedtls_asn1_write_tag)( unsigned char **p, const unsigned char *start, unsigned char tag ); + int (*_rom_mbedtls_asn1_write_mpi)( unsigned char **p, const unsigned char *start, const mbedtls_mpi *X ); + int (*_rom_mbedtls_base64_decode)( unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen ); + void (*_rom_mbedtls_mpi_init)( mbedtls_mpi *X ); + void (*_rom_mbedtls_mpi_free)( mbedtls_mpi *X ); + int (*_rom_mbedtls_mpi_grow)( mbedtls_mpi *X, size_t nblimbs ); + int (*_rom_mbedtls_mpi_shrink)( mbedtls_mpi *X, size_t nblimbs ); + int (*_rom_mbedtls_mpi_copy)( mbedtls_mpi *X, const mbedtls_mpi *Y ); + int (*_rom_mbedtls_mpi_safe_cond_assign)( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign ); + int (*_rom_mbedtls_mpi_safe_cond_swap)( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign ); + int (*_rom_mbedtls_mpi_lset)( mbedtls_mpi *X, mbedtls_mpi_sint z ); + int (*_rom_mbedtls_mpi_get_bit)( const mbedtls_mpi *X, size_t pos ); + int (*_rom_mbedtls_mpi_set_bit)( mbedtls_mpi *X, size_t pos, unsigned char val ); + size_t (*_rom_mbedtls_mpi_lsb)( const mbedtls_mpi *X ); + size_t (*_rom_mbedtls_mpi_bitlen)( const mbedtls_mpi *X ); + size_t (*_rom_mbedtls_mpi_size)( const mbedtls_mpi *X ); + int (*_rom_mbedtls_mpi_read_binary)( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ); + int (*_rom_mbedtls_mpi_write_binary)( const mbedtls_mpi *X, unsigned char *buf, size_t buflen ); + int (*_rom_mbedtls_mpi_shift_l)( mbedtls_mpi *X, size_t count ); + int (*_rom_mbedtls_mpi_shift_r)( mbedtls_mpi *X, size_t count ); + int (*_rom_mbedtls_mpi_cmp_abs)( const mbedtls_mpi *X, const mbedtls_mpi *Y ); + int (*_rom_mbedtls_mpi_cmp_mpi)( const mbedtls_mpi *X, const mbedtls_mpi *Y ); + int (*_rom_mbedtls_mpi_lt_mpi_ct)( const mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned *ret ); + int (*_rom_mbedtls_mpi_cmp_int)( const mbedtls_mpi *X, mbedtls_mpi_sint z ); + int (*_rom_mbedtls_mpi_add_abs)( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); + int (*_rom_mbedtls_mpi_sub_abs)( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); + int (*_rom_mbedtls_mpi_add_mpi)( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); + int (*_rom_mbedtls_mpi_sub_mpi)( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); + int (*_rom_mbedtls_mpi_add_int)( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ); + int (*_rom_mbedtls_mpi_sub_int)( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ); + int (*_rom_mbedtls_mpi_mul_mpi)( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); + int (*_rom_mbedtls_mpi_mul_int)( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b ); + int (*_rom_mbedtls_mpi_div_mpi)( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ); + int (*_rom_mbedtls_mpi_div_int)( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b ); + int (*_rom_mbedtls_mpi_mod_mpi)( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ); + int (*_rom_mbedtls_mpi_mod_int)( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b ); + int (*_rom_mbedtls_mpi_exp_mod)( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR ); + int (*_rom_mbedtls_mpi_fill_random)( mbedtls_mpi *X, size_t size, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_mpi_gcd)( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B ); + int (*_rom_mbedtls_mpi_inv_mod)( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N ); + int (*_rom_mbedtls_mpi_is_prime_ext)( const mbedtls_mpi *X, int rounds, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_ccm_star_encrypt_and_tag)( mbedtls_ccm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, unsigned char *tag, size_t tag_len ); + int (*_rom_mbedtls_ccm_star_auth_decrypt)( mbedtls_ccm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, const unsigned char *tag, size_t tag_len ); + void (*_rom_mbedtls_cipher_init)( mbedtls_cipher_context_t *ctx ); + int (*_rom_mbedtls_cipher_set_padding_mode)( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ); + int (*_rom_mbedtls_cipher_reset)( mbedtls_cipher_context_t *ctx ); + int (*_rom_mbedtls_cipher_finish)( mbedtls_cipher_context_t *ctx, unsigned char *output, size_t *olen ); + int (*_rom_mbedtls_cipher_crypt)( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen ); + int (*_rom_mbedtls_cipher_cmac_starts)( mbedtls_cipher_context_t *ctx, const unsigned char *key, size_t keybits ); + int (*_rom_mbedtls_cipher_cmac_update)( mbedtls_cipher_context_t *ctx, const unsigned char *input, size_t ilen ); + int (*_rom_mbedtls_cipher_cmac_finish)( mbedtls_cipher_context_t *ctx, unsigned char *output ); + void (*_rom_mbedtls_ctr_drbg_init)( mbedtls_ctr_drbg_context *ctx ); + int (*_rom_mbedtls_ctr_drbg_seed)( mbedtls_ctr_drbg_context *ctx, int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy, const unsigned char *custom, size_t len ); + void (*_rom_mbedtls_ctr_drbg_free)( mbedtls_ctr_drbg_context *ctx ); + int (*_rom_mbedtls_ctr_drbg_reseed)( mbedtls_ctr_drbg_context *ctx, const unsigned char *additional, size_t len ); + int (*_rom_mbedtls_ctr_drbg_random_with_add)( void *p_rng, unsigned char *output, size_t output_len, const unsigned char *additional, size_t add_len ); + int (*_rom_mbedtls_ctr_drbg_random)( void *p_rng, unsigned char *output, size_t output_len ); + void (*_rom_mbedtls_dhm_init)( mbedtls_dhm_context *ctx ); + int (*_rom_mbedtls_dhm_read_params)( mbedtls_dhm_context *ctx, unsigned char **p, const unsigned char *end ); + int (*_rom_mbedtls_dhm_make_public)( mbedtls_dhm_context *ctx, int x_size, unsigned char *output, size_t olen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_dhm_calc_secret)( mbedtls_dhm_context *ctx, unsigned char *output, size_t output_size, size_t *olen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + void (*_rom_mbedtls_dhm_free)( mbedtls_dhm_context *ctx ); + void (*_rom_mbedtls_ecdh_init)( mbedtls_ecdh_context *ctx ); + int (*_rom_mbedtls_ecdh_setup)( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id ); + void (*_rom_mbedtls_ecdh_free)( mbedtls_ecdh_context *ctx ); + int (*_rom_mbedtls_ecdh_read_params)( mbedtls_ecdh_context *ctx, const unsigned char **buf, const unsigned char *end ); + int (*_rom_mbedtls_ecdh_get_params)( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key, mbedtls_ecdh_side side ); + int (*_rom_mbedtls_ecdh_make_public)( mbedtls_ecdh_context *ctx, size_t *olen, unsigned char *buf, size_t blen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_ecdh_calc_secret)( mbedtls_ecdh_context *ctx, size_t *olen, unsigned char *buf, size_t blen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + void (*_rom_mbedtls_ecdh_enable_restart)( mbedtls_ecdh_context *ctx ); + int (*_rom_mbedtls_ecdsa_write_signature)( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hlen, unsigned char *sig, size_t *slen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_ecdsa_write_signature_restartable)( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hlen, unsigned char *sig, size_t *slen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, mbedtls_ecdsa_restart_ctx *rs_ctx ); + int (*_rom_mbedtls_ecdsa_read_signature)( mbedtls_ecdsa_context *ctx, const unsigned char *hash, size_t hlen, const unsigned char *sig, size_t slen ); + int (*_rom_mbedtls_ecdsa_read_signature_restartable)( mbedtls_ecdsa_context *ctx, const unsigned char *hash, size_t hlen, const unsigned char *sig, size_t slen, mbedtls_ecdsa_restart_ctx *rs_ctx ); + int (*_rom_mbedtls_ecdsa_from_keypair)( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key ); + void (*_rom_mbedtls_ecdsa_init)( mbedtls_ecdsa_context *ctx ); + void (*_rom_mbedtls_ecdsa_free)( mbedtls_ecdsa_context *ctx ); + void (*_rom_mbedtls_ecdsa_restart_init)( mbedtls_ecdsa_restart_ctx *ctx ); + void (*_rom_mbedtls_ecdsa_restart_free)( mbedtls_ecdsa_restart_ctx *ctx ); + void (*_rom_mbedtls_ecjpake_init)( mbedtls_ecjpake_context *ctx ); + int (*_rom_mbedtls_ecjpake_check)( const mbedtls_ecjpake_context *ctx ); + int (*_rom_mbedtls_ecjpake_write_round_one)( mbedtls_ecjpake_context *ctx, unsigned char *buf, size_t len, size_t *olen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_ecjpake_read_round_one)( mbedtls_ecjpake_context *ctx, const unsigned char *buf, size_t len ); + int (*_rom_mbedtls_ecjpake_write_round_two)( mbedtls_ecjpake_context *ctx, unsigned char *buf, size_t len, size_t *olen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_ecjpake_read_round_two)( mbedtls_ecjpake_context *ctx, const unsigned char *buf, size_t len ); + int (*_rom_mbedtls_ecjpake_derive_secret)( mbedtls_ecjpake_context *ctx, unsigned char *buf, size_t len, size_t *olen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + void (*_rom_mbedtls_ecjpake_free)( mbedtls_ecjpake_context *ctx ); + int (*_rom_mbedtls_ecp_check_budget)( const mbedtls_ecp_group *grp, mbedtls_ecp_restart_ctx *rs_ctx, unsigned ops ); + int (*_rom_mbedtls_ecp_restart_is_enabled)( void ); + const mbedtls_ecp_curve_info *(*_rom_mbedtls_ecp_curve_list)( void ); + const mbedtls_ecp_group_id *(*_rom_mbedtls_ecp_grp_id_list)( void ); + const mbedtls_ecp_curve_info *(*_rom_mbedtls_ecp_curve_info_from_grp_id)( mbedtls_ecp_group_id grp_id ); + const mbedtls_ecp_curve_info *(*_rom_mbedtls_ecp_curve_info_from_tls_id)( uint16_t tls_id ); + void (*_rom_mbedtls_ecp_point_init)( mbedtls_ecp_point *pt ); + void (*_rom_mbedtls_ecp_group_init)( mbedtls_ecp_group *grp ); + void (*_rom_mbedtls_ecp_keypair_init)( mbedtls_ecp_keypair *key ); + void (*_rom_mbedtls_ecp_point_free)( mbedtls_ecp_point *pt ); + void (*_rom_mbedtls_ecp_group_free)( mbedtls_ecp_group *grp ); + void (*_rom_mbedtls_ecp_keypair_free)( mbedtls_ecp_keypair *key ); + void (*_rom_mbedtls_ecp_restart_init)( mbedtls_ecp_restart_ctx *ctx ); + void (*_rom_mbedtls_ecp_restart_free)( mbedtls_ecp_restart_ctx *ctx ); + int (*_rom_mbedtls_ecp_copy)( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); + int (*_rom_mbedtls_ecp_group_copy)( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src ); + int (*_rom_mbedtls_ecp_set_zero)( mbedtls_ecp_point *pt ); + int (*_rom_mbedtls_ecp_is_zero)( mbedtls_ecp_point *pt ); + int (*_rom_mbedtls_ecp_point_cmp)( const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ); + int (*_rom_mbedtls_ecp_point_write_binary)( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P, int format, size_t *olen, unsigned char *buf, size_t buflen ); + int (*_rom_mbedtls_ecp_point_read_binary)( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, const unsigned char *buf, size_t ilen ); + int (*_rom_mbedtls_ecp_tls_read_point)( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, const unsigned char **buf, size_t len ); + int (*_rom_mbedtls_ecp_tls_write_point)( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt, int format, size_t *olen, unsigned char *buf, size_t blen ); + int (*_rom_mbedtls_ecp_group_load)( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ); + int (*_rom_mbedtls_ecp_tls_read_group)( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len ); + int (*_rom_mbedtls_ecp_tls_read_group_id)( mbedtls_ecp_group_id *grp, const unsigned char **buf, size_t len ); + int (*_rom_mbedtls_ecp_tls_write_group)( const mbedtls_ecp_group *grp, size_t *olen, unsigned char *buf, size_t blen ); + int (*_rom_mbedtls_ecp_mul)( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_ecp_mul_restartable)( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, mbedtls_ecp_restart_ctx *rs_ctx ); + int (*_rom_mbedtls_ecp_muladd)( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, const mbedtls_mpi *n, const mbedtls_ecp_point *Q ); + int (*_rom_mbedtls_ecp_muladd_restartable)( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, const mbedtls_mpi *n, const mbedtls_ecp_point *Q, mbedtls_ecp_restart_ctx *rs_ctx ); + int (*_rom_mbedtls_ecp_check_pubkey)( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ); + int (*_rom_mbedtls_ecp_check_privkey)( const mbedtls_ecp_group *grp, const mbedtls_mpi *d ); + int (*_rom_mbedtls_ecp_gen_privkey)( const mbedtls_ecp_group *grp, mbedtls_mpi *d, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_ecp_gen_keypair_base)( mbedtls_ecp_group *grp, const mbedtls_ecp_point *G, mbedtls_mpi *d, mbedtls_ecp_point *Q, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_ecp_check_pub_priv)( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv ); + int (*_rom_mbedtls_reserved0)(void); + int (*_rom_mbedtls_reserved1)(void); + int (*_rom_mbedtls_gcm_crypt_and_tag)( mbedtls_gcm_context *ctx, int mode, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, size_t tag_len, unsigned char *tag ); + int (*_rom_mbedtls_gcm_starts)( mbedtls_gcm_context *ctx, int mode, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len ); + int (*_rom_mbedtls_gcm_update)( mbedtls_gcm_context *ctx, size_t length, const unsigned char *input, unsigned char *output ); + int (*_rom_mbedtls_gcm_finish)( mbedtls_gcm_context *ctx, unsigned char *tag, size_t tag_len ); + void (*_rom_mbedtls_hmac_drbg_init)( mbedtls_hmac_drbg_context *ctx ); + int (*_rom_mbedtls_hmac_drbg_seed_buf)( mbedtls_hmac_drbg_context *ctx, const mbedtls_md_info_t * md_info, const unsigned char *data, size_t data_len ); + int (*_rom_mbedtls_hmac_drbg_update_ret)( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t add_len ); + int (*_rom_mbedtls_hmac_drbg_reseed)( mbedtls_hmac_drbg_context *ctx, const unsigned char *additional, size_t len ); + int (*_rom_mbedtls_hmac_drbg_random_with_add)( void *p_rng, unsigned char *output, size_t output_len, const unsigned char *additional, size_t add_len ); + int (*_rom_mbedtls_hmac_drbg_random)( void *p_rng, unsigned char *output, size_t out_len ); + void (*_rom_mbedtls_hmac_drbg_free)( mbedtls_hmac_drbg_context *ctx ); + const int *(*_rom_mbedtls_md_list)( void ); + void (*_rom_mbedtls_md_init)( mbedtls_md_context_t *ctx ); + void (*_rom_mbedtls_md_free)( mbedtls_md_context_t *ctx ); + int (*_rom_mbedtls_md_setup)( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ); + int (*_rom_mbedtls_md_clone)( mbedtls_md_context_t *dst, const mbedtls_md_context_t *src ); + unsigned char (*_rom_mbedtls_md_get_size)( const mbedtls_md_info_t *md_info ); + mbedtls_md_type_t (*_rom_mbedtls_md_get_type)( const mbedtls_md_info_t *md_info ); + int (*_rom_mbedtls_md_starts)( mbedtls_md_context_t *ctx ); + int (*_rom_mbedtls_md_update)( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ); + int (*_rom_mbedtls_md_finish)( mbedtls_md_context_t *ctx, unsigned char *output ); + int (*_rom_mbedtls_md)( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, unsigned char *output ); + int (*_rom_mbedtls_md_hmac_starts)( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ); + int (*_rom_mbedtls_md_hmac_update)( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ); + int (*_rom_mbedtls_md_hmac_finish)( mbedtls_md_context_t *ctx, unsigned char *output); + int (*_rom_mbedtls_md_hmac_reset)( mbedtls_md_context_t *ctx ); + int (*_rom_mbedtls_oid_get_x509_ext_type)( const mbedtls_asn1_buf *oid, int *ext_type ); + int (*_rom_mbedtls_oid_get_pk_alg)( const mbedtls_asn1_buf *oid, mbedtls_pk_type_t *pk_alg ); + int (*_rom_mbedtls_oid_get_ec_grp)( const mbedtls_asn1_buf *oid, mbedtls_ecp_group_id *grp_id ); + int (*_rom_mbedtls_oid_get_sig_alg)( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg ); + int (*_rom_mbedtls_oid_get_md_alg)( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg ); + int (*_rom_mbedtls_oid_get_md_hmac)( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_hmac ); + int (*_rom_mbedtls_oid_get_oid_by_md)( mbedtls_md_type_t md_alg, const char **oid, size_t *olen ); + int (*_rom_mbedtls_oid_get_cipher_alg)( const mbedtls_asn1_buf *oid, mbedtls_cipher_type_t *cipher_alg ); + int (*_rom_mbedtls_oid_get_pkcs12_pbe_alg)( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_alg, mbedtls_cipher_type_t *cipher_alg ); + void (*_rom_mbedtls_pem_init)( void *ctx ); + void (*_rom_mbedtls_pem_free)( void *ctx ); + int (*_rom_mbedtls_pkcs12_pbe_sha1_rc4_128)( mbedtls_asn1_buf *pbe_params, int mode, const unsigned char *pwd, size_t pwdlen, const unsigned char *input, size_t len, unsigned char *output ); + int (*_rom_mbedtls_pkcs12_pbe)( mbedtls_asn1_buf *pbe_params, int mode, mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, const unsigned char *pwd, size_t pwdlen, const unsigned char *input, size_t len, unsigned char *output ); + int (*_rom_mbedtls_pkcs12_derivation)( unsigned char *data, size_t datalen, const unsigned char *pwd, size_t pwdlen, const unsigned char *salt, size_t saltlen, mbedtls_md_type_t mbedtls_md, int id, int iterations ); + int (*_rom_mbedtls_pkcs5_pbes2)( const mbedtls_asn1_buf *pbe_params, int mode, const unsigned char *pwd, size_t pwdlen, const unsigned char *data, size_t datalen, unsigned char *output ); + int (*_rom_mbedtls_pkcs5_pbkdf2_hmac)( mbedtls_md_context_t *ctx, const unsigned char *password, size_t plen, const unsigned char *salt, size_t slen, unsigned int iteration_count, uint32_t key_length, unsigned char *output ); + const mbedtls_pk_info_t *(*_rom_mbedtls_pk_info_from_type)( mbedtls_pk_type_t pk_type ); + void (*_rom_mbedtls_pk_init)( mbedtls_pk_context *ctx ); + void (*_rom_mbedtls_pk_free)( mbedtls_pk_context *ctx ); + void (*_rom_mbedtls_pk_restart_init)( mbedtls_pk_restart_ctx *ctx ); + void (*_rom_mbedtls_pk_restart_free)( mbedtls_pk_restart_ctx *ctx ); + int (*_rom_mbedtls_pk_setup)( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ); + int (*_rom_mbedtls_pk_can_do)( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ); + int (*_rom_mbedtls_pk_verify)( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ); + int (*_rom_mbedtls_pk_verify_restartable)( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len, mbedtls_pk_restart_ctx *rs_ctx ); + int (*_rom_mbedtls_pk_verify_ext)( mbedtls_pk_type_t type, const void *options, mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len ); + int (*_rom_mbedtls_pk_sign_restartable)( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, mbedtls_pk_restart_ctx *rs_ctx ); + int (*_rom_mbedtls_pk_encrypt)( mbedtls_pk_context *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, size_t osize, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + mbedtls_pk_type_t (*_rom_mbedtls_pk_get_type)( const mbedtls_pk_context *ctx ); + int (*_rom_mbedtls_pk_parse_subpubkey)( unsigned char **p, const unsigned char *end, mbedtls_pk_context *pk ); + void (*_rom_mbedtls_rsa_init)( mbedtls_rsa_context *ctx ); + int (*_rom_mbedtls_rsa_import)( mbedtls_rsa_context *ctx, const mbedtls_mpi *N, const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *D, const mbedtls_mpi *E ); + int (*_rom_mbedtls_rsa_import_raw)( mbedtls_rsa_context *ctx, unsigned char const *N, size_t N_len, unsigned char const *P, size_t P_len, unsigned char const *Q, size_t Q_len, unsigned char const *D, size_t D_len, unsigned char const *E, size_t E_len ); + int (*_rom_mbedtls_rsa_complete)( mbedtls_rsa_context *ctx ); + int (*_rom_mbedtls_rsa_set_padding)( mbedtls_rsa_context *ctx, int padding, mbedtls_md_type_t hash_id ); + size_t (*_rom_mbedtls_rsa_get_len)( const mbedtls_rsa_context *ctx ); + int (*_rom_mbedtls_rsa_check_pubkey)( const mbedtls_rsa_context *ctx ); + int (*_rom_mbedtls_rsa_check_privkey)( const mbedtls_rsa_context *ctx ); + int (*_rom_mbedtls_rsa_check_pub_priv)( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv ); + int (*_rom_mbedtls_rsa_public)( mbedtls_rsa_context *ctx, const unsigned char *input, unsigned char *output ); + int (*_rom_mbedtls_rsa_private)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, const unsigned char *input, unsigned char *output ); + int (*_rom_mbedtls_rsa_pkcs1_encrypt)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, size_t ilen, const unsigned char *input, unsigned char *output ); + int (*_rom_mbedtls_rsa_rsaes_pkcs1_v15_encrypt)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, size_t ilen, const unsigned char *input, unsigned char *output ); + int (*_rom_mbedtls_rsa_rsaes_oaep_encrypt)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, const unsigned char *label, size_t label_len, size_t ilen, const unsigned char *input, unsigned char *output ); + int (*_rom_mbedtls_rsa_pkcs1_decrypt)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len ); + int (*_rom_mbedtls_rsa_rsaes_pkcs1_v15_decrypt)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len ); + int (*_rom_mbedtls_rsa_rsaes_oaep_decrypt)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, const unsigned char *label, size_t label_len, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len ); + int (*_rom_mbedtls_rsa_pkcs1_sign)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig ); + int (*_rom_mbedtls_rsa_rsassa_pkcs1_v15_sign)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig ); + int (*_rom_mbedtls_rsa_rsassa_pss_sign)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, unsigned char *sig ); + int (*_rom_mbedtls_rsa_pkcs1_verify)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, const unsigned char *sig ); + int (*_rom_mbedtls_rsa_rsassa_pkcs1_v15_verify)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, const unsigned char *sig ); + int (*_rom_mbedtls_rsa_rsassa_pss_verify)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, const unsigned char *sig ); + int (*_rom_mbedtls_rsa_rsassa_pss_verify_ext)( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode, mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash, mbedtls_md_type_t mgf1_hash_id, int expected_salt_len, const unsigned char *sig ); + void (*_rom_mbedtls_rsa_free)( mbedtls_rsa_context *ctx ); + int (*_rom_mbedtls_rsa_deduce_primes)( mbedtls_mpi const *N, mbedtls_mpi const *E, mbedtls_mpi const *D, mbedtls_mpi *P, mbedtls_mpi *Q ); + int (*_rom_mbedtls_rsa_deduce_private_exponent)( mbedtls_mpi const *P, mbedtls_mpi const *Q, mbedtls_mpi const *E, mbedtls_mpi *D ); + int (*_rom_mbedtls_rsa_deduce_crt)( const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *D, mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP ); + int (*_rom_mbedtls_rsa_validate_params)( const mbedtls_mpi *N, const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *D, const mbedtls_mpi *E, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + int (*_rom_mbedtls_rsa_validate_crt)( const mbedtls_mpi *P, const mbedtls_mpi *Q, const mbedtls_mpi *D, const mbedtls_mpi *DP, const mbedtls_mpi *DQ, const mbedtls_mpi *QP ); + void (*_rom_mbedtls_sha1_init)( mbedtls_sha1_context *ctx ); + void (*_rom_mbedtls_sha1_free)( mbedtls_sha1_context *ctx ); + void (*_rom_mbedtls_sha1_clone)( mbedtls_sha1_context *dst, const mbedtls_sha1_context *src ); + int (*_rom_mbedtls_sha1_starts)( mbedtls_sha1_context *ctx ); + int (*_rom_mbedtls_sha1_finish)( mbedtls_sha1_context *ctx, unsigned char output[20] ); + void (*_rom_mbedtls_sha256_init)( mbedtls_sha256_context *ctx ); + void (*_rom_mbedtls_sha256_free)( mbedtls_sha256_context *ctx ); + void (*_rom_mbedtls_sha256_clone)( mbedtls_sha256_context *dst, const mbedtls_sha256_context *src ); + int (*_rom_mbedtls_sha256_starts)( mbedtls_sha256_context *ctx, int is224 ); + int (*_rom_mbedtls_sha256_finish)( mbedtls_sha256_context *ctx, unsigned char output[32] ); + int (*_rom_mbedtls_sha256)( const unsigned char *input, size_t ilen, unsigned char output[32], int is224 ); + void (*_rom_mbedtls_sha512_init)( mbedtls_sha512_context *ctx ); + void (*_rom_mbedtls_sha512_free)( mbedtls_sha512_context *ctx ); + void (*_rom_mbedtls_sha512_clone)( mbedtls_sha512_context *dst, const mbedtls_sha512_context *src ); + int (*_rom_mbedtls_sha512_starts)( mbedtls_sha512_context *ctx, int is384 ); + int (*_rom_mbedtls_sha512_update)( mbedtls_sha512_context *ctx, const unsigned char *input, size_t ilen ); + int (*_rom_mbedtls_sha512_finish)( mbedtls_sha512_context *ctx, unsigned char output[64] ); + int (*_rom_mbedtls_internal_sha512_process)( mbedtls_sha512_context *ctx, const unsigned char data[128] ); + int (*_rom_mbedtls_sha512)( const unsigned char *input, size_t ilen, unsigned char output[64], int is384 ); + void (*_rom_mbedtls_ssl_conf_endpoint)( mbedtls_ssl_config *conf, int endpoint ); + void (*_rom_mbedtls_ssl_conf_transport)( mbedtls_ssl_config *conf, int transport ); + void (*_rom_mbedtls_ssl_set_bio)( mbedtls_ssl_context *ssl, void *p_bio, mbedtls_ssl_send_t *f_send, mbedtls_ssl_recv_t *f_recv, mbedtls_ssl_recv_timeout_t *f_recv_timeout ); + int (*_rom_mbedtls_ssl_conf_dh_param_bin)( mbedtls_ssl_config *conf, const unsigned char *dhm_P, size_t P_len, const unsigned char *dhm_G, size_t G_len ); + size_t (*_rom_mbedtls_ssl_get_max_frag_len)( const mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_get_max_out_record_payload)( const mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_handshake)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_handshake_step)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_renegotiate)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_send_alert_message)( mbedtls_ssl_context *ssl, unsigned char level, unsigned char message ); + int (*_rom_mbedtls_ssl_config_defaults)( mbedtls_ssl_config *conf, int endpoint, int transport, int preset ); + void (*_rom_mbedtls_ssl_session_init)( mbedtls_ssl_session *session ); + void (*_rom_mbedtls_ssl_session_free)( mbedtls_ssl_session *session ); + void (*_rom_mbedtls_ssl_transform_free)( mbedtls_ssl_transform *transform ); + void (*_rom_mbedtls_ssl_handshake_free)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_handshake_client_step)( mbedtls_ssl_context *ssl ); + void (*_rom_mbedtls_ssl_handshake_wrapup)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_derive_keys)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_handle_message_type)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_prepare_handshake_record)( mbedtls_ssl_context *ssl ); + void (*_rom_mbedtls_ssl_update_handshake_status)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_read_record)( mbedtls_ssl_context *ssl, unsigned update_hs_digest ); + int (*_rom_mbedtls_ssl_fetch_input)( mbedtls_ssl_context *ssl, size_t nb_want ); + int (*_rom_mbedtls_ssl_write_handshake_msg)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_write_record)( mbedtls_ssl_context *ssl, uint8_t force_flush ); + int (*_rom_mbedtls_ssl_flush_output)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_parse_certificate)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_write_certificate)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_parse_change_cipher_spec)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_write_change_cipher_spec)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_parse_finished)( mbedtls_ssl_context *ssl ); + int (*_rom_mbedtls_ssl_write_finished)( mbedtls_ssl_context *ssl ); + void (*_rom_mbedtls_ssl_optimize_checksum)( mbedtls_ssl_context *ssl, const mbedtls_ssl_ciphersuite_t *ciphersuite_info ); + int (*_rom_mbedtls_ssl_psk_derive_premaster)( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ); + unsigned char (*_rom_mbedtls_ssl_sig_from_pk)( mbedtls_pk_context *pk ); + mbedtls_pk_type_t (*_rom_mbedtls_ssl_pk_alg_from_sig)( unsigned char sig ); + mbedtls_md_type_t (*_rom_mbedtls_ssl_md_alg_from_hash)( unsigned char hash ); + unsigned char (*_rom_mbedtls_ssl_hash_from_md_alg)( int md ); + int (*_rom_mbedtls_ssl_check_curve)( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); + int (*_rom_mbedtls_ssl_check_sig_hash)( const mbedtls_ssl_context *ssl, mbedtls_md_type_t md ); + void (*_rom_mbedtls_ssl_write_version)( int major, int minor, int transport, unsigned char ver[2] ); + void (*_rom_mbedtls_ssl_read_version)( int *major, int *minor, int transport, const unsigned char ver[2] ); + int (*_rom_mbedtls_ssl_get_key_exchange_md_ssl_tls)( mbedtls_ssl_context *ssl, unsigned char *output, unsigned char *data, size_t data_len ); + int (*_rom_mbedtls_ssl_get_key_exchange_md_tls1_2)( mbedtls_ssl_context *ssl, unsigned char *hash, size_t *hashlen, unsigned char *data, size_t data_len, mbedtls_md_type_t md_alg ); + int (*_rom_mbedtls_ssl_cf_hmac)( mbedtls_md_context_t *ctx, const unsigned char *add_data, size_t add_data_len, const unsigned char *data, size_t data_len_secret, size_t min_data_len, size_t max_data_len, unsigned char *output ); + void (*_rom_mbedtls_ssl_cf_memcpy_offset)( unsigned char *dst, const unsigned char *src_base, size_t offset_secret, size_t offset_min, size_t offset_max, size_t len ); + int (*_rom_mbedtls_x509_crt_parse_der)( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ); + int (*_rom_mbedtls_x509_crt_verify_restartable)( mbedtls_x509_crt *crt, mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, const mbedtls_x509_crt_profile *profile, const char *cn, uint32_t *flags, int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy, mbedtls_x509_crt_restart_ctx *rs_ctx ); + int (*_rom_mbedtls_x509_crt_check_key_usage)( const mbedtls_x509_crt *crt, unsigned int usage ); + int (*_rom_mbedtls_x509_crt_check_extended_key_usage)( const mbedtls_x509_crt *crt, const char *usage_oid, size_t usage_len ); + int (*_rom_mbedtls_x509_crt_is_revoked)( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ); + void (*_rom_mbedtls_x509_crt_init)( mbedtls_x509_crt *crt ); + void (*_rom_mbedtls_x509_crt_free)( mbedtls_x509_crt *crt ); + void (*_rom_mbedtls_x509_crt_restart_init)( mbedtls_x509_crt_restart_ctx *ctx ); + void (*_rom_mbedtls_x509_crt_restart_free)( mbedtls_x509_crt_restart_ctx *ctx ); + int (*_rom_mbedtls_x509_get_name)( unsigned char **p, const unsigned char *end, mbedtls_x509_name *cur ); + int (*_rom_mbedtls_x509_get_alg_null)( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *alg ); + int (*_rom_mbedtls_x509_get_alg)( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *alg, mbedtls_x509_buf *params ); + int (*_rom_mbedtls_x509_get_rsassa_pss_params)( const mbedtls_x509_buf *params, mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, int *salt_len ); + int (*_rom_mbedtls_x509_get_sig)( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ); + int (*_rom_mbedtls_x509_get_sig_alg)( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, void **sig_opts ); + int (*_rom_mbedtls_x509_get_time)( unsigned char **p, const unsigned char *end, mbedtls_x509_time *t ); + int (*_rom_mbedtls_x509_get_serial)( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *serial ); + int (*_rom_mbedtls_x509_get_ext)( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *ext, int tag ); + void (*_mbedtls_mutex_init)( mbedtls_threading_mutex_t *mutex ); + void (*_mbedtls_mutex_free)( mbedtls_threading_mutex_t *mutex ); + int (*_mbedtls_mutex_lock)( mbedtls_threading_mutex_t *mutex ); + int (*_mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex ); + bool (*_mbedtls_allow_unsupported_critical_ext)( void ); + const mbedtls_cipher_info_t *(*_mbedtls_cipher_info_from_type)( const mbedtls_cipher_type_t cipher_type ); + const mbedtls_cipher_info_t *(*_mbedtls_cipher_info_from_values)( const mbedtls_cipher_id_t cipher_id, int key_bitlen, const mbedtls_cipher_mode_t mode ); + void (*_mbedtls_cipher_free)( mbedtls_cipher_context_t *ctx ); + int (*_mbedtls_cipher_setup)( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ); + int (*_mbedtls_cipher_setkey)( mbedtls_cipher_context_t *ctx, const unsigned char *key, int key_bitlen, const mbedtls_operation_t operation ); + int (*_mbedtls_cipher_set_iv)( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len ); + int (*_mbedtls_cipher_update)( mbedtls_cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen ); + int (*_mbedtls_cipher_auth_encrypt)( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, const unsigned char *ad, size_t ad_len, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, unsigned char *tag, size_t tag_len ); + int (*_mbedtls_cipher_auth_decrypt)( mbedtls_cipher_context_t *ctx, const unsigned char *iv, size_t iv_len, const unsigned char *ad, size_t ad_len, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen, const unsigned char *tag, size_t tag_len ); + int (*_mbedtls_hardware_poll)( void *data, unsigned char *output, size_t len, size_t *olen ); + const mbedtls_md_info_t *(*_mbedtls_md_info_from_type)( mbedtls_md_type_t md_type ); + int (*_mbedtls_pem_read_buffer)( void *ctx, const char *header, const char *footer, const unsigned char *data, const unsigned char *pwd, size_t pwdlen, size_t *use_len ); + void *(*_mbedtls_calloc)( size_t n, size_t size ); + void (*_mbedtls_free)( void *ptr ); + int (*_mbedtls_sha1_update)( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ); + int (*_mbedtls_internal_sha1_process)( mbedtls_sha1_context *ctx, const unsigned char data[64] ); + int (*_mbedtls_sha256_update)( mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen ); + int (*_mbedtls_internal_sha256_process)( mbedtls_sha256_context *ctx, const unsigned char data[64] ); + const int *(*_mbedtls_ssl_list_ciphersuites)( void ); + const mbedtls_ssl_ciphersuite_t *(*_mbedtls_ssl_ciphersuite_from_id)( int ciphersuite_id ); + mbedtls_pk_type_t (*_mbedtls_ssl_get_ciphersuite_sig_pk_alg)( const mbedtls_ssl_ciphersuite_t *info ); + int (*_mbedtls_ssl_ciphersuite_uses_ec)( const mbedtls_ssl_ciphersuite_t *info ); + int (*_mbedtls_ssl_ciphersuite_uses_psk)( const mbedtls_ssl_ciphersuite_t *info ); + int (*_mbedtls_ssl_handshake_server_step)( mbedtls_ssl_context *ssl ); + int (*_mbedtls_ssl_check_cert_usage)( const mbedtls_x509_crt *cert, const mbedtls_ssl_ciphersuite_t *ciphersuite, int cert_endpoint, uint32_t *flags ); + int (*_mbedtls_x509_time_is_past)( const mbedtls_x509_time *to ); + int (*_mbedtls_x509_time_is_future)( const mbedtls_x509_time *from ); +} mbedtls_rom_funcs_t; + +#define STRUCT_OFFSET_CHECK(x, y, z) _Static_assert((offsetof(x,y)==(z)), "The variables type of "#x" before "#y" should be "#z) +#define STRUCT_SIZE_CHECK(x, y) _Static_assert((sizeof(x)==(y)), "The sizeof "#x" should be "#y) + +#if (!defined(CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL)) +#error "CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL" +#endif + +/* platform_util.c */ +#if (defined(MBEDTLS_PLATFORM_ZEROIZE_ALT)) +#error "MBEDTLS_PLATFORM_ZEROIZE_ALT" +#endif + +/* sha1.c */ +STRUCT_OFFSET_CHECK(mbedtls_sha1_context, total, 0); +STRUCT_OFFSET_CHECK(mbedtls_sha1_context, state, 8); +STRUCT_OFFSET_CHECK(mbedtls_sha1_context, buffer, 28); +#if (!defined(MBEDTLS_SHA1_C)) || \ + (!defined(MBEDTLS_SHA1_ALT)) || \ + (defined(MBEDTLS_SHA1_PROCESS_ALT)) +#error "MBEDTLS_SHA1_C" +#endif + +/* sha256.c */ +STRUCT_OFFSET_CHECK(mbedtls_sha256_context, total, 0); +STRUCT_OFFSET_CHECK(mbedtls_sha256_context, state, 8); +STRUCT_OFFSET_CHECK(mbedtls_sha256_context, buffer, 40); +STRUCT_OFFSET_CHECK(mbedtls_sha256_context, first_block, 104); +STRUCT_OFFSET_CHECK(mbedtls_sha256_context, mode, 108); +STRUCT_OFFSET_CHECK(mbedtls_sha256_context, sha_state, 112); +STRUCT_SIZE_CHECK(mbedtls_sha256_context, 116); +#if (!defined(MBEDTLS_SHA256_C)) || \ + (!defined(MBEDTLS_SHA256_ALT)) || \ + (defined(MBEDTLS_SHA256_PROCESS_ALT)) || \ + (defined(MBEDTLS_SHA256_SMALLER)) +#error "!MBEDTLS_SHA256_C" +#endif + +/* sha512.c */ +STRUCT_OFFSET_CHECK(mbedtls_sha512_context, MBEDTLS_PRIVATE(total), 0); +STRUCT_OFFSET_CHECK(mbedtls_sha512_context, MBEDTLS_PRIVATE(state), 16); +STRUCT_OFFSET_CHECK(mbedtls_sha512_context, MBEDTLS_PRIVATE(buffer), 80); +STRUCT_OFFSET_CHECK(mbedtls_sha512_context, MBEDTLS_PRIVATE(is384), 208); +STRUCT_SIZE_CHECK(mbedtls_sha512_context, 216); +#if (!defined(MBEDTLS_SHA512_C)) || \ + (defined(MBEDTLS_SHA512_ALT)) || \ + (defined(MBEDTLS_SHA512_PROCESS_ALT)) +#error "MBEDTLS_SHA256_C" +#endif + +/* aes.c */ +STRUCT_OFFSET_CHECK(mbedtls_aes_context, MBEDTLS_PRIVATE(nr), 0); +STRUCT_OFFSET_CHECK(mbedtls_aes_context, MBEDTLS_PRIVATE(rk_offset), 4); +STRUCT_OFFSET_CHECK(mbedtls_aes_context, MBEDTLS_PRIVATE(buf), 8); +STRUCT_SIZE_CHECK(mbedtls_aes_context, 280); +STRUCT_OFFSET_CHECK(mbedtls_aes_xts_context, MBEDTLS_PRIVATE(crypt), 0); +STRUCT_OFFSET_CHECK(mbedtls_aes_xts_context, MBEDTLS_PRIVATE(tweak), 280); +STRUCT_SIZE_CHECK(mbedtls_aes_xts_context, 560); +#if (defined(MBEDTLS_HAVE_X86)) || \ + (defined(MBEDTLS_HAVE_X86_64)) +#error "MBEDTLS_HAVE_X86" +#endif +#if (!defined(MBEDTLS_AES_C)) || \ + (defined(MBEDTLS_AES_ALT)) || \ + (defined(MBEDTLS_AES_ENCRYPT_ALT)) || \ + (defined(MBEDTLS_AES_DECRYPT_ALT)) || \ + (defined(MBEDTLS_AES_SETKEY_ENC_ALT)) || \ + (defined(MBEDTLS_AES_SETKEY_DEC_ALT)) +#error "MBEDTLS_AES_C" +#endif +#if (!defined(MBEDTLS_AES_ROM_TABLES)) || \ + (defined(MBEDTLS_AES_FEWER_TABLES)) +#error "MBEDTLS_AES_ROM_TABLES" +#endif +#if (!defined(MBEDTLS_CIPHER_MODE_XTS)) || \ + (!defined(MBEDTLS_CIPHER_MODE_CBC)) || \ + (!defined(MBEDTLS_CIPHER_MODE_CFB)) || \ + (!defined(MBEDTLS_CIPHER_MODE_OFB)) || \ + (!defined(MBEDTLS_CIPHER_MODE_CTR)) +#error "MBEDTLS_CIPHER_MODE" +#endif + +/* asn1parse.c asn1write.c */ +STRUCT_OFFSET_CHECK(mbedtls_asn1_buf, tag, 0); +STRUCT_OFFSET_CHECK(mbedtls_asn1_buf, len, 4); +STRUCT_OFFSET_CHECK(mbedtls_asn1_buf, p, 8); +STRUCT_SIZE_CHECK(mbedtls_asn1_buf, 12); +STRUCT_OFFSET_CHECK(mbedtls_asn1_bitstring, len, 0); +STRUCT_OFFSET_CHECK(mbedtls_asn1_bitstring, unused_bits, 4); +STRUCT_OFFSET_CHECK(mbedtls_asn1_bitstring, p, 8); +STRUCT_SIZE_CHECK(mbedtls_asn1_bitstring, 12); +STRUCT_OFFSET_CHECK(mbedtls_asn1_sequence, buf, 0); +STRUCT_OFFSET_CHECK(mbedtls_asn1_sequence, next, 12); +STRUCT_SIZE_CHECK(mbedtls_asn1_sequence, 16); +STRUCT_OFFSET_CHECK(mbedtls_asn1_named_data, oid, 0); +STRUCT_OFFSET_CHECK(mbedtls_asn1_named_data, val, 12); +STRUCT_OFFSET_CHECK(mbedtls_asn1_named_data, next, 24); +STRUCT_OFFSET_CHECK(mbedtls_asn1_named_data, MBEDTLS_PRIVATE(next_merged), 28); +STRUCT_SIZE_CHECK(mbedtls_asn1_named_data, 32); +#if (!defined(MBEDTLS_ASN1_PARSE_C)) +#error "MBEDTLS_ASN1_PARSE_C" +#endif +#if (!defined(MBEDTLS_ASN1_WRITE_C)) +#error "MBEDTLS_ASN1_PARSE_C" +#endif + +/* base64.c */ +#if (!defined(MBEDTLS_BASE64_C)) +#error "MBEDTLS_BASE64_C" +#endif + +/* md5.c */ +#if (defined(MBEDTLS_MD2_C)) || \ + (defined(MBEDTLS_MD4_C)) || \ + (!defined(MBEDTLS_MD5_C)) /* || \ + (defined(MBEDTLS_MD5_ALT)) */ +#error "MBEDTLS_MD_C" +#endif +#ifdef CONFIG_MBEDTLS_ROM_MD5 +STRUCT_OFFSET_CHECK(mbedtls_md5_context, total, 0); +STRUCT_OFFSET_CHECK(mbedtls_md5_context, state, 8); +STRUCT_OFFSET_CHECK(mbedtls_md5_context, buffer, 24); +STRUCT_SIZE_CHECK(mbedtls_md5_context, 88); +#else +STRUCT_OFFSET_CHECK(mbedtls_md5_context, MBEDTLS_PRIVATE(total), 0); +STRUCT_OFFSET_CHECK(mbedtls_md5_context, MBEDTLS_PRIVATE(state), 8); +STRUCT_OFFSET_CHECK(mbedtls_md5_context, MBEDTLS_PRIVATE(buffer), 24); +STRUCT_SIZE_CHECK(mbedtls_md5_context, 88); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/port/sha/dma/sha.c b/components/mbedtls/port/sha/dma/sha.c index 35e76be8ae..0e09771688 100644 --- a/components/mbedtls/port/sha/dma/sha.c +++ b/components/mbedtls/port/sha/dma/sha.c @@ -217,7 +217,6 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen, { int ret = 0; unsigned char *dma_cap_buf = NULL; - int dma_op_num = ( ilen / (SOC_SHA_DMA_MAX_BUFFER_SIZE + 1) ) + 1; if (buf_len > block_length(sha_type)) { ESP_LOGE(TAG, "SHA DMA buf_len cannot exceed max size for a single block"); @@ -251,6 +250,16 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen, buf = dma_cap_buf; } + uint32_t dma_op_num; + + if (ilen > 0) { + /* Number of DMA operations based on maximum chunk size in single operation */ + dma_op_num = (ilen + SOC_SHA_DMA_MAX_BUFFER_SIZE - 1) / SOC_SHA_DMA_MAX_BUFFER_SIZE; + } else { + /* For zero input length, we must allow at-least 1 DMA operation to see + * if there is any pending data that is yet to be copied out */ + dma_op_num = 1; + } /* The max amount of blocks in a single hardware operation is 2^6 - 1 = 63 Thus we only do a single DMA input list + dma buf list, diff --git a/components/mbedtls/test_apps/main/app_main.c b/components/mbedtls/test_apps/main/app_main.c index 0716defabf..27735fb98d 100644 --- a/components/mbedtls/test_apps/main/app_main.c +++ b/components/mbedtls/test_apps/main/app_main.c @@ -1,16 +1,25 @@ /* - * 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 "freertos/FreeRTOS.h" #include "freertos/task.h" #include "unity.h" +#include "mbedtls/aes.h" #include "memory_checks.h" +#include "soc/soc_caps.h" /* setUp runs before every test */ void setUp(void) { + // Execute mbedtls_aes_init operation to allocate AES interrupt + // allocation memory which is considered as leak otherwise +#if SOC_AES_SUPPORTED + mbedtls_aes_context ctx; + mbedtls_aes_init(&ctx); +#endif // SOC_AES_SUPPORTED + test_utils_record_free_mem(); test_utils_set_leak_level(CONFIG_UNITY_CRITICAL_LEAK_LEVEL_GENERAL, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL); test_utils_set_leak_level(CONFIG_UNITY_WARN_LEAK_LEVEL_GENERAL, ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_GENERAL); diff --git a/components/mbedtls/test_apps/main/test_gcm.c b/components/mbedtls/test_apps/main/test_gcm.c new file mode 100644 index 0000000000..07af880d9c --- /dev/null +++ b/components/mbedtls/test_apps/main/test_gcm.c @@ -0,0 +1,144 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include "sys/param.h" +#include "esp_heap_caps.h" +#include "mbedtls/gcm.h" +#include "sdkconfig.h" +#include "unity.h" + + +#if CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER + +typedef struct { + uint8_t *plaintext; + size_t plaintext_length; + uint8_t *aad_buf; + size_t aad_length; + uint8_t *iv; + size_t iv_length; + uint8_t *key; + size_t key_bits; + size_t tag_len; +} gcm_test_cfg_t; + +typedef struct { + const uint8_t *expected_tag; + const uint8_t *ciphertext_last_block; // Last block of the ciphertext +} gcm_test_expected_res_t; + +typedef enum { + GCM_TEST_CRYPT_N_TAG, + GCM_TEST_START_UPDATE_FINISH, +} gcm_test_type_t; + +static void gcm_test(gcm_test_cfg_t *cfg, gcm_test_expected_res_t *res, gcm_test_type_t gcm_type) +{ + mbedtls_gcm_context ctx; + mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_ARIA; + + uint8_t tag_buf_encrypt[16] = {}; + uint8_t tag_buf_decrypt[16] = {}; + uint8_t iv_buf[16] = {}; + uint8_t *ciphertext = malloc(cfg->plaintext_length); + uint8_t *output = malloc(cfg->plaintext_length); + size_t olen; + + if (cfg->plaintext_length != 0) { + TEST_ASSERT_NOT_NULL(ciphertext); + TEST_ASSERT_NOT_NULL(output); + } + + memset(ciphertext, 0, cfg->plaintext_length); + memset(output, 0, cfg->plaintext_length); + memcpy(iv_buf, cfg->iv, cfg->iv_length); + + mbedtls_gcm_init(&ctx); + TEST_ASSERT(mbedtls_gcm_setkey(&ctx, cipher, cfg->key, cfg->key_bits) == 0); + + if (gcm_type == GCM_TEST_CRYPT_N_TAG) { + mbedtls_gcm_crypt_and_tag(&ctx, MBEDTLS_GCM_ENCRYPT, cfg->plaintext_length, iv_buf, cfg->iv_length, cfg->aad_buf, cfg->aad_length, cfg->plaintext, ciphertext, cfg->tag_len, tag_buf_encrypt); + } else if (gcm_type == GCM_TEST_START_UPDATE_FINISH) { + TEST_ASSERT(mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_ENCRYPT, iv_buf, cfg->iv_length) == 0); + TEST_ASSERT(mbedtls_gcm_update_ad(&ctx, cfg->aad_buf, cfg->aad_length) == 0); + TEST_ASSERT(mbedtls_gcm_update(&ctx, cfg->plaintext, cfg->plaintext_length, ciphertext, cfg->plaintext_length, &olen) == 0); + TEST_ASSERT(mbedtls_gcm_finish(&ctx, ciphertext, cfg->plaintext_length, &olen, tag_buf_encrypt, cfg->tag_len) == 0); + } + + size_t offset = cfg->plaintext_length > 16 ? cfg->plaintext_length - 16 : 0; + /* Sanity check: make sure the last ciphertext block matches what we expect to see. */ + TEST_ASSERT_EQUAL_HEX8_ARRAY(res->ciphertext_last_block, ciphertext + offset, MIN(16, cfg->plaintext_length)); + TEST_ASSERT_EQUAL_HEX8_ARRAY(res->expected_tag, tag_buf_encrypt, cfg->tag_len); + + + if (gcm_type == GCM_TEST_CRYPT_N_TAG) { + TEST_ASSERT(mbedtls_gcm_auth_decrypt(&ctx, cfg->plaintext_length, iv_buf, cfg->iv_length, cfg->aad_buf, cfg->aad_length, res->expected_tag, cfg->tag_len, ciphertext, output) == 0); + } else if (gcm_type == GCM_TEST_START_UPDATE_FINISH) { + TEST_ASSERT(mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv_buf, cfg->iv_length) == 0); + TEST_ASSERT(mbedtls_gcm_update_ad(&ctx, cfg->aad_buf, cfg->aad_length) == 0); + TEST_ASSERT(mbedtls_gcm_update(&ctx, ciphertext, cfg->plaintext_length, output, cfg->plaintext_length, &olen) == 0); + TEST_ASSERT(mbedtls_gcm_finish(&ctx, output, cfg->plaintext_length, &olen, tag_buf_decrypt, cfg->tag_len) == 0); + + /* mbedtls_gcm_auth_decrypt already checks tag so only needed for GCM_TEST_START_UPDATE_FINISH */ + TEST_ASSERT_EQUAL_HEX8_ARRAY(res->expected_tag, tag_buf_decrypt, cfg->tag_len); + } + + TEST_ASSERT_EQUAL_HEX8_ARRAY(cfg->plaintext, output, cfg->plaintext_length); + + mbedtls_gcm_free(&ctx); + free(ciphertext); + free(output); +} + + +TEST_CASE("mbedtls ARIA GCM test", "[gcm]") +{ + const unsigned SZ = 1600; + uint8_t aad[16]; + uint8_t iv[16]; + uint8_t key[16]; + + const uint8_t expected_last_block[] = { + 0xbe, 0x96, 0xf1, 0x57, 0x34, 0x07, 0x3f, 0x9d, + 0x87, 0x6b, 0x39, 0x22, 0xe4, 0xef, 0xff, 0xf0, + }; + const uint8_t expected_tag[] = { + 0xef, 0x4e, 0xa8, 0x24, 0x07, 0x65, 0x36, 0x12, + 0xb1, 0xde, 0x7e, 0x23, 0xda, 0xea, 0x7c, 0x6b, + }; + + uint8_t *plaintext = malloc(SZ); + TEST_ASSERT_NOT_NULL(plaintext); + + memset(plaintext, 0xAA, SZ); + memset(iv, 0xEE, 16); + memset(key, 0x44, 16); + memset(aad, 0x76, 16); + + gcm_test_cfg_t cfg = { + .plaintext = plaintext, + .plaintext_length = SZ, + .iv = iv, + .iv_length = sizeof(iv), + .key = key, + .key_bits = 8 * sizeof(key), + .aad_buf = aad, + .aad_length = sizeof(aad), + .tag_len = 16 + }; + + gcm_test_expected_res_t res = { + .expected_tag = expected_tag, + .ciphertext_last_block = expected_last_block, + }; + + gcm_test(&cfg, &res, GCM_TEST_CRYPT_N_TAG); + gcm_test(&cfg, &res, GCM_TEST_START_UPDATE_FINISH); + free(plaintext); +} + +#endif /* CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER */ diff --git a/components/mbedtls/test_apps/main/test_mbedtls_sha.c b/components/mbedtls/test_apps/main/test_mbedtls_sha.c index 0682c61a9c..68bc6a3670 100644 --- a/components/mbedtls/test_apps/main/test_mbedtls_sha.c +++ b/components/mbedtls/test_apps/main/test_mbedtls_sha.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 */ @@ -527,6 +527,40 @@ TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]") TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str); } + +#if SOC_SHA_SUPPORT_DMA +TEST_CASE("mbedtls SHA256 PSRAM DMA large buffer", "[hw_crypto]") +{ + mbedtls_sha256_context sha256_ctx; + unsigned char sha256[32]; + + const size_t SZ = 257984; // specific size to cover issue in https://github.com/espressif/esp-idf/issues/11915 + void *buffer = heap_caps_malloc(SZ, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + TEST_ASSERT_NOT_NULL(buffer); + memset(buffer, 0x55, SZ); + + mbedtls_sha256_init(&sha256_ctx); + int r = mbedtls_sha256_starts(&sha256_ctx, false); + TEST_ASSERT_EQUAL(0, r); + r = mbedtls_sha256_update(&sha256_ctx, buffer, SZ); + TEST_ASSERT_EQUAL(0, r); + r = mbedtls_sha256_finish(&sha256_ctx, sha256); + TEST_ASSERT_EQUAL(0, r); + mbedtls_sha256_free(&sha256_ctx); + free(buffer); + + /* Check the result. Reference value can be calculated using: + * dd if=/dev/zero bs=257984 count=1 | tr '\000' '\125' | sha256sum + */ + const char *expected_hash = "f2330c9f81ff1c8f0515247faa82be8b6f9685601de6f5dae79172766f136c33"; + + char hash_str[sizeof(sha256) * 2 + 1]; + utils_bin2hex(hash_str, sizeof(hash_str), sha256, sizeof(sha256)); + + TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str); +} +#endif // SOC_SHA_SUPPORT_DMA + #endif //CONFIG_SPIRAM_USE_MALLOC #if CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK diff --git a/components/mbedtls/test_apps/main/test_sha.c b/components/mbedtls/test_apps/main/test_sha.c index 68aeea941e..5a314514bb 100644 --- a/components/mbedtls/test_apps/main/test_sha.c +++ b/components/mbedtls/test_apps/main/test_sha.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 */ @@ -130,6 +130,9 @@ TEST_CASE("Test esp_sha() function with long input", "[hw_crypto]") TEST_ASSERT_EQUAL(0, r); #endif + /* munmap() 1MB of flash when the usge of memory-mapped ptr is over */ + spi_flash_munmap(handle); + TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha1_espsha, sha1_mbedtls, sizeof(sha1_espsha), "SHA1 results should match"); TEST_ASSERT_EQUAL_MEMORY_MESSAGE(sha256_espsha, sha256_mbedtls, sizeof(sha256_espsha), "SHA256 results should match"); diff --git a/components/mbedtls/test_apps/pytest_mbedtls_ut.py b/components/mbedtls/test_apps/pytest_mbedtls_ut.py index 1a2fdd0fd4..1445e9a5a4 100644 --- a/components/mbedtls/test_apps/pytest_mbedtls_ut.py +++ b/components/mbedtls/test_apps/pytest_mbedtls_ut.py @@ -74,3 +74,16 @@ def test_mbedtls_psram_esp32(dut: Dut) -> None: @pytest.mark.parametrize('config', ['ecdsa_sign',], indirect=True) def test_mbedtls_ecdsa_sign(dut: Dut) -> None: dut.run_all_single_board_cases(group='efuse_key') + + +@pytest.mark.esp32c2 +@pytest.mark.generic +@pytest.mark.parametrize( + 'config', + [ + 'rom_impl', + ], + indirect=True, +) +def test_mbedtls_rom_impl_esp32c2(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/mbedtls/test_apps/sdkconfig.ci.rom_impl b/components/mbedtls/test_apps/sdkconfig.ci.rom_impl new file mode 100644 index 0000000000..552cc7c973 --- /dev/null +++ b/components/mbedtls/test_apps/sdkconfig.ci.rom_impl @@ -0,0 +1,3 @@ +CONFIG_IDF_TARGET="esp32c2" +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL=y diff --git a/components/newlib/heap.c b/components/newlib/heap.c index fca44906a2..fbcaf8c147 100644 --- a/components/newlib/heap.c +++ b/components/newlib/heap.c @@ -74,6 +74,11 @@ void* memalign(size_t alignment, size_t n) return heap_caps_aligned_alloc(alignment, n, MALLOC_CAP_DEFAULT); } +void* aligned_alloc(size_t alignment, size_t n) +{ + return heap_caps_aligned_alloc(alignment, n, MALLOC_CAP_DEFAULT); +} + int posix_memalign(void **out_ptr, size_t alignment, size_t size) { if (size == 0) { diff --git a/components/newlib/sbom.yml b/components/newlib/sbom.yml new file mode 100644 index 0000000000..b7b2634bd3 --- /dev/null +++ b/components/newlib/sbom.yml @@ -0,0 +1,6 @@ +name: 'newlib' +version: '4.1.0' +cpe: cpe:2.3:a:newlib_project:newlib:{}:*:*:*:*:*:*:* +supplier: 'Organization: Espressif Systems (Shanghai) CO LTD' +originator: 'Organization: Red Hat Incorporated' +description: An open-source C standard library implementation with additional features and patches from Espressif. diff --git a/components/newlib/test_apps/newlib/main/test_newlib.c b/components/newlib/test_apps/newlib/main/test_newlib.c index 741af5c34c..c09918bb29 100644 --- a/components/newlib/test_apps/newlib/main/test_newlib.c +++ b/components/newlib/test_apps/newlib/main/test_newlib.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -32,10 +32,10 @@ TEST_CASE("test atoX functions", "[newlib]") TEST_ASSERT_EQUAL_INT(2147483647, atoi("2147483647")); TEST_ASSERT_EQUAL_INT(42, atoi("000000042")); TEST_ASSERT_EQUAL_INT(0, strtol("foo", NULL, 10)); - TEST_ASSERT_EQUAL(0.123443, atof("0.123443")); - TEST_ASSERT_EQUAL(0.123443f, atoff("0.123443")); - TEST_ASSERT_EQUAL(31.41238, strtod("0.3141238e2", NULL)); - TEST_ASSERT_EQUAL(0.025f, strtof("0.025", NULL)); + TEST_ASSERT_EQUAL_DOUBLE(0.123443, atof("0.123443")); + TEST_ASSERT_EQUAL_FLOAT(0.123443f, atoff("0.123443")); + TEST_ASSERT_EQUAL_DOUBLE(31.41238, strtod("0.3141238e2", NULL)); + TEST_ASSERT_EQUAL_FLOAT(0.025f, strtof("0.025", NULL)); } TEST_CASE("test sprintf function", "[newlib]") @@ -132,7 +132,7 @@ static bool fn_in_rom(void *fn) /* Older chips have newlib nano in rom as well, but this is not linked in due to us now using 64 bit time_t and the ROM code was compiled for 32 bit. */ -#define PRINTF_NANO_IN_ROM (CONFIG_NEWLIB_NANO_FORMAT && (CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H2)) +#define PRINTF_NANO_IN_ROM (CONFIG_NEWLIB_NANO_FORMAT && CONFIG_IDF_TARGET_ESP32C2) #define SSCANF_NANO_IN_ROM (CONFIG_NEWLIB_NANO_FORMAT && CONFIG_IDF_TARGET_ESP32C2) TEST_CASE("check if ROM or Flash is used for functions", "[newlib]") @@ -233,3 +233,10 @@ TEST_CASE("newlib: rom and toolchain localtime func gives the same result", "[ne printf("%s\n", test_result); TEST_ASSERT_EQUAL_STRING("2020-03-12 15:00:00 EDT (tm_isdst = 1)", test_result); } + +TEST_CASE("newlib: printf float as expected", "[newlib]") +{ + const float val = 1.23; + int len = printf("test printf float val is %1.2f\n", val); + TEST_ASSERT_EQUAL_INT(30, len); +} diff --git a/components/newlib/test_apps/newlib/main/test_stdatomic.c b/components/newlib/test_apps/newlib/main/test_stdatomic.c index b41d36ac5c..602dc45c03 100644 --- a/components/newlib/test_apps/newlib/main/test_stdatomic.c +++ b/components/newlib/test_apps/newlib/main/test_stdatomic.c @@ -218,104 +218,139 @@ TEST_EXCLUSION(8) #define ITER_COUNT 20000 -#define TEST_RACE_OPERATION(NAME, LHSTYPE, PRE, POST, INIT, FINAL) \ - \ -static _Atomic LHSTYPE var_##NAME = (INIT); \ - \ -static void *test_thread_##NAME (void *arg) \ -{ \ - for (int i = 0; i < ITER_COUNT; i++) \ - { \ - PRE var_##NAME POST; \ - } \ - return NULL; \ -} \ - \ -TEST_CASE("stdatomic - test_" #NAME, "[newlib_stdatomic]") \ -{ \ - pthread_t thread_id1; \ - pthread_t thread_id2; \ - esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); \ - cfg.pin_to_core = (xPortGetCoreID() + 1) % portNUM_PROCESSORS; \ - esp_pthread_set_cfg(&cfg); \ - pthread_create (&thread_id1, NULL, test_thread_##NAME, NULL); \ - cfg.pin_to_core = xPortGetCoreID(); \ - esp_pthread_set_cfg(&cfg); \ - pthread_create (&thread_id2, NULL, test_thread_##NAME, NULL); \ - pthread_join (thread_id1, NULL); \ - pthread_join (thread_id2, NULL); \ - TEST_ASSERT_EQUAL((FINAL), var_##NAME); \ +#define TEST_RACE_OPERATION(ASSERT_SUFFIX, NAME, LHSTYPE, PRE, POST, INIT, FINAL) \ + \ +static _Atomic LHSTYPE var_##NAME; \ + \ +static void *test_thread_##NAME (void *arg) \ +{ \ + for (int i = 0; i < ITER_COUNT; i++) \ + { \ + PRE var_##NAME POST; \ + } \ + return NULL; \ +} \ + \ +TEST_CASE("stdatomic - test_" #NAME, "[newlib_stdatomic]") \ +{ \ + pthread_t thread_id1; \ + pthread_t thread_id2; \ + var_##NAME = (INIT); \ + esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); \ + cfg.pin_to_core = (xPortGetCoreID() + 1) % portNUM_PROCESSORS; \ + esp_pthread_set_cfg(&cfg); \ + pthread_create (&thread_id1, NULL, test_thread_##NAME, NULL); \ + cfg.pin_to_core = xPortGetCoreID(); \ + esp_pthread_set_cfg(&cfg); \ + pthread_create (&thread_id2, NULL, test_thread_##NAME, NULL); \ + pthread_join (thread_id1, NULL); \ + pthread_join (thread_id2, NULL); \ + TEST_ASSERT_EQUAL##ASSERT_SUFFIX((FINAL), var_##NAME); \ +} + +// Note that the assert at the end is doing an excat bitwise comparison. +// This easily can fail due to rounding errors. However, there is currently +// no corresponding Unity assert macro for long double. USE THIS WITH CARE! +#define TEST_RACE_OPERATION_LONG_DOUBLE(NAME, LHSTYPE, PRE, POST, INIT, FINAL) \ + \ +static _Atomic LHSTYPE var_##NAME; \ + \ +static void *test_thread_##NAME (void *arg) \ +{ \ + for (int i = 0; i < ITER_COUNT; i++) \ + { \ + PRE var_##NAME POST; \ + } \ + return NULL; \ +} \ + \ +TEST_CASE("stdatomic - test_" #NAME, "[newlib_stdatomic]") \ +{ \ + pthread_t thread_id1; \ + pthread_t thread_id2; \ + var_##NAME = (INIT); \ + const LHSTYPE EXPECTED = (FINAL); \ + esp_pthread_cfg_t cfg = esp_pthread_get_default_config(); \ + cfg.pin_to_core = (xPortGetCoreID() + 1) % portNUM_PROCESSORS; \ + esp_pthread_set_cfg(&cfg); \ + pthread_create (&thread_id1, NULL, test_thread_##NAME, NULL); \ + cfg.pin_to_core = xPortGetCoreID(); \ + esp_pthread_set_cfg(&cfg); \ + pthread_create (&thread_id2, NULL, test_thread_##NAME, NULL); \ + pthread_join (thread_id1, NULL); \ + pthread_join (thread_id2, NULL); \ + TEST_ASSERT(EXPECTED == var_##NAME); \ } -TEST_RACE_OPERATION (uint8_add, uint8_t, , += 1, 0, (uint8_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint8_add_3, uint8_t, , += 3, 0, (uint8_t) (6*ITER_COUNT)) -TEST_RACE_OPERATION (uint8_postinc, uint8_t, , ++, 0, (uint8_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint8_preinc, uint8_t, ++, , 0, (uint8_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint8_sub, uint8_t, , -= 1, 0, (uint8_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint8_sub_3, uint8_t, , -= 3, 0, (uint8_t) -(6*ITER_COUNT)) -TEST_RACE_OPERATION (uint8_postdec, uint8_t, , --, 0, (uint8_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint8_predec, uint8_t, --, , 0, (uint8_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint8_mul, uint8_t, , *= 3, 1, (uint8_t) 0x1) - -TEST_RACE_OPERATION (uint16_add, uint16_t, , += 1, 0, (uint16_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint16_add_3, uint16_t, , += 3, 0, (uint16_t) (6*ITER_COUNT)) -TEST_RACE_OPERATION (uint16_postinc, uint16_t, , ++, 0, (uint16_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint16_preinc, uint16_t, ++, , 0, (uint16_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint16_sub, uint16_t, , -= 1, 0, (uint16_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint16_sub_3, uint16_t, , -= 3, 0, (uint16_t) -(6*ITER_COUNT)) -TEST_RACE_OPERATION (uint16_postdec, uint16_t, , --, 0, (uint16_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint16_predec, uint16_t, --, , 0, (uint16_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint16_mul, uint16_t, , *= 3, 1, (uint16_t) 0x6D01) - -TEST_RACE_OPERATION (uint32_add, uint32_t, , += 1, 0, (uint32_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint32_add_3, uint32_t, , += 3, 0, (uint32_t) (6*ITER_COUNT)) -TEST_RACE_OPERATION (uint32_postinc, uint32_t, , ++, 0, (uint32_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint32_preinc, uint32_t, ++, , 0, (uint32_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint32_sub, uint32_t, , -= 1, 0, (uint32_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint32_sub_3, uint32_t, , -= 3, 0, (uint32_t) -(6*ITER_COUNT)) -TEST_RACE_OPERATION (uint32_postdec, uint32_t, , --, 0, (uint32_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint32_predec, uint32_t, --, , 0, (uint32_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint32_mul, uint32_t, , *= 3, 1, (uint32_t) 0xC1E36D01U) - -TEST_RACE_OPERATION (uint64_add, uint64_t, , += 1, 0, (uint64_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint64_add_3, uint64_t, , += 3, 0, (uint64_t) (6*ITER_COUNT)) -TEST_RACE_OPERATION (uint64_add_neg, uint64_t, , += 1, -10000, (uint64_t) (2*ITER_COUNT-10000)) -TEST_RACE_OPERATION (uint64_postinc, uint64_t, , ++, 0, (uint64_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint64_postinc_neg, uint64_t, , ++, -10000, (uint64_t) (2*ITER_COUNT-10000)) -TEST_RACE_OPERATION (uint64_preinc, uint64_t, ++, , 0, (uint64_t) (2*ITER_COUNT)) -TEST_RACE_OPERATION (uint64_preinc_neg, uint64_t, ++, , -10000, (uint64_t) (2*ITER_COUNT-10000)) -TEST_RACE_OPERATION (uint64_sub, uint64_t, , -= 1, 0, (uint64_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint64_sub_3, uint64_t, , -= 3, 0, (uint64_t) -(6*ITER_COUNT)) -TEST_RACE_OPERATION (uint64_sub_neg, uint64_t, , -= 1, 10000, (uint64_t) ((-2*ITER_COUNT)+10000)) -TEST_RACE_OPERATION (uint64_postdec, uint64_t, , --, 0, (uint64_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint64_postdec_neg, uint64_t, , --, 10000, (uint64_t) ((-2*ITER_COUNT)+10000)) -TEST_RACE_OPERATION (uint64_predec, uint64_t, --, , 0, (uint64_t) -(2*ITER_COUNT)) -TEST_RACE_OPERATION (uint64_predec_neg, uint64_t, --, , 10000, (uint64_t) ((-2*ITER_COUNT)+10000)) -TEST_RACE_OPERATION (uint64_mul, uint64_t, , *= 3, 1, (uint64_t) 0x988EE974C1E36D01ULL) - -TEST_RACE_OPERATION (float_add, float, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (complex_float_add, _Complex float, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (float_postinc, float, , ++, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (float_preinc, float, ++, , 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (float_sub, float, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (complex_float_sub, _Complex float, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (float_postdec, float, , --, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (float_predec, float, --, , 0, -(2*ITER_COUNT)) - -TEST_RACE_OPERATION (double_add, double, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (complex_double_add, _Complex double, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (double_postinc, double, , ++, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (double_preinc, double, ++, , 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (double_sub, double, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (complex_double_sub, _Complex double, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (double_postdec, double, , --, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (double_predec, double, --, , 0, -(2*ITER_COUNT)) - -TEST_RACE_OPERATION (long_double_add, long double, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (complex_long_double_add, _Complex long double, , += 1, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (long_double_postinc, long double, , ++, 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (long_double_sub, long double, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (long_double_preinc, long double, ++, , 0, (2*ITER_COUNT)) -TEST_RACE_OPERATION (complex_long_double_sub, _Complex long double, , -= 1, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (long_double_postdec, long double, , --, 0, -(2*ITER_COUNT)) -TEST_RACE_OPERATION (long_double_predec, long double, --, , 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint8_add, uint8_t, , += 1, 0, (uint8_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint8_add_3, uint8_t, , += 3, 0, (uint8_t) (6*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint8_postinc, uint8_t, , ++, 0, (uint8_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint8_preinc, uint8_t, ++, , 0, (uint8_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint8_sub, uint8_t, , -= 1, 0, (uint8_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint8_sub_3, uint8_t, , -= 3, 0, (uint8_t) -(6*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint8_postdec, uint8_t, , --, 0, (uint8_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint8_predec, uint8_t, --, , 0, (uint8_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint8_mul, uint8_t, , *= 3, 1, (uint8_t) 0x1) + +TEST_RACE_OPERATION ( ,uint16_add, uint16_t, , += 1, 0, (uint16_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint16_add_3, uint16_t, , += 3, 0, (uint16_t) (6*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint16_postinc, uint16_t, , ++, 0, (uint16_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint16_preinc, uint16_t, ++, , 0, (uint16_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint16_sub, uint16_t, , -= 1, 0, (uint16_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint16_sub_3, uint16_t, , -= 3, 0, (uint16_t) -(6*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint16_postdec, uint16_t, , --, 0, (uint16_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint16_predec, uint16_t, --, , 0, (uint16_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint16_mul, uint16_t, , *= 3, 1, (uint16_t) 0x6D01) + +TEST_RACE_OPERATION ( ,uint32_add, uint32_t, , += 1, 0, (uint32_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint32_add_3, uint32_t, , += 3, 0, (uint32_t) (6*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint32_postinc, uint32_t, , ++, 0, (uint32_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint32_preinc, uint32_t, ++, , 0, (uint32_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint32_sub, uint32_t, , -= 1, 0, (uint32_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint32_sub_3, uint32_t, , -= 3, 0, (uint32_t) -(6*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint32_postdec, uint32_t, , --, 0, (uint32_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint32_predec, uint32_t, --, , 0, (uint32_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint32_mul, uint32_t, , *= 3, 1, (uint32_t) 0xC1E36D01U) + +TEST_RACE_OPERATION ( ,uint64_add, uint64_t, , += 1, 0, (uint64_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint64_add_3, uint64_t, , += 3, 0, (uint64_t) (6*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint64_add_neg, uint64_t, , += 1, -10000, (uint64_t) (2*ITER_COUNT-10000)) +TEST_RACE_OPERATION ( ,uint64_postinc, uint64_t, , ++, 0, (uint64_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint64_postinc_neg, uint64_t, , ++, -10000, (uint64_t) (2*ITER_COUNT-10000)) +TEST_RACE_OPERATION ( ,uint64_preinc, uint64_t, ++, , 0, (uint64_t) (2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint64_preinc_neg, uint64_t, ++, , -10000, (uint64_t) (2*ITER_COUNT-10000)) +TEST_RACE_OPERATION ( ,uint64_sub, uint64_t, , -= 1, 0, (uint64_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint64_sub_3, uint64_t, , -= 3, 0, (uint64_t) -(6*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint64_sub_neg, uint64_t, , -= 1, 10000, (uint64_t) ((-2*ITER_COUNT)+10000)) +TEST_RACE_OPERATION ( ,uint64_postdec, uint64_t, , --, 0, (uint64_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint64_postdec_neg, uint64_t, , --, 10000, (uint64_t) ((-2*ITER_COUNT)+10000)) +TEST_RACE_OPERATION ( ,uint64_predec, uint64_t, --, , 0, (uint64_t) -(2*ITER_COUNT)) +TEST_RACE_OPERATION ( ,uint64_predec_neg, uint64_t, --, , 10000, (uint64_t) ((-2*ITER_COUNT)+10000)) +TEST_RACE_OPERATION ( ,uint64_mul, uint64_t, , *= 3, 1, (uint64_t) 0x988EE974C1E36D01ULL) + +TEST_RACE_OPERATION (_FLOAT ,float_add, float, , += 1, 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION (_FLOAT ,complex_float_add, _Complex float, , += 1, 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION (_FLOAT ,float_postinc, float, , ++, 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION (_FLOAT ,float_preinc, float, ++, , 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION (_FLOAT ,float_sub, float, , -= 1, 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION (_FLOAT ,complex_float_sub, _Complex float, , -= 1, 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION (_FLOAT ,float_postdec, float, , --, 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION (_FLOAT ,float_predec, float, --, , 0, -(2*ITER_COUNT)) + +TEST_RACE_OPERATION (_DOUBLE ,double_add, double, , += 1, 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION (_DOUBLE ,complex_double_add, _Complex double, , += 1, 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION (_DOUBLE ,double_postinc, double, , ++, 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION (_DOUBLE ,double_preinc, double, ++, , 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION (_DOUBLE ,double_sub, double, , -= 1, 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION (_DOUBLE ,complex_double_sub, _Complex double, , -= 1, 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION (_DOUBLE ,double_postdec, double, , --, 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION (_DOUBLE ,double_predec, double, --, , 0, -(2*ITER_COUNT)) + +TEST_RACE_OPERATION_LONG_DOUBLE (long_double_add, long double, , += 1, 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE (complex_long_double_add, _Complex long double, , += 1, 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE (long_double_postinc, long double, , ++, 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE (long_double_sub, long double, , -= 1, 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE (long_double_preinc, long double, ++, , 0, (2*ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE (complex_long_double_sub, _Complex long double, , -= 1, 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE (long_double_postdec, long double, , --, 0, -(2*ITER_COUNT)) +TEST_RACE_OPERATION_LONG_DOUBLE (long_double_predec, long double, --, , 0, -(2*ITER_COUNT)) diff --git a/components/newlib/test_apps/newlib/pytest_newlib.py b/components/newlib/test_apps/newlib/pytest_newlib.py index 5fd6c062c5..78c01517d5 100644 --- a/components/newlib/test_apps/newlib/pytest_newlib.py +++ b/components/newlib/test_apps/newlib/pytest_newlib.py @@ -1,10 +1,35 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 +import subprocess +from os import path import pytest +import yaml from pytest_embedded import Dut +def validate_sbom(dut: Dut) -> None: + dirname = path.dirname(path.abspath(__file__)) + sbom_file = path.join(path.dirname(path.dirname(dirname)), 'sbom.yml') + gcc_input_file = path.join(dirname, 'test_sbom', 'newlib_version.c') + gcc = 'riscv32-esp-elf-gcc' + if dut.target in dut.XTENSA_TARGETS: + gcc = f'xtensa-{dut.target}-elf-gcc' + gcc_process = subprocess.run(f'{gcc} -E {gcc_input_file}', + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + check=True) + output_lines = gcc_process.stdout.splitlines() + assert output_lines, 'Can not get newlib version' + toolchain_newlib_version = output_lines[-1].replace(' ', '.') + with open(sbom_file, 'r', encoding='utf-8') as yaml_file: + sbom_newlib_version = yaml.safe_load(yaml_file).get('version') + assert sbom_newlib_version, 'Can not get newlib version from sbom.yml' + assert toolchain_newlib_version == sbom_newlib_version, 'toolchain_newlib_version != sbom_newlib_version' + + @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -19,4 +44,5 @@ indirect=True ) def test_newlib(dut: Dut) -> None: + validate_sbom(dut) dut.run_all_single_board_cases() diff --git a/components/newlib/test_apps/newlib/test_sbom/newlib_version.c b/components/newlib/test_apps/newlib/test_sbom/newlib_version.c new file mode 100644 index 0000000000..18c2290fbc --- /dev/null +++ b/components/newlib/test_apps/newlib/test_sbom/newlib_version.c @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include <_newlib_version.h> +__NEWLIB__ __NEWLIB_MINOR__ __NEWLIB_PATCHLEVEL__ diff --git a/components/riscv/include/riscv/csr.h b/components/riscv/include/riscv/csr.h index e5762c9e7e..17e1f723e3 100644 --- a/components/riscv/include/riscv/csr.h +++ b/components/riscv/include/riscv/csr.h @@ -140,10 +140,6 @@ extern "C" { Trigger Module register fields (Debug specification) ********************************************************/ -/* tcontrol CSRs not recognized by toolchain currently */ -#define CSR_TCONTROL 0x7a5 -#define CSR_TDATA1 0x7a1 - #define TCONTROL_MTE (1<<3) /*R/W, Current M mode trigger enable bit*/ #define TCONTROL_MPTE (1<<7) /*R/W, Previous M mode trigger enable bit*/ @@ -152,9 +148,11 @@ extern "C" { #define TDATA1_EXECUTE (1<<2) /*R/W,Fire trigger on instruction fetch address match*/ #define TDATA1_USER (1<<3) /*R/W,allow trigger to be fired in user mode*/ #define TDATA1_MACHINE (1<<6) /*R/W,Allow trigger to be fired while hart is executing in machine mode*/ -#define TDATA1_MATCH (1<<7) +#define TDATA1_MATCH_EXACT (0) +#define TDATA1_MATCH_NAPOT (1<<7) #define TDATA1_MATCH_V (0xF) /*R/W,Address match type :0 : Exact byte match 1 : NAPOT range match */ #define TDATA1_MATCH_S (7) +#define TDATA1_HIT_S (20) /* RISC-V CSR macros diff --git a/components/riscv/include/riscv/rv_utils.h b/components/riscv/include/riscv/rv_utils.h index 44f4b07e0c..b545edb137 100644 --- a/components/riscv/include/riscv/rv_utils.h +++ b/components/riscv/include/riscv/rv_utils.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 */ @@ -132,49 +132,68 @@ FORCE_INLINE_ATTR void rv_utils_set_breakpoint(int bp_num, uint32_t bp_addr) /* The code bellow sets breakpoint which will trigger `Breakpoint` exception * instead transfering control to debugger. */ RV_WRITE_CSR(tselect, bp_num); - RV_SET_CSR(CSR_TCONTROL, TCONTROL_MTE); - RV_SET_CSR(CSR_TDATA1, TDATA1_USER | TDATA1_MACHINE | TDATA1_EXECUTE); + RV_WRITE_CSR(tcontrol, TCONTROL_MPTE | TCONTROL_MTE); + RV_WRITE_CSR(tdata1, TDATA1_USER | TDATA1_MACHINE | TDATA1_EXECUTE); RV_WRITE_CSR(tdata2, bp_addr); } +FORCE_INLINE_ATTR void rv_utils_set_watchpoint(int wp_num, + uint32_t wp_addr, + size_t size, + bool on_read, + bool on_write) +{ + RV_WRITE_CSR(tselect, wp_num); + RV_WRITE_CSR(tcontrol, TCONTROL_MPTE | TCONTROL_MTE); + RV_WRITE_CSR(tdata1, TDATA1_USER | + TDATA1_MACHINE | + ((size == 1) ? TDATA1_MATCH_EXACT : TDATA1_MATCH_NAPOT) | + (on_read ? TDATA1_LOAD : 0) | + (on_write ? TDATA1_STORE : 0)); + /* From RISC-V Debug Specification: + * tdata1(mcontrol) match = 0 : Exact byte match + * + * tdata1(mcontrol) match = 1 : NAPOT (Naturally Aligned Power-Of-Two): + * Matches when the top M bits of any compare value match the top M bits of tdata2. + * M is XLEN − 1 minus the index of the least-significant bit containing 0 in tdata2. + * Note: Expecting that size is number power of 2 (numbers should be in the range of 1 ~ 31) + * + * Examples for understanding how to calculate match pattern to tdata2: + * + * nnnn...nnnnn 1-byte Exact byte match + * nnnn...nnnn0 2-byte NAPOT range + * nnnn...nnn01 4-byte NAPOT range + * nnnn...nn011 8-byte NAPOT range + * nnnn...n0111 16-byte NAPOT range + * nnnn...01111 32-byte NAPOT range + * ... + * n011...11111 2^31 byte NAPOT range + * * where n are bits from original address + */ + uint32_t match_pattern = (wp_addr & ~(size-1)) | ((size-1) >> 1); + + RV_WRITE_CSR(tdata2, match_pattern); +} + FORCE_INLINE_ATTR void rv_utils_clear_breakpoint(int bp_num) { RV_WRITE_CSR(tselect, bp_num); - RV_CLEAR_CSR(CSR_TCONTROL, TCONTROL_MTE); - RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER | TDATA1_MACHINE | TDATA1_EXECUTE); + /* tdata1 is a WARL(write any read legal) register + * We can just write 0 to it + */ + RV_WRITE_CSR(tdata1, 0); } -FORCE_INLINE_ATTR void rv_utils_set_watchpoint(int wp_num, - uint32_t wp_addr, - size_t size, - bool on_read, - bool on_write) +FORCE_INLINE_ATTR void rv_utils_clear_watchpoint(int wp_num) { - RV_WRITE_CSR(tselect, wp_num); - RV_SET_CSR(CSR_TCONTROL, TCONTROL_MPTE | TCONTROL_MTE); - RV_SET_CSR(CSR_TDATA1, TDATA1_USER | TDATA1_MACHINE); - RV_SET_CSR_FIELD(CSR_TDATA1, (long unsigned int) TDATA1_MATCH, 1); - - // add 0 in napot encoding - uint32_t addr_napot; - addr_napot = ((uint32_t) wp_addr) | ((size >> 1) - 1); - if (on_read) { - RV_SET_CSR(CSR_TDATA1, TDATA1_LOAD); - } - if (on_write) { - RV_SET_CSR(CSR_TDATA1, TDATA1_STORE); - } - RV_WRITE_CSR(tdata2, addr_napot); + /* riscv have the same registers for breakpoints and watchpoints */ + rv_utils_clear_breakpoint(wp_num); } -FORCE_INLINE_ATTR void rv_utils_clear_watchpoint(int wp_num) +FORCE_INLINE_ATTR bool rv_utils_is_trigger_fired(int id) { - RV_WRITE_CSR(tselect, wp_num); - RV_CLEAR_CSR(CSR_TCONTROL, TCONTROL_MTE); - RV_CLEAR_CSR(CSR_TDATA1, TDATA1_USER | TDATA1_MACHINE); - RV_CLEAR_CSR_FIELD(CSR_TDATA1, (long unsigned int) TDATA1_MATCH); - RV_CLEAR_CSR(CSR_TDATA1, TDATA1_MACHINE); - RV_CLEAR_CSR(CSR_TDATA1, TDATA1_LOAD | TDATA1_STORE | TDATA1_EXECUTE); + RV_WRITE_CSR(tselect, id); + return (RV_READ_CSR(tdata1) >> TDATA1_HIT_S) & 1; } // ---------------------- Debugger ------------------------- diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index 1222669e63..46212a3229 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -101,7 +101,7 @@ endif() if(CONFIG_SOC_USB_OTG_SUPPORTED) list(APPEND srcs "${target}/usb_periph.c" - "${target}/usb_otg_periph.c") + "${target}/usb_dwc_periph.c") endif() if(CONFIG_SOC_DAC_SUPPORTED) @@ -125,8 +125,6 @@ idf_component_register(SRCS ${srcs} # Replace this value in an adaptive way, if Kconfig isn't available on your platform target_compile_definitions(${COMPONENT_LIB} INTERFACE SOC_MMU_PAGE_SIZE=CONFIG_MMU_PAGE_SIZE) -target_compile_definitions(${COMPONENT_LIB} INTERFACE SOC_XTAL_FREQ_MHZ=CONFIG_XTAL_FREQ) - if(target STREQUAL "esp32") # esp_dport_access_reg_read is added as an undefined symbol because otherwise # the linker can ignore dport_access.c as it would no other files depending on any symbols in it. diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index be2c009449..a2c5772ee6 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -231,6 +231,10 @@ config SOC_SHARED_IDCACHE_SUPPORTED bool default y +config SOC_IDCACHE_PER_CORE + bool + default y + config SOC_CPU_CORES_NUM int default 2 @@ -251,7 +255,7 @@ config SOC_CPU_WATCHPOINTS_NUM int default 2 -config SOC_CPU_WATCHPOINT_SIZE +config SOC_CPU_WATCHPOINT_MAX_REGION_SIZE int default 64 @@ -854,3 +858,7 @@ config SOC_BLUFI_SUPPORTED config SOC_ULP_HAS_ADC bool default y + +config SOC_PHY_COMBO_MODULE + bool + default y diff --git a/components/soc/esp32/include/soc/dport_reg.h b/components/soc/esp32/include/soc/dport_reg.h index 3091138c39..74b87421df 100644 --- a/components/soc/esp32/include/soc/dport_reg.h +++ b/components/soc/esp32/include/soc/dport_reg.h @@ -1077,8 +1077,10 @@ #define DPORT_RW_BTMAC_RST BIT(9) #define DPORT_RW_BTLP_RST BIT(10) +//ESP32 should not reset FE in esp_wifi_bt_power_domain_on(). +//The FE of ESP32 is not in the WIFI PD power domain. +//When turning off WIFI PD, the FE will not power down, so phy_wakeup_init() did not rewrite the FE register. #define MODEM_RESET_FIELD_WHEN_PU (DPORT_WIFIBB_RST | \ - DPORT_FE_RST | \ DPORT_WIFIMAC_RST | \ DPORT_BTBB_RST | \ DPORT_BTMAC_RST | \ diff --git a/components/soc/esp32/include/soc/soc.h b/components/soc/esp32/include/soc/soc.h index 7a3036c421..8783554d5b 100644 --- a/components/soc/esp32/include/soc/soc.h +++ b/components/soc/esp32/include/soc/soc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -159,7 +159,6 @@ #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 //this may be incorrect, please refer to ESP_DEFAULT_CPU_FREQ_MHZ #define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz -#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) #define UART_CLK_FREQ APB_CLK_FREQ #define WDT_CLK_FREQ APB_CLK_FREQ @@ -177,7 +176,7 @@ #define SOC_IROM_LOW 0x400D0000 #define SOC_IROM_HIGH 0x40400000 #define SOC_IROM_MASK_LOW 0x40000000 -#define SOC_IROM_MASK_HIGH 0x40064F00 +#define SOC_IROM_MASK_HIGH 0x40070000 #define SOC_CACHE_PRO_LOW 0x40070000 #define SOC_CACHE_PRO_HIGH 0x40078000 #define SOC_CACHE_APP_LOW 0x40078000 @@ -291,51 +290,13 @@ #define ETS_CACHE_IA_INTR_SOURCE 68/**< interrupt of Cache Invalied Access, LEVEL*/ #define ETS_MAX_INTR_SOURCE 69/**< total number of interrupt sources*/ -#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 -//interrupt cpu using table, Please see the core-isa.h -/************************************************************************************************************* - * Intr num Level Type PRO CPU usage APP CPU uasge - * 0 1 extern level WMAC Reserved - * 1 1 extern level BT/BLE Host HCI DMA BT/BLE Host HCI DMA - * 2 1 extern level - * 3 1 extern level - * 4 1 extern level WBB - * 5 1 extern level - * 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1) - * 7 1 software BT/BLE VHCI BT/BLE VHCI - * 8 1 extern level BT/BLE BB(RX/TX) BT/BLE BB(RX/TX) - * 9 1 extern level - * 10 1 extern edge - * 11 3 profiling - * 12 1 extern level - * 13 1 extern level - * 14 7 nmi Reserved Reserved - * 15 3 timer FreeRTOS Tick(L3) FreeRTOS Tick(L3) - * 16 5 timer Reserved Reserved - * 17 1 extern level - * 18 1 extern level - * 19 2 extern level - * 20 2 extern level - * 21 2 extern level - * 22 3 extern edge - * 23 3 extern level - * 24 4 extern level - * 25 4 extern level BT/BLE Controller BT/BLE Controller - * 26 5 extern level TG1_WDT & CACHEERR - * 27 3 extern level Reserved Reserved - * 28 4 extern edge - * 29 3 software BT/BLE hli BT/BLE hli - * 30 4 extern edge Reserved Reserved - * 31 5 extern level IPC_ISR IPC_ISR - ************************************************************************************************************* - */ - //CPU0 Interrupt number reserved, not touch this. #define ETS_WMAC_INUM 0 #define ETS_BT_HOST_INUM 1 #define ETS_WBB_INUM 4 -#define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/ -#define ETS_FRC1_INUM 22 + +#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 + #define ETS_T1_WDT_CACHEERR_INUM 26 #define ETS_T1_WDT_INUM ETS_T1_WDT_CACHEERR_INUM #define ETS_MEMACCESS_ERR_INUM ETS_T1_WDT_CACHEERR_INUM @@ -345,50 +306,6 @@ #elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4 -//interrupt cpu using table, Please see the core-isa.h -/************************************************************************************************************* - * Intr num Level Type PRO CPU usage APP CPU uasge - * 0 1 extern level WMAC Reserved - * 1 1 extern level BT/BLE Host HCI DMA BT/BLE Host HCI DMA - * 2 1 extern level - * 3 1 extern level - * 4 1 extern level WBB - * 5 1 extern level BT/BLE Controller BT/BLE Controller - * 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1) - * 7 1 software BT/BLE VHCI BT/BLE VHCI - * 8 1 extern level BT/BLE BB(RX/TX) BT/BLE BB(RX/TX) - * 9 1 extern level - * 10 1 extern edge - * 11 3 profiling - * 12 1 extern level - * 13 1 extern level - * 14 7 nmi Reserved Reserved - * 15 3 timer FreeRTOS Tick(L3) FreeRTOS Tick(L3) - * 16 5 timer - * 17 1 extern level - * 18 1 extern level - * 19 2 extern level - * 20 2 extern level - * 21 2 extern level - * 22 3 extern edge - * 23 3 extern level - * 24 4 extern level TG1_WDT - * 25 4 extern level CACHEERR - * 26 5 extern level - * 27 3 extern level Reserved Reserved - * 28 4 extern edge IPC_ISR IPC_ISR - * 29 3 software Reserved Reserved - * 30 4 extern edge Reserved Reserved - * 31 5 extern level - ************************************************************************************************************* - */ - -//CPU0 Interrupt number reserved, not touch this. -#define ETS_WMAC_INUM 0 -#define ETS_BT_HOST_INUM 1 -#define ETS_WBB_INUM 4 -#define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/ -#define ETS_FRC1_INUM 22 #define ETS_T1_WDT_INUM 24 #define ETS_MEMACCESS_ERR_INUM 25 /* backwards compatibility only, use ETS_MEMACCESS_ERR_INUM instead*/ diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index 70dadda226..6f3aec51fa 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -1,6 +1,6 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -138,16 +138,17 @@ #endif /*-------------------------- CACHE CAPS --------------------------------------*/ -#define SOC_SHARED_IDCACHE_SUPPORTED 1 //Shared Cache for both instructions and data +#define SOC_SHARED_IDCACHE_SUPPORTED 1 //Shared Cache for both instructions and data within one core +#define SOC_IDCACHE_PER_CORE 1 //Independent Cache unit pre core /*-------------------------- CPU CAPS ----------------------------------------*/ #define SOC_CPU_CORES_NUM 2 #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FPU 1 -#define SOC_CPU_BREAKPOINTS_NUM 2 -#define SOC_CPU_WATCHPOINTS_NUM 2 -#define SOC_CPU_WATCHPOINT_SIZE 64 // bytes +#define SOC_CPU_BREAKPOINTS_NUM 2 +#define SOC_CPU_WATCHPOINTS_NUM 2 +#define SOC_CPU_WATCHPOINT_MAX_REGION_SIZE 64 // bytes /*-------------------------- DAC CAPS ----------------------------------------*/ #define SOC_DAC_CHAN_NUM 2 @@ -419,3 +420,6 @@ /*-------------------------- ULP CAPS ----------------------------------------*/ #define SOC_ULP_HAS_ADC (1) /* ADC can be accessed from ULP */ + +/*------------------------------------- PHY CAPS -------------------------------------*/ +#define SOC_PHY_COMBO_MODULE (1) /*!< Support Wi-Fi, BT and BLE*/ diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index 84ec111f15..231e4b17a1 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -195,7 +195,7 @@ config SOC_CPU_WATCHPOINTS_NUM int default 2 -config SOC_CPU_WATCHPOINT_SIZE +config SOC_CPU_WATCHPOINT_MAX_REGION_SIZE hex default 0x80000000 @@ -511,6 +511,10 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS int default 1 +config SOC_MWDT_SUPPORT_XTAL + bool + default y + config SOC_EFUSE_DIS_DOWNLOAD_ICACHE bool default y @@ -561,7 +565,7 @@ config SOC_UART_FIFO_LEN config SOC_UART_BITRATE_MAX int - default 5000000 + default 2500000 config SOC_UART_SUPPORT_WAKEUP_INT bool @@ -583,6 +587,10 @@ config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND bool default y +config SOC_SUPPORT_COEXISTENCE + bool + default y + config SOC_COEX_HW_PTI bool default y @@ -647,6 +655,10 @@ config SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW bool default y +config SOC_WIFI_PHY_NEEDS_USB_WORKAROUND + bool + default y + config SOC_BLE_SUPPORTED bool default y @@ -671,6 +683,14 @@ config SOC_BLUFI_SUPPORTED bool default y +config SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED + bool + default y + config SOC_PHY_IMPROVE_RX_11B bool default y + +config SOC_PHY_COMBO_MODULE + bool + default y diff --git a/components/soc/esp32c2/include/soc/clk_tree_defs.h b/components/soc/esp32c2/include/soc/clk_tree_defs.h index 4aaf76d103..b95a68cdca 100644 --- a/components/soc/esp32c2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c2/include/soc/clk_tree_defs.h @@ -185,9 +185,6 @@ typedef enum { UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F40M, /*!< UART source clock default choice is PLL_F40M */ } soc_periph_uart_clk_src_legacy_t; -/////////////////////////////////////////////////I2C//////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////SPI//////////////////////////////////////////////////////////////////// /** @@ -204,6 +201,8 @@ typedef enum { SPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */ } soc_periph_spi_clk_src_t; +/////////////////////////////////////////////////I2C//////////////////////////////////////////////////////////////////// + /** * @brief Array initializer for all supported clock sources of I2C */ diff --git a/components/soc/esp32c2/include/soc/regi2c_defs.h b/components/soc/esp32c2/include/soc/regi2c_defs.h index 715a62271b..99d0e2b5f9 100644 --- a/components/soc/esp32c2/include/soc/regi2c_defs.h +++ b/components/soc/esp32c2/include/soc/regi2c_defs.h @@ -30,7 +30,7 @@ /** * Restore regi2c analog calibration related configuration registers. - * This is a workaround, and is fixed on later chips + * This is a workaround for calibration error when waking up from light sleep */ #define REGI2C_ANA_CALI_PD_WORKAROUND 1 #define REGI2C_ANA_CALI_BYTE_NUM 8 diff --git a/components/soc/esp32c2/include/soc/soc.h b/components/soc/esp32c2/include/soc/soc.h index bc7a3ba69c..4c2ca8b91e 100644 --- a/components/soc/esp32c2/include/soc/soc.h +++ b/components/soc/esp32c2/include/soc/soc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,6 +31,7 @@ #define UART_FIFO_AHB_REG(i) (REG_UART_AHB_BASE(i) + 0x0) #define REG_TIMG_BASE(i) (DR_REG_TIMERGROUP0_BASE + (i)*0x1000) #define REG_SPI_MEM_BASE(i) (DR_REG_SPI0_BASE - (i) * 0x1000) +#define REG_SPI_BASE(i) (((i)==2) ? (DR_REG_SPI2_BASE) : (0)) // only one GPSPI #define REG_I2C_BASE(i) (DR_REG_I2C_EXT_BASE + (i) * 0x14000 ) //Registers Operation {{ @@ -146,7 +147,7 @@ #define EFUSE_CLK_FREQ_ROM ( 20*1000000) #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 ( CONFIG_XTAL_FREQ * 1000000 ) +#define APB_CLK_FREQ ( 40*1000000 ) #define SCLK_CLK_FREQ ( 60*1000000 ) #define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index fa2765c6e1..e1aa1e2509 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.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 */ @@ -92,9 +92,9 @@ #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FLEXIBLE_INTC 1 -#define SOC_CPU_BREAKPOINTS_NUM 2 -#define SOC_CPU_WATCHPOINTS_NUM 2 -#define SOC_CPU_WATCHPOINT_SIZE 0x80000000 // bytes +#define SOC_CPU_BREAKPOINTS_NUM 2 +#define SOC_CPU_WATCHPOINTS_NUM 2 +#define SOC_CPU_WATCHPOINT_MAX_REGION_SIZE 0x80000000 // bytes #define SOC_CPU_IDRAM_SPLIT_USING_PMP 1 @@ -246,6 +246,9 @@ #define SOC_TIMER_GROUP_SUPPORT_XTAL (1) #define SOC_TIMER_GROUP_TOTAL_TIMERS (1U) +/*--------------------------- WATCHDOG CAPS ---------------------------------------*/ +#define SOC_MWDT_SUPPORT_XTAL (1) + /*-------------------------- eFuse CAPS----------------------------*/ #define SOC_EFUSE_DIS_DOWNLOAD_ICACHE 1 #define SOC_EFUSE_DIS_PAD_JTAG 1 @@ -267,7 +270,7 @@ #define SOC_UART_NUM (2) #define SOC_UART_HP_NUM (2) #define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ -#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ +#define SOC_UART_BITRATE_MAX (2500000) /*!< Max bit rate supported by UART */ #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ #define SOC_UART_SUPPORT_PLL_F40M_CLK (1) /*!< Support APB as the clock source */ #define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ @@ -276,6 +279,9 @@ // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) +/*-------------------------- COEXISTENCE CAPS -------------------------------*/ +#define SOC_SUPPORT_COEXISTENCE (1) + /*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/ #define SOC_COEX_HW_PTI (1) @@ -306,6 +312,7 @@ #define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */ #define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */ #define SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW (1) /*!< Support delta early time for rf phy on/off */ +#define SOC_WIFI_PHY_NEEDS_USB_WORKAROUND (1) /*!< SoC has WiFi and USB PHYs interference, needs a workaround */ /*---------------------------------- Bluetooth CAPS ----------------------------------*/ #define SOC_BLE_SUPPORTED (1) /*!< Support Bluetooth Low Energy hardware */ @@ -314,6 +321,8 @@ #define SOC_BLE_50_SUPPORTED (1) /*!< Support Bluetooth 5.0 */ #define SOC_BLE_DEVICE_PRIVACY_SUPPORTED (1) /*!< Support BLE device privacy mode */ #define SOC_BLUFI_SUPPORTED (1) /*!< Support BLUFI */ +#define SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED (1) /*!< Support For BLE Periodic Adv Enhancements */ /*------------------------------------- PHY CAPS -------------------------------------*/ #define SOC_PHY_IMPROVE_RX_11B (1) +#define SOC_PHY_COMBO_MODULE (1) /*!< Support Wi-Fi and BLE*/ diff --git a/components/soc/esp32c2/include/soc/spi_reg.h b/components/soc/esp32c2/include/soc/spi_reg.h index 24fa77c80e..eaa92535e1 100644 --- a/components/soc/esp32c2/include/soc/spi_reg.h +++ b/components/soc/esp32c2/include/soc/spi_reg.h @@ -6,12 +6,11 @@ #ifndef _SOC_SPI_REG_H_ #define _SOC_SPI_REG_H_ +#include "soc/soc.h" #ifdef __cplusplus extern "C" { #endif -#include "soc/soc.h" -#define REG_SPI_BASE(i) (DR_REG_SPI2_BASE + (i - 2) * 0x1000) #define SPI_CMD_REG(i) (REG_SPI_BASE(i) + 0x0) /* SPI_USR : R/W/SC ;bitpos:[24] ;default: 1'b0 ; */ diff --git a/components/soc/esp32c2/ld/esp32c2.peripherals.ld b/components/soc/esp32c2/ld/esp32c2.peripherals.ld index 11dc633490..3484877eea 100644 --- a/components/soc/esp32c2/ld/esp32c2.peripherals.ld +++ b/components/soc/esp32c2/ld/esp32c2.peripherals.ld @@ -16,7 +16,7 @@ PROVIDE ( LEDC = 0x60019000 ); PROVIDE ( TIMERG0 = 0x6001F000 ); PROVIDE ( SYSTIMER = 0x60023000 ); PROVIDE ( GPSPI2 = 0x60024000 ); -PROVIDE ( GPSPI3 = 0x60025000 ); PROVIDE ( SYSCON = 0x60026000 ); PROVIDE ( APB_SARADC = 0x60040000 ); PROVIDE ( GDMA = 0x6003F000 ); +PROVIDE ( SYSTEM = 0x600C0000 ); diff --git a/components/soc/esp32c2/spi_periph.c b/components/soc/esp32c2/spi_periph.c index ce1c5c9af9..b2f7e416b2 100644 --- a/components/soc/esp32c2/spi_periph.c +++ b/components/soc/esp32c2/spi_periph.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 */ @@ -12,29 +12,30 @@ */ const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = { { - .spiclk_out = SPICLK_OUT_MUX_IDX, - .spiclk_in = 0,/* SPI clock is not an input signal*/ - .spid_out = SPID_OUT_IDX, - .spiq_out = SPIQ_OUT_IDX, - .spiwp_out = SPIWP_OUT_IDX, - .spihd_out = SPIHD_OUT_IDX, - .spid_in = SPID_IN_IDX, - .spiq_in = SPIQ_IN_IDX, - .spiwp_in = SPIWP_IN_IDX, - .spihd_in = SPIHD_IN_IDX, - .spics_out = {SPICS0_OUT_IDX, SPICS1_OUT_IDX},/* SPI0/1 do not have CS2 now */ - .spics_in = 0,/* SPI cs is not an input signal*/ - .spiclk_iomux_pin = SPI_IOMUX_PIN_NUM_CLK, - .spid_iomux_pin = SPI_IOMUX_PIN_NUM_MOSI, - .spiq_iomux_pin = SPI_IOMUX_PIN_NUM_MISO, - .spiwp_iomux_pin = SPI_IOMUX_PIN_NUM_WP, - .spihd_iomux_pin = SPI_IOMUX_PIN_NUM_HD, - .spics0_iomux_pin = SPI_IOMUX_PIN_NUM_CS, - .irq = ETS_SPI1_INTR_SOURCE, + // MSPI has dedicated iomux pins + .spiclk_out = -1, + .spiclk_in = -1, + .spid_out = -1, + .spiq_out = -1, + .spiwp_out = -1, + .spihd_out = -1, + .spid_in = -1, + .spiq_in = -1, + .spiwp_in = -1, + .spihd_in = -1, + .spics_out = {-1}, + .spics_in = -1, + .spiclk_iomux_pin = -1, + .spid_iomux_pin = -1, + .spiq_iomux_pin = -1, + .spiwp_iomux_pin = -1, + .spihd_iomux_pin = -1, + .spics0_iomux_pin = -1, + .irq = -1, .irq_dma = -1, - .module = PERIPH_SPI_MODULE, - .hw = (spi_dev_t *) &SPIMEM1, - .func = SPI_FUNC_NUM, + .module = -1, + .hw = NULL, + .func = -1, }, { .spiclk_out = FSPICLK_OUT_IDX, .spiclk_in = FSPICLK_IN_IDX, diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 3769837782..563713eb84 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -283,7 +283,7 @@ config SOC_CPU_WATCHPOINTS_NUM int default 8 -config SOC_CPU_WATCHPOINT_SIZE +config SOC_CPU_WATCHPOINT_MAX_REGION_SIZE hex default 0x80000000 @@ -531,6 +531,14 @@ config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM int default 108 +config SOC_SLEEP_SYSTIMER_STALL_WORKAROUND + bool + default y + +config SOC_SLEEP_TGWDT_STOP_WORKAROUND + bool + default y + config SOC_RTCIO_PIN_COUNT int default 0 @@ -731,6 +739,10 @@ config SOC_TIMER_GROUP_TOTAL_TIMERS int default 2 +config SOC_MWDT_SUPPORT_XTAL + bool + default y + config SOC_TWAI_CONTROLLER_NUM int default 1 @@ -967,6 +979,10 @@ config SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW bool default y +config SOC_WIFI_PHY_NEEDS_USB_WORKAROUND + bool + default y + config SOC_BLE_SUPPORTED bool default y @@ -986,3 +1002,7 @@ config SOC_BLE_DEVICE_PRIVACY_SUPPORTED config SOC_BLUFI_SUPPORTED bool default y + +config SOC_PHY_COMBO_MODULE + bool + default y diff --git a/components/soc/esp32c3/include/soc/clk_tree_defs.h b/components/soc/esp32c3/include/soc/clk_tree_defs.h index 894c872a83..88b11c71d7 100644 --- a/components/soc/esp32c3/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c3/include/soc/clk_tree_defs.h @@ -334,7 +334,7 @@ typedef enum { typedef enum { MWDT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ MWDT_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */ - MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */ + MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select APB as the default clock choice */ } soc_periph_mwdt_clk_src_t; //////////////////////////////////////////////////LEDC///////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32c3/include/soc/reg_base.h b/components/soc/esp32c3/include/soc/reg_base.h index d8980124e8..992cbd6ce6 100644 --- a/components/soc/esp32c3/include/soc/reg_base.h +++ b/components/soc/esp32c3/include/soc/reg_base.h @@ -41,7 +41,7 @@ #define DR_REG_SYSCON_BASE 0x60026000 #define DR_REG_APB_CTRL_BASE 0x60026000 /* Old name for SYSCON, to be removed */ #define DR_REG_TWAI_BASE 0x6002B000 -#define DR_REG_I2S0_BASE 0x6002D000 +#define DR_REG_I2S_BASE 0x6002D000 #define DR_REG_APB_SARADC_BASE 0x60040000 #define DR_REG_USB_SERIAL_JTAG_BASE 0x60043000 #define DR_REG_AES_XTS_BASE 0x600CC000 diff --git a/components/soc/esp32c3/include/soc/regi2c_defs.h b/components/soc/esp32c3/include/soc/regi2c_defs.h index 80170d6d71..142851b6f9 100644 --- a/components/soc/esp32c3/include/soc/regi2c_defs.h +++ b/components/soc/esp32c3/include/soc/regi2c_defs.h @@ -28,7 +28,7 @@ /** * Restore regi2c analog calibration related configuration registers. - * This is a workaround, and is fixed on later chips + * This is a workaround for calibration error when waking up from light sleep */ #define REGI2C_ANA_CALI_PD_WORKAROUND 1 #define REGI2C_ANA_CALI_BYTE_NUM 8 diff --git a/components/soc/esp32c3/include/soc/rtc.h b/components/soc/esp32c3/include/soc/rtc.h index 1a3e34b376..b9b977612c 100644 --- a/components/soc/esp32c3/include/soc/rtc.h +++ b/components/soc/esp32c3/include/soc/rtc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -650,18 +650,6 @@ void rtc_sleep_init(rtc_sleep_config_t cfg); */ void rtc_sleep_low_init(uint32_t slowclk_period); -#if CONFIG_ESP_SLEEP_SYSTIMER_STALL_WORKAROUND -/** - * @brief Configure systimer for esp32c3 systimer stall issue workaround - * - * This function configures related systimer for esp32c3 systimer stall issue. - * Only apply workaround when xtal powered up. - * - * @param en enable systimer or not - */ -void rtc_sleep_systimer_enable(bool en); -#endif - #define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup #define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup #define RTC_WIFI_TRIG_EN BIT(5) //!< WIFI wakeup (light sleep only) diff --git a/components/soc/esp32c3/include/soc/soc.h b/components/soc/esp32c3/include/soc/soc.h index 9d7e21714d..5e40d69d17 100644 --- a/components/soc/esp32c3/include/soc/soc.h +++ b/components/soc/esp32c3/include/soc/soc.h @@ -20,9 +20,10 @@ #define REG_UART_BASE(i) (DR_REG_UART_BASE + (i) * 0x10000) #define REG_UART_AHB_BASE(i) (0x60000000 + (i) * 0x10000) #define UART_FIFO_AHB_REG(i) (REG_UART_AHB_BASE(i) + 0x0) -#define REG_I2S_BASE(i) (DR_REG_I2S_BASE + (i) * 0x1E000) +#define REG_I2S_BASE(i) (DR_REG_I2S_BASE) // only one I2S on C3 #define REG_TIMG_BASE(i) (DR_REG_TIMERGROUP0_BASE + (i)*0x1000) #define REG_SPI_MEM_BASE(i) (DR_REG_SPI0_BASE - (i) * 0x1000) +#define REG_SPI_BASE(i) (((i)==2) ? (DR_REG_SPI2_BASE) : (0)) // only one GPSPI #define REG_I2C_BASE(i) (DR_REG_I2C_EXT_BASE + (i) * 0x14000 ) //Registers Operation {{ @@ -139,7 +140,6 @@ #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 ( 80*1000000 ) -#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) #define XTAL_CLK_FREQ (40*1000000) #define UART_CLK_FREQ APB_CLK_FREQ diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index c4e6199ba3..e5ba69cc09 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.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 */ @@ -124,9 +124,9 @@ #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FLEXIBLE_INTC 1 -#define SOC_CPU_BREAKPOINTS_NUM 8 -#define SOC_CPU_WATCHPOINTS_NUM 8 -#define SOC_CPU_WATCHPOINT_SIZE 0x80000000 // bytes +#define SOC_CPU_BREAKPOINTS_NUM 8 +#define SOC_CPU_WATCHPOINTS_NUM 8 +#define SOC_CPU_WATCHPOINT_MAX_REGION_SIZE 0x80000000 // bytes /*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/ /** The maximum length of a Digital Signature in bits. */ @@ -237,6 +237,9 @@ #define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3)) +#define SOC_SLEEP_SYSTIMER_STALL_WORKAROUND 1 +#define SOC_SLEEP_TGWDT_STOP_WORKAROUND 1 + /*-------------------------- RTCIO CAPS --------------------------------------*/ /* No dedicated RTCIO subsystem on ESP32-C3. RTC functions are still supported * for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */ @@ -327,6 +330,9 @@ #define SOC_TIMER_GROUP_SUPPORT_APB (1) #define SOC_TIMER_GROUP_TOTAL_TIMERS (2) +/*--------------------------- WATCHDOG CAPS ---------------------------------------*/ +#define SOC_MWDT_SUPPORT_XTAL (1) + /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 1UL #define SOC_TWAI_CLK_SUPPORT_APB 1 @@ -420,6 +426,7 @@ #define SOC_WIFI_CSI_SUPPORT (1) /*!< Support CSI */ #define SOC_WIFI_MESH_SUPPORT (1) /*!< Support WIFI MESH */ #define SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW (1) /*!< Support delta early time for rf phy on/off */ +#define SOC_WIFI_PHY_NEEDS_USB_WORKAROUND (1) /*!< SoC has WiFi and USB PHYs interference, needs a workaround */ /*---------------------------------- Bluetooth CAPS ----------------------------------*/ #define SOC_BLE_SUPPORTED (1) /*!< Support Bluetooth Low Energy hardware */ @@ -427,3 +434,6 @@ #define SOC_BLE_50_SUPPORTED (1) /*!< Support Bluetooth 5.0 */ #define SOC_BLE_DEVICE_PRIVACY_SUPPORTED (1) /*!< Support BLE device privacy mode */ #define SOC_BLUFI_SUPPORTED (1) /*!< Support BLUFI */ + +/*------------------------------------- PHY CAPS -------------------------------------*/ +#define SOC_PHY_COMBO_MODULE (1) /*!< Support Wi-Fi and BLE*/ diff --git a/components/soc/esp32c3/include/soc/spi_reg.h b/components/soc/esp32c3/include/soc/spi_reg.h index a08cb24f3c..361f58ba5c 100644 --- a/components/soc/esp32c3/include/soc/spi_reg.h +++ b/components/soc/esp32c3/include/soc/spi_reg.h @@ -1,24 +1,16 @@ -// 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_SPI_REG_H_ #define _SOC_SPI_REG_H_ +#include "soc.h" #ifdef __cplusplus extern "C" { #endif -#include "soc.h" #define SPI_CMD_REG(i) (REG_SPI_BASE(i) + 0x0) /* SPI_USR : R/W/SC ;bitpos:[24] ;default: 1'b0 ; */ diff --git a/components/soc/esp32c3/ld/esp32c3.peripherals.ld b/components/soc/esp32c3/ld/esp32c3.peripherals.ld index ea6e2ac419..12b81a44a8 100644 --- a/components/soc/esp32c3/ld/esp32c3.peripherals.ld +++ b/components/soc/esp32c3/ld/esp32c3.peripherals.ld @@ -26,10 +26,9 @@ PROVIDE ( TIMERG0 = 0x6001F000 ); PROVIDE ( TIMERG1 = 0x60020000 ); PROVIDE ( SYSTIMER = 0x60023000 ); PROVIDE ( GPSPI2 = 0x60024000 ); -PROVIDE ( GPSPI3 = 0x60025000 ); PROVIDE ( SYSCON = 0x60026000 ); PROVIDE ( TWAI = 0x6002B000 ); -PROVIDE ( GPSPI4 = 0x60037000 ); PROVIDE ( APB_SARADC = 0x60040000 ); PROVIDE ( USB_SERIAL_JTAG = 0x60043000 ); PROVIDE ( GDMA = 0x6003F000 ); +PROVIDE ( SYSTEM = 0x600C0000 ); diff --git a/components/soc/esp32c3/spi_periph.c b/components/soc/esp32c3/spi_periph.c index ce1c5c9af9..b2f7e416b2 100644 --- a/components/soc/esp32c3/spi_periph.c +++ b/components/soc/esp32c3/spi_periph.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 */ @@ -12,29 +12,30 @@ */ const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = { { - .spiclk_out = SPICLK_OUT_MUX_IDX, - .spiclk_in = 0,/* SPI clock is not an input signal*/ - .spid_out = SPID_OUT_IDX, - .spiq_out = SPIQ_OUT_IDX, - .spiwp_out = SPIWP_OUT_IDX, - .spihd_out = SPIHD_OUT_IDX, - .spid_in = SPID_IN_IDX, - .spiq_in = SPIQ_IN_IDX, - .spiwp_in = SPIWP_IN_IDX, - .spihd_in = SPIHD_IN_IDX, - .spics_out = {SPICS0_OUT_IDX, SPICS1_OUT_IDX},/* SPI0/1 do not have CS2 now */ - .spics_in = 0,/* SPI cs is not an input signal*/ - .spiclk_iomux_pin = SPI_IOMUX_PIN_NUM_CLK, - .spid_iomux_pin = SPI_IOMUX_PIN_NUM_MOSI, - .spiq_iomux_pin = SPI_IOMUX_PIN_NUM_MISO, - .spiwp_iomux_pin = SPI_IOMUX_PIN_NUM_WP, - .spihd_iomux_pin = SPI_IOMUX_PIN_NUM_HD, - .spics0_iomux_pin = SPI_IOMUX_PIN_NUM_CS, - .irq = ETS_SPI1_INTR_SOURCE, + // MSPI has dedicated iomux pins + .spiclk_out = -1, + .spiclk_in = -1, + .spid_out = -1, + .spiq_out = -1, + .spiwp_out = -1, + .spihd_out = -1, + .spid_in = -1, + .spiq_in = -1, + .spiwp_in = -1, + .spihd_in = -1, + .spics_out = {-1}, + .spics_in = -1, + .spiclk_iomux_pin = -1, + .spid_iomux_pin = -1, + .spiq_iomux_pin = -1, + .spiwp_iomux_pin = -1, + .spihd_iomux_pin = -1, + .spics0_iomux_pin = -1, + .irq = -1, .irq_dma = -1, - .module = PERIPH_SPI_MODULE, - .hw = (spi_dev_t *) &SPIMEM1, - .func = SPI_FUNC_NUM, + .module = -1, + .hw = NULL, + .func = -1, }, { .spiclk_out = FSPICLK_OUT_IDX, .spiclk_in = FSPICLK_IN_IDX, diff --git a/components/soc/esp32c6/esp_cpu_intr.c b/components/soc/esp32c6/esp_cpu_intr.c new file mode 100644 index 0000000000..ded3030aeb --- /dev/null +++ b/components/soc/esp32c6/esp_cpu_intr.c @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_cpu.h" +#include "esp_riscv_intr.h" + +void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_desc_ret) +{ + /* On targets that uses CLIC as the interrupt controller, the first 16 lines (0..15) are reserved for software + * interrupts, all the other lines starting from 16 and above can be used by external peripheral. + * + * Reserve interrupt line 1 for the Wifi controller. + * Reserve interrupt line 6 since it is used for disabling interrupts in the interrupt allocator (INT_MUX_DISABLED_INTNO) + */ + const uint32_t rsvd_mask = BIT(1) | BIT(6); + intr_desc_ret->priority = 1; + intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; + intr_desc_ret->flags = esp_riscv_intr_num_flags(intr_num, rsvd_mask); +} diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index b1ace25e8c..160c5e8b78 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -339,7 +339,7 @@ config SOC_CPU_WATCHPOINTS_NUM int default 4 -config SOC_CPU_WATCHPOINT_SIZE +config SOC_CPU_WATCHPOINT_MAX_REGION_SIZE hex default 0x80000000 @@ -403,14 +403,6 @@ config SOC_GPIO_SUPPORT_ETM bool default y -config SOC_GPIO_ETM_EVENTS_PER_GROUP - int - default 8 - -config SOC_GPIO_ETM_TASKS_PER_GROUP - int - default 8 - config SOC_GPIO_SUPPORT_RTC_INDEPENDENT bool default y @@ -967,6 +959,10 @@ config SOC_TIMER_SUPPORT_ETM bool default y +config SOC_MWDT_SUPPORT_XTAL + bool + default y + config SOC_TWAI_CONTROLLER_NUM int default 2 @@ -1119,6 +1115,10 @@ config SOC_PM_SUPPORT_EXT1_WAKEUP bool default y +config SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN + bool + default y + config SOC_PM_SUPPORT_CPU_PD bool default y @@ -1221,7 +1221,7 @@ config SOC_WIFI_HW_TSF config SOC_WIFI_FTM_SUPPORT bool - default n + default y config SOC_WIFI_GCMP_SUPPORT bool @@ -1267,10 +1267,26 @@ config SOC_BLE_POWER_CONTROL_SUPPORTED bool default y +config SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED + bool + default y + config SOC_BLUFI_SUPPORTED bool default y +config SOC_BLE_MULTI_CONN_OPTIMIZATION + bool + default y + config SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND bool default y + +config SOC_PHY_COMBO_MODULE + bool + default y + +config SOC_CAPS_NO_RESET_BY_ANA_BOD + bool + default y diff --git a/components/soc/esp32c6/include/soc/efuse_reg.h b/components/soc/esp32c6/include/soc/efuse_reg.h index 6caf63d890..882041ac41 100644 --- a/components/soc/esp32c6/include/soc/efuse_reg.h +++ b/components/soc/esp32c6/include/soc/efuse_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -650,20 +650,62 @@ extern "C" { * BLOCK1 data register $n. */ #define EFUSE_RD_MAC_SPI_SYS_2_REG (DR_REG_EFUSE_BASE + 0x4c) -/** EFUSE_MAC_SPI_RESERVED : RO; bitpos: [13:0]; default: 0; - * Reserved. - */ -#define EFUSE_MAC_SPI_RESERVED 0x00003FFFU -#define EFUSE_MAC_SPI_RESERVED_M (EFUSE_MAC_SPI_RESERVED_V << EFUSE_MAC_SPI_RESERVED_S) -#define EFUSE_MAC_SPI_RESERVED_V 0x00003FFFU -#define EFUSE_MAC_SPI_RESERVED_S 0 -/** EFUSE_SPI_PAD_CONF_1 : RO; bitpos: [31:14]; default: 0; +/** EFUSE_ACTIVE_HP_DBIAS : RO; bitpos: [4:0]; default: 0; + * Stores the active hp dbias. + */ +#define EFUSE_ACTIVE_HP_DBIAS 0x0000001FU +#define EFUSE_ACTIVE_HP_DBIAS_M (EFUSE_ACTIVE_HP_DBIAS_V << EFUSE_ACTIVE_HP_DBIAS_S) +#define EFUSE_ACTIVE_HP_DBIAS_V 0x0000001FU +#define EFUSE_ACTIVE_HP_DBIAS_S 0 +/** EFUSE_ACTIVE_LP_DBIAS : RO; bitpos: [9:5]; default: 0; + * Stores the active lp dbias. + */ +#define EFUSE_ACTIVE_LP_DBIAS 0x0000001FU +#define EFUSE_ACTIVE_LP_DBIAS_M (EFUSE_ACTIVE_LP_DBIAS_V << EFUSE_ACTIVE_LP_DBIAS_S) +#define EFUSE_ACTIVE_LP_DBIAS_V 0x0000001FU +#define EFUSE_ACTIVE_LP_DBIAS_S 5 +/** EFUSE_LSLP_HP_DBG : RO; bitpos: [11:10]; default: 0; + * Stores the lslp hp dbg. + */ +#define EFUSE_LSLP_HP_DBG 0x00000003U +#define EFUSE_LSLP_HP_DBG_M (EFUSE_LSLP_HP_DBG_V << EFUSE_LSLP_HP_DBG_S) +#define EFUSE_LSLP_HP_DBG_V 0x00000003U +#define EFUSE_LSLP_HP_DBG_S 10 +/** EFUSE_LSLP_HP_DBIAS : RO; bitpos: [15:12]; default: 0; + * Stores the lslp hp dbias. + */ +#define EFUSE_LSLP_HP_DBIAS 0x0000000FU +#define EFUSE_LSLP_HP_DBIAS_M (EFUSE_LSLP_HP_DBIAS_V << EFUSE_LSLP_HP_DBIAS_S) +#define EFUSE_LSLP_HP_DBIAS_V 0x0000000FU +#define EFUSE_LSLP_HP_DBIAS_S 12 +/** EFUSE_DSLP_LP_DBG : RO; bitpos: [18:16]; default: 0; + * Stores the dslp lp dbg. + */ +#define EFUSE_DSLP_LP_DBG 0x00000007U +#define EFUSE_DSLP_LP_DBG_M (EFUSE_DSLP_LP_DBG_V << EFUSE_DSLP_LP_DBG_S) +#define EFUSE_DSLP_LP_DBG_V 0x00000007U +#define EFUSE_DSLP_LP_DBG_S 16 +/** EFUSE_DSLP_LP_DBIAS : RO; bitpos: [22:19]; default: 0; + * Stores the dslp lp dbias. + */ +#define EFUSE_DSLP_LP_DBIAS 0x0000000FU +#define EFUSE_DSLP_LP_DBIAS_M (EFUSE_DSLP_LP_DBIAS_V << EFUSE_DSLP_LP_DBIAS_S) +#define EFUSE_DSLP_LP_DBIAS_V 0x0000000FU +#define EFUSE_DSLP_LP_DBIAS_S 19 +/** EFUSE_DBIAS_VOL_GAP : RO; bitpos: [27:23]; default: 0; + * Stores the hp and lp dbias vol gap. + */ +#define EFUSE_DBIAS_VOL_GAP 0x0000001FU +#define EFUSE_DBIAS_VOL_GAP_M (EFUSE_DBIAS_VOL_GAP_V << EFUSE_DBIAS_VOL_GAP_S) +#define EFUSE_DBIAS_VOL_GAP_V 0x0000001FU +#define EFUSE_DBIAS_VOL_GAP_S 23 +/** EFUSE_SPI_PAD_CONF_1 : RO; bitpos: [31:28]; default: 0; * Stores the first part of SPI_PAD_CONF. */ -#define EFUSE_SPI_PAD_CONF_1 0x0003FFFFU +#define EFUSE_SPI_PAD_CONF_1 0x0000000FU #define EFUSE_SPI_PAD_CONF_1_M (EFUSE_SPI_PAD_CONF_1_V << EFUSE_SPI_PAD_CONF_1_S) -#define EFUSE_SPI_PAD_CONF_1_V 0x0003FFFFU -#define EFUSE_SPI_PAD_CONF_1_S 14 +#define EFUSE_SPI_PAD_CONF_1_V 0x0000000FU +#define EFUSE_SPI_PAD_CONF_1_S 28 /** EFUSE_RD_MAC_SPI_SYS_3_REG register * BLOCK1 data register $n. diff --git a/components/soc/esp32c6/include/soc/efuse_struct.h b/components/soc/esp32c6/include/soc/efuse_struct.h index 08a60cf5b1..e6971b4d58 100644 --- a/components/soc/esp32c6/include/soc/efuse_struct.h +++ b/components/soc/esp32c6/include/soc/efuse_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -509,14 +509,38 @@ typedef union { */ typedef union { struct { - /** mac_spi_reserved : RO; bitpos: [13:0]; default: 0; - * Reserved. + /** active_hp_dbias : RO; bitpos: [4:0]; default: 0; + * Stores the active hp dbias. + */ + uint32_t active_hp_dbias:5; + /** active_lp_dbias : RO; bitpos: [9:5]; default: 0; + * Stores the active lp dbias. + */ + uint32_t active_lp_dbias:5; + /** lslp_hp_dbg : RO; bitpos: [11:10]; default: 0; + * Stores the lslp hp dbg. + */ + uint32_t lslp_hp_dbg:2; + /** lslp_hp_dbias : RO; bitpos: [15:12]; default: 0; + * Stores the lslp hp dbias. + */ + uint32_t lslp_hp_dbias:4; + /** dslp_lp_dbg : RO; bitpos: [18:16]; default: 0; + * Stores the dslp lp dbg. + */ + uint32_t dslp_lp_dbg:3; + /** dslp_lp_dbias : RO; bitpos: [22:19]; default: 0; + * Stores the dslp lp dbias. + */ + uint32_t dslp_lp_dbias:4; + /** dbias_vol_gap : RO; bitpos: [27:23]; default: 0; + * Stores the hp and lp dbias vol gap. */ - uint32_t mac_spi_reserved:14; - /** spi_pad_conf_1 : RO; bitpos: [31:14]; default: 0; + uint32_t dbias_vol_gap:5; + /** spi_pad_conf_1 : RO; bitpos: [31:28]; default: 0; * Stores the first part of SPI_PAD_CONF. */ - uint32_t spi_pad_conf_1:18; + uint32_t spi_pad_conf_1:4; }; uint32_t val; } efuse_rd_mac_spi_sys_2_reg_t; diff --git a/components/soc/esp32c6/include/soc/gpio_struct.h b/components/soc/esp32c6/include/soc/gpio_struct.h index ed3e224ca9..68a44048dc 100644 --- a/components/soc/esp32c6/include/soc/gpio_struct.h +++ b/components/soc/esp32c6/include/soc/gpio_struct.h @@ -589,8 +589,8 @@ typedef struct gpio_dev_t { uint32_t reserved_100[19]; volatile gpio_status_next_reg_t status_next; volatile gpio_status_next1_reg_t status_next1; - volatile gpio_func_in_sel_cfg_reg_t func_in_sel_cfg[125]; - uint32_t reserved_348[131]; + volatile gpio_func_in_sel_cfg_reg_t func_in_sel_cfg[128]; + uint32_t reserved_34b[128]; volatile gpio_func_out_sel_cfg_reg_t func_out_sel_cfg[35]; uint32_t reserved_5e0[19]; volatile gpio_clock_gate_reg_t clock_gate; diff --git a/components/soc/esp32c6/include/soc/i2c_ana_mst_reg.h b/components/soc/esp32c6/include/soc/i2c_ana_mst_reg.h index 0f94765f8f..d0f6d4c843 100644 --- a/components/soc/esp32c6/include/soc/i2c_ana_mst_reg.h +++ b/components/soc/esp32c6/include/soc/i2c_ana_mst_reg.h @@ -13,91 +13,207 @@ extern "C" { #endif -#define I2C_ANA_MST_I2C0_CTRL_REG (DR_REG_I2C_ANA_MST_BASE + 0x0000) -#define I2C_ANA_MST_I2C0_BUSY (BIT(25)) -#define I2C_ANA_MST_I2C0_BUSY_S 25 -#define I2C_ANA_MST_I2C0_CTRL 0x01FFFFFF -#define I2C_ANA_MST_I2C0_CTRL_S 0 - -#define I2C_ANA_MST_I2C1_CTRL_REG (DR_REG_I2C_ANA_MST_BASE + 0x0004) -#define I2C_ANA_MST_I2C1_BUSY (BIT(25)) -#define I2C_ANA_MST_I2C1_BUSY_S 25 -#define I2C_ANA_MST_I2C1_CTRL 0x01FFFFFF -#define I2C_ANA_MST_I2C1_CTRL_S 0 - -#define I2C_ANA_MST_I2C0_CONF_REG (DR_REG_I2C_ANA_MST_BASE + 0x0008) -#define I2C_ANA_MST_I2C0_STATUS 0x000000FF -#define I2C_ANA_MST_I2C0_STATUS_S 24 -#define I2C_ANA_MST_I2C0_CONF 0x00FFFFFF -#define I2C_ANA_MST_I2C0_CONF_S 0 - -#define I2C_ANA_MST_I2C1_CONF_REG (DR_REG_I2C_ANA_MST_BASE + 0x000C) -#define I2C_ANA_MST_I2C1_STATUS 0x000000FF -#define I2C_ANA_MST_I2C1_STATUS_S 24 -#define I2C_ANA_MST_I2C1_CONF 0x00FFFFFF -#define I2C_ANA_MST_I2C1_CONF_S 0 - -#define I2C_ANA_MST_I2C_BURST_CONF_REG (DR_REG_I2C_ANA_MST_BASE + 0x0010) -#define I2C_ANA_MST_BURST_CTRL 0xFFFFFFFF -#define I2C_ANA_MST_BURST_CTRL_S 0 - -#define I2C_ANA_MST_I2C_BURST_STATUS_REG (DR_REG_I2C_ANA_MST_BASE + 0x0014) -#define I2C_ANA_MST_BURST_TIMEOUT_CNT 0x00000FFF -#define I2C_ANA_MST_BURST_TIMEOUT_CNT_S 20 -#define I2C_ANA_MST1_BURST_ERR_FLAG (BIT(2)) -#define I2C_ANA_MST1_BURST_ERR_FLAG_S 2 -#define I2C_ANA_MST0_BURST_ERR_FLAG (BIT(1)) -#define I2C_ANA_MST0_BURST_ERR_FLAG_S 1 -#define I2C_ANA_MST_BURST_DONE (BIT(0)) -#define I2C_ANA_MST_BURST_DONE_S 0 - -#define I2C_ANA_MST_ANA_CONF0_REG (DR_REG_I2C_ANA_MST_BASE + 0x0018) -#define I2C_ANA_MST_ANA_STATUS0 0x000000FF -#define I2C_ANA_MST_ANA_STATUS0_S 24 -#define I2C_ANA_MST_ANA_CONF0 0x00FFFFFF -#define I2C_ANA_MST_ANA_CONF0_S 0 - -#define I2C_ANA_MST_ANA_CONF1_REG (DR_REG_I2C_ANA_MST_BASE + 0x001C) -#define I2C_ANA_MST_ANA_STATUS1 0x000000FF -#define I2C_ANA_MST_ANA_STATUS1_S 24 -#define I2C_ANA_MST_ANA_CONF1 0x00FFFFFF -#define I2C_ANA_MST_ANA_CONF1_S 0 - -#define I2C_ANA_MST_ANA_CONF2_REG (DR_REG_I2C_ANA_MST_BASE + 0x0020) -#define I2C_ANA_MST_ANA_STATUS2 0x000000FF -#define I2C_ANA_MST_ANA_STATUS2_S 24 -#define I2C_ANA_MST_ANA_CONF2 0x00FFFFFF -#define I2C_ANA_MST_ANA_CONF2_S 0 - -#define I2C_ANA_MST_I2C0_CTRL1_REG (DR_REG_I2C_ANA_MST_BASE + 0x0024) -#define I2C_ANA_MST_I2C0_SDA_SIDE_GUARD 0x0000001F -#define I2C_ANA_MST_I2C0_SDA_SIDE_GUARD_S 6 -#define I2C_ANA_MST_I2C0_SCL_PULSE_DUR 0x0000003F -#define I2C_ANA_MST_I2C0_SCL_PULSE_DUR_S 0 - -#define I2C_ANA_MST_I2C1_CTRL1_REG (DR_REG_I2C_ANA_MST_BASE + 0x0028) -#define I2C_ANA_MST_I2C1_SDA_SIDE_GUARD 0x0000001F -#define I2C_ANA_MST_I2C1_SDA_SIDE_GUARD_S 6 -#define I2C_ANA_MST_I2C1_SCL_PULSE_DUR 0x0000003F -#define I2C_ANA_MST_I2C1_SCL_PULSE_DUR_S 0 - -#define I2C_ANA_MST_HW_I2C_CTRL_REG (DR_REG_I2C_ANA_MST_BASE + 0x002C) -#define I2C_ANA_MST_ARBITER_DIS (BIT(11)) -#define I2C_ANA_MST_ARBITER_DIS_S 11 -#define I2C_ANA_MST_HW_I2C_SDA_SIDE_GUARD 0x0000001F -#define I2C_ANA_MST_HW_I2C_SDA_SIDE_GUARD_S 6 -#define I2C_ANA_MST_HW_I2C_SCL_PULSE_DUR 0x0000003F -#define I2C_ANA_MST_HW_I2C_SCL_PULSE_DUR_S 0 - -#define I2C_ANA_MST_NOUSE_REG (DR_REG_I2C_ANA_MST_BASE + 0x0030) -#define I2C_ANA_MST_NOUSE 0xFFFFFFFF -#define I2C_ANA_MST_NOUSE_S 0 - -#define I2C_ANA_MST_DATE_REG (DR_REG_I2C_ANA_MST_BASE + 0x0034) -#define I2C_ANA_MST_CLK_EN (BIT(28)) -#define I2C_ANA_MST_CLK_EN_S 28 -#define I2C_ANA_MST_DATE 0x0FFFFFFF -#define I2C_ANA_MST_DATE_S 0 +#define I2C_ANA_MST_I2C0_CTRL_REG (DR_REG_I2C_ANA_MST_BASE + 0x0) +/* I2C_MST_I2C0_BUSY : RO ;bitpos:[25] ;default: 1'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_BUSY (BIT(25)) +#define I2C_ANA_MST_I2C0_BUSY_M (BIT(25)) +#define I2C_ANA_MST_I2C0_BUSY_V 0x1 +#define I2C_ANA_MST_I2C0_BUSY_S 25 +/* I2C_MST_I2C0_CTRL : R/W ;bitpos:[24:0] ;default: 25'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_CTRL 0x01FFFFFF +#define I2C_ANA_MST_I2C0_CTRL_M ((I2C_MST_I2C0_CTRL_V)<<(I2C_MST_I2C0_CTRL_S)) +#define I2C_ANA_MST_I2C0_CTRL_V 0x1FFFFFF +#define I2C_ANA_MST_I2C0_CTRL_S 0 + +#define I2C_ANA_MST_I2C1_CTRL_REG (DR_REG_I2C_ANA_MST_BASE + 0x4) +/* I2C_MST_I2C1_BUSY : RO ;bitpos:[25] ;default: 1'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_BUSY (BIT(25)) +#define I2C_ANA_MST_I2C1_BUSY_M (BIT(25)) +#define I2C_ANA_MST_I2C1_BUSY_V 0x1 +#define I2C_ANA_MST_I2C1_BUSY_S 25 +/* I2C_MST_I2C1_CTRL : R/W ;bitpos:[24:0] ;default: 25'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_CTRL 0x01FFFFFF +#define I2C_ANA_MST_I2C1_CTRL_M ((I2C_MST_I2C1_CTRL_V)<<(I2C_MST_I2C1_CTRL_S)) +#define I2C_ANA_MST_I2C1_CTRL_V 0x1FFFFFF +#define I2C_ANA_MST_I2C1_CTRL_S 0 + +#define I2C_ANA_MST_I2C0_CONF_REG (DR_REG_I2C_ANA_MST_BASE + 0x8) +/* I2C_MST_I2C0_STATUS : RO ;bitpos:[31:24] ;default: 8'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_STATUS 0x000000FF +#define I2C_ANA_MST_I2C0_STATUS_M ((I2C_MST_I2C0_STATUS_V)<<(I2C_MST_I2C0_STATUS_S)) +#define I2C_ANA_MST_I2C0_STATUS_V 0xFF +#define I2C_ANA_MST_I2C0_STATUS_S 24 +/* I2C_MST_I2C0_CONF : R/W ;bitpos:[23:0] ;default: 24'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_CONF 0x00FFFFFF +#define I2C_ANA_MST_I2C0_CONF_M ((I2C_MST_I2C0_CONF_V)<<(I2C_MST_I2C0_CONF_S)) +#define I2C_ANA_MST_I2C0_CONF_V 0xFFFFFF +#define I2C_ANA_MST_I2C0_CONF_S 0 + +#define I2C_ANA_MST_I2C1_CONF_REG (DR_REG_I2C_ANA_MST_BASE + 0xC) +/* I2C_MST_I2C1_STATUS : RO ;bitpos:[31:24] ;default: 8'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_STATUS 0x000000FF +#define I2C_ANA_MST_I2C1_STATUS_M ((I2C_MST_I2C1_STATUS_V)<<(I2C_MST_I2C1_STATUS_S)) +#define I2C_ANA_MST_I2C1_STATUS_V 0xFF +#define I2C_ANA_MST_I2C1_STATUS_S 24 +/* I2C_MST_I2C1_CONF : R/W ;bitpos:[23:0] ;default: 24'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_CONF 0x00FFFFFF +#define I2C_ANA_MST_I2C1_CONF_M ((I2C_MST_I2C1_CONF_V)<<(I2C_MST_I2C1_CONF_S)) +#define I2C_ANA_MST_I2C1_CONF_V 0xFFFFFF +#define I2C_ANA_MST_I2C1_CONF_S 0 + +#define I2C_ANA_MST_I2C_BURST_CONF_REG (DR_REG_I2C_ANA_MST_BASE + 0x10) +/* I2C_MST_BURST_CTRL : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_BURST_CTRL 0xFFFFFFFF +#define I2C_ANA_MST_BURST_CTRL_M ((I2C_MST_BURST_CTRL_V)<<(I2C_MST_BURST_CTRL_S)) +#define I2C_ANA_MST_BURST_CTRL_V 0xFFFFFFFF +#define I2C_ANA_MST_BURST_CTRL_S 0 + +#define I2C_ANA_MST_I2C_BURST_STATUS_REG (DR_REG_I2C_ANA_MST_BASE + 0x14) +/* I2C_MST_BURST_TIMEOUT_CNT : R/W ;bitpos:[31:20] ;default: 12'h400 ; */ +/*description: .*/ +#define I2C_ANA_MST_BURST_TIMEOUT_CNT 0x00000FFF +#define I2C_ANA_MST_BURST_TIMEOUT_CNT_M ((I2C_MST_BURST_TIMEOUT_CNT_V)<<(I2C_MST_BURST_TIMEOUT_CNT_S)) +#define I2C_ANA_MST_BURST_TIMEOUT_CNT_V 0xFFF +#define I2C_ANA_MST_BURST_TIMEOUT_CNT_S 20 +/* I2C_MST1_BURST_ERR_FLAG : RO ;bitpos:[2] ;default: 1'b0 ; */ +/*description: .*/ +#define I2C_ANA_MST1_BURST_ERR_FLAG (BIT(2)) +#define I2C_ANA_MST1_BURST_ERR_FLAG_M (BIT(2)) +#define I2C_ANA_MST1_BURST_ERR_FLAG_V 0x1 +#define I2C_ANA_MST1_BURST_ERR_FLAG_S 2 +/* I2C_MST0_BURST_ERR_FLAG : RO ;bitpos:[1] ;default: 1'b0 ; */ +/*description: .*/ +#define I2C_ANA_MST0_BURST_ERR_FLAG (BIT(1)) +#define I2C_ANA_MST0_BURST_ERR_FLAG_M (BIT(1)) +#define I2C_ANA_MST0_BURST_ERR_FLAG_V 0x1 +#define I2C_ANA_MST0_BURST_ERR_FLAG_S 1 +/* I2C_MST_BURST_DONE : RO ;bitpos:[0] ;default: 1'b0 ; */ +/*description: .*/ +#define I2C_ANA_MST_BURST_DONE (BIT(0)) +#define I2C_ANA_MST_BURST_DONE_M (BIT(0)) +#define I2C_ANA_MST_BURST_DONE_V 0x1 +#define I2C_ANA_MST_BURST_DONE_S 0 + +#define I2C_ANA_MST_ANA_CONF0_REG (DR_REG_I2C_ANA_MST_BASE + 0x18) +/* I2C_ANA_MST_STATUS0 : RO ;bitpos:[31:24] ;default: 8'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_STATUS0 0x000000FF +#define I2C_ANA_MST_ANA_STATUS0_M ((I2C_ANA_MST_STATUS0_V)<<(I2C_ANA_MST_STATUS0_S)) +#define I2C_ANA_MST_ANA_STATUS0_V 0xFF +#define I2C_ANA_MST_ANA_STATUS0_S 24 +/* I2C_ANA_MST_ANA_CONF0 : R/W ;bitpos:[23:0] ;default: 24'h00_e408 ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_CONF0 0x00FFFFFF +#define I2C_ANA_MST_ANA_CONF0_M ((I2C_ANA_MST_ANA_CONF0_V)<<(I2C_ANA_MST_ANA_CONF0_S)) +#define I2C_ANA_MST_ANA_CONF0_V 0xFFFFFF +#define I2C_ANA_MST_ANA_CONF0_S 0 + +#define I2C_ANA_MST_ANA_CONF1_REG (DR_REG_I2C_ANA_MST_BASE + 0x1C) +/* I2C_ANA_MST_STATUS1 : RO ;bitpos:[31:24] ;default: 8'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_STATUS1 0x000000FF +#define I2C_ANA_MST_ANA_STATUS1_M ((I2C_ANA_MST_STATUS1_V)<<(I2C_ANA_MST_STATUS1_S)) +#define I2C_ANA_MST_ANA_STATUS1_V 0xFF +#define I2C_ANA_MST_ANA_STATUS1_S 24 +/* I2C_MST_AANA_NA_CONF1 : R/W ;bitpos:[23:0] ;default: 24'h00_002d ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_CONF1 0x00FFFFFF +#define I2C_ANA_MST_ANA_CONF1_M ((I2C_ANA_MST_ANA_CONF1_V)<<(I2C_ANA_MST_ANA_CONF1_S)) +#define I2C_ANA_MST_ANA_CONF1_V 0xFFFFFF +#define I2C_ANA_MST_ANA_CONF1_S 0 + +#define I2C_ANA_MST_ANA_CONF2_REG (DR_REG_I2C_ANA_MST_BASE + 0x20) +/* I2C_ANA_MST_STATUS2 : RO ;bitpos:[31:24] ;default: 8'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_STATUS2 0x000000FF +#define I2C_ANA_MST_ANA_STATUS2_M ((I2C_ANA_MST_STATUS2_V)<<(I2C_ANA_MST_STATUS2_S)) +#define I2C_ANA_MST_ANA_STATUS2_V 0xFF +#define I2C_ANA_MST_ANA_STATUS2_S 24 +/* I2C_ANA_MST_ANA_CONF2 : R/W ;bitpos:[23:0] ;default: 24'h00_0004 ; */ +/*description: .*/ +#define I2C_ANA_MST_ANA_CONF2 0x00FFFFFF +#define I2C_ANA_MST_ANA_CONF2_M ((I2C_ANA_MST_ANA_CONF2_V)<<(I2C_ANA_MST_ANA_CONF2_S)) +#define I2C_ANA_MST_ANA_CONF2_V 0xFFFFFF +#define I2C_ANA_MST_ANA_CONF2_S 0 + +#define I2C_ANA_MST_I2C0_CTRL1_REG (DR_REG_I2C_ANA_MST_BASE + 0x24) +/* I2C_MST_I2C0_SDA_SIDE_GUARD : R/W ;bitpos:[10:6] ;default: 5'h1 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_SDA_SIDE_GUARD 0x0000001F +#define I2C_ANA_MST_I2C0_SDA_SIDE_GUARD_M ((I2C_MST_I2C0_SDA_SIDE_GUARD_V)<<(I2C_MST_I2C0_SDA_SIDE_GUARD_S)) +#define I2C_ANA_MST_I2C0_SDA_SIDE_GUARD_V 0x1F +#define I2C_ANA_MST_I2C0_SDA_SIDE_GUARD_S 6 +/* I2C_MST_I2C0_SCL_PULSE_DUR : R/W ;bitpos:[5:0] ;default: 6'h2 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C0_SCL_PULSE_DUR 0x0000003F +#define I2C_ANA_MST_I2C0_SCL_PULSE_DUR_M ((I2C_MST_I2C0_SCL_PULSE_DUR_V)<<(I2C_MST_I2C0_SCL_PULSE_DUR_S)) +#define I2C_ANA_MST_I2C0_SCL_PULSE_DUR_V 0x3F +#define I2C_ANA_MST_I2C0_SCL_PULSE_DUR_S 0 + +#define I2C_ANA_MST_I2C1_CTRL1_REG (DR_REG_I2C_ANA_MST_BASE + 0x28) +/* I2C_MST_I2C1_SDA_SIDE_GUARD : R/W ;bitpos:[10:6] ;default: 5'h1 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_SDA_SIDE_GUARD 0x0000001F +#define I2C_ANA_MST_I2C1_SDA_SIDE_GUARD_M ((I2C_MST_I2C1_SDA_SIDE_GUARD_V)<<(I2C_MST_I2C1_SDA_SIDE_GUARD_S)) +#define I2C_ANA_MST_I2C1_SDA_SIDE_GUARD_V 0x1F +#define I2C_ANA_MST_I2C1_SDA_SIDE_GUARD_S 6 +/* I2C_MST_I2C1_SCL_PULSE_DUR : R/W ;bitpos:[5:0] ;default: 6'h2 ; */ +/*description: .*/ +#define I2C_ANA_MST_I2C1_SCL_PULSE_DUR 0x0000003F +#define I2C_ANA_MST_I2C1_SCL_PULSE_DUR_M ((I2C_MST_I2C1_SCL_PULSE_DUR_V)<<(I2C_MST_I2C1_SCL_PULSE_DUR_S)) +#define I2C_ANA_MST_I2C1_SCL_PULSE_DUR_V 0x3F +#define I2C_ANA_MST_I2C1_SCL_PULSE_DUR_S 0 + +#define I2C_ANA_MST_HW_I2C_CTRL_REG (DR_REG_I2C_ANA_MST_BASE + 0x2C) +/* I2C_MST_ARBITER_DIS : R/W ;bitpos:[11] ;default: 1'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_ARBITER_DIS (BIT(11)) +#define I2C_ANA_MST_ARBITER_DIS_M (BIT(11)) +#define I2C_ANA_MST_ARBITER_DIS_V 0x1 +#define I2C_ANA_MST_ARBITER_DIS_S 11 +/* I2C_MST_HW_I2C_SDA_SIDE_GUARD : R/W ;bitpos:[10:6] ;default: 5'h1 ; */ +/*description: .*/ +#define I2C_ANA_MST_HW_I2C_SDA_SIDE_GUARD 0x0000001F +#define I2C_ANA_MST_HW_I2C_SDA_SIDE_GUARD_M ((I2C_MST_HW_I2C_SDA_SIDE_GUARD_V)<<(I2C_MST_HW_I2C_SDA_SIDE_GUARD_S)) +#define I2C_ANA_MST_HW_I2C_SDA_SIDE_GUARD_V 0x1F +#define I2C_ANA_MST_HW_I2C_SDA_SIDE_GUARD_S 6 +/* I2C_MST_HW_I2C_SCL_PULSE_DUR : R/W ;bitpos:[5:0] ;default: 6'h2 ; */ +/*description: .*/ +#define I2C_ANA_MST_HW_I2C_SCL_PULSE_DUR 0x0000003F +#define I2C_ANA_MST_HW_I2C_SCL_PULSE_DUR_M ((I2C_MST_HW_I2C_SCL_PULSE_DUR_V)<<(I2C_MST_HW_I2C_SCL_PULSE_DUR_S)) +#define I2C_ANA_MST_HW_I2C_SCL_PULSE_DUR_V 0x3F +#define I2C_ANA_MST_HW_I2C_SCL_PULSE_DUR_S 0 + +#define I2C_ANA_MST_NOUSE_REG (DR_REG_I2C_ANA_MST_BASE + 0x30) +/* I2C_MST_NOUSE : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_NOUSE 0xFFFFFFFF +#define I2C_ANA_MST_NOUSE_M ((I2C_MST_NOUSE_V)<<(I2C_MST_NOUSE_S)) +#define I2C_ANA_MST_NOUSE_V 0xFFFFFFFF +#define I2C_ANA_MST_NOUSE_S 0 + +#define I2C_ANA_MST_DATE_REG (DR_REG_I2C_ANA_MST_BASE + 0x34) +/* I2C_MST_CLK_EN : R/W ;bitpos:[28] ;default: 1'h0 ; */ +/*description: .*/ +#define I2C_ANA_MST_CLK_EN (BIT(28)) +#define I2C_ANA_MST_CLK_EN_M (BIT(28)) +#define I2C_ANA_MST_CLK_EN_V 0x1 +#define I2C_ANA_MST_CLK_EN_S 28 +/* I2C_MST_DATE : R/W ;bitpos:[27:0] ;default: 28'h2201300 ; */ +/*description: .*/ +#define I2C_ANA_MST_DATE 0x0FFFFFFF +#define I2C_ANA_MST_DATE_M ((I2C_MST_DATE_V)<<(I2C_MST_DATE_S)) +#define I2C_ANA_MST_DATE_V 0xFFFFFFF +#define I2C_ANA_MST_DATE_S 0 #ifdef __cplusplus } diff --git a/components/soc/esp32c6/include/soc/ieee802154_reg.h b/components/soc/esp32c6/include/soc/ieee802154_reg.h index 978ef141bc..db8e6e12bf 100644 --- a/components/soc/esp32c6/include/soc/ieee802154_reg.h +++ b/components/soc/esp32c6/include/soc/ieee802154_reg.h @@ -471,32 +471,32 @@ extern "C" { #define IEEE802154_SFD_TIMEOUT_CNT_CLEAR_S 14 #define IEEE802154_CRC_ERROR_CNT_CLEAR (BIT(13)) #define IEEE802154_CRC_ERROR_CNT_CLEAR_S 13 -#define IEEE802154_ED_ABORT_CNT_CLEAR (BIT(12)) -#define IEEE802154_ED_ABORT_CNT_CLEAR_S 12 -#define IEEE802154_CCA_FAIL_CNT_CLEAR (BIT(11)) -#define IEEE802154_CCA_FAIL_CNT_CLEAR_S 11 -#define IEEE802154_RX_FILTER_FAIL_CNT_CLEAR (BIT(10)) -#define IEEE802154_RX_FILTER_FAIL_CNT_CLEAR_S 10 -#define IEEE802154_NO_RSS_DETECT_CNT_CLEAR (BIT(9)) -#define IEEE802154_NO_RSS_DETECT_CNT_CLEAR_S 9 -#define IEEE802154_RX_ABORT_COEX_CNT_CLEAR (BIT(8)) -#define IEEE802154_RX_ABORT_COEX_CNT_CLEAR_S 8 -#define IEEE802154_RX_RESTART_CNT_CLEAR (BIT(7)) -#define IEEE802154_RX_RESTART_CNT_CLEAR_S 7 +#define IEEE802154_RX_FILTER_FAIL_CNT_CLEAR (BIT(12)) +#define IEEE802154_RX_FILTER_FAIL_CNT_CLEAR_S 12 +#define IEEE802154_NO_RSS_DETECT_CNT_CLEAR (BIT(11)) +#define IEEE802154_NO_RSS_DETECT_CNT_CLEAR_S 11 +#define IEEE802154_RX_ABORT_COEX_CNT_CLEAR (BIT(10)) +#define IEEE802154_RX_ABORT_COEX_CNT_CLEAR_S 10 +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_CLEAR (BIT(9)) +#define IEEE802154_RX_ACK_ABORT_COEX_CNT_CLEAR_S 9 +#define IEEE802154_RX_RESTART_CNT_CLEAR (BIT(8)) +#define IEEE802154_RX_RESTART_CNT_CLEAR_S 8 +#define IEEE802154_RX_ACK_TIMEOUT_CNT_CLEAR (BIT(7)) +#define IEEE802154_RX_ACK_TIMEOUT_CNT_CLEAR_S 7 #define IEEE802154_TX_ACK_ABORT_COEX_CNT_CLEAR (BIT(6)) #define IEEE802154_TX_ACK_ABORT_COEX_CNT_CLEAR_S 6 -#define IEEE802154_ED_SCAN_COEX_CNT_CLEAR (BIT(5)) -#define IEEE802154_ED_SCAN_COEX_CNT_CLEAR_S 5 -#define IEEE802154_RX_ACK_ABORT_COEX_CNT_CLEAR (BIT(4)) -#define IEEE802154_RX_ACK_ABORT_COEX_CNT_CLEAR_S 4 -#define IEEE802154_RX_ACK_TIMEOUT_CNT_CLEAR (BIT(3)) -#define IEEE802154_RX_ACK_TIMEOUT_CNT_CLEAR_S 3 -#define IEEE802154_TX_BREAK_COEX_CNT_CLEAR (BIT(2)) -#define IEEE802154_TX_BREAK_COEX_CNT_CLEAR_S 2 -#define IEEE802154_TX_SECURITY_ERROR_CNT_CLEAR (BIT(1)) -#define IEEE802154_TX_SECURITY_ERROR_CNT_CLEAR_S 1 -#define IEEE802154_CCA_BUSY_CNT_CLEAR (BIT(0)) -#define IEEE802154_CCA_BUSY_CNT_CLEAR_S 0 +#define IEEE802154_TX_BREAK_COEX_CNT_CLEAR (BIT(5)) +#define IEEE802154_TX_BREAK_COEX_CNT_CLEAR_S 5 +#define IEEE802154_TX_SECURITY_ERROR_CNT_CLEAR (BIT(4)) +#define IEEE802154_TX_SECURITY_ERROR_CNT_CLEAR_S 4 +#define IEEE802154_ED_ABORT_CNT_CLEAR (BIT(3)) +#define IEEE802154_ED_ABORT_CNT_CLEAR_S 3 +#define IEEE802154_CCA_FAIL_CNT_CLEAR (BIT(2)) +#define IEEE802154_CCA_FAIL_CNT_CLEAR_S 2 +#define IEEE802154_CCA_BUSY_CNT_CLEAR (BIT(1)) +#define IEEE802154_CCA_BUSY_CNT_CLEAR_S 1 +#define IEEE802154_ED_SCAN_COEX_CNT_CLEAR (BIT(0)) +#define IEEE802154_ED_SCAN_COEX_CNT_CLEAR_S 0 #define IEEE802154_MAC_DATE_REG (IEEE802154_REG_BASE + 0x0184) #define IEEE802154_MAC_DATE 0xFFFFFFFF diff --git a/components/soc/esp32c6/include/soc/lpperi_reg.h b/components/soc/esp32c6/include/soc/lpperi_reg.h index 80b4d32f86..b39b2f353f 100644 --- a/components/soc/esp32c6/include/soc/lpperi_reg.h +++ b/components/soc/esp32c6/include/soc/lpperi_reg.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 */ @@ -137,13 +137,13 @@ extern "C" { * need_des */ #define LPPERI_RNG_DATA_REG (DR_REG_LPPERI_BASE + 0x8) -/** LPPERI_RND_DATA : RO; bitpos: [31:0]; default: 0; +/** LPPERI_RNG_DATA : RO; bitpos: [31:0]; default: 0; * need_des */ -#define LPPERI_RND_DATA 0xFFFFFFFFU -#define LPPERI_RND_DATA_M (LPPERI_RND_DATA_V << LPPERI_RND_DATA_S) -#define LPPERI_RND_DATA_V 0xFFFFFFFFU -#define LPPERI_RND_DATA_S 0 +#define LPPERI_RNG_DATA 0xFFFFFFFFU +#define LPPERI_RNG_DATA_M (LPPERI_RNG_DATA_V << LPPERI_RNG_DATA_S) +#define LPPERI_RNG_DATA_V 0xFFFFFFFFU +#define LPPERI_RNG_DATA_S 0 /** LPPERI_CPU_REG register * need_des diff --git a/components/soc/esp32c6/include/soc/lpperi_struct.h b/components/soc/esp32c6/include/soc/lpperi_struct.h index 278301712c..8dc3cde04f 100644 --- a/components/soc/esp32c6/include/soc/lpperi_struct.h +++ b/components/soc/esp32c6/include/soc/lpperi_struct.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 */ @@ -101,10 +101,10 @@ typedef union { */ typedef union { struct { - /** rnd_data : RO; bitpos: [31:0]; default: 0; + /** rng_data : RO; bitpos: [31:0]; default: 0; * need_des */ - uint32_t rnd_data:32; + uint32_t rng_data:32; }; uint32_t val; } lpperi_rng_data_reg_t; diff --git a/components/soc/esp32c6/include/soc/periph_defs.h b/components/soc/esp32c6/include/soc/periph_defs.h index 4334c388b7..e4c401a9ad 100644 --- a/components/soc/esp32c6/include/soc/periph_defs.h +++ b/components/soc/esp32c6/include/soc/periph_defs.h @@ -49,11 +49,15 @@ typedef enum { PERIPH_IEEE802154_MODULE, PERIPH_COEX_MODULE, PERIPH_PHY_MODULE, + PERIPH_ANA_I2C_MASTER_MODULE, + PERIPH_MODEM_ETM_MODULE, + PERIPH_MODEM_ADC_COMMON_FE_MODULE, PERIPH_MODULE_MAX +/* !!! Don't append soc modules here !!! */ } periph_module_t; #define PERIPH_MODEM_MODULE_MIN PERIPH_WIFI_MODULE -#define PERIPH_MODEM_MODULE_MAX PERIPH_PHY_MODULE +#define PERIPH_MODEM_MODULE_MAX PERIPH_MODEM_ADC_COMMON_FE_MODULE #define PERIPH_MODEM_MODULE_NUM (PERIPH_MODEM_MODULE_MAX - PERIPH_MODEM_MODULE_MIN + 1) #define IS_MODEM_MODULE(periph) ((periph>=PERIPH_MODEM_MODULE_MIN) && (periph<=PERIPH_MODEM_MODULE_MAX)) diff --git a/components/soc/esp32c6/include/soc/reg_base.h b/components/soc/esp32c6/include/soc/reg_base.h index 4575659382..7d8339605e 100644 --- a/components/soc/esp32c6/include/soc/reg_base.h +++ b/components/soc/esp32c6/include/soc/reg_base.h @@ -79,4 +79,4 @@ #define DR_REG_INTPRI_BASE 0x600C5000 #define DR_REG_EXTMEM_BASE 0x600C8000 -#define PWDET_CONF_REG 0x600A8010 +#define PWDET_CONF_REG 0x600A0810 diff --git a/components/soc/esp32c6/include/soc/reset_reasons.h b/components/soc/esp32c6/include/soc/reset_reasons.h index bd9831d5dd..b6b0e33ae3 100644 --- a/components/soc/esp32c6/include/soc/reset_reasons.h +++ b/components/soc/esp32c6/include/soc/reset_reasons.h @@ -23,7 +23,6 @@ extern "C" { #endif -// TODO: IDF-5719 /** * @brief Naming conventions: RESET_REASON_{reset level}_{reset reason} * @note refer to TRM: chapter diff --git a/components/soc/esp32c6/include/soc/soc.h b/components/soc/esp32c6/include/soc/soc.h index 17bbd54600..6c6fc6cd25 100644 --- a/components/soc/esp32c6/include/soc/soc.h +++ b/components/soc/esp32c6/include/soc/soc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,10 +23,10 @@ #define REG_I2S_BASE(i) (DR_REG_I2S_BASE) // only one I2S on C6 #define REG_TIMG_BASE(i) (DR_REG_TIMERGROUP0_BASE + (i) * 0x1000) // TIMERG0 and TIMERG1 #define REG_SPI_MEM_BASE(i) (DR_REG_SPI0_BASE + (i) * 0x1000) // SPIMEM0 and SPIMEM1 -#define REG_SPI_BASE(i) (DR_REG_SPI2_BASE) // only one GPSPI on C6 +#define REG_SPI_BASE(i) (((i)==2) ? (DR_REG_SPI2_BASE) : (0)) // only one GPSPI on C6 #define REG_I2C_BASE(i) (DR_REG_I2C_EXT_BASE) // only one I2C on C6 #define REG_MCPWM_BASE(i) (DR_REG_MCPWM_BASE) // only one MCPWM on C6 -#define REG_TWAI_BASE(i) (DR_REG_TWAI0_BASE + (i) * 0x2000) // TWAI0 and TWAI1 +#define REG_TWAI_BASE(i) (DR_REG_TWAI0_BASE + (i) * 0x2000) // TWAI0 and TWAI1 //Registers Operation {{ #define ETS_UNCACHED_ADDR(addr) (addr) @@ -142,8 +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 SCLK_CLK_FREQ ( 80*1000000 ) -#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) +#define MODEM_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) #define XTAL_CLK_FREQ (40*1000000) #define GPIO_MATRIX_DELAY_NS 0 @@ -160,8 +159,8 @@ #define SOC_DROM_LOW SOC_IROM_LOW #define SOC_DROM_HIGH SOC_IROM_HIGH #define SOC_IROM_MASK_LOW 0x40000000 -#define SOC_IROM_MASK_HIGH 0x4004AC00 -#define SOC_DROM_MASK_LOW 0x4004AC00 +#define SOC_IROM_MASK_HIGH 0x40050000 +#define SOC_DROM_MASK_LOW 0x40000000 #define SOC_DROM_MASK_HIGH 0x40050000 #define SOC_IRAM_LOW 0x40800000 #define SOC_IRAM_HIGH 0x40880000 @@ -204,9 +203,9 @@ #define SOC_PERIPHERAL_LOW 0x60000000 #define SOC_PERIPHERAL_HIGH 0x60100000 -// Debug region, not used by software -#define SOC_DEBUG_LOW 0x20000000 -#define SOC_DEBUG_HIGH 0x28000000 +// CPU sub-system region, contains interrupt config registers +#define SOC_CPU_SUBSYSTEM_LOW 0x20000000 +#define SOC_CPU_SUBSYSTEM_HIGH 0x30000000 // Start (highest address) of ROM boot stack, only relevant during early boot #define SOC_ROM_STACK_START 0x4087e610 diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 47fc5b05eb..07d76a0872 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -16,7 +16,7 @@ * If this file is changed the script will automatically run the script * and generate the kconfig variables as part of the pre-commit hooks. * - * It can also be ran manually with `./tools/gen_soc_caps_kconfig/gen_soc_caps_kconfig.py -d 'components/soc/esp32c6/include/soc/'` + * It can also be ran manually with `./tools/gen_soc_caps_kconfig/gen_soc_caps_kconfig.py 'components/soc/esp32c6/include/soc/'` * * For more information see `tools/gen_soc_caps_kconfig/README.md` * @@ -29,7 +29,6 @@ #define SOC_DEDICATED_GPIO_SUPPORTED 1 #define SOC_UART_SUPPORTED 1 #define SOC_GDMA_SUPPORTED 1 -#define SOC_AHB_GDMA_SUPPORTED 1 #define SOC_GPTIMER_SUPPORTED 1 #define SOC_PCNT_SUPPORTED 1 #define SOC_MCPWM_SUPPORTED 1 @@ -46,7 +45,6 @@ #define SOC_ULP_SUPPORTED 1 #define SOC_LP_CORE_SUPPORTED 1 #define SOC_EFUSE_KEY_PURPOSE_FIELD 1 -#define SOC_EFUSE_SUPPORTED 1 #define SOC_RTC_FAST_MEM_SUPPORTED 1 #define SOC_RTC_MEM_SUPPORTED 1 #define SOC_I2S_SUPPORTED 1 @@ -72,13 +70,7 @@ #define SOC_PAU_SUPPORTED 1 #define SOC_LP_TIMER_SUPPORTED 1 #define SOC_LP_AON_SUPPORTED 1 -#define SOC_LP_PERIPHERALS_SUPPORTED 1 #define SOC_LP_I2C_SUPPORTED 1 -#define SOC_ULP_LP_UART_SUPPORTED 1 -#define SOC_CLK_TREE_SUPPORTED 1 -#define SOC_ASSIST_DEBUG_SUPPORTED 1 -#define SOC_WDT_SUPPORTED 1 -#define SOC_SPI_FLASH_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 @@ -129,9 +121,6 @@ /*!< Interrupt */ #define SOC_ADC_TEMPERATURE_SHARE_INTR (1) -/*!< ADC power control is shared by PWDET */ -#define SOC_ADC_SHARED_POWER 1 - // ESP32C6-TODO: Copy from esp32c6, need check /*-------------------------- APB BACKUP DMA CAPS -------------------------------*/ #define SOC_APB_BACKUP_DMA (0) @@ -169,10 +158,9 @@ #define SOC_DS_KEY_CHECK_MAX_WAIT_US (1100) /*-------------------------- GDMA CAPS -------------------------------------*/ -#define SOC_AHB_GDMA_VERSION 1U -#define SOC_GDMA_NUM_GROUPS_MAX 1U -#define SOC_GDMA_PAIRS_PER_GROUP_MAX 3 -#define SOC_GDMA_SUPPORT_ETM 1 // Support ETM submodule +#define SOC_GDMA_GROUPS (1U) // Number of GDMA groups +#define SOC_GDMA_PAIRS_PER_GROUP (3) // Number of GDMA pairs in each group +#define SOC_GDMA_SUPPORT_ETM (1) // Support ETM submodule /*-------------------------- ETM CAPS --------------------------------------*/ #define SOC_ETM_GROUPS 1U // Number of ETM groups @@ -187,8 +175,6 @@ // GPIO peripheral has the ETM extension #define SOC_GPIO_SUPPORT_ETM 1 -#define SOC_GPIO_ETM_EVENTS_PER_GROUP 8 -#define SOC_GPIO_ETM_TASKS_PER_GROUP 8 // Target has the full LP IO subsystem // On ESP32-C6, Digital IOs have their own registers to control pullup/down capability, independent of LP registers. @@ -198,10 +184,6 @@ #define SOC_GPIO_VALID_GPIO_MASK ((1U<=PERIPH_MODEM_MODULE_MIN) && (periph<=PERIPH_MODEM_MODULE_MAX)) diff --git a/components/soc/esp32h2/include/soc/reg_base.h b/components/soc/esp32h2/include/soc/reg_base.h index a902acdf2a..70d5d8b212 100644 --- a/components/soc/esp32h2/include/soc/reg_base.h +++ b/components/soc/esp32h2/include/soc/reg_base.h @@ -68,4 +68,4 @@ #define DR_REG_INTPRI_BASE 0x600C5000 #define DR_REG_CACHE_BASE 0x600C8000 -#define PWDET_CONF_REG 0x600A8010 +#define PWDET_CONF_REG 0x600A0810 diff --git a/components/soc/esp32h2/include/soc/regi2c_defs.h b/components/soc/esp32h2/include/soc/regi2c_defs.h index e9611d885e..799f0e0b80 100644 --- a/components/soc/esp32h2/include/soc/regi2c_defs.h +++ b/components/soc/esp32h2/include/soc/regi2c_defs.h @@ -26,3 +26,10 @@ #define ANA_CONFIG2_M BIT(18) #define ANA_I2C_SAR_FORCE_PU BIT(16) + +/** + * Restore regi2c analog calibration related configuration registers. + * This is a workaround for calibration error when waking up from light sleep + */ +#define REGI2C_ANA_CALI_PD_WORKAROUND 1 +#define REGI2C_ANA_CALI_BYTE_NUM 8 diff --git a/components/soc/esp32h2/include/soc/regi2c_saradc.h b/components/soc/esp32h2/include/soc/regi2c_saradc.h index 7d211bf6aa..3b2b69cfb5 100644 --- a/components/soc/esp32h2/include/soc/regi2c_saradc.h +++ b/components/soc/esp32h2/include/soc/regi2c_saradc.h @@ -40,7 +40,7 @@ #define I2C_SARADC_TSENS_DAC 0x6 #define I2C_SARADC_TSENS_DAC_MSB 3 -#define I2C_SARADC_TSENS_DAC_LSB 3 +#define I2C_SARADC_TSENS_DAC_LSB 0 #define I2C_SARADC_DTEST 7 #define I2C_SARADC_DTEST_MSB 1 @@ -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/reset_reasons.h b/components/soc/esp32h2/include/soc/reset_reasons.h index dddfc94eef..24ce66c9a4 100644 --- a/components/soc/esp32h2/include/soc/reset_reasons.h +++ b/components/soc/esp32h2/include/soc/reset_reasons.h @@ -23,7 +23,6 @@ extern "C" { #endif -// ESP32H2-TODO: IDF-5719 Need update /** * @brief Naming conventions: RESET_REASON_{reset level}_{reset reason} * @note refer to TRM: chapter @@ -31,7 +30,6 @@ extern "C" { typedef enum { RESET_REASON_CHIP_POWER_ON = 0x01, // Power on reset RESET_REASON_CHIP_BROWN_OUT = 0x01, // VDD voltage is not stable and resets the chip - RESET_REASON_CHIP_SUPER_WDT = 0x01, // Super watch dog resets the chip RESET_REASON_CORE_SW = 0x03, // Software resets the digital core by RTC_CNTL_SW_SYS_RST RESET_REASON_CORE_DEEP_SLEEP = 0x05, // Deep sleep reset the digital core RESET_REASON_CORE_MWDT0 = 0x07, // Main watch dog 0 resets digital core @@ -44,11 +42,11 @@ typedef enum { RESET_REASON_SYS_RTC_WDT = 0x10, // RTC watch dog resets digital core and rtc module RESET_REASON_CPU0_MWDT1 = 0x11, // Main watch dog 1 resets CPU 0 RESET_REASON_SYS_SUPER_WDT = 0x12, // Super watch dog resets the digital core and rtc module - RESET_REASON_SYS_CLK_GLITCH = 0x13, // Glitch on clock resets the digital core and rtc module RESET_REASON_CORE_EFUSE_CRC = 0x14, // eFuse CRC error resets the digital core RESET_REASON_CORE_USB_UART = 0x15, // USB UART resets the digital core RESET_REASON_CORE_USB_JTAG = 0x16, // USB JTAG resets the digital core RESET_REASON_CORE_PWR_GLITCH = 0x17, // Glitch on power resets the digital core + RESET_REASON_CPU0_JTAG = 0x18, // JTAG resets the CPU 0 } soc_reset_reason_t; diff --git a/components/soc/esp32h2/include/soc/rtc.h b/components/soc/esp32h2/include/soc/rtc.h index 1730c29980..c383142328 100644 --- a/components/soc/esp32h2/include/soc/rtc.h +++ b/components/soc/esp32h2/include/soc/rtc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/components/soc/esp32h2/include/soc/rtc_io_channel.h b/components/soc/esp32h2/include/soc/rtc_io_channel.h new file mode 100644 index 0000000000..81435c63b4 --- /dev/null +++ b/components/soc/esp32h2/include/soc/rtc_io_channel.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +//RTC GPIO channels +#define RTCIO_GPIO7_CHANNEL 0 //RTCIO_CHANNEL_0 +#define RTCIO_CHANNEL_0_GPIO_NUM 7 + +#define RTCIO_GPIO8_CHANNEL 1 //RTCIO_CHANNEL_1 +#define RTCIO_CHANNEL_1_GPIO_NUM 8 + +#define RTCIO_GPIO9_CHANNEL 2 //RTCIO_CHANNEL_2 +#define RTCIO_CHANNEL_2_GPIO_NUM 9 + +#define RTCIO_GPIO10_CHANNEL 3 //RTCIO_CHANNEL_3 +#define RTCIO_CHANNEL_3_GPIO_NUM 10 + +#define RTCIO_GPIO11_CHANNEL 4 //RTCIO_CHANNEL_4 +#define RTCIO_CHANNEL_4_GPIO_NUM 11 + +#define RTCIO_GPIO12_CHANNEL 5 //RTCIO_CHANNEL_5 +#define RTCIO_CHANNEL_5_GPIO_NUM 12 + +#define RTCIO_GPIO13_CHANNEL 6 //RTCIO_CHANNEL_6 +#define RTCIO_CHANNEL_6_GPIO_NUM 13 + +#define RTCIO_GPIO14_CHANNEL 7 //RTCIO_CHANNEL_7 +#define RTCIO_CHANNEL_7_GPIO_NUM 14 diff --git a/components/soc/esp32h2/include/soc/soc.h b/components/soc/esp32h2/include/soc/soc.h index d2af053986..bfa1a9a3cc 100644 --- a/components/soc/esp32h2/include/soc/soc.h +++ b/components/soc/esp32h2/include/soc/soc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,11 +20,11 @@ #define REG_UART_BASE(i) (DR_REG_UART_BASE + (i) * 0x1000) #define REG_UART_AHB_BASE(i) (0x60000000 + (i) * 0x10000) #define UART_FIFO_AHB_REG(i) (REG_UART_AHB_BASE(i) + 0x0) -#define REG_I2S_BASE(i) (DR_REG_I2S_BASE + (i) * 0x1E000) +#define REG_I2S_BASE(i) (DR_REG_I2S_BASE) // only one I2S on H2 #define REG_TIMG_BASE(i) (DR_REG_TIMERGROUP0_BASE + (i)*0x1000) #define REG_SPI_MEM_BASE(i) (DR_REG_SPI0_BASE + (i) * 0x1000) +#define REG_SPI_BASE(i) (((i)==2) ? (DR_REG_SPI2_BASE) : (0)) // only one GPSPI #define REG_I2C_BASE(i) (DR_REG_I2C_EXT0_BASE + (i) * 0x1000) -#define REG_SPI_BASE(i) (DR_REG_SPI2_BASE + (i - 2) * 0x1000) //Registers Operation {{ #define ETS_UNCACHED_ADDR(addr) (addr) @@ -137,10 +137,10 @@ #define APB_CLK_FREQ_ROM ( 32*1000000 ) #define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM #define EFUSE_CLK_FREQ_ROM ( 20*1000000) -#define CPU_CLK_FREQ_MHZ_BTLD (96) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration +#define CPU_CLK_FREQ_MHZ_BTLD (64) // 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 ( 32*1000000 ) -#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 32*1000000 ) +#define MODEM_APB_CLK_FREQ ( 32*1000000 ) #define REF_CLK_FREQ ( 1000000 ) #define XTAL_CLK_FREQ (32*1000000) #define GPIO_MATRIX_DELAY_NS 0 @@ -157,8 +157,8 @@ #define SOC_DROM_LOW SOC_IROM_LOW #define SOC_DROM_HIGH SOC_IROM_HIGH #define SOC_IROM_MASK_LOW 0x40000000 -#define SOC_IROM_MASK_HIGH 0x4001C400 -#define SOC_DROM_MASK_LOW 0x4001C400 +#define SOC_IROM_MASK_HIGH 0x40020000 +#define SOC_DROM_MASK_LOW 0x40000000 #define SOC_DROM_MASK_HIGH 0x40020000 #define SOC_IRAM_LOW 0x40800000 #define SOC_IRAM_HIGH 0x40850000 @@ -201,9 +201,9 @@ #define SOC_PERIPHERAL_LOW 0x60000000 #define SOC_PERIPHERAL_HIGH 0x60100000 -// Debug region, not used by software -#define SOC_DEBUG_LOW 0x20000000 -#define SOC_DEBUG_HIGH 0x28000000 +// CPU sub-system region, contains interrupt config registers +#define SOC_CPU_SUBSYSTEM_LOW 0x20000000 +#define SOC_CPU_SUBSYSTEM_HIGH 0x30000000 // Start (highest address) of ROM boot stack, only relevant during early boot #define SOC_ROM_STACK_START 0x4084f380 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 7df9b8f0b8..78457619dc 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -53,7 +53,7 @@ #define SOC_LEDC_SUPPORTED 1 #define SOC_I2C_SUPPORTED 1 #define SOC_SYSTIMER_SUPPORTED 1 -// #define SOC_SUPPORT_COEXISTENCE 1 // TODO: IDF-6416 +#define SOC_SUPPORT_COEXISTENCE 1 #define SOC_AES_SUPPORTED 1 #define SOC_MPI_SUPPORTED 1 #define SOC_SHA_SUPPORTED 1 @@ -68,6 +68,7 @@ #define SOC_APM_SUPPORTED 1 #define SOC_PMU_SUPPORTED 1 #define SOC_LP_TIMER_SUPPORTED 1 +#define SOC_LP_AON_SUPPORTED 1 #define SOC_PAU_SUPPORTED 1 #define SOC_CLK_TREE_SUPPORTED 1 @@ -113,7 +114,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) @@ -135,9 +138,9 @@ #define SOC_CPU_HAS_FLEXIBLE_INTC 1 #define SOC_INT_PLIC_SUPPORTED 1 //riscv platform-level interrupt controller -#define SOC_CPU_BREAKPOINTS_NUM 4 -#define SOC_CPU_WATCHPOINTS_NUM 4 -#define SOC_CPU_WATCHPOINT_SIZE 0x80000000 // bytes +#define SOC_CPU_BREAKPOINTS_NUM 4 +#define SOC_CPU_WATCHPOINTS_NUM 4 +#define SOC_CPU_WATCHPOINT_MAX_REGION_SIZE 0x80000000 // bytes #define SOC_CPU_HAS_PMA 1 #define SOC_CPU_IDRAM_SPLIT_USING_PMP 1 @@ -178,17 +181,16 @@ // GPIO peripheral has the ETM extension #define SOC_GPIO_SUPPORT_ETM 1 -#define SOC_GPIO_ETM_EVENTS_PER_GROUP 8 -#define SOC_GPIO_ETM_TASKS_PER_GROUP 8 -// Target has no full LP IO subsystem, GPIO7~14 remain LP function (powered by VDD3V3_LP, and can be used as deep-sleep wakeup pins) +// Target has no full LP IO subsystem, GPIO7~14 remain LP function (powered by VDD3V3_LP, and can be used as ext1 wakeup pins) +// Digital IOs have their own registers to control pullup/down/capability +// However, there is no way to control pullup/down/capability for IOs under LP function since there is no LP_IOMUX registers +#define SOC_GPIO_SUPPORT_RTC_INDEPENDENT (1) -// GPIO7~14 on ESP32H2 can support chip deep sleep wakeup -#define SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP (1) +// GPIO7~14 on ESP32H2 can support chip deep sleep wakeup through EXT1 wake up -#define SOC_GPIO_VALID_GPIO_MASK ((1U<=2) ? (DR_REG_SPI2_BASE + (i-2) * 0x1000) : (0)) // GPSPI2 and GPSPI3 +#define REG_I2C_BASE(i) (DR_REG_I2C_EXT_BASE + (i) * 0x14000 ) //Convenient way to replace the register ops when ulp riscv projects //consume this file @@ -145,7 +146,6 @@ #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 ( 80*1000000 ) //unit: Hz -#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) #define UART_CLK_FREQ APB_CLK_FREQ #define WDT_CLK_FREQ APB_CLK_FREQ @@ -207,50 +207,8 @@ // Start (highest address) of ROM boot stack, only relevant during early boot #define SOC_ROM_STACK_START 0x3fffe70c -//interrupt cpu using table, Please see the core-isa.h -/************************************************************************************************************* - * Intr num Level Type PRO CPU usage - * 0 1 extern level WMAC - * 1 1 extern level BT/BLE Host HCI DMA - * 2 1 extern level - * 3 1 extern level - * 4 1 extern level WBB - * 5 1 extern level BT/BLE Controller - * 6 1 timer FreeRTOS Tick(L1) - * 7 1 software BT/BLE VHCI - * 8 1 extern level BT/BLE BB(RX/TX) - * 9 1 extern level - * 10 1 extern edge - * 11 3 profiling - * 12 1 extern level - * 13 1 extern level - * 14 7 nmi Reserved - * 15 3 timer FreeRTOS Tick(L3) - * 16 5 timer - * 17 1 extern level - * 18 1 extern level - * 19 2 extern level - * 20 2 extern level - * 21 2 extern level - * 22 3 extern edge - * 23 3 extern level - * 24 4 extern level TG1_WDT - * 25 4 extern level CACHEERR - * 26 5 extern level - * 27 3 extern level Reserved - * 28 4 extern edge Reserved - * 29 3 software Reserved - * 30 4 extern edge Reserved - * 31 5 extern level - ************************************************************************************************************* - */ - -//CPU0 Interrupt number reserved, not touch this. #define ETS_WMAC_INUM 0 -#define ETS_BT_HOST_INUM 1 #define ETS_WBB_INUM 4 -#define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/ -#define ETS_FRC1_INUM 22 #define ETS_T1_WDT_INUM 24 #define ETS_MEMACCESS_ERR_INUM 25 diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index f1088191ff..4a97ecaac5 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.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 */ @@ -133,9 +133,9 @@ #define SOC_CPU_CORES_NUM (1U) #define SOC_CPU_INTR_NUM 32 -#define SOC_CPU_BREAKPOINTS_NUM 2 -#define SOC_CPU_WATCHPOINTS_NUM 2 -#define SOC_CPU_WATCHPOINT_SIZE 64 // bytes +#define SOC_CPU_BREAKPOINTS_NUM 2 +#define SOC_CPU_WATCHPOINTS_NUM 2 +#define SOC_CPU_WATCHPOINT_MAX_REGION_SIZE 64 // bytes /*-------------------------- DAC CAPS ----------------------------------------*/ #define SOC_DAC_CHAN_NUM 2 @@ -247,7 +247,10 @@ /*-------------------------- RTCIO CAPS --------------------------------------*/ #define SOC_RTCIO_PIN_COUNT 22 -#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 +#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature, + * so it supports unique IOMUX configuration (including IE, OE, PU, PD, DRV etc.) + * when the pins are switched to RTC function. + */ #define SOC_RTCIO_HOLD_SUPPORTED 1 #define SOC_RTCIO_WAKE_SUPPORTED 1 @@ -334,8 +337,7 @@ #define SOC_SPIRAM_XIP_SUPPORTED 1 /*-------------------------- USB CAPS ----------------------------------------*/ -#define SOC_USB_PERIPH_NUM 1 - +#define SOC_USB_OTG_PERIPH_NUM (1U) /*--------------------------- SHA CAPS ---------------------------------------*/ /* Max amount of bytes in a single DMA operation is 4095, @@ -468,3 +470,6 @@ #define SOC_WIFI_NAN_SUPPORT (1) /*!< Support WIFI Aware (NAN) */ /*-------------------------- ULP CAPS ----------------------------------------*/ #define SOC_ULP_HAS_ADC (1) /* ADC can be accessed from ULP */ + +/*------------------------------------- PHY CAPS -------------------------------------*/ +#define SOC_PHY_COMBO_MODULE (0) /*!< Only support Wi-Fi*/ diff --git a/components/soc/esp32s2/include/soc/spi_mem_reg.h b/components/soc/esp32s2/include/soc/spi_mem_reg.h index fd3bf04a41..b08abdc1fb 100644 --- a/components/soc/esp32s2/include/soc/spi_mem_reg.h +++ b/components/soc/esp32s2/include/soc/spi_mem_reg.h @@ -1,25 +1,16 @@ -// Copyright 2017-2018 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: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _SOC_SPI_MEM_REG_H_ #define _SOC_SPI_MEM_REG_H_ +#include "soc.h" #ifdef __cplusplus extern "C" { #endif -#include "soc.h" -#define REG_SPI_MEM_BASE(i) (DR_REG_SPI0_BASE - (i) * 0x1000) #define SPI_MEM_CMD_REG(i) (REG_SPI_MEM_BASE(i) + 0x000) /* SPI_MEM_FLASH_READ : R/W ;bitpos:[31] ;default: 1'b0 ; */ diff --git a/components/soc/esp32s2/include/soc/spi_reg.h b/components/soc/esp32s2/include/soc/spi_reg.h index 0f0f732baa..1097f31a15 100644 --- a/components/soc/esp32s2/include/soc/spi_reg.h +++ b/components/soc/esp32s2/include/soc/spi_reg.h @@ -1,25 +1,16 @@ -// Copyright 2017-2018 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: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _SOC_SPI_REG_H_ #define _SOC_SPI_REG_H_ +#include "soc.h" #ifdef __cplusplus extern "C" { #endif -#include "soc.h" -#define REG_SPI_BASE(i) (DR_REG_SPI2_BASE + (((i)>3) ? (((i-2)* 0x1000) + 0x10000) : ((i - 2)* 0x1000 ))) #define SPI_CMD_REG(i) (REG_SPI_BASE(i) + 0x000) /* SPI_USR : R/W ;bitpos:[24] ;default: 1'b0 ; */ diff --git a/components/soc/esp32s2/include/soc/syscon_reg.h b/components/soc/esp32s2/include/soc/syscon_reg.h index 91d9e15375..62e031b55b 100644 --- a/components/soc/esp32s2/include/soc/syscon_reg.h +++ b/components/soc/esp32s2/include/soc/syscon_reg.h @@ -443,7 +443,8 @@ extern "C" { #define DPORT_WIFI_CLK_BT_EN_V 0x61 #define DPORT_WIFI_CLK_BT_EN_S 11 /* Mask for clock bits used by both WIFI and Bluetooth, bit 0, 3, 6, 7, 8, 9 */ -#define DPORT_WIFI_CLK_WIFI_BT_COMMON_M 0x000003c9 +#define SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M 0x000003c9 +#define DPORT_WIFI_CLK_WIFI_BT_COMMON_M SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M /* Digital team to check */ //bluetooth baseband bit11 diff --git a/components/soc/esp32s2/include/soc/usb_dwc_cfg.h b/components/soc/esp32s2/include/soc/usb_dwc_cfg.h new file mode 100644 index 0000000000..37cdcdf4bf --- /dev/null +++ b/components/soc/esp32s2/include/soc/usb_dwc_cfg.h @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/* +Configuration Set ID: 1 +*/ + +/* 3.1 Basic Config Parameters */ +#define OTG_MODE 0 +#define OTG_ARCHITECTURE 2 +#define OTG_SINGLE_POINT 1 +#define OTG_ENABLE_LPM 0 +#define OTG_EN_DED_TX_FIFO 1 +#define OTG_EN_DESC_DMA 1 +#define OTG_MULTI_PROC_INTRPT 0 + +/* 3.2 USB Physical Layer Interface Parameters */ +#define OTG_HSPHY_INTERFACE 0 +#define OTG_FSPHY_INTERFACE 1 +#define OTG_ENABLE_IC_USB 0 +#define OTG_I2C_INTERFACE 0 +#define OTG_ADP_SUPPORT 0 +#define OTG_BC_SUPPORT 0 + +/* 3.3 Device Endpoint Configuration Parameters */ +#define OTG_NUM_EPS 6 +#define OTG_NUM_IN_EPS 5 +#define OTG_NUM_CRL_EPS 0 + +/* 3.4 Host Endpoint Configuration Parameters */ +#define OTG_NUM_HOST_CHAN 8 +#define OTG_EN_PERIO_HOST 1 + +/* 3.5 Endpoint Channel FIFO Configuration Parameters */ +#define OTG_DFIFO_DEPTH 256 +#define OTG_DFIFO_DYNAMIC 1 +#define OTG_RX_DFIFO_DEPTH 256 +#define OTG_TX_HNPERIO_DFIFO_DEPTH 256 +#define OTG_TX_NPERIO_DFIFO_DEPTH 256 +#define OTG_TX_HPERIO_DFIFO_DEPTH 256 +#define OTG_NPERIO_TX_QUEUE_DEPTH 4 +#define OTG_PERIO_TX_QUEUE_DEPTH 8 + +/* 3.6 Additional Configuration Options Parameters */ +#define OTG_TRANS_COUNT_WIDTH 16 +#define OTG_PACKET_COUNT_WIDTH 7 +#define OTG_RM_OPT_FEATURES 1 +#define OTG_EN_PWROPT 1 +#define OTG_SYNC_RESET_TYPE 0 +#define OTG_EN_IDDIG_FILTER 1 +#define OTG_EN_VBUSVALID_FILTER 1 +#define OTG_EN_A_VALID_FILTER 1 +#define OTG_EN_B_VALID_FILTER 1 +#define OTG_EN_SESSIONEND_FILTER 1 +#define OTG_EXCP_CNTL_XFER_FLOW 1 +#define OTG_PWR_CLAMP 0 +#define OTG_PWR_SWITCH_POLARITY 0 + +/* 3.7 Endpoint Direction Parameters */ +#define OTG_EP_DIR_1 0 +#define OTG_EP_DIR_2 0 +#define OTG_EP_DIR_3 0 +#define OTG_EP_DIR_4 0 +#define OTG_EP_DIR_5 0 +#define OTG_EP_DIR_6 0 + +/* 3.8 Device Periodic FIFO Depth Parameters */ + +/* 3.9 Device IN Endpoint FIFO Depth Parameters */ +#define OTG_TX_DINEP_DFIFO_DEPTH_1 256 +#define OTG_TX_DINEP_DFIFO_DEPTH_2 256 +#define OTG_TX_DINEP_DFIFO_DEPTH_3 256 +#define OTG_TX_DINEP_DFIFO_DEPTH_4 256 + +/* 3.10 UTMI-To-UTMI Bridge Component Parameters */ +#define U2UB_EN 0 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32s2/include/soc/usb_dwc_struct.h b/components/soc/esp32s2/include/soc/usb_dwc_struct.h index 0402c4a83e..7c9ca381c3 100644 --- a/components/soc/esp32s2/include/soc/usb_dwc_struct.h +++ b/components/soc/esp32s2/include/soc/usb_dwc_struct.h @@ -1,16 +1,21 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include + #ifdef __cplusplus extern "C" { #endif -#include +/* +Registers and fields were generated based on a set of configuration options. +See the ESP32-S2 "usb_dwc_cfg.h" for more details. +*/ /* ---------------------------- Register Types ------------------------------ */ @@ -29,7 +34,7 @@ typedef union { uint32_t hstsethnpen: 1; uint32_t devhnpen: 1; uint32_t ehen: 1; - uint32_t reserved2: 2; + uint32_t reserved_13: 2; uint32_t dbncefltrbypass: 1; uint32_t conidsts: 1; uint32_t dbnctime: 1; @@ -37,23 +42,26 @@ typedef union { uint32_t bsesvld: 1; uint32_t otgver: 1; uint32_t curmod: 1; - uint32_t reserved10: 10; + uint32_t reserved_22: 5; + uint32_t reserved_27: 1; + uint32_t reserved_28: 4; }; uint32_t val; } usb_dwc_gotgctl_reg_t; typedef union { struct { - uint32_t reserved2: 2; + uint32_t reserved_0: 2; uint32_t sesenddet: 1; - uint32_t reserved5: 5; + uint32_t reserved_3: 5; uint32_t sesreqsucstschng: 1; uint32_t hstnegsucstschng: 1; - uint32_t reserved7: 7; + uint32_t reserved_10: 7; uint32_t hstnegdet: 1; uint32_t adevtoutchg: 1; uint32_t dbncedone: 1; - uint32_t reserved12: 12; + uint32_t reserved_20: 1; + uint32_t reserved_21: 11; }; uint32_t val; } usb_dwc_gotgint_reg_t; @@ -63,34 +71,44 @@ typedef union { uint32_t glbllntrmsk: 1; uint32_t hbstlen: 4; uint32_t dmaen: 1; - uint32_t reserved1: 1; + uint32_t reserved_6: 1; uint32_t nptxfemplvl: 1; uint32_t ptxfemplvl: 1; - uint32_t reserved12: 12; + uint32_t reserved_9: 12; uint32_t remmemsupp: 1; uint32_t notialldmawrit: 1; uint32_t ahbsingle: 1; uint32_t invdescendianess: 1; - uint32_t reserved7: 7; + uint32_t reserved_25: 7; }; uint32_t val; - //Checked } usb_dwc_gahbcfg_reg_t; typedef union { struct { uint32_t toutcal: 3; uint32_t phyif: 1; - uint32_t reserved1a: 1; + uint32_t reserved_4: 1; uint32_t fsintf: 1; uint32_t physel: 1; - uint32_t reserved1b: 1; + uint32_t reserved_7: 1; uint32_t srpcap: 1; uint32_t hnpcap: 1; uint32_t usbtrdtim: 4; - uint32_t reserved8: 8; + uint32_t reserved_14: 1; + uint32_t phylpwrclksel: 1; + uint32_t reserved_16: 1; + uint32_t reserved_17: 1; + uint32_t reserved_18: 1; + uint32_t reserved_19: 1; + uint32_t reserved_20: 1; + uint32_t reserved_21: 1; uint32_t termseldlpulse: 1; - uint32_t reserved5: 5; + uint32_t reserved_23: 1; + uint32_t reserved_24: 1; + uint32_t reserved_25: 1; + uint32_t icusbcap: 1; + uint32_t reserved_27: 1; uint32_t txenddelay: 1; uint32_t forcehstmode: 1; uint32_t forcedevmode: 1; @@ -104,11 +122,11 @@ typedef union { uint32_t csftrst: 1; uint32_t piufssftrst: 1; uint32_t frmcntrrst: 1; - uint32_t reserved1: 1; + uint32_t reserved_3: 1; uint32_t rxfflsh: 1; uint32_t txfflsh: 1; uint32_t txfnum: 5; - uint32_t reserved19: 19; + uint32_t reserved_11: 19; uint32_t dmareq: 1; uint32_t ahbidle: 1; }; @@ -117,22 +135,23 @@ typedef union { typedef union { struct { - uint32_t curmod_int: 1; + uint32_t curmod: 1; uint32_t modemis: 1; uint32_t otgint: 1; uint32_t sof: 1; - uint32_t rxflvi: 1; + uint32_t rxflvl: 1; uint32_t nptxfemp: 1; uint32_t ginnakeff: 1; uint32_t goutnakeff: 1; - uint32_t reserved2: 2; + uint32_t reserved_8: 1; + uint32_t reserved_9: 1; uint32_t erlysusp: 1; uint32_t usbsusp: 1; uint32_t usbrst: 1; uint32_t enumdone: 1; uint32_t isooutdrop: 1; uint32_t eopf: 1; - uint32_t reserved1a: 1; + uint32_t reserved_16: 1; uint32_t epmis: 1; uint32_t iepint: 1; uint32_t oepint: 1; @@ -140,10 +159,10 @@ typedef union { uint32_t incompip: 1; uint32_t fetsusp: 1; uint32_t resetdet: 1; - uint32_t prtlnt: 1; - uint32_t hchlnt: 1; + uint32_t prtint: 1; + uint32_t hchint: 1; uint32_t ptxfemp: 1; - uint32_t reserved1b: 1; + uint32_t reserved_27: 1; uint32_t conidstschng: 1; uint32_t disconnint: 1; uint32_t sessreqint: 1; @@ -154,22 +173,23 @@ typedef union { typedef union { struct { - uint32_t reserved1a: 1; + uint32_t reserved_0: 1; uint32_t modemismsk: 1; uint32_t otgintmsk: 1; uint32_t sofmsk: 1; - uint32_t rxflvimsk: 1; + uint32_t rxflvlmsk: 1; uint32_t nptxfempmsk: 1; uint32_t ginnakeffmsk: 1; uint32_t goutnackeffmsk: 1; - uint32_t reserved2: 2; + uint32_t reserved_8: 1; + uint32_t reserved_9: 1; uint32_t erlysuspmsk: 1; uint32_t usbsuspmsk: 1; uint32_t usbrstmsk: 1; uint32_t enumdonemsk: 1; uint32_t isooutdropmsk: 1; uint32_t eopfmsk: 1; - uint32_t reserved1b: 1; + uint32_t reserved_16: 1; uint32_t epmismsk: 1; uint32_t iepintmsk: 1; uint32_t oepintmsk: 1; @@ -177,10 +197,10 @@ typedef union { uint32_t incompipmsk: 1; uint32_t fetsuspmsk: 1; uint32_t resetdetmsk: 1; - uint32_t prtlntmsk: 1; + uint32_t prtintmsk: 1; uint32_t hchintmsk: 1; uint32_t ptxfempmsk: 1; - uint32_t reserved1c: 1; + uint32_t reserved_27: 1; uint32_t conidstschngmsk: 1; uint32_t disconnintmsk: 1; uint32_t sessreqintmsk: 1; @@ -191,12 +211,13 @@ typedef union { typedef union { struct { - uint32_t g_chnum: 4; - uint32_t g_bcnt: 11; - uint32_t g_dpid: 2; - uint32_t g_pktsts: 4; - uint32_t g_fn: 4; - uint32_t reserved7: 7; + uint32_t chnum: 4; + uint32_t bcnt: 11; + uint32_t dpid: 2; + uint32_t pktsts: 4; + uint32_t fn: 4; + uint32_t reserved_25: 6; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_grxstsr_reg_t; @@ -208,7 +229,8 @@ typedef union { uint32_t dpid: 2; uint32_t pktsts: 4; uint32_t fn: 4; - uint32_t reserved7: 7; + uint32_t reserved_25: 6; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_grxstsp_reg_t; @@ -216,7 +238,7 @@ typedef union { typedef union { struct { uint32_t rxfdep: 16; - uint32_t reserved16: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_grxfsiz_reg_t; @@ -232,10 +254,9 @@ typedef union { typedef union { struct { uint32_t nptxfspcavail: 16; - uint32_t nptxqspcavail: 4; - uint32_t reserved4: 4; + uint32_t nptxqspcavail: 8; uint32_t nptxqtop: 7; - uint32_t reserved1: 1; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_gnptxsts_reg_t; @@ -266,11 +287,11 @@ typedef union { uint32_t periosupport: 1; uint32_t dynfifosizing: 1; uint32_t multiprocintrpt: 1; - uint32_t reserved1a: 1; + uint32_t reserved_21: 1; uint32_t nptxqdepth: 2; uint32_t ptxqdepth: 2; uint32_t tknqdepth: 5; - uint32_t reserved1b: 1; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_ghwcfg2_reg_t; @@ -295,25 +316,25 @@ typedef union { typedef union { struct { - uint32_t g_numdevperioeps: 4; - uint32_t g_partialpwrdn: 1; - uint32_t g_ahbfreq: 1; - uint32_t g_hibernation: 1; - uint32_t g_extendedhibernation: 1; - uint32_t reserved4: 4; - uint32_t g_acgsupt: 1; - uint32_t g_enhancedlpmsupt: 1; - uint32_t g_phydatawidth: 2; - uint32_t g_numctleps: 4; - uint32_t g_iddqfltr: 1; - uint32_t g_vbusvalidfltr: 1; - uint32_t g_avalidfltr: 1; - uint32_t g_bvalidfltr: 1; - uint32_t g_sessendfltr: 1; - uint32_t g_dedfifomode: 1; - uint32_t g_ineps: 4; - uint32_t g_descdmaenabled: 1; - uint32_t g_descdma: 1; + uint32_t numdevperioeps: 4; + uint32_t partialpwrdn: 1; + uint32_t ahbfreq: 1; + uint32_t hibernation: 1; + uint32_t extendedhibernation: 1; + uint32_t reserved_8: 4; + uint32_t acgsupt: 1; + uint32_t enhancedlpmsupt: 1; + uint32_t phydatawidth: 2; + uint32_t numctleps: 4; + uint32_t iddqfltr: 1; + uint32_t vbusvalidfltr: 1; + uint32_t avalidfltr: 1; + uint32_t bvalidfltr: 1; + uint32_t sessendfltr: 1; + uint32_t dedfifomode: 1; + uint32_t ineps: 4; + uint32_t descdmaenabled: 1; + uint32_t descdma: 1; }; uint32_t val; } usb_dwc_ghwcfg4_reg_t; @@ -337,8 +358,8 @@ typedef union { typedef union { struct { - uint32_t inepitxfstaddr: 16; - uint32_t inep1txfdep: 16; + uint32_t inepntxfstaddr: 16; + uint32_t inepntxfdep: 16; }; uint32_t val; } usb_dwc_dieptxfi_reg_t; @@ -347,15 +368,15 @@ typedef union { struct { uint32_t fslspclksel: 2; uint32_t fslssupp: 1; - uint32_t reserved4a: 4; + uint32_t reserved_3: 4; uint32_t ena32khzs: 1; uint32_t resvalid: 8; - uint32_t reserved1: 1; - uint32_t reserved6: 6; + uint32_t reserved_16: 1; + uint32_t reserved_17: 6; uint32_t descdma: 1; uint32_t frlisten: 2; uint32_t perschedena: 1; - uint32_t reserved4b: 4; + uint32_t reserved_27: 4; uint32_t modechtimen: 1; }; uint32_t val; @@ -365,15 +386,14 @@ typedef union { struct { uint32_t frint: 16; uint32_t hfirrldctrl: 1; - uint32_t reserved15: 15; + uint32_t reserved_17: 15; }; uint32_t val; } usb_dwc_hfir_reg_t; typedef union { struct { - uint32_t frnum: 14; - uint32_t reserved: 2; + uint32_t frnum: 16; uint32_t frrem: 16; }; uint32_t val; @@ -382,8 +402,7 @@ typedef union { typedef union { struct { uint32_t ptxfspcavail: 16; - uint32_t ptxqspcavail: 5; - uint32_t reserved: 3; + uint32_t ptxqspcavail: 8; uint32_t ptxqtop: 8; }; uint32_t val; @@ -392,7 +411,7 @@ typedef union { typedef union { struct { uint32_t haint: 8; - uint32_t reserved24: 24; + uint32_t reserved_8: 24; }; uint32_t val; } usb_dwc_haint_reg_t; @@ -400,7 +419,7 @@ typedef union { typedef union { struct { uint32_t haintmsk: 8; - uint32_t reserved24: 24; + uint32_t reserved_8: 24; }; uint32_t val; } usb_dwc_haintmsk_reg_t; @@ -423,12 +442,12 @@ typedef union { uint32_t prtres: 1; uint32_t prtsusp: 1; uint32_t prtrst: 1; - uint32_t reserved1: 1; + uint32_t reserved_9: 1; uint32_t prtlnsts: 2; uint32_t prtpwr: 1; uint32_t prttstctl: 4; uint32_t prtspd: 2; - uint32_t reserved13: 13; + uint32_t reserved_19: 13; }; uint32_t val; } usb_dwc_hprt_reg_t; @@ -438,7 +457,7 @@ typedef union { uint32_t mps: 11; uint32_t epnum: 4; uint32_t epdir: 1; - uint32_t reserved: 1; + uint32_t reserved_16: 1; uint32_t lspddev: 1; uint32_t eptype: 2; uint32_t ec: 2; @@ -466,7 +485,7 @@ typedef union { uint32_t bnaintr: 1; uint32_t xcs_xact_err: 1; uint32_t desc_lst_rollintr: 1; - uint32_t reserved18: 18; + uint32_t reserved_14: 18; }; uint32_t val; } usb_dwc_hcint_reg_t; @@ -476,28 +495,26 @@ typedef union { uint32_t xfercomplmsk: 1; uint32_t chhltdmsk: 1; uint32_t ahberrmsk: 1; - uint32_t stallmsk: 1; - uint32_t nakmsk: 1; - uint32_t ackmsk: 1; - uint32_t nyetmsk: 1; - uint32_t xacterrmsk: 1; - uint32_t bblerrmsk: 1; - uint32_t frmovrunmsk: 1; - uint32_t datatglerrmsk: 1; + uint32_t reserved_3: 1; + uint32_t reserved_4: 1; + uint32_t reserved_5: 1; + uint32_t reserved_6: 1; + uint32_t reserved_7: 1; + uint32_t reserved_8: 1; + uint32_t reserved_9: 1; + uint32_t reserved_10: 1; uint32_t bnaintrmsk: 1; - uint32_t reserved1: 1; + uint32_t reserved_12: 1; uint32_t desc_lst_rollintrmsk: 1; - uint32_t reserved18: 18; + uint32_t reserved_14: 18; }; uint32_t val; } usb_dwc_hcintmsk_reg_t; typedef union { struct { - uint32_t sched_info: 8; - uint32_t ntd: 8; - uint32_t reserved3: 3; - uint32_t reserved10: 10; + uint32_t xfersize: 19; // Note: Width depends on OTG_TRANS_COUNT_WIDTH (see databook). + uint32_t pktcnt: 10; // Note: Width depends on OTG_PACKET_COUNT_WIDTH (see databook). uint32_t pid: 2; uint32_t dopng: 1; }; @@ -506,14 +523,8 @@ typedef union { typedef union { struct { - uint32_t reserved3: 3; - uint32_t ctd: 6; - uint32_t dmaaddr: 23; - } non_iso; - struct { - uint32_t reserved3: 3; - uint32_t dmaaddr_ctd: 29; - } iso; + uint32_t dmaaddr; + }; uint32_t val; } usb_dwc_hcdma_reg_t; @@ -526,16 +537,16 @@ typedef union { typedef union { struct { - uint32_t reserved2a: 2; + uint32_t devspd: 2; uint32_t nzstsouthshk: 1; - uint32_t reserved1: 1; + uint32_t ena32khzsusp: 1; uint32_t devaddr: 7; - uint32_t perfrlint: 2; + uint32_t perfrint: 2; uint32_t endevoutnak: 1; uint32_t xcvrdly: 1; uint32_t erraticintmsk: 1; - uint32_t reserved2b: 2; - uint32_t epmiscnt: 5; + uint32_t reserved_16: 2; + uint32_t reserved_18: 5; uint32_t descdma: 1; uint32_t perschintvl: 2; uint32_t resvalid: 6; @@ -555,13 +566,13 @@ typedef union { uint32_t sgoutnak: 1; uint32_t cgoutnak: 1; uint32_t pwronprgdone: 1; - uint32_t reserved1: 1; + uint32_t reserved_12: 1; uint32_t gmc: 2; uint32_t ignrfrmnum: 1; uint32_t nakonbble: 1; - uint32_t encountonbna: 1; - uint32_t deepsleepbeslreject: 1; - uint32_t reserved3: 13; + uint32_t encontonbna: 1; + uint32_t reserved_18: 1; + uint32_t reserved_19: 13; }; uint32_t val; } usb_dwc_dctl_reg_t; @@ -571,29 +582,29 @@ typedef union { uint32_t suspsts: 1; uint32_t enumspd: 2; uint32_t errticerr: 1; - uint32_t reserved4: 4; + uint32_t reserved_4: 4; uint32_t soffn: 14; uint32_t devlnsts: 2; - uint32_t reserved8: 8; + uint32_t reserved_24: 8; }; uint32_t val; } usb_dwc_dsts_reg_t; typedef union { struct { - uint32_t di_xfercomplmsk: 1; - uint32_t di_epdisbldmsk: 1; - uint32_t di_ahbermsk: 1; + uint32_t xfercomplmsk: 1; + uint32_t epdisbldmsk: 1; + uint32_t ahberrmsk: 1; uint32_t timeoutmsk: 1; uint32_t intkntxfempmsk: 1; uint32_t intknepmismsk: 1; uint32_t inepnakeffmsk: 1; - uint32_t reserved1: 1; + uint32_t reserved_7: 1; uint32_t txfifoundrnmsk: 1; uint32_t bnainintrmsk: 1; - uint32_t reserved3: 3; - uint32_t di_nakmsk: 1; - uint32_t reserved18: 18; + uint32_t reserved_10: 3; + uint32_t nakmsk: 1; + uint32_t reserved_14: 18; }; uint32_t val; } usb_dwc_diepmsk_reg_t; @@ -602,19 +613,19 @@ typedef union { struct { uint32_t xfercomplmsk: 1; uint32_t epdisbldmsk: 1; - uint32_t ahbermsk: 1; + uint32_t ahberrmsk: 1; uint32_t setupmsk: 1; uint32_t outtknepdismsk: 1; uint32_t stsphsercvdmsk: 1; uint32_t back2backsetup: 1; - uint32_t reserved1: 1; + uint32_t reserved_7: 1; uint32_t outpkterrmsk: 1; uint32_t bnaoutintrmsk: 1; - uint32_t reserved2: 2; + uint32_t reserved_10: 2; uint32_t bbleerrmsk: 1; uint32_t nakmsk: 1; uint32_t nyetmsk: 1; - uint32_t reserved17: 17; + uint32_t reserved_15: 17; }; uint32_t val; } usb_dwc_doepmsk_reg_t; @@ -628,7 +639,7 @@ typedef union { uint32_t inepint4: 1; uint32_t inepint5: 1; uint32_t inepint6: 1; - uint32_t reserved9a: 9; + uint32_t reserved_7: 9; uint32_t outepint0: 1; uint32_t outepint1: 1; uint32_t outepint2: 1; @@ -636,7 +647,7 @@ typedef union { uint32_t outepint4: 1; uint32_t outepint5: 1; uint32_t outepint6: 1; - uint32_t reserved9b: 9; + uint32_t reserved_24: 9; }; uint32_t val; } usb_dwc_daint_reg_t; @@ -650,7 +661,7 @@ typedef union { uint32_t inepmsk4: 1; uint32_t inepmsk5: 1; uint32_t inepmsk6: 1; - uint32_t reserved9a: 9; + uint32_t reserved_7: 9; uint32_t outepmsk0: 1; uint32_t outepmsk1: 1; uint32_t outepmsk2: 1; @@ -658,7 +669,7 @@ typedef union { uint32_t outepmsk4: 1; uint32_t outepmsk5: 1; uint32_t outepmsk6: 1; - uint32_t reserved9b: 9; + uint32_t reserved_24: 9; }; uint32_t val; } usb_dwc_daintmsk_reg_t; @@ -666,7 +677,7 @@ typedef union { typedef union { struct { uint32_t dvbusdis: 16; - uint32_t reserved16: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_dvbusdis_reg_t; @@ -674,7 +685,7 @@ typedef union { typedef union { struct { uint32_t dvbuspulse: 12; - uint32_t reserved20: 20; + uint32_t reserved_12: 20; }; uint32_t val; } usb_dwc_dvbuspulse_reg_t; @@ -685,109 +696,108 @@ typedef union { uint32_t isothren: 1; uint32_t txthrlen: 9; uint32_t ahbthrratio: 2; - uint32_t reserved3: 3; + uint32_t reserved_13: 3; uint32_t rxthren: 1; uint32_t rxthrlen: 9; - uint32_t reserved1: 1; + uint32_t reserved_26: 1; uint32_t arbprken: 1; - uint32_t reserved4: 4; + uint32_t reserved_28: 4; }; uint32_t val; } usb_dwc_dthrctl_reg_t; typedef union { struct { - uint32_t ineptxfernpmsk: 16; - uint32_t reserved16: 16; + uint32_t ineptxfempmsk: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_diepempmsk_reg_t; typedef union { struct { - uint32_t mps0: 2; - uint32_t reserved9: 9; - uint32_t reserved4: 4; - uint32_t usbactep0: 1; - uint32_t reserved1a: 1; - uint32_t naksts0: 1; - uint32_t eptype0: 2; - uint32_t reserved1b: 1; - uint32_t stall0: 1; - uint32_t txfnum0: 4; - uint32_t cnak0: 1; - uint32_t snak0: 1; - uint32_t reserved2: 2; - uint32_t epdis0: 1; - uint32_t epena0: 1; + uint32_t mps: 2; + uint32_t reserved_2: 9; + uint32_t reserved_11: 4; + uint32_t usbactep: 1; + uint32_t reserved_16: 1; + uint32_t naksts: 1; + uint32_t eptype: 2; + uint32_t reserved_20: 1; + uint32_t stall: 1; + uint32_t txfnum: 4; + uint32_t cnak: 1; + uint32_t snak: 1; + uint32_t reserved_28: 2; + uint32_t epdis: 1; + uint32_t epena: 1; }; uint32_t val; } usb_dwc_diepctl0_reg_t; typedef union { struct { - uint32_t xfercompl0: 1; - uint32_t epdisbld0: 1; - uint32_t ahberr0: 1; - uint32_t timeout0: 1; - uint32_t intkntxfemp0: 1; - uint32_t intknepmis0: 1; - uint32_t inepnakeff0: 1; - uint32_t txfemp0: 1; - uint32_t txfifoundrn0: 1; - uint32_t bnaintr0: 1; - uint32_t reserved1: 1; - uint32_t pktdrpsts0: 1; - uint32_t bbleerr0: 1; - uint32_t nakintrpt0: 1; - uint32_t nyetintrpt0: 1; - uint32_t reserved17: 17; + uint32_t xfercompl: 1; + uint32_t epdisbld: 1; + uint32_t ahberr: 1; + uint32_t timeout: 1; + uint32_t intkntxfemp: 1; + uint32_t intknepmis: 1; + uint32_t inepnakeff: 1; + uint32_t txfemp: 1; + uint32_t txfifoundrn: 1; + uint32_t bnaintr: 1; + uint32_t reserved_10: 1; + uint32_t pktdrpsts: 1; + uint32_t bbleerr: 1; + uint32_t nakintrpt: 1; + uint32_t nyetintrpt: 1; + uint32_t reserved_15: 17; }; uint32_t val; } usb_dwc_diepint0_reg_t; typedef union { struct { - uint32_t xfersize0: 7; - uint32_t reserved12: 12; - uint32_t pktcnt0: 2; - uint32_t reserved11: 11; + uint32_t xfersize: 7; + uint32_t reserved_7: 12; + uint32_t pktcnt: 2; + uint32_t reserved_21: 11; }; uint32_t val; } usb_dwc_dieptsiz0_reg_t; typedef union { struct { - uint32_t dmaaddr0; + uint32_t dmaaddr; }; uint32_t val; } usb_dwc_diepdma0_reg_t; typedef union { struct { - uint32_t ineptxfspcavail0: 16; - uint32_t reserved16: 16; + uint32_t ineptxfspcavail: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_dtxfsts0_reg_t; typedef union { struct { - uint32_t dmabufferaddr0; + uint32_t dmabufferaddr; }; uint32_t val; } usb_dwc_diepdmab0_reg_t; typedef union { struct { - uint32_t mps: 2; - uint32_t reserved9: 9; - uint32_t reserved4: 4; + uint32_t mps: 11; + uint32_t reserved_11: 4; uint32_t usbactep: 1; - uint32_t reserved1a: 1; + uint32_t dpid: 1; uint32_t naksts: 1; uint32_t eptype: 2; - uint32_t reserved1b: 1; + uint32_t reserved_20: 1; uint32_t stall: 1; uint32_t txfnum: 4; uint32_t cnak: 1; @@ -812,29 +822,29 @@ typedef union { uint32_t txfemp: 1; uint32_t txfifoundrn: 1; uint32_t bnaintr: 1; - uint32_t reserved1: 1; + uint32_t reserved_10: 1; uint32_t pktdrpsts: 1; uint32_t bbleerr: 1; uint32_t nakintrpt: 1; uint32_t nyetintrpt: 1; - uint32_t reserved15: 17; + uint32_t reserved_15: 17; }; uint32_t val; } usb_dwc_diepint_reg_t; typedef union { struct { - uint32_t xfersize: 7; - uint32_t reserved12: 12; - uint32_t pktcnt: 2; - uint32_t reserved11: 11; + uint32_t xfersize: 19; // Note: Width depends on OTG_TRANS_COUNT_WIDTH (see databook). + uint32_t pktcnt: 10; // Note: Width depends on OTG_PACKET_COUNT_WIDTH (see databook). + uint32_t mc: 2; + uint32_t reserved: 1; }; uint32_t val; } usb_dwc_dieptsiz_reg_t; typedef union { struct { - uint32_t dmaddr1; + uint32_t dmaddr; }; uint32_t val; } usb_dwc_diepdma_reg_t; @@ -842,83 +852,83 @@ typedef union { typedef union { struct { uint32_t ineptxfspcavail: 16; - uint32_t reserved16: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_dtxfsts_reg_t; typedef union { struct { - uint32_t dmabufferaddr1; + uint32_t dmabufferaddr; }; uint32_t val; } usb_dwc_diepdmab_reg_t; typedef union { struct { - uint32_t mps0: 2; - uint32_t reserved13: 13; - uint32_t usbactep0: 1; - uint32_t reserved1: 1; - uint32_t naksts0: 1; - uint32_t eptype0: 2; - uint32_t snp0: 1; - uint32_t stall0: 1; - uint32_t reserved4: 4; - uint32_t cnak0: 1; - uint32_t snak0: 1; - uint32_t reserved2: 2; - uint32_t epdis0: 1; - uint32_t epena0: 1; + uint32_t mps: 2; + uint32_t reserved_2: 13; + uint32_t usbactep: 1; + uint32_t reserved_16: 1; + uint32_t naksts: 1; + uint32_t eptype: 2; + uint32_t snp: 1; + uint32_t stall: 1; + uint32_t reserved_22: 4; + uint32_t cnak: 1; + uint32_t snak: 1; + uint32_t reserved_28: 2; + uint32_t epdis: 1; + uint32_t epena: 1; }; uint32_t val; } usb_dwc_doepctl0_reg_t; typedef union { struct { - uint32_t xfercompl0: 1; - uint32_t epdisbld0: 1; - uint32_t ahberr0: 1; - uint32_t setup0: 1; - uint32_t outtknepdis0: 1; - uint32_t stsphsercvd0: 1; - uint32_t back2backsetup0: 1; - uint32_t reserved1a: 1; - uint32_t outpkterr0: 1; - uint32_t bnaintr0: 1; - uint32_t reserved1b: 1; - uint32_t pktdrpsts0: 1; - uint32_t bbleerr0: 1; - uint32_t nakintrpt0: 1; - uint32_t nyepintrpt0: 1; - uint32_t stuppktrcvd0: 1; - uint32_t reserved16: 16; + uint32_t xfercompl: 1; + uint32_t epdisbld: 1; + uint32_t ahberr: 1; + uint32_t setup: 1; + uint32_t outtknepdis: 1; + uint32_t stsphsercvd: 1; + uint32_t back2backsetup: 1; + uint32_t reserved_7: 1; + uint32_t outpkterr: 1; + uint32_t bnaintr: 1; + uint32_t reserved_10: 1; + uint32_t pktdrpsts: 1; + uint32_t bbleerr: 1; + uint32_t nakintrpt: 1; + uint32_t nyepintrpt: 1; + uint32_t stuppktrcvd: 1; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_doepint0_reg_t; typedef union { struct { - uint32_t xfersize0: 7; - uint32_t reserved12: 12; - uint32_t pktcnt0: 1; - uint32_t reserved9: 9; - uint32_t supcnt0: 2; - uint32_t reserved1: 1; + uint32_t xfersize: 7; + uint32_t reserved_7: 12; + uint32_t pktcnt: 1; + uint32_t reserved_20: 9; + uint32_t supcnt: 2; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_doeptsiz0_reg_t; typedef union { struct { - uint32_t dmaaddr0; + uint32_t dmaaddr; }; uint32_t val; } usb_dwc_doepdma0_reg_t; typedef union { struct { - uint32_t dmabufferaddr0; + uint32_t dmabufferaddr; }; uint32_t val; } usb_dwc_doepdmab0_reg_t; @@ -926,14 +936,14 @@ typedef union { typedef union { struct { uint32_t mps: 11; - uint32_t reserved4a: 4; + uint32_t reserved_11: 4; uint32_t usbactep: 1; - uint32_t reserved1: 1; + uint32_t dpid: 1; uint32_t naksts: 1; uint32_t eptype: 2; uint32_t snp: 1; uint32_t stall: 1; - uint32_t reserved4b: 4; + uint32_t reserved_22: 4; uint32_t cnak: 1; uint32_t snak: 1; uint32_t setd0pid: 1; @@ -953,28 +963,26 @@ typedef union { uint32_t outtknepdis: 1; uint32_t stsphsercvd: 1; uint32_t back2backsetup: 1; - uint32_t reserved1a: 1; + uint32_t reserved_7: 1; uint32_t outpkterr: 1; uint32_t bnaintr: 1; - uint32_t reserved1b: 1; + uint32_t reserved_10: 1; uint32_t pktdrpsts: 1; uint32_t bbleerr: 1; uint32_t nakintrpt: 1; - uint32_t nyepintrpt: 1; + uint32_t nyetintrpt: 1; uint32_t stuppktrcvd: 1; - uint32_t reserved16: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_doepint_reg_t; typedef union { struct { - uint32_t xfersize: 7; - uint32_t reserved12: 12; - uint32_t pktcnt: 1; - uint32_t reserved9: 9; - uint32_t supcnt: 2; - uint32_t reserved1: 1; + uint32_t xfersize: 19; // Note: Width depends on OTG_TRANS_COUNT_WIDTH (see databook). + uint32_t pktcnt: 10; // Note: Width depends on OTG_PACKET_COUNT_WIDTH (see databook). + uint32_t rxdpid: 2; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_doeptsiz_reg_t; @@ -999,11 +1007,17 @@ typedef union { uint32_t gatehclk: 1; uint32_t pwrclmp: 1; uint32_t rstpdwnmodule: 1; - uint32_t reserved2: 2; + uint32_t reserved_4: 1; + uint32_t reserved_5: 1; uint32_t physleep: 1; uint32_t l1suspended: 1; uint32_t resetaftersusp: 1; - uint32_t reserved23: 23; + uint32_t reserved_9: 1; + uint32_t reserved_10: 1; + uint32_t reserved_11: 1; + uint32_t reserved_12: 1; + uint32_t reserved_13: 1; + uint32_t reserved_14: 18; }; uint32_t val; } usb_dwc_pcgcctl_reg_t; @@ -1012,21 +1026,21 @@ typedef union { typedef struct { volatile usb_dwc_hcchar_reg_t hcchar_reg; // 0x00 - uint32_t reserved_0x04_0x08[1]; // 0x04 + uint32_t reserved_0x04[1]; // 0x04 volatile usb_dwc_hcint_reg_t hcint_reg; // 0x08 volatile usb_dwc_hcintmsk_reg_t hcintmsk_reg; // 0x0c volatile usb_dwc_hctsiz_reg_t hctsiz_reg; // 0x10 volatile usb_dwc_hcdma_reg_t hcdma_reg; // 0x14 - uint32_t reserved_0x14_0x14[1]; // 0x18 + uint32_t reserved_0x18[1]; // 0x18 volatile usb_dwc_hcdmab_reg_t hcdmab_reg; // 0x1c } usb_dwc_host_chan_regs_t; typedef struct { volatile usb_dwc_diepctl_reg_t diepctl_reg; // 0x00 - uint32_t reserved_0x04_0x08[1]; // 0x04 + uint32_t reserved_0x04[1]; // 0x04 volatile usb_dwc_diepint_reg_t diepint_reg; // 0x08 - uint32_t reserved_0x0c_0x10[1]; // 0x0c - volatile usb_dwc_dieptsiz_reg_t dieptsiz_reg; // 0x010 + uint32_t reserved_0x0c[1]; // 0x0c + volatile usb_dwc_dieptsiz_reg_t dieptsiz_reg; // 0x10 volatile usb_dwc_diepdma_reg_t diepdma_reg; // 0x14 volatile usb_dwc_dtxfsts_reg_t dtxfsts_reg; // 0x18 volatile usb_dwc_diepdmab_reg_t diepdmab_reg; // 0x1c @@ -1034,19 +1048,19 @@ typedef struct { typedef struct { volatile usb_dwc_doepctl_reg_t doepctl_reg; // 0x00 - uint32_t reserved_0x04_0x08[1]; // 0x04 + uint32_t reserved_0x04[1]; // 0x04 volatile usb_dwc_doepint_reg_t doepint_reg; // 0x08 - uint32_t reserved_0x0c_0x10[1]; // 0x0c + uint32_t reserved_0x0c[1]; // 0x0c volatile usb_dwc_doeptsiz_reg_t doeptsiz_reg; // 0x10 volatile usb_dwc_doepdma_reg_t doepdma_reg; // 0x14 - uint32_t reserved_0x18_0x1c[1]; // 0x18 + uint32_t reserved_0x18[1]; // 0x18 volatile usb_dwc_doepdmab_reg_t doepdmab_reg; // 0x1c } usb_dwc_out_ep_regs_t; /* --------------------------- Register Layout ------------------------------ */ typedef struct { - //Global Registers + // Global Registers volatile usb_dwc_gotgctl_reg_t gotgctl_reg; // 0x0000 volatile usb_dwc_gotgint_reg_t gotgint_reg; // 0x0004 volatile usb_dwc_gahbcfg_reg_t gahbcfg_reg; // 0x0008 @@ -1059,94 +1073,106 @@ typedef struct { volatile usb_dwc_grxfsiz_reg_t grxfsiz_reg; // 0x0024 volatile usb_dwc_gnptxfsiz_reg_t gnptxfsiz_reg; // 0x0028 volatile usb_dwc_gnptxsts_reg_t gnptxsts_reg; // 0x002c - uint32_t reserved_0x0030_0x0040[4]; // 0x0030 to 0x0040 + uint32_t reserved_0x0030; // 0x0030 + uint32_t reserved_0x0034; // 0x0034 + uint32_t reserved_0x0038; // 0x0038 + uint32_t reserved_0x003c; // 0x003c volatile usb_dwc_gsnpsid_reg_t gsnpsid_reg; // 0x0040 volatile usb_dwc_ghwcfg1_reg_t ghwcfg1_reg; // 0x0044 volatile usb_dwc_ghwcfg2_reg_t ghwcfg2_reg; // 0x0048 volatile usb_dwc_ghwcfg3_reg_t ghwcfg3_reg; // 0x004c volatile usb_dwc_ghwcfg4_reg_t ghwcfg4_reg; // 0x0050 - uint32_t reserved_0x0054_0x005c[2]; // 0x0054 to 0x005c - - //FIFO Configurations + uint32_t reserved_0x0054; // 0x0054 + uint32_t reserved_0x0058; // 0x0058 volatile usb_dwc_gdfifocfg_reg_t gdfifocfg_reg; // 0x005c - uint32_t reserved_0x0060_0x0100[40]; // 0x0060 to 0x0100 + uint32_t reserved_0x0060; // 0x0060 + uint32_t reserved_0x0064_0x0100[39]; // 0x0064 to 0x0100 volatile usb_dwc_hptxfsiz_reg_t hptxfsiz_reg; // 0x0100 - volatile usb_dwc_dieptxfi_reg_t dieptxfi_regs[4]; // 0x0104 to 0x0114 - usb_dwc_dieptxfi_reg_t reserved_0x0114_0x0140[11]; // 0x0114 to 0x0140 - uint32_t reserved_0x140_0x400[176]; // 0x0140 to 0x0400 + volatile usb_dwc_dieptxfi_reg_t dieptxf_regs[4]; // 0x0104 to 0x0110 (depends on OTG_NUM_IN_EPS) + usb_dwc_dieptxfi_reg_t reserved_0x0114_0x013c[11]; // 0x0114 to 0x013c (depends on OTG_NUM_IN_EPS) + uint32_t reserved_0x140_0x3fc[176]; // 0x0140 to 0x03fc - //Host Mode Registers + // Host Mode Registers volatile usb_dwc_hcfg_reg_t hcfg_reg; // 0x0400 volatile usb_dwc_hfir_reg_t hfir_reg; // 0x0404 volatile usb_dwc_hfnum_reg_t hfnum_reg; // 0x0408 - uint32_t reserved_0x40c_0x410[1]; // 0x040c to 0x0410 + uint32_t reserved_0x40c[1]; // 0x040c volatile usb_dwc_hptxsts_reg_t hptxsts_reg; // 0x0410 volatile usb_dwc_haint_reg_t haint_reg; // 0x0414 volatile usb_dwc_haintmsk_reg_t haintmsk_reg; // 0x0418 volatile usb_dwc_hflbaddr_reg_t hflbaddr_reg; // 0x041c - uint32_t reserved_0x420_0x440[8]; // 0x0420 to 0x0440 + uint32_t reserved_0x420_0x43c[8]; // 0x0420 to 0x043c volatile usb_dwc_hprt_reg_t hprt_reg; // 0x0440 - uint32_t reserved_0x0444_0x0500[47]; // 0x0444 to 0x0500 - usb_dwc_host_chan_regs_t host_chans[8]; // 0x0500 to 0x0600 - usb_dwc_host_chan_regs_t reserved_0x0600_0x0700[8]; // 0x0600 to 0x0700 - uint32_t reserved_0x0700_0x0800[64]; // 0x0700 to 0x0800 + uint32_t reserved_0x0444_0x04fc[47]; // 0x0444 to 0x04fc + + // Host Channel Registers + usb_dwc_host_chan_regs_t host_chans[8]; // 0x0500 to 0x05fc (depends on OTG_NUM_HOST_CHAN) + usb_dwc_host_chan_regs_t reserved_0x0600_0x06fc[8]; // 0x0600 to 0x06fc (depends on OTG_NUM_HOST_CHAN) + uint32_t reserved_0x0700_0x07fc[64]; // 0x0700 to 0x07fc + + // Device Mode Registers volatile usb_dwc_dcfg_reg_t dcfg_reg; // 0x0800 volatile usb_dwc_dctl_reg_t dctl_reg; // 0x0804 volatile usb_dwc_dsts_reg_t dsts_reg; // 0x0808 - uint32_t reserved_0x080c_0x0810[1]; // 0x080c to 0x0810 - - //Device Mode Registers - volatile usb_dwc_diepmsk_reg_t diepmsk_reg; // 0x810 + uint32_t reserved_0x080c[1]; // 0x080c + volatile usb_dwc_diepmsk_reg_t diepmsk_reg; // 0x0810 volatile usb_dwc_doepmsk_reg_t doepmsk_reg; // 0x0814 volatile usb_dwc_daint_reg_t daint_reg; // 0x0818 volatile usb_dwc_daintmsk_reg_t daintmsk_reg; // 0x081c - uint32_t reserved_0x0820_0x0828[2]; // 0x0820 to 0x0828 + uint32_t reserved_0x0820; // 0x0820 + uint32_t reserved_0x0824; // 0x0824 volatile usb_dwc_dvbusdis_reg_t dvbusdis_reg; // 0x0828 volatile usb_dwc_dvbuspulse_reg_t dvbuspulse_reg; // 0x082c volatile usb_dwc_dthrctl_reg_t dthrctl_reg; // 0x0830 volatile usb_dwc_diepempmsk_reg_t diepempmsk_reg; // 0x0834 - uint32_t reserved_0x0838_0x0900[50]; // 0x0838 to 0x0900 - - //Deivce: IN EP0 reigsters + uint32_t reserved_0x0838; // 0x0838 + uint32_t reserved_0x083c; // 0x083c + uint32_t reserved_0x0840; // 0x0840 + uint32_t reserved_0x0844_0x087c[15]; // 0x0844 to 0x087c (depends on OTG_NUM_EPS) + uint32_t reserved_0x0880; // 0x0880 + uint32_t reserved_0x0884_0x08c0[15]; // 0x0884 to 0x08c0 (depends on OTG_NUM_EPS) + uint32_t reserved_0x08c4_0x08fc[16]; // 0x08c4 to 0x08fc + + // Device: IN EP0 registers volatile usb_dwc_diepctl0_reg_t diepctl0_reg; // 0x0900 - uint32_t reserved_0x0904_0x0908[1]; // 0x0904 to 0x0908 + uint32_t reserved_0x0904[1]; // 0x0904 volatile usb_dwc_diepint0_reg_t diepint0_reg; // 0x0908 - uint32_t reserved_0x090c_0x0910[1]; // 0x090c to 0x0910 + uint32_t reserved_0x090c[1]; // 0x090c volatile usb_dwc_dieptsiz0_reg_t dieptsiz0_reg; // 0x0910 volatile usb_dwc_diepdma0_reg_t diepdma0_reg; // 0x0914 volatile usb_dwc_dtxfsts0_reg_t dtxfsts0_reg; // 0x0918 volatile usb_dwc_diepdmab0_reg_t diepdmab0_reg; // 0x091c - //Deivce: IN EP registers - usb_dwc_in_ep_regs_t in_eps[6]; // 0x0920 to 0x09e0 - usb_dwc_in_ep_regs_t reserved_0x09e0_0x0b00[9]; // 0x09e0 to 0x0b00 + // Device: IN EP registers + usb_dwc_in_ep_regs_t in_eps[6]; // 0x0920 to 0x09dc (depends on OTG_NUM_EPS) + usb_dwc_in_ep_regs_t reserved_0x09e0_0x0afc[9]; // 0x09e0 to 0x0afc (depends on OTG_NUM_EPS) - //Device: OUT EP0 reigsters + // Device: OUT EP0 registers volatile usb_dwc_doepctl0_reg_t doepctl0_reg; // 0x0b00 - uint32_t reserved_0x0b04_0x0b08[1]; // 0x0b04 to 0x0b08 + uint32_t reserved_0x0b04[1]; // 0x0b04 volatile usb_dwc_doepint0_reg_t doepint0_reg; // 0b0b08 - uint32_t reserved_0x0b0c_0x0b10[1]; // 0x0b0c to 0x0b10 + uint32_t reserved_0x0b0c[1]; // 0x0b0c volatile usb_dwc_doeptsiz0_reg_t doeptsiz0_reg; // 0x0b10 volatile usb_dwc_doepdma0_reg_t doepdma0_reg; // 0x0b14 - uint32_t reserved_0x0b18_0x0b1c[1]; // 0x0b18 to 0x0b1c + uint32_t reserved_0x0b18[1]; // 0x0b18 volatile usb_dwc_doepdmab0_reg_t doepdmab0_reg; // 0x0b1c - //Deivce: OUT EP registers - usb_dwc_out_ep_regs_t out_eps[6]; // 0xb1c - usb_dwc_out_ep_regs_t reserved_0x0be0_0x0d00[9]; // 0x0be0 to 0x0d00 - uint32_t reserved_0x0d00_0x0e00[64]; // 0x0d00 to 0x0e00 + // Device: OUT EP registers + usb_dwc_out_ep_regs_t out_eps[6]; // 0x0b20 to 0x0bdc (depends on OTG_NUM_EPS) + usb_dwc_out_ep_regs_t reserved_0x0be0_0x0d00[9]; // 0x0be0 to 0x0cfc (depends on OTG_NUM_EPS) + uint32_t reserved_0x0d00_0x0dfc[64]; // 0x0d00 to 0x0dfc + + // Power and Clock Gating volatile usb_dwc_pcgcctl_reg_t pcgcctl_reg; // 0x0e00 - uint32_t reserved_0x0e04_0x0e08[1]; // 0x0d00 to 0x0e00 + uint32_t reserved_0x0e04[1]; // 0x0e04 } usb_dwc_dev_t; - #ifndef __cplusplus _Static_assert(sizeof(usb_dwc_dev_t) == 0xe08, "Invalid size of usb_dwc_dev_t structure"); #endif extern usb_dwc_dev_t USB_DWC; - #ifdef __cplusplus } #endif diff --git a/components/soc/esp32s2/include/soc/usb_pins.h b/components/soc/esp32s2/include/soc/usb_pins.h index 436df2baa6..8c837fed27 100644 --- a/components/soc/esp32s2/include/soc/usb_pins.h +++ b/components/soc/esp32s2/include/soc/usb_pins.h @@ -1,12 +1,18 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once -/* GPIOs used to connect an external USB PHY */ +/* +Note: These macros are deprecated. When connecting USB OTG to an external FSLS +PHY, the FSLS Serial Interface signals can be routed to any GPIO via the GPIO +matrix. Thus, these macros are meaningless. + +Todo: Remove in IDF v6.0 (IDF-9029) +*/ #define USBPHY_VP_NUM 33 #define USBPHY_VM_NUM 34 #define USBPHY_RCV_NUM 35 diff --git a/components/soc/esp32s2/include/soc/usb_struct.h b/components/soc/esp32s2/include/soc/usb_struct.h index 14277b10e8..697c79e416 100644 --- a/components/soc/esp32s2/include/soc/usb_struct.h +++ b/components/soc/esp32s2/include/soc/usb_struct.h @@ -1,26 +1,41 @@ -// 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-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include -#include "usb_types.h" #ifdef __cplusplus extern "C" { #endif +/* USB IN EP Register block type */ +typedef struct usb_in_ep_reg { + volatile uint32_t diepctl; + uint32_t reserved; + volatile uint32_t diepint; + uint32_t reserved1; + volatile uint32_t dieptsiz; + volatile uint32_t diepdma; + volatile uint32_t dtxfsts; + uint32_t reserved2; +} usb_in_endpoint_t; + +/* USB OUT EP Register block type */ +typedef struct usb_out_ep_reg { + volatile uint32_t doepctl; + uint32_t reserved; + volatile uint32_t doepint; + uint32_t reserved1; + volatile uint32_t doeptsiz; + volatile uint32_t doepdma; + uint32_t reserved2; + uint32_t reserved3; +} usb_out_endpoint_t; + typedef struct usb_reg { volatile uint32_t gotgctl; // 0x0000 OTG Control and Status Register volatile uint32_t gotgint; // 0x0004 OTG Interrupt Register @@ -82,10 +97,10 @@ typedef struct usb_reg { volatile uint32_t dtknqr4_fifoemptymsk; // 0x0834 Device IN Endpoint FIFO Empty Interrupt Mask register uint32_t reserved_0x0838_0x0900[50]; // 0x0838 to 0x0900 // Input Endpoints - usb_in_endpoint_t in_ep_reg[USB_IN_EP_NUM]; // 0x0900 to 0x09e0 IN EP registers + usb_in_endpoint_t in_ep_reg[7]; // 0x0900 to 0x09e0 IN EP registers uint32_t reserved_0x09e0_0x0b00[72]; // 0x09e0 to 0x0b00 // Output Endpoints - usb_out_endpoint_t out_ep_reg[USB_OUT_EP_NUM]; // 0x0b00 to 0x0be0 OUT EP registers + usb_out_endpoint_t out_ep_reg[7]; // 0x0b00 to 0x0be0 OUT EP registers uint32_t reserved_0x0be0_0x0d00[72]; // 0x0be0 to 0x0d00 uint32_t reserved_0x0d00_0x0e00[64]; // 0x0d00 to 0x0e00 /** diff --git a/components/soc/esp32s2/include/soc/usb_types.h b/components/soc/esp32s2/include/soc/usb_types.h deleted file mode 100644 index 69e213ec84..0000000000 --- a/components/soc/esp32s2/include/soc/usb_types.h +++ /dev/null @@ -1,73 +0,0 @@ -// 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. - -#pragma once -#ifdef __cplusplus -extern "C" -{ -#endif - -#include - -/* USB IN EP index */ -typedef enum { - USB_IN_EP_0 = 0, - USB_IN_EP_1, - USB_IN_EP_2, - USB_IN_EP_3, - USB_IN_EP_4, - USB_IN_EP_5, - USB_IN_EP_6, - USB_IN_EP_NUM -} usb_in_ep_idx_t; - -/* USB OUT EP index */ -typedef enum { - USB_OUT_EP_0 = 0, - USB_OUT_EP_1, - USB_OUT_EP_2, - USB_OUT_EP_3, - USB_OUT_EP_4, - USB_OUT_EP_5, - USB_OUT_EP_6, - USB_OUT_EP_NUM -} usb_out_ep_idx_t; - -/* USB IN EP Register block type */ -typedef struct usb_in_ep_reg { - volatile uint32_t diepctl; - uint32_t reserved; - volatile uint32_t diepint; - uint32_t reserved1; - volatile uint32_t dieptsiz; - volatile uint32_t diepdma; - volatile uint32_t dtxfsts; - uint32_t reserved2; -} usb_in_endpoint_t; - -/* USB OUT EP Register block type */ -typedef struct usb_out_ep_reg { - volatile uint32_t doepctl; - uint32_t reserved; - volatile uint32_t doepint; - uint32_t reserved1; - volatile uint32_t doeptsiz; - volatile uint32_t doepdma; - uint32_t reserved2; - uint32_t reserved3; -} usb_out_endpoint_t; - -#ifdef __cplusplus -} -#endif diff --git a/components/soc/esp32s2/include/soc/usb_wrap_struct.h b/components/soc/esp32s2/include/soc/usb_wrap_struct.h index 1b89179774..0a01ebb0e1 100644 --- a/components/soc/esp32s2/include/soc/usb_wrap_struct.h +++ b/components/soc/esp32s2/include/soc/usb_wrap_struct.h @@ -153,7 +153,7 @@ typedef union { * USB D- rx value in test. */ uint32_t test_rx_dm:1; - uint32_t reserved:25; + uint32_t reserved_7:25; }; uint32_t val; } usb_wrap_test_conf_reg_t; diff --git a/components/soc/esp32s3/usb_otg_periph.c b/components/soc/esp32s2/usb_dwc_periph.c similarity index 91% rename from components/soc/esp32s3/usb_otg_periph.c rename to components/soc/esp32s2/usb_dwc_periph.c index e2f96e23b6..eba3eaaf60 100644 --- a/components/soc/esp32s3/usb_otg_periph.c +++ b/components/soc/esp32s2/usb_dwc_periph.c @@ -1,10 +1,10 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/usb_otg_periph.h" +#include "soc/usb_dwc_periph.h" #include "soc/gpio_sig_map.h" /* diff --git a/components/soc/esp32s2/usb_periph.c b/components/soc/esp32s2/usb_periph.c index 2f55335feb..a3fda7193e 100644 --- a/components/soc/esp32s2/usb_periph.c +++ b/components/soc/esp32s2/usb_periph.c @@ -1,20 +1,19 @@ -// 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: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "soc/soc_caps.h" #include "soc/usb_periph.h" +/* +Note: These IO pins are deprecated. When connecting USB OTG to an external FSLS +PHY, the FSLS Serial Interface signals can be routed to any GPIO via the GPIO +matrix. Thus, this mapping of signals to IO pins is meaningless. + +Todo: Remove in IDF v6.0 (IDF-9029) +*/ const usb_iopin_dsc_t usb_periph_iopins[] = { {USBPHY_VP_NUM, USB_EXTPHY_VP_IDX, 0, 1}, {USBPHY_VM_NUM, USB_EXTPHY_VM_IDX, 0, 1}, diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index c7508d3437..5a5d5e373f 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -339,7 +339,7 @@ config SOC_CPU_WATCHPOINTS_NUM int default 2 -config SOC_CPU_WATCHPOINT_SIZE +config SOC_CPU_WATCHPOINT_MAX_REGION_SIZE int default 64 @@ -915,9 +915,9 @@ config SOC_UART_REQUIRE_CORE_RESET bool default y -config SOC_USB_PERIPH_NUM - bool - default y +config SOC_USB_OTG_PERIPH_NUM + int + default 1 config SOC_SHA_DMA_MAX_BUFFER_SIZE int @@ -1247,6 +1247,10 @@ config SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW bool default y +config SOC_WIFI_PHY_NEEDS_USB_WORKAROUND + bool + default y + config SOC_BLE_SUPPORTED bool default y @@ -1270,3 +1274,7 @@ config SOC_BLUFI_SUPPORTED config SOC_ULP_HAS_ADC bool default y + +config SOC_PHY_COMBO_MODULE + bool + default y diff --git a/components/soc/esp32s3/include/soc/efuse_defs.h b/components/soc/esp32s3/include/soc/efuse_defs.h index 6c61b202b9..6dacc58906 100644 --- a/components/soc/esp32s3/include/soc/efuse_defs.h +++ b/components/soc/esp32s3/include/soc/efuse_defs.h @@ -12,6 +12,9 @@ extern "C" { #define EFUSE_WRITE_OP_CODE 0x5a5a #define EFUSE_READ_OP_CODE 0x5aa5 +#define EFUSE_PKG_VERSION_ESP32S3 0 // QFN56 +#define EFUSE_PKG_VERSION_ESP32S3PICO 1 // LGA56 + /** EFUSE_RD_MAC_SPI_SYS_2_REG register * BLOCK1 data register 2. */ diff --git a/components/soc/esp32s3/include/soc/efuse_reg.h b/components/soc/esp32s3/include/soc/efuse_reg.h index 6b4119620b..c4b8a5ed47 100644 --- a/components/soc/esp32s3/include/soc/efuse_reg.h +++ b/components/soc/esp32s3/include/soc/efuse_reg.h @@ -816,25 +816,60 @@ extern "C" { #define EFUSE_BLK_VERSION_MINOR_M (EFUSE_BLK_VERSION_MINOR_V << EFUSE_BLK_VERSION_MINOR_S) #define EFUSE_BLK_VERSION_MINOR_V 0x00000007U #define EFUSE_BLK_VERSION_MINOR_S 24 -/** EFUSE_RESERVED_1_123 : R; bitpos: [31:27]; default: 0; - * reserved +/** EFUSE_FLASH_CAP : R; bitpos: [29:27]; default: 0; + * Flash capacity + */ +#define EFUSE_FLASH_CAP 0x00000007U +#define EFUSE_FLASH_CAP_M (EFUSE_FLASH_CAP_V << EFUSE_FLASH_CAP_S) +#define EFUSE_FLASH_CAP_V 0x00000007U +#define EFUSE_FLASH_CAP_S 27 +/** EFUSE_FLASH_TEMP : R; bitpos: [31:30]; default: 0; + * Flash temperature */ -#define EFUSE_RESERVED_1_123 0x0000001FU -#define EFUSE_RESERVED_1_123_M (EFUSE_RESERVED_1_123_V << EFUSE_RESERVED_1_123_S) -#define EFUSE_RESERVED_1_123_V 0x0000001FU -#define EFUSE_RESERVED_1_123_S 27 +#define EFUSE_FLASH_TEMP 0x00000003U +#define EFUSE_FLASH_TEMP_M (EFUSE_FLASH_TEMP_V << EFUSE_FLASH_TEMP_S) +#define EFUSE_FLASH_TEMP_V 0x00000003U +#define EFUSE_FLASH_TEMP_S 30 /** EFUSE_RD_MAC_SPI_SYS_4_REG register * BLOCK1 data register 4. */ #define EFUSE_RD_MAC_SPI_SYS_4_REG (DR_REG_EFUSE_BASE + 0x54) -/** EFUSE_RESERVED_1_128 : R; bitpos: [12:0]; default: 0; +/** EFUSE_FLASH_VENDOR : R; bitpos: [2:0]; default: 0; + * Flash vendor + */ +#define EFUSE_FLASH_VENDOR 0x00000007U +#define EFUSE_FLASH_VENDOR_M (EFUSE_FLASH_VENDOR_V << EFUSE_FLASH_VENDOR_S) +#define EFUSE_FLASH_VENDOR_V 0x00000007U +#define EFUSE_FLASH_VENDOR_S 0 +/** EFUSE_PSRAM_CAP : R; bitpos: [4:3]; default: 0; + * PSRAM capacity + */ +#define EFUSE_PSRAM_CAP 0x00000003U +#define EFUSE_PSRAM_CAP_M (EFUSE_PSRAM_CAP_V << EFUSE_PSRAM_CAP_S) +#define EFUSE_PSRAM_CAP_V 0x00000003U +#define EFUSE_PSRAM_CAP_S 3 +/** EFUSE_PSRAM_TEMP : R; bitpos: [6:5]; default: 0; + * PSRAM temperature + */ +#define EFUSE_PSRAM_TEMP 0x00000003U +#define EFUSE_PSRAM_TEMP_M (EFUSE_PSRAM_TEMP_V << EFUSE_PSRAM_TEMP_S) +#define EFUSE_PSRAM_TEMP_V 0x00000003U +#define EFUSE_PSRAM_TEMP_S 5 +/** EFUSE_PSRAM_VENDOR : R; bitpos: [8:7]; default: 0; + * PSRAM vendor + */ +#define EFUSE_PSRAM_VENDOR 0x00000003U +#define EFUSE_PSRAM_VENDOR_M (EFUSE_PSRAM_VENDOR_V << EFUSE_PSRAM_VENDOR_S) +#define EFUSE_PSRAM_VENDOR_V 0x00000003U +#define EFUSE_PSRAM_VENDOR_S 7 +/** EFUSE_RESERVED_1_137 : R; bitpos: [12:9]; default: 0; * reserved */ -#define EFUSE_RESERVED_1_128 0x00001FFFU -#define EFUSE_RESERVED_1_128_M (EFUSE_RESERVED_1_128_V << EFUSE_RESERVED_1_128_S) -#define EFUSE_RESERVED_1_128_V 0x00001FFFU -#define EFUSE_RESERVED_1_128_S 0 +#define EFUSE_RESERVED_1_137 0x0000000FU +#define EFUSE_RESERVED_1_137_M (EFUSE_RESERVED_1_137_V << EFUSE_RESERVED_1_137_S) +#define EFUSE_RESERVED_1_137_V 0x0000000FU +#define EFUSE_RESERVED_1_137_S 9 /** EFUSE_K_RTC_LDO : R; bitpos: [19:13]; default: 0; * BLOCK1 K_RTC_LDO */ diff --git a/components/soc/esp32s3/include/soc/efuse_struct.h b/components/soc/esp32s3/include/soc/efuse_struct.h index c5f811d94e..a3c589f543 100644 --- a/components/soc/esp32s3/include/soc/efuse_struct.h +++ b/components/soc/esp32s3/include/soc/efuse_struct.h @@ -602,10 +602,14 @@ typedef union { * BLK_VERSION_MINOR */ uint32_t blk_version_minor:3; - /** reserved_1_123 : R; bitpos: [31:27]; default: 0; - * reserved + /** flash_cap : R; bitpos: [29:27]; default: 0; + * Flash capacity + */ + uint32_t flash_cap:3; + /** flash_temp : R; bitpos: [31:30]; default: 0; + * Flash temperature */ - uint32_t reserved_1_123:5; + uint32_t flash_temp:2; }; uint32_t val; } efuse_rd_mac_spi_sys_3_reg_t; @@ -615,10 +619,26 @@ typedef union { */ typedef union { struct { - /** reserved_1_128 : R; bitpos: [12:0]; default: 0; + /** flash_vendor : R; bitpos: [2:0]; default: 0; + * Flash vendor + */ + uint32_t flash_vendor:3; + /** psram_cap : R; bitpos: [4:3]; default: 0; + * PSRAM capacity + */ + uint32_t psram_cap:2; + /** psram_temp : R; bitpos: [6:5]; default: 0; + * PSRAM temperature + */ + uint32_t psram_temp:2; + /** psram_vendor : R; bitpos: [8:7]; default: 0; + * PSRAM vendor + */ + uint32_t psram_vendor:2; + /** reserved_1_137 : R; bitpos: [12:9]; default: 0; * reserved */ - uint32_t reserved_1_128:13; + uint32_t reserved_1_137:4; /** k_rtc_ldo : R; bitpos: [19:13]; default: 0; * BLOCK1 K_RTC_LDO */ diff --git a/components/soc/esp32s3/include/soc/regi2c_defs.h b/components/soc/esp32s3/include/soc/regi2c_defs.h index 8b90a70b6c..e6a6e9cb72 100644 --- a/components/soc/esp32s3/include/soc/regi2c_defs.h +++ b/components/soc/esp32s3/include/soc/regi2c_defs.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 */ @@ -27,7 +27,7 @@ /** * Restore regi2c analog calibration related configuration registers. - * This is a workaround, and is fixed on later chips + * This is a workaround for calibration error when waking up from light sleep */ #define REGI2C_ANA_CALI_PD_WORKAROUND 1 #define REGI2C_ANA_CALI_BYTE_NUM 8 diff --git a/components/soc/esp32s3/include/soc/rtc_cntl_reg.h b/components/soc/esp32s3/include/soc/rtc_cntl_reg.h index c66e06b38a..107b729d79 100644 --- a/components/soc/esp32s3/include/soc/rtc_cntl_reg.h +++ b/components/soc/esp32s3/include/soc/rtc_cntl_reg.h @@ -3689,7 +3689,7 @@ Due to the LDO slaves, RTC_CNTL_DATE_REG[18:13] can only be used for LDO adjustm /*LDO SLAVE : R/W ;bitpos:[18:13] ; default: 6'd0 ;*/ /*description: .*/ #define RTC_CNTL_SLAVE_PD 0x0000003F -#define RTC_CNTL_SLAVE_PD_M ((RTC_CNTL_SLAVE_V)<<(RTC_CNTL_SLAVE_S)) +#define RTC_CNTL_SLAVE_PD_M ((RTC_CNTL_SLAVE_PD_V)<<(RTC_CNTL_SLAVE_PD_S)) #define RTC_CNTL_SLAVE_PD_V 0x3F #define RTC_CNTL_SLAVE_PD_S 13 diff --git a/components/soc/esp32s3/include/soc/soc.h b/components/soc/esp32s3/include/soc/soc.h index a2d5031769..2204ad683d 100644 --- a/components/soc/esp32s3/include/soc/soc.h +++ b/components/soc/esp32s3/include/soc/soc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,14 +27,15 @@ #define DR_REG_EXT_MEM_ENC 0x600CC000 -#define REG_UHCI_BASE(i) (DR_REG_UHCI0_BASE - (i) * 0x8000) -#define REG_UART_BASE( i ) (DR_REG_UART_BASE + (i) * 0x10000 + ( (i) > 1 ? 0xe000 : 0 ) ) -#define REG_UART_AHB_BASE(i) (0x60000000 + (i) * 0x10000 + ( (i) > 1 ? 0xe000 : 0 ) ) -#define UART_FIFO_AHB_REG(i) (REG_UART_AHB_BASE(i) + 0x0) -#define REG_I2S_BASE( i ) (DR_REG_I2S_BASE + (i) * 0x1E000) -#define REG_TIMG_BASE(i) (DR_REG_TIMERGROUP0_BASE + (i)*0x1000) +#define REG_UHCI_BASE(i) (DR_REG_UHCI0_BASE - (i) * 0x8000) +#define REG_UART_BASE( i ) (DR_REG_UART_BASE + (i) * 0x10000 + ( (i) > 1 ? 0xe000 : 0 ) ) +#define REG_UART_AHB_BASE(i) (0x60000000 + (i) * 0x10000 + ( (i) > 1 ? 0xe000 : 0 ) ) +#define UART_FIFO_AHB_REG(i) (REG_UART_AHB_BASE(i) + 0x0) +#define REG_I2S_BASE( i ) (DR_REG_I2S_BASE + (i) * 0x1E000) +#define REG_TIMG_BASE(i) (DR_REG_TIMERGROUP0_BASE + (i)*0x1000) #define REG_SPI_MEM_BASE(i) (DR_REG_SPI0_BASE - (i) * 0x1000) -#define REG_I2C_BASE(i) (DR_REG_I2C_EXT_BASE + (i) * 0x14000 ) +#define REG_SPI_BASE(i) (((i)>=2) ? (DR_REG_SPI2_BASE + (i-2) * 0x1000) : (0)) // GPSPI2 and GPSPI3 +#define REG_I2C_BASE(i) (DR_REG_I2C_EXT_BASE + (i) * 0x14000 ) //Convenient way to replace the register ops when ulp riscv projects //consume this file @@ -155,7 +156,6 @@ #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 (80*1000000) -#define MODEM_REQUIRED_MIN_APB_CLK_FREQ (80*1000000) #define REF_CLK_FREQ (1000000) #define XTAL_CLK_FREQ (40*1000000) #define UART_CLK_FREQ APB_CLK_FREQ @@ -168,7 +168,7 @@ /* Overall memory map */ #define SOC_DROM_LOW 0x3C000000 -#define SOC_DROM_HIGH 0x3D000000 +#define SOC_DROM_HIGH 0x3E000000 #define SOC_IROM_LOW 0x42000000 #define SOC_IROM_HIGH 0x44000000 #define SOC_IRAM_LOW 0x40370000 @@ -187,7 +187,7 @@ #define SOC_EXTRAM_DATA_LOW 0x3C000000 #define SOC_EXTRAM_DATA_HIGH 0x3E000000 #define SOC_IROM_MASK_LOW 0x40000000 -#define SOC_IROM_MASK_HIGH 0x4001A100 +#define SOC_IROM_MASK_HIGH 0x40060000 #define SOC_EXTRAM_DATA_SIZE (SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW) #define SOC_MAX_CONTIGUOUS_RAM_SIZE (SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW) ///< Largest span of contiguous memory (DRAM or IRAM) in the address space @@ -225,50 +225,8 @@ #define SOC_ROM_STACK_START 0x3fceb710 #define SOC_ROM_STACK_SIZE 0x2000 -//interrupt cpu using table, Please see the core-isa.h -/************************************************************************************************************* - * Intr num Level Type PRO CPU usage APP CPU uasge - * 0 1 extern level WMAC Reserved - * 1 1 extern level BT/BLE Host HCI DMA BT/BLE Host HCI DMA - * 2 1 extern level - * 3 1 extern level - * 4 1 extern level WBB - * 5 1 extern level BT/BLE Controller BT/BLE Controller - * 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1) - * 7 1 software BT/BLE VHCI BT/BLE VHCI - * 8 1 extern level BT/BLE BB(RX/TX) BT/BLE BB(RX/TX) - * 9 1 extern level - * 10 1 extern edge - * 11 3 profiling - * 12 1 extern level - * 13 1 extern level - * 14 7 nmi Reserved Reserved - * 15 3 timer FreeRTOS Tick(L3) FreeRTOS Tick(L3) - * 16 5 timer - * 17 1 extern level - * 18 1 extern level - * 19 2 extern level - * 20 2 extern level - * 21 2 extern level - * 22 3 extern edge - * 23 3 extern level - * 24 4 extern level TG1_WDT - * 25 4 extern level CACHEERR - * 26 5 extern level - * 27 3 extern level Reserved Reserved - * 28 4 extern edge IPC_ISR IPC_ISR - * 29 3 software Reserved Reserved - * 30 4 extern edge Reserved Reserved - * 31 5 extern level - ************************************************************************************************************* - */ - -//CPU0 Interrupt number reserved, not touch this. #define ETS_WMAC_INUM 0 -#define ETS_BT_HOST_INUM 1 #define ETS_WBB_INUM 4 -#define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/ -#define ETS_FRC1_INUM 22 #define ETS_T1_WDT_INUM 24 #define ETS_MEMACCESS_ERR_INUM 25 #define ETS_CACHEERR_INUM ETS_MEMACCESS_ERR_INUM diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index d928962c01..900db1ba1c 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -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 */ @@ -127,9 +127,9 @@ #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FPU 1 -#define SOC_CPU_BREAKPOINTS_NUM 2 -#define SOC_CPU_WATCHPOINTS_NUM 2 -#define SOC_CPU_WATCHPOINT_SIZE 64 // bytes +#define SOC_CPU_BREAKPOINTS_NUM 2 +#define SOC_CPU_WATCHPOINTS_NUM 2 +#define SOC_CPU_WATCHPOINT_MAX_REGION_SIZE 64 // bytes /*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/ /** The maximum length of a Digital Signature in bits. */ @@ -275,7 +275,10 @@ /*-------------------------- RTCIO CAPS --------------------------------------*/ #define SOC_RTCIO_PIN_COUNT 22 -#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 +#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature, + * so it supports unique IOMUX configuration (including IE, OE, PU, PD, DRV etc.) + * when the pins are switched to RTC function. + */ #define SOC_RTCIO_HOLD_SUPPORTED 1 #define SOC_RTCIO_WAKE_SUPPORTED 1 @@ -363,7 +366,7 @@ #define SOC_UART_REQUIRE_CORE_RESET (1) /*-------------------------- USB CAPS ----------------------------------------*/ -#define SOC_USB_PERIPH_NUM 1 +#define SOC_USB_OTG_PERIPH_NUM (1U) /*--------------------------- SHA CAPS ---------------------------------------*/ @@ -506,6 +509,7 @@ #define SOC_WIFI_CSI_SUPPORT (1) /*!< Support CSI */ #define SOC_WIFI_MESH_SUPPORT (1) /*!< Support WIFI MESH */ #define SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW (1) /*!< Support delta early time for rf phy on/off */ +#define SOC_WIFI_PHY_NEEDS_USB_WORKAROUND (1) /*!< SoC has WiFi and USB PHYs interference, needs a workaround */ /*---------------------------------- Bluetooth CAPS ----------------------------------*/ #define SOC_BLE_SUPPORTED (1) /*!< Support Bluetooth Low Energy hardware */ @@ -516,3 +520,6 @@ /*-------------------------- ULP CAPS ----------------------------------------*/ #define SOC_ULP_HAS_ADC (1) /* ADC can be accessed from ULP */ + +/*------------------------------------- PHY CAPS -------------------------------------*/ +#define SOC_PHY_COMBO_MODULE (1) /*!< Support Wi-Fi and BLE*/ diff --git a/components/soc/esp32s3/include/soc/usb_dwc_cfg.h b/components/soc/esp32s3/include/soc/usb_dwc_cfg.h new file mode 100644 index 0000000000..37cdcdf4bf --- /dev/null +++ b/components/soc/esp32s3/include/soc/usb_dwc_cfg.h @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/* +Configuration Set ID: 1 +*/ + +/* 3.1 Basic Config Parameters */ +#define OTG_MODE 0 +#define OTG_ARCHITECTURE 2 +#define OTG_SINGLE_POINT 1 +#define OTG_ENABLE_LPM 0 +#define OTG_EN_DED_TX_FIFO 1 +#define OTG_EN_DESC_DMA 1 +#define OTG_MULTI_PROC_INTRPT 0 + +/* 3.2 USB Physical Layer Interface Parameters */ +#define OTG_HSPHY_INTERFACE 0 +#define OTG_FSPHY_INTERFACE 1 +#define OTG_ENABLE_IC_USB 0 +#define OTG_I2C_INTERFACE 0 +#define OTG_ADP_SUPPORT 0 +#define OTG_BC_SUPPORT 0 + +/* 3.3 Device Endpoint Configuration Parameters */ +#define OTG_NUM_EPS 6 +#define OTG_NUM_IN_EPS 5 +#define OTG_NUM_CRL_EPS 0 + +/* 3.4 Host Endpoint Configuration Parameters */ +#define OTG_NUM_HOST_CHAN 8 +#define OTG_EN_PERIO_HOST 1 + +/* 3.5 Endpoint Channel FIFO Configuration Parameters */ +#define OTG_DFIFO_DEPTH 256 +#define OTG_DFIFO_DYNAMIC 1 +#define OTG_RX_DFIFO_DEPTH 256 +#define OTG_TX_HNPERIO_DFIFO_DEPTH 256 +#define OTG_TX_NPERIO_DFIFO_DEPTH 256 +#define OTG_TX_HPERIO_DFIFO_DEPTH 256 +#define OTG_NPERIO_TX_QUEUE_DEPTH 4 +#define OTG_PERIO_TX_QUEUE_DEPTH 8 + +/* 3.6 Additional Configuration Options Parameters */ +#define OTG_TRANS_COUNT_WIDTH 16 +#define OTG_PACKET_COUNT_WIDTH 7 +#define OTG_RM_OPT_FEATURES 1 +#define OTG_EN_PWROPT 1 +#define OTG_SYNC_RESET_TYPE 0 +#define OTG_EN_IDDIG_FILTER 1 +#define OTG_EN_VBUSVALID_FILTER 1 +#define OTG_EN_A_VALID_FILTER 1 +#define OTG_EN_B_VALID_FILTER 1 +#define OTG_EN_SESSIONEND_FILTER 1 +#define OTG_EXCP_CNTL_XFER_FLOW 1 +#define OTG_PWR_CLAMP 0 +#define OTG_PWR_SWITCH_POLARITY 0 + +/* 3.7 Endpoint Direction Parameters */ +#define OTG_EP_DIR_1 0 +#define OTG_EP_DIR_2 0 +#define OTG_EP_DIR_3 0 +#define OTG_EP_DIR_4 0 +#define OTG_EP_DIR_5 0 +#define OTG_EP_DIR_6 0 + +/* 3.8 Device Periodic FIFO Depth Parameters */ + +/* 3.9 Device IN Endpoint FIFO Depth Parameters */ +#define OTG_TX_DINEP_DFIFO_DEPTH_1 256 +#define OTG_TX_DINEP_DFIFO_DEPTH_2 256 +#define OTG_TX_DINEP_DFIFO_DEPTH_3 256 +#define OTG_TX_DINEP_DFIFO_DEPTH_4 256 + +/* 3.10 UTMI-To-UTMI Bridge Component Parameters */ +#define U2UB_EN 0 + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32s3/include/soc/usb_dwc_struct.h b/components/soc/esp32s3/include/soc/usb_dwc_struct.h index 0402c4a83e..5fd5800715 100644 --- a/components/soc/esp32s3/include/soc/usb_dwc_struct.h +++ b/components/soc/esp32s3/include/soc/usb_dwc_struct.h @@ -1,16 +1,21 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include + #ifdef __cplusplus extern "C" { #endif -#include +/* +Registers and fields were generated based on a set of configuration options. +See the ESP32-S3 "usb_dwc_cfg.h" for more details. +*/ /* ---------------------------- Register Types ------------------------------ */ @@ -29,7 +34,7 @@ typedef union { uint32_t hstsethnpen: 1; uint32_t devhnpen: 1; uint32_t ehen: 1; - uint32_t reserved2: 2; + uint32_t reserved_13: 2; uint32_t dbncefltrbypass: 1; uint32_t conidsts: 1; uint32_t dbnctime: 1; @@ -37,23 +42,26 @@ typedef union { uint32_t bsesvld: 1; uint32_t otgver: 1; uint32_t curmod: 1; - uint32_t reserved10: 10; + uint32_t reserved_22: 5; + uint32_t reserved_27: 1; + uint32_t reserved_28: 4; }; uint32_t val; } usb_dwc_gotgctl_reg_t; typedef union { struct { - uint32_t reserved2: 2; + uint32_t reserved_0: 2; uint32_t sesenddet: 1; - uint32_t reserved5: 5; + uint32_t reserved_3: 5; uint32_t sesreqsucstschng: 1; uint32_t hstnegsucstschng: 1; - uint32_t reserved7: 7; + uint32_t reserved_10: 7; uint32_t hstnegdet: 1; uint32_t adevtoutchg: 1; uint32_t dbncedone: 1; - uint32_t reserved12: 12; + uint32_t reserved_20: 1; + uint32_t reserved_21: 11; }; uint32_t val; } usb_dwc_gotgint_reg_t; @@ -63,34 +71,44 @@ typedef union { uint32_t glbllntrmsk: 1; uint32_t hbstlen: 4; uint32_t dmaen: 1; - uint32_t reserved1: 1; + uint32_t reserved_6: 1; uint32_t nptxfemplvl: 1; uint32_t ptxfemplvl: 1; - uint32_t reserved12: 12; + uint32_t reserved_9: 12; uint32_t remmemsupp: 1; uint32_t notialldmawrit: 1; uint32_t ahbsingle: 1; uint32_t invdescendianess: 1; - uint32_t reserved7: 7; + uint32_t reserved_25: 7; }; uint32_t val; - //Checked } usb_dwc_gahbcfg_reg_t; typedef union { struct { uint32_t toutcal: 3; uint32_t phyif: 1; - uint32_t reserved1a: 1; + uint32_t reserved_4: 1; uint32_t fsintf: 1; uint32_t physel: 1; - uint32_t reserved1b: 1; + uint32_t reserved_7: 1; uint32_t srpcap: 1; uint32_t hnpcap: 1; uint32_t usbtrdtim: 4; - uint32_t reserved8: 8; + uint32_t reserved_14: 1; + uint32_t phylpwrclksel: 1; + uint32_t reserved_16: 1; + uint32_t reserved_17: 1; + uint32_t reserved_18: 1; + uint32_t reserved_19: 1; + uint32_t reserved_20: 1; + uint32_t reserved_21: 1; uint32_t termseldlpulse: 1; - uint32_t reserved5: 5; + uint32_t reserved_23: 1; + uint32_t reserved_24: 1; + uint32_t reserved_25: 1; + uint32_t icusbcap: 1; + uint32_t reserved_27: 1; uint32_t txenddelay: 1; uint32_t forcehstmode: 1; uint32_t forcedevmode: 1; @@ -104,11 +122,11 @@ typedef union { uint32_t csftrst: 1; uint32_t piufssftrst: 1; uint32_t frmcntrrst: 1; - uint32_t reserved1: 1; + uint32_t reserved_3: 1; uint32_t rxfflsh: 1; uint32_t txfflsh: 1; uint32_t txfnum: 5; - uint32_t reserved19: 19; + uint32_t reserved_11: 19; uint32_t dmareq: 1; uint32_t ahbidle: 1; }; @@ -117,22 +135,23 @@ typedef union { typedef union { struct { - uint32_t curmod_int: 1; + uint32_t curmod: 1; uint32_t modemis: 1; uint32_t otgint: 1; uint32_t sof: 1; - uint32_t rxflvi: 1; + uint32_t rxflvl: 1; uint32_t nptxfemp: 1; uint32_t ginnakeff: 1; uint32_t goutnakeff: 1; - uint32_t reserved2: 2; + uint32_t reserved_8: 1; + uint32_t reserved_9: 1; uint32_t erlysusp: 1; uint32_t usbsusp: 1; uint32_t usbrst: 1; uint32_t enumdone: 1; uint32_t isooutdrop: 1; uint32_t eopf: 1; - uint32_t reserved1a: 1; + uint32_t reserved_16: 1; uint32_t epmis: 1; uint32_t iepint: 1; uint32_t oepint: 1; @@ -140,10 +159,10 @@ typedef union { uint32_t incompip: 1; uint32_t fetsusp: 1; uint32_t resetdet: 1; - uint32_t prtlnt: 1; - uint32_t hchlnt: 1; + uint32_t prtint: 1; + uint32_t hchint: 1; uint32_t ptxfemp: 1; - uint32_t reserved1b: 1; + uint32_t reserved_27: 1; uint32_t conidstschng: 1; uint32_t disconnint: 1; uint32_t sessreqint: 1; @@ -154,22 +173,23 @@ typedef union { typedef union { struct { - uint32_t reserved1a: 1; + uint32_t reserved_0: 1; uint32_t modemismsk: 1; uint32_t otgintmsk: 1; uint32_t sofmsk: 1; - uint32_t rxflvimsk: 1; + uint32_t rxflvlmsk: 1; uint32_t nptxfempmsk: 1; uint32_t ginnakeffmsk: 1; uint32_t goutnackeffmsk: 1; - uint32_t reserved2: 2; + uint32_t reserved_8: 1; + uint32_t reserved_9: 1; uint32_t erlysuspmsk: 1; uint32_t usbsuspmsk: 1; uint32_t usbrstmsk: 1; uint32_t enumdonemsk: 1; uint32_t isooutdropmsk: 1; uint32_t eopfmsk: 1; - uint32_t reserved1b: 1; + uint32_t reserved_16: 1; uint32_t epmismsk: 1; uint32_t iepintmsk: 1; uint32_t oepintmsk: 1; @@ -177,10 +197,10 @@ typedef union { uint32_t incompipmsk: 1; uint32_t fetsuspmsk: 1; uint32_t resetdetmsk: 1; - uint32_t prtlntmsk: 1; + uint32_t prtintmsk: 1; uint32_t hchintmsk: 1; uint32_t ptxfempmsk: 1; - uint32_t reserved1c: 1; + uint32_t reserved_27: 1; uint32_t conidstschngmsk: 1; uint32_t disconnintmsk: 1; uint32_t sessreqintmsk: 1; @@ -191,12 +211,13 @@ typedef union { typedef union { struct { - uint32_t g_chnum: 4; - uint32_t g_bcnt: 11; - uint32_t g_dpid: 2; - uint32_t g_pktsts: 4; - uint32_t g_fn: 4; - uint32_t reserved7: 7; + uint32_t chnum: 4; + uint32_t bcnt: 11; + uint32_t dpid: 2; + uint32_t pktsts: 4; + uint32_t fn: 4; + uint32_t reserved_25: 6; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_grxstsr_reg_t; @@ -208,7 +229,8 @@ typedef union { uint32_t dpid: 2; uint32_t pktsts: 4; uint32_t fn: 4; - uint32_t reserved7: 7; + uint32_t reserved_25: 6; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_grxstsp_reg_t; @@ -216,7 +238,7 @@ typedef union { typedef union { struct { uint32_t rxfdep: 16; - uint32_t reserved16: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_grxfsiz_reg_t; @@ -232,10 +254,9 @@ typedef union { typedef union { struct { uint32_t nptxfspcavail: 16; - uint32_t nptxqspcavail: 4; - uint32_t reserved4: 4; + uint32_t nptxqspcavail: 8; uint32_t nptxqtop: 7; - uint32_t reserved1: 1; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_gnptxsts_reg_t; @@ -266,11 +287,11 @@ typedef union { uint32_t periosupport: 1; uint32_t dynfifosizing: 1; uint32_t multiprocintrpt: 1; - uint32_t reserved1a: 1; + uint32_t reserved_21: 1; uint32_t nptxqdepth: 2; uint32_t ptxqdepth: 2; uint32_t tknqdepth: 5; - uint32_t reserved1b: 1; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_ghwcfg2_reg_t; @@ -295,25 +316,25 @@ typedef union { typedef union { struct { - uint32_t g_numdevperioeps: 4; - uint32_t g_partialpwrdn: 1; - uint32_t g_ahbfreq: 1; - uint32_t g_hibernation: 1; - uint32_t g_extendedhibernation: 1; - uint32_t reserved4: 4; - uint32_t g_acgsupt: 1; - uint32_t g_enhancedlpmsupt: 1; - uint32_t g_phydatawidth: 2; - uint32_t g_numctleps: 4; - uint32_t g_iddqfltr: 1; - uint32_t g_vbusvalidfltr: 1; - uint32_t g_avalidfltr: 1; - uint32_t g_bvalidfltr: 1; - uint32_t g_sessendfltr: 1; - uint32_t g_dedfifomode: 1; - uint32_t g_ineps: 4; - uint32_t g_descdmaenabled: 1; - uint32_t g_descdma: 1; + uint32_t numdevperioeps: 4; + uint32_t partialpwrdn: 1; + uint32_t ahbfreq: 1; + uint32_t hibernation: 1; + uint32_t extendedhibernation: 1; + uint32_t reserved_8: 4; + uint32_t acgsupt: 1; + uint32_t enhancedlpmsupt: 1; + uint32_t phydatawidth: 2; + uint32_t numctleps: 4; + uint32_t iddqfltr: 1; + uint32_t vbusvalidfltr: 1; + uint32_t avalidfltr: 1; + uint32_t bvalidfltr: 1; + uint32_t sessendfltr: 1; + uint32_t dedfifomode: 1; + uint32_t ineps: 4; + uint32_t descdmaenabled: 1; + uint32_t descdma: 1; }; uint32_t val; } usb_dwc_ghwcfg4_reg_t; @@ -337,8 +358,8 @@ typedef union { typedef union { struct { - uint32_t inepitxfstaddr: 16; - uint32_t inep1txfdep: 16; + uint32_t inepntxfstaddr: 16; + uint32_t inepntxfdep: 16; }; uint32_t val; } usb_dwc_dieptxfi_reg_t; @@ -347,15 +368,15 @@ typedef union { struct { uint32_t fslspclksel: 2; uint32_t fslssupp: 1; - uint32_t reserved4a: 4; + uint32_t reserved_3: 4; uint32_t ena32khzs: 1; uint32_t resvalid: 8; - uint32_t reserved1: 1; - uint32_t reserved6: 6; + uint32_t reserved_16: 1; + uint32_t reserved_17: 6; uint32_t descdma: 1; uint32_t frlisten: 2; uint32_t perschedena: 1; - uint32_t reserved4b: 4; + uint32_t reserved_27: 4; uint32_t modechtimen: 1; }; uint32_t val; @@ -365,15 +386,14 @@ typedef union { struct { uint32_t frint: 16; uint32_t hfirrldctrl: 1; - uint32_t reserved15: 15; + uint32_t reserved_17: 15; }; uint32_t val; } usb_dwc_hfir_reg_t; typedef union { struct { - uint32_t frnum: 14; - uint32_t reserved: 2; + uint32_t frnum: 16; uint32_t frrem: 16; }; uint32_t val; @@ -382,8 +402,7 @@ typedef union { typedef union { struct { uint32_t ptxfspcavail: 16; - uint32_t ptxqspcavail: 5; - uint32_t reserved: 3; + uint32_t ptxqspcavail: 8; uint32_t ptxqtop: 8; }; uint32_t val; @@ -392,7 +411,7 @@ typedef union { typedef union { struct { uint32_t haint: 8; - uint32_t reserved24: 24; + uint32_t reserved_8: 24; }; uint32_t val; } usb_dwc_haint_reg_t; @@ -400,7 +419,7 @@ typedef union { typedef union { struct { uint32_t haintmsk: 8; - uint32_t reserved24: 24; + uint32_t reserved_8: 24; }; uint32_t val; } usb_dwc_haintmsk_reg_t; @@ -423,12 +442,12 @@ typedef union { uint32_t prtres: 1; uint32_t prtsusp: 1; uint32_t prtrst: 1; - uint32_t reserved1: 1; + uint32_t reserved_9: 1; uint32_t prtlnsts: 2; uint32_t prtpwr: 1; uint32_t prttstctl: 4; uint32_t prtspd: 2; - uint32_t reserved13: 13; + uint32_t reserved_19: 13; }; uint32_t val; } usb_dwc_hprt_reg_t; @@ -438,7 +457,7 @@ typedef union { uint32_t mps: 11; uint32_t epnum: 4; uint32_t epdir: 1; - uint32_t reserved: 1; + uint32_t reserved_16: 1; uint32_t lspddev: 1; uint32_t eptype: 2; uint32_t ec: 2; @@ -466,7 +485,7 @@ typedef union { uint32_t bnaintr: 1; uint32_t xcs_xact_err: 1; uint32_t desc_lst_rollintr: 1; - uint32_t reserved18: 18; + uint32_t reserved_14: 18; }; uint32_t val; } usb_dwc_hcint_reg_t; @@ -476,28 +495,26 @@ typedef union { uint32_t xfercomplmsk: 1; uint32_t chhltdmsk: 1; uint32_t ahberrmsk: 1; - uint32_t stallmsk: 1; - uint32_t nakmsk: 1; - uint32_t ackmsk: 1; - uint32_t nyetmsk: 1; - uint32_t xacterrmsk: 1; - uint32_t bblerrmsk: 1; - uint32_t frmovrunmsk: 1; - uint32_t datatglerrmsk: 1; + uint32_t reserved_3: 1; + uint32_t reserved_4: 1; + uint32_t reserved_5: 1; + uint32_t reserved_6: 1; + uint32_t reserved_7: 1; + uint32_t reserved_8: 1; + uint32_t reserved_9: 1; + uint32_t reserved_10: 1; uint32_t bnaintrmsk: 1; - uint32_t reserved1: 1; + uint32_t reserved_12: 1; uint32_t desc_lst_rollintrmsk: 1; - uint32_t reserved18: 18; + uint32_t reserved_14: 18; }; uint32_t val; } usb_dwc_hcintmsk_reg_t; typedef union { struct { - uint32_t sched_info: 8; - uint32_t ntd: 8; - uint32_t reserved3: 3; - uint32_t reserved10: 10; + uint32_t xfersize: 19; // Note: Width depends on OTG_TRANS_COUNT_WIDTH (see databook). + uint32_t pktcnt: 10; // Note: Width depends on OTG_PACKET_COUNT_WIDTH (see databook). uint32_t pid: 2; uint32_t dopng: 1; }; @@ -506,14 +523,8 @@ typedef union { typedef union { struct { - uint32_t reserved3: 3; - uint32_t ctd: 6; - uint32_t dmaaddr: 23; - } non_iso; - struct { - uint32_t reserved3: 3; - uint32_t dmaaddr_ctd: 29; - } iso; + uint32_t dmaaddr; + }; uint32_t val; } usb_dwc_hcdma_reg_t; @@ -526,16 +537,16 @@ typedef union { typedef union { struct { - uint32_t reserved2a: 2; + uint32_t devspd: 2; uint32_t nzstsouthshk: 1; - uint32_t reserved1: 1; + uint32_t ena32khzsusp: 1; uint32_t devaddr: 7; - uint32_t perfrlint: 2; + uint32_t perfrint: 2; uint32_t endevoutnak: 1; uint32_t xcvrdly: 1; uint32_t erraticintmsk: 1; - uint32_t reserved2b: 2; - uint32_t epmiscnt: 5; + uint32_t reserved_16: 2; + uint32_t reserved_18: 5; uint32_t descdma: 1; uint32_t perschintvl: 2; uint32_t resvalid: 6; @@ -555,13 +566,13 @@ typedef union { uint32_t sgoutnak: 1; uint32_t cgoutnak: 1; uint32_t pwronprgdone: 1; - uint32_t reserved1: 1; + uint32_t reserved_12: 1; uint32_t gmc: 2; uint32_t ignrfrmnum: 1; uint32_t nakonbble: 1; - uint32_t encountonbna: 1; - uint32_t deepsleepbeslreject: 1; - uint32_t reserved3: 13; + uint32_t encontonbna: 1; + uint32_t reserved_18: 1; + uint32_t reserved_19: 13; }; uint32_t val; } usb_dwc_dctl_reg_t; @@ -571,29 +582,29 @@ typedef union { uint32_t suspsts: 1; uint32_t enumspd: 2; uint32_t errticerr: 1; - uint32_t reserved4: 4; + uint32_t reserved_4: 4; uint32_t soffn: 14; uint32_t devlnsts: 2; - uint32_t reserved8: 8; + uint32_t reserved_24: 8; }; uint32_t val; } usb_dwc_dsts_reg_t; typedef union { struct { - uint32_t di_xfercomplmsk: 1; - uint32_t di_epdisbldmsk: 1; - uint32_t di_ahbermsk: 1; + uint32_t xfercomplmsk: 1; + uint32_t epdisbldmsk: 1; + uint32_t ahberrmsk: 1; uint32_t timeoutmsk: 1; uint32_t intkntxfempmsk: 1; uint32_t intknepmismsk: 1; uint32_t inepnakeffmsk: 1; - uint32_t reserved1: 1; + uint32_t reserved_7: 1; uint32_t txfifoundrnmsk: 1; uint32_t bnainintrmsk: 1; - uint32_t reserved3: 3; - uint32_t di_nakmsk: 1; - uint32_t reserved18: 18; + uint32_t reserved_10: 3; + uint32_t nakmsk: 1; + uint32_t reserved_14: 18; }; uint32_t val; } usb_dwc_diepmsk_reg_t; @@ -602,19 +613,19 @@ typedef union { struct { uint32_t xfercomplmsk: 1; uint32_t epdisbldmsk: 1; - uint32_t ahbermsk: 1; + uint32_t ahberrmsk: 1; uint32_t setupmsk: 1; uint32_t outtknepdismsk: 1; uint32_t stsphsercvdmsk: 1; uint32_t back2backsetup: 1; - uint32_t reserved1: 1; + uint32_t reserved_7: 1; uint32_t outpkterrmsk: 1; uint32_t bnaoutintrmsk: 1; - uint32_t reserved2: 2; + uint32_t reserved_10: 2; uint32_t bbleerrmsk: 1; uint32_t nakmsk: 1; uint32_t nyetmsk: 1; - uint32_t reserved17: 17; + uint32_t reserved_15: 17; }; uint32_t val; } usb_dwc_doepmsk_reg_t; @@ -628,7 +639,7 @@ typedef union { uint32_t inepint4: 1; uint32_t inepint5: 1; uint32_t inepint6: 1; - uint32_t reserved9a: 9; + uint32_t reserved_7: 9; uint32_t outepint0: 1; uint32_t outepint1: 1; uint32_t outepint2: 1; @@ -636,7 +647,7 @@ typedef union { uint32_t outepint4: 1; uint32_t outepint5: 1; uint32_t outepint6: 1; - uint32_t reserved9b: 9; + uint32_t reserved_24: 9; }; uint32_t val; } usb_dwc_daint_reg_t; @@ -650,7 +661,7 @@ typedef union { uint32_t inepmsk4: 1; uint32_t inepmsk5: 1; uint32_t inepmsk6: 1; - uint32_t reserved9a: 9; + uint32_t reserved_7: 9; uint32_t outepmsk0: 1; uint32_t outepmsk1: 1; uint32_t outepmsk2: 1; @@ -658,7 +669,7 @@ typedef union { uint32_t outepmsk4: 1; uint32_t outepmsk5: 1; uint32_t outepmsk6: 1; - uint32_t reserved9b: 9; + uint32_t reserved_24: 9; }; uint32_t val; } usb_dwc_daintmsk_reg_t; @@ -666,7 +677,7 @@ typedef union { typedef union { struct { uint32_t dvbusdis: 16; - uint32_t reserved16: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_dvbusdis_reg_t; @@ -674,7 +685,7 @@ typedef union { typedef union { struct { uint32_t dvbuspulse: 12; - uint32_t reserved20: 20; + uint32_t reserved_12: 20; }; uint32_t val; } usb_dwc_dvbuspulse_reg_t; @@ -685,109 +696,108 @@ typedef union { uint32_t isothren: 1; uint32_t txthrlen: 9; uint32_t ahbthrratio: 2; - uint32_t reserved3: 3; + uint32_t reserved_13: 3; uint32_t rxthren: 1; uint32_t rxthrlen: 9; - uint32_t reserved1: 1; + uint32_t reserved_26: 1; uint32_t arbprken: 1; - uint32_t reserved4: 4; + uint32_t reserved_28: 4; }; uint32_t val; } usb_dwc_dthrctl_reg_t; typedef union { struct { - uint32_t ineptxfernpmsk: 16; - uint32_t reserved16: 16; + uint32_t ineptxfempmsk: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_diepempmsk_reg_t; typedef union { struct { - uint32_t mps0: 2; - uint32_t reserved9: 9; - uint32_t reserved4: 4; - uint32_t usbactep0: 1; - uint32_t reserved1a: 1; - uint32_t naksts0: 1; - uint32_t eptype0: 2; - uint32_t reserved1b: 1; - uint32_t stall0: 1; - uint32_t txfnum0: 4; - uint32_t cnak0: 1; - uint32_t snak0: 1; - uint32_t reserved2: 2; - uint32_t epdis0: 1; - uint32_t epena0: 1; + uint32_t mps: 2; + uint32_t reserved_2: 9; + uint32_t reserved_11: 4; + uint32_t usbactep: 1; + uint32_t reserved_16: 1; + uint32_t naksts: 1; + uint32_t eptype: 2; + uint32_t reserved_20: 1; + uint32_t stall: 1; + uint32_t txfnum: 4; + uint32_t cnak: 1; + uint32_t snak: 1; + uint32_t reserved_28: 2; + uint32_t epdis: 1; + uint32_t epena: 1; }; uint32_t val; } usb_dwc_diepctl0_reg_t; typedef union { struct { - uint32_t xfercompl0: 1; - uint32_t epdisbld0: 1; - uint32_t ahberr0: 1; - uint32_t timeout0: 1; - uint32_t intkntxfemp0: 1; - uint32_t intknepmis0: 1; - uint32_t inepnakeff0: 1; - uint32_t txfemp0: 1; - uint32_t txfifoundrn0: 1; - uint32_t bnaintr0: 1; - uint32_t reserved1: 1; - uint32_t pktdrpsts0: 1; - uint32_t bbleerr0: 1; - uint32_t nakintrpt0: 1; - uint32_t nyetintrpt0: 1; - uint32_t reserved17: 17; + uint32_t xfercompl: 1; + uint32_t epdisbld: 1; + uint32_t ahberr: 1; + uint32_t timeout: 1; + uint32_t intkntxfemp: 1; + uint32_t intknepmis: 1; + uint32_t inepnakeff: 1; + uint32_t txfemp: 1; + uint32_t txfifoundrn: 1; + uint32_t bnaintr: 1; + uint32_t reserved_10: 1; + uint32_t pktdrpsts: 1; + uint32_t bbleerr: 1; + uint32_t nakintrpt: 1; + uint32_t nyetintrpt: 1; + uint32_t reserved_15: 17; }; uint32_t val; } usb_dwc_diepint0_reg_t; typedef union { struct { - uint32_t xfersize0: 7; - uint32_t reserved12: 12; - uint32_t pktcnt0: 2; - uint32_t reserved11: 11; + uint32_t xfersize: 7; + uint32_t reserved_7: 12; + uint32_t pktcnt: 2; + uint32_t reserved_21: 11; }; uint32_t val; } usb_dwc_dieptsiz0_reg_t; typedef union { struct { - uint32_t dmaaddr0; + uint32_t dmaaddr; }; uint32_t val; } usb_dwc_diepdma0_reg_t; typedef union { struct { - uint32_t ineptxfspcavail0: 16; - uint32_t reserved16: 16; + uint32_t ineptxfspcavail: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_dtxfsts0_reg_t; typedef union { struct { - uint32_t dmabufferaddr0; + uint32_t dmabufferaddr; }; uint32_t val; } usb_dwc_diepdmab0_reg_t; typedef union { struct { - uint32_t mps: 2; - uint32_t reserved9: 9; - uint32_t reserved4: 4; + uint32_t mps: 11; + uint32_t reserved_11: 4; uint32_t usbactep: 1; - uint32_t reserved1a: 1; + uint32_t dpid: 1; uint32_t naksts: 1; uint32_t eptype: 2; - uint32_t reserved1b: 1; + uint32_t reserved_20: 1; uint32_t stall: 1; uint32_t txfnum: 4; uint32_t cnak: 1; @@ -812,29 +822,29 @@ typedef union { uint32_t txfemp: 1; uint32_t txfifoundrn: 1; uint32_t bnaintr: 1; - uint32_t reserved1: 1; + uint32_t reserved_10: 1; uint32_t pktdrpsts: 1; uint32_t bbleerr: 1; uint32_t nakintrpt: 1; uint32_t nyetintrpt: 1; - uint32_t reserved15: 17; + uint32_t reserved_15: 17; }; uint32_t val; } usb_dwc_diepint_reg_t; typedef union { struct { - uint32_t xfersize: 7; - uint32_t reserved12: 12; - uint32_t pktcnt: 2; - uint32_t reserved11: 11; + uint32_t xfersize: 19; // Note: Width depends on OTG_TRANS_COUNT_WIDTH (see databook). + uint32_t pktcnt: 10; // Note: Width depends on OTG_PACKET_COUNT_WIDTH (see databook). + uint32_t mc: 2; + uint32_t reserved: 1; }; uint32_t val; } usb_dwc_dieptsiz_reg_t; typedef union { struct { - uint32_t dmaddr1; + uint32_t dmaddr; }; uint32_t val; } usb_dwc_diepdma_reg_t; @@ -842,83 +852,83 @@ typedef union { typedef union { struct { uint32_t ineptxfspcavail: 16; - uint32_t reserved16: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_dtxfsts_reg_t; typedef union { struct { - uint32_t dmabufferaddr1; + uint32_t dmabufferaddr; }; uint32_t val; } usb_dwc_diepdmab_reg_t; typedef union { struct { - uint32_t mps0: 2; - uint32_t reserved13: 13; - uint32_t usbactep0: 1; - uint32_t reserved1: 1; - uint32_t naksts0: 1; - uint32_t eptype0: 2; - uint32_t snp0: 1; - uint32_t stall0: 1; - uint32_t reserved4: 4; - uint32_t cnak0: 1; - uint32_t snak0: 1; - uint32_t reserved2: 2; - uint32_t epdis0: 1; - uint32_t epena0: 1; + uint32_t mps: 2; + uint32_t reserved_2: 13; + uint32_t usbactep: 1; + uint32_t reserved_16: 1; + uint32_t naksts: 1; + uint32_t eptype: 2; + uint32_t snp: 1; + uint32_t stall: 1; + uint32_t reserved_22: 4; + uint32_t cnak: 1; + uint32_t snak: 1; + uint32_t reserved_28: 2; + uint32_t epdis: 1; + uint32_t epena: 1; }; uint32_t val; } usb_dwc_doepctl0_reg_t; typedef union { struct { - uint32_t xfercompl0: 1; - uint32_t epdisbld0: 1; - uint32_t ahberr0: 1; - uint32_t setup0: 1; - uint32_t outtknepdis0: 1; - uint32_t stsphsercvd0: 1; - uint32_t back2backsetup0: 1; - uint32_t reserved1a: 1; - uint32_t outpkterr0: 1; - uint32_t bnaintr0: 1; - uint32_t reserved1b: 1; - uint32_t pktdrpsts0: 1; - uint32_t bbleerr0: 1; - uint32_t nakintrpt0: 1; - uint32_t nyepintrpt0: 1; - uint32_t stuppktrcvd0: 1; - uint32_t reserved16: 16; + uint32_t xfercompl: 1; + uint32_t epdisbld: 1; + uint32_t ahberr: 1; + uint32_t setup: 1; + uint32_t outtknepdis: 1; + uint32_t stsphsercvd: 1; + uint32_t back2backsetup: 1; + uint32_t reserved_7: 1; + uint32_t outpkterr: 1; + uint32_t bnaintr: 1; + uint32_t reserved_10: 1; + uint32_t pktdrpsts: 1; + uint32_t bbleerr: 1; + uint32_t nakintrpt: 1; + uint32_t nyepintrpt: 1; + uint32_t stuppktrcvd: 1; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_doepint0_reg_t; typedef union { struct { - uint32_t xfersize0: 7; - uint32_t reserved12: 12; - uint32_t pktcnt0: 1; - uint32_t reserved9: 9; - uint32_t supcnt0: 2; - uint32_t reserved1: 1; + uint32_t xfersize: 7; + uint32_t reserved_7: 12; + uint32_t pktcnt: 1; + uint32_t reserved_20: 9; + uint32_t supcnt: 2; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_doeptsiz0_reg_t; typedef union { struct { - uint32_t dmaaddr0; + uint32_t dmaaddr; }; uint32_t val; } usb_dwc_doepdma0_reg_t; typedef union { struct { - uint32_t dmabufferaddr0; + uint32_t dmabufferaddr; }; uint32_t val; } usb_dwc_doepdmab0_reg_t; @@ -926,14 +936,14 @@ typedef union { typedef union { struct { uint32_t mps: 11; - uint32_t reserved4a: 4; + uint32_t reserved_11: 4; uint32_t usbactep: 1; - uint32_t reserved1: 1; + uint32_t dpid: 1; uint32_t naksts: 1; uint32_t eptype: 2; uint32_t snp: 1; uint32_t stall: 1; - uint32_t reserved4b: 4; + uint32_t reserved_22: 4; uint32_t cnak: 1; uint32_t snak: 1; uint32_t setd0pid: 1; @@ -953,28 +963,26 @@ typedef union { uint32_t outtknepdis: 1; uint32_t stsphsercvd: 1; uint32_t back2backsetup: 1; - uint32_t reserved1a: 1; + uint32_t reserved_7: 1; uint32_t outpkterr: 1; uint32_t bnaintr: 1; - uint32_t reserved1b: 1; + uint32_t reserved_10: 1; uint32_t pktdrpsts: 1; uint32_t bbleerr: 1; uint32_t nakintrpt: 1; - uint32_t nyepintrpt: 1; + uint32_t nyetintrpt: 1; uint32_t stuppktrcvd: 1; - uint32_t reserved16: 16; + uint32_t reserved_16: 16; }; uint32_t val; } usb_dwc_doepint_reg_t; typedef union { struct { - uint32_t xfersize: 7; - uint32_t reserved12: 12; - uint32_t pktcnt: 1; - uint32_t reserved9: 9; - uint32_t supcnt: 2; - uint32_t reserved1: 1; + uint32_t xfersize: 19; // Note: Width depends on OTG_TRANS_COUNT_WIDTH (see databook). + uint32_t pktcnt: 10; // Note: Width depends on OTG_PACKET_COUNT_WIDTH (see databook). + uint32_t rxdpid: 2; + uint32_t reserved_31: 1; }; uint32_t val; } usb_dwc_doeptsiz_reg_t; @@ -999,11 +1007,17 @@ typedef union { uint32_t gatehclk: 1; uint32_t pwrclmp: 1; uint32_t rstpdwnmodule: 1; - uint32_t reserved2: 2; + uint32_t reserved_4: 1; + uint32_t reserved_5: 1; uint32_t physleep: 1; uint32_t l1suspended: 1; uint32_t resetaftersusp: 1; - uint32_t reserved23: 23; + uint32_t reserved_9: 1; + uint32_t reserved_10: 1; + uint32_t reserved_11: 1; + uint32_t reserved_12: 1; + uint32_t reserved_13: 1; + uint32_t reserved_14: 18; }; uint32_t val; } usb_dwc_pcgcctl_reg_t; @@ -1012,21 +1026,21 @@ typedef union { typedef struct { volatile usb_dwc_hcchar_reg_t hcchar_reg; // 0x00 - uint32_t reserved_0x04_0x08[1]; // 0x04 + uint32_t reserved_0x04[1]; // 0x04 volatile usb_dwc_hcint_reg_t hcint_reg; // 0x08 volatile usb_dwc_hcintmsk_reg_t hcintmsk_reg; // 0x0c volatile usb_dwc_hctsiz_reg_t hctsiz_reg; // 0x10 volatile usb_dwc_hcdma_reg_t hcdma_reg; // 0x14 - uint32_t reserved_0x14_0x14[1]; // 0x18 + uint32_t reserved_0x18[1]; // 0x18 volatile usb_dwc_hcdmab_reg_t hcdmab_reg; // 0x1c } usb_dwc_host_chan_regs_t; typedef struct { volatile usb_dwc_diepctl_reg_t diepctl_reg; // 0x00 - uint32_t reserved_0x04_0x08[1]; // 0x04 + uint32_t reserved_0x04[1]; // 0x04 volatile usb_dwc_diepint_reg_t diepint_reg; // 0x08 - uint32_t reserved_0x0c_0x10[1]; // 0x0c - volatile usb_dwc_dieptsiz_reg_t dieptsiz_reg; // 0x010 + uint32_t reserved_0x0c[1]; // 0x0c + volatile usb_dwc_dieptsiz_reg_t dieptsiz_reg; // 0x10 volatile usb_dwc_diepdma_reg_t diepdma_reg; // 0x14 volatile usb_dwc_dtxfsts_reg_t dtxfsts_reg; // 0x18 volatile usb_dwc_diepdmab_reg_t diepdmab_reg; // 0x1c @@ -1034,19 +1048,19 @@ typedef struct { typedef struct { volatile usb_dwc_doepctl_reg_t doepctl_reg; // 0x00 - uint32_t reserved_0x04_0x08[1]; // 0x04 + uint32_t reserved_0x04[1]; // 0x04 volatile usb_dwc_doepint_reg_t doepint_reg; // 0x08 - uint32_t reserved_0x0c_0x10[1]; // 0x0c + uint32_t reserved_0x0c[1]; // 0x0c volatile usb_dwc_doeptsiz_reg_t doeptsiz_reg; // 0x10 volatile usb_dwc_doepdma_reg_t doepdma_reg; // 0x14 - uint32_t reserved_0x18_0x1c[1]; // 0x18 + uint32_t reserved_0x18[1]; // 0x18 volatile usb_dwc_doepdmab_reg_t doepdmab_reg; // 0x1c } usb_dwc_out_ep_regs_t; /* --------------------------- Register Layout ------------------------------ */ typedef struct { - //Global Registers + // Global Registers volatile usb_dwc_gotgctl_reg_t gotgctl_reg; // 0x0000 volatile usb_dwc_gotgint_reg_t gotgint_reg; // 0x0004 volatile usb_dwc_gahbcfg_reg_t gahbcfg_reg; // 0x0008 @@ -1059,94 +1073,106 @@ typedef struct { volatile usb_dwc_grxfsiz_reg_t grxfsiz_reg; // 0x0024 volatile usb_dwc_gnptxfsiz_reg_t gnptxfsiz_reg; // 0x0028 volatile usb_dwc_gnptxsts_reg_t gnptxsts_reg; // 0x002c - uint32_t reserved_0x0030_0x0040[4]; // 0x0030 to 0x0040 + uint32_t reserved_0x0030; // 0x0030 + uint32_t reserved_0x0034; // 0x0034 + uint32_t reserved_0x0038; // 0x0038 + uint32_t reserved_0x003c; // 0x003c volatile usb_dwc_gsnpsid_reg_t gsnpsid_reg; // 0x0040 volatile usb_dwc_ghwcfg1_reg_t ghwcfg1_reg; // 0x0044 volatile usb_dwc_ghwcfg2_reg_t ghwcfg2_reg; // 0x0048 volatile usb_dwc_ghwcfg3_reg_t ghwcfg3_reg; // 0x004c volatile usb_dwc_ghwcfg4_reg_t ghwcfg4_reg; // 0x0050 - uint32_t reserved_0x0054_0x005c[2]; // 0x0054 to 0x005c - - //FIFO Configurations + uint32_t reserved_0x0054; // 0x0054 + uint32_t reserved_0x0058; // 0x0058 volatile usb_dwc_gdfifocfg_reg_t gdfifocfg_reg; // 0x005c - uint32_t reserved_0x0060_0x0100[40]; // 0x0060 to 0x0100 + uint32_t reserved_0x0060; // 0x0060 + uint32_t reserved_0x0064_0x0100[39]; // 0x0064 to 0x0100 volatile usb_dwc_hptxfsiz_reg_t hptxfsiz_reg; // 0x0100 - volatile usb_dwc_dieptxfi_reg_t dieptxfi_regs[4]; // 0x0104 to 0x0114 - usb_dwc_dieptxfi_reg_t reserved_0x0114_0x0140[11]; // 0x0114 to 0x0140 - uint32_t reserved_0x140_0x400[176]; // 0x0140 to 0x0400 + volatile usb_dwc_dieptxfi_reg_t dieptxf_regs[4]; // 0x0104 to 0x0110 (depends on OTG_NUM_IN_EPS) + usb_dwc_dieptxfi_reg_t reserved_0x0114_0x013c[11]; // 0x0114 to 0x013c (depends on OTG_NUM_IN_EPS) + uint32_t reserved_0x140_0x3fc[176]; // 0x0140 to 0x03fc - //Host Mode Registers + // Host Mode Registers volatile usb_dwc_hcfg_reg_t hcfg_reg; // 0x0400 volatile usb_dwc_hfir_reg_t hfir_reg; // 0x0404 volatile usb_dwc_hfnum_reg_t hfnum_reg; // 0x0408 - uint32_t reserved_0x40c_0x410[1]; // 0x040c to 0x0410 + uint32_t reserved_0x40c[1]; // 0x040c volatile usb_dwc_hptxsts_reg_t hptxsts_reg; // 0x0410 volatile usb_dwc_haint_reg_t haint_reg; // 0x0414 volatile usb_dwc_haintmsk_reg_t haintmsk_reg; // 0x0418 volatile usb_dwc_hflbaddr_reg_t hflbaddr_reg; // 0x041c - uint32_t reserved_0x420_0x440[8]; // 0x0420 to 0x0440 + uint32_t reserved_0x420_0x43c[8]; // 0x0420 to 0x043c volatile usb_dwc_hprt_reg_t hprt_reg; // 0x0440 - uint32_t reserved_0x0444_0x0500[47]; // 0x0444 to 0x0500 - usb_dwc_host_chan_regs_t host_chans[8]; // 0x0500 to 0x0600 - usb_dwc_host_chan_regs_t reserved_0x0600_0x0700[8]; // 0x0600 to 0x0700 - uint32_t reserved_0x0700_0x0800[64]; // 0x0700 to 0x0800 + uint32_t reserved_0x0444_0x04fc[47]; // 0x0444 to 0x04fc + + // Host Channel Registers + usb_dwc_host_chan_regs_t host_chans[8]; // 0x0500 to 0x05fc (depends on OTG_NUM_HOST_CHAN) + usb_dwc_host_chan_regs_t reserved_0x0600_0x06fc[8]; // 0x0600 to 0x06fc (depends on OTG_NUM_HOST_CHAN) + uint32_t reserved_0x0700_0x07fc[64]; // 0x0700 to 0x07fc + + // Device Mode Registers volatile usb_dwc_dcfg_reg_t dcfg_reg; // 0x0800 volatile usb_dwc_dctl_reg_t dctl_reg; // 0x0804 volatile usb_dwc_dsts_reg_t dsts_reg; // 0x0808 - uint32_t reserved_0x080c_0x0810[1]; // 0x080c to 0x0810 - - //Device Mode Registers - volatile usb_dwc_diepmsk_reg_t diepmsk_reg; // 0x810 + uint32_t reserved_0x080c[1]; // 0x080c + volatile usb_dwc_diepmsk_reg_t diepmsk_reg; // 0x0810 volatile usb_dwc_doepmsk_reg_t doepmsk_reg; // 0x0814 volatile usb_dwc_daint_reg_t daint_reg; // 0x0818 volatile usb_dwc_daintmsk_reg_t daintmsk_reg; // 0x081c - uint32_t reserved_0x0820_0x0828[2]; // 0x0820 to 0x0828 + uint32_t reserved_0x0820; // 0x0820 + uint32_t reserved_0x0824; // 0x0824 volatile usb_dwc_dvbusdis_reg_t dvbusdis_reg; // 0x0828 volatile usb_dwc_dvbuspulse_reg_t dvbuspulse_reg; // 0x082c volatile usb_dwc_dthrctl_reg_t dthrctl_reg; // 0x0830 volatile usb_dwc_diepempmsk_reg_t diepempmsk_reg; // 0x0834 - uint32_t reserved_0x0838_0x0900[50]; // 0x0838 to 0x0900 - - //Deivce: IN EP0 reigsters + uint32_t reserved_0x0838; // 0x0838 + uint32_t reserved_0x083c; // 0x083c + uint32_t reserved_0x0840; // 0x0840 + uint32_t reserved_0x0844_0x087c[15]; // 0x0844 to 0x087c (depends on OTG_NUM_EPS) + uint32_t reserved_0x0880; // 0x0880 + uint32_t reserved_0x0884_0x08c0[15]; // 0x0884 to 0x08c0 (depends on OTG_NUM_EPS) + uint32_t reserved_0x08c4_0x08fc[16]; // 0x08c4 to 0x08fc + + // Device: IN EP0 registers volatile usb_dwc_diepctl0_reg_t diepctl0_reg; // 0x0900 - uint32_t reserved_0x0904_0x0908[1]; // 0x0904 to 0x0908 + uint32_t reserved_0x0904[1]; // 0x0904 volatile usb_dwc_diepint0_reg_t diepint0_reg; // 0x0908 - uint32_t reserved_0x090c_0x0910[1]; // 0x090c to 0x0910 + uint32_t reserved_0x090c[1]; // 0x090c volatile usb_dwc_dieptsiz0_reg_t dieptsiz0_reg; // 0x0910 volatile usb_dwc_diepdma0_reg_t diepdma0_reg; // 0x0914 volatile usb_dwc_dtxfsts0_reg_t dtxfsts0_reg; // 0x0918 volatile usb_dwc_diepdmab0_reg_t diepdmab0_reg; // 0x091c - //Deivce: IN EP registers - usb_dwc_in_ep_regs_t in_eps[6]; // 0x0920 to 0x09e0 - usb_dwc_in_ep_regs_t reserved_0x09e0_0x0b00[9]; // 0x09e0 to 0x0b00 + // Device: IN EP registers + usb_dwc_in_ep_regs_t in_eps[6]; // 0x0920 to 0x09dc (depends on OTG_NUM_EPS) + usb_dwc_in_ep_regs_t reserved_0x09e0_0x0afc[9]; // 0x09e0 to 0x0afc (depends on OTG_NUM_EPS) - //Device: OUT EP0 reigsters + // Device: OUT EP0 registers volatile usb_dwc_doepctl0_reg_t doepctl0_reg; // 0x0b00 - uint32_t reserved_0x0b04_0x0b08[1]; // 0x0b04 to 0x0b08 + uint32_t reserved_0x0b04[1]; // 0x0b04 volatile usb_dwc_doepint0_reg_t doepint0_reg; // 0b0b08 - uint32_t reserved_0x0b0c_0x0b10[1]; // 0x0b0c to 0x0b10 + uint32_t reserved_0x0b0c[1]; // 0x0b0c volatile usb_dwc_doeptsiz0_reg_t doeptsiz0_reg; // 0x0b10 volatile usb_dwc_doepdma0_reg_t doepdma0_reg; // 0x0b14 - uint32_t reserved_0x0b18_0x0b1c[1]; // 0x0b18 to 0x0b1c + uint32_t reserved_0x0b18[1]; // 0x0b18 volatile usb_dwc_doepdmab0_reg_t doepdmab0_reg; // 0x0b1c - //Deivce: OUT EP registers - usb_dwc_out_ep_regs_t out_eps[6]; // 0xb1c - usb_dwc_out_ep_regs_t reserved_0x0be0_0x0d00[9]; // 0x0be0 to 0x0d00 - uint32_t reserved_0x0d00_0x0e00[64]; // 0x0d00 to 0x0e00 + // Device: OUT EP registers + usb_dwc_out_ep_regs_t out_eps[6]; // 0x0b20 to 0x0bdc (depends on OTG_NUM_EPS) + usb_dwc_out_ep_regs_t reserved_0x0be0_0x0d00[9]; // 0x0be0 to 0x0cfc (depends on OTG_NUM_EPS) + uint32_t reserved_0x0d00_0x0dfc[64]; // 0x0d00 to 0x0dfc + + // Power and Clock Gating volatile usb_dwc_pcgcctl_reg_t pcgcctl_reg; // 0x0e00 - uint32_t reserved_0x0e04_0x0e08[1]; // 0x0d00 to 0x0e00 + uint32_t reserved_0x0e04[1]; // 0x0e04 } usb_dwc_dev_t; - #ifndef __cplusplus _Static_assert(sizeof(usb_dwc_dev_t) == 0xe08, "Invalid size of usb_dwc_dev_t structure"); #endif extern usb_dwc_dev_t USB_DWC; - #ifdef __cplusplus } #endif diff --git a/components/soc/esp32s3/include/soc/usb_pins.h b/components/soc/esp32s3/include/soc/usb_pins.h index 7407b0a615..7b82a1b440 100644 --- a/components/soc/esp32s3/include/soc/usb_pins.h +++ b/components/soc/esp32s3/include/soc/usb_pins.h @@ -1,12 +1,18 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once -/* GPIOs used to connect an external USB PHY */ +/* +Note: These macros are deprecated. When connecting USB OTG to an external FSLS +PHY, the FSLS Serial Interface signals can be routed to any GPIO via the GPIO +matrix. Thus, these macros are meaningless. + +Todo: Remove in IDF v6.0 (IDF-9029) +*/ #define USBPHY_VP_NUM 42 #define USBPHY_VM_NUM 41 #define USBPHY_RCV_NUM 21 diff --git a/components/soc/esp32s3/include/soc/usb_struct.h b/components/soc/esp32s3/include/soc/usb_struct.h index d9645f1cb5..697c79e416 100644 --- a/components/soc/esp32s3/include/soc/usb_struct.h +++ b/components/soc/esp32s3/include/soc/usb_struct.h @@ -1,27 +1,41 @@ -// 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-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include -#include "usb_types.h" -#include #ifdef __cplusplus extern "C" { #endif +/* USB IN EP Register block type */ +typedef struct usb_in_ep_reg { + volatile uint32_t diepctl; + uint32_t reserved; + volatile uint32_t diepint; + uint32_t reserved1; + volatile uint32_t dieptsiz; + volatile uint32_t diepdma; + volatile uint32_t dtxfsts; + uint32_t reserved2; +} usb_in_endpoint_t; + +/* USB OUT EP Register block type */ +typedef struct usb_out_ep_reg { + volatile uint32_t doepctl; + uint32_t reserved; + volatile uint32_t doepint; + uint32_t reserved1; + volatile uint32_t doeptsiz; + volatile uint32_t doepdma; + uint32_t reserved2; + uint32_t reserved3; +} usb_out_endpoint_t; + typedef struct usb_reg { volatile uint32_t gotgctl; // 0x0000 OTG Control and Status Register volatile uint32_t gotgint; // 0x0004 OTG Interrupt Register @@ -83,10 +97,10 @@ typedef struct usb_reg { volatile uint32_t dtknqr4_fifoemptymsk; // 0x0834 Device IN Endpoint FIFO Empty Interrupt Mask register uint32_t reserved_0x0838_0x0900[50]; // 0x0838 to 0x0900 // Input Endpoints - usb_in_endpoint_t in_ep_reg[USB_IN_EP_NUM]; // 0x0900 to 0x09e0 IN EP registers + usb_in_endpoint_t in_ep_reg[7]; // 0x0900 to 0x09e0 IN EP registers uint32_t reserved_0x09e0_0x0b00[72]; // 0x09e0 to 0x0b00 // Output Endpoints - usb_out_endpoint_t out_ep_reg[USB_OUT_EP_NUM]; // 0x0b00 to 0x0be0 OUT EP registers + usb_out_endpoint_t out_ep_reg[7]; // 0x0b00 to 0x0be0 OUT EP registers uint32_t reserved_0x0be0_0x0d00[72]; // 0x0be0 to 0x0d00 uint32_t reserved_0x0d00_0x0e00[64]; // 0x0d00 to 0x0e00 /** diff --git a/components/soc/esp32s3/include/soc/usb_types.h b/components/soc/esp32s3/include/soc/usb_types.h deleted file mode 100644 index 69e213ec84..0000000000 --- a/components/soc/esp32s3/include/soc/usb_types.h +++ /dev/null @@ -1,73 +0,0 @@ -// 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. - -#pragma once -#ifdef __cplusplus -extern "C" -{ -#endif - -#include - -/* USB IN EP index */ -typedef enum { - USB_IN_EP_0 = 0, - USB_IN_EP_1, - USB_IN_EP_2, - USB_IN_EP_3, - USB_IN_EP_4, - USB_IN_EP_5, - USB_IN_EP_6, - USB_IN_EP_NUM -} usb_in_ep_idx_t; - -/* USB OUT EP index */ -typedef enum { - USB_OUT_EP_0 = 0, - USB_OUT_EP_1, - USB_OUT_EP_2, - USB_OUT_EP_3, - USB_OUT_EP_4, - USB_OUT_EP_5, - USB_OUT_EP_6, - USB_OUT_EP_NUM -} usb_out_ep_idx_t; - -/* USB IN EP Register block type */ -typedef struct usb_in_ep_reg { - volatile uint32_t diepctl; - uint32_t reserved; - volatile uint32_t diepint; - uint32_t reserved1; - volatile uint32_t dieptsiz; - volatile uint32_t diepdma; - volatile uint32_t dtxfsts; - uint32_t reserved2; -} usb_in_endpoint_t; - -/* USB OUT EP Register block type */ -typedef struct usb_out_ep_reg { - volatile uint32_t doepctl; - uint32_t reserved; - volatile uint32_t doepint; - uint32_t reserved1; - volatile uint32_t doeptsiz; - volatile uint32_t doepdma; - uint32_t reserved2; - uint32_t reserved3; -} usb_out_endpoint_t; - -#ifdef __cplusplus -} -#endif diff --git a/components/soc/esp32s3/include/soc/usb_wrap_struct.h b/components/soc/esp32s3/include/soc/usb_wrap_struct.h index ac0b871034..71013fe25f 100644 --- a/components/soc/esp32s3/include/soc/usb_wrap_struct.h +++ b/components/soc/esp32s3/include/soc/usb_wrap_struct.h @@ -154,7 +154,7 @@ typedef union { * USB D- rx value in test. */ uint32_t test_rx_dm:1; - uint32_t reserved7:25; + uint32_t reserved_7:25; }; uint32_t val; } usb_wrap_test_conf_reg_t; diff --git a/components/soc/esp32s3/interrupts.c b/components/soc/esp32s3/interrupts.c index 3f074b00b9..82c9924a35 100644 --- a/components/soc/esp32s3/interrupts.c +++ b/components/soc/esp32s3/interrupts.c @@ -80,8 +80,8 @@ const char *const esp_isr_names[ETS_MAX_INTR_SOURCE] = { [74] = "DMA_OUT_CH3", [75] = "DMA_OUT_CH4", [76] = "RSA", - [77] = "SHA", - [78] = "AES", + [77] = "AES", + [78] = "SHA", [79] = "FROM_CPU_INTR0", [80] = "FROM_CPU_INTR1", [81] = "FROM_CPU_INTR2", diff --git a/components/soc/esp32s3/ld/esp32s3.peripherals.ld b/components/soc/esp32s3/ld/esp32s3.peripherals.ld index 3d69f72f43..0b6d8881a2 100644 --- a/components/soc/esp32s3/ld/esp32s3.peripherals.ld +++ b/components/soc/esp32s3/ld/esp32s3.peripherals.ld @@ -38,7 +38,6 @@ PROVIDE ( SYSCON = 0x60026000 ); PROVIDE ( I2C1 = 0x60027000 ); PROVIDE ( SDMMC = 0x60028000 ); PROVIDE ( TWAI = 0x6002B000 ); -PROVIDE ( GPSPI4 = 0x60037000 ); PROVIDE ( GDMA = 0x6003F000 ); PROVIDE ( UART2 = 0x6002E000 ); PROVIDE ( DMA = 0x6003F000 ); @@ -49,3 +48,4 @@ PROVIDE ( USB0 = 0x60080000 ); PROVIDE ( USB_DWC = 0x60080000 ); PROVIDE ( USB_WRAP = 0x60039000 ); PROVIDE ( WORLD_CONTROLLER = 0x600D0000 ); +PROVIDE ( SYSTEM = 0x600C0000 ); diff --git a/components/soc/esp32s3/spi_periph.c b/components/soc/esp32s3/spi_periph.c index fb7417ba6d..a1098d035f 100644 --- a/components/soc/esp32s3/spi_periph.c +++ b/components/soc/esp32s3/spi_periph.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 */ @@ -12,29 +12,30 @@ */ const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = { { - .spiclk_out = SPICLK_OUT_IDX, - .spiclk_in = 0,/* SPI clock is not an input signal*/ - .spid_out = SPID_OUT_IDX, - .spiq_out = SPIQ_OUT_IDX, - .spiwp_out = SPIWP_OUT_IDX, - .spihd_out = SPIHD_OUT_IDX, - .spid_in = SPID_IN_IDX, - .spiq_in = SPIQ_IN_IDX, - .spiwp_in = SPIWP_IN_IDX, - .spihd_in = SPIHD_IN_IDX, - .spics_out = {SPICS0_OUT_IDX, SPICS1_OUT_IDX},/* SPI0/1 do not have CS2 now */ - .spics_in = 0,/* SPI cs is not an input signal*/ - .spiclk_iomux_pin = SPI_IOMUX_PIN_NUM_CLK, - .spid_iomux_pin = SPI_IOMUX_PIN_NUM_MOSI, - .spiq_iomux_pin = SPI_IOMUX_PIN_NUM_MISO, - .spiwp_iomux_pin = SPI_IOMUX_PIN_NUM_WP, - .spihd_iomux_pin = SPI_IOMUX_PIN_NUM_HD, - .spics0_iomux_pin = SPI_IOMUX_PIN_NUM_CS, - .irq = ETS_SPI1_INTR_SOURCE, + // MSPI has dedicated iomux pins + .spiclk_out = -1, + .spiclk_in = -1, + .spid_out = -1, + .spiq_out = -1, + .spiwp_out = -1, + .spihd_out = -1, + .spid_in = -1, + .spiq_in = -1, + .spiwp_in = -1, + .spihd_in = -1, + .spics_out = {-1}, + .spics_in = -1, + .spiclk_iomux_pin = -1, + .spid_iomux_pin = -1, + .spiq_iomux_pin = -1, + .spiwp_iomux_pin = -1, + .spihd_iomux_pin = -1, + .spics0_iomux_pin = -1, + .irq = -1, .irq_dma = -1, - .module = PERIPH_SPI_MODULE, - .hw = (spi_dev_t *) &SPIMEM1, - .func = SPI_FUNC_NUM, + .module = -1, + .hw = NULL, + .func = -1, }, { .spiclk_out = FSPICLK_OUT_IDX, .spiclk_in = FSPICLK_IN_IDX, diff --git a/components/soc/esp32s2/usb_otg_periph.c b/components/soc/esp32s3/usb_dwc_periph.c similarity index 91% rename from components/soc/esp32s2/usb_otg_periph.c rename to components/soc/esp32s3/usb_dwc_periph.c index e2f96e23b6..eba3eaaf60 100644 --- a/components/soc/esp32s2/usb_otg_periph.c +++ b/components/soc/esp32s3/usb_dwc_periph.c @@ -1,10 +1,10 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/usb_otg_periph.h" +#include "soc/usb_dwc_periph.h" #include "soc/gpio_sig_map.h" /* diff --git a/components/soc/esp32s3/usb_periph.c b/components/soc/esp32s3/usb_periph.c index 2f55335feb..a3fda7193e 100644 --- a/components/soc/esp32s3/usb_periph.c +++ b/components/soc/esp32s3/usb_periph.c @@ -1,20 +1,19 @@ -// 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: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "soc/soc_caps.h" #include "soc/usb_periph.h" +/* +Note: These IO pins are deprecated. When connecting USB OTG to an external FSLS +PHY, the FSLS Serial Interface signals can be routed to any GPIO via the GPIO +matrix. Thus, this mapping of signals to IO pins is meaningless. + +Todo: Remove in IDF v6.0 (IDF-9029) +*/ const usb_iopin_dsc_t usb_periph_iopins[] = { {USBPHY_VP_NUM, USB_EXTPHY_VP_IDX, 0, 1}, {USBPHY_VM_NUM, USB_EXTPHY_VM_IDX, 0, 1}, diff --git a/components/soc/include/soc/chip_revision.h b/components/soc/include/soc/chip_revision.h index 51955c94d9..fbdc94a02c 100644 --- a/components/soc/include/soc/chip_revision.h +++ b/components/soc/include/soc/chip_revision.h @@ -1,13 +1,11 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once -#include "sdkconfig.h" - #ifdef __cplusplus extern "C" { #endif @@ -33,8 +31,6 @@ extern "C" { #define ESP_CHIP_REV_ABOVE(rev, min_rev) ((min_rev) <= (rev)) #define ESP_CHIP_REV_MAJOR_AND_ABOVE(rev, min_rev) (((rev) / 100 == (min_rev) / 100) && ((rev) >= (min_rev))) -// _Static_assert(CONFIG_ESP_REV_MIN_FULL <= CONFIG_ESP_REV_MAX_FULL); - #ifdef __cplusplus } #endif diff --git a/components/soc/include/soc/rtc_io_periph.h b/components/soc/include/soc/rtc_io_periph.h index cb4facbf76..eaba50077f 100644 --- a/components/soc/include/soc/rtc_io_periph.h +++ b/components/soc/include/soc/rtc_io_periph.h @@ -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 */ @@ -11,11 +11,13 @@ //include soc related (generated) definitions #include "soc/soc_caps.h" -#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED +#if SOC_RTCIO_PIN_COUNT > 0 #include "soc/rtc_io_channel.h" +#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED #include "soc/rtc_io_reg.h" #include "soc/rtc_io_struct.h" #endif +#endif #if SOC_ADC_RTC_CTRL_SUPPORTED #include "soc/sens_struct.h" @@ -26,8 +28,8 @@ extern "C" { #endif +#if SOC_RTCIO_PIN_COUNT > 0 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED - /** * @brief Pin function information for a single RTCIO pad's. * @@ -60,6 +62,7 @@ typedef struct { * for external use. */ extern const rtc_io_desc_t rtc_io_desc[SOC_RTCIO_PIN_COUNT]; +#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED /** * @brief Provides a constant table to get rtc io number with gpio number @@ -68,8 +71,7 @@ extern const rtc_io_desc_t rtc_io_desc[SOC_RTCIO_PIN_COUNT]; * for external use. */ extern const int rtc_io_num_map[SOC_GPIO_PIN_COUNT]; - -#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED +#endif //SOC_RTCIO_PIN_COUNT > 0 #ifdef __cplusplus } diff --git a/components/soc/include/soc/usb_dwc_periph.h b/components/soc/include/soc/usb_dwc_periph.h new file mode 100644 index 0000000000..d13286aa1d --- /dev/null +++ b/components/soc/include/soc/usb_dwc_periph.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include +#include "soc/soc_caps.h" +#include "soc/periph_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Stores a bunch of USB-peripheral data. +*/ +typedef struct { + const uint8_t extphy_vp_in; + const uint8_t extphy_vm_in; + const uint8_t extphy_rcv_in; + const uint8_t extphy_oen_out; + const uint8_t extphy_vpo_out; + const uint8_t extphy_vmo_out; + const uint8_t extphy_suspend_in; + const uint8_t extphy_speed_in; + const uint8_t srp_bvalid_in; + const uint8_t srp_sessend_in; + const uint8_t srp_chrgvbus_out; + const uint8_t srp_dischrgvbus_out; + const uint8_t otg_iddig_in; + const uint8_t otg_avalid_in; + const uint8_t otg_vbusvalid_in; + const uint8_t otg_idpullup_out; + const uint8_t otg_dppulldown_out; + const uint8_t otg_dmpulldown_out; + const uint8_t otg_drvvbus_out; + const periph_module_t module; +} usb_phy_signal_conn_t; + +extern const usb_phy_signal_conn_t usb_otg_periph_signal; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/include/soc/usb_otg_periph.h b/components/soc/include/soc/usb_otg_periph.h index d13286aa1d..be92ac4eb1 100644 --- a/components/soc/include/soc/usb_otg_periph.h +++ b/components/soc/include/soc/usb_otg_periph.h @@ -1,46 +1,12 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once -#include -#include "soc/soc_caps.h" -#include "soc/periph_defs.h" -#ifdef __cplusplus -extern "C" { -#endif +/* Todo: Remove in ESP-IDF v6.0 (IDF-9052) */ +#warning "This header is deprecated, please use usb_dwc_periph.h instead" -/* - Stores a bunch of USB-peripheral data. -*/ -typedef struct { - const uint8_t extphy_vp_in; - const uint8_t extphy_vm_in; - const uint8_t extphy_rcv_in; - const uint8_t extphy_oen_out; - const uint8_t extphy_vpo_out; - const uint8_t extphy_vmo_out; - const uint8_t extphy_suspend_in; - const uint8_t extphy_speed_in; - const uint8_t srp_bvalid_in; - const uint8_t srp_sessend_in; - const uint8_t srp_chrgvbus_out; - const uint8_t srp_dischrgvbus_out; - const uint8_t otg_iddig_in; - const uint8_t otg_avalid_in; - const uint8_t otg_vbusvalid_in; - const uint8_t otg_idpullup_out; - const uint8_t otg_dppulldown_out; - const uint8_t otg_dmpulldown_out; - const uint8_t otg_drvvbus_out; - const periph_module_t module; -} usb_phy_signal_conn_t; - -extern const usb_phy_signal_conn_t usb_otg_periph_signal; - -#ifdef __cplusplus -} -#endif +#include "soc/usb_dwc_periph.h" diff --git a/components/soc/include/soc/usb_periph.h b/components/soc/include/soc/usb_periph.h index 1f0adb36b5..cd2672e79a 100644 --- a/components/soc/include/soc/usb_periph.h +++ b/components/soc/include/soc/usb_periph.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,18 +10,21 @@ #include #include "soc/soc_pins.h" #include "soc/gpio_sig_map.h" -#include "soc/usb_reg.h" -#include "soc/usb_types.h" -#include "soc/usb_struct.h" -#include "soc/usb_wrap_reg.h" -#include "soc/usb_wrap_struct.h" #ifdef __cplusplus extern "C" { #endif +#if SOC_USB_OTG_SUPPORTED + /** - * @brief A pin descriptor for init + * @brief A pin descriptor for init (DEPRECATED) + * + * Todo: Remove in IDF v6.0 (IDF-9029) + * + * @note These IO pins are deprecated. When connecting USB OTG to an external + * FSLS PHY, the FSLS Serial Interface signals can be routed to any GPIO via the + * GPI0 matrix. Thus, this mapping of signals to IO pins is meaningless. */ typedef struct { const int pin; @@ -32,6 +35,8 @@ typedef struct { extern const usb_iopin_dsc_t usb_periph_iopins[]; +#endif // SOC_USB_OTG_SUPPORTED + #ifdef __cplusplus } #endif diff --git a/components/spi_flash/.build-test-rules.yml b/components/spi_flash/.build-test-rules.yml index 6f208cb0ab..c7a4396dc8 100644 --- a/components/spi_flash/.build-test-rules.yml +++ b/components/spi_flash/.build-test-rules.yml @@ -6,6 +6,12 @@ components/spi_flash/test_apps/esp_flash: temporary: true reason: target esp32c6 cannot pass atomic build, target esp32h2 currently doesn't support GPSPI. +components/spi_flash/test_apps/esp_flash_stress: + enable: + - if: IDF_TARGET in ["esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s2", "esp32s3"] + temporary: true + reason: all targets according to the README file + components/spi_flash/test_apps/flash_encryption: disable_test: - if: IDF_TARGET in ["esp32c2", "esp32s2", "esp32c6", "esp32h2"] diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index e6242bd07f..eee2c4989f 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -1,5 +1,7 @@ idf_build_get_property(target IDF_TARGET) if(${target} STREQUAL "linux") + idf_component_register(INCLUDE_DIRS include + PRIV_INCLUDE_DIRS include/spi_flash) return() endif() @@ -13,7 +15,7 @@ else() list(APPEND srcs "${target}/spi_flash_oct_flash_init.c") endif() - if(CONFIG_IDF_TARGET_ESP32S3) + if(CONFIG_SPI_FLASH_HPM_ON) list(APPEND srcs "spi_flash_hpm_enable.c") endif() diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index 86112d67e1..652cd5e53b 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -1,3 +1,109 @@ +menu "Main Flash configuration" + depends on !APP_BUILD_TYPE_PURE_RAM_APP + + menu "SPI Flash behavior when brownout" + + config SPI_FLASH_BROWNOUT_RESET_XMC + bool "Enable sending reset when brownout for XMC flash chips" + default y + select SPI_FLASH_BROWNOUT_RESET + help + When this option is selected, the patch will be enabled for XMC. + Follow the recommended flow by XMC for better stability. + + DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING. + + config SPI_FLASH_BROWNOUT_RESET + bool + default y + select ESP_SYSTEM_BROWNOUT_INTR + help + When brownout happens during flash erase/write operations, + send reset command to stop the flash operations to improve stability. + + endmenu + + menu "Optional and Experimental Features (READ DOCS FIRST)" + + comment "Features here require specific hardware (READ DOCS FIRST!)" + + config SPI_FLASH_UNDER_HIGH_FREQ + bool + default y if ESPTOOLPY_FLASHFREQ_120M + help + This is a helper config for HPM. Invisible for users. + + choice SPI_FLASH_HPM + prompt "High Performance Mode (READ DOCS FIRST, > 80MHz)" + # Currently, only esp32s3 allows high performance mode. + depends on IDF_TARGET_ESP32S3 && !ESPTOOLPY_OCT_FLASH + default SPI_FLASH_HPM_AUTO + help + Whether the High Performance Mode of Flash is enabled. As an optional feature, user needs to manually + enable this option as a confirmation. To be back-compatible with earlier IDF versionn, this option is + automatically enabled with warning when Flash running > 80Mhz. + + config SPI_FLASH_HPM_ENA + # Not using name of SPI_FLASH_HPM_ENABLE because it was used as an invisible option and we don't want + # to inherit the value of that one + bool "Enable" + config SPI_FLASH_HPM_AUTO + bool "Auto (Not recommended)" + config SPI_FLASH_HPM_DIS + bool "Disabled" + endchoice + + config SPI_FLASH_HPM_ON + bool + # For ESP32-S3, it's enabled by default. For later chips it should be disabled by default + default y if IDF_TARGET_ESP32S3 && ((SPI_FLASH_HPM_ENA || SPI_FLASH_HPM_AUTO)) || \ + (!IDF_TARGET_ESP32S3 && SPI_FLASH_HPM_ENA) + help + This option is invisible, and will be selected automatically + when ``ESPTOOLPY_FLASHFREQ_120M`` is selected. + + choice SPI_FLASH_HPM_DC + prompt "Support HPM using DC (READ DOCS FIRST)" + depends on SPI_FLASH_HPM_ON + default SPI_FLASH_HPM_DC_AUTO + help + This feature needs your bootloader to be compiled DC-aware (BOOTLOADER_FLASH_DC_AWARE=y). Otherwise the + chip will not be able to boot after a reset. + + config SPI_FLASH_HPM_DC_AUTO + bool "Auto (Enable when bootloader support enabled (BOOTLOADER_FLASH_DC_AWARE))" + config SPI_FLASH_HPM_DC_DISABLE + bool "Disable (READ DOCS FIRST)" + endchoice + + config SPI_FLASH_HPM_DC_ON + bool + default y if SPI_FLASH_HPM_DC_AUTO && BOOTLOADER_FLASH_DC_AWARE + help + This is a helper config for HPM. Whether HPM-DC is enabled is also determined by bootloader. + Invisible for users. + + config SPI_FLASH_AUTO_SUSPEND + bool "Auto suspend long erase/write operations (READ DOCS FIRST)" + default n + depends on IDF_TARGET_ESP32C3 && !SPI_FLASH_ROM_IMPL + help + This option is disabled by default because it is supported only + for specific flash chips and for specific Espressif chips. + To evaluate if you can use this feature refer to + `Optional Features for Flash` > `Auto Suspend & Resume` of the `ESP-IDF Programming Guide`. + + CAUTION: If you want to OTA to an app with this feature turned on, please make + sure the bootloader has the support for it. (later than IDF v4.3) + + If you are using an official Espressif module, please contact Espressif Business support + to check if the module has the flash that support this feature installed. + Also refer to `Concurrency Constraints for Flash on SPI1` > `Flash Auto Suspend Feature` + before enabling this option. + + endmenu +endmenu + menu "SPI Flash driver" depends on !APP_BUILD_TYPE_PURE_RAM_APP @@ -147,20 +253,6 @@ menu "SPI Flash driver" help Defines how many ticks will be before returning to continue a erasing. - config SPI_FLASH_AUTO_SUSPEND - bool "Auto suspend long erase/write operations (READ DOCS FIRST)" - default n - depends on IDF_TARGET_ESP32C3 && !SPI_FLASH_ROM_IMPL - help - This option is default n before ESP32-C3, because it needs bootloader support. - - CAUTION: If you want to OTA to an app with this feature turned on, please make - sure the bootloader has the support for it. (later than IDF v4.3) - - Auto-suspend feature only supported by XMC chip. - If you are using an official module, please contact Espressif Business support. - Also reading auto suspend part in `SPI Flash API` document before you enable this function. - config SPI_FLASH_WRITE_CHUNK_SIZE int "Flash write chunk size" default 8192 @@ -197,28 +289,6 @@ menu "SPI Flash driver" See example: custom_chip_driver under examples/storage for more details. - menu "SPI Flash behavior when brownout" - - config SPI_FLASH_BROWNOUT_RESET_XMC - bool "Enable sending reset when brownout for XMC flash chips" - default y - select SPI_FLASH_BROWNOUT_RESET - help - When this option is selected, the patch will be enabled for XMC. - Follow the recommended flow by XMC for better stability. - - DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING. - - config SPI_FLASH_BROWNOUT_RESET - bool - default y - select ESP_SYSTEM_BROWNOUT_INTR - help - When brownout happens during flash erase/write operations, - send reset command to stop the flash operations to improve stability. - - endmenu - menu "Auto-detect flash chips" visible if !SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST @@ -305,10 +375,4 @@ menu "SPI Flash driver" application is not using flash encryption feature and is in need of some additional memory from IRAM region (~1KB) then this config can be disabled. - config SPI_FLASH_HPM_ENABLE - bool - default n - help - This option is invisible, and will be selected automatically - when ``ESPTOOLPY_FLASHFREQ_120M`` is selected. endmenu diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index f91817d69b..b2d1c9b958 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -41,10 +41,12 @@ #include "soc/ext_mem_defs.h" #endif #include "esp_rom_spiflash.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" #include #include "sdkconfig.h" #ifndef CONFIG_FREERTOS_UNICORE -#include "esp_ipc.h" +#include "esp_private/esp_ipc.h" #endif #include "esp_attr.h" #include "esp_memory_utils.h" @@ -58,18 +60,6 @@ static __attribute__((unused)) const char *TAG = "cache"; -#define DPORT_CACHE_BIT(cpuid, regid) DPORT_ ## cpuid ## regid - -#define DPORT_CACHE_MASK(cpuid) (DPORT_CACHE_BIT(cpuid, _CACHE_MASK_OPSDRAM) | DPORT_CACHE_BIT(cpuid, _CACHE_MASK_DROM0) | \ - DPORT_CACHE_BIT(cpuid, _CACHE_MASK_DRAM1) | DPORT_CACHE_BIT(cpuid, _CACHE_MASK_IROM0) | \ - DPORT_CACHE_BIT(cpuid, _CACHE_MASK_IRAM1) | DPORT_CACHE_BIT(cpuid, _CACHE_MASK_IRAM0) ) - -#define DPORT_CACHE_VAL(cpuid) (~(DPORT_CACHE_BIT(cpuid, _CACHE_MASK_DROM0) | \ - DPORT_CACHE_BIT(cpuid, _CACHE_MASK_DRAM1) | \ - DPORT_CACHE_BIT(cpuid, _CACHE_MASK_IRAM0))) - -#define DPORT_CACHE_GET_VAL(cpuid) (cpuid == 0) ? DPORT_CACHE_VAL(PRO) : DPORT_CACHE_VAL(APP) -#define DPORT_CACHE_GET_MASK(cpuid) (cpuid == 0) ? DPORT_CACHE_MASK(PRO) : DPORT_CACHE_MASK(APP) /** * These two shouldn't be declared as static otherwise if `CONFIG_SPI_FLASH_ROM_IMPL` is enabled, @@ -78,15 +68,9 @@ static __attribute__((unused)) const char *TAG = "cache"; void spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state); void spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state); +// Used only on ROM impl. in idf, this param unused, cache status hold by hal static uint32_t s_flash_op_cache_state[2]; -#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 -/* esp32c6 does not has a register indicating if cache is enabled - * so we use s static data to store to state of cache, every time - * disable/restore api is called, the state will be updated - */ -static volatile DRAM_ATTR bool s_cache_enabled = 1; -#endif #ifndef CONFIG_FREERTOS_UNICORE static SemaphoreHandle_t s_flash_op_mutex; @@ -171,8 +155,8 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void) spi_flash_op_lock(); - const int cpuid = xPortGetCoreID(); - const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; + int cpuid = xPortGetCoreID(); + uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; #ifndef NDEBUG // For sanity check later: record the CPU which has started doing flash operation assert(s_flash_op_cpu == -1); @@ -187,33 +171,45 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void) // esp_intr_noniram_disable. assert(other_cpuid == 1); } else { - // Temporarily raise current task priority to prevent a deadlock while - // waiting for IPC task to start on the other CPU - prvTaskSavedPriority_t SavedPriority; - prvTaskPriorityRaise(&SavedPriority, configMAX_PRIORITIES - 1); - - // Signal to the spi_flash_op_block_task on the other CPU that we need it to - // disable cache there and block other tasks from executing. - s_flash_op_can_start = false; - ESP_ERROR_CHECK(esp_ipc_call(other_cpuid, &spi_flash_op_block_func, (void *) other_cpuid)); + bool ipc_call_was_send_to_other_cpu; + do { + #ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionDisable(NULL); + #else + // Disable scheduler on the current CPU + vTaskSuspendAll(); + #endif // CONFIG_FREERTOS_SMP + + cpuid = xPortGetCoreID(); + other_cpuid = (cpuid == 0) ? 1 : 0; + #ifndef NDEBUG + s_flash_op_cpu = cpuid; + #endif + + s_flash_op_can_start = false; + + ipc_call_was_send_to_other_cpu = esp_ipc_call_nonblocking(other_cpuid, &spi_flash_op_block_func, (void *) other_cpuid) == ESP_OK; + + if (!ipc_call_was_send_to_other_cpu) { + // IPC call was not send to other cpu because another nonblocking API is running now. + // Enable the Scheduler again will not help the IPC to speed it up + // but there is a benefit to schedule to a higher priority task before the nonblocking running IPC call is done. + #ifdef CONFIG_FREERTOS_SMP + //Note: Scheduler suspension behavior changed in FreeRTOS SMP + vTaskPreemptionEnable(NULL); + #else + xTaskResumeAll(); + #endif // CONFIG_FREERTOS_SMP + } + } while (!ipc_call_was_send_to_other_cpu); while (!s_flash_op_can_start) { // Busy loop and wait for spi_flash_op_block_func to disable cache // on the other CPU } -#ifdef CONFIG_FREERTOS_SMP - //Note: Scheduler suspension behavior changed in FreeRTOS SMP - vTaskPreemptionDisable(NULL); -#else - // Disable scheduler on the current CPU - vTaskSuspendAll(); -#endif // CONFIG_FREERTOS_SMP - // Can now set the priority back to the normal one - prvTaskPriorityRestore(&SavedPriority); - // This is guaranteed to run on CPU because the other CPU is now - // occupied by highest priority task - assert(xPortGetCoreID() == cpuid); } + // Kill interrupts that aren't located in IRAM esp_intr_noniram_disable(); // This CPU executes this routine, with non-IRAM interrupts and the scheduler @@ -221,13 +217,16 @@ void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu(void) // with non-iram interrupts and the scheduler disabled. None of these CPUs will // touch external RAM or flash this way, so we can safely disable caches. spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]); +#if SOC_IDCACHE_PER_CORE + //only needed if cache(s) is per core spi_flash_disable_cache(other_cpuid, &s_flash_op_cache_state[other_cpuid]); +#endif } void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu(void) { const int cpuid = xPortGetCoreID(); - const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; + #ifndef NDEBUG // Sanity check: flash operation ends on the same CPU as it has started assert(cpuid == s_flash_op_cpu); @@ -236,9 +235,13 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu(void) s_flash_op_cpu = -1; #endif - // Re-enable cache on both CPUs. After this, cache (flash and external RAM) should work again. + // Re-enable cache. After this, cache (flash and external RAM) should work again. spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]); +#if SOC_IDCACHE_PER_CORE + //only needed if cache(s) is per core + const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0; spi_flash_restore_cache(other_cpuid, s_flash_op_cache_state[other_cpuid]); +#endif if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { // Signal to spi_flash_op_block_task that flash operation is complete @@ -352,6 +355,19 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os(void) #endif // CONFIG_FREERTOS_UNICORE + +void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid) +{ +#if CONFIG_IDF_TARGET_ESP32 + uint32_t cache_value = cache_ll_l1_get_enabled_bus(cpuid); + + // Re-enable cache on this CPU + spi_flash_restore_cache(cpuid, cache_value); +#else + spi_flash_restore_cache(0, 0); // TODO cache_value should be non-zero +#endif +} + /** * The following two functions are replacements for Cache_Read_Disable and Cache_Read_Enable * function in ROM. They are used to work around a bug where Cache_Read_Disable requires a call to @@ -359,87 +375,17 @@ void IRAM_ATTR spi_flash_enable_interrupts_caches_no_os(void) */ void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t *saved_state) { -#if CONFIG_IDF_TARGET_ESP32 - uint32_t ret = 0; - const uint32_t cache_mask = DPORT_CACHE_GET_MASK(cpuid); - if (cpuid == 0) { - ret |= DPORT_GET_PERI_REG_BITS2(DPORT_PRO_CACHE_CTRL1_REG, cache_mask, 0); - while (DPORT_GET_PERI_REG_BITS2(DPORT_PRO_DCACHE_DBUG0_REG, DPORT_PRO_CACHE_STATE, DPORT_PRO_CACHE_STATE_S) != 1) { - ; - } - DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 0, DPORT_PRO_CACHE_ENABLE_S); - } -#if !CONFIG_FREERTOS_UNICORE - else { - ret |= DPORT_GET_PERI_REG_BITS2(DPORT_APP_CACHE_CTRL1_REG, cache_mask, 0); - while (DPORT_GET_PERI_REG_BITS2(DPORT_APP_DCACHE_DBUG0_REG, DPORT_APP_CACHE_STATE, DPORT_APP_CACHE_STATE_S) != 1) { - ; - } - DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL_REG, 1, 0, DPORT_APP_CACHE_ENABLE_S); - } -#endif - *saved_state = ret; -#elif CONFIG_IDF_TARGET_ESP32S2 - *saved_state = Cache_Suspend_ICache(); -#elif CONFIG_IDF_TARGET_ESP32S3 - uint32_t icache_state, dcache_state; - icache_state = Cache_Suspend_ICache() << 16; - dcache_state = Cache_Suspend_DCache(); - *saved_state = icache_state | dcache_state; -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 - uint32_t icache_state; - icache_state = Cache_Suspend_ICache() << 16; - *saved_state = icache_state; -#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 - uint32_t icache_state; - icache_state = Cache_Suspend_ICache(); - *saved_state = icache_state; - s_cache_enabled = 0; -#endif + cache_hal_suspend(CACHE_TYPE_ALL); } void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state) { -#if CONFIG_IDF_TARGET_ESP32 - const uint32_t cache_mask = DPORT_CACHE_GET_MASK(cpuid); - if (cpuid == 0) { - DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL_REG, 1, 1, DPORT_PRO_CACHE_ENABLE_S); - DPORT_SET_PERI_REG_BITS(DPORT_PRO_CACHE_CTRL1_REG, cache_mask, saved_state, 0); - } -#if !CONFIG_FREERTOS_UNICORE - else { - DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL_REG, 1, 1, DPORT_APP_CACHE_ENABLE_S); - DPORT_SET_PERI_REG_BITS(DPORT_APP_CACHE_CTRL1_REG, cache_mask, saved_state, 0); - } -#endif -#elif CONFIG_IDF_TARGET_ESP32S2 - Cache_Resume_ICache(saved_state); -#elif CONFIG_IDF_TARGET_ESP32S3 - Cache_Resume_DCache(saved_state & 0xffff); - Cache_Resume_ICache(saved_state >> 16); -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 - Cache_Resume_ICache(saved_state >> 16); -#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 - Cache_Resume_ICache(saved_state); - s_cache_enabled = 1; -#endif + cache_hal_resume(CACHE_TYPE_ALL); } -IRAM_ATTR bool spi_flash_cache_enabled(void) +bool IRAM_ATTR spi_flash_cache_enabled(void) { -#if CONFIG_IDF_TARGET_ESP32 - bool result = (DPORT_REG_GET_BIT(DPORT_PRO_CACHE_CTRL_REG, DPORT_PRO_CACHE_ENABLE) != 0); -#if portNUM_PROCESSORS == 2 - result = result && (DPORT_REG_GET_BIT(DPORT_APP_CACHE_CTRL_REG, DPORT_APP_CACHE_ENABLE) != 0); -#endif -#elif CONFIG_IDF_TARGET_ESP32S2 - bool result = (REG_GET_BIT(EXTMEM_PRO_ICACHE_CTRL_REG, EXTMEM_PRO_ICACHE_ENABLE) != 0); -#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 - bool result = (REG_GET_BIT(EXTMEM_ICACHE_CTRL_REG, EXTMEM_ICACHE_ENABLE) != 0); -#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 - bool result = s_cache_enabled; -#endif - return result; + return cache_hal_is_cache_enabled(CACHE_TYPE_ALL); } #if CONFIG_IDF_TARGET_ESP32S2 @@ -471,12 +417,17 @@ IRAM_ATTR void esp_config_instruction_cache_mode(void) IRAM_ATTR void esp_config_data_cache_mode(void) { +#define CACHE_SIZE_0KB 99 //If Cache set to 0 KB, cache is bypassed, the cache size doesn't take into effect. Set this macro to a unique value for log + cache_size_t cache_size; cache_ways_t cache_ways; cache_line_size_t cache_line_size; #if CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB -#if CONFIG_ESP32S2_DATA_CACHE_8KB +#if CONFIG_ESP32S2_DATA_CACHE_0KB + Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); + cache_size = CACHE_SIZE_0KB; +#elif CONFIG_ESP32S2_DATA_CACHE_8KB Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); cache_size = CACHE_SIZE_8KB; #else @@ -484,7 +435,10 @@ IRAM_ATTR void esp_config_data_cache_mode(void) cache_size = CACHE_SIZE_16KB; #endif #else -#if CONFIG_ESP32S2_DATA_CACHE_8KB +#if CONFIG_ESP32S2_DATA_CACHE_0KB + Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); + cache_size = CACHE_SIZE_0KB; +#elif CONFIG_ESP32S2_DATA_CACHE_8KB Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_DCACHE_LOW, CACHE_MEMORY_INVALID); cache_size = CACHE_SIZE_8KB; #else @@ -499,7 +453,7 @@ IRAM_ATTR void esp_config_data_cache_mode(void) #else cache_line_size = CACHE_LINE_SIZE_32B; #endif - ESP_EARLY_LOGI(TAG, "Data cache \t\t: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_8KB ? 8 : 16, 4, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : 32); + ESP_EARLY_LOGI(TAG, "Data cache \t\t: size %dKB, %dWays, cache line size %dByte", (cache_size == CACHE_SIZE_0KB) ? 0 : ((cache_size == CACHE_SIZE_8KB) ? 8 : 16), 4, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : 32); Cache_Set_DCache_Mode(cache_size, cache_ways, cache_line_size); Cache_Invalidate_DCache_All(); } @@ -980,16 +934,3 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable) return ESP_OK; } #endif // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 - -void IRAM_ATTR spi_flash_enable_cache(uint32_t cpuid) -{ -#if CONFIG_IDF_TARGET_ESP32 - uint32_t cache_value = DPORT_CACHE_GET_VAL(cpuid); - cache_value &= DPORT_CACHE_GET_MASK(cpuid); - - // Re-enable cache on this CPU - spi_flash_restore_cache(cpuid, cache_value); -#else - spi_flash_restore_cache(0, 0); // TODO cache_value should be non-zero -#endif -} diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index 7ffe2ef6ff..eff32ad4bc 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -148,12 +148,12 @@ _Static_assert(sizeof(io_mode_str)/IO_STR_LEN == SPI_FLASH_READ_MODE_MAX, "the i esp_err_t esp_flash_read_chip_id(esp_flash_t* chip, uint32_t* flash_id); -#ifndef CONFIG_SPI_FLASH_ROM_IMPL +#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV static esp_err_t spiflash_start_default(esp_flash_t *chip); static esp_err_t spiflash_end_default(esp_flash_t *chip, esp_err_t err); static esp_err_t check_chip_pointer_default(esp_flash_t **inout_chip); static esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t err, bool bus_acquired, uint32_t address, uint32_t length); -#endif //CONFIG_SPI_FLASH_ROM_IMPL +#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV typedef struct { esp_err_t (*start)(esp_flash_t *chip); @@ -162,7 +162,7 @@ typedef struct { esp_err_t (*flash_end_flush_cache)(esp_flash_t* chip, esp_err_t err, bool bus_acquired, uint32_t address, uint32_t length); } rom_spiflash_api_func_t; -#ifndef CONFIG_SPI_FLASH_ROM_IMPL +#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV // These functions can be placed in the ROM. For now we use the code in IDF. DRAM_ATTR static rom_spiflash_api_func_t default_spiflash_rom_api = { .start = spiflash_start_default, @@ -175,20 +175,17 @@ DRAM_ATTR rom_spiflash_api_func_t *rom_spiflash_api_funcs = &default_spiflash_ro #else extern rom_spiflash_api_func_t *esp_flash_api_funcs; #define rom_spiflash_api_funcs esp_flash_api_funcs -#endif // CONFIG_SPI_FLASH_ROM_IMPL +#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV /* Static function to notify OS of a new SPI flash operation. If returns an error result, caller must abort. If returns ESP_OK, caller must call rom_spiflash_api_funcs->end() before returning. */ -#ifndef CONFIG_SPI_FLASH_ROM_IMPL +#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV static esp_err_t IRAM_ATTR spiflash_start_default(esp_flash_t *chip) { - if (chip->os_func != NULL - && chip->os_func_data != NULL - && chip->os_func->start != NULL) - { + if (chip->os_func != NULL && chip->os_func->start != NULL) { esp_err_t err = chip->os_func->start(chip->os_func_data); if (err != ESP_OK) { return err; @@ -203,7 +200,6 @@ static esp_err_t IRAM_ATTR spiflash_start_default(esp_flash_t *chip) static esp_err_t IRAM_ATTR spiflash_end_default(esp_flash_t *chip, esp_err_t err) { if (chip->os_func != NULL - && chip->os_func_data != NULL && chip->os_func->end != NULL) { esp_err_t end_err = chip->os_func->end(chip->os_func_data); if (err == ESP_OK) { @@ -245,7 +241,7 @@ static IRAM_ATTR esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t er } return rom_spiflash_api_funcs->end(chip, err); } -#endif //CONFIG_SPI_FLASH_ROM_IMPL +#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV /* Top-level API functions, calling into chip_drv functions via chip->drv */ @@ -1127,6 +1123,98 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3 return err; } +inline static IRAM_ATTR bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len) +{ + uint32_t a_end = a_start + a_len; + uint32_t b_end = b_start + b_len; + return (a_end > b_start && b_end > a_start); +} + +esp_err_t IRAM_ATTR esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address, void *out_buffer, uint32_t length) +{ + esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); + if (err != ESP_OK) return err; + if (address + length > g_rom_flashchip.chip_size) { + return ESP_ERR_INVALID_SIZE; + } + if (length == 0) { + return ESP_OK; + } + if (out_buffer == NULL) { + return ESP_ERR_INVALID_ARG; + } + + COUNTER_START(); + const uint8_t *map; + spi_flash_mmap_handle_t map_handle; + size_t map_src = address & ~(SPI_FLASH_MMU_PAGE_SIZE - 1); + size_t map_size = length + (address - map_src); + + err = spi_flash_mmap(map_src, map_size, SPI_FLASH_MMAP_DATA, (const void **)&map, &map_handle); + if (err != ESP_OK) { + return err; + } + memcpy(out_buffer, map + (address - map_src), length); + spi_flash_munmap(map_handle); + + COUNTER_ADD_BYTES(read, length); + COUNTER_STOP(read); + return err; +} + +// test only, non-public +IRAM_ATTR esp_err_t esp_flash_get_io_mode(esp_flash_t* chip, bool* qe) +{ + esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); + VERIFY_CHIP_OP(get_io_mode); + esp_flash_io_mode_t io_mode; + + err = rom_spiflash_api_funcs->start(chip); + if (err != ESP_OK) { + return err; + } + err = chip->chip_drv->get_io_mode(chip, &io_mode); + err = rom_spiflash_api_funcs->end(chip, err); + if (err == ESP_OK) { + *qe = (io_mode == SPI_FLASH_QOUT); + } + return err; +} + +IRAM_ATTR esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe) +{ + esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); + VERIFY_CHIP_OP(set_io_mode); + + chip->read_mode = (qe? SPI_FLASH_QOUT: SPI_FLASH_SLOWRD); + err = rom_spiflash_api_funcs->start(chip); + if (err != ESP_OK) { + return err; + } + err = chip->chip_drv->set_io_mode(chip); + return rom_spiflash_api_funcs->end(chip, err); +} +#endif //CONFIG_SPI_FLASH_ROM_IMPL + +FORCE_INLINE_ATTR esp_err_t s_encryption_write_lock(esp_flash_t *chip) { +#if CONFIG_IDF_TARGET_ESP32S2 + esp_crypto_dma_lock_acquire(); +#endif //CONFIG_IDF_TARGET_ESP32S2 + return rom_spiflash_api_funcs->start(chip); +} + +FORCE_INLINE_ATTR esp_err_t s_encryption_write_unlock(esp_flash_t *chip) { + esp_err_t err = rom_spiflash_api_funcs->end(chip, ESP_OK); +#if CONFIG_IDF_TARGET_ESP32S2 + esp_crypto_dma_lock_release(); +#endif //CONFIG_IDF_TARGET_ESP32S2 + return err; +} + + +#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV +// use `esp_flash_write_encrypted` ROM version not in C3 and S3 + esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const void *buffer, uint32_t length) { esp_err_t ret = ESP_FAIL; @@ -1136,17 +1224,19 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres #endif //CONFIG_SPI_FLASH_VERIFY_WRITE esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); + VERIFY_CHIP_OP(write); // Flash encryption only support on main flash. if (chip != esp_flash_default_chip) { return ESP_ERR_NOT_SUPPORTED; } - if (err != ESP_OK) return err; + CHECK_WRITE_ADDRESS(chip, address, length); + if (buffer == NULL || address + length > chip->size) { return ESP_ERR_INVALID_ARG; } if ((address % 16) != 0) { - ESP_EARLY_LOGE(TAG, "flash encrypted write address must be 16 bytes aligned"); + ESP_DRAM_LOGE(TAG, "flash encrypted write address must be 16 bytes aligned"); return ESP_ERR_INVALID_ARG; } @@ -1155,14 +1245,22 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres } if ((length % 16) != 0) { - ESP_EARLY_LOGE(TAG, "flash encrypted write length must be multiple of 16"); + ESP_DRAM_LOGE(TAG, "flash encrypted write length must be multiple of 16"); return ESP_ERR_INVALID_SIZE; } bool bus_acquired = false; + bool lock_once = true; const uint8_t *ssrc = (const uint8_t *)buffer; + /* For buffer in internal RAM already, we only need to lock only once. + While for buffer in flash, we need to copy data from flash to internal RAM before + encrypted write every time. That means we need to lock/unlock before/after encrypted + write every time. + */ + lock_once = esp_ptr_in_dram(buffer); + COUNTER_START(); /* On ESP32, write_encrypted encrypts data in RAM as it writes, @@ -1180,6 +1278,27 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres */ uint8_t encrypt_buf[64] __attribute__((aligned(4))); uint32_t row_size_length; +#if CONFIG_IDF_TARGET_ESP32 + uint8_t pre_buf[16] = {0}; + uint8_t post_buf[16] = {0}; + + if((address % 32) != 0) { + esp_flash_read_encrypted(chip, address - 16, pre_buf, 16); + } + if(((address + length) % 32) != 0) { + esp_flash_read_encrypted(chip, address + length, post_buf, 16); + } +#endif + + if (lock_once == true) { + err = s_encryption_write_lock(chip); + if (err != ESP_OK) { + ESP_DRAM_LOGE(TAG, "flash acquire lock failed"); + return err; + } + bus_acquired = true; + } + for (size_t i = 0; i < length; i += row_size_length) { uint32_t row_addr = address + i; uint8_t row_size; @@ -1192,14 +1311,14 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres /* copy to second block in buffer */ memcpy(encrypt_buf + 16, ssrc + i, row_size); /* decrypt the first block from flash, will reencrypt to same bytes */ - esp_flash_read_encrypted(chip, row_addr, encrypt_buf, 16); + memcpy(encrypt_buf, pre_buf, 16); } else if (length - i == 16) { /* 16 bytes left, is first block of a 32 byte row */ row_size = 16; /* copy to first block in buffer */ memcpy(encrypt_buf, ssrc + i, row_size); /* decrypt the second block from flash, will reencrypt to same bytes */ - esp_flash_read_encrypted(chip, row_addr + 16, encrypt_buf + 16, 16); + memcpy(encrypt_buf + 16, post_buf, 16); } else { /* Writing a full 32 byte row (2 blocks) */ row_size = 32; @@ -1225,42 +1344,39 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres #if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE err = s_check_setting_zero_to_one(chip, row_addr, encrypt_byte, NULL, is_encrypted); if (err != ESP_OK) { + rom_spiflash_api_funcs->end(chip, ESP_OK); +#if CONFIG_IDF_TARGET_ESP32S2 + esp_crypto_dma_lock_release(); +#endif //CONFIG_IDF_TARGET_ESP32S2 //Error happens, we end flash operation. Re-enable cache and flush it goto restore_cache; } #endif //#if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE -#if CONFIG_IDF_TARGET_ESP32S2 -#endif //CONFIG_IDF_TARGET_ESP32S2 - err = rom_spiflash_api_funcs->start(chip); - - if (err != ESP_OK) { -#if CONFIG_IDF_TARGET_ESP32S2 -#endif //CONFIG_IDF_TARGET_ESP32S2 - //Error happens, we end flash operation. Re-enable cache and flush it - goto restore_cache; + if (lock_once == false) { + err = s_encryption_write_lock(chip); + if (err != ESP_OK) { + goto restore_cache; + } + bus_acquired = true; } - bus_acquired = true; err = chip->chip_drv->write_encrypted(chip, (uint32_t *)encrypt_buf, row_addr, encrypt_byte); if (err!= ESP_OK) { -#if CONFIG_IDF_TARGET_ESP32S2 -#endif //CONFIG_IDF_TARGET_ESP32S2 - bus_acquired = false; - assert(bus_acquired); //Error happens, we end flash operation. Re-enable cache and flush it goto restore_cache; } - err = rom_spiflash_api_funcs->end(chip, ESP_OK); - COUNTER_ADD_BYTES(write, encrypt_byte); -#if CONFIG_IDF_TARGET_ESP32S2 -#endif //CONFIG_IDF_TARGET_ESP32S2 - if (err != ESP_OK) { + if (lock_once == false) { + err = s_encryption_write_unlock(chip); + if (err != ESP_OK) { + bus_acquired = false; + //Error happens, we end flash operation. Re-enable cache and flush it + goto restore_cache; + } bus_acquired = false; - //Error happens, we end flash operation. Re-enable cache and flush it - goto restore_cache; } - bus_acquired = false; + + COUNTER_ADD_BYTES(write, encrypt_byte); #if CONFIG_SPI_FLASH_VERIFY_WRITE err = s_verify_write(chip, row_addr, encrypt_byte, (uint32_t *)encrypt_buf, is_encrypted); @@ -1271,12 +1387,25 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres #endif //CONFIG_SPI_FLASH_VERIFY_WRITE } + if (lock_once == true) { + err = s_encryption_write_unlock(chip); + if (err != ESP_OK) { + bus_acquired = false; + //Error happens, we end flash operation. Re-enable cache and flush it + goto restore_cache; + } + } + + bus_acquired = false; + COUNTER_STOP(write); err = rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); return err; restore_cache: + s_encryption_write_unlock(chip); + bus_acquired = false; COUNTER_STOP(write); ret = rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, address, length); if (ret != ESP_OK) { @@ -1286,78 +1415,7 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres return err; } -inline static IRAM_ATTR bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len) -{ - uint32_t a_end = a_start + a_len; - uint32_t b_end = b_start + b_len; - return (a_end > b_start && b_end > a_start); -} - -esp_err_t IRAM_ATTR esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address, void *out_buffer, uint32_t length) -{ - esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); - if (err != ESP_OK) return err; - if (address + length > g_rom_flashchip.chip_size) { - return ESP_ERR_INVALID_SIZE; - } - if (length == 0) { - return ESP_OK; - } - if (out_buffer == NULL) { - return ESP_ERR_INVALID_ARG; - } - - COUNTER_START(); - const uint8_t *map; - spi_flash_mmap_handle_t map_handle; - size_t map_src = address & ~(SPI_FLASH_MMU_PAGE_SIZE - 1); - size_t map_size = length + (address - map_src); - - err = spi_flash_mmap(map_src, map_size, SPI_FLASH_MMAP_DATA, (const void **)&map, &map_handle); - if (err != ESP_OK) { - return err; - } - memcpy(out_buffer, map + (address - map_src), length); - spi_flash_munmap(map_handle); - - COUNTER_ADD_BYTES(read, length); - COUNTER_STOP(read); - return err; -} - -// test only, non-public -IRAM_ATTR esp_err_t esp_flash_get_io_mode(esp_flash_t* chip, bool* qe) -{ - esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); - VERIFY_CHIP_OP(get_io_mode); - esp_flash_io_mode_t io_mode; - - err = rom_spiflash_api_funcs->start(chip); - if (err != ESP_OK) { - return err; - } - err = chip->chip_drv->get_io_mode(chip, &io_mode); - err = rom_spiflash_api_funcs->end(chip, err); - if (err == ESP_OK) { - *qe = (io_mode == SPI_FLASH_QOUT); - } - return err; -} - -IRAM_ATTR esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe) -{ - esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); - VERIFY_CHIP_OP(set_io_mode); - - chip->read_mode = (qe? SPI_FLASH_QOUT: SPI_FLASH_SLOWRD); - err = rom_spiflash_api_funcs->start(chip); - if (err != ESP_OK) { - return err; - } - err = chip->chip_drv->set_io_mode(chip); - return rom_spiflash_api_funcs->end(chip, err); -} -#endif //CONFIG_SPI_FLASH_ROM_IMPL +#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV //init suspend mode cmd, uses internal. esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip) diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index e999218b60..54c157a57e 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -354,6 +354,8 @@ esp_err_t esp_flash_init_default_chip(void) #endif #if CONFIG_ESPTOOLPY_OCT_FLASH + // Default value. When `CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT` selected, if the selected mode not consistent with + // hardware, will be overwritten in s_esp_flash_choose_correct_mode. cfg.octal_mode_en = 1; cfg.default_io_mode = DEFAULT_FLASH_MODE; #endif @@ -409,7 +411,7 @@ esp_err_t esp_flash_init_default_chip(void) } #endif -#if CONFIG_SPI_FLASH_HPM_ENABLE +#if CONFIG_SPI_FLASH_HPM_DC_ON if (spi_flash_hpm_dummy_adjust()) { default_chip.hpm_dummy_ena = 1; } diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index 55d0884cd9..4f9c4e7ad7 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -279,38 +279,6 @@ uint32_t spi_flash_mmap_get_free_pages(spi_flash_mmap_memory_t memory) return len / CONFIG_MMU_PAGE_SIZE; } - -size_t spi_flash_cache2phys(const void *cached) -{ - if (cached == NULL) { - return SPI_FLASH_CACHE2PHYS_FAIL; - } - - esp_err_t ret = ESP_FAIL; - uint32_t paddr = 0; - mmu_target_t target = 0; - - ret = esp_mmu_vaddr_to_paddr((void *)cached, &paddr, &target); - if (ret != ESP_OK) { - return SPI_FLASH_CACHE2PHYS_FAIL; - } - - int offset = 0; -#if CONFIG_SPIRAM_RODATA - if ((uint32_t)cached >= (uint32_t)&_rodata_reserved_start && (uint32_t)cached <= (uint32_t)&_rodata_reserved_end) { - offset = rodata_flash2spiram_offset(); - } -#endif -#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS - if ((uint32_t)cached >= (uint32_t)&_instruction_reserved_start && (uint32_t)cached <= (uint32_t)&_instruction_reserved_end) { - offset = instruction_flash2spiram_offset(); - } -#endif - - return paddr + offset * CONFIG_MMU_PAGE_SIZE; -} - - const void * spi_flash_phys2cache(size_t phys_offs, spi_flash_mmap_memory_t memory) { esp_err_t ret = ESP_FAIL; @@ -393,3 +361,37 @@ IRAM_ATTR bool spi_flash_check_and_flush_cache(size_t start_addr, size_t length) return ret; } #endif //!CONFIG_SPI_FLASH_ROM_IMPL + +#if !CONFIG_SPI_FLASH_ROM_IMPL || CONFIG_SPIRAM_FETCH_INSTRUCTIONS || CONFIG_SPIRAM_RODATA +//The ROM implementation returns physical address of the PSRAM when the .text or .rodata is in the PSRAM. +//Always patch it when SPIRAM_FETCH_INSTRUCTIONS or SPIRAM_RODATA is set. +size_t spi_flash_cache2phys(const void *cached) +{ + if (cached == NULL) { + return SPI_FLASH_CACHE2PHYS_FAIL; + } + + esp_err_t ret = ESP_FAIL; + uint32_t paddr = 0; + mmu_target_t target = 0; + + ret = esp_mmu_vaddr_to_paddr((void *)cached, &paddr, &target); + if (ret != ESP_OK) { + return SPI_FLASH_CACHE2PHYS_FAIL; + } + + int offset = 0; +#if CONFIG_SPIRAM_RODATA + if ((uint32_t)cached >= (uint32_t)&_rodata_reserved_start && (uint32_t)cached <= (uint32_t)&_rodata_reserved_end) { + offset = rodata_flash2spiram_offset(); + } +#endif +#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS + if ((uint32_t)cached >= (uint32_t)&_instruction_reserved_start && (uint32_t)cached <= (uint32_t)&_instruction_reserved_end) { + offset = instruction_flash2spiram_offset(); + } +#endif + + return paddr + offset * CONFIG_MMU_PAGE_SIZE; +} +#endif diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 43e6b7d4ed..8a1683afc6 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -159,16 +159,12 @@ esp_err_t IRAM_ATTR spi_flash_init_chip_state(void) #if SOC_SPI_MEM_SUPPORT_OPI_MODE if (bootloader_flash_is_octal_mode_enabled()) { return esp_opiflash_init(rom_spiflash_legacy_data->chip.device_id); - } else + } #endif - { - #if CONFIG_IDF_TARGET_ESP32S3 - // Currently, only esp32s3 allows high performance mode. +#if CONFIG_SPI_FLASH_HPM_ON return spi_flash_enable_high_performance_mode(); - #else - return ESP_OK; - #endif // CONFIG_IDF_TARGET_ESP32S3 - } +#endif // CONFIG_SPI_FLASH_HPM_ON + return ESP_OK; } void IRAM_ATTR spi_flash_set_rom_required_regs(void) diff --git a/components/spi_flash/include/esp_flash.h b/components/spi_flash/include/esp_flash.h index e5b92b9412..6031d77d7c 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -171,6 +171,8 @@ esp_err_t esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size); esp_err_t esp_flash_get_physical_size(esp_flash_t *chip, uint32_t *flash_size); /** @brief Read flash unique ID via the common "RDUID" SPI flash command. + * + * @note This is an optional feature, which is not supported on all flash chips. READ PROGRAMMING GUIDE FIRST! * * @param chip Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init(). * @param[out] out_id Pointer to receive unique ID value. diff --git a/components/spi_flash/include/esp_private/spi_flash_os.h b/components/spi_flash/include/esp_private/spi_flash_os.h index 15ef0bf4a2..2f6e1b3919 100644 --- a/components/spi_flash/include/esp_private/spi_flash_os.h +++ b/components/spi_flash/include/esp_private/spi_flash_os.h @@ -114,9 +114,15 @@ void spi_flash_set_erasing_flag(bool status); */ bool spi_flash_brownout_need_reset(void); +#if CONFIG_SPI_FLASH_HPM_ON /** * @brief Enable SPI flash high performance mode. * + * @note 1. When `CONFIG_SPI_FLASH_HPM_ON` is True, caller can always call this function without taking whether the used + * frequency falls into the HPM range into consideration. + * 2. However, caller shouldn't attempt to call this function on Octal flash. `CONFIG_SPI_FLASH_HPM_ON` may be + * True when `CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT && !CONFIG_ESPTOOLPY_OCT_FLASH` + * * @return ESP_OK if success. */ esp_err_t spi_flash_enable_high_performance_mode(void); @@ -136,6 +142,7 @@ const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void); * @return true Yes, and work under HPM with adjusting dummy. Otherwise, false. */ bool spi_flash_hpm_dummy_adjust(void); +#endif //CONFIG_SPI_FLASH_HPM_ON #if SOC_SPI_MEM_SUPPORT_WRAP /** diff --git a/components/spi_flash/linker.lf b/components/spi_flash/linker.lf index aae6bfa293..e331cfb36a 100644 --- a/components/spi_flash/linker.lf +++ b/components/spi_flash/linker.lf @@ -15,6 +15,8 @@ entries: if IDF_TARGET_ESP32S3 = y: spi_flash_chip_mxic_opi (noflash) + + if SPI_FLASH_HPM_ON = y: spi_flash_hpm_enable (noflash) if ESPTOOLPY_OCT_FLASH = y || ESPTOOLPY_FLASH_MODE_AUTO_DETECT = y: diff --git a/components/spi_flash/spi_flash_chip_generic.c b/components/spi_flash/spi_flash_chip_generic.c index d63bb73afc..7bf62abcf1 100644 --- a/components/spi_flash/spi_flash_chip_generic.c +++ b/components/spi_flash/spi_flash_chip_generic.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,7 @@ #include "esp_log.h" #include "esp_attr.h" #include "esp_private/spi_flash_os.h" +#include "esp_rom_caps.h" typedef struct flash_chip_dummy { uint8_t dio_dummy_bitlen; @@ -303,69 +304,6 @@ esp_err_t spi_flash_chip_generic_write(esp_flash_t *chip, const void *buffer, ui return err; } -esp_err_t spi_flash_chip_generic_write_encrypted(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length) -{ - spi_flash_encryption_t *esp_flash_encryption = &esp_flash_encryption_default; - esp_err_t err = ESP_OK; - // Encryption must happen on main flash. - if (chip != esp_flash_default_chip) { - return ESP_ERR_NOT_SUPPORTED; - } - - /* Check if the buffer and length can qualify the requirments */ - if (esp_flash_encryption->flash_encryption_check(address, length) != true) { - return ESP_ERR_NOT_SUPPORTED; - } - - const uint8_t *data_bytes = (const uint8_t *)buffer; - esp_flash_encryption->flash_encryption_enable(); - while (length > 0) { - int block_size; - /* Write the largest block if possible */ - if (address % 64 == 0 && length >= 64) { - block_size = 64; - } else if (address % 32 == 0 && length >= 32) { - block_size = 32; - } else { - block_size = 16; - } - // Prepare the flash chip (same time as AES operation, for performance) - esp_flash_encryption->flash_encryption_data_prepare(address, (uint32_t *)data_bytes, block_size); - err = chip->chip_drv->set_chip_write_protect(chip, false); - if (err != ESP_OK) { - return err; - } - // Waiting for encrypting buffer to finish and making result visible for SPI1 - esp_flash_encryption->flash_encryption_done(); - - // Note: For encryption function, after write flash command is sent. The hardware will write the encrypted buffer - // prepared in XTS_FLASH_ENCRYPTION register in function `flash_encryption_data_prepare`, instead of the origin - // buffer named `data_bytes`. - - err = chip->chip_drv->write(chip, (uint32_t *)data_bytes, address, length); - if (err != ESP_OK) { - return err; - } - err = chip->chip_drv->wait_idle(chip, chip->chip_drv->timeout->page_program_timeout); - if (err != ESP_OK) { - return err; - } - - // Note: we don't wait for idle status here, because this way - // the AES peripheral can start encrypting the next - // block while the SPI flash chip is busy completing the write - - esp_flash_encryption->flash_encryption_destroy(); - - length -= block_size; - data_bytes += block_size; - address += block_size; - } - - esp_flash_encryption->flash_encryption_disable(); - return err; -} - esp_err_t spi_flash_chip_generic_set_write_protect(esp_flash_t *chip, bool write_protect) { esp_err_t err = ESP_OK; @@ -562,6 +500,71 @@ esp_err_t spi_flash_chip_generic_set_io_mode(esp_flash_t *chip) } #endif // CONFIG_SPI_FLASH_ROM_IMPL +#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV +esp_err_t spi_flash_chip_generic_write_encrypted(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length) +{ + spi_flash_encryption_t *esp_flash_encryption = &esp_flash_encryption_default; + esp_err_t err = ESP_OK; + // Encryption must happen on main flash. + if (chip != esp_flash_default_chip) { + return ESP_ERR_NOT_SUPPORTED; + } + + /* Check if the buffer and length can qualify the requirments */ + if (esp_flash_encryption->flash_encryption_check(address, length) != true) { + return ESP_ERR_NOT_SUPPORTED; + } + + const uint8_t *data_bytes = (const uint8_t *)buffer; + esp_flash_encryption->flash_encryption_enable(); + while (length > 0) { + int block_size; + /* Write the largest block if possible */ + if (address % 64 == 0 && length >= 64) { + block_size = 64; + } else if (address % 32 == 0 && length >= 32) { + block_size = 32; + } else { + block_size = 16; + } + // Prepare the flash chip (same time as AES operation, for performance) + esp_flash_encryption->flash_encryption_data_prepare(address, (uint32_t *)data_bytes, block_size); + err = chip->chip_drv->set_chip_write_protect(chip, false); + if (err != ESP_OK) { + return err; + } + // Waiting for encrypting buffer to finish and making result visible for SPI1 + esp_flash_encryption->flash_encryption_done(); + + // Note: For encryption function, after write flash command is sent. The hardware will write the encrypted buffer + // prepared in XTS_FLASH_ENCRYPTION register in function `flash_encryption_data_prepare`, instead of the origin + // buffer named `data_bytes`. + + err = chip->chip_drv->write(chip, (uint32_t *)data_bytes, address, length); + if (err != ESP_OK) { + return err; + } + err = chip->chip_drv->wait_idle(chip, chip->chip_drv->timeout->page_program_timeout); + if (err != ESP_OK) { + return err; + } + + // Note: we don't wait for idle status here, because this way + // the AES peripheral can start encrypting the next + // block while the SPI flash chip is busy completing the write + + esp_flash_encryption->flash_encryption_destroy(); + + length -= block_size; + data_bytes += block_size; + address += block_size; + } + + esp_flash_encryption->flash_encryption_disable(); + return err; +} +#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV + esp_err_t spi_flash_chip_generic_read_unique_id(esp_flash_t *chip, uint64_t* flash_unique_id) { uint64_t unique_id_buf = 0; diff --git a/components/spi_flash/spi_flash_chip_mxic.c b/components/spi_flash/spi_flash_chip_mxic.c index fef8f99f19..089e08cff8 100644 --- a/components/spi_flash/spi_flash_chip_mxic.c +++ b/components/spi_flash/spi_flash_chip_mxic.c @@ -1,16 +1,8 @@ -// Copyright 2015-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: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include "spi_flash_chip_generic.h" @@ -35,6 +27,26 @@ esp_err_t spi_flash_chip_mxic_probe(esp_flash_t *chip, uint32_t flash_id) return ESP_OK; } +esp_err_t spi_flash_chip_mxic_detect_size(esp_flash_t *chip, uint32_t *size) +{ + uint32_t id = chip->chip_id; + *size = 0; + + /* Can't detect size unless the high byte of the product ID matches the same convention, which is usually 0x40 or + * 0xC0 or similar. */ + if (((id & 0xFFFF) == 0x0000) || ((id & 0xFFFF) == 0xFFFF)) { + return ESP_ERR_FLASH_UNSUPPORTED_CHIP; + } + + uint32_t mem_density = (id & 0xFF); + if (mem_density > 0x30) { // For OPI chips + mem_density -= 0x20; + } + + *size = (mem_density <= 31) ? (1U << mem_density) : 0; + return ESP_OK; +} + esp_err_t spi_flash_chip_issi_set_io_mode(esp_flash_t *chip); esp_err_t spi_flash_chip_issi_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* out_io_mode); @@ -61,7 +73,7 @@ const spi_flash_chip_t esp_flash_chip_mxic = { .timeout = &spi_flash_chip_generic_timeout, .probe = spi_flash_chip_mxic_probe, .reset = spi_flash_chip_generic_reset, - .detect_size = spi_flash_chip_generic_detect_size, + .detect_size = spi_flash_chip_mxic_detect_size, .erase_chip = spi_flash_chip_generic_erase_chip, .erase_sector = spi_flash_chip_generic_erase_sector, .erase_block = spi_flash_chip_generic_erase_block, diff --git a/components/spi_flash/spi_flash_hpm_enable.c b/components/spi_flash/spi_flash_hpm_enable.c index cf114c58c0..6e306d2f02 100644 --- a/components/spi_flash/spi_flash_hpm_enable.c +++ b/components/spi_flash/spi_flash_hpm_enable.c @@ -28,14 +28,28 @@ * 3. Some flash chips adjust dummy cycles. ******************************************************************************/ -#if CONFIG_ESPTOOLPY_FLASHFREQ_120M -#define FLASH_FREQUENCY 120 -#elif CONFIG_ESPTOOLPY_FLASHFREQ_80M -#define FLASH_FREQUENCY 80 -#elif CONFIG_ESPTOOLPY_FLASHFREQ_40M -#define FLASH_FREQUENCY 40 -#elif CONFIG_ESPTOOLPY_FLASHFREQ_20M -#define FLASH_FREQUENCY 20 +/* + * Note: This file should only be compiled when HPM_ON, which is only available when !CONFIG_ESPTOOLPY_OCT_FLASH. + * However when HPM_ON, there are still some cases this file is not actually used: + * + * - !CONFIG_SPI_FLASH_UNDER_HIGH_FREQ: + * It mean that the flash not running under frequency requires HPM. spi_flash_enable_high_performance_mode() still + * called because caller shouldn't take care of the frequency. + * + * - bootloader_flash_is_octal_mode_enabled() == true: + * This is possible when `CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT` selected + * + * Octal Flash for now all support 120M. No need to enable HPM. The file is compiled, but will not actually run + * into spi_flash_enable_high_performance_mode(). + */ + +void spi_flash_hpm_get_dummy_generic(spi_flash_hpm_dummy_conf_t *dummy_conf); + +#if CONFIG_SPI_FLASH_UNDER_HIGH_FREQ + +#if CONFIG_SPI_FLASH_HPM_AUTO +// This only happens on S3, where HPM_AUTO leads to HPM_ON +#warning High Performance Mode (QSPI Flash > 80MHz) is optional feature that depends on flash model. Read Docs First! #endif const static char *HPM_TAG = "flash HPM"; @@ -119,6 +133,7 @@ static esp_err_t spi_flash_high_performance_check_hpf_bit_5(void) //-----------------For flash chips which enter HPM via adjust dummy-----------------------// +#if CONFIG_SPI_FLASH_HPM_DC_ON /** * @brief Probe the chip whether adjust dummy to enable HPM mode. Take XMC as an example: * Adjust dummy bits to enable HPM mode of the flash. If XMC works under 80MHz, the dummy bits @@ -202,6 +217,14 @@ static void spi_flash_hpm_get_dummy_xmc(spi_flash_hpm_dummy_conf_t *dummy_conf) dummy_conf->qout_dummy = SPI_FLASH_QOUT_DUMMY_BITLEN; dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN; } +#elif !CONFIG_SPI_FLASH_HPM_DC_DISABLE + +//This is because bootloader doesn't support this +#warning HPM-DC, which helps to run some flash > 80MHz by adjusting dummy cycles, is no longer enabled by default. +#warning To enable this feature, your bootloader needs to have the support for it (by explicitly selecting BOOTLOADER_FLASH_DC_AWARE). +#warning If your bootloader does not support it, select SPI_FLASH_HPM_DC_DISABLE to suppress the warning. READ DOCS FIRST! + +#endif //CONFIG_SPI_FLASH_HPM_DC_ON //-----------------For flash chips which enter HPM via write status register-----------------------// @@ -251,33 +274,38 @@ static void spi_flash_turn_high_performance_write_hpf_bit_5(void) esp_rom_spiflash_wait_idle(&g_rom_flashchip); } -//-----------------------generic functions-------------------------------------// - -/** - * @brief Default dummy for almost all flash chips. If your flash does't need to reconfigure dummy, - * just call this function. - */ -void __attribute__((weak)) spi_flash_hpm_get_dummy_generic(spi_flash_hpm_dummy_conf_t *dummy_conf) -{ - dummy_conf->dio_dummy = SPI_FLASH_DIO_DUMMY_BITLEN; - dummy_conf->dout_dummy = SPI_FLASH_DOUT_DUMMY_BITLEN; - dummy_conf->qio_dummy = SPI_FLASH_QIO_DUMMY_BITLEN; - dummy_conf->qout_dummy = SPI_FLASH_QOUT_DUMMY_BITLEN; - dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN; -} - const spi_flash_hpm_info_t __attribute__((weak)) spi_flash_hpm_enable_list[] = { /* vendor, chip_id, freq_threshold, temperature threshold, operation for setting high performance, reading HPF status, get dummy */ { "command", spi_flash_hpm_probe_chip_with_cmd, spi_flash_hpm_chip_hpm_requirement_check_with_cmd, spi_flash_enable_high_performance_send_cmd, spi_flash_high_performance_check_hpf_bit_5, spi_flash_hpm_get_dummy_generic }, +#if CONFIG_SPI_FLASH_HPM_DC_ON { "dummy", spi_flash_hpm_probe_chip_with_dummy, spi_flash_hpm_chip_hpm_requirement_check_with_dummy, spi_flash_turn_high_performance_reconfig_dummy, spi_flash_high_performance_check_dummy_sr, spi_flash_hpm_get_dummy_xmc}, +#endif //CONFIG_SPI_FLASH_HPM_DC_ON { "write sr3-bit5", spi_flash_hpm_probe_chip_with_write_hpf_bit_5, spi_flash_hpm_chip_hpm_requirement_check_with_write_hpf_bit_5, spi_flash_turn_high_performance_write_hpf_bit_5, spi_flash_high_performance_check_hpf_bit_5, spi_flash_hpm_get_dummy_generic}, // default: do nothing, but keep the dummy get function. The first item with NULL as its probe will be the fallback. { "NULL", NULL, NULL, NULL, NULL, spi_flash_hpm_get_dummy_generic}, }; static const spi_flash_hpm_info_t *chip_hpm = NULL; -static spi_flash_hpm_dummy_conf_t dummy_conf; -static bool hpm_dummy_changed = false; + +#if CONFIG_SPI_FLASH_HPM_DC_ON +static bool s_hpm_dummy_changed = false; +static spi_flash_hpm_dummy_conf_t s_dummy_conf; + +const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void) +{ + chip_hpm->flash_get_dummy(&s_dummy_conf); + return &s_dummy_conf; +} + +bool spi_flash_hpm_dummy_adjust(void) +{ + return s_hpm_dummy_changed; +} +#endif //CONFIG_SPI_FLASH_HPM_DC_ON + +#if CONFIG_ESPTOOLPY_FLASHFREQ_120M +#define FLASH_FREQUENCY 120 +#endif esp_err_t spi_flash_enable_high_performance_mode(void) { @@ -288,6 +316,21 @@ esp_err_t spi_flash_enable_high_performance_mode(void) int voltage = 0; int temperature = 0; +#if CONFIG_SPI_FLASH_HPM_AUTO + ESP_EARLY_LOGW(HPM_TAG, "HPM mode is optional feature that depends on flash model. Read Docs First!"); +#endif + +#if CONFIG_SPI_FLASH_HPM_DC_DISABLE + // case 1: force disabled + ESP_EARLY_LOGI(HPM_TAG, "w/o HPM-DC support"); +#elif CONFIG_SPI_FLASH_HPM_DC_ON + // case 2: auto, and actually enabled + ESP_EARLY_LOGI(HPM_TAG, "with HPM-DC support"); +#else + // case 3: auto, but disabled (not supported by bootloader) + ESP_EARLY_LOGW(HPM_TAG, "HPM mode with DC adjustment is disabled. Some flash models may not be supported. Read Docs First!"); +#endif + const spi_flash_hpm_info_t *chip = spi_flash_hpm_enable_list; esp_err_t ret = ESP_OK; while (chip->probe) { @@ -299,10 +342,12 @@ esp_err_t spi_flash_enable_high_performance_mode(void) } chip_hpm = chip; + /* When > 80 MHz, flash chips usually need special HPM support to run normally. The support is chip-specific. When + * the chip is not in the known flash list, nothing will be done and there will be an warning. + * When <= 80 MHz, it's assumed that all flash chips can run without chip-specific HPM support. This function will not be called and there will be no warning. + */ if (ret != ESP_OK) { -#if (FLASH_FREQUENCY == 120) - ESP_EARLY_LOGW(HPM_TAG, "Flash high performance mode hasn't been supported"); -#endif + ESP_EARLY_LOGW(HPM_TAG, "High performance mode of this flash model hasn't been supported."); return ret; } @@ -316,21 +361,50 @@ esp_err_t spi_flash_enable_high_performance_mode(void) ESP_EARLY_LOGE(HPM_TAG, "Flash high performance mode hasn't been executed successfully"); return ESP_FAIL; } - hpm_dummy_changed = (hpm_requirement_check == SPI_FLASH_HPM_DUMMY_NEEDED) ? true : false; +#if CONFIG_SPI_FLASH_HPM_DC_ON + s_hpm_dummy_changed = (hpm_requirement_check == SPI_FLASH_HPM_DUMMY_NEEDED) ? true : false; +#else + assert(hpm_requirement_check != SPI_FLASH_HPM_DUMMY_NEEDED); +#endif } else if (hpm_requirement_check == SPI_FLASH_HPM_BEYOND_LIMIT) { ESP_EARLY_LOGE(HPM_TAG, "Flash does not have the ability to raise to that frequency"); return ESP_FAIL; } return ESP_OK; } +#else +//!CONFIG_SPI_FLASH_UNDER_HIGH_FREQ + +static spi_flash_hpm_dummy_conf_t s_dummy_conf; + +esp_err_t spi_flash_enable_high_performance_mode(void) +{ + return ESP_OK; +} const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void) { - chip_hpm->flash_get_dummy(&dummy_conf); - return &dummy_conf; + spi_flash_hpm_get_dummy_generic(&s_dummy_conf); + return &s_dummy_conf; } bool spi_flash_hpm_dummy_adjust(void) { - return hpm_dummy_changed; + return false; +} +#endif //CONFIG_SPI_FLASH_UNDER_HIGH_FREQ + +//-----------------------generic functions-------------------------------------// + +/** + * @brief Default dummy for almost all flash chips. If your flash does't need to reconfigure dummy, + * just call this function. + */ +void __attribute__((weak)) spi_flash_hpm_get_dummy_generic(spi_flash_hpm_dummy_conf_t *dummy_conf) +{ + dummy_conf->dio_dummy = SPI_FLASH_DIO_DUMMY_BITLEN; + dummy_conf->dout_dummy = SPI_FLASH_DOUT_DUMMY_BITLEN; + dummy_conf->qio_dummy = SPI_FLASH_QIO_DUMMY_BITLEN; + dummy_conf->qout_dummy = SPI_FLASH_QOUT_DUMMY_BITLEN; + dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN; } diff --git a/components/spi_flash/test_apps/esp_flash_stress/CMakeLists.txt b/components/spi_flash/test_apps/esp_flash_stress/CMakeLists.txt index e557291582..483d14044b 100644 --- a/components/spi_flash/test_apps/esp_flash_stress/CMakeLists.txt +++ b/components/spi_flash/test_apps/esp_flash_stress/CMakeLists.txt @@ -6,3 +6,16 @@ set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/components/spi_flash/test_apps/componen include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(test_esp_flash_stress) + +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-dir ${CMAKE_BINARY_DIR}/esp-idf/driver/ + --elf-file ${CMAKE_BINARY_DIR}/mspi_test.elf + find-refs + --from-sections=.iram0.text + --to-sections=.flash.text,.flash.rodata + --exit-code + DEPENDS ${elf} + ) +endif() diff --git a/components/spi_flash/test_apps/flash_encryption/CMakeLists.txt b/components/spi_flash/test_apps/flash_encryption/CMakeLists.txt index 6f1f017893..debb41982c 100644 --- a/components/spi_flash/test_apps/flash_encryption/CMakeLists.txt +++ b/components/spi_flash/test_apps/flash_encryption/CMakeLists.txt @@ -2,4 +2,9 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(EXTRA_COMPONENT_DIRS + "$ENV{IDF_PATH}/tools/unit-test-app/components" + "$ENV{IDF_PATH}/components/spi_flash/test_apps/components" +) + project(test_flash_encryption) 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 df989b7274..54646b5d4b 100644 --- a/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt +++ b/components/spi_flash/test_apps/flash_encryption/main/CMakeLists.txt @@ -2,5 +2,6 @@ set(srcs "test_app_main.c" "test_flash_encryption.c") idf_component_register(SRCS ${srcs} + PRIV_REQUIRES unity spi_flash bootloader_support esp_partition test_utils test_flash_utils WHOLE_ARCHIVE) target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/spi_flash/test_apps/flash_encryption/main/idf_component.yml b/components/spi_flash/test_apps/flash_encryption/main/idf_component.yml new file mode 100644 index 0000000000..2ae836a935 --- /dev/null +++ b/components/spi_flash/test_apps/flash_encryption/main/idf_component.yml @@ -0,0 +1,2 @@ +dependencies: + ccomp_timer: "^1.0.0" diff --git a/components/spi_flash/test_apps/flash_encryption/main/test_app_main.c b/components/spi_flash/test_apps/flash_encryption/main/test_app_main.c index c8d6ded5bb..e3bcad0ebd 100644 --- a/components/spi_flash/test_apps/flash_encryption/main/test_app_main.c +++ b/components/spi_flash/test_apps/flash_encryption/main/test_app_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,6 +7,8 @@ #include "unity.h" #include "unity_test_runner.h" #include "esp_heap_caps.h" +#include "esp_partition.h" +#include "memory_checks.h" // Some resources are lazy allocated in flash encryption, the threadhold is left for that case #define TEST_MEMORY_LEAK_THRESHOLD (-600) @@ -23,6 +25,12 @@ static void check_leak(size_t before_free, size_t after_free, const char *type) void setUp(void) { + // Calling esp_partition_find_first ensures that the paritions have been loaded + // and subsequent calls to esp_partition_find_first from the tests would not + // load partitions which otherwise gets considered as a memory leak. + esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL); + + test_utils_record_free_mem(); before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT); before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT); } 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 52cb317144..f285f5ddb2 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,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -15,6 +15,10 @@ #include "esp_log.h" #include "esp_partition.h" #include "esp_heap_caps.h" +#include "esp_cpu.h" +#include "test_utils.h" +#include "ccomp_timer.h" +#include "test_flash_utils.h" /*-------------------- For running this test, some configurations are necessary -------------------*/ /* ESP32 | CONFIG_SECURE_FLASH_ENC_ENABLED | SET */ @@ -32,15 +36,6 @@ static void verify_erased_flash(size_t offset, size_t length); static size_t start; -const esp_partition_t *get_test_data_partition(void) -{ - /* This finds "flash_test" partition defined in partition_table_unit_test_app.csv */ - const esp_partition_t *result = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, - ESP_PARTITION_SUBTYPE_ANY, "flash_test"); - TEST_ASSERT_NOT_NULL(result); /* means partition table set wrong */ - return result; -} - static void setup_tests(void) { const esp_partition_t *part = get_test_data_partition(); @@ -260,7 +255,7 @@ TEST_CASE("test read & write encrypted data(32 bytes alianed address)", "[flash_ start = (start + 31) & (~31); // round up to 32 byte boundary ESP_LOG_BUFFER_HEXDUMP(TAG, plainttext_data, sizeof(plainttext_data), ESP_LOG_INFO); - printf("Encrypteed writting......\n"); + printf("Encrypted writing......\n"); TEST_ESP_OK(esp_flash_write_encrypted(NULL, start, plainttext_data, sizeof(plainttext_data))); uint8_t *cmp_encrypt_buf = heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); @@ -292,7 +287,7 @@ TEST_CASE("test read & write encrypted data(16 bytes alianed but 32 bytes unalig printf("Write data partition @ 0x%x\n", start); ESP_LOG_BUFFER_HEXDUMP(TAG, plainttext_data, sizeof(plainttext_data), ESP_LOG_INFO); - printf("Encrypteed writting......\n"); + printf("Encrypted writing......\n"); TEST_ESP_OK(esp_flash_write_encrypted(NULL, start, plainttext_data, sizeof(plainttext_data))); uint8_t *cmp_encrypt_buf = heap_caps_malloc(SPI_FLASH_SEC_SIZE, MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); @@ -329,14 +324,50 @@ TEST_CASE("test read & write encrypted data with large buffer(n*64+32+16)", "[fl // The tested buffer should be n*64(or n*32)+16 bytes. setup_tests(); TEST_ESP_OK(esp_flash_erase_region(NULL, start, 5 * 4096)); - printf("Encrypteed writting......\n"); + printf("Encrypted writing......\n"); + TEST_ESP_OK(ccomp_timer_start()); TEST_ESP_OK(esp_flash_write_encrypted(NULL, start, large_const_buffer, sizeof(large_const_buffer))); - uint8_t *buf = (uint8_t*)heap_caps_malloc(sizeof(large_const_buffer), MALLOC_CAP_32BIT | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + int64_t write_time = ccomp_timer_stop(); + IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time/sizeof(large_const_buffer))*1024); + + uint8_t *buf = (uint8_t*)heap_caps_malloc(sizeof(large_const_buffer), MALLOC_CAP_8BIT); TEST_ESP_OK(esp_flash_read_encrypted(NULL, start, buf, sizeof(large_const_buffer))); TEST_ASSERT_EQUAL_HEX8_ARRAY(buf, large_const_buffer, sizeof(large_const_buffer)); free(buf); } +static DRAM_ATTR const uint8_t large_const_buffer_dram[16432] = { + 203, // first byte + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + [50 ... 99] = 2, + [108 ... 1520] = 0x9b, + [1600 ... 2000] = 0x3d, + [8000 ... 9000] = 0xf7, + [15000 ... 16398] = 0xe8, + 43, 0x7f, + [16401 ... 16430] = 0xd1, + 202, // last byte +}; + +TEST_CASE("test read & write encrypted data with large buffer in ram", "[flash_encryption]") +{ + // The tested buffer should be n*64(or n*32)+16 bytes. + setup_tests(); + TEST_ESP_OK(esp_flash_erase_region(NULL, start, 5 * 4096)); + printf("Encrypted writing......\n"); + + TEST_ESP_OK(ccomp_timer_start()); + TEST_ESP_OK(esp_flash_write_encrypted(NULL, start, large_const_buffer_dram, sizeof(large_const_buffer_dram))); + int64_t write_time = ccomp_timer_stop(); + IDF_LOG_PERFORMANCE(TAG, "Writing speed: %.2f us/KB", (double)(write_time/sizeof(large_const_buffer_dram))*1024); + uint8_t *buf = (uint8_t*)heap_caps_malloc(sizeof(large_const_buffer_dram), MALLOC_CAP_32BIT | MALLOC_CAP_8BIT); + + TEST_ESP_OK(esp_flash_read_encrypted(NULL, start, buf, sizeof(large_const_buffer_dram))); + TEST_ASSERT_EQUAL_HEX8_ARRAY(buf, large_const_buffer_dram, sizeof(large_const_buffer_dram)); + free(buf); +} + #endif // CONFIG_SECURE_FLASH_ENC_ENABLED diff --git a/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py b/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py index d573be4435..572231288d 100644 --- a/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py +++ b/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 - import pytest from pytest_embedded import Dut @@ -19,12 +18,26 @@ def test_flash_encryption(dut: Dut) -> None: dut.run_all_single_board_cases() +@pytest.mark.esp32c3 +@pytest.mark.flash_encryption +@pytest.mark.parametrize( + 'config', + [ + 'rom_impl', + ], + indirect=True, +) +def test_flash_encryption_rom_impl(dut: Dut) -> None: + dut.run_all_single_board_cases() + + @pytest.mark.esp32s3 @pytest.mark.flash_encryption_f4r8 @pytest.mark.parametrize( 'config', [ 'release_f4r8', + 'rom_impl', ], indirect=True, ) diff --git a/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.release_f8r8 b/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.release_f8r8 index 840771961e..b31f5907ca 100644 --- a/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.release_f8r8 +++ b/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.release_f8r8 @@ -16,4 +16,5 @@ CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_TYPE_AUTO=y +CONFIG_ESPTOOLPY_OCT_FLASH=y CONFIG_ESPTOOLPY_FLASHMODE_OPI=y diff --git a/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.rom_impl b/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.rom_impl new file mode 100644 index 0000000000..1fe12679eb --- /dev/null +++ b/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.rom_impl @@ -0,0 +1,5 @@ +CONFIG_ESP_TASK_WDT_EN=n +CONFIG_SPI_FLASH_ROM_IMPL=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/spi_flash/test_apps/flash_mmap/main/test_flash_mmap.c b/components/spi_flash/test_apps/flash_mmap/main/test_flash_mmap.c index 548de17285..9b3de3ae3d 100644 --- a/components/spi_flash/test_apps/flash_mmap/main/test_flash_mmap.c +++ b/components/spi_flash/test_apps/flash_mmap/main/test_flash_mmap.c @@ -101,6 +101,33 @@ static void setup_mmap_tests(void) } } +TEST_CASE("Can get correct data in existing mapped region", "[spi_flash][mmap]") +{ + setup_mmap_tests(); + + printf("Mapping %"PRIx32" (+%"PRIx32")\n", start, end - start); + const void *ptr1; + TEST_ESP_OK( spi_flash_mmap(start, end - start, SPI_FLASH_MMAP_DATA, &ptr1, &handle1) ); + printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle1, ptr1); + + /* Remap in the previously mapped region itself */ + uint32_t new_start = start + CONFIG_MMU_PAGE_SIZE; + printf("Mapping %"PRIx32" (+%"PRIx32")\n", new_start, end - new_start); + const void *ptr2; + TEST_ESP_OK( spi_flash_mmap(new_start, end - new_start, SPI_FLASH_MMAP_DATA, &ptr2, &handle2) ); + printf("mmap_res: handle=%"PRIx32" ptr=%p\n", (uint32_t)handle2, ptr2); + + const void *src1 = (void *) ((uint32_t) ptr1 + CONFIG_MMU_PAGE_SIZE); + const void *src2 = ptr2; + /* Memory contents should be identical - as the region is same */ + TEST_ASSERT_EQUAL(0, memcmp(src1, src2, end - new_start)); + + spi_flash_munmap(handle1); + handle1 = 0; + spi_flash_munmap(handle2); + handle2 = 0; + TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA)); +} TEST_CASE("Can mmap into data address space", "[spi_flash][mmap]") { diff --git a/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special new file mode 100644 index 0000000000..250b5921a6 --- /dev/null +++ b/components/spi_flash/test_apps/mspi_test/sdkconfig.ci.special @@ -0,0 +1,5 @@ +# This config lists merged freertos_flash no_optimization in UT all together. +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n +CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y +CONFIG_COMPILER_OPTIMIZATION_NONE=y +CONFIG_COMPILER_DUMP_RTL_FILES=y diff --git a/components/wpa_supplicant/CMakeLists.txt b/components/wpa_supplicant/CMakeLists.txt index 1a32337d71..3b50a1db44 100644 --- a/components/wpa_supplicant/CMakeLists.txt +++ b/components/wpa_supplicant/CMakeLists.txt @@ -1,3 +1,5 @@ +set(linker_fragments linker.lf) + set(srcs "port/os_xtensa.c" "port/eloop.c" "src/ap/ap_config.c" @@ -61,7 +63,8 @@ set(srcs "port/os_xtensa.c" "src/wps/wps_dev_attr.c" "src/wps/wps_enrollee.c") -set(esp_srcs "esp_supplicant/src/esp_wpa2.c" +set(esp_srcs "esp_supplicant/src/esp_eap_client.c" + "esp_supplicant/src/esp_wpa2_api_port.c" "esp_supplicant/src/esp_wpa_main.c" "esp_supplicant/src/esp_wpas_glue.c" "esp_supplicant/src/esp_common.c" @@ -96,6 +99,7 @@ endif() if(CONFIG_ESP_WIFI_MBEDTLS_CRYPTO) set(crypto_src + "esp_supplicant/src/crypto/fastpbkdf2.c" "esp_supplicant/src/crypto/crypto_mbedtls.c" "esp_supplicant/src/crypto/crypto_mbedtls-bignum.c" "esp_supplicant/src/crypto/crypto_mbedtls-rsa.c" @@ -170,7 +174,7 @@ if(CONFIG_ESP_WIFI_ENABLE_SAE_PK) "src/common/sae_pk.c") endif() -if(CONFIG_ESP_WIFI_11KV_SUPPORT OR CONFIG_ESP_WIFI_11R_SUPPORT OR CONFIG_ESP_WIFI_ENABLE_SAE_PK) +if(CONFIG_ESP_WIFI_11KV_SUPPORT OR CONFIG_ESP_WIFI_11R_SUPPORT) set(srcs ${srcs} "src/common/bss.c" "src/common/scan.c" @@ -209,6 +213,7 @@ idf_component_register(SRCS "${srcs}" "${esp_srcs}" "${tls_src}" "${roaming_src} "${crypto_src}" "${mbo_src}" "${dpp_src}" "${wps_registrar_src}" INCLUDE_DIRS include port/include esp_supplicant/include PRIV_INCLUDE_DIRS src src/utils esp_supplicant/src src/crypto + LDFRAGMENTS ${linker_fragments} PRIV_REQUIRES mbedtls esp_timer esp_wifi) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-strict-aliasing -Wno-write-strings -Werror) @@ -229,6 +234,7 @@ target_compile_definitions(${COMPONENT_LIB} PRIVATE CONFIG_IEEE80211W CONFIG_SHA256 CONFIG_NO_RADIUS + CONFIG_FAST_PBKDF2 ) if(CONFIG_ESP_WIFI_ENABLE_WPA3_SAE) diff --git a/components/wpa_supplicant/COPYING b/components/wpa_supplicant/COPYING index 7efce0dee1..7ca30301e2 100644 --- a/components/wpa_supplicant/COPYING +++ b/components/wpa_supplicant/COPYING @@ -1,7 +1,7 @@ wpa_supplicant and hostapd -------------------------- -Copyright (c) 2002-2016, Jouni Malinen and contributors +Copyright (c) 2002-2022, Jouni Malinen and contributors All Rights Reserved. diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h b/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h index f932c327ff..6bcd846ef3 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h +++ b/components/wpa_supplicant/esp_supplicant/include/esp_dpp.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 */ @@ -15,10 +15,12 @@ extern "C" { #endif +#define ESP_DPP_AUTH_TIMEOUT_SECS 1 + #define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */ #define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */ #define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */ - +#define ESP_ERR_DPP_AUTH_TIMEOUT (ESP_ERR_WIFI_BASE + 154) /*!< DPP Auth response was not recieved in time */ /** @brief Types of Bootstrap Methods for DPP. */ typedef enum dpp_bootstrap_type { DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */ diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_eap_client.h b/components/wpa_supplicant/esp_supplicant/include/esp_eap_client.h new file mode 100644 index 0000000000..1cbfac781e --- /dev/null +++ b/components/wpa_supplicant/esp_supplicant/include/esp_eap_client.h @@ -0,0 +1,326 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enumeration of phase 2 authentication types for EAP-TTLS. + * + * This enumeration defines the supported phase 2 authentication methods + * that can be used in the EAP-TTLS (Extensible Authentication Protocol - + * Tunneled Transport Layer Security) protocol for the second authentication + * phase. + */ +typedef enum { + ESP_EAP_TTLS_PHASE2_EAP, /**< EAP (Extensible Authentication Protocol) */ + ESP_EAP_TTLS_PHASE2_MSCHAPV2, /**< MS-CHAPv2 (Microsoft Challenge Handshake Authentication Protocol - Version 2) */ + ESP_EAP_TTLS_PHASE2_MSCHAP, /**< MS-CHAP (Microsoft Challenge Handshake Authentication Protocol) */ + ESP_EAP_TTLS_PHASE2_PAP, /**< PAP (Password Authentication Protocol) */ + ESP_EAP_TTLS_PHASE2_CHAP /**< CHAP (Challenge Handshake Authentication Protocol) */ +} esp_eap_ttls_phase2_types; + +/** + * @brief Configuration settings for EAP-FAST + * (Extensible Authentication Protocol - Flexible Authentication via Secure Tunneling). + * + * This structure defines the configuration options that can be used to customize the behavior of the + * EAP-FAST authentication protocol, specifically for Fast Provisioning and PAC (Protected Access Credential) handling. + */ +typedef struct { + int fast_provisioning; /**< Enable or disable Fast Provisioning in EAP-FAST (0 = disabled, 1 = enabled) */ + int fast_max_pac_list_len; /**< Maximum length of the PAC (Protected Access Credential) list */ + bool fast_pac_format_binary; /**< Set to true for binary format PAC, false for ASCII format PAC */ +} esp_eap_fast_config; + + +/** + * @brief Enable EAP authentication(WiFi Enterprise) for the station mode. + * + * This function enables Extensible Authentication Protocol (EAP) authentication + * for the Wi-Fi station mode. When EAP authentication is enabled, the ESP device + * will attempt to authenticate with the configured EAP credentials when connecting + * to a secure Wi-Fi network. + * + * @note Before calling this function, ensure that the Wi-Fi configuration and EAP + * credentials (such as username and password) have been properly set using the + * appropriate configuration APIs. + * + * @return + * - ESP_OK: EAP authentication enabled successfully. + * - ESP_ERR_NO_MEM: Failed to enable EAP authentication due to memory allocation failure. + */ +esp_err_t esp_wifi_sta_enterprise_enable(void); + + +/** + * @brief Disable EAP authentication(WiFi Enterprise) for the station mode. + * + * This function disables Extensible Authentication Protocol (EAP) authentication + * for the Wi-Fi station mode. When EAP authentication is disabled, the ESP device + * will not attempt to authenticate using EAP credentials when connecting to a + * secure Wi-Fi network. + * + * @note Disabling EAP authentication may cause the device to connect to the Wi-Fi + * network using other available authentication methods, if configured using esp_wifi_set_config(). + * + * @return + * - ESP_OK: EAP authentication disabled successfully. + * - ESP_ERR_INVALID_STATE: EAP client is in an invalid state for disabling. + */ +esp_err_t esp_wifi_sta_enterprise_disable(void); + +/** + * @brief Set identity for PEAP/TTLS authentication method. + * + * This function sets the identity to be used during PEAP/TTLS authentication. + * + * @param[in] identity Pointer to the identity data. + * @param[in] len Length of the identity data (limited to 1~127 bytes). + * + * @return + * - ESP_OK: The identity was set successfully. + * - ESP_ERR_INVALID_ARG: Invalid argument (len <= 0 or len >= 128). + * - ESP_ERR_NO_MEM: Memory allocation failure. + */ +esp_err_t esp_eap_client_set_identity(const unsigned char *identity, int len); + +/** + * @brief Clear the previously set identity for PEAP/TTLS authentication. + * + * This function clears the identity that was previously set for the EAP client. + * After calling this function, the EAP client will no longer use the previously + * configured identity during the authentication process. + */ +void esp_eap_client_clear_identity(void); + +/** + * @brief Set username for PEAP/TTLS authentication method. + * + * This function sets the username to be used during PEAP/TTLS authentication. + * + * @param[in] username Pointer to the username data. + * @param[in] len Length of the username data (limited to 1~127 bytes). + * + * @return + * - ESP_OK: The username was set successfully. + * - ESP_ERR_INVALID_ARG: Failed due to an invalid argument (len <= 0 or len >= 128). + * - ESP_ERR_NO_MEM: Failed due to memory allocation failure. + */ +esp_err_t esp_eap_client_set_username(const unsigned char *username, int len); + +/** + * @brief Clear username for PEAP/TTLS method. + * + * This function clears the previously set username for the EAP client. + */ +void esp_eap_client_clear_username(void); + +/** + * @brief Set password for PEAP/TTLS authentication method. + * + * This function sets the password to be used during PEAP/TTLS authentication. + * + * @param[in] password Pointer to the password data. + * @param[in] len Length of the password data (len > 0). + * + * @return + * - ESP_OK: The password was set successfully. + * - ESP_ERR_INVALID_ARG: Failed due to an invalid argument (len <= 0). + * - ESP_ERR_NO_MEM: Failed due to memory allocation failure. + */ +esp_err_t esp_eap_client_set_password(const unsigned char *password, int len); + +/** + * @brief Clear password for PEAP/TTLS method. + * + * This function clears the previously set password for the EAP client. + */ +void esp_eap_client_clear_password(void); + +/** + * @brief Set a new password for MSCHAPv2 authentication method. + * + * This function sets the new password to be used during MSCHAPv2 authentication. + * The new password is used to substitute the old password when an eap-mschapv2 failure request + * message with error code ERROR_PASSWD_EXPIRED is received. + * + * @param[in] new_password Pointer to the new password data. + * @param[in] len Length of the new password data. + * + * @return + * - ESP_OK: The new password was set successfully. + * - ESP_ERR_INVALID_ARG: Failed due to an invalid argument (len <= 0). + * - ESP_ERR_NO_MEM: Failed due to memory allocation failure. + */ +esp_err_t esp_eap_client_set_new_password(const unsigned char *new_password, int len); + +/** + * @brief Clear new password for MSCHAPv2 method. + * + * This function clears the previously set new password for the EAP client. + */ +void esp_eap_client_clear_new_password(void); + +/** + * @brief Set CA certificate for EAP authentication. + * + * This function sets the Certificate Authority (CA) certificate to be used during EAP authentication. + * The CA certificate is passed to the EAP client module through a global pointer. + * + * @param[in] ca_cert Pointer to the CA certificate data. + * @param[in] ca_cert_len Length of the CA certificate data. + * + * @return + * - ESP_OK: The CA certificate was set successfully. + */ +esp_err_t esp_eap_client_set_ca_cert(const unsigned char *ca_cert, int ca_cert_len); + +/** + * @brief Clear the previously set Certificate Authority (CA) certificate for EAP authentication. + * + * This function clears the CA certificate that was previously set for the EAP client. + * After calling this function, the EAP client will no longer use the previously + * configured CA certificate during the authentication process. + */ +void esp_eap_client_clear_ca_cert(void); + +/** + * @brief Set client certificate and private key for EAP authentication. + * + * This function sets the client certificate and private key to be used during authentication. + * Optionally, a private key password can be provided for encrypted private keys. + * + * @attention 1. The client certificate, private key, and private key password are provided as pointers + * to the respective data arrays. + * @attention 2. The client_cert, private_key, and private_key_password should be zero-terminated. + * + * @param[in] client_cert Pointer to the client certificate data. + * @param[in] client_cert_len Length of the client certificate data. + * @param[in] private_key Pointer to the private key data. + * @param[in] private_key_len Length of the private key data (limited to 1~4096 bytes). + * @param[in] private_key_password Pointer to the private key password data (optional). + * @param[in] private_key_passwd_len Length of the private key password data (can be 0 for no password). + * + * @return + * - ESP_OK: The certificate, private key, and password (if provided) were set successfully. + */ +esp_err_t esp_eap_client_set_certificate_and_key(const unsigned char *client_cert, int client_cert_len, + const unsigned char *private_key, int private_key_len, + const unsigned char *private_key_password, int private_key_passwd_len); + +/** + * @brief Clear the previously set client certificate and private key for EAP authentication. + * + * This function clears the client certificate and private key that were previously set + * for the EAP client. After calling this function, the EAP client will no longer use the + * previously configured certificate and private key during the authentication process. + */ +void esp_eap_client_clear_certificate_and_key(void); + +/** + * @brief Set EAP client certificates time check (disable or not). + * + * This function enables or disables the time check for EAP client certificates. + * When disabled, the certificates' expiration time will not be checked during the authentication process. + * + * @param[in] disable True to disable EAP client certificates time check, false to enable it. + * + * @return + * - ESP_OK: The EAP client certificates time check setting was updated successfully. + */ +esp_err_t esp_eap_client_set_disable_time_check(bool disable); + +/** + * @brief Get EAP client certificates time check status. + * + * This function retrieves the current status of the EAP client certificates time check. + * + * @param[out] disable Pointer to a boolean variable to store the disable status. + * + * @return + * - ESP_OK: The status of EAP client certificates time check was retrieved successfully. + */ +esp_err_t esp_eap_client_get_disable_time_check(bool *disable); + +/** + * @brief Set EAP-TTLS phase 2 method. + * + * This function sets the phase 2 method to be used during EAP-TTLS authentication. + * + * @param[in] type The type of phase 2 method to be used (e.g., EAP, MSCHAPv2, MSCHAP, PAP, CHAP). + * + * @return + * - ESP_OK: The EAP-TTLS phase 2 method was set successfully. + */ +esp_err_t esp_eap_client_set_ttls_phase2_method(esp_eap_ttls_phase2_types type); + +/** + * @brief Enable or disable Suite-B 192-bit certification checks. + * + * This function enables or disables the 192-bit Suite-B certification checks during EAP-TLS authentication. + * Suite-B is a set of cryptographic algorithms which generally are considered more secure. + * + * @param[in] enable True to enable 192-bit Suite-B certification checks, false to disable it. + * + * @return + * - ESP_OK: The 192-bit Suite-B certification checks were set successfully. + */ +esp_err_t esp_eap_client_set_suiteb_192bit_certification(bool enable); + +/** + * @brief Set the PAC (Protected Access Credential) file for EAP-FAST authentication. + * + * EAP-FAST requires a PAC file that contains the client's credentials. + * + * @attention 1. For files read from the file system, length has to be decremented by 1 byte. + * @attention 2. Disabling the ESP_WIFI_MBEDTLS_TLS_CLIENT config is required to use EAP-FAST. + * + * @param[in] pac_file Pointer to the PAC file buffer. + * @param[in] pac_file_len Length of the PAC file buffer. + * + * @return + * - ESP_OK: The PAC file for EAP-FAST authentication was set successfully. + */ +esp_err_t esp_eap_client_set_pac_file(const unsigned char *pac_file, int pac_file_len); + +/** + * @brief Set the parameters for EAP-FAST Phase 1 authentication. + * + * EAP-FAST supports Fast Provisioning, where clients can be authenticated faster using precomputed keys (PAC). + * This function allows configuring parameters for Fast Provisioning. + * + * @attention 1. Disabling the ESP_WIFI_MBEDTLS_TLS_CLIENT config is required to use EAP-FAST. + * + * @param[in] config Configuration structure with Fast Provisioning parameters. + * + * @return + * - ESP_OK: The parameters for EAP-FAST Phase 1 authentication were set successfully. + */ +esp_err_t esp_eap_client_set_fast_params(esp_eap_fast_config config); + +/** + * @brief Use the default certificate bundle for EAP authentication. + * + * By default, the EAP client uses a built-in certificate bundle for server verification. + * Enabling this option allows the use of the default certificate bundle. + * + * @param[in] use_default_bundle True to use the default certificate bundle, false to use a custom bundle. + * + * @return + * - ESP_OK: The option to use the default certificate bundle was set successfully. + */ +esp_err_t esp_eap_client_use_default_cert_bundle(bool use_default_bundle); + +#ifdef __cplusplus +} +#endif diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_mbo.h b/components/wpa_supplicant/esp_supplicant/include/esp_mbo.h index 4292213943..4319ecc000 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_mbo.h +++ b/components/wpa_supplicant/esp_supplicant/include/esp_mbo.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,39 +13,41 @@ extern "C" { #endif /** - * enum non_pref_chan_reason: Reason for non preference of channel - */ + * @brief Enumeration of reasons for a channel being non-preferred in a wireless network. + * + * This enumeration defines various reasons why a specific channel might be considered non-preferred + * in a wireless network configuration. + */ enum non_pref_chan_reason { - NON_PREF_CHAN_REASON_UNSPECIFIED = 0, - NON_PREF_CHAN_REASON_RSSI = 1, - NON_PREF_CHAN_REASON_EXT_INTERFERENCE = 2, - NON_PREF_CHAN_REASON_INT_INTERFERENCE = 3, + NON_PREF_CHAN_REASON_UNSPECIFIED = 0, /**< Unspecified reason for non-preference */ + NON_PREF_CHAN_REASON_RSSI = 1, /**< Non-preferred due to low RSSI (Received Signal Strength Indication) */ + NON_PREF_CHAN_REASON_EXT_INTERFERENCE = 2, /**< Non-preferred due to external interference */ + NON_PREF_CHAN_REASON_INT_INTERFERENCE = 3, /**< Non-preferred due to internal interference */ }; /** - * @brief Channel structure for non preferred channel - * - * @param reason: enum non_pref_chan_reason - * @param oper_class: operating class for the channel - * @param chan: channel number - * @param preference: channel preference - */ + * @brief Structure representing a non-preferred channel in a wireless network. + * + * This structure encapsulates information about a non-preferred channel + * including the reason for its non-preference, the operating class, channel number, and preference level. + */ struct non_pref_chan { - enum non_pref_chan_reason reason; - uint8_t oper_class; - uint8_t chan; - uint8_t preference; + enum non_pref_chan_reason reason; /**< Reason for the channel being non-preferred */ + uint8_t oper_class; /**< Operating class of the channel */ + uint8_t chan; /**< Channel number */ + uint8_t preference; /**< Preference level of the channel */ }; /** - * @brief Array structure for non preferred channel struct - * - * @param non_pref_chan_num: channel count - * @param chan: array of non_pref_chan type - */ + * @brief Structure representing a list of non-preferred channels in a wireless network. + * + * This structure encapsulates information about a list of non-preferred channels + * including the number of non-preferred channels and an array of structures + * representing individual non-preferred channels. + */ struct non_pref_chan_s { - size_t non_pref_chan_num; - struct non_pref_chan chan[]; + size_t non_pref_chan_num; /**< Number of non-preferred channels in the list */ + struct non_pref_chan chan[]; /**< Array of structures representing individual non-preferred channels */ }; /** diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_wpa.h b/components/wpa_supplicant/esp_supplicant/include/esp_wpa.h index 5e232486c5..fd8e82768e 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_wpa.h +++ b/components/wpa_supplicant/esp_supplicant/include/esp_wpa.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -57,6 +57,22 @@ esp_err_t esp_supplicant_init(void); */ esp_err_t esp_supplicant_deinit(void); +/** + * @brief Disable or enable the caching of Pairwise Master Keys (PMK) in the supplicant. + * + * This function allows disabling or enabling the caching of Pairwise Master Keys (PMK). + * PMK caching is used in Wi-Fi Protected Access (WPA/WPA2/WPA3) networks to speed up the reconnection process + * by storing the PMK generated during the initial connection. Disabling PMK caching may result in slightly + * longer reconnection times. PMK caching is enabled by default, this configuration has been provided + * in case the AP is known not to support PMK caching or has a buggy implementation for PMK caching. + * + * @param disable Boolean indicating whether to disable (true) or enable (false) PMK caching. + * @return + * - ESP_OK: Success + * - An error code if disabling or enabling PMK caching fails. + */ +esp_err_t esp_supplicant_disable_pmk_caching(bool disable); + /** * @} */ diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h b/components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h index d483be8e90..3f3b78934f 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h +++ b/components/wpa_supplicant/esp_supplicant/include/esp_wpa2.h @@ -7,54 +7,47 @@ #ifndef _ESP_WPA2_H #define _ESP_WPA2_H -#include +#pragma message("esp_wpa2.h is deprecated. Use esp_eap_client.h instead.") -#include "esp_err.h" - -typedef enum { - ESP_EAP_TTLS_PHASE2_EAP, - ESP_EAP_TTLS_PHASE2_MSCHAPV2, - ESP_EAP_TTLS_PHASE2_MSCHAP, - ESP_EAP_TTLS_PHASE2_PAP, - ESP_EAP_TTLS_PHASE2_CHAP -} esp_eap_ttls_phase2_types; - -typedef struct { - int fast_provisioning; - int fast_max_pac_list_len; - bool fast_pac_format_binary; -} esp_eap_fast_config; - -#ifdef __cplusplus -extern "C" { -#endif +#include "esp_eap_client.h" /** * @brief Enable wpa2 enterprise authentication. * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_wifi_sta_enterprise_enable()` instead. + * * @attention 1. wpa2 enterprise authentication can only be used when station mode is enabled. - * @attention 2. wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. + * @attention 2. wpa2 enterprise authentication supports EAP-FAST, TLS, PEAP, TTLS(EAP, MSCHAPv2, MSCHAP, PAP, CHAP) methods. * * @return * - ESP_OK: succeed. * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) */ +__attribute__((deprecated("Use 'esp_wifi_sta_enterprise_enable' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_enable(void); /** * @brief Disable wpa2 enterprise authentication. * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_wifi_sta_enterprise_disable()` instead. + * * @attention 1. wpa2 enterprise authentication can only be used when station mode is enabled. - * @attention 2. wpa2 enterprise authentication can only support TLS, PEAP-MSCHAPv2 and TTLS-MSCHAPv2 method. + * @attention 2. wpa2 enterprise authentication supports EAP-FAST, TLS, PEAP, TTLS(EAP, MSCHAPv2, MSCHAP, PAP, CHAP) methods. * * @return * - ESP_OK: succeed. */ +__attribute__((deprecated("Use 'esp_wifi_sta_enterprise_disable' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_disable(void); /** * @brief Set identity for PEAP/TTLS method. * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_identity` instead. + * * @attention The API only passes the parameter identity to the global pointer variable in wpa2 enterprise module. * * @param identity: point to address where stores the identity; @@ -65,17 +58,24 @@ esp_err_t esp_wifi_sta_wpa2_ent_disable(void); * - ESP_ERR_INVALID_ARG: fail(len <= 0 or len >= 128) * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) */ +__attribute__((deprecated("Use 'esp_eap_client_set_identity' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_set_identity(const unsigned char *identity, int len); /** * @brief Clear identity for PEAP/TTLS method. + * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_clear_identity` instead. + * */ +__attribute__((deprecated("Use 'esp_eap_client_clear_identity' instead"))) void esp_wifi_sta_wpa2_ent_clear_identity(void); /** * @brief Set username for PEAP/TTLS method. * - * @attention The API only passes the parameter username to the global pointer variable in wpa2 enterprise module. + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_username` instead. * * @param username: point to address where stores the username; * @param len: length of username, limited to 1~127 @@ -85,17 +85,23 @@ void esp_wifi_sta_wpa2_ent_clear_identity(void); * - ESP_ERR_INVALID_ARG: fail(len <= 0 or len >= 128) * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) */ +__attribute__((deprecated("Use 'esp_eap_client_set_username' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_set_username(const unsigned char *username, int len); /** * @brief Clear username for PEAP/TTLS method. + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_clear_username` instead. + * */ +__attribute__((deprecated("Use 'esp_eap_client_clear_username' instead"))) void esp_wifi_sta_wpa2_ent_clear_username(void); /** * @brief Set password for PEAP/TTLS method.. * - * @attention The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_password` instead. * * @param password: point to address where stores the password; * @param len: length of password(len > 0) @@ -105,18 +111,25 @@ void esp_wifi_sta_wpa2_ent_clear_username(void); * - ESP_ERR_INVALID_ARG: fail(len <= 0) * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) */ +__attribute__((deprecated("Use 'esp_eap_client_set_password' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_set_password(const unsigned char *password, int len); /** * @brief Clear password for PEAP/TTLS method.. + * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_clear_password` instead. */ +__attribute__((deprecated("Use 'esp_eap_client_clear_password' instead"))) void esp_wifi_sta_wpa2_ent_clear_password(void); /** * @brief Set new password for MSCHAPv2 method.. * - * @attention 1. The API only passes the parameter password to the global pointer variable in wpa2 enterprise module. - * @attention 2. The new password is used to substitute the old password when eap-mschapv2 failure request message with error code ERROR_PASSWD_EXPIRED is received. + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_new_password` instead. + * + * @attention 1. The new password is used to substitute the old password when eap-mschapv2 failure request message with error code ERROR_PASSWD_EXPIRED is received. * * @param new_password: point to address where stores the password; * @param len: length of password @@ -126,17 +139,25 @@ void esp_wifi_sta_wpa2_ent_clear_password(void); * - ESP_ERR_INVALID_ARG: fail(len <= 0) * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) */ - +__attribute__((deprecated("Use 'esp_eap_client_set_new_password' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_set_new_password(const unsigned char *new_password, int len); /** * @brief Clear new password for MSCHAPv2 method.. + * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_clear_new_password` instead. + * */ +__attribute__((deprecated("Use 'esp_eap_client_clear_new_password' instead"))) void esp_wifi_sta_wpa2_ent_clear_new_password(void); /** * @brief Set CA certificate for PEAP/TTLS method. * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_ca_cert` instead. + * * @attention 1. The API only passes the parameter ca_cert to the global pointer variable in wpa2 enterprise module. * @attention 2. The ca_cert should be zero terminated. * @@ -146,16 +167,25 @@ void esp_wifi_sta_wpa2_ent_clear_new_password(void); * @return * - ESP_OK: succeed */ +__attribute__((deprecated("Use 'esp_eap_client_set_ca_cert' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_set_ca_cert(const unsigned char *ca_cert, int ca_cert_len); /** * @brief Clear CA certificate for PEAP/TTLS method. + * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_clear_ca_cert` instead. + * */ +__attribute__((deprecated("Use 'esp_eap_client_clear_ca_cert' instead"))) void esp_wifi_sta_wpa2_ent_clear_ca_cert(void); /** * @brief Set client certificate and key. * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_certificate_and_key` instead. + * * @attention 1. The API only passes the parameter client_cert, private_key and private_key_passwd to the global pointer variable in wpa2 enterprise module. * @attention 2. The client_cert, private_key and private_key_passwd should be zero terminated. * @@ -169,57 +199,84 @@ void esp_wifi_sta_wpa2_ent_clear_ca_cert(void); * @return * - ESP_OK: succeed */ -esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, int client_cert_len, const unsigned char *private_key, int private_key_len, const unsigned char *private_key_passwd, int private_key_passwd_len); +__attribute__((deprecated("Use 'esp_eap_client_set_certificate_and_key' instead"))) +esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, int client_cert_len, + const unsigned char *private_key, int private_key_len, + const unsigned char *private_key_passwd, int private_key_passwd_len); /** * @brief Clear client certificate and key. + * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_clear_certificate_and_key` instead. + * */ +__attribute__((deprecated("Use 'esp_eap_client_clear_certificate_and_key' instead"))) void esp_wifi_sta_wpa2_ent_clear_cert_key(void); /** * @brief Set wpa2 enterprise certs time check(disable or not). * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_disable_time_check` instead. + * * @param true: disable wpa2 enterprise certs time check * @param false: enable wpa2 enterprise certs time check * * @return * - ESP_OK: succeed */ +__attribute__((deprecated("Use 'esp_eap_client_set_disable_time_check' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable); /** * @brief Get wpa2 enterprise certs time check(disable or not). * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_get_disable_time_check` instead. + * * @param disable: store disable value * * @return * - ESP_OK: succeed */ +__attribute__((deprecated("Use 'esp_eap_client_get_disable_time_check' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable); /** * @brief Set wpa2 enterprise ttls phase2 method * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_ttls_phase2_method` instead. + * * @param type: the type of phase 2 method to be used * * @return * - ESP_OK: succeed */ +__attribute__((deprecated("Use 'esp_eap_client_set_ttls_phase2_method' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types type); /** * @brief enable/disable 192 bit suite b certification checks * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_suiteb_192bit_certification` instead. + * * @param enable: bool to enable/disable it. * * @return * - ESP_OK: succeed */ +__attribute__((deprecated("Use 'esp_eap_client_set_suiteb_192bit_certification' instead"))) esp_err_t esp_wifi_sta_wpa2_set_suiteb_192bit_certification(bool enable); /** * @brief Set client pac file * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_pac_file` instead. + * * @attention 1. For files read from the file system, length has to be decremented by 1 byte. * @attention 2. Disabling the ESP_WIFI_MBEDTLS_TLS_CLIENT config is required to use EAP-FAST. * @@ -230,11 +287,15 @@ esp_err_t esp_wifi_sta_wpa2_set_suiteb_192bit_certification(bool enable); * - ESP_OK: succeed * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) */ +__attribute__((deprecated("Use 'esp_eap_client_set_pac_file' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_set_pac_file(const unsigned char *pac_file, int pac_file_len); /** * @brief Set Phase 1 parameters for EAP-FAST * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_set_fast_params` instead. + * * @attention 1. Disabling the ESP_WIFI_MBEDTLS_TLS_CLIENT config is required to use EAP-FAST. * * @param config: eap fast phase 1 configuration @@ -244,17 +305,22 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_pac_file(const unsigned char *pac_file, int * - ESP_ERR_INVALID_ARG: fail(out of bound arguments) * - ESP_ERR_NO_MEM: fail(internal memory malloc fail) */ +__attribute__((deprecated("Use 'esp_eap_client_set_fast_params' instead"))) esp_err_t esp_wifi_sta_wpa2_ent_set_fast_phase1_params(esp_eap_fast_config config); /** * @brief Use default CA cert bundle for server validation * + * @deprecated This function is deprecated and will be removed in the future. + * Please use `esp_eap_client_use_default_cert_bundle` instead. + * * @use_default_bundle : whether to use bundle or not * * @return * - ESP_OK: succeed * - ESP_FAIL: fail */ +__attribute__((deprecated("Use 'esp_eap_client_use_default_cert_bundle' instead"))) esp_err_t esp_wifi_sta_wpa2_use_default_cert_bundle(bool use_default_bundle); #ifdef __cplusplus diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_wps.h b/components/wpa_supplicant/esp_supplicant/include/esp_wps.h index c9d60ecb8d..148bc81da7 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_wps.h +++ b/components/wpa_supplicant/esp_supplicant/include/esp_wps.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 */ @@ -33,32 +33,60 @@ extern "C" { #define ESP_ERR_WIFI_WPS_TYPE (ESP_ERR_WIFI_BASE + 52) /*!< WPS type error */ #define ESP_ERR_WIFI_WPS_SM (ESP_ERR_WIFI_BASE + 53) /*!< WPS state machine is not initialized */ +/** + * @brief Enumeration of WPS (Wi-Fi Protected Setup) types. + */ typedef enum wps_type { - WPS_TYPE_DISABLE = 0, - WPS_TYPE_PBC, - WPS_TYPE_PIN, - WPS_TYPE_MAX, + WPS_TYPE_DISABLE = 0, /**< WPS is disabled */ + WPS_TYPE_PBC, /**< WPS Push Button Configuration method */ + WPS_TYPE_PIN, /**< WPS PIN (Personal Identification Number) method */ + WPS_TYPE_MAX /**< Maximum value for WPS type enumeration */ } wps_type_t; -#define WPS_MAX_MANUFACTURER_LEN 65 -#define WPS_MAX_MODEL_NUMBER_LEN 33 -#define WPS_MAX_MODEL_NAME_LEN 33 -#define WPS_MAX_DEVICE_NAME_LEN 33 +#define WPS_MAX_MANUFACTURER_LEN 65 /**< Maximum length of the manufacturer name in WPS information */ +#define WPS_MAX_MODEL_NUMBER_LEN 33 /**< Maximum length of the model number in WPS information */ +#define WPS_MAX_MODEL_NAME_LEN 33 /**< Maximum length of the model name in WPS information */ +#define WPS_MAX_DEVICE_NAME_LEN 33 /**< Maximum length of the device name in WPS information */ +/** + * @brief Structure representing WPS factory information for ESP device. + * + * This structure holds various strings representing factory information for a device, such as the manufacturer, + * model number, model name, and device name. Each string is a null-terminated character array. If any of the + * strings are empty, the default values are used. + */ typedef struct { - char manufacturer[WPS_MAX_MANUFACTURER_LEN]; /*!< Manufacturer, null-terminated string. The default manufcturer is used if the string is empty */ - char model_number[WPS_MAX_MODEL_NUMBER_LEN]; /*!< Model number, null-terminated string. The default model number is used if the string is empty */ - char model_name[WPS_MAX_MODEL_NAME_LEN]; /*!< Model name, null-terminated string. The default model name is used if the string is empty */ - char device_name[WPS_MAX_DEVICE_NAME_LEN]; /*!< Device name, null-terminated string. The default device name is used if the string is empty */ + char manufacturer[WPS_MAX_MANUFACTURER_LEN]; /*!< Manufacturer of the device. If empty, the default manufacturer is used. */ + char model_number[WPS_MAX_MODEL_NUMBER_LEN]; /*!< Model number of the device. If empty, the default model number is used. */ + char model_name[WPS_MAX_MODEL_NAME_LEN]; /*!< Model name of the device. If empty, the default model name is used. */ + char device_name[WPS_MAX_DEVICE_NAME_LEN]; /*!< Device name. If empty, the default device name is used. */ } wps_factory_information_t; -#define PIN_LEN 9 +#define PIN_LEN 9 /*!< The length of the WPS PIN (Personal Identification Number). */ +/** + * @brief Structure representing configuration settings for WPS (Wi-Fi Protected Setup). + * + * This structure encapsulates various configuration settings for WPS, including the WPS type (PBC or PIN), + * factory information that will be shown in the WPS Information Element (IE), and a PIN if the WPS type is + * set to PIN. + */ typedef struct { - wps_type_t wps_type; - wps_factory_information_t factory_info; - char pin[PIN_LEN]; + wps_type_t wps_type; /*!< The type of WPS to be used (PBC or PIN). */ + wps_factory_information_t factory_info; /*!< Factory information to be shown in the WPS Information Element (IE). Vendor can choose to display their own information. */ + char pin[PIN_LEN]; /*!< WPS PIN (Personal Identification Number) used when wps_type is set to WPS_TYPE_PIN. */ } esp_wps_config_t; +/** + * @def WPS_CONFIG_INIT_DEFAULT(type) + * @brief Initialize a default WPS configuration structure with specified WPS type. + * + * This macro initializes a `esp_wps_config_t` structure with default values for the specified WPS type. + * It sets the WPS type, factory information (including default manufacturer, model number, model name, and device name), + * and a default PIN value if applicable. + * + * @param type The WPS type to be used (PBC or PIN). + * @return An initialized `esp_wps_config_t` structure with the specified WPS type and default values. + */ #define WPS_CONFIG_INIT_DEFAULT(type) { \ .wps_type = type, \ .factory_info = { \ @@ -73,9 +101,7 @@ typedef struct { /** * @brief Enable Wi-Fi WPS function. * - * @attention WPS can only be used when station is enabled. - * - * @param wps_type_t wps_type : WPS type, so far only WPS_TYPE_PBC and WPS_TYPE_PIN is supported + * @param config : WPS config to be used in connection * * @return * - ESP_OK : succeed @@ -88,8 +114,6 @@ esp_err_t esp_wifi_wps_enable(const esp_wps_config_t *config); /** * @brief Disable Wi-Fi WPS function and release resource it taken. * - * @param null - * * @return * - ESP_OK : succeed * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on @@ -97,9 +121,9 @@ esp_err_t esp_wifi_wps_enable(const esp_wps_config_t *config); esp_err_t esp_wifi_wps_disable(void); /** - * @brief WPS starts to work. + * @brief Start WPS session. * - * @attention WPS can only be used when station is enabled. + * @attention WPS can only be used when station is enabled. WPS needs to be enabled first for using this API. * * @param timeout_ms : deprecated: This argument's value will have not effect in functionality of API. * The argument will be removed in future. @@ -120,7 +144,7 @@ esp_err_t esp_wifi_wps_start(int timeout_ms); * * @attention WPS can only be used when softAP is enabled. * - * @param esp_wps_config_t config: wps configuration to be used. + * @param config: wps configuration to be used. * * @return * - ESP_OK : succeed @@ -133,8 +157,6 @@ esp_err_t esp_wifi_ap_wps_enable(const esp_wps_config_t *config); /** * @brief Disable Wi-Fi SoftAP WPS function and release resource it taken. * - * @param null - * * @return * - ESP_OK : succeed * - ESP_ERR_WIFI_WPS_MODE : wifi is not in station mode or sniffer mode is on diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c index c5f38fa793..b69a68288c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,8 @@ #include "mbedtls/error.h" #include "mbedtls/oid.h" -#define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES +#define ECP_PRV_DER_MAX_BYTES ( 29 + 3 * MBEDTLS_ECP_MAX_BYTES ) +#define ECP_PUB_DER_MAX_BYTES ( 30 + 2 * MBEDTLS_ECP_MAX_BYTES ) #ifdef CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT #define ACCESS_ECDH(S, var) S->MBEDTLS_PRIVATE(var) @@ -518,6 +519,7 @@ struct crypto_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *gro struct crypto_key *pkey = NULL; int ret; mbedtls_pk_context *key = (mbedtls_pk_context *)crypto_alloc_key(); + mbedtls_ecp_group *ecp_grp = (mbedtls_ecp_group *)group; if (!key) { wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__); @@ -538,7 +540,7 @@ struct crypto_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *gro goto fail; } - if (mbedtls_ecp_check_pubkey((mbedtls_ecp_group *)group, point) < 0) { //typecast + if (mbedtls_ecp_check_pubkey(ecp_grp, point) < 0) { // ideally should have failed in upper condition, duplicate code?? wpa_printf(MSG_ERROR, "Invalid key"); goto fail; @@ -547,8 +549,9 @@ struct crypto_key * crypto_ec_set_pubkey_point(const struct crypto_ec_group *gro if( ( ret = mbedtls_pk_setup( key, mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY) ) ) != 0 ) goto fail; + mbedtls_ecp_copy(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(Q), point); - mbedtls_ecp_group_load(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1); + mbedtls_ecp_group_load(&mbedtls_pk_ec(*key)->MBEDTLS_PRIVATE(grp), ecp_grp->id); pkey = (struct crypto_key *)key; crypto_ec_point_deinit((struct crypto_ec_point *)point, 0); @@ -581,19 +584,27 @@ struct crypto_ec_point *crypto_ec_get_public_key(struct crypto_key *key) int crypto_ec_get_priv_key_der(struct crypto_key *key, unsigned char **key_data, int *key_len) { mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; - char der_data[ECP_PRV_DER_MAX_BYTES]; + char *der_data = os_malloc(ECP_PRV_DER_MAX_BYTES); + if (!der_data) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + return -1; + } *key_len = mbedtls_pk_write_key_der(pkey, (unsigned char *)der_data, ECP_PRV_DER_MAX_BYTES); - if (*key_len <= 0) + if (*key_len <= 0) { + wpa_printf(MSG_ERROR, "Failed to write priv key"); + os_free(der_data); return -1; - + } *key_data = os_malloc(*key_len); if (!*key_data) { wpa_printf(MSG_ERROR, "memory allocation failed"); + os_free(der_data); return -1; } - os_memcpy(*key_data, der_data, *key_len); + os_memcpy(*key_data, der_data + ECP_PRV_DER_MAX_BYTES - *key_len, *key_len); + os_free(der_data); return 0; } @@ -643,16 +654,25 @@ int crypto_ec_get_publickey_buf(struct crypto_key *key, u8 *key_buf, int len) int crypto_write_pubkey_der(struct crypto_key *key, unsigned char **key_buf) { - unsigned char output_buf[1600] = {0}; - int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, output_buf, 1600); - if (len <= 0) - return 0; + unsigned char *buf = os_malloc(ECP_PUB_DER_MAX_BYTES); + + if(!buf) { + wpa_printf(MSG_ERROR, "memory allocation failed"); + return -1; + } + int len = mbedtls_pk_write_pubkey_der((mbedtls_pk_context *)key, buf, ECP_PUB_DER_MAX_BYTES); + if (len <= 0) { + os_free(buf); + return -1; + } *key_buf = os_malloc(len); if (!*key_buf) { - return 0; + os_free(buf); + return -1; } - os_memcpy(*key_buf, output_buf + 1600 - len, len); + os_memcpy(*key_buf, buf + ECP_PUB_DER_MAX_BYTES - len, len); + os_free(buf); return len; } @@ -812,28 +832,21 @@ int crypto_ecdsa_get_sign(unsigned char *hash, int crypto_edcsa_sign_verify(const unsigned char *hash, const struct crypto_bignum *r, const struct crypto_bignum *s, struct crypto_key *csign, int hlen) { - mbedtls_pk_context *pkey = (mbedtls_pk_context *)csign; - int ret = 0; - - mbedtls_ecdsa_context *ctx = os_malloc(sizeof(*ctx)); - if (!ctx) { - wpa_printf(MSG_ERROR, "failed to allcate memory"); - return ret; + /* (mbedtls_ecdsa_context *) */ + mbedtls_ecp_keypair *ecp_kp = mbedtls_pk_ec(*(mbedtls_pk_context *)csign); + if (!ecp_kp) { + return -1; } - mbedtls_ecdsa_init(ctx); - - if (mbedtls_ecdsa_from_keypair(ctx, mbedtls_pk_ec(*pkey)) < 0) - return ret; - if((ret = mbedtls_ecdsa_verify(&ctx->MBEDTLS_PRIVATE(grp), hash, hlen, - &ctx->MBEDTLS_PRIVATE(Q), (mbedtls_mpi *)r, (mbedtls_mpi *)s)) != 0){ + mbedtls_ecp_group *ecp_kp_grp = &ecp_kp->MBEDTLS_PRIVATE(grp); + mbedtls_ecp_point *ecp_kp_q = &ecp_kp->MBEDTLS_PRIVATE(Q); + int ret = mbedtls_ecdsa_verify(ecp_kp_grp, hash, hlen, + ecp_kp_q, (mbedtls_mpi *)r, (mbedtls_mpi *)s); + if (ret != 0) { wpa_printf(MSG_ERROR, "ecdsa verification failed"); return ret; } - mbedtls_ecdsa_free(ctx); - os_free(ctx); - return ret; } @@ -861,14 +874,18 @@ struct crypto_key *crypto_ec_parse_subpub_key(const unsigned char *p, size_t len { int ret; mbedtls_pk_context *pkey = (mbedtls_pk_context *)crypto_alloc_key(); - ret = mbedtls_pk_parse_subpubkey((unsigned char **)&p, p + len, pkey); - if (ret < 0) { - os_free(pkey); + if (!pkey) { return NULL; } + ret = mbedtls_pk_parse_subpubkey((unsigned char **)&p, p + len, pkey); + if (ret == 0) { + return (struct crypto_key *)pkey; + } - return (struct crypto_key *)pkey; + mbedtls_pk_free(pkey); + os_free(pkey); + return NULL; } int crypto_is_ec_key(struct crypto_key *key) 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 88dd222ed8..cfc5ec064e 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,6 +46,10 @@ #endif #endif +#ifdef CONFIG_FAST_PBKDF2 +#include "fastpbkdf2.h" +#endif + static int digest_vector(mbedtls_md_type_t md_type, size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) { @@ -512,16 +516,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; } @@ -755,9 +762,14 @@ int crypto_mod_exp(const uint8_t *base, size_t base_len, int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, int iterations, u8 *buf, size_t buflen) { +#ifdef CONFIG_FAST_PBKDF2 + fastpbkdf2_hmac_sha1((const u8 *) passphrase, os_strlen(passphrase), + ssid, ssid_len, iterations, buf, buflen); + return 0; +#else int ret = mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, (const u8 *) passphrase, os_strlen(passphrase) , ssid, - ssid_len, iterations, 32, buf); + ssid_len, iterations, buflen, buf); if (ret != 0) { ret = -1; goto cleanup; @@ -765,6 +777,7 @@ int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, cleanup: return ret; +#endif } #ifdef MBEDTLS_DES_C diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c new file mode 100644 index 0000000000..24fc706c63 --- /dev/null +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.c @@ -0,0 +1,388 @@ +/* + * SPDX-FileCopyrightText: 2015 Joseph Birr-Pixton + * + * SPDX-License-Identifier: CC0-1.0 + */ + +/* + * fast-pbkdf2 - Optimal PBKDF2-HMAC calculation + * Written in 2015 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ +#include "utils/common.h" +#include "fastpbkdf2.h" + +#include +#include +#if defined(__GNUC__) +#include +#endif + +#include +#include "mbedtls/esp_config.h" +#include "utils/wpa_debug.h" + +/* --- MSVC doesn't support C99 --- */ +#ifdef _MSC_VER +#define restrict +#define _Pragma __pragma +#endif + +/* --- Common useful things --- */ +#ifndef MIN +#define MIN(a, b) ((a) > (b)) ? (b) : (a) +#endif + +static inline void write32_be(uint32_t n, uint8_t out[4]) +{ +#if defined(__GNUC__) && __GNUC__ >= 4 && __BYTE_ORDER == __LITTLE_ENDIAN + *(uint32_t *)(out) = __builtin_bswap32(n); +#else + out[0] = (n >> 24) & 0xff; + out[1] = (n >> 16) & 0xff; + out[2] = (n >> 8) & 0xff; + out[3] = n & 0xff; +#endif +} + +/* Prepare block (of blocksz bytes) to contain md padding denoting a msg-size + * message (in bytes). block has a prefix of used bytes. + * + * Message length is expressed in 32 bits (so suitable for sha1, sha256, sha512). */ +static inline void md_pad(uint8_t *block, size_t blocksz, size_t used, size_t msg) +{ + memset(block + used, 0, blocksz - used - 4); + block[used] = 0x80; + block += blocksz - 4; + write32_be((uint32_t) (msg * 8), block); +} + +/* Internal function/type names for hash-specific things. */ +#define HMAC_CTX(_name) HMAC_ ## _name ## _ctx +#define HMAC_INIT(_name) HMAC_ ## _name ## _init +#define HMAC_UPDATE(_name) HMAC_ ## _name ## _update +#define HMAC_FINAL(_name) HMAC_ ## _name ## _final + +#define PBKDF2_F(_name) pbkdf2_f_ ## _name +#define PBKDF2(_name) pbkdf2_ ## _name + +/* This macro expands to decls for the whole implementation for a given + * hash function. Arguments are: + * + * _name like 'sha1', added to symbol names + * _blocksz block size, in bytes + * _hashsz digest output, in bytes + * _ctx hash context type + * _init hash context initialisation function + * args: (_ctx *c) + * _update hash context update function + * args: (_ctx *c, const void *data, size_t ndata) + * _final hash context finish function + * args: (_ctx *c, void *out) + * _xform hash context raw block update function + * args: (_ctx *c, const void *data) + * _xcpy hash context raw copy function (only need copy hash state) + * args: (_ctx * restrict out, const _ctx *restrict in) + * _xtract hash context state extraction + * args: args (_ctx *restrict c, uint8_t *restrict out) + * _xxor hash context xor function (only need xor hash state) + * args: (_ctx *restrict out, const _ctx *restrict in) + * + * The resulting function is named PBKDF2(_name). + */ +#define DECL_PBKDF2(_name, _blocksz, _hashsz, _ctx, \ + _init, _update, _xform, _final, _xcpy, _xtract, _xxor) \ + typedef struct { \ + _ctx inner; \ + _ctx outer; \ + } HMAC_CTX(_name); \ + \ + static inline void HMAC_INIT(_name)(HMAC_CTX(_name) *ctx, \ + const uint8_t *key, size_t nkey) \ + { \ + /* Prepare key: */ \ + uint8_t k[_blocksz]; \ + \ + /* Shorten long keys. */ \ + if (nkey > _blocksz) \ + { \ + _init(&ctx->inner); \ + _update(&ctx->inner, key, nkey); \ + _final(&ctx->inner, k); \ + \ + key = k; \ + nkey = _hashsz; \ + } \ + \ + /* Standard doesn't cover case where blocksz < hashsz. */ \ + assert(nkey <= _blocksz); \ + \ + /* Right zero-pad short keys. */ \ + if (k != key) \ + memcpy(k, key, nkey); \ + if (_blocksz > nkey) \ + memset(k + nkey, 0, _blocksz - nkey); \ + \ + /* Start inner hash computation */ \ + uint8_t blk_inner[_blocksz]; \ + uint8_t blk_outer[_blocksz]; \ + \ + for (size_t i = 0; i < _blocksz; i++) \ + { \ + blk_inner[i] = 0x36 ^ k[i]; \ + blk_outer[i] = 0x5c ^ k[i]; \ + } \ + \ + _init(&ctx->inner); \ + _update(&ctx->inner, blk_inner, sizeof blk_inner); \ + \ + /* And outer. */ \ + _init(&ctx->outer); \ + _update(&ctx->outer, blk_outer, sizeof blk_outer); \ + } \ + \ + static inline void HMAC_UPDATE(_name)(HMAC_CTX(_name) *ctx, \ + const void *data, size_t ndata) \ + { \ + _update(&ctx->inner, data, ndata); \ + } \ + \ + static inline void HMAC_FINAL(_name)(HMAC_CTX(_name) *ctx, \ + uint8_t out[_hashsz]) \ + { \ + _final(&ctx->inner, out); \ + _update(&ctx->outer, out, _hashsz); \ + _final(&ctx->outer, out); \ + } \ + \ + \ + /* --- PBKDF2 --- */ \ + static inline void PBKDF2_F(_name)(const HMAC_CTX(_name) *startctx, \ + uint32_t counter, \ + const uint8_t *salt, size_t nsalt, \ + uint32_t iterations, \ + uint8_t *out) \ + { \ + uint8_t countbuf[4]; \ + write32_be(counter, countbuf); \ + \ + /* Prepare loop-invariant padding block. */ \ + uint8_t Ublock[_blocksz]; \ + md_pad(Ublock, _blocksz, _hashsz, _blocksz + _hashsz); \ + \ + /* First iteration: \ + * U_1 = PRF(P, S || INT_32_BE(i)) \ + */ \ + HMAC_CTX(_name) ctx = *startctx; \ + HMAC_UPDATE(_name)(&ctx, salt, nsalt); \ + HMAC_UPDATE(_name)(&ctx, countbuf, sizeof countbuf); \ + HMAC_FINAL(_name)(&ctx, Ublock); \ + _ctx result = ctx.outer; \ + \ + /* Subsequent iterations: \ + * U_c = PRF(P, U_{c-1}) \ + */ \ + for (uint32_t i = 1; i < iterations; i++) \ + { \ + /* Complete inner hash with previous U */ \ + _xcpy(&ctx.inner, &startctx->inner); \ + _xform(&ctx.inner, Ublock); \ + _xtract(&ctx.inner, Ublock); \ + /* Complete outer hash with inner output */ \ + _xcpy(&ctx.outer, &startctx->outer); \ + _xform(&ctx.outer, Ublock); \ + _xtract(&ctx.outer, Ublock); \ + _xxor(&result, &ctx.outer); \ + } \ + \ + /* Reform result into output buffer. */ \ + _xtract(&result, out); \ + } \ + \ + static inline void PBKDF2(_name)(const uint8_t *pw, size_t npw, \ + const uint8_t *salt, size_t nsalt, \ + uint32_t iterations, \ + uint8_t *out, size_t nout) \ + { \ + assert(iterations); \ + assert(out && nout); \ + \ + /* Starting point for inner loop. */ \ + HMAC_CTX(_name) ctx; \ + HMAC_INIT(_name)(&ctx, pw, npw); \ + \ + /* How many blocks do we need? */ \ + uint32_t blocks_needed = (uint32_t)(nout + _hashsz - 1) / _hashsz; \ + \ + for (uint32_t counter = 1; counter <= blocks_needed; counter++) \ + { \ + uint8_t block[_hashsz]; \ + PBKDF2_F(_name)(&ctx, counter, salt, nsalt, iterations, block); \ + \ + size_t offset = (counter - 1) * _hashsz; \ + size_t taken = MIN(nout - offset, _hashsz); \ + memcpy(out + offset, block, taken); \ + } \ + } + +static inline void sha1_extract(mbedtls_sha1_context *restrict ctx, uint8_t *restrict out) +{ +#if defined(MBEDTLS_SHA1_ALT) +#if CONFIG_IDF_TARGET_ESP32 + /* ESP32 stores internal SHA state in BE format similar to software */ + write32_be(ctx->state[0], out); + write32_be(ctx->state[1], out + 4); + write32_be(ctx->state[2], out + 8); + write32_be(ctx->state[3], out + 12); + write32_be(ctx->state[4], out + 16); +#else + *(uint32_t *)(out) = ctx->state[0]; + *(uint32_t *)(out + 4) = ctx->state[1]; + *(uint32_t *)(out + 8) = ctx->state[2]; + *(uint32_t *)(out + 12) = ctx->state[3]; + *(uint32_t *)(out + 16) = ctx->state[4]; +#endif +#else + write32_be(ctx->MBEDTLS_PRIVATE(state)[0], out); + write32_be(ctx->MBEDTLS_PRIVATE(state)[1], out + 4); + write32_be(ctx->MBEDTLS_PRIVATE(state)[2], out + 8); + write32_be(ctx->MBEDTLS_PRIVATE(state)[3], out + 12); + write32_be(ctx->MBEDTLS_PRIVATE(state)[4], out + 16); +#endif +} + +static inline void sha1_cpy(mbedtls_sha1_context *restrict out, const mbedtls_sha1_context *restrict in) +{ +#if defined(MBEDTLS_SHA1_ALT) + out->state[0] = in->state[0]; + out->state[1] = in->state[1]; + out->state[2] = in->state[2]; + out->state[3] = in->state[3]; + out->state[4] = in->state[4]; +#else + out->MBEDTLS_PRIVATE(state)[0] = in->MBEDTLS_PRIVATE(state)[0]; + out->MBEDTLS_PRIVATE(state)[1] = in->MBEDTLS_PRIVATE(state)[1]; + out->MBEDTLS_PRIVATE(state)[2] = in->MBEDTLS_PRIVATE(state)[2]; + out->MBEDTLS_PRIVATE(state)[3] = in->MBEDTLS_PRIVATE(state)[3]; + out->MBEDTLS_PRIVATE(state)[4] = in->MBEDTLS_PRIVATE(state)[4]; +#endif +} + +static inline void sha1_xor(mbedtls_sha1_context *restrict out, const mbedtls_sha1_context *restrict in) +{ +#if defined(MBEDTLS_SHA1_ALT) + out->state[0] ^= in->state[0]; + out->state[1] ^= in->state[1]; + out->state[2] ^= in->state[2]; + out->state[3] ^= in->state[3]; + out->state[4] ^= in->state[4]; +#else + out->MBEDTLS_PRIVATE(state)[0] ^= in->MBEDTLS_PRIVATE(state)[0]; + out->MBEDTLS_PRIVATE(state)[1] ^= in->MBEDTLS_PRIVATE(state)[1]; + out->MBEDTLS_PRIVATE(state)[2] ^= in->MBEDTLS_PRIVATE(state)[2]; + out->MBEDTLS_PRIVATE(state)[3] ^= in->MBEDTLS_PRIVATE(state)[3]; + out->MBEDTLS_PRIVATE(state)[4] ^= in->MBEDTLS_PRIVATE(state)[4]; +#endif +} + +static int mbedtls_sha1_init_start(mbedtls_sha1_context *ctx) +{ + mbedtls_sha1_init(ctx); + mbedtls_sha1_starts(ctx); +#if defined(CONFIG_IDF_TARGET_ESP32) && defined(MBEDTLS_SHA1_ALT) + /* Use software mode for esp32 since hardware can't give output more than 20 */ + esp_mbedtls_set_sha1_mode(ctx, ESP_MBEDTLS_SHA1_SOFTWARE); +#endif + 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 + mbedtls_sha1_context, // _ctx + 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 + +void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, + const uint8_t *salt, size_t nsalt, + uint32_t iterations, + uint8_t *out, size_t nout) +{ + PBKDF2(sha1)(pw, npw, salt, nsalt, iterations, out, nout); +} diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.h b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.h new file mode 100644 index 0000000000..60838942dd --- /dev/null +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/fastpbkdf2.h @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: 2015 Joseph Birr-Pixton + * + * SPDX-License-Identifier: CC0-1.0 + */ + +/* + * fastpbkdf2 - Faster PBKDF2-HMAC calculation + * Written in 2015 by Joseph Birr-Pixton + * + * To the extent possible under law, the author(s) have dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication + * along with this software. If not, see + * . + */ + +#ifndef FASTPBKDF2_H +#define FASTPBKDF2_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Calculates PBKDF2-HMAC-SHA1. + * + * @p npw bytes at @p pw are the password input. + * @p nsalt bytes at @p salt are the salt input. + * @p iterations is the PBKDF2 iteration count and must be non-zero. + * @p nout bytes of output are written to @p out. @p nout must be non-zero. + * + * This function cannot fail; it does not report errors. + */ +void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, + const uint8_t *salt, size_t nsalt, + uint32_t iterations, + uint8_t *out, size_t nout); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c index d3d1af4070..9fdac04823 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,6 +40,7 @@ #endif /* CONFIG_MBEDTLS_CFG_FILE */ #endif #endif +#include "mbedtls/platform.h" #include "eap_peer/eap.h" @@ -682,6 +683,59 @@ int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn, return -1; } +#ifdef CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER +static void esp_mbedtls_free_dhm(mbedtls_ssl_context *ssl) +{ +#ifdef CONFIG_MBEDTLS_DHM_C + const mbedtls_ssl_config *conf = mbedtls_ssl_context_get_config(ssl); + mbedtls_mpi_free((mbedtls_mpi *)&conf->MBEDTLS_PRIVATE(dhm_P)); + mbedtls_mpi_free((mbedtls_mpi *)&conf->MBEDTLS_PRIVATE(dhm_G)); +#endif /* CONFIG_MBEDTLS_DHM_C */ +} + +static void esp_mbedtls_free_keycert(mbedtls_ssl_context *ssl) +{ + mbedtls_ssl_config *conf = (mbedtls_ssl_config * )mbedtls_ssl_context_get_config(ssl); + mbedtls_ssl_key_cert *keycert = conf->MBEDTLS_PRIVATE(key_cert), *next; + + while (keycert) { + next = keycert->next; + + if (keycert) { + mbedtls_free(keycert); + } + + keycert = next; + } + + conf->MBEDTLS_PRIVATE(key_cert) = NULL; +} + +static void esp_mbedtls_free_keycert_key(mbedtls_ssl_context *ssl) +{ + const mbedtls_ssl_config *conf = mbedtls_ssl_context_get_config(ssl); + mbedtls_ssl_key_cert *keycert = conf->MBEDTLS_PRIVATE(key_cert); + + while (keycert) { + if (keycert->key) { + mbedtls_pk_free(keycert->key); + keycert->key = NULL; + } + keycert = keycert->next; + } +} + +static void esp_mbedtls_free_cacert(mbedtls_ssl_context *ssl) +{ + if (ssl->MBEDTLS_PRIVATE(conf)->MBEDTLS_PRIVATE(ca_chain)) { + mbedtls_ssl_config *conf = (mbedtls_ssl_config * )mbedtls_ssl_context_get_config(ssl); + + mbedtls_x509_crt_free(conf->MBEDTLS_PRIVATE(ca_chain)); + conf->MBEDTLS_PRIVATE(ca_chain) = NULL; + } +} +#endif + struct wpabuf * tls_connection_handshake(void *tls_ctx, struct tls_connection *conn, const struct wpabuf *in_data, @@ -690,6 +744,7 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx, tls_context_t *tls = conn->tls; int ret = 0; struct wpabuf *resp; + int cli_state; /* data freed by sender */ conn->tls_io_data.out_data = NULL; @@ -699,7 +754,8 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx, /* Multiple reads */ while (!mbedtls_ssl_is_handshake_over(&tls->ssl)) { - if (tls->ssl.MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_CLIENT_CERTIFICATE) { + cli_state = tls->ssl.MBEDTLS_PRIVATE(state); + if (cli_state == MBEDTLS_SSL_CLIENT_CERTIFICATE) { /* Read random data before session completes, not present after handshake */ if (tls->ssl.MBEDTLS_PRIVATE(handshake)) { os_memcpy(conn->randbytes, tls->ssl.MBEDTLS_PRIVATE(handshake)->randbytes, @@ -709,8 +765,20 @@ struct wpabuf * tls_connection_handshake(void *tls_ctx, } ret = mbedtls_ssl_handshake_step(&tls->ssl); - if (ret < 0) + if (ret < 0) { break; + } +#ifdef CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER + if (mbedtls_ssl_get_version_number(&tls->ssl) == MBEDTLS_SSL_VERSION_TLS1_2) { + if (cli_state == MBEDTLS_SSL_SERVER_CERTIFICATE) { + esp_mbedtls_free_cacert(&tls->ssl); + } else if (cli_state == MBEDTLS_SSL_CERTIFICATE_VERIFY) { + esp_mbedtls_free_dhm(&tls->ssl); + esp_mbedtls_free_keycert_key(&tls->ssl); + esp_mbedtls_free_keycert(&tls->ssl); + } + } +#endif } if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ) { wpa_printf(MSG_INFO, "%s: ret is %d line:%d", __func__, ret, __LINE__); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common.c b/components/wpa_supplicant/esp_supplicant/src/esp_common.c index 12adbad686..0c74341c57 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,6 +22,7 @@ #include "esp_wnm.h" #include "rsn_supp/wpa_i.h" #include "rsn_supp/wpa.h" +#include "esp_private/wifi.h" /* Utility Functions */ esp_err_t esp_supplicant_str_to_mac(const char *str, uint8_t dest[6]) @@ -46,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); @@ -72,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 */ @@ -88,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]; @@ -214,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) { @@ -229,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) { @@ -245,18 +246,26 @@ static int handle_assoc_frame(u8 *frame, size_t len, #endif /* CONFIG_IEEE80211R */ #endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */ +void esp_supplicant_unset_all_appie(void) +{ + uint8_t appie; + for (appie = WIFI_APPIE_PROBEREQ; appie < WIFI_APPIE_RAM_MAX; appie++) { + esp_wifi_unset_appie_internal(appie); + } +} + 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; switch (type) { -#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211KV) || defined(CONFIG_SAE_PK) +#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211KV) case WLAN_FC_STYPE_BEACON: case WLAN_FC_STYPE_PROBE_RESP: ret = esp_handle_beacon_probe(type, frame, len, sender, rssi, channel, current_tsf); break; -#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_SAE_PK)*/ +#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */ #ifdef CONFIG_IEEE80211R case WLAN_FC_STYPE_AUTH: ret = handle_auth_frame(frame, len, sender, rssi, channel); @@ -319,7 +328,7 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb) struct wpa_supplicant *wpa_s = &g_wpa_supp; int ret = 0; -#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_SAE_PK) +#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) #ifdef CONFIG_SUPPLICANT_TASK if (!s_supplicant_api_lock) { s_supplicant_api_lock = os_recursive_mutex_create(); @@ -352,7 +361,7 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb) #endif /* CONFIG_IEEE80211KV */ esp_scan_init(wpa_s); -#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_SAE_PK)*/ +#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */ wpa_s->type = 0; wpa_s->subtype = 0; wpa_s->type |= (1 << WLAN_FC_STYPE_ASSOC_RESP) | (1 << WLAN_FC_STYPE_REASSOC_RESP) | (1 << WLAN_FC_STYPE_AUTH); @@ -377,13 +386,13 @@ void esp_supplicant_common_deinit(void) { struct wpa_supplicant *wpa_s = &g_wpa_supp; -#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_SAE_PK) +#if defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) esp_scan_deinit(wpa_s); #ifdef CONFIG_IEEE80211KV wpas_rrm_reset(wpa_s); wpas_clear_beacon_rep_data(wpa_s); #endif /* CONFIG_IEEE80211KV */ -#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) || defined(CONFIG_SAE_PK)*/ +#endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */ if (wpa_s->type) { wpa_s->type = 0; esp_wifi_register_mgmt_frame_internal(wpa_s->type, wpa_s->subtype); @@ -529,12 +538,14 @@ int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason, return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason, btm_candidates, cand_list); } +#ifdef CONFIG_MBO int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan) { int ret = wpas_mbo_update_non_pref_chan(&g_wpa_supp, non_pref_chan); return ret; } +#endif /* CONFIG_MBO */ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, char *ssid) @@ -644,6 +655,8 @@ static uint8_t get_extended_caps_ie(uint8_t *ie, size_t len) uint8_t ext_caps_ie[5] = {0}; uint8_t ext_caps_ie_len = 3; uint8_t *pos = ext_caps_ie; + wifi_ioctl_config_t cfg = {0}; + esp_err_t err = 0; if (!esp_wifi_is_btm_enabled_internal(WIFI_IF_STA)) { return 0; @@ -651,8 +664,14 @@ static uint8_t get_extended_caps_ie(uint8_t *ie, size_t len) *pos++ = WLAN_EID_EXT_CAPAB; *pos++ = ext_caps_ie_len; - *pos++ = 0; - *pos++ = 0; + + err = esp_wifi_internal_ioctl(WIFI_IOCTL_GET_STA_HT2040_COEX, &cfg); + if (err == ESP_OK && cfg.data.ht2040_coex.enable) { + *pos++ |= BIT(WLAN_EXT_CAPAB_20_40_COEX); + } else { + *pos++ = 0; + } + *pos ++ = 0; #define CAPAB_BSS_TRANSITION BIT(3) *pos |= CAPAB_BSS_TRANSITION; #undef CAPAB_BSS_TRANSITION @@ -778,7 +797,7 @@ int wpa_drv_send_action(struct wpa_supplicant *wpa_s, } req->ifx = WIFI_IF_STA; - req->subtype = WLAN_FC_STYPE_ACTION; + req->subtype = (WLAN_FC_STYPE_ACTION << 4); req->data_len = data_len; os_memcpy(req->data, data, req->data_len); @@ -841,10 +860,6 @@ int esp_wnm_send_bss_transition_mgmt_query(enum btm_query_reason query_reason, return -1; } -int esp_mbo_update_non_pref_chan(struct non_pref_chan_s *non_pref_chan) -{ - return -1; -} void esp_set_scan_ie(void) { } #endif /* defined(CONFIG_IEEE80211KV) || defined(CONFIG_IEEE80211R) */ @@ -864,9 +879,6 @@ void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool mdie) } pos = ie; #ifdef CONFIG_IEEE80211KV - ie_len = get_extended_caps_ie(pos, len); - pos += ie_len; - len -= ie_len; ie_len = get_rm_enabled_ie(pos, len); pos += ie_len; len -= ie_len; 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 c738dba671..e6c1d23290 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]; }; @@ -42,6 +42,7 @@ bool mbo_bss_profile_match(u8 *bssid); #endif int esp_supplicant_common_init(struct wpa_funcs *wpa_cb); void esp_supplicant_common_deinit(void); +void esp_supplicant_unset_all_appie(void); void esp_set_scan_ie(void); void esp_set_assoc_ie(uint8_t *bssid, const u8 *ies, size_t ies_len, bool add_mdie); void supplicant_sta_conn_handler(uint8_t* bssid); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index bd43dbdb45..08e6934c5c 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "utils/includes.h" #include "utils/common.h" +#include "utils/eloop.h" #include "common/defs.h" #include "esp_dpp_i.h" @@ -14,15 +15,15 @@ #include "esp_event.h" #include "esp_wifi.h" #include "common/ieee802_11_defs.h" +#include "esp_wps_i.h" #ifdef CONFIG_DPP static void *s_dpp_task_hdl = NULL; static void *s_dpp_evt_queue = NULL; static void *s_dpp_api_lock = NULL; -static bool s_dpp_stop_listening; -static int s_dpp_auth_retries; -struct esp_dpp_context_t s_dpp_ctx; +static bool s_dpp_listen_in_progress; +static struct esp_dpp_context_t s_dpp_ctx; static wifi_action_rx_cb_t s_action_rx_cb = esp_supp_rx_action; #define DPP_API_LOCK() os_mutex_lock(s_dpp_api_lock) @@ -36,6 +37,7 @@ struct action_rx_param { struct ieee80211_action *action_frm; }; + static int esp_dpp_post_evt(uint32_t evt_id, uint32_t data) { dpp_event_t *evt = os_zalloc(sizeof(dpp_event_t)); @@ -61,26 +63,51 @@ static int esp_dpp_post_evt(uint32_t evt_id, uint32_t data) if (evt_id != SIG_DPP_DEL_TASK) { DPP_API_UNLOCK(); } + wpa_printf(MSG_DEBUG,"DPP: Sent event %d to DPP task", evt_id); return ret; end: if (evt) { os_free(evt); } + wpa_printf(MSG_ERROR,"DPP: Failed to send event %d to DPP task", evt_id); return ret; } +static uint8_t esp_dpp_deinit_auth(void) +{ + esp_err_t ret = esp_dpp_post_evt(SIG_DPP_DEINIT_AUTH, 0); + if (ESP_OK != ret) { + wpa_printf(MSG_ERROR, "Failed to post DPP auth deinit to DPP Task(status=%d)", ret); + return ret; + } + return ESP_OK; +} + static void esp_dpp_call_cb(esp_supp_dpp_event_t evt, void *data) { + if ( evt == ESP_SUPP_DPP_FAIL && s_dpp_ctx.dpp_auth) { + esp_dpp_deinit_auth(); + } s_dpp_ctx.dpp_event_cb(evt, data); } -void esp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len, - uint8_t channel, uint32_t wait_time_ms) +static void esp_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx) +{ + if (!s_dpp_ctx.dpp_auth || !s_dpp_ctx.dpp_auth->waiting_auth_conf) + return; + + wpa_printf(MSG_DEBUG, + "DPP: Terminate authentication exchange due to Auth Confirm timeout"); + esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_AUTH_TIMEOUT); +} + +static esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len, + uint8_t channel, uint32_t wait_time_ms) { wifi_action_tx_req_t *req = os_zalloc(sizeof(*req) + len);; if (!req) { - return; + return ESP_FAIL;; } req->ifx = WIFI_IF_STA; @@ -95,13 +122,15 @@ void esp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len, if (ESP_OK != esp_wifi_action_tx_req(WIFI_OFFCHAN_TX_REQ, channel, wait_time_ms, req)) { - wpa_printf(MSG_ERROR, "DPP: Failed to perfrm offchannel operation"); + wpa_printf(MSG_ERROR, "DPP: Failed to perform offchannel operation"); esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE); os_free(req); - return; + return ESP_FAIL;; } os_free(req); + + return ESP_OK; } static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_data) @@ -140,15 +169,20 @@ static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_d rc = ESP_ERR_DPP_INVALID_ATTR; goto fail; } - + if (s_dpp_ctx.dpp_auth) { + wpa_printf(MSG_DEBUG, "DPP: Already in DPP authentication exchange - ignore new one"); + return; + } s_dpp_ctx.dpp_auth = dpp_auth_req_rx(NULL, DPP_CAPAB_ENROLLEE, 0, NULL, own_bi, rx_param->channel, (const u8 *)&rx_param->action_frm->u.public_action.v, dpp_data, len); os_memcpy(s_dpp_ctx.dpp_auth->peer_mac_addr, rx_param->sa, ETH_ALEN); - - esp_send_action_frame(rx_param->sa, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg), + esp_dpp_send_action_frame(rx_param->sa, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg), wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg), rx_param->channel, OFFCHAN_TX_WAIT_TIME); + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL,NULL); + eloop_register_timeout(ESP_DPP_AUTH_TIMEOUT_SECS, 0, esp_dpp_auth_conf_wait_timeout,NULL, NULL); + return; fail: esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)rc); @@ -170,7 +204,7 @@ static void gas_query_req_tx(struct dpp_authentication *auth) wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (chan %u)", MAC2STR(auth->peer_mac_addr), auth->curr_chan); - esp_send_action_frame(auth->peer_mac_addr, wpabuf_head(buf), wpabuf_len(buf), + esp_dpp_send_action_frame(auth->peer_mac_addr, wpabuf_head(buf), wpabuf_len(buf), auth->curr_chan, OFFCHAN_TX_WAIT_TIME); } @@ -179,6 +213,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); } @@ -201,8 +236,9 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth, wpa_printf(MSG_INFO, DPP_EVENT_CONNECTOR "%s", conf->connector); } - s_dpp_stop_listening = false; - esp_wifi_action_tx_req(WIFI_OFFCHAN_TX_CANCEL, 0, 0, NULL); + if (s_dpp_listen_in_progress) { + esp_supp_dpp_stop_listen(); + } esp_dpp_call_cb(ESP_SUPP_DPP_CFG_RECVD, wifi_cfg); return 0; @@ -232,6 +268,8 @@ static void esp_dpp_rx_auth_conf(struct action_rx_param *rx_param, uint8_t *dpp_ goto fail; } + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + if (dpp_auth_conf_rx(auth, (const u8 *)&public_action->v, dpp_data, len) < 0) { wpa_printf(MSG_DEBUG, "DPP: Authentication failed"); @@ -281,7 +319,7 @@ static void gas_query_resp_rx(struct action_rx_param *rx_param) int i, res; if (pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 && - WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1) { + WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth) { if (dpp_conf_resp_rx(auth, resp, rx_param->vendor_data_len - 2) < 0) { wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed"); goto fail; @@ -317,7 +355,7 @@ static void esp_dpp_rx_action(struct action_rx_param *rx_param) (size_t)(public_action->v.pa_vendor_spec.vendor_data - (u8 *)rx_param->action_frm); - if (!s_dpp_stop_listening) { + if (s_dpp_listen_in_progress) { esp_supp_dpp_stop_listen(); } @@ -354,6 +392,21 @@ static void esp_dpp_task(void *pvParameters ) switch (evt->id) { case SIG_DPP_DEL_TASK: + struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + if (params->info) { + os_free(params->info); + params->info = NULL; + } + + if (s_dpp_ctx.dpp_global) { + dpp_global_deinit(s_dpp_ctx.dpp_global); + s_dpp_ctx.dpp_global = NULL; + } + if (s_dpp_ctx.dpp_auth) { + dpp_auth_deinit(s_dpp_ctx.dpp_auth); + s_dpp_ctx.dpp_auth = NULL; + } task_del = true; break; @@ -378,10 +431,29 @@ static void esp_dpp_task(void *pvParameters ) struct dpp_bootstrap_params_t *p = &s_dpp_ctx.bootstrap_params; static int counter; int channel; + esp_err_t ret = 0; + if (p->num_chan <= 0) { + wpa_printf(MSG_ERROR, "Listen channel not set"); + break; + } channel = p->chan_list[counter++ % p->num_chan]; - esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel, + ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel, BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb); + if (ret != ESP_OK) { + wpa_printf(MSG_ERROR, "Failed ROC. error : 0x%x", ret); + break; + } + s_dpp_listen_in_progress = true; + } + break; + + case SIG_DPP_DEINIT_AUTH: { + if (s_dpp_ctx.dpp_auth) { + dpp_auth_deinit(s_dpp_ctx.dpp_auth); + s_dpp_ctx.dpp_auth = NULL; + } + wpa_printf(MSG_DEBUG, "DPP auth deinintialized"); } break; @@ -454,13 +526,17 @@ static void offchan_event_handler(void *arg, esp_event_base_t event_base, evt->status, (uint32_t)evt->context); if (evt->status) { + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + if (s_dpp_listen_in_progress) { + esp_supp_dpp_stop_listen(); + } esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE); } } else if (event_id == WIFI_EVENT_ROC_DONE) { wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data; - if (!s_dpp_stop_listening && evt->context == (uint32_t)s_action_rx_cb) { + if (s_dpp_listen_in_progress && evt->context == (uint32_t)s_action_rx_cb) { esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0); } } @@ -518,6 +594,10 @@ esp_err_t esp_supp_dpp_bootstrap_gen(const char *chan_list, enum dpp_bootstrap_type type, const char *key, const char *uri_info) { + if (!s_dpp_ctx.dpp_global) { + wpa_printf(MSG_ERROR, "DPP: failed to bootstrap as dpp not initialized."); + return ESP_FAIL; + } struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; char *uri_chan_list = esp_dpp_parse_chan_list(chan_list); char *command = os_zalloc(1200); @@ -581,47 +661,87 @@ esp_supp_dpp_bootstrap_gen(const char *chan_list, enum dpp_bootstrap_type type, esp_err_t esp_supp_dpp_start_listen(void) { + if (s_dpp_listen_in_progress) { + wpa_printf(MSG_ERROR, "DPP: Failed to start listen as listen is already in progress."); + return ESP_FAIL; + } + + if (!s_dpp_ctx.dpp_global || s_dpp_ctx.id < 1) { + wpa_printf(MSG_ERROR, "DPP: failed to start listen as dpp not initialized or bootstrapped."); + return ESP_FAIL; + } + if (esp_wifi_get_user_init_flag_internal() == 0) { wpa_printf(MSG_ERROR, "DPP: ROC not possible before wifi is started"); return ESP_ERR_INVALID_STATE; } - s_dpp_stop_listening = false; return esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0); } void esp_supp_dpp_stop_listen(void) { - s_dpp_stop_listening = true; + s_dpp_listen_in_progress = false; esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_CANCEL, 0, 0, NULL); } +bool is_dpp_enabled(void) +{ + return (s_dpp_ctx.dpp_global ? true : false); +} + esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb) { - struct dpp_global_config cfg = {0}; - int ret; + esp_err_t ret = ESP_OK; + wifi_mode_t mode = 0; + if (esp_wifi_get_mode(&mode) || ((mode != WIFI_MODE_STA) && (mode != WIFI_MODE_APSTA))) { + wpa_printf(MSG_ERROR, "DPP: failed to init as not in station mode."); + return ESP_FAIL; + } - os_bzero(&s_dpp_ctx, sizeof(s_dpp_ctx)); - s_dpp_ctx.dpp_event_cb = cb; + if (is_wps_enabled()) { + wpa_printf(MSG_ERROR, "DPP: failed to init since WPS is enabled"); + return ESP_FAIL; + } + if (s_dpp_ctx.dpp_global) { + wpa_printf(MSG_ERROR, "DPP: failed to init as init already done."); + return ESP_FAIL; + } + os_bzero(&s_dpp_ctx, sizeof(s_dpp_ctx)); + struct dpp_global_config cfg = {0}; cfg.cb_ctx = &s_dpp_ctx; cfg.msg_ctx = &s_dpp_ctx; s_dpp_ctx.dpp_global = dpp_global_init(&cfg); + if (!s_dpp_ctx.dpp_global) { + wpa_printf(MSG_ERROR, "DPP: failed to allocate memory for dpp_global"); + ret = ESP_ERR_NO_MEM; + goto init_fail; + } + + s_dpp_api_lock = os_recursive_mutex_create(); + if (!s_dpp_api_lock) { + wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API lock"); + ret = ESP_ERR_NO_MEM; + goto init_fail; + } - s_dpp_stop_listening = false; s_dpp_evt_queue = os_queue_create(3, sizeof(dpp_event_t)); + if (!s_dpp_evt_queue) { + wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API queue"); + ret = ESP_ERR_NO_MEM; + goto init_fail; + } + ret = os_task_create(esp_dpp_task, "dppT", DPP_TASK_STACK_SIZE, NULL, 2, &s_dpp_task_hdl); if (ret != TRUE) { wpa_printf(MSG_ERROR, "DPP: failed to create task"); - return ESP_FAIL; + ret = ESP_ERR_NO_MEM; + goto init_fail; } - s_dpp_api_lock = os_recursive_mutex_create(); - if (!s_dpp_api_lock) { - esp_supp_dpp_deinit(); - wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API lock"); - return ESP_ERR_NO_MEM; - } + s_dpp_listen_in_progress = false; + s_dpp_ctx.dpp_event_cb = cb; esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, &offchan_event_handler, NULL); @@ -631,23 +751,32 @@ esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb) wpa_printf(MSG_INFO, "esp_dpp_task prio:%d, stack:%d", 2, DPP_TASK_STACK_SIZE); return ESP_OK; +init_fail: + if (s_dpp_ctx.dpp_global) { + dpp_global_deinit(s_dpp_ctx.dpp_global); + s_dpp_ctx.dpp_global = NULL; + } + if (s_dpp_api_lock) { + os_mutex_delete(s_dpp_api_lock); + s_dpp_api_lock = NULL; + } + if (s_dpp_evt_queue) { + os_queue_delete(s_dpp_evt_queue); + s_dpp_evt_queue = NULL; + } + return ret; } - void esp_supp_dpp_deinit(void) { - struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; - - if (params->info) { - os_free(params->info); - params->info = NULL; - } esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, &offchan_event_handler); esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, &offchan_event_handler); - s_dpp_auth_retries = 0; - dpp_global_deinit(s_dpp_ctx.dpp_global); - esp_dpp_post_evt(SIG_DPP_DEL_TASK, 0); + if (s_dpp_ctx.dpp_global) { + if (esp_dpp_post_evt(SIG_DPP_DEL_TASK, 0)) { + wpa_printf(MSG_ERROR, "DPP Deinit Failed"); + } + } } #endif diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h index 3646d1866c..1208eba63a 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp_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 */ @@ -23,6 +23,7 @@ enum SIG_DPP { SIG_DPP_RX_ACTION, SIG_DPP_LISTEN_NEXT_CHANNEL, SIG_DPP_DEL_TASK, + SIG_DPP_DEINIT_AUTH, SIG_DPP_MAX, }; @@ -55,4 +56,12 @@ struct esp_dpp_context_t { int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel); +#ifdef CONFIG_ESP_WIFI_DPP_SUPPORT +bool is_dpp_enabled(void); +#else +static inline bool is_dpp_enabled(void) +{ + return false; +} +#endif #endif /* ESP_DPP_I_H */ diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c similarity index 86% rename from components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c rename to components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c index 290c4fa6cc..12701161de 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa2.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -36,6 +36,8 @@ #include "esp_crt_bundle.h" #endif #include "esp_wpas_glue.h" +#include "esp_eap_client_i.h" +#include "esp_eap_client.h" #define WPA2_VERSION "v2.0" @@ -63,6 +65,7 @@ static int wpa2_start_eapol_internal(void); int wpa2_post(uint32_t sig, uint32_t par); #ifdef USE_WPA2_TASK +#define WPA2_TASK_PRIORITY 7 static void *s_wpa2_task_hdl = NULL; static void *s_wpa2_queue = NULL; static wpa2_state_t s_wpa2_state = WPA2_STATE_DISABLED; @@ -75,7 +78,7 @@ static void wpa2_api_lock(void) if (s_wpa2_api_lock == NULL) { s_wpa2_api_lock = os_recursive_mutex_create(); if (!s_wpa2_api_lock) { - wpa_printf(MSG_ERROR, "WPA2: failed to create wpa2 api lock"); + wpa_printf(MSG_ERROR, "EAP: failed to create EAP api lock"); return; } } @@ -115,20 +118,29 @@ static void wpa2_set_eap_state(wpa2_ent_eap_state_t state) esp_wifi_set_wpa2_ent_state_internal(state); } +wpa2_ent_eap_state_t eap_client_get_eap_state(void) +{ + if (!gEapSm) { + return WPA2_ENT_EAP_STATE_NOT_START; + } + + return gEapSm->finish_state; +} + static inline void wpa2_task_delete(void *arg) { void *my_task_hdl = os_task_get_current_task(); int ret = ESP_OK; if (my_task_hdl == s_wpa2_task_hdl) { - wpa_printf(MSG_ERROR, "WPA2: should never call task delete api in wpa2 task context"); + wpa_printf(MSG_ERROR, "EAP: should never call task delete api in eap task context"); return; } ret = wpa2_post(SIG_WPA2_TASK_DEL, 0); if (ESP_OK != ret) { - wpa_printf(MSG_ERROR, "WPA2: failed to post task delete event, ret=%d", ret); + wpa_printf(MSG_ERROR, "EAP: failed to post task delete event, ret=%d", ret); return; } } @@ -230,23 +242,23 @@ void wpa2_task(void *pvParameters ) break; } else { if (s_wifi_wpa2_sync_sem) { - wpa_printf(MSG_DEBUG, "WPA2: wifi->wpa2 api completed sig(%" PRId32 ")", e->sig); + wpa_printf(MSG_DEBUG, "EAP: wifi->EAP api completed sig(%" PRId32 ")", e->sig); os_semphr_give(s_wifi_wpa2_sync_sem); } else { - wpa_printf(MSG_ERROR, "WPA2: null wifi->wpa2 sync sem"); + wpa_printf(MSG_ERROR, "EAP: null wifi->EAP sync sem"); } } } - wpa_printf(MSG_DEBUG, "WPA2: queue deleted"); + wpa_printf(MSG_DEBUG, "EAP: queue deleted"); os_queue_delete(s_wpa2_queue); - wpa_printf(MSG_DEBUG, "WPA2: task deleted"); + wpa_printf(MSG_DEBUG, "EAP: task deleted"); s_wpa2_queue = NULL; if (s_wifi_wpa2_sync_sem) { - wpa_printf(MSG_DEBUG, "WPA2: wifi->wpa2 api completed sig(%" PRId32 ")", e->sig); + wpa_printf(MSG_DEBUG, "EAP: wifi->EAP api completed sig(%" PRId32 ")", e->sig); os_semphr_give(s_wifi_wpa2_sync_sem); } else { - wpa_printf(MSG_ERROR, "WPA2: null wifi->wpa2 sync sem"); + wpa_printf(MSG_ERROR, "EAP: null wifi->EAP sync sem"); } /* At this point, we completed */ @@ -268,7 +280,7 @@ int wpa2_post(uint32_t sig, uint32_t par) } else { ETSEvent *evt = (ETSEvent *)os_malloc(sizeof(ETSEvent)); if (evt == NULL) { - wpa_printf(MSG_ERROR, "WPA2: E N M"); + wpa_printf(MSG_ERROR, "EAP: E N M"); DATA_MUTEX_GIVE(); return ESP_FAIL; } @@ -277,14 +289,14 @@ int wpa2_post(uint32_t sig, uint32_t par) evt->sig = sig; evt->par = par; if (os_queue_send(s_wpa2_queue, &evt, os_task_ms_to_tick(10)) != TRUE) { - wpa_printf(MSG_ERROR, "WPA2: Q S E"); + wpa_printf(MSG_ERROR, "EAP: Q S E"); return ESP_FAIL; } else { if (s_wifi_wpa2_sync_sem) { os_semphr_take(s_wifi_wpa2_sync_sem, OS_BLOCK); - wpa_printf(MSG_DEBUG, "WPA2: wpa2 api return, sm->state(%d)", sm->finish_state); + wpa_printf(MSG_DEBUG, "EAP: EAP api return, sm->state(%d)", sm->finish_state); } else { - wpa_printf(MSG_ERROR, "WPA2: null wifi->wpa2 sync sem"); + wpa_printf(MSG_ERROR, "EAP: null wifi->EAP sync sem"); } } } @@ -541,20 +553,20 @@ static int eap_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len, uint8_t *bss /* TODO: backwards compatibility */ } if (hdr->type != IEEE802_1X_TYPE_EAP_PACKET) { - wpa_printf(MSG_DEBUG, "WPA2: EAP frame (type %u) discarded, " + wpa_printf(MSG_DEBUG, "EAP: EAP frame (type %u) discarded, " "not a EAP PACKET frame", hdr->type); ret = -2; goto _out; } if (plen > len - sizeof(*hdr) || plen < sizeof(*ehdr)) { - wpa_printf(MSG_DEBUG, "WPA2: EAPOL frame payload size %lu " + wpa_printf(MSG_DEBUG, "EAP: EAPOL frame payload size %lu " "invalid (frame size %lu)", (unsigned long) plen, (unsigned long) len); ret = -2; goto _out; } - wpa_hexdump(MSG_MSGDUMP, "WPA2: RX EAPOL-EAP PACKET", tmp, len); + wpa_hexdump(MSG_MSGDUMP, "EAP: RX EAPOL-EAP PACKET", tmp, len); if (data_len < len) { wpa_printf(MSG_DEBUG, "WPA: ignoring %lu bytes after the IEEE " @@ -566,7 +578,7 @@ static int eap_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len, uint8_t *bss case EAP_CODE_REQUEST: /* Handle EAP-reauthentication case */ if (sm->finish_state == WPA2_ENT_EAP_STATE_SUCCESS) { - wpa_printf(MSG_INFO, ">>>>>wpa2 EAP Re-authentication in progress"); + wpa_printf(MSG_INFO, "EAP Re-authentication in progress"); wpa2_set_eap_state(WPA2_ENT_EAP_STATE_IN_PROGRESS); } @@ -581,18 +593,18 @@ static int eap_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len, uint8_t *bss wpa_set_pmk(sm->eapKeyData, NULL, false); os_free(sm->eapKeyData); sm->eapKeyData = NULL; - wpa_printf(MSG_INFO, ">>>>>wpa2 FINISH"); + wpa_printf(MSG_INFO, ">>>>>EAP FINISH"); ret = WPA2_ENT_EAP_STATE_SUCCESS; wpa2_set_eap_state(WPA2_ENT_EAP_STATE_SUCCESS); eap_deinit_prev_method(sm, "EAP Success"); } else { - wpa_printf(MSG_INFO, ">>>>>wpa2 FAILED, receive EAP_SUCCESS but pmk is empty, potential attack!"); + wpa_printf(MSG_INFO, ">>>>>EAP FAILED, receive EAP_SUCCESS but pmk is empty, potential attack!"); ret = WPA2_ENT_EAP_STATE_FAIL; wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL); } break; case EAP_CODE_FAILURE: - wpa_printf(MSG_INFO, ">>>>>wpa2 FAILED"); + wpa_printf(MSG_INFO, ">>>>>EAP FAILED"); ret = WPA2_ENT_EAP_STATE_FAIL; wpa2_set_eap_state(WPA2_ENT_EAP_STATE_FAIL); break; @@ -667,7 +679,7 @@ static int eap_peer_sm_init(void) struct eap_sm *sm; if (gEapSm) { - wpa_printf(MSG_ERROR, "WPA2: wpa2 sm not null, deinit it"); + wpa_printf(MSG_ERROR, "EAP: EAP sm not null, deinit it"); eap_peer_sm_deinit(); } @@ -680,7 +692,7 @@ static int eap_peer_sm_init(void) gEapSm = sm; s_wpa2_data_lock = os_recursive_mutex_create(); if (!s_wpa2_data_lock) { - wpa_printf(MSG_ERROR, "wpa2 eap_peer_sm_init: failed to alloc data lock"); + wpa_printf(MSG_ERROR, "EAP eap_peer_sm_init: failed to alloc data lock"); ret = ESP_ERR_NO_MEM; goto _err; } @@ -714,7 +726,7 @@ static int eap_peer_sm_init(void) gEapSm = sm; #ifdef USE_WPA2_TASK s_wpa2_queue = os_queue_create(SIG_WPA2_MAX, sizeof(s_wpa2_queue)); - ret = os_task_create(wpa2_task, "wpa2T", WPA2_TASK_STACK_SIZE, NULL, 2, &s_wpa2_task_hdl); + ret = os_task_create(wpa2_task, "wpa2T", WPA2_TASK_STACK_SIZE, NULL, WPA2_TASK_PRIORITY, &s_wpa2_task_hdl); if (ret != TRUE) { wpa_printf(MSG_ERROR, "wps enable: failed to create task"); ret = ESP_FAIL; @@ -722,12 +734,12 @@ static int eap_peer_sm_init(void) } s_wifi_wpa2_sync_sem = os_semphr_create(1, 0); if (!s_wifi_wpa2_sync_sem) { - wpa_printf(MSG_ERROR, "WPA2: failed create wifi wpa2 task sync sem"); + wpa_printf(MSG_ERROR, "EAP: failed create wifi EAP task sync sem"); ret = ESP_FAIL; goto _err; } - wpa_printf(MSG_INFO, "wpa2_task prio:%d, stack:%d", 2, WPA2_TASK_STACK_SIZE); + wpa_printf(MSG_INFO, "wifi_task prio:%d, stack:%d", WPA2_TASK_PRIORITY, WPA2_TASK_STACK_SIZE); #endif return ESP_OK; @@ -772,7 +784,7 @@ static void eap_peer_sm_deinit(void) if (s_wpa2_data_lock) { os_semphr_delete(s_wpa2_data_lock); s_wpa2_data_lock = NULL; - wpa_printf(MSG_DEBUG, "wpa2 eap_peer_sm_deinit: free data lock"); + wpa_printf(MSG_DEBUG, "EAP: eap_peer_sm_deinit: free data lock"); } if (s_wpa2_queue) { @@ -783,16 +795,15 @@ static void eap_peer_sm_deinit(void) gEapSm = NULL; } -esp_err_t esp_wifi_sta_wpa2_ent_enable_fn(void *arg) +static esp_err_t esp_client_enable_fn(void *arg) { struct wpa2_funcs *wpa2_cb; - wpa_printf(MSG_INFO, "WPA2 ENTERPRISE VERSION: [%s] enable", - WPA2_VERSION); + wpa_printf(MSG_INFO, "WiFi Enterprise enable"); wpa2_cb = (struct wpa2_funcs *)os_zalloc(sizeof(struct wpa2_funcs)); if (wpa2_cb == NULL) { - wpa_printf(MSG_ERROR, "WPA2: no mem for wpa2 cb"); + wpa_printf(MSG_ERROR, "EAP: no mem for eap cb"); return ESP_ERR_NO_MEM; } @@ -803,7 +814,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_enable_fn(void *arg) esp_wifi_register_wpa2_cb_internal(wpa2_cb); - wpa_printf(MSG_DEBUG, "WPA2 ENTERPRISE CRYPTO INIT.\r"); + wpa_printf(MSG_DEBUG, "WiFi Enterprise crypto init.\r"); #ifdef EAP_PEER_METHOD if (eap_peer_register_methods()) { @@ -813,7 +824,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_enable_fn(void *arg) return ESP_OK; } -esp_err_t esp_wifi_sta_wpa2_ent_enable(void) +esp_err_t esp_wifi_sta_enterprise_enable(void) { wifi_wpa2_param_t param; esp_err_t ret; @@ -822,21 +833,21 @@ esp_err_t esp_wifi_sta_wpa2_ent_enable(void) wpa2_api_lock(); if (wpa2_is_enabled()) { - wpa_printf(MSG_INFO, "WPA2: already enabled"); + wpa_printf(MSG_INFO, "EAP: already enabled"); wpa2_api_unlock(); return ESP_OK; } - param.fn = (wifi_wpa2_fn_t)esp_wifi_sta_wpa2_ent_enable_fn; + param.fn = (wifi_wpa2_fn_t)esp_client_enable_fn; param.param = NULL; ret = esp_wifi_sta_wpa2_ent_enable_internal(¶m); if (ESP_OK == ret) { wpa2_set_state(WPA2_STATE_ENABLED); - sm->wpa_sm_wpa2_ent_disable = esp_wifi_sta_wpa2_ent_disable; + sm->wpa_sm_eap_disable = esp_wifi_sta_enterprise_disable; } else { - wpa_printf(MSG_ERROR, "failed to enable wpa2 ret=%d", ret); + wpa_printf(MSG_ERROR, "failed to enable eap ret=%d", ret); } wpa2_api_unlock(); @@ -844,10 +855,10 @@ esp_err_t esp_wifi_sta_wpa2_ent_enable(void) return ret; } -esp_err_t esp_wifi_sta_wpa2_ent_disable_fn(void *param) +static esp_err_t eap_client_disable_fn(void *param) { struct wpa_sm *sm = &gWpaSm; - wpa_printf(MSG_INFO, "WPA2 ENTERPRISE VERSION: [%s] disable", WPA2_VERSION); + wpa_printf(MSG_INFO, "WiFi enterprise disable"); esp_wifi_unregister_wpa2_cb_internal(); if (gEapSm) { @@ -858,11 +869,11 @@ esp_err_t esp_wifi_sta_wpa2_ent_disable_fn(void *param) eap_peer_unregister_methods(); #endif - sm->wpa_sm_wpa2_ent_disable = NULL; + sm->wpa_sm_eap_disable = NULL; return ESP_OK; } -esp_err_t esp_wifi_sta_wpa2_ent_disable(void) +esp_err_t esp_wifi_sta_enterprise_disable(void) { wifi_wpa2_param_t param; esp_err_t ret; @@ -870,19 +881,19 @@ esp_err_t esp_wifi_sta_wpa2_ent_disable(void) wpa2_api_lock(); if (wpa2_is_disabled()) { - wpa_printf(MSG_INFO, "WPA2: already disabled"); + wpa_printf(MSG_INFO, "EAP: already disabled"); wpa2_api_unlock(); return ESP_OK; } - param.fn = (wifi_wpa2_fn_t)esp_wifi_sta_wpa2_ent_disable_fn; + param.fn = (wifi_wpa2_fn_t)eap_client_disable_fn; param.param = 0; ret = esp_wifi_sta_wpa2_ent_disable_internal(¶m); if (ESP_OK == ret) { wpa2_set_state(WPA2_STATE_DISABLED); } else { - wpa_printf(MSG_ERROR, "failed to disable wpa2 ret=%d", ret); + wpa_printf(MSG_ERROR, "failed to disable eap ret=%d", ret); } wpa2_api_unlock(); @@ -890,7 +901,9 @@ esp_err_t esp_wifi_sta_wpa2_ent_disable(void) return ret; } -esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, int client_cert_len, const unsigned char *private_key, int private_key_len, const unsigned char *private_key_passwd, int private_key_passwd_len) +esp_err_t esp_eap_client_set_certificate_and_key(const unsigned char *client_cert, int client_cert_len, + const unsigned char *private_key, int private_key_len, + const unsigned char *private_key_passwd, int private_key_passwd_len) { if (client_cert && client_cert_len > 0) { g_wpa_client_cert = client_cert; @@ -908,10 +921,8 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, i return ESP_OK; } -void esp_wifi_sta_wpa2_ent_clear_cert_key(void) +void esp_eap_client_clear_certificate_and_key(void) { - esp_wifi_unregister_wpa2_cb_internal(); - g_wpa_client_cert = NULL; g_wpa_client_cert_len = 0; g_wpa_private_key = NULL; @@ -923,7 +934,7 @@ void esp_wifi_sta_wpa2_ent_clear_cert_key(void) g_wpa_pac_file_len = 0; } -esp_err_t esp_wifi_sta_wpa2_ent_set_ca_cert(const unsigned char *ca_cert, int ca_cert_len) +esp_err_t esp_eap_client_set_ca_cert(const unsigned char *ca_cert, int ca_cert_len) { if (ca_cert && ca_cert_len > 0) { g_wpa_ca_cert = ca_cert; @@ -933,14 +944,14 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_ca_cert(const unsigned char *ca_cert, int ca return ESP_OK; } -void esp_wifi_sta_wpa2_ent_clear_ca_cert(void) +void esp_eap_client_clear_ca_cert(void) { g_wpa_ca_cert = NULL; g_wpa_ca_cert_len = 0; } #define ANONYMOUS_ID_LEN_MAX 128 -esp_err_t esp_wifi_sta_wpa2_ent_set_identity(const unsigned char *identity, int len) +esp_err_t esp_eap_client_set_identity(const unsigned char *identity, int len) { if (len <= 0 || len > ANONYMOUS_ID_LEN_MAX) { return ESP_ERR_INVALID_ARG; @@ -962,7 +973,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_identity(const unsigned char *identity, int return ESP_OK; } -void esp_wifi_sta_wpa2_ent_clear_identity(void) +void esp_eap_client_clear_identity(void) { if (g_wpa_anonymous_identity) { os_free(g_wpa_anonymous_identity); @@ -973,7 +984,7 @@ void esp_wifi_sta_wpa2_ent_clear_identity(void) } #define USERNAME_LEN_MAX 128 -esp_err_t esp_wifi_sta_wpa2_ent_set_username(const unsigned char *username, int len) +esp_err_t esp_eap_client_set_username(const unsigned char *username, int len) { if (len <= 0 || len > USERNAME_LEN_MAX) { return ESP_ERR_INVALID_ARG; @@ -995,7 +1006,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_username(const unsigned char *username, int return ESP_OK; } -void esp_wifi_sta_wpa2_ent_clear_username(void) +void esp_eap_client_clear_username(void) { if (g_wpa_username) { os_free(g_wpa_username); @@ -1005,7 +1016,7 @@ void esp_wifi_sta_wpa2_ent_clear_username(void) g_wpa_username_len = 0; } -esp_err_t esp_wifi_sta_wpa2_ent_set_password(const unsigned char *password, int len) +esp_err_t esp_eap_client_set_password(const unsigned char *password, int len) { if (len <= 0) { return ESP_ERR_INVALID_ARG; @@ -1027,7 +1038,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_password(const unsigned char *password, int return ESP_OK; } -void esp_wifi_sta_wpa2_ent_clear_password(void) +void esp_eap_client_clear_password(void) { if (g_wpa_password) { os_free(g_wpa_password); @@ -1036,7 +1047,7 @@ void esp_wifi_sta_wpa2_ent_clear_password(void) g_wpa_password_len = 0; } -esp_err_t esp_wifi_sta_wpa2_ent_set_new_password(const unsigned char *new_password, int len) +esp_err_t esp_eap_client_set_new_password(const unsigned char *new_password, int len) { if (len <= 0) { return ESP_ERR_INVALID_ARG; @@ -1058,7 +1069,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_new_password(const unsigned char *new_passwo return ESP_OK; } -void esp_wifi_sta_wpa2_ent_clear_new_password(void) +void esp_eap_client_clear_new_password(void) { if (g_wpa_new_password) { os_free(g_wpa_new_password); @@ -1067,7 +1078,7 @@ void esp_wifi_sta_wpa2_ent_clear_new_password(void) g_wpa_new_password_len = 0; } -esp_err_t esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable) +esp_err_t esp_eap_client_set_disable_time_check(bool disable) { s_disable_time_check = disable; return ESP_OK; @@ -1078,13 +1089,13 @@ bool wifi_sta_get_enterprise_disable_time_check(void) return s_disable_time_check; } -esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable) +esp_err_t esp_eap_client_get_disable_time_check(bool *disable) { *disable = wifi_sta_get_enterprise_disable_time_check(); return ESP_OK; } -esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types type) +esp_err_t esp_eap_client_set_ttls_phase2_method(esp_eap_ttls_phase2_types type) { switch (type) { case ESP_EAP_TTLS_PHASE2_EAP: @@ -1109,7 +1120,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types return ESP_OK; } -esp_err_t esp_wifi_sta_wpa2_set_suiteb_192bit_certification(bool enable) +esp_err_t esp_eap_client_set_suiteb_192bit_certification(bool enable) { #ifdef CONFIG_SUITEB192 g_wpa_suiteb_certification = enable; @@ -1119,7 +1130,7 @@ esp_err_t esp_wifi_sta_wpa2_set_suiteb_192bit_certification(bool enable) #endif } -esp_err_t esp_wifi_sta_wpa2_ent_set_pac_file(const unsigned char *pac_file, int pac_file_len) +esp_err_t esp_eap_client_set_pac_file(const unsigned char *pac_file, int pac_file_len) { if (pac_file && pac_file_len > -1) { if (pac_file_len < 512) { // The file contains less than 1 pac and is to be rewritten later @@ -1143,7 +1154,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_pac_file(const unsigned char *pac_file, int return ESP_OK; } -esp_err_t esp_wifi_sta_wpa2_ent_set_fast_phase1_params(esp_eap_fast_config config) +esp_err_t esp_eap_client_set_fast_params(esp_eap_fast_config config) { char config_for_supplicant[PHASE1_PARAM_STRING_LEN] = ""; if ((config.fast_provisioning > -1) && (config.fast_provisioning <= 2)) { @@ -1175,7 +1186,7 @@ esp_err_t esp_wifi_sta_wpa2_ent_set_fast_phase1_params(esp_eap_fast_config confi } -esp_err_t esp_wifi_sta_wpa2_use_default_cert_bundle(bool use_default_bundle) +esp_err_t esp_eap_client_use_default_cert_bundle(bool use_default_bundle) { #ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE g_wpa_default_cert_bundle = use_default_bundle; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_eap_client_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client_i.h new file mode 100644 index 0000000000..d0e6b30bad --- /dev/null +++ b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client_i.h @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_wifi_driver.h" + +wpa2_ent_eap_state_t eap_client_get_eap_state(void); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c index 20f41306e9..172ae2f072 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -59,10 +59,7 @@ void *hostap_init(void) auth_conf = (struct wpa_auth_config *)os_zalloc(sizeof(struct wpa_auth_config)); if (auth_conf == NULL) { - os_free(hapd->conf); - os_free(hapd); - hapd = NULL; - return NULL; + goto fail; } hapd->conf->sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal(WIFI_IF_AP); @@ -145,23 +142,14 @@ void *hostap_init(void) hapd->conf->wpa_key_mgmt = auth_conf->wpa_key_mgmt; hapd->conf->ssid.wpa_passphrase = (char *)os_zalloc(WIFI_PASSWORD_LEN_MAX); if (hapd->conf->ssid.wpa_passphrase == NULL) { - os_free(auth_conf); - os_free(hapd->conf); - os_free(hapd); - hapd = NULL; - return NULL; + goto fail; } #ifdef CONFIG_SAE if (authmode == WIFI_AUTH_WPA3_PSK || authmode == WIFI_AUTH_WPA2_WPA3_PSK) { if (wpa3_hostap_auth_init(hapd) != 0) { - os_free(hapd->conf->ssid.wpa_passphrase); - os_free(auth_conf); - os_free(hapd->conf); - os_free(hapd); - hapd = NULL; - return NULL; + goto fail; } } #endif /* CONFIG_SAE */ @@ -176,11 +164,26 @@ void *hostap_init(void) esp_wifi_get_macaddr_internal(WIFI_IF_AP, hapd->own_addr); hapd->wpa_auth = wpa_init(hapd->own_addr, auth_conf, NULL); + if (hapd->wpa_auth == NULL) { + goto fail; + } + esp_wifi_set_appie_internal(WIFI_APPIE_WPA, hapd->wpa_auth->wpa_ie, (uint16_t)hapd->wpa_auth->wpa_ie_len, 0); os_free(auth_conf); global_hapd = hapd; return (void *)hapd; +fail: + if (hapd->conf->ssid.wpa_passphrase != NULL) { + os_free(hapd->conf->ssid.wpa_passphrase); + } + if (auth_conf != NULL) { + os_free(auth_conf); + } + os_free(hapd->conf); + os_free(hapd); + hapd = NULL; + return NULL; } void hostapd_cleanup(struct hostapd_data *hapd) @@ -233,6 +236,7 @@ bool hostap_deinit(void *data) return true; } esp_wifi_unset_appie_internal(WIFI_APPIE_WPA); + esp_wifi_unset_appie_internal(WIFI_APPIE_ASSOC_RESP); #ifdef CONFIG_SAE wpa3_hostap_auth_deinit(); @@ -277,8 +281,8 @@ int esp_wifi_build_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len) return pos - eid; } -u16 esp_send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, - const u8 *addr, u16 status_code, bool omit_rsnxe, int subtype) +u16 esp_send_assoc_resp(struct hostapd_data *hapd, const u8 *addr, + u16 status_code, bool omit_rsnxe, int subtype) { #define ASSOC_RESP_LENGTH 20 u8 buf[ASSOC_RESP_LENGTH]; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.h b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.h index 94d142f808..394153c43d 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,9 +17,8 @@ extern "C" { #ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT void *hostap_init(void); bool hostap_deinit(void *data); -u16 esp_send_assoc_resp(struct hostapd_data *data, struct sta_info *sta, - const u8 *addr, u16 status_code, bool omit_rsnxe, - int subtype); +u16 esp_send_assoc_resp(struct hostapd_data *data, const u8 *addr, + u16 status_code, bool omit_rsnxe, int subtype); #endif #ifdef __cplusplus diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostpad_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostpad_wps.c index 84a8177dc6..c96ca958e0 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostpad_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostpad_wps.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,12 +26,15 @@ #include "ap/hostapd.h" #include "ap/ap_config.h" #include "ap/wps_hostapd.h" +#include "utils/eloop.h" extern struct wps_sm *gWpsSm; extern void *s_wps_api_lock; extern void *s_wps_api_sem; extern bool s_wps_enabled; +static int wps_reg_eloop_post_block(uint32_t sig, void *arg); + static int wifi_ap_wps_init(const esp_wps_config_t *config) { struct wps_sm *sm = NULL; @@ -138,41 +141,8 @@ int wifi_ap_wps_deinit(void) return ESP_OK; } -int wifi_ap_wps_enable_internal(const esp_wps_config_t *config) -{ - int ret = 0; - - wpa_printf(MSG_DEBUG, "ESP WPS crypto initialize!"); - if (config->wps_type == WPS_TYPE_DISABLE) { - wpa_printf(MSG_ERROR, "wps enable: invalid wps type"); - return ESP_ERR_WIFI_WPS_TYPE; - } - - wpa_printf(MSG_DEBUG, "Set factory information."); - ret = wps_set_factory_info(config); - if (ret != 0) { - return ret; - } - - wpa_printf(MSG_INFO, "wifi_wps_enable"); - - wps_set_type(config->wps_type); - wps_set_status(WPS_STATUS_DISABLE); - - ret = wifi_ap_wps_init(config); - - if (ret != 0) { - wps_set_type(WPS_STATUS_DISABLE); - wps_set_status(WPS_STATUS_DISABLE); - return ESP_FAIL; - } - - return ESP_OK; -} - -int esp_wifi_ap_wps_enable(const esp_wps_config_t *config) +static int wifi_ap_wps_enable_internal(const esp_wps_config_t *config) { - int ret = ESP_OK; struct wps_sm *sm = gWpsSm; wifi_mode_t mode = WIFI_MODE_NULL; @@ -181,7 +151,11 @@ int esp_wifi_ap_wps_enable(const esp_wps_config_t *config) return ESP_ERR_WIFI_STATE; } - ret = esp_wifi_get_mode(&mode); + if (esp_wifi_get_mode(&mode) != ESP_OK) { + wpa_printf(MSG_ERROR, "wps enable: unable to get current wifi mode"); + return ESP_FAIL; + } + if (mode != WIFI_MODE_AP && mode != WIFI_MODE_APSTA) { wpa_printf(MSG_ERROR, "wps enable: mode=%d does not include AP", mode); return ESP_ERR_WIFI_MODE; @@ -192,58 +166,106 @@ int esp_wifi_ap_wps_enable(const esp_wps_config_t *config) return ESP_ERR_WIFI_MODE; } - API_MUTEX_TAKE(); if (s_wps_enabled) { if (sm && os_memcmp(sm->identity, WSC_ID_ENROLLEE, sm->identity_len) == 0) { wpa_printf(MSG_ERROR, "wps enable: wps enrollee already enabled cannot enable wpsreg"); - ret = ESP_ERR_WIFI_MODE; + return ESP_ERR_WIFI_MODE; } else { wpa_printf(MSG_DEBUG, "wps enable: already enabled"); - ret = ESP_OK; + return ESP_OK; } - API_MUTEX_GIVE(); - return ret; } - ret = wifi_ap_wps_enable_internal(config); + if (config->wps_type == WPS_TYPE_DISABLE) { + wpa_printf(MSG_ERROR, "wps enable: invalid wps type"); + return ESP_ERR_WIFI_WPS_TYPE; + } + + wpa_printf(MSG_DEBUG, "Set factory information."); + if (wps_set_factory_info(config) != ESP_OK) { + return ESP_FAIL; + } + + + if (wps_set_type(config->wps_type) != ESP_OK) { + goto _err; + } + + if (wps_set_status(WPS_STATUS_DISABLE) != ESP_OK) { + goto _err; + } + + if (wifi_ap_wps_init(config) != ESP_OK) { + goto _err; + } + + wpa_printf(MSG_INFO, "wifi_wps_enable"); s_wps_enabled = true; + return ESP_OK; + +_err: + wpa_printf(MSG_ERROR, "failure in wifi_wps_enable"); + wps_set_type(WPS_TYPE_DISABLE); + wps_set_status(WPS_STATUS_DISABLE); + + return ESP_FAIL; +} + +int esp_wifi_ap_wps_enable(const esp_wps_config_t *config) +{ + int ret = ESP_OK; + + API_MUTEX_TAKE(); + ret = wps_reg_eloop_post_block(SIG_WPS_REG_ENABLE, (void *) config); API_MUTEX_GIVE(); return ret; } -int esp_wifi_ap_wps_disable(void) +int wifi_ap_wps_disable_internal(void) { - int ret = 0; struct wps_sm *sm = gWpsSm; if (sm && os_memcmp(sm->identity, WSC_ID_ENROLLEE, sm->identity_len) == 0) { return ESP_ERR_WIFI_MODE; } - API_MUTEX_TAKE(); - if (!s_wps_enabled) { wpa_printf(MSG_DEBUG, "wps disable: already disabled"); - API_MUTEX_GIVE(); return ESP_OK; } wpa_printf(MSG_INFO, "wifi_wps_disable"); - wps_set_type(WPS_TYPE_DISABLE); - wps_set_status(WPS_STATUS_DISABLE); + if (wps_set_type(WPS_TYPE_DISABLE) != ESP_OK) { + goto _err; + } - wifi_ap_wps_deinit(); + if (wps_set_status(WPS_STATUS_DISABLE) != ESP_OK) { + goto _err; + } - if (ESP_OK != ret) { - wpa_printf(MSG_ERROR, "wps disable: failed to disable wps, ret=%d", ret); + if (wifi_ap_wps_deinit() != ESP_OK) { + goto _err; } + s_wps_enabled = false; - API_MUTEX_GIVE(); return ESP_OK; + +_err: + wpa_printf(MSG_ERROR, "wps disable: failed to disable wps"); + return ESP_FAIL; } -int esp_wifi_ap_wps_start(const unsigned char *pin) +int esp_wifi_ap_wps_disable(void) +{ + int ret = ESP_FAIL; + API_MUTEX_TAKE(); + ret = wps_reg_eloop_post_block(SIG_WPS_REG_DISABLE, NULL); + API_MUTEX_GIVE(); + return ret; +} + +static int wifi_ap_wps_start_internal(const unsigned char *pin) { wifi_mode_t mode = WIFI_MODE_NULL; @@ -253,7 +275,6 @@ int esp_wifi_ap_wps_start(const unsigned char *pin) return ESP_ERR_WIFI_MODE; } - API_MUTEX_TAKE(); if (!s_wps_enabled) { wpa_printf(MSG_ERROR, "wps start: wps not enabled"); @@ -261,29 +282,100 @@ int esp_wifi_ap_wps_start(const unsigned char *pin) return ESP_ERR_WIFI_WPS_SM; } - if (wps_get_type() == WPS_TYPE_DISABLE || (wps_get_status() != WPS_STATUS_DISABLE && wps_get_status() != WPS_STATUS_SCANNING)) { - wpa_printf(MSG_ERROR, "wps start: wps_get_type=%d wps_get_status=%d", wps_get_type(), wps_get_status()); - API_MUTEX_GIVE(); + if (wps_get_type() == WPS_TYPE_DISABLE || + (wps_get_status() != WPS_STATUS_DISABLE && + wps_get_status() != WPS_STATUS_SCANNING)) { + wpa_printf(MSG_ERROR, "wps start: wps_get_type=%d wps_get_status=%d", + wps_get_type(), wps_get_status()); return ESP_ERR_WIFI_WPS_TYPE; } if (esp_wifi_get_user_init_flag_internal() == 0) { - wpa_printf(MSG_ERROR, "wps start: esp_wifi_get_user_init_flag_internal=%d", esp_wifi_get_user_init_flag_internal()); - API_MUTEX_GIVE(); + wpa_printf(MSG_ERROR, "wps start: esp_wifi_get_user_init_flag_internal=%d", + esp_wifi_get_user_init_flag_internal()); return ESP_ERR_WIFI_STATE; } if (!pin) { pin = gWpsSm->wps->dev_password; } + /* TODO ideally SoftAP mode should also do a single scan in PBC mode * however softAP scanning is not available at the moment */ - wps_set_status(WPS_STATUS_PENDING); + if (wps_set_status(WPS_STATUS_PENDING) != ESP_OK) { + return ESP_FAIL; + } if (wps_get_type() == WPS_TYPE_PBC) { - hostapd_wps_button_pushed(hostapd_get_hapd_data(), NULL); + if (hostapd_wps_button_pushed(hostapd_get_hapd_data(), NULL) != ESP_OK) { + return ESP_FAIL; + } } else if (wps_get_type() == WPS_TYPE_PIN) { - hostapd_wps_add_pin(hostapd_get_hapd_data(), pin); + if (hostapd_wps_add_pin(hostapd_get_hapd_data(), pin) != ESP_OK) { + return ESP_FAIL; + } } - API_MUTEX_GIVE(); return ESP_OK; } + +int esp_wifi_ap_wps_start(const unsigned char *pin) +{ + int ret = ESP_FAIL; + API_MUTEX_TAKE(); + ret = wps_reg_eloop_post_block(SIG_WPS_REG_START, (void *)pin); + API_MUTEX_GIVE(); + return ret; +} + +static void wps_reg_eloop_handler(void *eloop_ctx, void *user_ctx) +{ + int ret = ESP_FAIL; + enum wps_reg_sig_type *sig = (enum wps_reg_sig_type *) eloop_ctx; + wps_ioctl_param_t *param = (wps_ioctl_param_t *) user_ctx; + + switch(*sig) { + case SIG_WPS_REG_ENABLE: + esp_wps_config_t *config = (esp_wps_config_t *)param->arg; + ret = wifi_ap_wps_enable_internal(config); + break; + case SIG_WPS_REG_START: + unsigned char *pin = (unsigned char *)param->arg; + ret = wifi_ap_wps_start_internal((const unsigned char *)pin); + break; + case SIG_WPS_REG_DISABLE: + ret = wifi_ap_wps_disable_internal(); + break; + default: + wpa_printf(MSG_WARNING, "%s(): invalid signal type=%d", __func__, *sig); + ret = ESP_FAIL; + break; + } + + param->ret = ret; + os_semphr_give(s_wps_api_sem); +} + +static int wps_reg_eloop_post_block(uint32_t sig, void *arg) +{ + int ret = ESP_FAIL; + wps_ioctl_param_t param; + param.ret = ESP_FAIL; + param.arg = arg; + + if (s_wps_api_sem == NULL) { + s_wps_api_sem = os_semphr_create(1, 0); + if (s_wps_api_sem == NULL) { + wpa_printf(MSG_ERROR, "%s(): failed to create WPA API semaphore", __func__); + return ESP_ERR_NO_MEM; + } + } + + eloop_register_timeout(0, 0, wps_reg_eloop_handler, (void *)&sig, (void *)¶m); + + if (TRUE == os_semphr_take(s_wps_api_sem, OS_BLOCK)) { + ret = param.ret; + } else { + ret = ESP_FAIL; + } + + return ret; +} diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_scan.c b/components/wpa_supplicant/esp_supplicant/src/esp_scan.c index d8d0553dcd..059b49d7de 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-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -66,13 +66,10 @@ static void handle_wnm_scan_done(struct wpa_supplicant *wpa_s) static void scan_done_cleanup(struct wpa_supplicant *wpa_s) { - uint16_t number = 1; - wifi_ap_record_t ap_records; - wpa_s->scanning = 0; wpa_s->scan_reason = 0; /* clean scan list from net80211 */ - esp_wifi_scan_get_ap_records(&number, &ap_records); + esp_wifi_clear_ap_list(); } void esp_supplicant_handle_scan_done_evt(void) @@ -114,7 +111,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 25442a6ac0..bbea379867 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 57b036f9a1..6be0bb3358 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -124,7 +124,7 @@ struct wpa_funcs { bool (*wpa_sta_in_4way_handshake)(void); void *(*wpa_ap_init)(void); bool (*wpa_ap_deinit)(void *data); - bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8* rsnxe, u8 rsnxe_len, bool *pmf_enable, int subtype); + bool (*wpa_ap_join)(void **sm, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8* rsnxe, u8 rsnxe_len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher); bool (*wpa_ap_remove)(u8 *bssid); uint8_t *(*wpa_ap_get_wpa_ie)(uint8_t *len); bool (*wpa_ap_rx_eapol)(void *hapd_data, void *sm, u8 *data, size_t data_len); @@ -136,11 +136,10 @@ 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); - int (*wpa_sta_set_ap_rsnxe)(const u8 *rsnxe, size_t rsnxe_ie_len); }; struct wpa2_funcs { @@ -175,8 +174,8 @@ typedef enum wps_status { WPS_STATUS_MAX, } WPS_STATUS_t; -#define WIFI_TXCB_EAPOL_ID 3 typedef void(*wifi_tx_cb_t)(void *); +typedef void(* eapol_txcb_t)(uint8_t *, size_t, bool); typedef int (*wifi_ipc_fn_t)(void *); typedef struct { wifi_ipc_fn_t fn; @@ -241,6 +240,7 @@ bool esp_wifi_wpa_ptk_init_done_internal(uint8_t *mac); uint8_t esp_wifi_sta_set_reset_param_internal(uint8_t reset_flag); uint8_t esp_wifi_get_sta_gtk_index_internal(void); int esp_wifi_register_tx_cb_internal(wifi_tx_cb_t fn, u8 id); +int esp_wifi_register_eapol_txdonecb_internal(eapol_txcb_t fn); int esp_wifi_register_wpa_cb_internal(struct wpa_funcs *cb); int esp_wifi_unregister_wpa_cb_internal(void); int esp_wifi_get_assoc_bssid_internal(uint8_t *bssid); @@ -285,15 +285,18 @@ esp_err_t esp_wifi_remain_on_channel(uint8_t ifx, uint8_t type, uint8_t channel, bool esp_wifi_is_mbo_enabled_internal(uint8_t if_index); void esp_wifi_get_pmf_config_internal(wifi_pmf_config_t *pmf_cfg, uint8_t ifx); bool esp_wifi_is_ft_enabled_internal(uint8_t if_index); -uint8_t esp_wifi_sta_get_use_h2e_internal(void); uint8_t esp_wifi_sta_get_config_sae_pk_internal(void); void esp_wifi_sta_disable_sae_pk_internal(void); void esp_wifi_sta_disable_wpa2_authmode_internal(void); +void esp_wifi_sta_disable_owe_trans_internal(void); uint8_t esp_wifi_ap_get_max_sta_conn(void); uint8_t esp_wifi_get_config_sae_pwe_h2e_internal(uint8_t ifx); bool esp_wifi_ap_notify_node_sae_auth_done(uint8_t *mac); bool esp_wifi_ap_is_sta_sae_reauth_node(uint8_t *mac); uint8_t* esp_wifi_sta_get_sae_identifier_internal(void); bool esp_wifi_eb_tx_status_success_internal(void *eb); +uint8_t* esp_wifi_sta_get_rsnxe(u8 *bssid); +esp_err_t esp_wifi_sta_connect_internal(const uint8_t *bssid); +void esp_wifi_enable_sae_pk_only_mode_internal(void); #endif /* _ESP_WIFI_DRIVER_H_ */ diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa2_api_port.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa2_api_port.c new file mode 100644 index 0000000000..a61c3ca8eb --- /dev/null +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa2_api_port.c @@ -0,0 +1,115 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_eap_client.h" + +esp_err_t esp_wifi_sta_wpa2_ent_enable(void) +{ + return esp_wifi_sta_enterprise_enable(); +} + +esp_err_t esp_wifi_sta_wpa2_ent_disable(void) +{ + return esp_wifi_sta_enterprise_disable(); +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_identity(const unsigned char *identity, int len) +{ + return esp_eap_client_set_identity(identity, len); +} + +void esp_wifi_sta_wpa2_ent_clear_identity(void) +{ + esp_eap_client_clear_identity(); +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_username(const unsigned char *username, int len) +{ + return esp_eap_client_set_username(username, len); +} + +void esp_wifi_sta_wpa2_ent_clear_username(void) +{ + esp_eap_client_clear_username(); +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_password(const unsigned char *password, int len) +{ + return esp_eap_client_set_password(password, len); +} + +void esp_wifi_sta_wpa2_ent_clear_password(void) +{ + esp_eap_client_clear_password(); +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_new_password(const unsigned char *new_password, int len) +{ + return esp_eap_client_set_new_password(new_password, len); +} + +void esp_wifi_sta_wpa2_ent_clear_new_password(void) +{ + esp_eap_client_clear_new_password(); +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_ca_cert(const unsigned char *ca_cert, int ca_cert_len) +{ + return esp_eap_client_set_ca_cert(ca_cert, ca_cert_len); +} + +void esp_wifi_sta_wpa2_ent_clear_ca_cert(void) +{ + esp_eap_client_clear_ca_cert(); +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_cert_key(const unsigned char *client_cert, int client_cert_len, + const unsigned char *private_key, int private_key_len, + const unsigned char *private_key_passwd, int private_key_passwd_len) +{ + return esp_eap_client_set_certificate_and_key(client_cert, client_cert_len, + private_key, private_key_len, private_key_passwd, private_key_passwd_len); +} + +void esp_wifi_sta_wpa2_ent_clear_cert_key(void) +{ + esp_eap_client_clear_certificate_and_key(); +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_disable_time_check(bool disable) +{ + return esp_eap_client_set_disable_time_check(disable); +} + +esp_err_t esp_wifi_sta_wpa2_ent_get_disable_time_check(bool *disable) +{ + return esp_eap_client_get_disable_time_check(disable); +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_ttls_phase2_method(esp_eap_ttls_phase2_types type) +{ + return esp_eap_client_set_ttls_phase2_method(type); +} + +esp_err_t esp_wifi_sta_wpa2_set_suiteb_192bit_certification(bool enable) +{ + return esp_eap_client_set_suiteb_192bit_certification(enable); +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_pac_file(const unsigned char *pac_file, int pac_file_len) +{ + return esp_eap_client_set_pac_file(pac_file, pac_file_len); +} + +esp_err_t esp_wifi_sta_wpa2_ent_set_fast_phase1_params(esp_eap_fast_config config) +{ + return esp_eap_client_set_fast_params(config); +} + +esp_err_t esp_wifi_sta_wpa2_use_default_cert_bundle(bool use_default_bundle) +{ + return esp_eap_client_use_default_cert_bundle(use_default_bundle); +} diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c index 85ba2bcaae..bc445ef9c4 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -17,11 +17,6 @@ #include "esp_hostap.h" #include #include -#ifdef CONFIG_SAE_PK -#include "common/bss.h" -extern struct wpa_supplicant g_wpa_supp; -#endif - static struct sae_pt *g_sae_pt; static struct sae_data g_sae_data; static struct wpabuf *g_sae_token = NULL; @@ -33,12 +28,53 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid, size_t *sae_msg_len) { int default_group = IANA_SECP256R1; u32 len = 0; + uint8_t use_pt = 0; u8 own_addr[ETH_ALEN]; const u8 *pw = (const u8 *)esp_wifi_sta_get_prof_password_internal(); struct wifi_ssid *ssid = esp_wifi_sta_get_prof_ssid_internal(); - uint8_t use_pt = esp_wifi_sta_get_use_h2e_internal(); + uint8_t sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal(WIFI_IF_STA); char sae_pwd_id[SAE_H2E_IDENTIFIER_LEN+1] = {0}; bool valid_pwd_id = false; + const u8 *rsnxe; + u8 rsnxe_capa = 0; + + rsnxe = esp_wifi_sta_get_rsnxe(bssid); + if (rsnxe && rsnxe[1] >= 1) { + rsnxe_capa = rsnxe[2]; + } + +#ifdef CONFIG_SAE_PK + bool use_pk = false; + uint8_t sae_pk_mode = esp_wifi_sta_get_config_sae_pk_internal(); + + if ((rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) && + sae_pk_mode != WPA3_SAE_PK_MODE_DISABLED && + ((pw && sae_pk_valid_password((const char*)pw)))) { + use_pt = 1; + use_pk = true; + } + + if (sae_pk_mode == WPA3_SAE_PK_MODE_ONLY && !use_pk) { + wpa_printf(MSG_DEBUG, + "SAE: Cannot use PK with the selected AP"); + return ESP_FAIL; + } +#endif /* CONFIG_SAE_PK */ + if (use_pt || sae_pwe == SAE_PWE_HASH_TO_ELEMENT || + sae_pwe == SAE_PWE_BOTH) { + use_pt = !!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E)); + + if ((sae_pwe == SAE_PWE_HASH_TO_ELEMENT +#ifdef CONFIG_SAE_PK + || (use_pk && sae_pk_mode == WPA3_SAE_PK_MODE_ONLY) +#endif /* CONFIG_SAE_PK */ + ) && !use_pt) { + wpa_printf(MSG_DEBUG, + "SAE: Cannot use H2E with the selected AP"); + return ESP_FAIL; + } + } + if (use_pt != 0) { memcpy(sae_pwd_id, esp_wifi_sta_get_sae_identifier_internal(), SAE_H2E_IDENTIFIER_LEN); @@ -79,40 +115,6 @@ static esp_err_t wpa3_build_sae_commit(u8 *bssid, size_t *sae_msg_len) return ESP_FAIL; } -#ifdef CONFIG_SAE_PK - bool use_pk = false; - uint8_t sae_pk_mode = esp_wifi_sta_get_config_sae_pk_internal(); - u8 rsnxe_capa = 0; - struct wpa_bss *bss = wpa_bss_get_bssid(&g_wpa_supp, (uint8_t *)bssid); - if (!bss) { - wpa_printf(MSG_ERROR, - "SAE: BSS not available, update scan result to get BSS"); - // TODO: should we trigger scan again. - return ESP_FAIL; - } - if (bss) { - const u8 *rsnxe; - - rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX); - if (rsnxe && rsnxe[1] >= 1) { - rsnxe_capa = rsnxe[2]; - } - } - - if (use_pt && (rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) && - sae_pk_mode != WPA3_SAE_PK_MODE_DISABLED && - ((pw && sae_pk_valid_password((const char*)pw)))) { - use_pt = 1; - use_pk = true; - } - - if (sae_pk_mode == WPA3_SAE_PK_MODE_ONLY && !use_pk) { - wpa_printf(MSG_DEBUG, - "SAE: Cannot use PK with the selected AP"); - return ESP_FAIL; - } -#endif /* CONFIG_SAE_PK */ - if (use_pt && sae_prepare_commit_pt(&g_sae_data, g_sae_pt, own_addr, bssid, NULL, NULL) < 0) { @@ -239,9 +241,8 @@ static int wpa3_parse_sae_commit(u8 *buf, u32 len, u16 status) int ret; if (g_sae_data.state != SAE_COMMITTED) { - wpa_printf(MSG_ERROR, "wpa3: failed to parse SAE commit in state(%d)!", - g_sae_data.state); - return ESP_FAIL; + wpa_printf(MSG_DEBUG, "wpa3: Discarding commit frame received in state %d", g_sae_data.state); + return ESP_ERR_WIFI_DISCARD; } if (status == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ) { @@ -264,7 +265,10 @@ static int wpa3_parse_sae_commit(u8 *buf, u32 len, u16 status) ret = sae_parse_commit(&g_sae_data, buf, len, NULL, 0, g_allowed_groups, (status == WLAN_STATUS_SAE_HASH_TO_ELEMENT || status == WLAN_STATUS_SAE_PK)); - if (ret) { + if (ret == SAE_SILENTLY_DISCARD) { + wpa_printf(MSG_DEBUG, "wpa3: Discarding commit frame due to reflection attack"); + return ESP_ERR_WIFI_DISCARD; + } else if (ret) { wpa_printf(MSG_ERROR, "wpa3: could not parse commit(%d)", ret); return ret; } @@ -410,6 +414,7 @@ static void wpa3_process_rx_commit(wpa3_hostap_auth_event_t *evt) goto free; } } + if (sta->lock && os_semphr_take(sta->lock, 0)) { sta->sae_commit_processing = true; ret = handle_auth_sae(hapd, sta, frm->msg, frm->len, frm->bssid, frm->auth_transaction, frm->status); @@ -423,9 +428,10 @@ static void wpa3_process_rx_commit(wpa3_hostap_auth_event_t *evt) uint16_t aid = 0; if (ret != WLAN_STATUS_SUCCESS && ret != WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ) { - if (esp_wifi_ap_get_sta_aid(frm->bssid, &aid) == ESP_OK && aid == 0) { + esp_wifi_ap_get_sta_aid(frm->bssid, &aid); + if (aid == 0) { esp_wifi_ap_deauth_internal(frm->bssid, ret); - } + } } } @@ -463,8 +469,9 @@ static void wpa3_process_rx_confirm(wpa3_hostap_auth_event_t *evt) } os_semphr_give(sta->lock); if (ret != WLAN_STATUS_SUCCESS) { - uint16_t aid = -1; - if (esp_wifi_ap_get_sta_aid(frm->bssid, &aid) == ESP_OK && aid == 0) { + uint16_t aid = 0; + esp_wifi_ap_get_sta_aid(frm->bssid, &aid); + if (aid == 0) { esp_wifi_ap_deauth_internal(frm->bssid, ret); } } @@ -548,6 +555,7 @@ int wpa3_hostap_auth_init(void *data) &g_wpa3_hostap_task_hdl) != pdPASS) { wpa_printf(MSG_ERROR, "wpa3_hostap_auth_init: failed to create task"); os_queue_delete(g_wpa3_hostap_evt_queue); + g_wpa3_hostap_evt_queue = NULL; return ESP_FAIL; } @@ -617,7 +625,7 @@ int esp_send_sae_auth_reply(struct hostapd_data *hapd, os_memcpy(&((uint16_t *)req->data)[3], ies, ies_len - 3 * sizeof(uint16_t)); req->ifx = WIFI_IF_AP; - req->subtype = WLAN_FC_STYPE_AUTH; + req->subtype = (WLAN_FC_STYPE_AUTH << 4); req->data_len = ies_len; os_memcpy(req->da, bssid, ETH_ALEN); 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 56dce029b5..4ee3c9729a 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,18 +28,21 @@ #include "esp_wifi_driver.h" #include "esp_private/wifi.h" #include "esp_wpa3_i.h" -#include "esp_wpa2.h" +#include "esp_eap_client.h" #include "esp_common_i.h" #include "esp_owe_i.h" #include "esp_wps.h" +#include "esp_wps_i.h" #include "eap_server/eap.h" #include "eapol_auth/eapol_auth_sm.h" #include "ap/ieee802_1x.h" #include "ap/sta_info.h" #include "wps/wps_defs.h" +#include "wps/wps.h" #include "zephyr_compat.h" +bool g_wpa_pmk_caching_disabled = 0; const wifi_osi_funcs_t *wifi_funcs; struct wpa_funcs *wpa_cb; @@ -129,7 +132,7 @@ bool wpa_attach(void) bool ret = true; ret = wpa_sm_init(); if(ret) { - ret = (esp_wifi_register_tx_cb_internal(eapol_txcb, WIFI_TXCB_EAPOL_ID) == ESP_OK); + ret = (esp_wifi_register_eapol_txdonecb_internal(eapol_txcb) == ESP_OK); } esp_set_scan_ie(); return ret; @@ -181,16 +184,19 @@ void wpa_ap_get_peer_spp_msg(void *sm_data, bool *spp_cap, bool *spp_req) *spp_req = sm->spp_sup.require; } -bool wpa_deattach(void) +bool wpa_deattach(void) { struct wpa_sm *sm = &gWpaSm; esp_wpa3_free_sae_data(); - if (sm->wpa_sm_wpa2_ent_disable) { - sm->wpa_sm_wpa2_ent_disable(); +#ifdef CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT + if (sm->wpa_sm_eap_disable) { + sm->wpa_sm_eap_disable(); } +#endif if (sm->wpa_sm_wps_disable) { sm->wpa_sm_wps_disable(); } + esp_wifi_register_eapol_txdonecb_internal(NULL); wpa_sm_deinit(); return true; @@ -211,7 +217,8 @@ int wpa_sta_connect(uint8_t *bssid) esp_set_assoc_ie((uint8_t *)bssid, NULL, 0, false); } - return 0; + ret = esp_wifi_sta_connect_internal(bssid); + return ret; } void wpa_config_done(void) @@ -254,17 +261,26 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code) case WIFI_REASON_ASSOC_FAIL: case WIFI_REASON_CONNECTION_FAIL: case WIFI_REASON_HANDSHAKE_TIMEOUT: - esp_wpa3_free_sae_data(); wpa_sta_clear_curr_pmksa(); wpa_sm_notify_disassoc(&gWpaSm); break; default: + if (g_wpa_pmk_caching_disabled) { + wpa_sta_clear_curr_pmksa(); + } break; } + + struct wps_sm_funcs *wps_sm_cb = wps_get_wps_sm_cb(); + if (wps_sm_cb && wps_sm_cb->wps_sm_notify_deauth) { + wps_sm_cb->wps_sm_notify_deauth(); + } + #ifdef CONFIG_OWE_STA owe_deinit(); #endif /* CONFIG_OWE_STA */ + esp_wpa3_free_sae_data(); supplicant_sta_disconn_handler(); } @@ -281,12 +297,19 @@ static int check_n_add_wps_sta(struct hostapd_data *hapd, struct sta_info *sta_i return 0; } + if (wps_type == WPS_TYPE_PBC) { + if (esp_wps_registrar_check_pbc_overlap(hapd->wps)) { + wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected"); + return -1; + } + } + sta_info->wps_ie = wps_ie; sta_info->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta_info); if (sta_info->eapol_sm) { wpa_printf(MSG_DEBUG, "considering station " MACSTR " for WPS", MAC2STR(sta_info->addr)); - if (esp_send_assoc_resp(hapd, sta_info, sta_info->addr, WLAN_STATUS_SUCCESS, true, subtype) != WLAN_STATUS_SUCCESS) { + if (esp_send_assoc_resp(hapd, sta_info->addr, WLAN_STATUS_SUCCESS, true, subtype) != WLAN_STATUS_SUCCESS) { wpa_printf(MSG_ERROR, "failed to send assoc response " MACSTR, MAC2STR(sta_info->addr)); return -1; } @@ -296,7 +319,7 @@ static int check_n_add_wps_sta(struct hostapd_data *hapd, struct sta_info *sta_i } #endif -static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len,u8 *rsnxe, u8 rsnxe_len, bool *pmf_enable, int subtype) +static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8 *rsnxe, u8 rsnxe_len, bool *pmf_enable, int subtype, uint8_t *pairwise_cipher) { struct sta_info *sta_info = NULL; struct hostapd_data *hapd = hostapd_get_hapd_data(); @@ -305,35 +328,81 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len,u8 goto fail; } - if (*sta && !esp_wifi_ap_is_sta_sae_reauth_node(bssid)) { - ap_free_sta(hapd, *sta); + if (*sta) { + struct sta_info *old_sta = *sta; +#ifdef CONFIG_SAE + if (old_sta->lock && os_semphr_take(old_sta->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, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) { + goto fail; + } + return false; + } +#endif /* CONFIG_SAE */ + if (!esp_wifi_ap_is_sta_sae_reauth_node(bssid)) { + ap_free_sta(hapd, old_sta); + *sta = NULL; + } +#ifdef CONFIG_SAE + else if (old_sta && old_sta->lock) { + sta_info = old_sta; + goto process_old_sta; + } +#endif /* CONFIG_SAE */ } - sta_info = ap_sta_add(hapd, bssid); + sta_info = ap_get_sta(hapd, bssid); if (!sta_info) { - wpa_printf(MSG_ERROR, "failed to add station " MACSTR, MAC2STR(bssid)); - goto fail; + sta_info = ap_sta_add(hapd,bssid); + if (!sta_info) { + wpa_printf(MSG_ERROR, "failed to add station " MACSTR, MAC2STR(bssid)); + 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, bssid, WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY, rsnxe ? false : true, subtype) != WLAN_STATUS_SUCCESS) { + goto fail; + } + return false; + } + +process_old_sta: +#endif /* CONFIG_SAE */ + + #ifdef CONFIG_WPS_REGISTRAR if (check_n_add_wps_sta(hapd, sta_info, wpa_ie, wpa_ie_len, pmf_enable, subtype) == 0) { if (sta_info->eapol_sm) { - *sta = sta_info; - return true; + goto done; } } else { goto fail; } #endif - if (wpa_ap_join(sta_info, bssid, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len, pmf_enable, subtype)) { - *sta = sta_info; - return true; + if (wpa_ap_join(sta_info, bssid, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len, pmf_enable, subtype, pairwise_cipher)) { + goto done; + } else { + goto fail; + } +done: + *sta = sta_info; +#ifdef CONFIG_SAE + if (sta_info->lock) { + os_semphr_give(sta_info->lock); } +#endif /* CONFIG_SAE */ + return true; fail: - if (sta_info) { - ap_free_sta(hapd, sta_info); - } +#ifdef CONFIG_SAE + if (sta_info && sta_info->lock) { + os_semphr_give(sta_info->lock); + } +#endif /* CONFIG_SAE */ + esp_wifi_ap_deauth_internal(bssid, WLAN_REASON_PREV_AUTH_NOT_VALID); return false; } #endif @@ -374,7 +443,6 @@ int esp_supplicant_init(void) wpa_cb->wpa_config_bss = NULL;//wpa_config_bss; wpa_cb->wpa_michael_mic_failure = wpa_michael_mic_failure; wpa_cb->wpa_config_done = wpa_config_done; - wpa_cb->wpa_sta_set_ap_rsnxe = wpa_sm_set_ap_rsnxe; esp_wifi_register_wpa3_ap_cb(wpa_cb); esp_wifi_register_wpa3_cb(wpa_cb); @@ -400,7 +468,14 @@ int esp_supplicant_init(void) int esp_supplicant_deinit(void) { esp_supplicant_common_deinit(); + esp_supplicant_unset_all_appie(); eloop_destroy(); wpa_cb = NULL; return esp_wifi_unregister_wpa_cb_internal(); } + +esp_err_t esp_supplicant_disable_pmk_caching(bool disable) +{ + g_wpa_pmk_caching_disabled = disable; + return ESP_OK; +} diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c index 4f1da5d792..189c7aa965 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -93,12 +93,36 @@ int hostapd_send_eapol(const u8 *source, const u8 *sta_addr, } -void wpa_supplicant_transition_disable(void *sm, u8 bitmap) +static void disable_wpa_wpa2(void) +{ + esp_wifi_sta_disable_wpa2_authmode_internal(); +} + +void wpa_supplicant_transition_disable(struct wpa_sm *sm, u8 bitmap) { wpa_printf(MSG_DEBUG, "TRANSITION_DISABLE %02x", bitmap); - if (bitmap & TRANSITION_DISABLE_WPA3_PERSONAL) { - esp_wifi_sta_disable_wpa2_authmode_internal(); + if ((bitmap & TRANSITION_DISABLE_WPA3_PERSONAL) && + wpa_key_mgmt_sae(sm->key_mgmt)) { + disable_wpa_wpa2(); + } + + if ((bitmap & TRANSITION_DISABLE_SAE_PK) && + wpa_key_mgmt_sae(sm->key_mgmt)) { + wpa_printf(MSG_INFO, + "SAE-PK: SAE authentication without PK disabled based on AP notification"); + disable_wpa_wpa2(); + esp_wifi_enable_sae_pk_only_mode_internal(); + } + + if ((bitmap & TRANSITION_DISABLE_WPA3_ENTERPRISE) && + wpa_key_mgmt_wpa_ieee8021x(sm->key_mgmt)) { + disable_wpa_wpa2(); + } + + if ((bitmap & TRANSITION_DISABLE_ENHANCED_OPEN) && + wpa_key_mgmt_owe(sm->key_mgmt)) { + esp_wifi_sta_disable_owe_trans_internal(); } } diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h index 11f5b3ddff..e18ad28cdd 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpas_glue.h @@ -31,7 +31,7 @@ void wpa_free_eapol(u8 *buffer); int wpa_ether_send(void *ctx, const u8 *dest, u16 proto, const u8 *data, size_t data_len); -void wpa_supplicant_transition_disable(void *sm, u8 bitmap); +void wpa_supplicant_transition_disable(struct wpa_sm *sm, u8 bitmap); int hostapd_send_eapol(const u8 *source, const u8 *sta_addr, const u8 *data, size_t data_len); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index b3aa227a07..35a8b123c0 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,14 +26,15 @@ #include "esp_err.h" #include "esp_private/wifi.h" #include "esp_wps_i.h" +#include "esp_dpp_i.h" #include "esp_wps.h" #include "eap_common/eap_wsc_common.h" #include "esp_wpas_glue.h" const char *wps_model_number = CONFIG_IDF_TARGET; -void *s_wps_api_lock = NULL; /* Used in WPS public API only, never be freed */ -void *s_wps_api_sem = NULL; /* Sync semaphore used between WPS publi API caller task and WPS task */ +void *s_wps_api_lock = NULL; /* Used in WPS/WPS-REG public API only, never be freed */ +void *s_wps_api_sem = NULL; /* Sync semaphore used between WPS/WPS-REG public API caller task and WPS task, never be freed */ bool s_wps_enabled = false; #ifdef USE_WPS_TASK struct wps_rx_param { @@ -44,11 +45,7 @@ struct wps_rx_param { }; static STAILQ_HEAD(,wps_rx_param) s_wps_rxq; -typedef struct { - void *arg; - int ret; /* return value */ -} wps_ioctl_param_t; - +struct wps_sm_funcs *s_wps_sm_cb = NULL; static void *s_wps_task_hdl = NULL; static void *s_wps_queue = NULL; static void *s_wps_data_lock = NULL; @@ -157,9 +154,11 @@ void wps_task(void *pvParameters ) if (e->sig == SIG_WPS_ENABLE) { param->ret = wifi_wps_enable_internal((esp_wps_config_t *)(param->arg)); } else if (e->sig == SIG_WPS_DISABLE) { + DATA_MUTEX_TAKE(); param->ret = wifi_wps_disable_internal(); del_task = true; s_wps_task_hdl = NULL; + DATA_MUTEX_GIVE(); } else { param->ret = wifi_station_wps_start(); } @@ -220,6 +219,12 @@ int wps_post(uint32_t sig, uint32_t par) wpa_printf(MSG_DEBUG, "wps post: sig=%" PRId32 " cnt=%d", sig, s_wps_sig_cnt[sig]); DATA_MUTEX_TAKE(); + + if (!s_wps_task_hdl) { + wpa_printf(MSG_DEBUG, "wps post: sig=%" PRId32 " failed as wps task has been deinited", sig); + DATA_MUTEX_GIVE(); + return ESP_FAIL; + } if (s_wps_sig_cnt[sig]) { wpa_printf(MSG_DEBUG, "wps post: sig=%" PRId32 " processing", sig); DATA_MUTEX_GIVE(); @@ -333,6 +338,23 @@ wps_build_ic_appie_wps_ar(void) } } +static bool ap_supports_sae(struct wps_scan_ie *scan) +{ + struct wpa_ie_data rsn_info; + + if (!scan->rsn) { + return false; + } + + wpa_parse_wpa_ie_rsn(scan->rsn, scan->rsn[1] + 2, &rsn_info); + + if (rsn_info.key_mgmt & WPA_KEY_MGMT_SAE) { + return true; + } + + return false; +} + static bool wps_parse_scan_result(struct wps_scan_ie *scan) { @@ -402,10 +424,17 @@ wps_parse_scan_result(struct wps_scan_ie *scan) os_memcpy(sm->ssid[0], (char *)&scan->ssid[2], (int)scan->ssid[1]); sm->ssid_len[0] = scan->ssid[1]; if (scan->bssid && memcmp(sm->bssid, scan->bssid, ETH_ALEN) != 0) { - wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR "\n", + wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR, MAC2STR(sm->bssid), MAC2STR(scan->bssid)); sm->discover_ssid_cnt++; os_memcpy(sm->bssid, scan->bssid, ETH_ALEN); + if (ap_supports_sae(scan)) { + wpa_printf(MSG_INFO, "AP supports SAE, get password in passphrase"); + sm->dev->config_methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY; + sm->wps->wps->config_methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY; + /* Reset assoc req, probe reset not needed */ + wps_build_ic_appie_wps_ar(); + } } wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->ssid); sm->channel = scan->chan; @@ -552,7 +581,7 @@ int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) int frag_len; u16 be_tot_len = 0; - if (!sm) { + if (!sm || !res) { return ESP_FAIL; } @@ -599,9 +628,7 @@ int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) return ESP_FAIL; } if (flag & WPS_MSG_FLAG_MORE) { - if (res) { - *res = WPS_FRAGMENT; - } + *res = WPS_FRAGMENT; return ESP_OK; } } else { //not frag msg @@ -619,13 +646,9 @@ int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL); - if (res) { - *res = wps_enrollee_process_msg(sm->wps, expd->opcode, wps_buf); - } else { - wps_enrollee_process_msg(sm->wps, expd->opcode, wps_buf); - } + *res = wps_enrollee_process_msg(sm->wps, expd->opcode, wps_buf); - if (res && *res == WPS_FAILURE) { + if (*res == WPS_FAILURE) { sm->state = WPA_FAIL; } @@ -668,7 +691,6 @@ int wps_send_wps_mX_rsp(u8 id) wpabuf_put_u8(eap_buf, 0x00); /* flags */ wpabuf_put_data(eap_buf, wpabuf_head_u8(wps_buf), wpabuf_len(wps_buf)); - wpabuf_free(wps_buf); buf = wps_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head_u8(eap_buf), wpabuf_len(eap_buf), (size_t *)&len, NULL); @@ -823,6 +845,13 @@ int wps_finish(void) return ret; } +static void wps_sm_notify_deauth(void) +{ + if (gWpsSm && gWpsSm->wps->state != WPS_FINISHED) { + wps_stop_process(WPS_FAIL_REASON_RECV_DEAUTH); + } +} + /* Add current ap to discard ap list */ void wps_add_discard_ap(u8 *bssid) { @@ -1013,24 +1042,22 @@ int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len) break; case EAP_TYPE_EXPANDED: wpa_printf(MSG_DEBUG, "=========expanded plen[%" PRId32 "], %d===========", plen, sizeof(*ehdr)); - if (ehdr->identifier == sm->current_identifier) { - ret = 0; - wpa_printf(MSG_DEBUG, "wps: ignore overlap identifier"); - goto out; - } sm->current_identifier = ehdr->identifier; tmp = (u8 *)(ehdr + 1) + 1; ret = wps_process_wps_mX_req(tmp, plen - sizeof(*ehdr) - 1, &res); - if (ret == 0 && res != WPS_FAILURE && res != WPS_FRAGMENT) { + if (res == WPS_FRAGMENT) { + wpa_printf(MSG_DEBUG, "wps frag, silently exit", res); + ret = ESP_OK; + break; + } + if (ret == ESP_OK && res != WPS_FAILURE) { ret = wps_send_wps_mX_rsp(ehdr->identifier); - if (ret == 0) { + + if (ret == ESP_OK) { wpa_printf(MSG_DEBUG, "sm->wps->state = %d", sm->wps->state); wps_start_msg_timer(); } - } else if (ret == 0 && res == WPS_FRAGMENT) { - wpa_printf(MSG_DEBUG, "wps frag, continue..."); - ret = ESP_OK; } else { ret = ESP_FAIL; } @@ -1372,6 +1399,11 @@ int wps_init_cfg_pin(struct wps_config *cfg) return 0; } +struct wps_sm_funcs* wps_get_wps_sm_cb(void) +{ + return s_wps_sm_cb; +} + static int wifi_station_wps_init(const esp_wps_config_t *config) { struct wps_funcs *wps_cb; @@ -1453,6 +1485,12 @@ static int wifi_station_wps_init(const esp_wps_config_t *config) wps_cb->wps_start_pending = wps_start_pending; esp_wifi_set_wps_cb_internal(wps_cb); + s_wps_sm_cb = os_malloc(sizeof(struct wps_sm_funcs)); + if (s_wps_sm_cb == NULL) { + goto _err; + } + s_wps_sm_cb->wps_sm_notify_deauth = wps_sm_notify_deauth; + return ESP_OK; _err: @@ -1526,6 +1564,11 @@ wifi_station_wps_deinit(void) wps_deinit(sm->wps); sm->wps = NULL; } + if (s_wps_sm_cb) { + os_free(s_wps_sm_cb); + s_wps_sm_cb = NULL; + } + os_free(gWpsSm); gWpsSm = NULL; @@ -1558,9 +1601,13 @@ wifi_wps_scan_done(void *arg, ETS_STATUS status) } else if (sm->discover_ssid_cnt == 0) { wps_set_status(WPS_STATUS_SCANNING); } else { - wpa_printf(MSG_INFO, "PBC session overlap!"); - wps_set_status(WPS_STATUS_DISABLE); - esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, 0, 0, OS_BLOCK); + if (wps_get_type() == WPS_TYPE_PBC) { + wpa_printf(MSG_INFO, "PBC session overlap!"); + wps_set_status(WPS_STATUS_DISABLE); + esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, 0, 0, OS_BLOCK); + } else { + wps_set_status(WPS_STATUS_PENDING); + } } wpa_printf(MSG_DEBUG, "wps scan_done discover_ssid_cnt = %d", sm->discover_ssid_cnt); @@ -1690,12 +1737,6 @@ int wps_task_deinit(void) wps_rxq_deinit(); } - if (s_wps_data_lock) { - os_semphr_delete(s_wps_data_lock); - s_wps_data_lock = NULL; - wpa_printf(MSG_DEBUG, "wps task deinit: free data lock"); - } - return ESP_OK; } @@ -1707,10 +1748,12 @@ int wps_task_init(void) */ wps_task_deinit(); - s_wps_data_lock = os_recursive_mutex_create(); if (!s_wps_data_lock) { - wpa_printf(MSG_ERROR, "wps task init: failed to alloc data lock"); - goto _wps_no_mem; + s_wps_data_lock = os_recursive_mutex_create(); + if (!s_wps_data_lock) { + wpa_printf(MSG_ERROR, "wps task init: failed to alloc data lock"); + goto _wps_no_mem; + } } s_wps_api_sem = os_semphr_create(1, 0); @@ -1807,6 +1850,11 @@ int esp_wifi_wps_enable(const esp_wps_config_t *config) return ESP_ERR_WIFI_MODE; } + if (is_dpp_enabled()) { + wpa_printf(MSG_ERROR, "wps enabled failed since DPP is initialized"); + return ESP_FAIL; + } + API_MUTEX_TAKE(); if (s_wps_enabled) { if (sm && os_memcmp(sm->identity, WSC_ID_REGISTRAR, sm->identity_len) == 0) { @@ -1844,6 +1892,11 @@ int esp_wifi_wps_enable(const esp_wps_config_t *config) #endif } +bool is_wps_enabled(void) +{ + return s_wps_enabled; +} + int wifi_wps_enable_internal(const esp_wps_config_t *config) { int ret = 0; @@ -1854,7 +1907,10 @@ int wifi_wps_enable_internal(const esp_wps_config_t *config) wpa_printf(MSG_ERROR, "wps enable: invalid wps type"); return ESP_ERR_WIFI_WPS_TYPE; } - + if (is_dpp_enabled()) { + wpa_printf(MSG_ERROR, "wps enabled failed since DPP is initialized"); + return ESP_FAIL; + } wpa_printf(MSG_DEBUG, "Set factory information."); ret = wps_set_factory_info(config); if (ret != 0) { @@ -1880,6 +1936,11 @@ int wifi_wps_enable_internal(const esp_wps_config_t *config) int wifi_wps_disable_internal(void) { wps_set_status(WPS_STATUS_DISABLE); + + /* Call wps_delete_timer to delete all WPS timer, no timer will call wps_post() + * to post message to wps_task once this function returns. + */ + wps_delete_timer(); wifi_station_wps_deinit(); return ESP_OK; } @@ -1907,11 +1968,6 @@ int esp_wifi_wps_disable(void) wpa_printf(MSG_INFO, "wifi_wps_disable"); wps_set_type(WPS_TYPE_DISABLE); /* Notify WiFi task */ - /* Call wps_delete_timer to delete all WPS timer, no timer will call wps_post() - * to post message to wps_task once this function returns. - */ - wps_delete_timer(); - #ifdef USE_WPS_TASK ret = wps_post_block(SIG_WPS_DISABLE, 0); #else diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h index 5dd055ad4d..e7d030f37a 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,6 +27,19 @@ enum wps_sig_type { SIG_WPS_NUM, //10 }; #endif + +enum wps_reg_sig_type { + SIG_WPS_REG_ENABLE = 1, //1 + SIG_WPS_REG_DISABLE, //2 + SIG_WPS_REG_START, //3 + SIG_WPS_REG_MAX, //4 +}; + +typedef struct { + void *arg; + int ret; /* return value */ +} wps_ioctl_param_t; + #ifdef ESP_SUPPLICANT enum wps_sm_state{ WAIT_START, @@ -106,6 +119,11 @@ int wps_dev_deinit(struct wps_device_data *dev); int wps_dev_init(void); int wps_set_factory_info(const esp_wps_config_t *config); +struct wps_sm_funcs { + void (*wps_sm_notify_deauth)(void); +}; + +struct wps_sm_funcs* wps_get_wps_sm_cb(void); static inline int wps_get_type(void) { return esp_wifi_get_wps_type_internal(); @@ -125,5 +143,7 @@ static inline int wps_set_status(uint32_t status) { return esp_wifi_set_wps_status_internal(status); } + +bool is_wps_enabled(void); int wps_init_cfg_pin(struct wps_config *cfg); void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx); diff --git a/components/wpa_supplicant/linker.lf b/components/wpa_supplicant/linker.lf new file mode 100644 index 0000000000..e8dd3f2d9d --- /dev/null +++ b/components/wpa_supplicant/linker.lf @@ -0,0 +1,5 @@ +[mapping:wpa_supplicant] +archive: libwpa_supplicant.a +entries: + if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (extram_bss) diff --git a/components/wpa_supplicant/src/ap/ap_config.h b/components/wpa_supplicant/src/ap/ap_config.h index 3d6d6af94c..486d802a11 100644 --- a/components/wpa_supplicant/src/ap/ap_config.h +++ b/components/wpa_supplicant/src/ap/ap_config.h @@ -338,7 +338,7 @@ struct hostapd_config { char country[3]; /* first two octets: country code as described in * ISO/IEC 3166-1. Third octet: * ' ' (ascii 32): all environments - * 'O': Outdoor environemnt only + * 'O': Outdoor environment only * 'I': Indoor environment only */ @@ -384,7 +384,7 @@ int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf); struct sta_info; bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len,uint8_t *rsnxe, uint8_t rsnxe_len, - bool *pmf_enable, int subtype); + bool *pmf_enable, int subtype, uint8_t *pairwise_cipher); bool wpa_ap_remove(u8* bssid); #endif /* HOSTAPD_CONFIG_H */ diff --git a/components/wpa_supplicant/src/ap/ieee802_11.c b/components/wpa_supplicant/src/ap/ieee802_11.c index 2b2b2c09a2..e8dbc7f067 100644 --- a/components/wpa_supplicant/src/ap/ieee802_11.c +++ b/components/wpa_supplicant/src/ap/ieee802_11.c @@ -559,7 +559,7 @@ int handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, } if (sae_check_confirm(sta->sae, buf, len) < 0) { - resp = WLAN_STATUS_UNSPECIFIED_FAILURE; + resp = WLAN_STATUS_CHALLENGE_FAIL; goto reply; } sta->sae->rc = peer_send_confirm; @@ -569,7 +569,6 @@ int handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, } else { wpa_printf(MSG_ERROR, "unexpected SAE authentication transaction %u (status=%u )", auth_transaction, status); if (status != WLAN_STATUS_SUCCESS) { - resp = -1; goto remove_sta; } resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index 9b2680c8c1..513ec9fa82 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -217,10 +217,10 @@ int wpa_auth_for_each_sta(struct wpa_authenticator *wpa_auth, } static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth, - const u8 *addr) + const u8 *addr, u16 reason) { wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr)); - esp_wifi_ap_deauth_internal((uint8_t*)addr, WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT); + esp_wifi_ap_deauth_internal((uint8_t*)addr, reason); return; } @@ -488,6 +488,7 @@ static void wpa_free_sta_sm(struct wpa_state_machine *sm) wpa_printf( MSG_DEBUG, "wpa_free_sta_sm: free eapol=%p\n", sm->last_rx_eapol_key); os_free(sm->last_rx_eapol_key); os_free(sm->wpa_ie); + os_free(sm->rsnxe); os_free(sm); } @@ -788,7 +789,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *s * strong random numbers. Reject the first 4-way * handshake(s) and collect some entropy based on the * information from it. Once enough entropy is - * available, the next atempt will trigger GMK/Key + * available, the next attempt will trigger GMK/Key * Counter update and the station will be allowed to * continue. */ @@ -796,7 +797,8 @@ void wpa_receive(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *s "collect more entropy for random number " "generation"); random_mark_pool_ready(); - wpa_sta_disconnect(wpa_auth, sm->addr); + wpa_sta_disconnect(wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); return; } if (wpa_parse_kde_ies((u8 *) (key + 1), key_data_length, @@ -823,12 +825,14 @@ void wpa_receive(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *s wpa_hexdump(MSG_DEBUG, "WPA IE in msg 2/4", eapol_key_ie, eapol_key_ie_len); /* MLME-DEAUTHENTICATE.request */ - wpa_sta_disconnect(wpa_auth, sm->addr); + wpa_sta_disconnect(wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); return; } #ifdef CONFIG_IEEE80211R_AP if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) { - wpa_sta_disconnect(wpa_auth, sm->addr); + wpa_sta_disconnect(wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); return; } #endif /* CONFIG_IEEE80211R_AP */ @@ -862,6 +866,8 @@ void wpa_receive(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *s if (sm->PTK_valid && !sm->update_snonce) { if (wpa_verify_key_mic(sm->wpa_key_mgmt, &sm->PTK, data, data_len)) { + wpa_printf(MSG_INFO, + "received EAPOL-Key with invalid MIC"); return; } sm->MICVerified = TRUE; @@ -875,6 +881,8 @@ void wpa_receive(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *s memcpy(sm->req_replay_counter, key->replay_counter, WPA_REPLAY_COUNTER_LEN); } else { + wpa_printf(MSG_INFO, + "received EAPOL-Key request with invalid MIC"); return; } @@ -1358,9 +1366,14 @@ SM_STATE(WPA_PTK, INITIALIZE) SM_STATE(WPA_PTK, DISCONNECT) { + u16 reason = sm->disconnect_reason; + SM_ENTRY_MA(WPA_PTK, DISCONNECT, wpa_ptk); sm->Disconnect = FALSE; - wpa_sta_disconnect(sm->wpa_auth, sm->addr); + sm->disconnect_reason = 0; + if (!reason) + reason = WLAN_REASON_PREV_AUTH_NOT_VALID; + wpa_sta_disconnect(sm->wpa_auth, sm->addr, reason); } @@ -1430,7 +1443,7 @@ SM_STATE(WPA_PTK, AUTHENTICATION2) if (os_get_random(sm->ANonce, WPA_NONCE_LEN)) { wpa_printf( MSG_ERROR, "WPA: Failed to get random data for " "ANonce."); - wpa_sta_disconnect(sm->wpa_auth, sm->addr); + sm->Disconnect = true; return; } wpa_hexdump(MSG_DEBUG, "WPA: Assign ANonce", sm->ANonce, @@ -1644,11 +1657,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK, sm->last_rx_eapol_key, sm->last_rx_eapol_key_len) == 0) { - wpa_printf( MSG_DEBUG, "mic verify ok, pmk=%p", pmk); ok = 1; break; - } else { - wpa_printf( MSG_DEBUG, "mic verify fail, pmk=%p", pmk); } if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) || @@ -1659,6 +1669,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) } if (!ok) { + wpa_printf(MSG_INFO, "invalid MIC in msg 2/4 of 4-Way Handshake"); return; } @@ -1704,7 +1715,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) sm->rsnxe, sm->rsnxe_len); wpa_hexdump(MSG_DEBUG, "RSNXE in EAPOL-Key msg 2/4", kde.rsnxe, kde.rsnxe_len); - wpa_sta_disconnect(sm->wpa_auth, sm->addr); + wpa_sta_disconnect(sm->wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); return; } @@ -1949,7 +1961,8 @@ SM_STATE(WPA_PTK, PTKINITDONE) int klen = wpa_cipher_key_len(sm->pairwise); if (wpa_auth_set_key(sm->wpa_auth, 0, alg, sm->addr, 0, sm->PTK.tk, klen)) { - wpa_sta_disconnect(sm->wpa_auth, sm->addr); + wpa_sta_disconnect(sm->wpa_auth, sm->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); return; } /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ @@ -2061,6 +2074,8 @@ SM_STEP(WPA_PTK) SM_ENTER(WPA_PTK, PTKCALCNEGOTIATING); else if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { + sm->disconnect_reason = + WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT; SM_ENTER(WPA_PTK, DISCONNECT); } else if (sm->TimeoutEvt) SM_ENTER(WPA_PTK, PTKSTART); @@ -2085,6 +2100,8 @@ SM_STEP(WPA_PTK) SM_ENTER(WPA_PTK, PTKINITDONE); else if (sm->TimeoutCtr > (int) dot11RSNAConfigPairwiseUpdateCount) { + sm->disconnect_reason = + WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT; SM_ENTER(WPA_PTK, DISCONNECT); } else if (sm->TimeoutEvt) SM_ENTER(WPA_PTK, PTKINITNEGOTIATING); @@ -2190,6 +2207,7 @@ SM_STATE(WPA_PTK_GROUP, KEYERROR) sm->group->GKeyDoneStations--; sm->GUpdateStationKeys = FALSE; sm->Disconnect = TRUE; + sm->disconnect_reason = WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT; } @@ -2542,7 +2560,7 @@ void wpa_deinit(struct wpa_authenticator *wpa_auth) #ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len, uint8_t *rsnxe, uint8_t rsnxe_len, - bool *pmf_enable, int subtype) + bool *pmf_enable, int subtype, uint8_t *pairwise_cipher) { struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal(); enum wpa_validate_result status_code = WPA_IE_OK; @@ -2583,7 +2601,7 @@ bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, omit_rsnxe = true; } - if (esp_send_assoc_resp(hapd, sta, bssid, resp, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) { + if (esp_send_assoc_resp(hapd, bssid, resp, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) { resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; } @@ -2593,6 +2611,7 @@ bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, //Check whether AP uses Management Frame Protection for this connection *pmf_enable = wpa_auth_uses_mfp(sta->wpa_sm); + *pairwise_cipher = GET_BIT_POSITION(sta->wpa_sm->pairwise); } wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); @@ -2601,21 +2620,6 @@ bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, return true; } -#ifdef CONFIG_WPS_REGISTRAR -static void ap_free_sta_timeout(void *ctx, void *data) -{ - struct hostapd_data *hapd = (struct hostapd_data *) ctx; - u8 *addr = (u8 *) data; - struct sta_info *sta = ap_get_sta(hapd, addr); - - if (sta) { - ap_free_sta(hapd, sta); - } - - os_free(addr); -} -#endif - bool wpa_ap_remove(u8* bssid) { struct hostapd_data *hapd = hostapd_get_hapd_data(); @@ -2635,22 +2639,9 @@ bool wpa_ap_remove(u8* bssid) } else { sta->remove_pending = true; } - return true; + return true; } #endif /* CONFIG_SAE */ - -#ifdef CONFIG_WPS_REGISTRAR - wpa_printf(MSG_DEBUG, "wps_status=%d", wps_get_status()); - if (wps_get_status() == WPS_STATUS_PENDING) { - u8 *addr = os_malloc(ETH_ALEN); - - if (!addr) { - return false; - } - os_memcpy(addr, sta->addr, ETH_ALEN); - eloop_register_timeout(0, 10000, ap_free_sta_timeout, hapd, addr); - } else -#endif ap_free_sta(hapd, sta); return true; diff --git a/components/wpa_supplicant/src/ap/wpa_auth_i.h b/components/wpa_supplicant/src/ap/wpa_auth_i.h index 672cc09425..2516b34f69 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth_i.h +++ b/components/wpa_supplicant/src/ap/wpa_auth_i.h @@ -47,6 +47,7 @@ struct wpa_state_machine { Boolean AuthenticationRequest; Boolean ReAuthenticationRequest; Boolean Disconnect; + u16 disconnect_reason; /* specific reason code to use with Disconnect */ int TimeoutCtr; int GTimeoutCtr; Boolean TimeoutEvt; diff --git a/components/wpa_supplicant/src/ap/wps_hostapd.c b/components/wpa_supplicant/src/ap/wps_hostapd.c index 3210438f94..a2b7ecc6dd 100644 --- a/components/wpa_supplicant/src/ap/wps_hostapd.c +++ b/components/wpa_supplicant/src/ap/wps_hostapd.c @@ -321,6 +321,14 @@ int hostapd_init_wps(struct hostapd_data *hapd, struct wps_data *wps_data, struc return -1; } +#ifdef ESP_SUPPLICANT +static int ap_sta_server_sm_deinit(struct hostapd_data *hapd, + struct sta_info *sta, void *ctx) +{ + ieee802_1x_free_station(hapd, sta); + return 0; +} +#endif /* ESP_SUPPLICANT */ void hostapd_deinit_wps(struct hostapd_data *hapd) { @@ -332,6 +340,11 @@ void hostapd_deinit_wps(struct hostapd_data *hapd) } wps_registrar_deinit(hapd->wps->registrar); hapd->wps->registrar = NULL; + +#ifdef ESP_SUPPLICANT + ap_for_each_sta(hapd, ap_sta_server_sm_deinit, NULL); +#endif /* ESP_SUPPLICANT */ + eap_server_unregister_methods(); hapd->wps = NULL; hostapd_wps_clear_ies(hapd, 1); diff --git a/components/wpa_supplicant/src/common/bss.c b/components/wpa_supplicant/src/common/bss.c index 5868328c54..167fcc96ff 100644 --- a/components/wpa_supplicant/src/common/bss.c +++ b/components/wpa_supplicant/src/common/bss.c @@ -225,11 +225,11 @@ wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, * to filter out the obsolete results here to make sure only the * most current BSS information remains in the table. */ - wpa_printf(MSG_DEBUG, "BSS: " MACSTR + wpa_printf(MSG_MSGDUMP, "BSS: " MACSTR " has multiple entries in the scan results - select the most current one", MAC2STR(bss->bssid)); calculate_update_time(fetch_time, res->age, &update_time); - wpa_printf(MSG_DEBUG, + wpa_printf(MSG_MSGDUMP, "Accept this BSS entry since it looks more current than the previous update"); } diff --git a/components/wpa_supplicant/src/common/defs.h b/components/wpa_supplicant/src/common/defs.h index 2524e5b361..6799370dec 100644 --- a/components/wpa_supplicant/src/common/defs.h +++ b/components/wpa_supplicant/src/common/defs.h @@ -51,6 +51,7 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean; static inline int wpa_key_mgmt_wpa_ieee8021x(int akm) { +#ifdef CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT return !!(akm & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_CCKM | @@ -58,6 +59,9 @@ static inline int wpa_key_mgmt_wpa_ieee8021x(int akm) WPA_KEY_MGMT_IEEE8021X_SHA256 | WPA_KEY_MGMT_IEEE8021X_SUITE_B | WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)); +#else + return 0; +#endif } static inline int wpa_key_mgmt_wpa_psk(int akm) diff --git a/components/wpa_supplicant/src/common/dpp.c b/components/wpa_supplicant/src/common/dpp.c index a2f075b9f7..9d3507ad3a 100644 --- a/components/wpa_supplicant/src/common/dpp.c +++ b/components/wpa_supplicant/src/common/dpp.c @@ -43,7 +43,7 @@ struct dpp_global { static const struct dpp_curve_params dpp_curves[] = { /* The mandatory to support and the default NIST P-256 curve needs to * be the first entry on this list. */ - { "sec256r1", 32, 32, 16, 32, "P-256", 19, "ES256" }, + { "secp256r1", 32, 32, 16, 32, "P-256", 19, "ES256" }, { "secp384r1", 48, 48, 24, 48, "P-384", 20, "ES384" }, { "secp521r1", 64, 64, 32, 66, "P-521", 21, "ES512" }, { "brainpoolP256r1", 32, 32, 16, 32, "BP-256", 28, "BS256" }, @@ -4669,7 +4669,8 @@ static struct crypto_key * dpp_parse_jwk(struct json_token *jwk, { struct json_token *token; const struct dpp_curve_params *curve; - struct wpabuf *x = NULL, *y = NULL, *a = NULL; + struct wpabuf *x = NULL, *y = NULL; + unsigned char *a = NULL; struct crypto_ec_group *group; struct crypto_key *pkey = NULL; size_t len; @@ -4731,17 +4732,19 @@ static struct crypto_key * dpp_parse_jwk(struct json_token *jwk, goto fail; } - len = wpabuf_len(x); - a = wpabuf_concat(x, y); - pkey = crypto_ec_set_pubkey_point(group, wpabuf_head(a), - len); + len = wpabuf_len(x) + wpabuf_len(y); + a = os_zalloc(len); + os_memcpy(a, wpabuf_head(x), wpabuf_len(x)); + os_memcpy(a + wpabuf_len(x), wpabuf_head(y), wpabuf_len(y)); + pkey = crypto_ec_set_pubkey_point(group, a, len); + crypto_ec_deinit((struct crypto_ec *)group); *key_curve = curve; fail: - wpabuf_free(a); wpabuf_free(x); wpabuf_free(y); + os_free(a); return pkey; } diff --git a/components/wpa_supplicant/src/common/ieee802_11_defs.h b/components/wpa_supplicant/src/common/ieee802_11_defs.h index 8d5f3aea2b..3c7eab6a44 100644 --- a/components/wpa_supplicant/src/common/ieee802_11_defs.h +++ b/components/wpa_supplicant/src/common/ieee802_11_defs.h @@ -261,6 +261,7 @@ #define WLAN_RSNX_CAPAB_SAE_H2E 5 #define WLAN_RSNX_CAPAB_SAE_PK 6 +#define WLAN_EXT_CAPAB_20_40_COEX 0 #define WLAN_EXT_CAPAB_BSS_TRANSITION 19 /* Action frame categories (IEEE Std 802.11-2016, 9.4.1.11, Table 9-76) */ diff --git a/components/wpa_supplicant/src/common/rrm.c b/components/wpa_supplicant/src/common/rrm.c index dc7a2aec25..085f52facb 100644 --- a/components/wpa_supplicant/src/common/rrm.c +++ b/components/wpa_supplicant/src/common/rrm.c @@ -150,12 +150,9 @@ int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s, /* Refuse if there's a live request */ if (wpa_s->rrm.notify_neighbor_rep) { - wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL); -#if 0 wpa_dbg(wpa_s, MSG_DEBUG, "RRM: Currently handling previous Neighbor Report."); return -EBUSY; -#endif } /* 3 = action category + action code + dialog token */ diff --git a/components/wpa_supplicant/src/common/wpa_common.c b/components/wpa_supplicant/src/common/wpa_common.c index 05e00463aa..8cfc1fec83 100644 --- a/components/wpa_supplicant/src/common/wpa_common.c +++ b/components/wpa_supplicant/src/common/wpa_common.c @@ -409,7 +409,7 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len, data->num_pmkid = 0; data->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC; - wpa_hexdump(MSG_DEBUG, "rsn_ie", rsn_ie, rsn_ie_len); + wpa_hexdump(MSG_MSGDUMP, "rsn_ie", rsn_ie, rsn_ie_len); if (rsn_ie_len == 0) { /* No RSN IE - fail silently */ return -1; diff --git a/components/wpa_supplicant/src/common/wpa_common.h b/components/wpa_supplicant/src/common/wpa_common.h index 4462c81f00..92f5c140d7 100644 --- a/components/wpa_supplicant/src/common/wpa_common.h +++ b/components/wpa_supplicant/src/common/wpa_common.h @@ -325,6 +325,9 @@ struct rsn_rdie { /* WFA Transition Disable KDE (using OUI_WFA) */ /* Transition Disable Bitmap bits */ #define TRANSITION_DISABLE_WPA3_PERSONAL BIT(0) +#define TRANSITION_DISABLE_SAE_PK BIT(1) +#define TRANSITION_DISABLE_WPA3_ENTERPRISE BIT(2) +#define TRANSITION_DISABLE_ENHANCED_OPEN BIT(3) #ifdef CONFIG_IEEE80211R int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, diff --git a/components/wpa_supplicant/src/crypto/ccmp.c b/components/wpa_supplicant/src/crypto/ccmp.c index 3b66d5fc18..9b1cfa0e9d 100644 --- a/components/wpa_supplicant/src/crypto/ccmp.c +++ b/components/wpa_supplicant/src/crypto/ccmp.c @@ -157,8 +157,8 @@ u8 * ccmp_decrypt(const u8 *tk, const u8 *hdr, os_memset(aad, 0, sizeof(aad)); ccmp_aad_nonce((const struct ieee80211_hdr *)hdr, data, aad, &aad_len, nonce); - wpa_hexdump(MSG_DEBUG, "CCMP AAD", aad, aad_len); - wpa_hexdump(MSG_DEBUG, "CCMP nonce", nonce, 13); + wpa_hexdump(MSG_MSGDUMP, "CCMP AAD", aad, aad_len); + wpa_hexdump(MSG_MSGDUMP, "CCMP nonce", nonce, 13); #ifdef ESPRESSIF_USE if (espnow_pkt) { @@ -167,11 +167,11 @@ u8 * ccmp_decrypt(const u8 *tk, const u8 *hdr, } #endif if (aes_ccm_ad(tk, 16, nonce, tag_len, data + 8, mlen, aad, aad_len, - data + 8 + mlen, plain) < 0) { + data + 8 + mlen, plain) < 0) { os_free(plain); return NULL; } - wpa_hexdump(MSG_DEBUG, "CCMP decrypted", plain, mlen); + wpa_hexdump(MSG_MSGDUMP, "CCMP decrypted", plain, mlen); *decrypted_len = mlen; return plain; @@ -219,17 +219,17 @@ u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, os_memset(aad, 0, sizeof(aad)); ccmp_aad_nonce(hdr, crypt + hdrlen, aad, &aad_len, nonce); - wpa_hexdump(MSG_DEBUG, "CCMP AAD", aad, aad_len); - wpa_hexdump(MSG_DEBUG, "CCMP nonce", nonce, 13); + wpa_hexdump(MSG_MSGDUMP, "CCMP AAD", aad, aad_len); + wpa_hexdump(MSG_MSGDUMP, "CCMP nonce", nonce, 13); - if (aes_ccm_ae(tk, 16, nonce, 8, frame + hdrlen, plen, aad, aad_len, + if (aes_ccm_ae(tk, 16, nonce, 8, frame + hdrlen + 8, plen, aad, aad_len, pos, pos + plen) < 0) { wpa_printf(MSG_ERROR, "aes ccm ae failed"); os_free(crypt); return NULL; } - wpa_hexdump(MSG_DEBUG, "CCMP encrypted", crypt + hdrlen + 8, plen); + wpa_hexdump(MSG_MSGDUMP, "CCMP encrypted", crypt + hdrlen + 8, plen); *encrypted_len = hdrlen + 8 + plen + 8; diff --git a/components/wpa_supplicant/src/crypto/crypto_ops.c b/components/wpa_supplicant/src/crypto/crypto_ops.c index 17c052c986..7b3f31a148 100644 --- a/components/wpa_supplicant/src/crypto/crypto_ops.c +++ b/components/wpa_supplicant/src/crypto/crypto_ops.c @@ -43,7 +43,7 @@ static int esp_aes_gmac(const u8 *key, size_t key_len, const u8 *iv, size_t iv_l #if CONFIG_GMAC return aes_gmac(key, key_len, iv, iv_len, aad, aad_len, tag); #else - return 0; + return -1; #endif } diff --git a/components/wpa_supplicant/src/eap_peer/eap_i.h b/components/wpa_supplicant/src/eap_peer/eap_i.h index 15cedbe1bf..fec7856714 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_i.h +++ b/components/wpa_supplicant/src/eap_peer/eap_i.h @@ -13,7 +13,6 @@ #include "eap.h" #include "eap_common.h" #include "eap_config.h" -#include "esp_wpa2.h" /* RFC 4137 - EAP Peer state machine */ diff --git a/components/wpa_supplicant/src/eap_peer/eap_peap.c b/components/wpa_supplicant/src/eap_peer/eap_peap.c index 53d4dc05d0..744a6bb6ae 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_peap.c +++ b/components/wpa_supplicant/src/eap_peer/eap_peap.c @@ -66,6 +66,7 @@ struct eap_peap_data { u8 cmk[20]; int soh; /* Whether IF-TNCCS-SOH (Statement of Health; Microsoft NAP) * is enabled. */ + enum { NO_AUTH, FOR_INITIAL, ALWAYS } phase2_auth; }; @@ -114,6 +115,19 @@ eap_peap_parse_phase1(struct eap_peap_data *data, wpa_printf(MSG_DEBUG, "EAP-PEAP: Require cryptobinding"); } + if (os_strstr(phase1, "phase2_auth=0")) { + data->phase2_auth = NO_AUTH; + wpa_printf(MSG_DEBUG, + "EAP-PEAP: Do not require Phase 2 authentication"); + } else if (os_strstr(phase1, "phase2_auth=1")) { + data->phase2_auth = FOR_INITIAL; + wpa_printf(MSG_DEBUG, + "EAP-PEAP: Require Phase 2 authentication for initial connection"); + } else if (os_strstr(phase1, "phase2_auth=2")) { + data->phase2_auth = ALWAYS; + wpa_printf(MSG_DEBUG, + "EAP-PEAP: Require Phase 2 authentication for all cases"); + } #ifdef EAP_TNC if (os_strstr(phase1, "tnc=soh2")) { data->soh = 2; @@ -145,6 +159,7 @@ eap_peap_init(struct eap_sm *sm) data->force_peap_version = -1; data->peap_outer_success = 2; data->crypto_binding = OPTIONAL_BINDING; + data->phase2_auth = FOR_INITIAL; if (config && config->phase1 && eap_peap_parse_phase1(data, config->phase1) < 0) { @@ -449,6 +464,19 @@ eap_tlv_validate_cryptobinding(struct eap_sm *sm, return 0; } +static bool peap_phase2_sufficient(struct eap_sm *sm, + struct eap_peap_data *data) +{ + if ((data->phase2_auth == ALWAYS || + (data->phase2_auth == FOR_INITIAL && + !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn) && + !data->ssl.client_cert_conf) || + data->phase2_eap_started) && + !data->phase2_eap_success) + return false; + return true; +} + /** * eap_tlv_process - Process a received EAP-TLV message and generate a response @@ -565,6 +593,11 @@ eap_tlv_process(struct eap_sm *sm, struct eap_peap_data *data, " - force failed Phase 2"); resp_status = EAP_TLV_RESULT_FAILURE; ret->decision = DECISION_FAIL; + } else if (!peap_phase2_sufficient(sm, data)) { + wpa_printf(MSG_INFO, + "EAP-PEAP: Server indicated Phase 2 success, but sufficient Phase 2 authentication has not been completed"); + resp_status = EAP_TLV_RESULT_FAILURE; + ret->decision = DECISION_FAIL; } else { resp_status = EAP_TLV_RESULT_SUCCESS; ret->decision = DECISION_UNCOND_SUCC; @@ -939,8 +972,7 @@ eap_peap_decrypt(struct eap_sm *sm, struct eap_peap_data *data, /* EAP-Success within TLS tunnel is used to indicate * shutdown of the TLS channel. The authentication has * been completed. */ - if (data->phase2_eap_started && - !data->phase2_eap_success) { + if (!peap_phase2_sufficient(sm, data)) { wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 " "Success used to indicate success, " "but Phase 2 EAP was not yet " @@ -1200,8 +1232,9 @@ static bool eap_peap_has_reauth_data(struct eap_sm *sm, void *priv) { struct eap_peap_data *data = priv; + return tls_connection_established(sm->ssl_ctx, data->ssl.conn) && - data->phase2_success; + data->phase2_success && data->phase2_auth != ALWAYS; } diff --git a/components/wpa_supplicant/src/eap_peer/eap_tls_common.c b/components/wpa_supplicant/src/eap_peer/eap_tls_common.c index d8ab2a3262..b3ebfa7362 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_tls_common.c +++ b/components/wpa_supplicant/src/eap_peer/eap_tls_common.c @@ -94,7 +94,7 @@ static void eap_tls_params_from_conf1(struct tls_connection_params *params, static int eap_tls_params_from_conf(struct eap_sm *sm, struct eap_ssl_data *data, struct tls_connection_params *params, - struct eap_peer_config *config) + struct eap_peer_config *config, int phase2) { os_memset(params, 0, sizeof(*params)); if (sm->workaround && data->eap_type != EAP_TYPE_FAST) { @@ -133,6 +133,12 @@ static int eap_tls_params_from_conf(struct eap_sm *sm, return -1; } + if (!phase2) + data->client_cert_conf = params->client_cert || + params->client_cert_blob || + params->private_key || + params->private_key_blob; + return 0; } @@ -210,7 +216,7 @@ int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, data->eap = sm; data->eap_type = eap_type; data->ssl_ctx = sm->ssl_ctx; - if (eap_tls_params_from_conf(sm, data, ¶ms, config) < 0) /* no phase2 */ + if (eap_tls_params_from_conf(sm, data, ¶ms, config, data->phase2) < 0) /* no phase2 */ return -1; if (eap_tls_init_connection(sm, data, config, ¶ms) < 0) diff --git a/components/wpa_supplicant/src/eap_peer/eap_tls_common.h b/components/wpa_supplicant/src/eap_peer/eap_tls_common.h index 1a5e0f89e4..50390c4ce0 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_tls_common.h +++ b/components/wpa_supplicant/src/eap_peer/eap_tls_common.h @@ -73,6 +73,11 @@ struct eap_ssl_data { * eap_type - EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) */ u8 eap_type; + + /** + * client_cert_conf: Whether client certificate has been configured + */ + bool client_cert_conf; }; diff --git a/components/wpa_supplicant/src/eap_server/eap_server_wsc.c b/components/wpa_supplicant/src/eap_server/eap_server_wsc.c index f3c4756257..653480efcc 100644 --- a/components/wpa_supplicant/src/eap_server/eap_server_wsc.c +++ b/components/wpa_supplicant/src/eap_server/eap_server_wsc.c @@ -103,6 +103,13 @@ static void eap_wsc_reset(struct eap_sm *sm, void *priv) wpabuf_free(data->out_buf); //wps_deinit(data->wps); os_free(data); +#ifdef ESP_SUPPLICANT + /* TODO: When wps-registrar is shifted in a separate task other than wifi task, + * call esp_wifi_ap_wps_disable() here instead of wifi_ap_wps_disable_internal() + * */ + extern int wifi_ap_wps_disable_internal(void); + wifi_ap_wps_disable_internal(); +#endif } diff --git a/components/wpa_supplicant/src/rsn_supp/wpa.c b/components/wpa_supplicant/src/rsn_supp/wpa.c index 5f56da1067..e4c26f8c23 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa.c +++ b/components/wpa_supplicant/src/rsn_supp/wpa.c @@ -35,6 +35,7 @@ #include "esp_common_i.h" #include "esp_owe_i.h" #include "common/sae.h" +#include "esp_eap_client_i.h" /** * eapol_sm_notify_eap_success - Notification of external EAP success trigger @@ -169,6 +170,7 @@ unsigned cipher_type_map_public_to_supp(wifi_cipher_type_t cipher) } } +#ifdef CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT static bool is_wpa2_enterprise_connection(void) { uint8_t authmode; @@ -184,6 +186,7 @@ static bool is_wpa2_enterprise_connection(void) return false; } +#endif /** * get_bssid - Get the current BSSID @@ -388,7 +391,6 @@ static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry, - static int wpa_supplicant_get_pmk(struct wpa_sm *sm, const unsigned char *src_addr, const u8 *pmkid) @@ -504,7 +506,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm, if (buf) { wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL, buf, buflen); - os_free(buf); + wpa_sm_free_eapol(buf); return -2; } @@ -653,6 +655,17 @@ 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) { + wpa_printf(MSG_INFO, "EAP Success has not been processed yet." + " Drop EAPOL message."); + return; + } + } +#endif + wpa_sm_set_state(WPA_FIRST_HALF_4WAY_HANDSHAKE); wpa_printf(MSG_DEBUG, "WPA 1/4-Way Handshake"); @@ -680,9 +693,11 @@ void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, if (res) goto failed; +#ifdef CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT if (is_wpa2_enterprise_connection()) { pmksa_cache_set_current(sm, NULL, sm->bssid, 0, 0); } +#endif if (sm->renew_snonce) { if (os_get_random(sm->snonce, WPA_NONCE_LEN)) { @@ -996,37 +1011,37 @@ int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, static int wpa_supplicant_install_igtk(struct wpa_sm *sm, const wifi_wpa_igtk_t *igtk) { - size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher); - u16 keyidx = WPA_GET_LE16(igtk->keyid); - - /* Detect possible key reinstallation */ - if (sm->igtk.igtk_len == len && - os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) { - wpa_printf(MSG_DEBUG, - "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)", - keyidx); - return 0; - } - - wpa_printf(MSG_DEBUG, - "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x", - keyidx, MAC2STR(igtk->pn)); - wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len); - if (keyidx > 4095) { - wpa_printf(MSG_WARNING, - "WPA: Invalid IGTK KeyID %d", keyidx); - return -1; - } - if (esp_wifi_set_igtk_internal(WIFI_IF_STA, igtk) < 0) { - wpa_printf(MSG_WARNING, - "WPA: Failed to configure IGTK to the driver"); - return -1; - } - - sm->igtk.igtk_len = len; - os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); - - return 0; + size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher); + u16 keyidx = WPA_GET_LE16(igtk->keyid); + + /* Detect possible key reinstallation */ + if (sm->igtk.igtk_len == len && + os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) { + wpa_printf(MSG_DEBUG, + "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)", + keyidx); + return 0; + } + + wpa_printf(MSG_DEBUG, + "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x", + keyidx, MAC2STR(igtk->pn)); + wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len); + + if (esp_wifi_set_igtk_internal(WIFI_IF_STA, igtk) < 0) { + if (keyidx > 4095) { + wpa_printf(MSG_WARNING, + "WPA: Invalid IGTK KeyID %d", keyidx); + } + wpa_printf(MSG_WARNING, + "WPA: Failed to configure IGTK to the driver"); + return -1; + } + + sm->igtk.igtk_len = len; + os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); + + return 0; } #endif /* CONFIG_IEEE80211W */ @@ -2341,6 +2356,7 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher, sm->ap_notify_completed_rsne = esp_wifi_sta_is_ap_notify_completed_rsne_internal(); sm->use_ext_key_id = (sm->proto == WPA_PROTO_WPA); pmksa_cache_clear_current(sm); + sm->sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal(WIFI_IF_STA); struct rsn_pmksa_cache_entry *pmksa = NULL; if (use_pmk_cache) { @@ -2426,6 +2442,10 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher, if (res < 0) return -1; sm->assoc_wpa_ie_len = res; + + const u8 *rsnxe; + rsnxe = esp_wifi_sta_get_rsnxe((u8*)bssid); + wpa_sm_set_ap_rsnxe(rsnxe, rsnxe ? (rsnxe[1] + 2) : 0); res = wpa_gen_rsnxe(sm, assoc_rsnxe, assoc_rsnxe_len); if (res < 0) return -1; @@ -2588,7 +2608,7 @@ int wpa_michael_mic_failure(u16 isunicast) * Need to wait for completion of request frame. We do not get * any callback for the message completion, so just wait a * short while and hope for the best. */ - esp_rom_delay_us(10000); + os_sleep(0, 10000); /*deauthenticate AP*/ @@ -2614,30 +2634,48 @@ int wpa_michael_mic_failure(u16 isunicast) eapol tx callback function to make sure new key install after 4-way handoff */ -void eapol_txcb(void *eb) +void eapol_txcb(uint8_t *eapol_payload, size_t len, bool tx_failure) { + struct ieee802_1x_hdr *hdr; + struct wpa_eapol_key *key; struct wpa_sm *sm = &gWpaSm; u8 isdeauth = 0; //no_zero value is the reason for deauth - if (false == esp_wifi_sta_is_running_internal()){ + if (len < sizeof(struct ieee802_1x_hdr)) { + /* Invalid 802.1X header, ignore */ + return; + } + hdr = (struct ieee802_1x_hdr *) eapol_payload; + if (hdr->type != IEEE802_1X_TYPE_EAPOL_KEY) { + /* Ignore EAPOL non-key frames */ return; } + if (len < (sizeof(struct ieee802_1x_hdr) + sizeof(struct wpa_eapol_key))) { + wpa_printf(MSG_ERROR, "EAPOL TxDone with invalid payload len! (len - %zu)", len); + return; + } + key = (struct wpa_eapol_key *) (hdr + 1); switch(WPA_SM_STATE(sm)) { case WPA_FIRST_HALF_4WAY_HANDSHAKE: - break; case WPA_LAST_HALF_4WAY_HANDSHAKE: + if (WPA_GET_BE16(key->key_data_length) == 0 || + (WPA_GET_BE16(key->key_info) & WPA_KEY_INFO_SECURE)) { + /* msg 4/4 Tx Done */ + if (tx_failure) { + wpa_printf(MSG_ERROR, "Eapol message 4/4 tx failure, not installing keys"); + return; + } - if (esp_wifi_eb_tx_status_success_internal(eb) != true) { - wpa_printf(MSG_ERROR, "Eapol message 4/4 tx failure, not installing keys"); - return; - } - - if (sm->txcb_flags & WPA_4_4_HANDSHAKE_BIT) { - sm->txcb_flags &= ~WPA_4_4_HANDSHAKE_BIT; - isdeauth = wpa_supplicant_send_4_of_4_txcallback(sm); + if (sm->txcb_flags & WPA_4_4_HANDSHAKE_BIT) { + sm->txcb_flags &= ~WPA_4_4_HANDSHAKE_BIT; + isdeauth = wpa_supplicant_send_4_of_4_txcallback(sm); + } else { + wpa_printf(MSG_DEBUG, "4/4 txcb, flags=%d", sm->txcb_flags); + } } else { - wpa_printf(MSG_DEBUG, "4/4 txcb, flags=%d", sm->txcb_flags); + /* msg 2/4 Tx Done */ + wpa_printf(MSG_DEBUG, "2/4 txcb, flags=%d, txfail %d", sm->txcb_flags, tx_failure); } break; case WPA_GROUP_HANDSHAKE: @@ -2714,14 +2752,16 @@ int wpa_sm_set_ap_rsnxe(const u8 *ie, size_t len) sm->ap_rsnxe_len = len; } - sm->sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal(WIFI_IF_STA); + if (sm->ap_rsnxe != NULL) { + sm->sae_pwe = esp_wifi_get_config_sae_pwe_h2e_internal(WIFI_IF_STA); #ifdef CONFIG_SAE_PK - const u8 *pw = (const u8 *)esp_wifi_sta_get_prof_password_internal(); - if (esp_wifi_sta_get_config_sae_pk_internal() != WPA3_SAE_PK_MODE_DISABLED && - sae_pk_valid_password((const char*)pw)) { - sm->sae_pk = true; - } + const u8 *pw = (const u8 *)esp_wifi_sta_get_prof_password_internal(); + if (esp_wifi_sta_get_config_sae_pk_internal() != WPA3_SAE_PK_MODE_DISABLED && + sae_pk_valid_password((const char*)pw)) { + sm->sae_pk = true; + } #endif /* CONFIG_SAE_PK */ + } return 0; } @@ -2832,7 +2872,8 @@ int owe_process_assoc_resp(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_i struct wpa_sm *sm; sm = get_wpa_sm(); - wpabuf_free(sm->owe_ie); //free the dh ie constructed in owe_build_assoc_req + /* Deallocate the dh ie buffer constructed in owe_build_assoc_req */ + wpabuf_free(sm->owe_ie); sm->owe_ie = NULL; struct wpa_ie_data *parsed_rsn_data; @@ -2846,121 +2887,129 @@ int owe_process_assoc_resp(const u8 *rsn_ie, size_t rsn_len, const uint8_t *dh_i goto fail; } + if (!dh_ie && parsed_rsn_data->num_pmkid == 0) { + wpa_printf(MSG_ERROR, "OWE: Assoc response should either have pmkid or DH IE"); + goto fail; + } + + /* Check for PMK caching */ + if (sm->cur_pmksa && parsed_rsn_data && parsed_rsn_data->num_pmkid == 1 && parsed_rsn_data->pmkid) { + if (os_memcmp(parsed_rsn_data->pmkid, sm->cur_pmksa->pmkid, OWE_PMKID_LEN) == 0) { + wpa_printf(MSG_DEBUG, "OWE: Using PMK caching"); + wpa_sm_set_pmk_from_pmksa(sm); + goto done; + } else { + /* If PMKID mismatches, derive keys again */ + wpa_printf(MSG_DEBUG, "OWE : Invalid PMKID in response"); + } + } + + if (dh_ie == NULL) { + wpa_printf(MSG_ERROR, "OWE: No Diffie Hellman IE in association response"); + goto fail; + } if (dh_ie && MIN_DH_LEN(dh_len)) { wpa_printf(MSG_ERROR, "OWE: Invalid Diffie Hellman IE"); goto fail; } - if (!dh_ie && parsed_rsn_data->num_pmkid == 0) { - wpa_printf(MSG_ERROR, "OWE: Assoc response should either have pmkid or DH IE"); + + /* If STA or AP does not have PMKID, or PMKID mismatches, proceed with normal association */ + dh_len += 2; + + dh_ie += 3; + dh_len -=3; + group = WPA_GET_LE16(dh_ie); + + /* Only group 19 is supported */ + if ((group != sm->owe_group) || (group != OWE_DH_GRP19)) { + wpa_printf(MSG_ERROR, "OWE: Unexpected Diffie-Hellman group in response"); goto fail; } - if (!sm->cur_pmksa) { /* No PMK caching */ - if (dh_ie == NULL) { - goto fail; - } - dh_len += 2; + prime_len = OWE_PRIME_LEN; - dh_ie += 3; - dh_len -=3; - group = WPA_GET_LE16(dh_ie); + /* Set peer's public key point and calculate shared secret */ + sh_secret = crypto_ecdh_set_peerkey(sm->owe_ecdh, 0, dh_ie+2, dh_len-2); + sh_secret = wpabuf_zeropad(sh_secret, prime_len); + if (!sh_secret) { + wpa_printf(MSG_ERROR, "OWE: Invalid peer DH public key"); + goto fail; + } - /* Only group 19 is supported */ - if ((group != sm->owe_group) || (group != OWE_DH_GRP19)) { - wpa_printf(MSG_ERROR, "OWE: Unexpected Diffie-Hellman group in response"); - goto fail; - } + wpa_hexdump_buf_key(MSG_DEBUG, "OWE: DH shared secret", sh_secret); + pub = crypto_ecdh_get_pubkey(sm->owe_ecdh, 0); + if (!pub) { + wpa_printf(MSG_ERROR, "No own public key"); + goto fail; + } - prime_len = OWE_PRIME_LEN; + /* PMKID = Truncate-128(Hash(C | A)) */ + addr[0] = wpabuf_head(pub); + len[0] = wpabuf_len(pub); + addr[1] = dh_ie + 2; + len[1] = dh_len - 2; - /* Set peer's public key point and calculate shared secret */ - sh_secret = crypto_ecdh_set_peerkey(sm->owe_ecdh, 0, dh_ie+2, dh_len-2); - sh_secret = wpabuf_zeropad(sh_secret, prime_len); - if (!sh_secret) { - wpa_printf(MSG_ERROR, "OWE: Invalid peer DH public key"); - goto fail; - } + int res = sha256_vector(2, addr, len, pmkid); + if (res < 0 ) { + goto fail; + } - wpa_hexdump_buf_key(MSG_DEBUG, "OWE: DH shared secret", sh_secret); - pub = crypto_ecdh_get_pubkey(sm->owe_ecdh, 0); - if (!pub) { - wpa_printf(MSG_ERROR, "No own public key"); - wpabuf_free(sh_secret); - goto fail; - } + hash_len = SHA256_MAC_LEN; - /* PMKID = Truncate-128(Hash(C | A)) */ - addr[0] = wpabuf_head(pub); - len[0] = wpabuf_len(pub); - addr[1] = dh_ie + 2; - len[1] = dh_len - 2; + pub = wpabuf_zeropad(pub, prime_len); + if (!pub) { + goto fail; + } - int res = sha256_vector(2, addr, len, pmkid); - if (res < 0 ) { - goto fail; - } + /* prk = HKDF-extract(C | A | group, z) */ + hkey = wpabuf_alloc(wpabuf_len(pub) + dh_len - 2 + 2); + if (!hkey) { + goto fail; + } - hash_len = SHA256_MAC_LEN; + wpabuf_put_buf(hkey, pub); /* C */ + wpabuf_free(pub); - pub = wpabuf_zeropad(pub, prime_len); + wpabuf_put_data(hkey, dh_ie + 2, dh_len - 2); /* A */ + wpabuf_put_le16(hkey, sm->owe_group); /* group */ - /* prk = HKDF-extract(C | A | group, z) */ - hkey = wpabuf_alloc(wpabuf_len(pub) + dh_len - 2 + 2); + res = hmac_sha256(wpabuf_head(hkey), wpabuf_len(hkey), wpabuf_head(sh_secret), wpabuf_len(sh_secret), prk); + if (res < 0 ) { + goto fail; + } - wpabuf_put_buf(hkey, pub); /* C */ - wpabuf_free(pub); + hash_len = SHA256_MAC_LEN; - wpabuf_put_data(hkey, dh_ie + 2, dh_len - 2); /* A */ - wpabuf_put_le16(hkey, sm->owe_group); /* group */ + wpabuf_free(hkey); + wpabuf_clear_free(sh_secret); - res = hmac_sha256(wpabuf_head(hkey), wpabuf_len(hkey), wpabuf_head(sh_secret), wpabuf_len(sh_secret), prk); - if (res < 0 ) { - goto fail; - } + wpa_hexdump_key(MSG_DEBUG, "OWE: prk", prk, hash_len); - hash_len = SHA256_MAC_LEN; + /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */ + res = hmac_sha256_kdf(prk, hash_len, NULL, (const u8 *)info, + os_strlen(info), pmk, hash_len); + if (res < 0 ) { + goto fail; + } - wpabuf_free(hkey); - wpabuf_free(sh_secret); + forced_memzero(prk, SHA256_MAC_LEN); + wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, OWE_PMKID_LEN); - wpa_hexdump_key(MSG_DEBUG, "OWE: prk", prk, hash_len); + os_memcpy(sm->pmk,pmk,hash_len); + sm->pmk_len = hash_len; + wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sm->pmk, sm->pmk_len); - /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */ - res = hmac_sha256_kdf(prk, hash_len, NULL, (const u8 *)info, - os_strlen(info), pmk, hash_len); - if (res < 0 ) { - goto fail; - } + pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, pmkid, NULL, 0, + sm->bssid, sm->own_addr, sm->network_ctx, sm->key_mgmt); - forced_memzero(prk, SHA256_MAC_LEN); - wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, OWE_PMKID_LEN); - - os_memcpy(sm->pmk,pmk,hash_len); - sm->pmk_len = hash_len; - wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sm->pmk, sm->pmk_len); - - pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, pmkid, NULL, 0, - sm->bssid, sm->own_addr, sm->network_ctx, sm->key_mgmt); - goto done; - } else { /* PMK caching */ - if (parsed_rsn_data && sm->cur_pmksa) { - if (parsed_rsn_data->num_pmkid == 1 && parsed_rsn_data->pmkid) { - if (os_memcmp(parsed_rsn_data->pmkid, sm->cur_pmksa->pmkid, OWE_PMKID_LEN) == 0) { - wpa_printf(MSG_DEBUG, "OWE: Using PMK caching"); - wpa_sm_set_pmk_from_pmksa(sm); - goto done; - } else { - wpa_printf(MSG_DEBUG, "OWE : Invalid PMKID in response"); - goto fail; - } - } - } - } done: os_free(parsed_rsn_data); return 0; fail: os_free(parsed_rsn_data); + wpabuf_free(pub); + wpabuf_free(hkey); + wpabuf_clear_free(sh_secret); return -1; } #endif // CONFIG_OWE_STA diff --git a/components/wpa_supplicant/src/rsn_supp/wpa_i.h b/components/wpa_supplicant/src/rsn_supp/wpa_i.h index b4b0ce75d9..03cca337a5 100644 --- a/components/wpa_supplicant/src/rsn_supp/wpa_i.h +++ b/components/wpa_supplicant/src/rsn_supp/wpa_i.h @@ -117,7 +117,7 @@ struct wpa_sm { struct wpabuf *owe_ie; #endif /* CONFIG_OWE_STA */ int (*wpa_sm_wps_disable)(void); - esp_err_t (*wpa_sm_wpa2_ent_disable)(void); + esp_err_t (*wpa_sm_eap_disable)(void); }; /** @@ -199,7 +199,7 @@ bool wpa_sm_init(void); void wpa_sm_deinit(void); -void eapol_txcb(void *eb); +void eapol_txcb(uint8_t *eapol_payload, size_t len, bool tx_failure); void wpa_set_profile(u32 wpa_proto, u8 auth_mode); diff --git a/components/wpa_supplicant/src/utils/common.h b/components/wpa_supplicant/src/utils/common.h index e6245bf226..a913313110 100644 --- a/components/wpa_supplicant/src/utils/common.h +++ b/components/wpa_supplicant/src/utils/common.h @@ -335,6 +335,10 @@ void perror(const char *s); #define BIT(x) (1U << (x)) #endif +#ifndef GET_BIT_POSITION +#define GET_BIT_POSITION(value) (__builtin_ffs(value) - 1) +#endif + /* * Definitions for sparse validation * (http://kernel.org/pub/linux/kernel/people/josh/sparse/) diff --git a/components/wpa_supplicant/src/wps/wps.h b/components/wpa_supplicant/src/wps/wps.h index 6ba008b4ea..2800566782 100644 --- a/components/wpa_supplicant/src/wps/wps.h +++ b/components/wpa_supplicant/src/wps/wps.h @@ -870,6 +870,9 @@ void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e, void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr, const struct wpabuf *wps_data, int p2p_wildcard); +#ifdef ESP_SUPPLICANT +bool esp_wps_registrar_check_pbc_overlap(struct wps_context *wps); +#endif /* ESP_SUPPLICANT */ int wps_registrar_update_ie(struct wps_registrar *reg); int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr, char *buf, size_t buflen); diff --git a/components/wpa_supplicant/src/wps/wps_registrar.c b/components/wpa_supplicant/src/wps/wps_registrar.c index d5fa424b5c..a7edf79ff6 100644 --- a/components/wpa_supplicant/src/wps/wps_registrar.c +++ b/components/wpa_supplicant/src/wps/wps_registrar.c @@ -1228,6 +1228,19 @@ void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr, } } +#ifdef ESP_SUPPLICANT +bool esp_wps_registrar_check_pbc_overlap(struct wps_context *wps) +{ + + if (wps_registrar_pbc_overlap(wps->registrar, NULL, NULL)) { + wps->registrar->force_pbc_overlap = 1; + wps_pbc_overlap_event(wps); + return true; + } + + return false; +} +#endif /* ESP_SUPPLICANT */ int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr, const u8 *p2p_dev_addr, const u8 *psk, size_t psk_len) diff --git a/components/wpa_supplicant/test/test_fast_pbkdf2.c b/components/wpa_supplicant/test/test_fast_pbkdf2.c new file mode 100644 index 0000000000..02055c045e --- /dev/null +++ b/components/wpa_supplicant/test/test_fast_pbkdf2.c @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include "string.h" +#include +#include "unity.h" +#include "utils/common.h" +#include "mbedtls/pkcs5.h" +#include "crypto/sha1.h" + +#if SOC_WIFI_SUPPORTED + +#define PMK_LEN 32 + +TEST_CASE("Test pbkdf2", "[crypto-pbkdf2]") +{ + uint8_t PMK[PMK_LEN]; + uint8_t ssid_len; + uint8_t passphrase_len; + uint8_t ssid[MAX_SSID_LEN]; + uint8_t passphrase[MAX_PASSPHRASE_LEN]; + uint8_t expected_pmk1[PMK_LEN] = + {0xe7, 0x90, 0xd0, 0x65, 0x67, 0xf0, 0xbf, 0xca, 0xca, 0x10, 0x88, 0x0b, 0x85, 0xb2, 0x33, 0xe5, + 0xe1, 0xd5, 0xe5, 0xb8, 0xd0, 0xfd, 0x94, 0x60, 0x56, 0x95, 0x5e, 0x41, 0x5a, 0x7f, 0xfa, 0xfa}; + + uint8_t expected_pmk[PMK_LEN]; + + /* Compare Fast PBKDF output with expected output*/ + pbkdf2_sha1("espressif", (uint8_t *)"espressif", strlen("espressif"), 4096, PMK, PMK_LEN); + TEST_ASSERT(memcmp(PMK, expected_pmk1, PMK_LEN) == 0); + + /* Compare fast PBKDF output with mbedtls pbkdf2 function's output */ + pbkdf2_sha1("espressif2", (uint8_t *)"espressif2", strlen("espressif2"), 4096, PMK, PMK_LEN); + mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, (const unsigned char *) "espressif2", + strlen("espressif2") , (const unsigned char *)"espressif2", + strlen("espressif2"), 4096, PMK_LEN, expected_pmk); + TEST_ASSERT(memcmp(PMK, expected_pmk, PMK_LEN) == 0); + + /* Calculate PMK using random ssid and passphrase and compare */ + os_memset(ssid, 0, MAX_SSID_LEN); + os_memset(passphrase, 0, MAX_PASSPHRASE_LEN); + ssid_len = os_random(); + ssid_len %= MAX_SSID_LEN; + + os_get_random(ssid, ssid_len); + + passphrase_len = os_random(); + passphrase_len %= MAX_PASSPHRASE_LEN; + + os_get_random(passphrase, passphrase_len); + pbkdf2_sha1((char *)passphrase, ssid, ssid_len, 4096, PMK, PMK_LEN); + mbedtls_pkcs5_pbkdf2_hmac_ext(MBEDTLS_MD_SHA1, (const unsigned char *) passphrase, + strlen((char *)passphrase) , (const unsigned char *)ssid, + ssid_len, 4096, PMK_LEN, expected_pmk); + + /* Dump values if fails */ + if (memcmp(PMK, expected_pmk, PMK_LEN) != 0) { + ESP_LOG_BUFFER_HEXDUMP("passphrase", passphrase, passphrase_len, ESP_LOG_INFO); + ESP_LOG_BUFFER_HEXDUMP("ssid", ssid, ssid_len, ESP_LOG_INFO); + ESP_LOG_BUFFER_HEXDUMP("PMK", PMK, PMK_LEN, ESP_LOG_INFO); + ESP_LOG_BUFFER_HEXDUMP("expected_pmk", expected_pmk, PMK_LEN, ESP_LOG_INFO); + } + TEST_ASSERT(memcmp(PMK, expected_pmk, PMK_LEN) == 0); +} + +#endif /* SOC_WIFI_SUPPORTED */