diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0c55ce4cd..08156cfe8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1299,6 +1299,12 @@ UT_001_42: - ESP32_IDF - UT_T1_1 +UT_001_43: + <<: *unit_test_template + tags: + - ESP32_IDF + - UT_T1_1 + UT_002_01: <<: *unit_test_template tags: diff --git a/components/bt/bt.c b/components/bt/bt.c index 82bf79fde..dc17d9b02 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -43,6 +43,7 @@ #include "soc/rtc_cntl_reg.h" #include "soc/soc_memory_layout.h" #include "esp_clk.h" +#include "esp_coexist_internal.h" #if CONFIG_BT_ENABLED @@ -166,6 +167,11 @@ struct osi_funcs_t { void (* _btdm_sleep_exit_phase1)(void); /* called from ISR */ void (* _btdm_sleep_exit_phase2)(void); /* called from ISR */ void (* _btdm_sleep_exit_phase3)(void); /* called from task */ + int (* _coex_bt_request)(uint32_t event, uint32_t latency, uint32_t duration); + int (* _coex_bt_release)(uint32_t event); + int (* _coex_register_bt_cb)(coex_func_cb_t cb); + uint32_t (* _coex_bb_reset_lock)(void); + void (* _coex_bb_reset_unlock)(uint32_t restore); uint32_t _magic; }; @@ -205,6 +211,12 @@ extern int bredr_txpwr_set(int min_power_level, int max_power_level); extern int bredr_txpwr_get(int *min_power_level, int *max_power_level); extern void bredr_sco_datapath_set(uint8_t data_path); extern void btdm_controller_scan_duplicate_list_clear(void); +/* Coexistence */ +extern int coex_bt_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration); +extern int coex_bt_release_wrapper(uint32_t event); +extern int coex_register_bt_cb_wrapper(coex_func_cb_t cb); +extern uint32_t coex_bb_reset_lock_wrapper(void); +extern void coex_bb_reset_unlock_wrapper(uint32_t restore); extern char _bss_start_btdm; extern char _bss_end_btdm; @@ -311,6 +323,11 @@ static const struct osi_funcs_t osi_funcs_ro = { ._btdm_sleep_exit_phase1 = btdm_sleep_exit_phase1_wrapper, ._btdm_sleep_exit_phase2 = NULL, ._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper, + ._coex_bt_request = coex_bt_request_wrapper, + ._coex_bt_release = coex_bt_release_wrapper, + ._coex_register_bt_cb = coex_register_bt_cb_wrapper, + ._coex_bb_reset_lock = coex_bb_reset_lock_wrapper, + ._coex_bb_reset_unlock = coex_bb_reset_unlock_wrapper, ._magic = OSI_MAGIC_VALUE, }; diff --git a/components/bt/lib b/components/bt/lib index 86fa066be..48ecf82c9 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 86fa066be494c2f3889dbea0821da44fdc1ba4df +Subproject commit 48ecf82c99f9e5d729e07c39a9d4c350a0f2f8e9 diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 75b76010d..9ad625631 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -19,6 +19,7 @@ else() "dbg_stubs.c" "dport_access.c" "dport_panic_highint_hdl.S" + "esp_adapter.c" "esp_err_to_name.c" "esp_timer.c" "esp_timer_esp32.c" @@ -48,7 +49,6 @@ else() "system_api.c" "task_wdt.c" "wifi_init.c" - "wifi_os_adapter.c" "hwcrypto/aes.c" "hwcrypto/sha.c") set(COMPONENT_ADD_INCLUDEDIRS "include") diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 1952e2feb..051c73326 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -924,6 +924,8 @@ menu Wi-Fi If enabled, WiFi & Bluetooth coexistence is controlled by software rather than hardware. Recommended for heavy traffic scenarios. Both coexistence configuration options are automatically managed, no user intervention is required. + If only Bluetooth is used, it is recommended to disable this option to reduce binary file + size. choice SW_COEXIST_PREFERENCE prompt "WiFi/Bluetooth coexistence performance preference" diff --git a/components/esp32/coexist.c b/components/esp32/coexist.c index 9eff30868..628269942 100644 --- a/components/esp32/coexist.c +++ b/components/esp32/coexist.c @@ -13,7 +13,7 @@ // limitations under the License. #include "esp_coexist.h" -#include "coexist_internal.h" +#include "esp_coexist_internal.h" const char *esp_coex_version_get(void) { diff --git a/components/esp32/coexist_internal.h b/components/esp32/coexist_internal.h deleted file mode 100644 index fb21e2487..000000000 --- a/components/esp32/coexist_internal.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2018-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. - -#ifndef __COEXIST_INTERNAL_H__ -#define __COEXIST_INTERNAL_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - COEX_PREFER_WIFI = 0, - COEX_PREFER_BT, - COEX_PREFER_BALANCE, - COEX_PREFER_NUM, -} coex_prefer_t; - -/** - * @brief Init software coexist - * extern function for internal use. - * - * @return Init ok or failed. - */ -esp_err_t coex_init(void); - -/** - * @brief De-init software coexist - * extern function for internal use. - */ -void coex_deinit(void); - -/** - * @brief Pause software coexist - * extern function for internal use. - */ -void coex_pause(void); - -/** - * @brief Resume software coexist - * extern function for internal use. - */ -void coex_resume(void); - -/** - * @brief Get software coexist version string - * extern function for internal use. - * @return : version string - */ -const char *coex_version_get(void); - -/** - * @brief Coexist performance preference set from libbt.a - * extern function for internal use. - * - * @param prefer : the prefer enumeration value - * @return : ESP_OK - success, other - failed - */ -esp_err_t coex_preference_set(coex_prefer_t prefer); - -#ifdef __cplusplus -} -#endif - -#endif /* __COEXIST_INTERNAL_H__ */ diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index bf28857fb..7e45abb03 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -59,7 +59,7 @@ #include "esp_task_wdt.h" #include "esp_phy_init.h" #include "esp_cache_err_int.h" -#include "esp_coexist.h" +#include "esp_coexist_internal.h" #include "esp_panic.h" #include "esp_core_dump.h" #include "esp_app_trace.h" @@ -412,6 +412,10 @@ void start_cpu0_default(void) } #endif +#if CONFIG_SW_COEXIST_ENABLE + esp_coex_adapter_register(&g_coex_adapter_funcs); +#endif + portBASE_TYPE res = xTaskCreatePinnedToCore(&main_task, "main", ESP_TASK_MAIN_STACK, NULL, ESP_TASK_MAIN_PRIO, NULL, 0); diff --git a/components/esp32/wifi_os_adapter.c b/components/esp32/esp_adapter.c similarity index 74% rename from components/esp32/wifi_os_adapter.c rename to components/esp32/esp_adapter.c index e63b0135f..342494233 100644 --- a/components/esp32/wifi_os_adapter.c +++ b/components/esp32/esp_adapter.c @@ -46,6 +46,8 @@ #include "os.h" #include "esp_smartconfig.h" #include "smartconfig_ack.h" +#include "esp_coexist_internal.h" +#include "esp_coexist_adapter.h" extern void esp_dport_access_stall_other_cpu_start_wrap(void); @@ -100,38 +102,38 @@ static void * IRAM_ATTR wifi_zalloc_wrapper(size_t size) } wifi_static_queue_t* wifi_create_queue( int queue_len, int item_size) -{ +{ wifi_static_queue_t *queue = NULL; - + queue = (wifi_static_queue_t*)heap_caps_malloc(sizeof(wifi_static_queue_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); if (!queue) { return NULL; } - + #if CONFIG_SPIRAM_USE_MALLOC queue->storage = heap_caps_calloc(1, sizeof(StaticQueue_t) + (queue_len*item_size), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); if (!queue->storage) { goto _error; } - + queue->handle = xQueueCreateStatic( queue_len, item_size, ((uint8_t*)(queue->storage)) + sizeof(StaticQueue_t), (StaticQueue_t*)(queue->storage)); - + if (!queue->handle) { goto _error; } - + return queue; - + _error: if (queue) { if (queue->storage) { free(queue->storage); } - + free(queue); } - + return NULL; #else queue->handle = xQueueCreate( queue_len, item_size); @@ -154,26 +156,26 @@ void wifi_delete_queue(wifi_static_queue_t *queue) } } -static void * IRAM_ATTR wifi_create_queue_wrapper(int queue_len, int item_size) +static void * wifi_create_queue_wrapper(int queue_len, int item_size) { return wifi_create_queue(queue_len, item_size); } -static void IRAM_ATTR wifi_delete_queue_wrapper(void *queue) +static void wifi_delete_queue_wrapper(void *queue) { wifi_delete_queue(queue); } -static void IRAM_ATTR set_isr_wrapper(int32_t n, void *f, void *arg) +static void set_isr_wrapper(int32_t n, void *f, void *arg) { xt_set_interrupt_handler(n, (xt_handler)f, arg); } -static void * IRAM_ATTR spin_lock_create_wrapper(void) +static void * 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; @@ -184,10 +186,10 @@ static void * IRAM_ATTR spin_lock_create_wrapper(void) static uint32_t IRAM_ATTR wifi_int_disable_wrapper(void *wifi_int_mux) { if (xPortInIsrContext()) { - portENTER_CRITICAL_ISR(wifi_int_mux); - } else { - portENTER_CRITICAL(wifi_int_mux); - } + portENTER_CRITICAL_ISR(wifi_int_mux); + } else { + portENTER_CRITICAL(wifi_int_mux); + } return 0; } @@ -195,10 +197,10 @@ static uint32_t IRAM_ATTR wifi_int_disable_wrapper(void *wifi_int_mux) static void IRAM_ATTR wifi_int_restore_wrapper(void *wifi_int_mux, uint32_t tmp) { if (xPortInIsrContext()) { - portEXIT_CRITICAL_ISR(wifi_int_mux); - } else { - portEXIT_CRITICAL(wifi_int_mux); - } + portEXIT_CRITICAL_ISR(wifi_int_mux); + } else { + portEXIT_CRITICAL(wifi_int_mux); + } } static void IRAM_ATTR task_yield_from_isr_wrapper(void) @@ -206,12 +208,12 @@ static void IRAM_ATTR task_yield_from_isr_wrapper(void) portYIELD_FROM_ISR(); } -static void *IRAM_ATTR semphr_create_wrapper(uint32_t max, uint32_t init) +static void * semphr_create_wrapper(uint32_t max, uint32_t init) { return (void *)xSemaphoreCreateCounting(max, init); } -static void IRAM_ATTR semphr_delete_wrapper(void *semphr) +static void semphr_delete_wrapper(void *semphr) { vSemaphoreDelete(semphr); } @@ -226,7 +228,7 @@ static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw) return (int32_t)xSemaphoreGiveFromISR(semphr, hptw); } -static int32_t IRAM_ATTR semphr_take_wrapper(void *semphr, uint32_t block_time_tick) +static int32_t 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); @@ -235,22 +237,22 @@ static int32_t IRAM_ATTR semphr_take_wrapper(void *semphr, uint32_t block_time_t } } -static int32_t IRAM_ATTR semphr_give_wrapper(void *semphr) +static int32_t semphr_give_wrapper(void *semphr) { return (int32_t)xSemaphoreGive(semphr); } -static void *IRAM_ATTR recursive_mutex_create_wrapper(void) +static void * recursive_mutex_create_wrapper(void) { return (void *)xSemaphoreCreateRecursiveMutex(); } -static void *IRAM_ATTR mutex_create_wrapper(void) +static void * mutex_create_wrapper(void) { return (void *)xSemaphoreCreateMutex(); } -static void IRAM_ATTR mutex_delete_wrapper(void *mutex) +static void mutex_delete_wrapper(void *mutex) { vSemaphoreDelete(mutex); } @@ -265,12 +267,12 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) return (int32_t)xSemaphoreGiveRecursive(mutex); } -static void *IRAM_ATTR queue_create_wrapper(uint32_t queue_len, uint32_t item_size) +static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) { return (void *)xQueueCreate(queue_len, item_size); } -static int32_t IRAM_ATTR queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) +static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_tick) { if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { return (int32_t)xQueueSend(queue, item, portMAX_DELAY); @@ -284,17 +286,17 @@ static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, vo return (int32_t)xQueueSendFromISR(queue, item, hptw); } -static int32_t IRAM_ATTR queue_send_to_back_wrapper(void *queue, void *item, uint32_t block_time_tick) +static int32_t queue_send_to_back_wrapper(void *queue, void *item, uint32_t block_time_tick) { - return (int32_t)xQueueGenericSend(queue, item, block_time_tick, queueSEND_TO_BACK); + return (int32_t)xQueueGenericSend(queue, item, block_time_tick, queueSEND_TO_BACK); } -static int32_t IRAM_ATTR queue_send_to_front_wrapper(void *queue, void *item, uint32_t block_time_tick) +static int32_t queue_send_to_front_wrapper(void *queue, void *item, uint32_t block_time_tick) { return (int32_t)xQueueGenericSend(queue, item, block_time_tick, queueSEND_TO_FRONT); } -static int32_t IRAM_ATTR queue_recv_wrapper(void *queue, void *item, uint32_t block_time_tick) +static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t block_time_tick) { if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { return (int32_t)xQueueReceive(queue, item, portMAX_DELAY); @@ -303,7 +305,7 @@ static int32_t IRAM_ATTR queue_recv_wrapper(void *queue, void *item, uint32_t bl } } -static uint32_t IRAM_ATTR event_group_wait_bits_wrapper(void *event, uint32_t bits_to_wait_for, int clear_on_exit, int wait_for_all_bits, uint32_t block_time_tick) +static uint32_t event_group_wait_bits_wrapper(void *event, uint32_t bits_to_wait_for, int clear_on_exit, int wait_for_all_bits, uint32_t block_time_tick) { if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) { return (uint32_t)xEventGroupWaitBits(event, bits_to_wait_for, clear_on_exit, wait_for_all_bits, portMAX_DELAY); @@ -312,12 +314,12 @@ static uint32_t IRAM_ATTR event_group_wait_bits_wrapper(void *event, uint32_t bi } } -static int32_t IRAM_ATTR task_create_pinned_to_core_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) +static int32_t task_create_pinned_to_core_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)); } -static int32_t IRAM_ATTR task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle) +static int32_t task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle) { return (uint32_t)xTaskCreate(task_func, name, stack_depth, param, prio, task_handle); } @@ -328,16 +330,11 @@ static int32_t IRAM_ATTR task_ms_to_tick_wrapper(uint32_t ms) } -static int32_t IRAM_ATTR task_get_max_priority_wrapper(void) +static int32_t task_get_max_priority_wrapper(void) { return (int32_t)(configMAX_PRIORITIES); } -static int32_t IRAM_ATTR phy_rf_init_wrapper(const void* init_data, uint32_t mode, void* calibration_data, uint32_t module) -{ - return esp_phy_rf_init( init_data, mode, calibration_data, module); -} - static void IRAM_ATTR timer_arm_wrapper(void *timer, uint32_t tmout, bool repeat) { ets_timer_arm(timer, tmout, repeat); @@ -348,12 +345,12 @@ static void IRAM_ATTR timer_disarm_wrapper(void *timer) ets_timer_disarm(timer); } -static void IRAM_ATTR timer_done_wrapper(void *ptimer) +static void timer_done_wrapper(void *ptimer) { ets_timer_done(ptimer); } -static void IRAM_ATTR timer_setfn_wrapper(void *ptimer, void *pfunction, void *parg) +static void timer_setfn_wrapper(void *ptimer, void *pfunction, void *parg) { ets_timer_setfn(ptimer, pfunction, parg); } @@ -363,7 +360,7 @@ static void IRAM_ATTR timer_arm_us_wrapper(void *ptimer, uint32_t us, bool repea ets_timer_arm_us(ptimer, us, repeat); } -static int IRAM_ATTR get_time_wrapper(void *t) +static int get_time_wrapper(void *t) { return os_get_time(t); } @@ -373,7 +370,7 @@ static void * IRAM_ATTR malloc_internal_wrapper(size_t size) return heap_caps_malloc(size, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); } -static void * IRAM_ATTR realloc_internal_wrapper(void *ptr, size_t size) +static void * IRAM_ATTR realloc_internal_wrapper(void *ptr, size_t size) { return heap_caps_realloc(ptr, size, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); } @@ -392,11 +389,81 @@ static void * IRAM_ATTR zalloc_internal_wrapper(size_t size) return ptr; } -static void IRAM_ATTR sc_ack_send_wrapper(void *param) +static void sc_ack_send_wrapper(void *param) { return sc_ack_send((sc_ack_t *)param); } +static uint32_t coex_status_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_status_get(); +#else + return 0; +#endif +} + +static int coex_wifi_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_wifi_request(event, latency, duration); +#else + return 0; +#endif +} + +static int coex_wifi_release_wrapper(uint32_t event) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_wifi_release(event); +#else + return 0; +#endif +} + +int IRAM_ATTR coex_bt_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_bt_request(event, latency, duration); +#else + return 0; +#endif +} + +int IRAM_ATTR coex_bt_release_wrapper(uint32_t event) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_bt_release(event); +#else + return 0; +#endif +} + +int coex_register_bt_cb_wrapper(coex_func_cb_t cb) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_register_bt_cb(cb); +#else + return 0; +#endif +} + +uint32_t IRAM_ATTR coex_bb_reset_lock_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_bb_reset_lock(); +#else + return 0; +#endif +} + +void IRAM_ATTR coex_bb_reset_unlock_wrapper(uint32_t restore) +{ +#if CONFIG_SW_COEXIST_ENABLE + coex_bb_reset_unlock(restore); +#endif +} + wifi_osi_funcs_t g_wifi_osi_funcs = { ._version = ESP_WIFI_OS_ADAPTER_VERSION, ._set_isr = set_isr_wrapper, @@ -406,12 +473,9 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._spin_lock_delete = free, ._wifi_int_disable = wifi_int_disable_wrapper, ._wifi_int_restore = wifi_int_restore_wrapper, - ._task_yield = vPortYield, ._task_yield_from_isr = task_yield_from_isr_wrapper, ._semphr_create = semphr_create_wrapper, ._semphr_delete = semphr_delete_wrapper, - ._semphr_take_from_isr = semphr_take_from_isr_wrapper, - ._semphr_give_from_isr = semphr_give_from_isr_wrapper, ._semphr_take = semphr_take_wrapper, ._semphr_give = semphr_give_wrapper, ._mutex_create = mutex_create_wrapper, @@ -426,7 +490,6 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._queue_send_to_back = queue_send_to_back_wrapper, ._queue_send_to_front = queue_send_to_front_wrapper, ._queue_recv = queue_recv_wrapper, - ._queue_recv_from_isr = xQueueReceiveFromISR, ._queue_msg_waiting = uxQueueMessagesWaiting, ._event_group_create = xEventGroupCreate, ._event_group_delete = vEventGroupDelete, @@ -440,19 +503,15 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._task_ms_to_tick = task_ms_to_tick_wrapper, ._task_get_current_task = xTaskGetCurrentTaskHandle, ._task_get_max_priority = task_get_max_priority_wrapper, - ._is_in_isr = xPortInIsrContext, ._malloc = malloc, ._free = free, ._get_free_heap_size = esp_get_free_heap_size, ._rand = esp_random, ._dport_access_stall_other_cpu_start_wrap = esp_dport_access_stall_other_cpu_start_wrap, ._dport_access_stall_other_cpu_end_wrap = esp_dport_access_stall_other_cpu_end_wrap, - ._phy_rf_init = phy_rf_init_wrapper, ._phy_rf_deinit = esp_phy_rf_deinit, ._phy_load_cal_and_init = esp_phy_load_cal_and_init, ._read_mac = esp_read_mac, - ._timer_init = ets_timer_init, - ._timer_deinit = ets_timer_deinit, ._timer_arm = timer_arm_wrapper, ._timer_disarm = timer_disarm_wrapper, ._timer_done = timer_done_wrapper, @@ -481,7 +540,7 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._malloc_internal = malloc_internal_wrapper, ._realloc_internal = realloc_internal_wrapper, ._calloc_internal = calloc_internal_wrapper, - ._zalloc_internal = zalloc_internal_wrapper, + ._zalloc_internal = zalloc_internal_wrapper, ._wifi_malloc = wifi_malloc, ._wifi_realloc = wifi_realloc, ._wifi_calloc = wifi_calloc, @@ -494,5 +553,32 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._modem_sleep_deregister = esp_modem_sleep_deregister, ._sc_ack_send = sc_ack_send_wrapper, ._sc_ack_send_stop = sc_ack_send_stop, + ._coex_status_get = coex_status_get_wrapper, + ._coex_wifi_request = coex_wifi_request_wrapper, + ._coex_wifi_release = coex_wifi_release_wrapper, ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, }; + +coex_adapter_funcs_t g_coex_adapter_funcs = { + ._version = COEX_ADAPTER_VERSION, + ._spin_lock_create = spin_lock_create_wrapper, + ._spin_lock_delete = free, + ._int_disable = wifi_int_disable_wrapper, + ._int_enable = wifi_int_restore_wrapper, + ._task_yield_from_isr = task_yield_from_isr_wrapper, + ._semphr_create = semphr_create_wrapper, + ._semphr_delete = semphr_delete_wrapper, + ._semphr_take_from_isr = semphr_take_from_isr_wrapper, + ._semphr_give_from_isr = semphr_give_from_isr_wrapper, + ._semphr_take = semphr_take_wrapper, + ._semphr_give = semphr_give_wrapper, + ._is_in_isr = xPortInIsrContext, + ._malloc_internal = malloc_internal_wrapper, + ._free = free, + ._timer_disarm = timer_disarm_wrapper, + ._timer_done = timer_done_wrapper, + ._timer_setfn = timer_setfn_wrapper, + ._timer_arm_us = timer_arm_us_wrapper, + ._esp_timer_get_time = esp_timer_get_time, + ._magic = COEX_ADAPTER_MAGIC, +}; diff --git a/components/esp32/include/esp_coexist_adapter.h b/components/esp32/include/esp_coexist_adapter.h new file mode 100644 index 000000000..f2a38c31e --- /dev/null +++ b/components/esp32/include/esp_coexist_adapter.h @@ -0,0 +1,59 @@ +// Copyright 2019 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. + +#ifndef __ESP_COEXIST_ADAPTER_H__ +#define __ESP_COEXIST_ADAPTER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define COEX_ADAPTER_VERSION 0x00000001 +#define COEX_ADAPTER_MAGIC 0xDEADBEAF + +#define COEX_ADAPTER_FUNCS_TIME_BLOCKING 0xffffffff + +typedef struct { + int32_t _version; + void *(* _spin_lock_create)(void); + void (* _spin_lock_delete)(void *lock); + uint32_t (*_int_disable)(void *mux); + void (*_int_enable)(void *mux, uint32_t tmp); + void (*_task_yield_from_isr)(void); + void *(*_semphr_create)(uint32_t max, uint32_t init); + void (*_semphr_delete)(void *semphr); + int32_t (*_semphr_take_from_isr)(void *semphr, void *hptw); + int32_t (*_semphr_give_from_isr)(void *semphr, void *hptw); + int32_t (*_semphr_take)(void *semphr, uint32_t block_time_tick); + int32_t (*_semphr_give)(void *semphr); + int32_t (* _is_in_isr)(void); + void * (* _malloc_internal)(size_t size); + void (* _free)(void *p); + void (* _timer_disarm)(void *timer); + void (* _timer_done)(void *ptimer); + void (* _timer_setfn)(void *ptimer, void *pfunction, void *parg); + void (* _timer_arm_us)(void *ptimer, uint32_t us, bool repeat); + int64_t (* _esp_timer_get_time)(void); + int32_t _magic; +} coex_adapter_funcs_t; + +extern coex_adapter_funcs_t g_coex_adapter_funcs; + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_COEXIST_ADAPTER_H__ */ diff --git a/components/esp32/include/esp_coexist_internal.h b/components/esp32/include/esp_coexist_internal.h new file mode 100644 index 000000000..1d94d6db7 --- /dev/null +++ b/components/esp32/include/esp_coexist_internal.h @@ -0,0 +1,163 @@ +// Copyright 2018-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. + +#ifndef __ESP_COEXIST_INTERNAL_H__ +#define __ESP_COEXIST_INTERNAL_H__ + +#include +#include "esp_coexist_adapter.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + COEX_PREFER_WIFI = 0, + COEX_PREFER_BT, + COEX_PREFER_BALANCE, + COEX_PREFER_NUM, +} coex_prefer_t; + +typedef void (* coex_func_cb_t)(uint32_t event, int sched_cnt); + +/** + * @brief Init software coexist + * extern function for internal use. + * + * @return Init ok or failed. + */ +esp_err_t coex_init(void); + +/** + * @brief De-init software coexist + * extern function for internal use. + */ +void coex_deinit(void); + +/** + * @brief Pause software coexist + * extern function for internal use. + */ +void coex_pause(void); + +/** + * @brief Resume software coexist + * extern function for internal use. + */ +void coex_resume(void); + +/** + * @brief Get software coexist version string + * extern function for internal use. + * @return : version string + */ +const char *coex_version_get(void); + +/** + * @brief Coexist performance preference set from libbt.a + * extern function for internal use. + * + * @param prefer : the prefer enumeration value + * @return : ESP_OK - success, other - failed + */ +esp_err_t coex_preference_set(coex_prefer_t prefer); + +/** + * @brief Get software coexist status. + * @return : software coexist status + */ +uint32_t coex_status_get(void); + +/** + * @brief WiFi requests coexistence. + * + * @param event : WiFi event + * @param latency : WiFi will request coexistence after latency + * @param duration : duration for WiFi to request coexistence + * @return : 0 - success, other - failed + */ +int coex_wifi_request(uint32_t event, uint32_t latency, uint32_t duration); + +/** + * @brief WiFi release coexistence. + * + * @param event : WiFi event + * @return : 0 - success, other - failed + */ +int coex_wifi_release(uint32_t event); + +/** + * @brief Blue tooth requests coexistence. + * + * @param event : blue tooth event + * @param latency : blue tooth will request coexistence after latency + * @param duration : duration for blue tooth to request coexistence + * @return : 0 - success, other - failed + */ +int coex_bt_request(uint32_t event, uint32_t latency, uint32_t duration); + +/** + * @brief Blue tooth release coexistence. + * + * @param event : blue tooth event + * @return : 0 - success, other - failed + */ +int coex_bt_release(uint32_t event); + +/** + * @brief Register callback function for blue tooth. + * + * @param cb : callback function + * @return : 0 - success, other - failed + */ +int coex_register_bt_cb(coex_func_cb_t cb); + +/** + * @brief Lock before reset base band. + * + * @return : lock value + */ +uint32_t coex_bb_reset_lock(void); + +/** + * @brief Unlock after reset base band. + * + * @param restore : lock value + */ +void coex_bb_reset_unlock(uint32_t restore); + +/** + * @brief Register coexistence adapter functions. + * + * @param funcs : coexistence adapter functions + * @return : ESP_OK - success, other - failed + */ +esp_err_t esp_coex_adapter_register(coex_adapter_funcs_t *funcs); + +/** + * @brief Check the MD5 values of the coexistence adapter header files in IDF and WiFi library + * + * @attention 1. It is used for internal CI version check + * + * @return + * - ESP_OK : succeed + * - ESP_WIFI_INVALID_ARG : MD5 check fail + */ +esp_err_t esp_coex_adapter_funcs_md5_check(const char *md5); + +#ifdef __cplusplus +} +#endif + +#endif /* __ESP_COEXIST_INTERNAL_H__ */ diff --git a/components/esp32/include/esp_wifi_internal.h b/components/esp32/include/esp_wifi_internal.h index 67bfd926d..979d0134e 100644 --- a/components/esp32/include/esp_wifi_internal.h +++ b/components/esp32/include/esp_wifi_internal.h @@ -249,6 +249,15 @@ void *wifi_realloc( void *ptr, size_t size ); */ void *wifi_calloc( size_t n, size_t size ); +/** + * @brief Update WiFi MAC time + * + * @param uint32_t time_delta : time duration since the WiFi/BT common clock is disabled + * + * @return Always returns ESP_OK + */ +typedef esp_err_t (* wifi_mac_time_update_cb_t)( uint32_t time_delta ); + /** * @brief Update WiFi MAC time * diff --git a/components/esp32/include/esp_wifi_os_adapter.h b/components/esp32/include/esp_wifi_os_adapter.h index 1dd522c49..752ccf990 100644 --- a/components/esp32/include/esp_wifi_os_adapter.h +++ b/components/esp32/include/esp_wifi_os_adapter.h @@ -21,7 +21,7 @@ extern "C" { #endif -#define ESP_WIFI_OS_ADAPTER_VERSION 0x00000001 +#define ESP_WIFI_OS_ADAPTER_VERSION 0x00000002 #define ESP_WIFI_OS_ADAPTER_MAGIC 0xDEADBEAF #define OSI_FUNCS_TIME_BLOCKING 0xffffffff @@ -39,12 +39,9 @@ typedef struct { void (* _spin_lock_delete)(void *lock); uint32_t (*_wifi_int_disable)(void *wifi_int_mux); void (*_wifi_int_restore)(void *wifi_int_mux, uint32_t tmp); - void (*_task_yield)(void); void (*_task_yield_from_isr)(void); void *(*_semphr_create)(uint32_t max, uint32_t init); void (*_semphr_delete)(void *semphr); - int32_t (*_semphr_take_from_isr)(void *semphr, void *hptw); - int32_t (*_semphr_give_from_isr)(void *semphr, void *hptw); int32_t (*_semphr_take)(void *semphr, uint32_t block_time_tick); int32_t (*_semphr_give)(void *semphr); void *(*_mutex_create)(void); @@ -59,7 +56,6 @@ typedef struct { int32_t (* _queue_send_to_back)(void *queue, void *item, uint32_t block_time_tick); int32_t (* _queue_send_to_front)(void *queue, void *item, uint32_t block_time_tick); int32_t (* _queue_recv)(void *queue, void *item, uint32_t block_time_tick); - int32_t (* _queue_recv_from_isr)(void *queue, void * const item, int32_t * const hptw); uint32_t (* _queue_msg_waiting)(void *queue); void *(* _event_group_create)(void); void (* _event_group_delete)(void *event); @@ -73,19 +69,15 @@ typedef struct { int32_t (* _task_ms_to_tick)(uint32_t ms); void *(* _task_get_current_task)(void); int32_t (* _task_get_max_priority)(void); - int32_t (* _is_in_isr)(void); void *(* _malloc)(uint32_t size); void (* _free)(void *p); uint32_t (* _get_free_heap_size)(void); uint32_t (* _rand)(void); void (* _dport_access_stall_other_cpu_start_wrap)(void); void (* _dport_access_stall_other_cpu_end_wrap)(void); - int32_t (* _phy_rf_init)(const void * init_data, uint32_t mode, void * calibration_data, uint32_t module); int32_t (* _phy_rf_deinit)(uint32_t module); void (* _phy_load_cal_and_init)(uint32_t module); int32_t (* _read_mac)(uint8_t* mac, uint32_t type); - void (* _timer_init)(void); - void (* _timer_deinit)(void); void (* _timer_arm)(void *timer, uint32_t tmout, bool repeat); void (* _timer_disarm)(void *timer); void (* _timer_done)(void *ptimer); @@ -127,6 +119,9 @@ typedef struct { int32_t (* _modem_sleep_deregister)(uint32_t module); void (* _sc_ack_send)(void *param); void (* _sc_ack_send_stop)(void); + uint32_t (* _coex_status_get)(void); + int32_t (* _coex_wifi_request)(uint32_t event, uint32_t latency, uint32_t duration); + int32_t (* _coex_wifi_release)(uint32_t event); int32_t _magic; } wifi_osi_funcs_t; diff --git a/components/esp32/lib b/components/esp32/lib index 8ab53aee3..61530b0bd 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 8ab53aee3dff28cf374d25a8defdea0dc7c2fa32 +Subproject commit 61530b0bddb1de1cdcc73b8aa5f290da970bd1fe diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index d72f60dc0..18b3fa8b4 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -36,10 +36,11 @@ #include "freertos/portmacro.h" #include "phy.h" #include "phy_init_data.h" -#include "coexist_internal.h" +#include "esp_coexist_internal.h" #include "driver/periph_ctrl.h" #include "esp_wifi_internal.h" +extern wifi_mac_time_update_cb_t s_wifi_mac_time_update_cb; static const char* TAG = "phy_init"; @@ -92,7 +93,9 @@ static inline void phy_update_wifi_mac_time(bool en_clock_stopped, int64_t now) if (s_common_clock_disable_time) { uint32_t diff = (uint64_t)now - s_common_clock_disable_time; - esp_wifi_internal_update_mac_time(diff); + if (s_wifi_mac_time_update_cb) { + s_wifi_mac_time_update_cb(diff); + } s_common_clock_disable_time = 0; ESP_LOGD(TAG, "wifi mac time delta: %u", diff); } @@ -159,14 +162,6 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibrat #endif } - -extern esp_err_t wifi_osi_funcs_register(wifi_osi_funcs_t *osi_funcs); - status = wifi_osi_funcs_register(&g_wifi_osi_funcs); - if(status != ESP_OK) { - ESP_LOGE(TAG, "failed to register wifi os adapter, ret(%d)", status); - _lock_release(&s_phy_rf_init_lock); - return ESP_FAIL; - } coex_bt_high_prio(); } } diff --git a/components/esp32/test/CMakeLists.txt b/components/esp32/test/CMakeLists.txt index 939b386a5..b99e2888b 100644 --- a/components/esp32/test/CMakeLists.txt +++ b/components/esp32/test/CMakeLists.txt @@ -21,9 +21,16 @@ execute_process(COMMAND md5sum ${IDF_PATH}/components/esp32/include/esp_wifi_cry COMMAND cut -c 1-7 OUTPUT_VARIABLE WIFI_CRYPTO_MD5 OUTPUT_STRIP_TRAILING_WHITESPACE) + +# Calculate MD5 value of header file esp_coexist_adapter.h +execute_process(COMMAND md5sum ${IDF_PATH}/components/esp32/include/esp_coexist_adapter.h + COMMAND cut -c 1-7 + OUTPUT_VARIABLE COEX_ADAPTER_MD5 + OUTPUT_STRIP_TRAILING_WHITESPACE) add_definitions(-DWIFI_OS_ADAPTER_MD5=\"${WIFI_OS_ADAPTER_MD5}\") add_definitions(-DWIFI_CRYPTO_MD5=\"${WIFI_CRYPTO_MD5}\") +add_definitions(-DCOEX_ADAPTER_MD5=\"${COEX_ADAPTER_MD5}\") add_custom_target(esp32_test_logo DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/test_tjpgd_logo.h") diff --git a/components/esp32/test/component.mk b/components/esp32/test/component.mk index 11e0f7ed7..6fb41f30a 100644 --- a/components/esp32/test/component.mk +++ b/components/esp32/test/component.mk @@ -16,6 +16,9 @@ CFLAGS+=-DWIFI_OS_ADAPTER_MD5=$(WIFI_OS_ADAPTER_MD5_VAL) WIFI_CRYPTO_MD5_VAL=\"$(shell md5sum $(IDF_PATH)/components/esp32/include/esp_wifi_crypto_types.h | cut -c 1-7)\" CFLAGS+=-DWIFI_CRYPTO_MD5=$(WIFI_CRYPTO_MD5_VAL) +# Calculate MD5 value of header file esp_coexist_adapter.h +COEX_ADAPTER_MD5_VAL=\"$(shell md5sum $(IDF_PATH)/components/esp32/include/esp_coexist_adapter.h | cut -c 1-7)\" +CFLAGS+=-DCOEX_ADAPTER_MD5=$(COEX_ADAPTER_MD5_VAL) test_tjpgd.o: test_tjpgd_logo.h diff --git a/components/esp32/test/test_header_files_md5.c b/components/esp32/test/test_header_files_md5.c index 009de0ea5..c2d80350a 100644 --- a/components/esp32/test/test_header_files_md5.c +++ b/components/esp32/test/test_header_files_md5.c @@ -4,6 +4,7 @@ #include "unity.h" #include "esp_log.h" #include "esp_wifi_internal.h" +#include "esp_coexist_internal.h" static const char* TAG = "test_header_files_md5"; @@ -26,3 +27,13 @@ TEST_CASE("wifi crypto types MD5","[wifi]") ESP_LOGI(TAG, "test passed..."); } + +TEST_CASE("coexist adapter MD5","[coex]") +{ + const char *test_coex_adapter_funcs_md5 = COEX_ADAPTER_MD5; + + ESP_LOGI(TAG, "test coexist adapter MD5..."); + TEST_ESP_OK(esp_coex_adapter_funcs_md5_check(test_coex_adapter_funcs_md5)); + + ESP_LOGI(TAG, "test passed..."); +} diff --git a/components/esp32/wifi_init.c b/components/esp32/wifi_init.c index 2b3dae6b0..cf5d79b7b 100644 --- a/components/esp32/wifi_init.c +++ b/components/esp32/wifi_init.c @@ -27,6 +27,9 @@ mesh_event_cb_t g_mesh_event_cb = NULL; static esp_pm_lock_handle_t s_wifi_modem_sleep_lock; #endif +/* Callback function to update WiFi MAC time */ +wifi_mac_time_update_cb_t s_wifi_mac_time_update_cb = NULL; + static void __attribute__((constructor)) s_set_default_wifi_log_level() { /* WiFi libraries aren't compiled to know CONFIG_LOG_DEFAULT_LEVEL, @@ -97,7 +100,10 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) #endif esp_event_set_default_wifi_handlers(); esp_err_t result = esp_wifi_init_internal(config); - esp_wifi_set_debug_log(); + if (result == ESP_OK) { + esp_wifi_set_debug_log(); + s_wifi_mac_time_update_cb = esp_wifi_internal_update_mac_time; + } return result; }