diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index ba55b21c45..ff4ab64d58 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -314,14 +314,14 @@ menu "Wi-Fi" config ESP_WIFI_EXTERNAL_COEXIST_ENABLE bool "WiFi External Coexistence" default n - depends on (!BT_ENABLED && (IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3)) + depends on (!(BT_ENABLED||NIMBLE_ENABLED)&&(!IDF_TARGET_ESP32)) help If enabled, HW External coexistence arbitration is managed by GPIO pins. It can support three types of wired combinations so far which are 1-wired/2-wired/3-wired. User can select GPIO pins in application code with configure interfaces. This function depends on BT-off - because currently we don't support external coex and internal coex simultaneously. + because currently we do not support external coex and internal coex simultaneously. config ESP_WIFI_GCMP_SUPPORT bool "WiFi GCMP Support(GCMP128 and GCMP256)" diff --git a/components/esp_wifi/esp32s3/esp_adapter.c b/components/esp_wifi/esp32s3/esp_adapter.c index b2bfe0e32d..dd67515fda 100644 --- a/components/esp_wifi/esp32s3/esp_adapter.c +++ b/components/esp_wifi/esp32s3/esp_adapter.c @@ -575,7 +575,7 @@ static void * IRAM_ATTR zalloc_internal_wrapper(size_t size) static int coex_init_wrapper(void) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_init(); #else return 0; @@ -584,14 +584,14 @@ static int coex_init_wrapper(void) static void coex_deinit_wrapper(void) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE coex_deinit(); #endif } static int coex_enable_wrapper(void) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_enable(); #else return 0; @@ -600,14 +600,14 @@ static int coex_enable_wrapper(void) static void coex_disable_wrapper(void) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE coex_disable(); #endif } static IRAM_ATTR uint32_t coex_status_get_wrapper(void) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_status_get(); #else return 0; @@ -616,14 +616,14 @@ static IRAM_ATTR uint32_t coex_status_get_wrapper(void) static void coex_condition_set_wrapper(uint32_t type, bool dissatisfy) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE coex_condition_set(type, dissatisfy); #endif } static int coex_wifi_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_wifi_request(event, latency, duration); #else return 0; @@ -632,7 +632,7 @@ static int coex_wifi_request_wrapper(uint32_t event, uint32_t latency, uint32_t static IRAM_ATTR int coex_wifi_release_wrapper(uint32_t event) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_wifi_release(event); #else return 0; @@ -641,7 +641,7 @@ static IRAM_ATTR int coex_wifi_release_wrapper(uint32_t event) static int coex_wifi_channel_set_wrapper(uint8_t primary, uint8_t secondary) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_wifi_channel_set(primary, secondary); #else return 0; @@ -650,7 +650,7 @@ static int coex_wifi_channel_set_wrapper(uint8_t primary, uint8_t secondary) static IRAM_ATTR int coex_event_duration_get_wrapper(uint32_t event, uint32_t *duration) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_event_duration_get(event, duration); #else return 0; @@ -659,7 +659,7 @@ static IRAM_ATTR int coex_event_duration_get_wrapper(uint32_t event, uint32_t *d static int coex_pti_get_wrapper(uint32_t event, uint8_t *pti) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_pti_get(event, pti); #else return 0; @@ -668,21 +668,21 @@ static int coex_pti_get_wrapper(uint32_t event, uint8_t *pti) static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_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 +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE coex_schm_status_bit_set(type, status); #endif } static IRAM_ATTR int coex_schm_interval_set_wrapper(uint32_t interval) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_schm_interval_set(interval); #else return 0; @@ -691,7 +691,7 @@ static IRAM_ATTR int coex_schm_interval_set_wrapper(uint32_t interval) static uint32_t coex_schm_interval_get_wrapper(void) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_schm_interval_get(); #else return 0; @@ -700,7 +700,7 @@ static uint32_t coex_schm_interval_get_wrapper(void) static uint8_t coex_schm_curr_period_get_wrapper(void) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_schm_curr_period_get(); #else return 0; @@ -709,7 +709,7 @@ static uint8_t coex_schm_curr_period_get_wrapper(void) static void * coex_schm_curr_phase_get_wrapper(void) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_schm_curr_phase_get(); #else return NULL; @@ -718,7 +718,7 @@ static void * coex_schm_curr_phase_get_wrapper(void) static int coex_schm_curr_phase_idx_set_wrapper(int idx) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_schm_curr_phase_idx_set(idx); #else return 0; @@ -727,7 +727,7 @@ static int coex_schm_curr_phase_idx_set_wrapper(int idx) static int coex_schm_curr_phase_idx_get_wrapper(void) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_schm_curr_phase_idx_get(); #else return 0; @@ -736,7 +736,7 @@ static int coex_schm_curr_phase_idx_get_wrapper(void) static int coex_register_start_cb_wrapper(int (* cb)(void)) { -#if CONFIG_SW_COEXIST_ENABLE +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE return coex_register_start_cb(cb); #else return 0; diff --git a/components/esp_wifi/include/esp_coexist.h b/components/esp_wifi/include/esp_coexist.h index 14b7c9aa50..e3fb019d42 100644 --- a/components/esp_wifi/include/esp_coexist.h +++ b/components/esp_wifi/include/esp_coexist.h @@ -40,13 +40,15 @@ typedef enum { ESP_COEX_ST_TYPE_BT, } esp_coex_status_type_t; +#if CONFIG_EXTERNAL_COEX_ENABLE /** * @brief external coex gpio pti */ typedef struct { - int32_t in_pin0; - int32_t in_pin1; - int32_t out_pin0; + uint32_t in_pin0; + uint32_t in_pin1; + uint32_t out_pin0; + uint32_t out_pin1; } esp_external_coex_gpio_set_t; /** @@ -59,16 +61,43 @@ typedef enum { } esp_coex_pti_level_t; /** - * @brief external coex pti + * @brief external coex follower pti */ typedef struct { - uint32_t in_pti1; - uint32_t in_pti2; - uint32_t in_pti3; - uint32_t out_pti1; - uint32_t out_pti2; - uint32_t out_pti3; -} esp_external_coex_pti_set_t; + uint32_t pti_val1; + uint32_t pti_val2; +} esp_external_coex_follower_pti_t; + +/** + * @brief external coex role + */ +typedef enum { + EXTERNAL_COEX_LEADER_ROLE = 0, + EXTERNAL_COEX_FOLLOWER_ROLE = 2, + EXTERNAL_COEX_UNKNOWN_ROLE, +} esp_extern_coex_work_mode_t; + +/** + * @brief external coex wiretype & role composition + */ +typedef enum { + wire_3_leader_mode = 0, + wire_2_leader_mode, + wire_1_leader_mode, + wire_3_follower_mode, + wire_2_follower_mode, + wire_1_follower_mode, +} external_coex_classification; + +/** + * @brief external coex advance setup + */ +typedef struct { + esp_extern_coex_work_mode_t work_mode; + uint8_t delay_us; + bool is_high_valid; +} esp_external_coex_advance_t; +#endif #define ESP_COEX_BLE_ST_MESH_CONFIG 0x08 #define ESP_COEX_BLE_ST_MESH_TRAFFIC 0x10 @@ -115,15 +144,61 @@ esp_err_t esp_coex_status_bit_clear(esp_coex_status_type_t type, uint32_t status #if CONFIG_EXTERNAL_COEX_ENABLE /** - * @brief Setup gpio pin and corresponding pti level, start external coex. + * @brief Setup gpio pin and corresponding pti level, start external coex, + * the default work mode is leader role, the default output grant validate pin is high, + * and the default delay output grant value is zero. * @param wire_type : to select the whole external coex gpio number. * @param gpio_pin : gpio pin number to choose. * @return : ESP_OK - success, other - failed */ esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, - esp_external_coex_gpio_set_t gpio_pin); + esp_external_coex_gpio_set_t gpio_pin); +/** + * @brief Disable external coex. + * @return : ESP_OK - success, other - failed + */ esp_err_t esp_disable_extern_coex_gpio_pin(); + +#if SOC_EXTERNAL_COEX_ADVANCE +/** + * @brief Configure leader work mode, gpio pin correspondly and finally enable external coex, + * demand not to call the legacy function of `esp_enable_extern_coex_gpio_pin` any more. + * @param wire_type : to select the whole external coex gpio number. + * @param gpio_pin : gpio pin number to select. + * @return : ESP_OK - success, other - failed + */ +esp_err_t esp_external_coex_leader_role_set_gpio_pin(external_coex_wire_t wire_type, uint32_t in_pin0, + uint32_t in_pin1, uint32_t out_pin0); + +/** + * @brief Configure follower work mode, gpio pin correspondly and finally enable external coex, + * demand not to call the legacy function of `esp_enable_extern_coex_gpio_pin` any more. + * @param wire_type : to select the whole external coex gpio number. + * @param gpio_pin : gpio pin number to select. + * @return : ESP_OK - success, other - failed + */ +esp_err_t esp_external_coex_follower_role_set_gpio_pin(external_coex_wire_t wire_type, uint32_t in_pin0, + uint32_t out_pin0, uint32_t out_pin1); + +/** + * @brief Configure output grant signal latency in delay microseconds only for leader role of external coex, + * demand to call this function before `esp_external_coex_leader_role_set_gpio_pin`, + * if users want to setup output delay value. + * @param delay_us : to setup how many microseconds the output signal performs latency. + * @return : ESP_OK - success, other - failed + */ +esp_err_t esp_external_coex_set_grant_delay(uint8_t delay_us); + +/** + * @brief Configure output grant signal is high validate or not only for leader role of external coex, + * demand to call this function before `esp_external_coex_leader_role_set_gpio_pin`, + * if users want to setup output grant validate pin value. + * @param is_high_valid : to select true means the output grant signal validate is high, other - validate is low. + * @return : ESP_OK - success, other - failed + */ +esp_err_t esp_external_coex_set_validate_high(bool is_high_valid); +#endif #endif #ifdef __cplusplus diff --git a/components/esp_wifi/include/esp_coexist_internal.h b/components/esp_wifi/include/esp_coexist_internal.h index 4e1bda69a1..c9fbd2a15a 100644 --- a/components/esp_wifi/include/esp_coexist_internal.h +++ b/components/esp_wifi/include/esp_coexist_internal.h @@ -225,6 +225,28 @@ int coex_register_start_cb(int (* cb)(void)); esp_err_t esp_coex_adapter_register(coex_adapter_funcs_t *funcs); #if CONFIG_EXTERNAL_COEX_ENABLE +/** + * @brief Force RX Anttena only in external coex situation. + */ +extern void phy_coex_force_rx_ant(void); + +/** + * @brief Dismiss RX Anttena only in external coex situation. + */ +extern void phy_coex_dismiss_rx_ant(void); + +/** + * @brief Set external coexistence advanced informations, like working mode and grant mode in which level. + * + * @param outpti1 Only for slave mode, external coex output priority in level1. + * @param output2 Only for slave mode, external coex output priority in level2. + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_coex_external_params(esp_external_coex_advance_t coex_info, + uint32_t out_pti1, uint32_t out_pti2); + /** * @brief Set external coexistence pti level and enable it. * diff --git a/components/esp_wifi/src/coexist.c b/components/esp_wifi/src/coexist.c index b0509d4570..c603800575 100644 --- a/components/esp_wifi/src/coexist.c +++ b/components/esp_wifi/src/coexist.c @@ -8,11 +8,13 @@ #include "esp_coexist_internal.h" #if CONFIG_EXTERNAL_COEX_ENABLE +#include "esp_log.h" #include "driver/gpio.h" #include "esp_rom_gpio.h" #include "hal/gpio_hal.h" #include "hal/gpio_types.h" #include "soc/gpio_periph.h" +#include "soc/gpio_struct.h" #endif const char *esp_coex_version_get(void) @@ -27,32 +29,281 @@ esp_err_t esp_coex_preference_set(esp_coex_prefer_t prefer) #if CONFIG_EXTERNAL_COEX_ENABLE #define GPIO_PIN_REG(a) (GPIO_PIN0_REG + a * 0x04) + +#if SOC_EXTERNAL_COEX_ADVANCE +static const char *TAG = "external_coex"; + +external_coex_classification s_external_coex_partner[EXTERNAL_COEX_UNKNOWN_ROLE][EXTERN_COEX_WIRE_NUM] = { + { wire_1_leader_mode, wire_2_leader_mode, wire_3_leader_mode }, + {}, + { wire_1_follower_mode, wire_2_follower_mode, wire_3_follower_mode }, +}; + +static esp_external_coex_advance_t g_external_coex_params = { EXTERNAL_COEX_LEADER_ROLE, 0, true }; +esp_external_coex_follower_pti_t g_external_coex_follower_pti_val = { 0, 0 }; + +esp_err_t esp_external_coex_set_work_mode(esp_extern_coex_work_mode_t work_mode) +{ + g_external_coex_params.work_mode = work_mode; + + if(EXTERNAL_COEX_FOLLOWER_ROLE == work_mode) { + g_external_coex_follower_pti_val.pti_val1 = 8; + g_external_coex_follower_pti_val.pti_val2 = 13; + } + + return ESP_OK; +} + +esp_err_t esp_external_coex_set_grant_delay(uint8_t delay_us) +{ + g_external_coex_params.delay_us = delay_us; + + return ESP_OK; +} + +esp_err_t esp_external_coex_set_validate_high(bool is_high_valid) +{ + g_external_coex_params.is_high_valid = is_high_valid; + + return ESP_OK; +} + +bool is_legal_external_coex_gpio(external_coex_wire_t wire_type, esp_external_coex_gpio_set_t gpio_pin) +{ + external_coex_classification external_coex_configure = s_external_coex_partner[g_external_coex_params.work_mode][wire_type]; + + switch (external_coex_configure) + { + case wire_3_leader_mode: + { + if(gpio_pin.in_pin0 == gpio_pin.in_pin1) { + return false; + } + if(gpio_pin.in_pin0 == gpio_pin.out_pin0) { + return false; + } + if(gpio_pin.in_pin1 == gpio_pin.out_pin0) { + return false; + } + if(gpio_pin.in_pin0 >= SOC_GPIO_PIN_COUNT) { + return false; + } + if(gpio_pin.in_pin1 >= SOC_GPIO_PIN_COUNT) { + return false; + } + if(gpio_pin.out_pin0 >= SOC_GPIO_PIN_COUNT) { + return false; + } + return true; + } + case wire_3_follower_mode: + { + if(gpio_pin.in_pin0 == gpio_pin.out_pin0) { + return false; + } + if(gpio_pin.in_pin0 == gpio_pin.out_pin1) { + return false; + } + if(gpio_pin.out_pin0 == gpio_pin.out_pin1) { + return false; + } + if(gpio_pin.in_pin0 >= SOC_GPIO_PIN_COUNT) { + return false; + } + if(gpio_pin.out_pin1 >= SOC_GPIO_PIN_COUNT) { + return false; + } + if(gpio_pin.out_pin0 >= SOC_GPIO_PIN_COUNT) { + return false; + } + return true; + } + case wire_2_leader_mode: + case wire_2_follower_mode: + { + if(gpio_pin.in_pin0 == gpio_pin.out_pin0) { + return false; + } + if(gpio_pin.in_pin0 >= SOC_GPIO_PIN_COUNT) { + return false; + } + if(gpio_pin.out_pin0 >= SOC_GPIO_PIN_COUNT) { + return false; + } + return true; + } + case wire_1_leader_mode: + { + if(gpio_pin.in_pin0 >= SOC_GPIO_PIN_COUNT) { + return false; + } + return true; + } + case wire_1_follower_mode: + { + if(gpio_pin.out_pin0 >= SOC_GPIO_PIN_COUNT) { + return false; + } + return true; + } + default: + return false; + } +} + +esp_err_t esp_external_coex_leader_role_set_gpio_pin(external_coex_wire_t wire_type, uint32_t in_pin0, uint32_t in_pin1, uint32_t out_pin0) +{ + esp_external_coex_set_work_mode(EXTERNAL_COEX_LEADER_ROLE); + esp_external_coex_gpio_set_t gpio_pin; + + switch (wire_type) { + case EXTERN_COEX_WIRE_3: + { + gpio_pin.in_pin0 = in_pin0; + gpio_pin.in_pin1 = in_pin1; + gpio_pin.out_pin0 = out_pin0; + break; + } + case EXTERN_COEX_WIRE_2: + { + gpio_pin.in_pin0 = in_pin0; + gpio_pin.out_pin0 = out_pin0; + break; + } + case EXTERN_COEX_WIRE_1: + { + gpio_pin.in_pin0 = in_pin0; + break; + } + default: + { + gpio_pin.in_pin0 = in_pin0; + gpio_pin.in_pin1 = in_pin1; + gpio_pin.out_pin0 = out_pin0; + break; + } + } + + return esp_enable_extern_coex_gpio_pin(wire_type, gpio_pin); +} + +esp_err_t esp_external_coex_follower_role_set_gpio_pin(external_coex_wire_t wire_type, uint32_t in_pin0, uint32_t out_pin0, uint32_t out_pin1) +{ + esp_external_coex_set_work_mode(EXTERNAL_COEX_FOLLOWER_ROLE); + esp_external_coex_gpio_set_t gpio_pin; + + switch (wire_type) { + case EXTERN_COEX_WIRE_3: + { + gpio_pin.in_pin0 = in_pin0; + gpio_pin.out_pin0 = out_pin0; + gpio_pin.out_pin1 = out_pin1; + break; + } + case EXTERN_COEX_WIRE_2: + { + gpio_pin.in_pin0 = in_pin0; + gpio_pin.out_pin0 = out_pin0; + break; + } + case EXTERN_COEX_WIRE_1: + { + gpio_pin.out_pin0 = out_pin0; + break; + } + default: + { + gpio_pin.in_pin0 = in_pin0; + gpio_pin.out_pin0 = out_pin0; + gpio_pin.out_pin1 = out_pin1; + break; + } + } + + return esp_enable_extern_coex_gpio_pin(wire_type, gpio_pin); +} +#endif + esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, esp_external_coex_gpio_set_t gpio_pin) { +#if SOC_EXTERNAL_COEX_ADVANCE + if(false == is_legal_external_coex_gpio(wire_type, gpio_pin)) + { + ESP_LOGE(TAG, "Configure external coex with unexpected gpio pin!!!\n"); + return ESP_ERR_INVALID_ARG; + } + phy_coex_force_rx_ant(); + + esp_coex_external_params(g_external_coex_params, g_external_coex_follower_pti_val.pti_val1, + g_external_coex_follower_pti_val.pti_val2); +#endif + switch (wire_type) { case EXTERN_COEX_WIRE_3: { +#if SOC_EXTERNAL_COEX_ADVANCE + if(EXTERNAL_COEX_LEADER_ROLE == g_external_coex_params.work_mode) { +#endif /*Input gpio pin setup --> GPIO_BT_PRIORITY_IDX:GPIO_BT_ACTIVE_IDX*/ gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_pin.in_pin0], PIN_FUNC_GPIO); gpio_set_direction(gpio_pin.in_pin0, GPIO_MODE_INPUT); + +#if SOC_EXTERNAL_COEX_ADVANCE + esp_rom_gpio_connect_in_signal(gpio_pin.in_pin0, EXTERN_ACTIVE_I_IDX, false); +#else esp_rom_gpio_connect_in_signal(gpio_pin.in_pin0, GPIO_BT_ACTIVE_IDX, false); +#endif gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_pin.in_pin1], PIN_FUNC_GPIO); gpio_set_direction(gpio_pin.in_pin1, GPIO_MODE_INPUT); + +#if SOC_EXTERNAL_COEX_ADVANCE + esp_rom_gpio_connect_in_signal(gpio_pin.in_pin1, EXTERN_PRIORITY_I_IDX, false); +#else esp_rom_gpio_connect_in_signal(gpio_pin.in_pin1, GPIO_BT_PRIORITY_IDX, false); +#endif /*Output gpio pin setup --> GPIO_WLAN_ACTIVE_IDX: 1 BT, 0 WiFi*/ gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_pin.out_pin0], PIN_FUNC_GPIO); gpio_set_direction(gpio_pin.out_pin0, GPIO_MODE_OUTPUT); REG_WRITE(GPIO_ENABLE_W1TC_REG, BIT(gpio_pin.out_pin0)); + +#if SOC_EXTERNAL_COEX_ADVANCE + esp_rom_gpio_connect_out_signal(gpio_pin.out_pin0, EXTERN_ACTIVE_O_IDX, false, false); +#else esp_rom_gpio_connect_out_signal(gpio_pin.out_pin0, GPIO_WLAN_ACTIVE_IDX, false, false); +#endif REG_SET_FIELD(GPIO_PIN_REG(gpio_pin.in_pin0), GPIO_PIN1_SYNC1_BYPASS, 2); REG_SET_FIELD(GPIO_PIN_REG(gpio_pin.in_pin0), GPIO_PIN1_SYNC2_BYPASS, 2); REG_SET_FIELD(GPIO_PIN_REG(gpio_pin.in_pin1), GPIO_PIN1_SYNC1_BYPASS, 2); REG_SET_FIELD(GPIO_PIN_REG(gpio_pin.in_pin1), GPIO_PIN1_SYNC2_BYPASS, 2); +#if SOC_EXTERNAL_COEX_ADVANCE + } + else if(EXTERNAL_COEX_FOLLOWER_ROLE == g_external_coex_params.work_mode) { + /*Input gpio pin setup --> GPIO_BT_PRIORITY_IDX:GPIO_BT_ACTIVE_IDX*/ + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_pin.in_pin0], PIN_FUNC_GPIO); + gpio_set_direction(gpio_pin.in_pin0, GPIO_MODE_INPUT); + esp_rom_gpio_connect_in_signal(gpio_pin.in_pin0, EXTERN_ACTIVE_I_IDX, false); + + /*Output gpio pin setup --> GPIO_WLAN_ACTIVE_IDX: 1 BT, 0 WiFi*/ + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_pin.out_pin0], PIN_FUNC_GPIO); + gpio_set_direction(gpio_pin.out_pin0, GPIO_MODE_OUTPUT); + REG_WRITE(GPIO_ENABLE_W1TC_REG, BIT(gpio_pin.out_pin0)); + esp_rom_gpio_connect_out_signal(gpio_pin.out_pin0, EXTERN_ACTIVE_O_IDX, false, false); + + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_pin.out_pin1], PIN_FUNC_GPIO); + gpio_set_direction(gpio_pin.out_pin1, GPIO_MODE_OUTPUT); + REG_WRITE(GPIO_ENABLE_W1TC_REG, BIT(gpio_pin.out_pin1)); + esp_rom_gpio_connect_out_signal(gpio_pin.out_pin1, EXTERN_PRIORITY_O_IDX, false, false); + + REG_SET_FIELD(GPIO_PIN_REG(gpio_pin.in_pin0), GPIO_PIN1_SYNC1_BYPASS, 2); + REG_SET_FIELD(GPIO_PIN_REG(gpio_pin.in_pin0), GPIO_PIN1_SYNC2_BYPASS, 2); + } +#else +#endif int ret = esp_coex_external_set(EXTERN_COEX_PTI_MID, EXTERN_COEX_PTI_MID, EXTERN_COEX_PTI_HIGH); if (ESP_OK != ret) { return ESP_FAIL; @@ -64,13 +315,23 @@ esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, esp_ex /*Input gpio pin setup --> GPIO_BT_PRIORITY_IDX:GPIO_BT_ACTIVE_IDX*/ gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_pin.in_pin0], PIN_FUNC_GPIO); gpio_set_direction(gpio_pin.in_pin0, GPIO_MODE_INPUT); + +#if SOC_EXTERNAL_COEX_ADVANCE + esp_rom_gpio_connect_in_signal(gpio_pin.in_pin0, EXTERN_ACTIVE_I_IDX, false); +#else esp_rom_gpio_connect_in_signal(gpio_pin.in_pin0, GPIO_BT_ACTIVE_IDX, false); +#endif /*Output gpio pin setup --> GPIO_WLAN_ACTIVE_IDX: 1 BT, 0 WiFi*/ gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_pin.out_pin0], PIN_FUNC_GPIO); gpio_set_direction(gpio_pin.out_pin0, GPIO_MODE_OUTPUT); REG_WRITE(GPIO_ENABLE_W1TC_REG, BIT(gpio_pin.out_pin0)); + +#if SOC_EXTERNAL_COEX_ADVANCE + esp_rom_gpio_connect_out_signal(gpio_pin.out_pin0, EXTERN_ACTIVE_O_IDX, false, false); +#else esp_rom_gpio_connect_out_signal(gpio_pin.out_pin0, GPIO_WLAN_ACTIVE_IDX, false, false); +#endif REG_SET_FIELD(GPIO_PIN_REG(gpio_pin.in_pin0), GPIO_PIN1_SYNC1_BYPASS, 2); REG_SET_FIELD(GPIO_PIN_REG(gpio_pin.in_pin0), GPIO_PIN1_SYNC2_BYPASS, 2); @@ -83,13 +344,32 @@ esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, esp_ex } case EXTERN_COEX_WIRE_1: { +#if SOC_EXTERNAL_COEX_ADVANCE + if(EXTERNAL_COEX_LEADER_ROLE == g_external_coex_params.work_mode) { +#endif /*Input gpio pin setup --> GPIO_BT_PRIORITY_IDX:GPIO_BT_ACTIVE_IDX*/ gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_pin.in_pin0], PIN_FUNC_GPIO); gpio_set_direction(gpio_pin.in_pin0, GPIO_MODE_INPUT); + +#if SOC_EXTERNAL_COEX_ADVANCE + esp_rom_gpio_connect_in_signal(gpio_pin.in_pin0, EXTERN_ACTIVE_I_IDX, false); +#else esp_rom_gpio_connect_in_signal(gpio_pin.in_pin0, GPIO_BT_ACTIVE_IDX, false); +#endif REG_SET_FIELD(GPIO_PIN_REG(gpio_pin.in_pin0), GPIO_PIN1_SYNC1_BYPASS, 2); REG_SET_FIELD(GPIO_PIN_REG(gpio_pin.in_pin0), GPIO_PIN1_SYNC2_BYPASS, 2); +#if SOC_EXTERNAL_COEX_ADVANCE + } + else if(EXTERNAL_COEX_FOLLOWER_ROLE == g_external_coex_params.work_mode) { + /*Output gpio pin setup --> GPIO_WLAN_ACTIVE_IDX: 1 BT, 0 WiFi*/ + gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_pin.out_pin0], PIN_FUNC_GPIO); + gpio_set_direction(gpio_pin.out_pin0, GPIO_MODE_OUTPUT); + REG_WRITE(GPIO_ENABLE_W1TC_REG, BIT(gpio_pin.out_pin0)); + esp_rom_gpio_connect_out_signal(gpio_pin.out_pin0, EXTERN_ACTIVE_O_IDX, false, false); + } +#else +#endif int ret = esp_coex_external_set(EXTERN_COEX_PTI_HIGH, EXTERN_COEX_PTI_HIGH, EXTERN_COEX_PTI_HIGH); if (ESP_OK != ret) { @@ -107,6 +387,9 @@ esp_err_t esp_enable_extern_coex_gpio_pin(external_coex_wire_t wire_type, esp_ex esp_err_t esp_disable_extern_coex_gpio_pin() { +#if SOC_EXTERNAL_COEX_ADVANCE + phy_coex_dismiss_rx_ant(); +#endif esp_coex_external_stop(); return ESP_OK; diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index c4fe0ca78f..25b9a3d940 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -519,6 +519,10 @@ config SOC_COEX_HW_PTI bool default y +config SOC_EXTERNAL_COEX_ADVANCE + bool + default y + config SOC_PHY_DIG_REGS_MEM_SIZE int default 21 diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index 73eb682a9d..9b4304afdd 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -251,6 +251,9 @@ /*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/ #define SOC_COEX_HW_PTI (1) +/*-------------------------- HARDWARE ADVANCED EXTERNAL COEXISTENCE CAPS -------------------*/ +#define SOC_EXTERNAL_COEX_ADVANCE (1) + /*--------------- PHY REGISTER AND MEMORY SIZE CAPS --------------------------*/ #define SOC_PHY_DIG_REGS_MEM_SIZE (21*4) #define SOC_MAC_BB_PD_MEM_SIZE (192*4) diff --git a/examples/wifi/iperf/main/cmd_wifi.c b/examples/wifi/iperf/main/cmd_wifi.c index 1162649f53..7d4d4854bd 100644 --- a/examples/wifi/iperf/main/cmd_wifi.c +++ b/examples/wifi/iperf/main/cmd_wifi.c @@ -146,12 +146,18 @@ void initialise_wifi(void) ESP_ERROR_CHECK(esp_wifi_start() ); #if CONFIG_EXTERNAL_COEX_ENABLE +#if SOC_EXTERNAL_COEX_ADVANCE + uint32_t in_pin0 = 1; + uint32_t in_pin1 = 2; + uint32_t out_pin0 = 3; + ESP_ERROR_CHECK( esp_external_coex_leader_role_set_gpio_pin(EXTERN_COEX_WIRE_3, in_pin0, in_pin1, out_pin0) ); +#else esp_external_coex_gpio_set_t gpio_pin; gpio_pin.in_pin0 = 1; gpio_pin.in_pin1 = 2; gpio_pin.out_pin0 = 3; - ESP_ERROR_CHECK( esp_enable_extern_coex_gpio_pin(EXTERN_COEX_WIRE_3, gpio_pin) ); +#endif #endif initialized = true;