From 145d9175872148632db4db4dc5fccf71d181144c Mon Sep 17 00:00:00 2001 From: xiewenxiang Date: Wed, 2 Jun 2021 11:52:57 +0800 Subject: [PATCH] riscv/esp32c3: Add Wi-Fi and BLE coexist --- arch/risc-v/src/esp32c3/Kconfig | 5 + arch/risc-v/src/esp32c3/Make.defs | 2 +- arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c | 25 +- .../risc-v/src/esp32c3/esp32c3_wifi_adapter.c | 237 +++++++++++++++++- .../risc-v/src/esp32c3/esp32c3_wifi_adapter.h | 19 ++ .../esp32c3-devkit/src/esp32c3_bringup.c | 13 + 6 files changed, 297 insertions(+), 4 deletions(-) diff --git a/arch/risc-v/src/esp32c3/Kconfig b/arch/risc-v/src/esp32c3/Kconfig index 791b08732b..f5ba5130d4 100644 --- a/arch/risc-v/src/esp32c3/Kconfig +++ b/arch/risc-v/src/esp32c3/Kconfig @@ -352,6 +352,11 @@ config ESP32C3_BLE endmenu # ESP32-C3 Peripheral Support +menuconfig ESP32C3_WIFI_BT_COEXIST + bool "Wi-Fi and BT coexist" + default n + depends on ESP32C3_WIFI && ESP32C3_BLE + menu "I2C Configuration" depends on ESP32C3_I2C diff --git a/arch/risc-v/src/esp32c3/Make.defs b/arch/risc-v/src/esp32c3/Make.defs index df1b047e98..9866ee46d0 100644 --- a/arch/risc-v/src/esp32c3/Make.defs +++ b/arch/risc-v/src/esp32c3/Make.defs @@ -212,7 +212,7 @@ endif ifeq ($(CONFIG_ESP32C3_WIFI),y) CHIP_CSRCS += esp32c3_wlan.c esp32c3_wifi_utils.c esp32c3_wifi_adapter.c -EXTRA_LIBS += -lcore -lnet80211 -lpp -lsmartconfig -lcoexist -lespnow -lwpa_supplicant -lwapi +EXTRA_LIBS += -lcore -lnet80211 -lpp -lsmartconfig -lcoexist -lespnow -lwpa_supplicant -lwapi -lmesh endif ifeq ($(CONFIG_ESP32C3_BLE),y) diff --git a/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c b/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c index 561cffb13d..bcf8b51c64 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c +++ b/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c @@ -56,6 +56,11 @@ #include "esp32c3_rt_timer.h" #include "esp32c3_ble_adapter.h" +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST +# include "esp_coexist_internal.h" +# include "esp_coexist_adapter.h" +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -1356,7 +1361,9 @@ static uint32_t IRAM_ATTR btdm_hus_2_lpcycles(uint32_t us) static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status) { - /* empty function */ +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_schm_status_bit_set(type, status); +#endif } /**************************************************************************** @@ -1376,7 +1383,9 @@ 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) { - /* empty function */ +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_schm_status_bit_clear(type, status); +#endif } /**************************************************************************** @@ -1786,6 +1795,10 @@ int esp32c3_bt_controller_init(void) wlinfo("BT controller compile version [%s]\n", btdm_controller_get_compile_version()); +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_init(); +#endif + modifyreg32(SYSTEM_WIFI_CLK_EN_REG, 0, UINT32_MAX); bt_phy_enable(); @@ -1867,6 +1880,10 @@ int esp32c3_bt_controller_disable(void) btdm_controller_disable(); +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_disable(); +#endif + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; return 0; @@ -1901,6 +1918,10 @@ int esp32c3_bt_controller_enable(esp_bt_mode_t mode) return -1; } +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_enable(); +#endif + /* enable low power mode */ if (g_lp_cntl.enable) diff --git a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c index 8d73dba526..ee3daabaf3 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c +++ b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c @@ -65,6 +65,11 @@ #include "espidf_wifi.h" +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST +# include "esp_coexist_internal.h" +# include "esp_coexist_adapter.h" +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -227,6 +232,11 @@ static void *esp_semphr_create(uint32_t max, uint32_t init); static void esp_semphr_delete(void *semphr); static int32_t esp_semphr_take(void *semphr, uint32_t block_time_tick); static int32_t esp_semphr_give(void *semphr); +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST +static int32_t esp_semphr_take_from_isr(void *semphr, void *hptw); +static int32_t esp_semphr_give_from_isr(void *semphr, void *hptw); +static int wifi_is_in_isr(void); +#endif static void *esp_thread_semphr_get(void); static void *esp_mutex_create(void); static void *esp_recursive_mutex_create(void); @@ -443,6 +453,27 @@ static bool g_softap_started; static wifi_txdone_cb_t g_softap_txdone_cb; #endif +/* Wi-Fi and BT coexistance OS adapter data */ + +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST +coex_adapter_funcs_t g_coex_adapter_funcs = +{ + ._version = COEX_ADAPTER_VERSION, + ._task_yield_from_isr = esp_task_yield_from_isr, + ._semphr_create = esp_semphr_create, + ._semphr_delete = esp_semphr_delete, + ._semphr_take_from_isr = esp_semphr_take_from_isr, + ._semphr_give_from_isr = esp_semphr_give_from_isr, + ._semphr_take = esp_semphr_take, + ._semphr_give = esp_semphr_give, + ._is_in_isr = wifi_is_in_isr, + ._malloc_internal = esp_malloc_internal, + ._free = esp_free, + ._esp_timer_get_time = esp_timer_get_time, + ._magic = COEX_ADAPTER_MAGIC, +}; +#endif + /**************************************************************************** * Public Data ****************************************************************************/ @@ -1138,6 +1169,69 @@ static int32_t esp_semphr_give(void *semphr) return osi_errno_trans(ret); } +/**************************************************************************** + * Name: esp_semphr_take_from_isr + * + * Description: + * Try to task semaphore in interrupt + * + * Input Parameters: + * semphr - Semaphore data pointer + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST +static int32_t esp_semphr_take_from_isr(void *semphr, void *hptw) +{ + *(int *)hptw = 0; + + return esp_semphr_take(semphr, 0); +} + +/**************************************************************************** + * Name: esp_semphr_give_from_isr + * + * Description: + * Post semaphore in interrupt + * + * Input Parameters: + * semphr - Semaphore data pointer + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t esp_semphr_give_from_isr(void *semphr, void *hptw) +{ + *(int *)hptw = 0; + + return esp_semphr_give(semphr); +} + +/**************************************************************************** + * Name: wifi_is_in_isr + * + * Description: + * Check current is in interrupt + * + * Input Parameters: + * None + * + * Returned Value: + * true if in interrupt or false if not + * + ****************************************************************************/ + +static int IRAM_ATTR wifi_is_in_isr(void) +{ + return up_interrupt_context(); +} +#endif + /**************************************************************************** * Name: esp_thread_semphr_get * @@ -3812,7 +3906,11 @@ static void esp_wifi_delete_queue(void *queue) static int wifi_coex_init(void) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_init(); +#else return 0; +#endif } /**************************************************************************** @@ -3825,6 +3923,9 @@ static int wifi_coex_init(void) static void wifi_coex_deinit(void) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_deinit(); +#endif } /**************************************************************************** @@ -3837,7 +3938,11 @@ static void wifi_coex_deinit(void) static int wifi_coex_enable(void) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_enable(); +#else return 0; +#endif } /**************************************************************************** @@ -3850,6 +3955,9 @@ static int wifi_coex_enable(void) static void wifi_coex_disable(void) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_disable(); +#endif } /**************************************************************************** @@ -3862,7 +3970,11 @@ static void wifi_coex_disable(void) static uint32_t esp_coex_status_get(void) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_status_get(); +#else return 0; +#endif } /**************************************************************************** @@ -3875,6 +3987,9 @@ static uint32_t esp_coex_status_get(void) static void esp_coex_condition_set(uint32_t type, bool dissatisfy) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_condition_set(type, dissatisfy); +#endif } /**************************************************************************** @@ -3886,9 +4001,13 @@ static void esp_coex_condition_set(uint32_t type, bool dissatisfy) ****************************************************************************/ static int esp_coex_wifi_request(uint32_t event, uint32_t latency, - uint32_t duration) + uint32_t duration) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_wifi_request(event, latency, duration); +#else return 0; +#endif } /**************************************************************************** @@ -3901,7 +4020,11 @@ static int esp_coex_wifi_request(uint32_t event, uint32_t latency, static int esp_coex_wifi_release(uint32_t event) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_wifi_release(event); +#else return 0; +#endif } /**************************************************************************** @@ -3914,7 +4037,11 @@ static int esp_coex_wifi_release(uint32_t event) static int wifi_coex_wifi_set_channel(uint8_t primary, uint8_t secondary) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_wifi_channel_set(primary, secondary); +#else return 0; +#endif } /**************************************************************************** @@ -3927,7 +4054,11 @@ static int wifi_coex_wifi_set_channel(uint8_t primary, uint8_t secondary) static int wifi_coex_get_event_duration(uint32_t event, uint32_t *duration) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_event_duration_get(event, duration); +#else return 0; +#endif } /**************************************************************************** @@ -3940,7 +4071,11 @@ static int wifi_coex_get_event_duration(uint32_t event, uint32_t *duration) static int wifi_coex_get_pti(uint32_t event, uint8_t *pti) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_pti_get(event, pti); +#else return 0; +#endif } /**************************************************************************** @@ -3953,6 +4088,9 @@ static int wifi_coex_get_pti(uint32_t event, uint8_t *pti) static void wifi_coex_clear_schm_status_bit(uint32_t type, uint32_t status) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_schm_status_bit_clear(type, status); +#endif } /**************************************************************************** @@ -3965,6 +4103,9 @@ static void wifi_coex_clear_schm_status_bit(uint32_t type, uint32_t status) static void wifi_coex_set_schm_status_bit(uint32_t type, uint32_t status) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_schm_status_bit_set(type, status); +#endif } /**************************************************************************** @@ -3977,7 +4118,11 @@ static void wifi_coex_set_schm_status_bit(uint32_t type, uint32_t status) static int wifi_coex_set_schm_interval(uint32_t interval) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_schm_interval_set(interval); +#else return 0; +#endif } /**************************************************************************** @@ -3990,7 +4135,11 @@ static int wifi_coex_set_schm_interval(uint32_t interval) static uint32_t wifi_coex_get_schm_interval(void) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_schm_interval_get(); +#else return 0; +#endif } /**************************************************************************** @@ -4003,7 +4152,11 @@ static uint32_t wifi_coex_get_schm_interval(void) static uint8_t wifi_coex_get_schm_curr_period(void) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_schm_curr_period_get(); +#else return 0; +#endif } /**************************************************************************** @@ -4016,7 +4169,11 @@ static uint8_t wifi_coex_get_schm_curr_period(void) static void *wifi_coex_get_schm_curr_phase(void) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_schm_curr_phase_get(); +#else return NULL; +#endif } /**************************************************************************** @@ -4030,6 +4187,11 @@ static void *wifi_coex_get_schm_curr_phase(void) static int wifi_coex_set_schm_curr_phase_idx(int idx) { return -1; +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_schm_curr_phase_idx_set(idx); +#else + return 0; +#endif } /**************************************************************************** @@ -4042,7 +4204,11 @@ static int wifi_coex_set_schm_curr_phase_idx(int idx) static int wifi_coex_get_schm_curr_phase_idx(void) { +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + return coex_schm_curr_phase_idx_get(); +#else return 0; +#endif } /**************************************************************************** @@ -4378,6 +4544,35 @@ int pp_printf(const char *format, ...) return 0; } +/**************************************************************************** + * Name: coexist_printf + * + * Description: + * Output format string and its arguments + * + * Input Parameters: + * format - format string + * + * Returned Value: + * 0 + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST +int coexist_printf(const char * format, ...) +{ +#ifdef CONFIG_DEBUG_WIRELESS_INFO + va_list arg; + + va_start(arg, format); + vsyslog(LOG_INFO, format, arg); + va_end(arg); +#endif + + return 0; +} +#endif + /**************************************************************************** * Functions needed by libnet80211.a ****************************************************************************/ @@ -4655,10 +4850,22 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) { esp_err_t ret; +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + ret = coex_init(); + if (ret) + { + wlerr("ERROR: Failed to initialize coex error=%d\n", ret); + return ret; + } +#endif + ret = esp_wifi_init_internal(config); if (ret) { wlerr("ERROR: Failed to initialize Wi-Fi error=%d\n", ret); +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_deinit(); +#endif return ret; } @@ -4667,6 +4874,9 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) { wlerr("ERROR: Failed to initialize WPA supplicant error=%d\n", ret); esp_wifi_deinit_internal(); +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + coex_deinit(); +#endif return ret; } @@ -6776,3 +6986,28 @@ int esp_wifi_softap_rssi(struct iwreq *iwr, bool set) return -ENOSYS; } #endif + +/**************************************************************************** + * Name: esp32c3_wifi_bt_coexist_init + * + * Description: + * Initialize ESP32-C3 Wi-Fi and BT coexistance module. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST +int esp32c3_wifi_bt_coexist_init(void) +{ + esp_coex_adapter_register(&g_coex_adapter_funcs); + coex_pre_init(); + + return 0; +} +#endif diff --git a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h index 159dc492bf..0e9e8408c4 100644 --- a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h +++ b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h @@ -817,6 +817,25 @@ int esp_wifi_softap_country(struct iwreq *iwr, bool set); int esp_wifi_softap_rssi(struct iwreq *iwr, bool set); #endif +/**************************************************************************** + * Name: esp32c3_wifi_bt_coexist_init + * + * Description: + * Initialize ESP32-C3 Wi-Fi and BT coexistance module. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success (positive non-zero values are cmd-specific) + * Negated errno returned on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST +int esp32c3_wifi_bt_coexist_init(void); +#endif + #ifdef __cplusplus } #endif diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c index 15297a737d..320753fdca 100644 --- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c +++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c @@ -311,6 +311,17 @@ int esp32c3_bringup(void) } #endif +#ifdef CONFIG_ESP32C3_WIRELESS + +#ifdef CONFIG_ESP32C3_WIFI_BT_COEXIST + ret = esp32c3_wifi_bt_coexist_init(); + if (ret) + { + syslog(LOG_ERR, "ERROR: Failed to initialize Wi-Fi and BT coexist\n"); + return ret; + } +#endif + #ifdef CONFIG_ESP32C3_BLE ret = esp32c3_ble_initialize(); if (ret) @@ -353,6 +364,8 @@ int esp32c3_bringup(void) #endif +#endif /* CONFIG_ESP32C3_WIRELESS */ + #ifdef CONFIG_ESP32C3_LEDC ret = esp32c3_pwm_setup(); if (ret < 0)