diff --git a/components/esp_coex/esp32c5/esp_coex_adapter.c b/components/esp_coex/esp32c5/esp_coex_adapter.c new file mode 100644 index 0000000000..1c41974a90 --- /dev/null +++ b/components/esp_coex/esp32c5/esp_coex_adapter.c @@ -0,0 +1,164 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "freertos/portmacro.h" +#include "esp_heap_caps.h" +#include "esp_timer.h" +#include "soc/rtc.h" +#include "esp_private/esp_clk.h" +#include "private/esp_coexist_adapter.h" +#include "esp32c5/rom/ets_sys.h" + +#define TAG "esp_coex_adapter" + +#define OSI_FUNCS_TIME_BLOCKING 0xffffffff + +bool IRAM_ATTR esp_coex_common_env_is_chip_wrapper(void) +{ +#ifdef CONFIG_IDF_ENV_FPGA + return false; +#else + return true; +#endif +} + +void *esp_coex_common_spin_lock_create_wrapper(void) +{ + portMUX_TYPE tmp = portMUX_INITIALIZER_UNLOCKED; + void *mux = malloc(sizeof(portMUX_TYPE)); + + if (mux) { + memcpy(mux, &tmp, sizeof(portMUX_TYPE)); + return mux; + } + return NULL; +} + +uint32_t IRAM_ATTR esp_coex_common_int_disable_wrapper(void *wifi_int_mux) +{ + if (xPortInIsrContext()) { + portENTER_CRITICAL_ISR(wifi_int_mux); + } else { + portENTER_CRITICAL(wifi_int_mux); + } + + return 0; +} + +void IRAM_ATTR esp_coex_common_int_restore_wrapper(void *wifi_int_mux, uint32_t tmp) +{ + if (xPortInIsrContext()) { + portEXIT_CRITICAL_ISR(wifi_int_mux); + } else { + portEXIT_CRITICAL(wifi_int_mux); + } +} + +void IRAM_ATTR esp_coex_common_task_yield_from_isr_wrapper(void) +{ + portYIELD_FROM_ISR(); +} + +void *esp_coex_common_semphr_create_wrapper(uint32_t max, uint32_t init) +{ + return (void *)xSemaphoreCreateCounting(max, init); +} + +void esp_coex_common_semphr_delete_wrapper(void *semphr) +{ + vSemaphoreDelete(semphr); +} + +int32_t esp_coex_common_semphr_take_wrapper(void *semphr, uint32_t block_time_tick) +{ + if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { + return (int32_t)xSemaphoreTake(semphr, portMAX_DELAY); + } else { + return (int32_t)xSemaphoreTake(semphr, block_time_tick); + } +} + +int32_t esp_coex_common_semphr_give_wrapper(void *semphr) +{ + return (int32_t)xSemaphoreGive(semphr); +} + +void IRAM_ATTR esp_coex_common_timer_disarm_wrapper(void *timer) +{ + ets_timer_disarm(timer); +} + +void esp_coex_common_timer_done_wrapper(void *ptimer) +{ + ets_timer_done(ptimer); +} + +void esp_coex_common_timer_setfn_wrapper(void *ptimer, void *pfunction, void *parg) +{ + ets_timer_setfn(ptimer, pfunction, parg); +} + +void IRAM_ATTR esp_coex_common_timer_arm_us_wrapper(void *ptimer, uint32_t us, bool repeat) +{ + ets_timer_arm_us(ptimer, us, repeat); +} + +uint32_t esp_coex_common_clk_slowclk_cal_get_wrapper(void) +{ + /* The bit width of WiFi light sleep clock calibration is 12 while the one of + * system is 19. It should shift 19 - 12 = 7. + */ + return (esp_clk_slowclk_cal_get() >> (RTC_CLK_CAL_FRACT - SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH)); +} + +void *IRAM_ATTR esp_coex_common_malloc_internal_wrapper(size_t size) +{ + return heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL); +} + +/* static wrapper */ + +static int32_t IRAM_ATTR esp_coex_semphr_take_from_isr_wrapper(void *semphr, void *hptw) +{ + return (int32_t)xSemaphoreTakeFromISR(semphr, hptw); +} + +static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, void *hptw) +{ + return (int32_t)xSemaphoreGiveFromISR(semphr, hptw); +} + +coex_adapter_funcs_t g_coex_adapter_funcs = { + ._version = COEX_ADAPTER_VERSION, + ._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper, + ._semphr_create = esp_coex_common_semphr_create_wrapper, + ._semphr_delete = esp_coex_common_semphr_delete_wrapper, + ._semphr_take_from_isr = esp_coex_semphr_take_from_isr_wrapper, + ._semphr_give_from_isr = esp_coex_semphr_give_from_isr_wrapper, + ._semphr_take = esp_coex_common_semphr_take_wrapper, + ._semphr_give = esp_coex_common_semphr_give_wrapper, + ._is_in_isr = xPortInIsrContext, + ._malloc_internal = esp_coex_common_malloc_internal_wrapper, + ._free = free, + ._esp_timer_get_time = esp_timer_get_time, + ._env_is_chip = esp_coex_common_env_is_chip_wrapper, + ._timer_disarm = esp_coex_common_timer_disarm_wrapper, + ._timer_done = esp_coex_common_timer_done_wrapper, + ._timer_setfn = esp_coex_common_timer_setfn_wrapper, + ._timer_arm_us = esp_coex_common_timer_arm_us_wrapper, + ._magic = COEX_ADAPTER_MAGIC, +}; diff --git a/components/esp_phy/CMakeLists.txt b/components/esp_phy/CMakeLists.txt index 11c4b10e0c..d542d6ab51 100644 --- a/components/esp_phy/CMakeLists.txt +++ b/components/esp_phy/CMakeLists.txt @@ -4,7 +4,7 @@ if(${idf_target} STREQUAL "linux") return() # This component is not supported by the POSIX/Linux simulator endif() -if(IDF_TARGET STREQUAL "esp32p4" OR IDF_TARGET STREQUAL "esp32c5" OR IDF_TARGET STREQUAL "esp32c61") +if(IDF_TARGET STREQUAL "esp32p4" OR IDF_TARGET STREQUAL "esp32c61") # TODO: IDF-7460, IDF-8851, IDF-9553 return() endif() diff --git a/components/esp_phy/esp32c5/include/btbb_retention_reg.h b/components/esp_phy/esp32c5/include/btbb_retention_reg.h new file mode 100644 index 0000000000..fbb3997296 --- /dev/null +++ b/components/esp_phy/esp32c5/include/btbb_retention_reg.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +// btbb sleep retention reg + +#define BB_PART_0_SIZE 93 +#define BB_PART_1_SIZE 62 +#define BB_PART_2_SIZE 19 +#define BB_PART_0_ADDR 0x600A2000 +#define BB_PART_1_ADDR 0x600A2800 +#define BB_PART_2_ADDR 0x600A2C00 + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_phy/esp32c5/include/phy_init_data.h b/components/esp_phy/esp32c5/include/phy_init_data.h new file mode 100644 index 0000000000..112b4e9a00 --- /dev/null +++ b/components/esp_phy/esp32c5/include/phy_init_data.h @@ -0,0 +1,199 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef PHY_INIT_DATA_H +#define PHY_INIT_DATA_H /* don't use #pragma once here, we compile this file sometimes */ +#include "esp_phy_init.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// constrain a value between 'low' and 'high', inclusive +#define LIMIT(val, low, high) ((val < low) ? low : (val > high) ? high : val) + +#define PHY_INIT_MAGIC "PHYINIT" + +// define the lowest tx power as LOWEST_PHY_TX_POWER +#define PHY_TX_POWER_LOWEST LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 52) +#define PHY_TX_POWER_OFFSET 2 +#define PHY_TX_POWER_NUM 14 + +#if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN +#define PHY_CRC_ALGORITHM 1 +#define PHY_COUNTRY_CODE_LEN 2 +#define PHY_INIT_DATA_TYPE_OFFSET 126 +#define PHY_SUPPORT_MULTIPLE_BIN_OFFSET 125 +#endif + + +static const char __attribute__((section(".rodata"))) phy_init_magic_pre[] = PHY_INIT_MAGIC; + +/** + * @brief Structure containing default recommended PHY initialization parameters. + */ +static const esp_phy_init_data_t phy_init_data= { { + 0x01, + 0x00, + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x44), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x3C), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x3C), + LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x3C), + 0x00, + 0x00, + 0x00, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0x70 +} }; + +static const char __attribute__((section(".rodata"))) phy_init_magic_post[] = PHY_INIT_MAGIC; + +#if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN +/** + * @brief PHY init data control infomation structure + */ +typedef struct { + uint8_t control_info_checksum[4]; /*!< 4-byte control infomation checksum */ + uint8_t multiple_bin_checksum[4]; /*!< 4-byte multiple bin checksum */ + uint8_t check_algorithm; /*!< check algorithm */ + uint8_t version; /*!< PHY init data bin version */ + uint8_t number; /*!< PHY init data bin number */ + uint8_t length[2]; /*!< Length of each PHY init data bin */ + uint8_t reserved[19]; /*!< 19-byte reserved */ +} __attribute__ ((packed)) phy_control_info_data_t; + +/** + * @brief Country corresponds to PHY init data type structure + */ +typedef struct { + char cc[PHY_COUNTRY_CODE_LEN]; + uint8_t type; +} phy_country_to_bin_type_t; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PHY_INIT_DATA_H */ diff --git a/components/esp_phy/esp32c5/phy_multiple_init_data.bin b/components/esp_phy/esp32c5/phy_multiple_init_data.bin new file mode 100644 index 0000000000..0f754a2c49 Binary files /dev/null and b/components/esp_phy/esp32c5/phy_multiple_init_data.bin differ diff --git a/components/esp_phy/lib b/components/esp_phy/lib index 2d319a3823..603b695836 160000 --- a/components/esp_phy/lib +++ b/components/esp_phy/lib @@ -1 +1 @@ -Subproject commit 2d319a382336cf0522ea4bb5a3fbd6701a8633c6 +Subproject commit 603b69583635ffcedf2a5e1d0f70da77edf82d10 diff --git a/components/esp_phy/src/phy_init.c b/components/esp_phy/src/phy_init.c index 2b029d6c30..3bfbb4f47a 100644 --- a/components/esp_phy/src/phy_init.c +++ b/components/esp_phy/src/phy_init.c @@ -59,10 +59,12 @@ static _lock_t s_phy_access_lock; #if SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD #if !SOC_PMU_SUPPORTED +#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8667 static DRAM_ATTR struct { int count; /* power on count of wifi and bt power domain */ _lock_t lock; } s_wifi_bt_pd_controller = { .count = 0 }; +#endif #endif // !SOC_PMU_SUPPORTED #endif // SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD @@ -326,6 +328,7 @@ void IRAM_ATTR esp_wifi_bt_power_domain_on(void) { #if SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD #if !SOC_PMU_SUPPORTED +#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8667 _lock_acquire(&s_wifi_bt_pd_controller.lock); if (s_wifi_bt_pd_controller.count++ == 0) { CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); @@ -343,6 +346,7 @@ void IRAM_ATTR esp_wifi_bt_power_domain_on(void) wifi_bt_common_module_disable(); } _lock_release(&s_wifi_bt_pd_controller.lock); +#endif #endif // !SOC_PMU_SUPPORTED #endif // SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD } @@ -351,12 +355,14 @@ void esp_wifi_bt_power_domain_off(void) { #if SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD #if !SOC_PMU_SUPPORTED +#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8667 _lock_acquire(&s_wifi_bt_pd_controller.lock); if (--s_wifi_bt_pd_controller.count == 0) { SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); } _lock_release(&s_wifi_bt_pd_controller.lock); +#endif #endif // !SOC_PMU_SUPPORTED #endif // SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD } @@ -864,10 +870,13 @@ void esp_phy_load_cal_and_init(void) #else esp_phy_release_init_data(init_data); #endif - +#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8638 ESP_ERROR_CHECK(esp_deep_sleep_register_hook(&phy_close_rf)); +#endif #if !CONFIG_IDF_TARGET_ESP32 +#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8638 ESP_ERROR_CHECK(esp_deep_sleep_register_hook(&phy_xpd_tsens)); +#endif #endif free(cal_data); // PHY maintains a copy of calibration data, so we can free this diff --git a/components/esp_phy/src/phy_override.c b/components/esp_phy/src/phy_override.c index f374b36f1c..e2172020bf 100644 --- a/components/esp_phy/src/phy_override.c +++ b/components/esp_phy/src/phy_override.c @@ -18,8 +18,10 @@ */ static bool s_wifi_adc_xpd_flag; +#if CONFIG_SOC_TEMP_SENSOR_SUPPORTED // TODO: [ESP32C5] IDF-8727 remove me when fix IDF-8727 static bool s_wifi_pwdet_xpd_flag; static bool s_wifi_tsens_xpd_flag; +#endif void include_esp_phy_override(void) { @@ -57,6 +59,7 @@ IRAM_ATTR void phy_i2c_exit_critical(void) void phy_set_pwdet_power(bool en) { +#if CONFIG_SOC_TEMP_SENSOR_SUPPORTED // TODO: [ESP32C5] IDF-8727 remove me when fix IDF-8727 if (s_wifi_pwdet_xpd_flag == en) { /* ignore repeated calls to phy_set_pwdet_power when the state is already correct */ return; @@ -68,10 +71,12 @@ void phy_set_pwdet_power(bool en) } else { sar_periph_ctrl_pwdet_power_release(); } +#endif } void phy_set_tsens_power(bool en) { +#if CONFIG_SOC_TEMP_SENSOR_SUPPORTED // TODO: [ESP32C5] IDF-8727 remove me when fix IDF-8727 if (s_wifi_tsens_xpd_flag == en) { /* ignore repeated calls to phy_set_tsens_power when the state is already correct */ return; @@ -83,9 +88,14 @@ void phy_set_tsens_power(bool en) } else { temperature_sensor_power_release(); } +#endif } int16_t phy_get_tsens_value(void) { +#if CONFIG_SOC_TEMP_SENSOR_SUPPORTED // TODO: [ESP32C5] IDF-8727 remove me when fix IDF-8727 return temp_sensor_get_raw_value(NULL); +#else + return 0; +#endif }