diff --git a/components/esp_rom/include/esp32c3/rom/apb_dma.h b/components/esp_rom/include/esp32c3/rom/apb_backup_dma.h similarity index 100% rename from components/esp_rom/include/esp32c3/rom/apb_dma.h rename to components/esp_rom/include/esp32c3/rom/apb_backup_dma.h diff --git a/components/esp_system/port/soc/esp32c3/CMakeLists.txt b/components/esp_system/port/soc/esp32c3/CMakeLists.txt index aadf132fcd..7a0a56c9ee 100644 --- a/components/esp_system/port/soc/esp32c3/CMakeLists.txt +++ b/components/esp_system/port/soc/esp32c3/CMakeLists.txt @@ -1,7 +1,7 @@ set(srcs "clk.c" "reset_reason.c" "../../async_memcpy_impl_gdma.c" - "apb_dma.c" + "apb_backup_dma.c" "../../arch/riscv/panic_arch.c") add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs}) diff --git a/components/esp_system/port/soc/esp32c3/apb_dma.c b/components/esp_system/port/soc/esp32c3/apb_backup_dma.c similarity index 57% rename from components/esp_system/port/soc/esp32c3/apb_dma.c rename to components/esp_system/port/soc/esp32c3/apb_backup_dma.c index 5702d4b763..24b0ad0e04 100644 --- a/components/esp_system/port/soc/esp32c3/apb_dma.c +++ b/components/esp_system/port/soc/esp32c3/apb_backup_dma.c @@ -13,32 +13,36 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "soc/soc_caps.h" + +#if SOC_APB_BACKUP_DMA #include "esp_attr.h" #include "freertos/FreeRTOS.h" #include "freertos/portmacro.h" -#include "esp32c3/rom/apb_dma.h" +#include "esp32c3/rom/apb_backup_dma.h" -static portMUX_TYPE apb_backup_mutex = portMUX_INITIALIZER_UNLOCKED; +static portMUX_TYPE s_apb_backup_dma_mutex = portMUX_INITIALIZER_UNLOCKED; -static void IRAM_ATTR apb_backup_lock(void) +static void IRAM_ATTR apb_backup_dma_lock(void) { if (xPortInIsrContext()) { - portENTER_CRITICAL_ISR(&apb_backup_mutex); + portENTER_CRITICAL_ISR(&s_apb_backup_dma_mutex); } else { - portENTER_CRITICAL(&apb_backup_mutex); + portENTER_CRITICAL(&s_apb_backup_dma_mutex); } } -static void IRAM_ATTR apb_backup_unlock(void) +static void IRAM_ATTR apb_backup_dma_unlock(void) { if (xPortInIsrContext()) { - portEXIT_CRITICAL_ISR(&apb_backup_mutex); + portEXIT_CRITICAL_ISR(&s_apb_backup_dma_mutex); } else { - portEXIT_CRITICAL(&apb_backup_mutex); + portEXIT_CRITICAL(&s_apb_backup_dma_mutex); } } -void esp_apb_backup_lock_init(void) +void esp_apb_backup_dma_lock_init(void) { - ets_apb_backup_init_lock_func(apb_backup_lock, apb_backup_unlock); + ets_apb_backup_init_lock_func(apb_backup_dma_lock, apb_backup_dma_unlock); } +#endif diff --git a/components/esp_system/startup.c b/components/esp_system/startup.c index d8f4d039d5..69b7fe19d5 100644 --- a/components/esp_system/startup.c +++ b/components/esp_system/startup.c @@ -89,6 +89,11 @@ uint64_t g_startup_time = 0; +#if SOC_APB_BACKUP_DMA +// APB DMA lock initialising API +extern void esp_apb_backup_dma_lock_init(void); +#endif + // App entry point for core 0 extern void esp_startup_start_app(void); @@ -380,6 +385,10 @@ IRAM_ATTR ESP_SYSTEM_INIT_FN(init_components0, BIT(0)) esp_core_dump_init(); #endif +#if SOC_APB_BACKUP_DMA + esp_apb_backup_dma_lock_init(); +#endif + #if CONFIG_SW_COEXIST_ENABLE esp_coex_adapter_register(&g_coex_adapter_funcs); coex_pre_init(); diff --git a/components/esp_wifi/CMakeLists.txt b/components/esp_wifi/CMakeLists.txt index 62a6dd7f00..d7e456c50e 100644 --- a/components/esp_wifi/CMakeLists.txt +++ b/components/esp_wifi/CMakeLists.txt @@ -8,14 +8,6 @@ if(${idf_target} STREQUAL "esp32s3") return() endif() -# remove these when wifi support is ready on esp32-c3 -if(${idf_target} STREQUAL "esp32c3") - idf_component_register(INCLUDE_DIRS "include" - REQUIRES esp_event - PRIV_REQUIRES wpa_supplicant nvs_flash esp_netif) - return() -endif() - if(CONFIG_ESP32_NO_BLOBS OR CONFIG_ESP32S2_NO_BLOBS) set(link_binary_libs 0) set(ldfragments) @@ -54,8 +46,10 @@ target_link_libraries(${COMPONENT_LIB} PUBLIC "-L ${CMAKE_CURRENT_SOURCE_DIR}/li if(link_binary_libs) set(phy phy) - set(blobs coexist core espnow mesh net80211 pp rtc smartconfig ${phy}) - + set(blobs coexist core espnow mesh net80211 pp smartconfig ${phy}) + if(${idf_target} STREQUAL "esp32") + list(APPEND blobs rtc) + endif() foreach(blob ${blobs}) add_prebuilt_library(${blob} "${CMAKE_CURRENT_SOURCE_DIR}/lib/${target_name}/lib${blob}.a" REQUIRES ${COMPONENT_NAME}) diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index 661cae116b..a9ae9b409f 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -390,4 +390,14 @@ menu "PHY" int default ESP32_PHY_MAX_WIFI_TX_POWER + config ESP32_PHY_MAC_BB_PD + bool "Power down MAC and baseband of Wi-Fi and Bluetooth when PHY is disabled" + depends on IDF_TARGET_ESP32C3 + default n + help + If enabled, the MAC and baseband of Wi-Fi and Bluetooth will be powered + down when PHY is disabled. Enabling this setting reduces power consumption + by a small amount but increases RAM use by approximately 4 KB(Wi-Fi only), + 2 KB(Bluetooth only) or 5.3 KB(Wi-Fi + Bluetooth). + endmenu # PHY diff --git a/components/esp_wifi/esp32/esp_adapter.c b/components/esp_wifi/esp32/esp_adapter.c index 8505b5d792..65f0c22b08 100644 --- a/components/esp_wifi/esp32/esp_adapter.c +++ b/components/esp_wifi/esp32/esp_adapter.c @@ -109,9 +109,6 @@ IRAM_ATTR void *wifi_calloc( size_t n, size_t size ) static void * IRAM_ATTR wifi_zalloc_wrapper(size_t size) { void *ptr = wifi_calloc(1, size); - if (ptr) { - memset(ptr, 0, size); - } return ptr; } @@ -494,9 +491,6 @@ static void * IRAM_ATTR calloc_internal_wrapper(size_t n, size_t size) static void * IRAM_ATTR zalloc_internal_wrapper(size_t size) { void *ptr = heap_caps_calloc(1, size, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); - if (ptr) { - memset(ptr, 0, size); - } return ptr; } diff --git a/components/esp_wifi/esp32c3/esp_adapter.c b/components/esp_wifi/esp32c3/esp_adapter.c new file mode 100644 index 0000000000..193c15b598 --- /dev/null +++ b/components/esp_wifi/esp32c3/esp_adapter.c @@ -0,0 +1,790 @@ +// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "freertos/event_groups.h" +#include "freertos/portmacro.h" +#include "riscv/interrupt.h" +#include "riscv/riscv_interrupts.h" +#include "esp_types.h" +#include "esp_system.h" +#include "esp_task.h" +#include "esp_intr_alloc.h" +#include "esp_attr.h" +#include "esp_log.h" +#include "esp_event.h" +#include "esp_heap_caps.h" +#include "esp_timer.h" +#include "esp_private/wifi_os_adapter.h" +#include "esp_private/wifi.h" +#include "esp_phy_init.h" +#include "esp32c3/clk.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/rtc.h" +#include "soc/syscon_reg.h" +#include "phy_init_data.h" +#include "driver/periph_ctrl.h" +#include "nvs.h" +#include "os.h" +#include "esp_smartconfig.h" +#include "esp_coexist_internal.h" +#include "esp_coexist_adapter.h" + +#define TAG "esp_adapter" + +#ifdef CONFIG_PM_ENABLE +extern void wifi_apb80m_request(void); +extern void wifi_apb80m_release(void); +#endif + +IRAM_ATTR void *wifi_malloc( size_t size ) +{ + return malloc(size); +} + +IRAM_ATTR void *wifi_realloc( void *ptr, size_t size ) +{ + return realloc(ptr, size); +} + +IRAM_ATTR void *wifi_calloc( size_t n, size_t size ) +{ + return calloc(n, size); +} + +static void * IRAM_ATTR wifi_zalloc_wrapper(size_t size) +{ + void *ptr = wifi_calloc(1, size); + return ptr; +} + +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; + } + + queue->handle = xQueueCreate( queue_len, item_size); + return queue; +} + +void wifi_delete_queue(wifi_static_queue_t *queue) +{ + if (queue) { + vQueueDelete(queue->handle); + free(queue); + } +} + +static void * wifi_create_queue_wrapper(int queue_len, int item_size) +{ + return wifi_create_queue(queue_len, item_size); +} + +static void wifi_delete_queue_wrapper(void *queue) +{ + wifi_delete_queue(queue); +} + +static bool IRAM_ATTR env_is_chip_wrapper(void) +{ +#ifdef CONFIG_IDF_ENV_FPGA + return false; +#else + return true; +#endif +} + +static void set_intr_wrapper(int32_t cpu_no, uint32_t intr_source, uint32_t intr_num, int32_t intr_prio) +{ + intr_matrix_route(intr_source, intr_num); + esprv_intc_int_set_priority(intr_num, intr_prio); + esprv_intc_int_set_type(intr_num, INTR_TYPE_LEVEL); +} + +static void clear_intr_wrapper(uint32_t intr_source, uint32_t intr_num) +{ + +} + +static void set_isr_wrapper(int32_t n, void *f, void *arg) +{ + intr_handler_set(n, (intr_handler_t)f, arg); +} + +static void enable_intr_wrapper(uint32_t intr_mask) +{ + esprv_intc_int_enable(intr_mask); +} + +static void disable_intr_wrapper(uint32_t intr_mask) +{ + esprv_intc_int_disable(intr_mask); +} + +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; + } + return NULL; +} + +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); + } + + return 0; +} + +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); + } +} + +static bool IRAM_ATTR is_from_isr_wrapper(void) +{ + return !xPortCanYield(); +} + +static void IRAM_ATTR task_yield_from_isr_wrapper(void) +{ + portYIELD_FROM_ISR(); +} + +static void * semphr_create_wrapper(uint32_t max, uint32_t init) +{ + return (void *)xSemaphoreCreateCounting(max, init); +} + +static void semphr_delete_wrapper(void *semphr) +{ + vSemaphoreDelete(semphr); +} + +static void wifi_thread_semphr_free(void* data) +{ + SemaphoreHandle_t *sem = (SemaphoreHandle_t*)(data); + + if (sem) { + vSemaphoreDelete(sem); + } +} + +static void * wifi_thread_semphr_get_wrapper(void) +{ + static bool s_wifi_thread_sem_key_init = false; + static pthread_key_t s_wifi_thread_sem_key; + SemaphoreHandle_t sem = NULL; + + if (s_wifi_thread_sem_key_init == false) { + if (0 != pthread_key_create(&s_wifi_thread_sem_key, wifi_thread_semphr_free)) { + return NULL; + } + s_wifi_thread_sem_key_init = true; + } + + sem = pthread_getspecific(s_wifi_thread_sem_key); + if (!sem) { + sem = xSemaphoreCreateCounting(1, 0); + if (sem) { + pthread_setspecific(s_wifi_thread_sem_key, sem); + ESP_LOGV(TAG, "thread sem create: sem=%p", sem); + } + } + + ESP_LOGV(TAG, "thread sem get: sem=%p", sem); + return (void*)sem; +} + +static int32_t IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw) +{ + return (int32_t)xSemaphoreTakeFromISR(semphr, hptw); +} + +static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw) +{ + return (int32_t)xSemaphoreGiveFromISR(semphr, hptw); +} + +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); + } else { + return (int32_t)xSemaphoreTake(semphr, block_time_tick); + } +} + +static int32_t semphr_give_wrapper(void *semphr) +{ + return (int32_t)xSemaphoreGive(semphr); +} + +static void * recursive_mutex_create_wrapper(void) +{ + return (void *)xSemaphoreCreateRecursiveMutex(); +} + +static void * mutex_create_wrapper(void) +{ + return (void *)xSemaphoreCreateMutex(); +} + +static void mutex_delete_wrapper(void *mutex) +{ + vSemaphoreDelete(mutex); +} + +static int32_t IRAM_ATTR mutex_lock_wrapper(void *mutex) +{ + return (int32_t)xSemaphoreTakeRecursive(mutex, portMAX_DELAY); +} + +static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) +{ + return (int32_t)xSemaphoreGiveRecursive(mutex); +} + +static void * queue_create_wrapper(uint32_t queue_len, uint32_t item_size) +{ + return (void *)xQueueCreate(queue_len, item_size); +} + +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); + } else { + return (int32_t)xQueueSend(queue, item, block_time_tick); + } +} + +static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, void *hptw) +{ + return (int32_t)xQueueSendFromISR(queue, item, hptw); +} + +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); +} + +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 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); + } else { + return (int32_t)xQueueReceive(queue, item, 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); + } else { + return (uint32_t)xEventGroupWaitBits(event, bits_to_wait_for, clear_on_exit, wait_for_all_bits, block_time_tick); + } +} + +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 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); +} + +static int32_t IRAM_ATTR task_ms_to_tick_wrapper(uint32_t ms) +{ + return (int32_t)(ms / portTICK_PERIOD_MS); +} + +static int32_t task_get_max_priority_wrapper(void) +{ + return (int32_t)(configMAX_PRIORITIES); +} + +static int32_t esp_event_post_wrapper(const char* event_base, int32_t event_id, void* event_data, size_t event_data_size, uint32_t ticks_to_wait) +{ + if (ticks_to_wait == OSI_FUNCS_TIME_BLOCKING) { + return (int32_t)esp_event_post(event_base, event_id, event_data, event_data_size, portMAX_DELAY); + } else { + return (int32_t)esp_event_post(event_base, event_id, event_data, event_data_size, ticks_to_wait); + } +} + +static void IRAM_ATTR wifi_apb80m_request_wrapper(void) +{ +#ifdef CONFIG_PM_ENABLE + wifi_apb80m_request(); +#endif +} + +static void IRAM_ATTR wifi_apb80m_release_wrapper(void) +{ +#ifdef CONFIG_PM_ENABLE + wifi_apb80m_release(); +#endif +} + +static void IRAM_ATTR timer_arm_wrapper(void *timer, uint32_t tmout, bool repeat) +{ + ets_timer_arm(timer, tmout, repeat); +} + +static void IRAM_ATTR timer_disarm_wrapper(void *timer) +{ + ets_timer_disarm(timer); +} + +static void IRAM_ATTR timer_done_wrapper(void *ptimer) +{ + ets_timer_done(ptimer); +} + +static void IRAM_ATTR timer_setfn_wrapper(void *ptimer, void *pfunction, void *parg) +{ + ets_timer_setfn(ptimer, pfunction, parg); +} + +static void IRAM_ATTR timer_arm_us_wrapper(void *ptimer, uint32_t us, bool repeat) +{ + ets_timer_arm_us(ptimer, us, repeat); +} + +static void wifi_reset_mac_wrapper(void) +{ + SET_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_MAC_RST); + CLEAR_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_MAC_RST); +} + +static void IRAM_ATTR wifi_rtc_enable_iso_wrapper(void) +{ +#if CONFIG_MAC_BB_PD + esp_mac_bb_power_down(); + SET_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_MAC_RST); +#endif +} + +static void IRAM_ATTR wifi_rtc_disable_iso_wrapper(void) +{ +#if CONFIG_MAC_BB_PD + esp_mac_bb_power_up(); + SET_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_MAC_RST); + CLEAR_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_MAC_RST); +#endif +} + +static void IRAM_ATTR wifi_clock_enable_wrapper(void) +{ + periph_module_enable(PERIPH_WIFI_MODULE); +} + +static void IRAM_ATTR wifi_clock_disable_wrapper(void) +{ + periph_module_disable(PERIPH_WIFI_MODULE); +} + +static int get_time_wrapper(void *t) +{ + return os_get_time(t); +} + +#define WIFI_LIGHT_SLEEP_CLK_WIDTH 12 +static uint32_t esp_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 - WIFI_LIGHT_SLEEP_CLK_WIDTH)); +} + +static void * IRAM_ATTR malloc_internal_wrapper(size_t size) +{ + return heap_caps_malloc(size, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); +} + +static void * IRAM_ATTR realloc_internal_wrapper(void *ptr, size_t size) +{ + return heap_caps_realloc(ptr, size, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); +} + +static void * IRAM_ATTR calloc_internal_wrapper(size_t n, size_t size) +{ + return heap_caps_calloc(n, size, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); +} + +static void * IRAM_ATTR zalloc_internal_wrapper(size_t size) +{ + void *ptr = heap_caps_calloc(1, size, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); + return ptr; +} + +static esp_err_t nvs_open_wrapper(const char* name, uint32_t open_mode, nvs_handle_t *out_handle) +{ + return nvs_open(name,(nvs_open_mode_t)open_mode, out_handle); +} + +static void esp_log_writev_wrapper(uint32_t level, const char *tag, const char *format, va_list args) +{ + return esp_log_writev((esp_log_level_t)level,tag,format,args); +} + +static void esp_log_write_wrapper(uint32_t level,const char *tag,const char *format, ...) +{ + va_list list; + va_start(list, format); + esp_log_writev((esp_log_level_t)level, tag, format, list); + va_end(list); +} + +static esp_err_t esp_read_mac_wrapper(uint8_t* mac, uint32_t type) +{ + return esp_read_mac(mac, (esp_mac_type_t)type); +} + +static int coex_init_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_init(); +#else + return 0; +#endif +} + +static void coex_deinit_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + coex_deinit(); +#endif +} + +static int coex_enable_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_enable(); +#else + return 0; +#endif +} + +static void coex_disable_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + coex_disable(); +#endif +} + +static IRAM_ATTR uint32_t coex_status_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_status_get(); +#else + return 0; +#endif +} + +static void coex_condition_set_wrapper(uint32_t type, bool dissatisfy) +{ +#if CONFIG_SW_COEXIST_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 + return coex_wifi_request(event, latency, duration); +#else + return 0; +#endif +} + +static IRAM_ATTR int coex_wifi_release_wrapper(uint32_t event) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_wifi_release(event); +#else + return 0; +#endif +} + +static int coex_wifi_channel_set_wrapper(uint8_t primary, uint8_t secondary) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_wifi_channel_set(primary, secondary); +#else + return 0; +#endif +} + +static IRAM_ATTR int coex_event_duration_get_wrapper(uint32_t event, uint32_t *duration) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_event_duration_get(event, duration); +#else + return 0; +#endif +} + +static int coex_pti_get_wrapper(uint32_t event, uint8_t *pti) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_pti_get(event, pti); +#else + return 0; +#endif +} + +static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) +{ +#if CONFIG_SW_COEXIST_ENABLE + coex_schm_status_bit_clear(type, status); +#endif +} + +static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status) +{ +#if CONFIG_SW_COEXIST_ENABLE + coex_schm_status_bit_set(type, status); +#endif +} + +static IRAM_ATTR int coex_schm_interval_set_wrapper(uint32_t interval) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_interval_set(interval); +#else + return 0; +#endif +} + +static uint32_t coex_schm_interval_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_interval_get(); +#else + return 0; +#endif +} + +static uint8_t coex_schm_curr_period_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_curr_period_get(); +#else + return 0; +#endif +} + +static void * coex_schm_curr_phase_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_curr_phase_get(); +#else + return NULL; +#endif +} + +static int coex_schm_curr_phase_idx_set_wrapper(int idx) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_curr_phase_idx_set(idx); +#else + return 0; +#endif +} + +static int coex_schm_curr_phase_idx_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_curr_phase_idx_get(); +#else + return 0; +#endif +} + +static void IRAM_ATTR esp_empty_wrapper(void) +{ + +} + +wifi_osi_funcs_t g_wifi_osi_funcs = { + ._version = ESP_WIFI_OS_ADAPTER_VERSION, + ._env_is_chip = env_is_chip_wrapper, + ._set_intr = set_intr_wrapper, + ._clear_intr = clear_intr_wrapper, + ._set_isr = set_isr_wrapper, + ._ints_on = enable_intr_wrapper, + ._ints_off = disable_intr_wrapper, + ._is_from_isr = is_from_isr_wrapper, + ._spin_lock_create = spin_lock_create_wrapper, + ._spin_lock_delete = free, + ._wifi_int_disable = wifi_int_disable_wrapper, + ._wifi_int_restore = 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 = semphr_take_wrapper, + ._semphr_give = semphr_give_wrapper, + ._wifi_thread_semphr_get = wifi_thread_semphr_get_wrapper, + ._mutex_create = mutex_create_wrapper, + ._recursive_mutex_create = recursive_mutex_create_wrapper, + ._mutex_delete = mutex_delete_wrapper, + ._mutex_lock = mutex_lock_wrapper, + ._mutex_unlock = mutex_unlock_wrapper, + ._queue_create = queue_create_wrapper, + ._queue_delete = (void(*)(void *))vQueueDelete, + ._queue_send = queue_send_wrapper, + ._queue_send_from_isr = queue_send_from_isr_wrapper, + ._queue_send_to_back = queue_send_to_back_wrapper, + ._queue_send_to_front = queue_send_to_front_wrapper, + ._queue_recv = queue_recv_wrapper, + ._queue_msg_waiting = (uint32_t(*)(void *))uxQueueMessagesWaiting, + ._event_group_create = (void *(*)(void))xEventGroupCreate, + ._event_group_delete = (void(*)(void *))vEventGroupDelete, + ._event_group_set_bits = (uint32_t(*)(void *,uint32_t))xEventGroupSetBits, + ._event_group_clear_bits = (uint32_t(*)(void *,uint32_t))xEventGroupClearBits, + ._event_group_wait_bits = event_group_wait_bits_wrapper, + ._task_create_pinned_to_core = task_create_pinned_to_core_wrapper, + ._task_create = task_create_wrapper, + ._task_delete = (void(*)(void *))vTaskDelete, + ._task_delay = vTaskDelay, + ._task_ms_to_tick = task_ms_to_tick_wrapper, + ._task_get_current_task = (void *(*)(void))xTaskGetCurrentTaskHandle, + ._task_get_max_priority = task_get_max_priority_wrapper, + ._malloc = malloc, + ._free = free, + ._event_post = esp_event_post_wrapper, + ._get_free_heap_size = esp_get_free_internal_heap_size, + ._rand = esp_random, + ._dport_access_stall_other_cpu_start_wrap = esp_empty_wrapper, + ._dport_access_stall_other_cpu_end_wrap = esp_empty_wrapper, + ._wifi_apb80m_request = wifi_apb80m_request_wrapper, + ._wifi_apb80m_release = wifi_apb80m_release_wrapper, + ._phy_disable = esp_phy_disable, + ._phy_enable = esp_phy_enable, + ._phy_update_country_info = esp_phy_update_country_info, + ._read_mac = esp_read_mac_wrapper, + ._timer_arm = timer_arm_wrapper, + ._timer_disarm = timer_disarm_wrapper, + ._timer_done = timer_done_wrapper, + ._timer_setfn = timer_setfn_wrapper, + ._timer_arm_us = timer_arm_us_wrapper, + ._wifi_reset_mac = wifi_reset_mac_wrapper, + ._wifi_clock_enable = wifi_clock_enable_wrapper, + ._wifi_clock_disable = wifi_clock_disable_wrapper, + ._wifi_rtc_enable_iso = wifi_rtc_enable_iso_wrapper, + ._wifi_rtc_disable_iso = wifi_rtc_disable_iso_wrapper, + ._esp_timer_get_time = esp_timer_get_time, + ._nvs_set_i8 = nvs_set_i8, + ._nvs_get_i8 = nvs_get_i8, + ._nvs_set_u8 = nvs_set_u8, + ._nvs_get_u8 = nvs_get_u8, + ._nvs_set_u16 = nvs_set_u16, + ._nvs_get_u16 = nvs_get_u16, + ._nvs_open = nvs_open_wrapper, + ._nvs_close = nvs_close, + ._nvs_commit = nvs_commit, + ._nvs_set_blob = nvs_set_blob, + ._nvs_get_blob = nvs_get_blob, + ._nvs_erase_key = nvs_erase_key, + ._get_random = os_get_random, + ._get_time = get_time_wrapper, + ._random = os_random, + ._slowclk_cal_get = esp_clk_slowclk_cal_get_wrapper, + ._log_write = esp_log_write_wrapper, + ._log_writev = esp_log_writev_wrapper, + ._log_timestamp = esp_log_timestamp, + ._malloc_internal = malloc_internal_wrapper, + ._realloc_internal = realloc_internal_wrapper, + ._calloc_internal = calloc_internal_wrapper, + ._zalloc_internal = zalloc_internal_wrapper, + ._wifi_malloc = wifi_malloc, + ._wifi_realloc = wifi_realloc, + ._wifi_calloc = wifi_calloc, + ._wifi_zalloc = wifi_zalloc_wrapper, + ._wifi_create_queue = wifi_create_queue_wrapper, + ._wifi_delete_queue = wifi_delete_queue_wrapper, + ._coex_init = coex_init_wrapper, + ._coex_deinit = coex_deinit_wrapper, + ._coex_enable = coex_enable_wrapper, + ._coex_disable = coex_disable_wrapper, + ._coex_status_get = coex_status_get_wrapper, + ._coex_condition_set = coex_condition_set_wrapper, + ._coex_wifi_request = coex_wifi_request_wrapper, + ._coex_wifi_release = coex_wifi_release_wrapper, + ._coex_wifi_channel_set = coex_wifi_channel_set_wrapper, + ._coex_event_duration_get = coex_event_duration_get_wrapper, + ._coex_pti_get = coex_pti_get_wrapper, + ._coex_schm_status_bit_clear = coex_schm_status_bit_clear_wrapper, + ._coex_schm_status_bit_set = coex_schm_status_bit_set_wrapper, + ._coex_schm_interval_set = coex_schm_interval_set_wrapper, + ._coex_schm_interval_get = coex_schm_interval_get_wrapper, + ._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper, + ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper, + ._coex_schm_curr_phase_idx_set = coex_schm_curr_phase_idx_set_wrapper, + ._coex_schm_curr_phase_idx_get = coex_schm_curr_phase_idx_get_wrapper, + ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, +}; + +coex_adapter_funcs_t g_coex_adapter_funcs = { + ._version = COEX_ADAPTER_VERSION, + ._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, + ._esp_timer_get_time = esp_timer_get_time, + ._magic = COEX_ADAPTER_MAGIC, +}; diff --git a/components/esp_wifi/esp32c3/include/phy_init_data.h b/components/esp_wifi/esp32c3/include/phy_init_data.h new file mode 100644 index 0000000000..774be4e48c --- /dev/null +++ b/components/esp_wifi/esp32c3/include/phy_init_data.h @@ -0,0 +1,185 @@ +// Copyright 2016-2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#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_ESP32_PHY_MAX_TX_POWER * 4, 0, 52) +#define PHY_TX_POWER_OFFSET 44 +#define PHY_TX_POWER_NUM 5 + +#if CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_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 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= { { + 3, + 3, + 0x05, + 0x09, + 0x06, + 0x05, + 0x03, + 0x06, + 0x05, + 0x04, + 0x06, + 0x04, + 0x05, + 0x00, + 0x00, + 0x00, + 0x00, + 0x05, + 0x09, + 0x06, + 0x05, + 0x03, + 0x06, + 0x05, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0xfc, + 0xfc, + 0xfe, + 0xf0, + 0xf0, + 0xf0, + 0xe0, + 0xe0, + 0xe0, + 0x18, + 0x18, + 0x18, + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 84), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 72), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 66), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 60), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 56), + LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 52), + 0, + 1, + 1, + 2, + 2, + 3, + 4, + 5, + 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, +} }; + +static const char phy_init_magic_post[] = PHY_INIT_MAGIC; + +#if CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_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_wifi/esp32s2/esp_adapter.c b/components/esp_wifi/esp32s2/esp_adapter.c index 28a3318d8c..3573eb20c5 100644 --- a/components/esp_wifi/esp32s2/esp_adapter.c +++ b/components/esp_wifi/esp32s2/esp_adapter.c @@ -96,9 +96,6 @@ IRAM_ATTR void *wifi_calloc( size_t n, size_t size ) static void * IRAM_ATTR wifi_zalloc_wrapper(size_t size) { void *ptr = wifi_calloc(1, size); - if (ptr) { - memset(ptr, 0, size); - } return ptr; } @@ -479,9 +476,6 @@ static void * IRAM_ATTR calloc_internal_wrapper(size_t n, size_t size) static void * IRAM_ATTR zalloc_internal_wrapper(size_t size) { void *ptr = heap_caps_calloc(1, size, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); - if (ptr) { - memset(ptr, 0, size); - } return ptr; } diff --git a/components/esp_wifi/include/esp_coexist_internal.h b/components/esp_wifi/include/esp_coexist_internal.h index d6b64c6f09..3501f0da6f 100644 --- a/components/esp_wifi/include/esp_coexist_internal.h +++ b/components/esp_wifi/include/esp_coexist_internal.h @@ -131,6 +131,17 @@ int coex_wifi_channel_set(uint8_t primary, uint8_t secondary); */ int coex_event_duration_get(uint32_t event, uint32_t *duration); +#if SOC_COEX_HW_PTI +/** + * @brief Get coexistence event priority. + * + * @param event : Coexistence event + * @param pti: Coexistence event priority + * @return : 0 - success, other - failed + */ +int coex_pti_get(uint32_t event, uint8_t *pti); +#endif + /** * @brief Clear coexistence status. * diff --git a/components/esp_wifi/include/esp_phy_init.h b/components/esp_wifi/include/esp_phy_init.h index 6e273ba745..72dc673337 100644 --- a/components/esp_wifi/include/esp_phy_init.h +++ b/components/esp_wifi/include/esp_phy_init.h @@ -178,6 +178,23 @@ void esp_phy_disable(void); */ void esp_phy_load_cal_and_init(void); +#if CONFIG_MAC_BB_PD +/** + * @brief Initialize backup memory for MAC and Baseband power up/down + */ +void esp_mac_bb_pd_mem_init(void); + +/** + * @brief Power up MAC and Baseband + */ +void esp_mac_bb_power_up(void); + +/** + * @brief Power down MAC and Baseband + */ +void esp_mac_bb_power_down(void); +#endif + /** * @brief Enable WiFi/BT common clock * diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index 459650f875..2e9d0efbe1 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -478,6 +478,18 @@ esp_err_t esp_wifi_internal_get_negotiated_bandwidth(wifi_interface_t ifx, uint8 bool esp_wifi_internal_is_tsf_active(void); #endif +#if CONFIG_MAC_BB_PD +/** + * @brief Enable or disable powering down MAC and baseband when Wi-Fi is sleeping. + * + * @param enable : enable or disable + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_internal_set_mac_sleep(bool enable); +#endif + /** * @breif TxDone callback function type. Should be registered using esp_wifi_set_tx_done_cb() * diff --git a/components/esp_wifi/include/phy.h b/components/esp_wifi/include/phy.h index a33b63751a..352ce97595 100644 --- a/components/esp_wifi/include/phy.h +++ b/components/esp_wifi/include/phy.h @@ -21,6 +21,10 @@ extern "C" { #define ESP_CAL_DATA_CHECK_FAIL 1 +#if CONFIG_MAC_BB_PD +#define MAC_BB_PD_MEM_SIZE (192*4) +#endif + /** * @file phy.h * @brief Declarations for functions provided by libphy.a @@ -59,18 +63,23 @@ void phy_set_wifi_mode_only(bool wifi_only); */ void coex_bt_high_prio(void); -#if CONFIG_IDF_TARGET_ESP32S2 /** * @brief Open PHY and RF. */ void phy_wakeup_init(void); -#endif /** * @brief Shutdown PHY and RF. */ void phy_close_rf(void); +#if CONFIG_MAC_BB_PD +/** + * @brief Store and load baseband registers. + */ +void phy_freq_mem_backup(bool backup_en, uint32_t *mem); +#endif + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 46c804d361..4e0f77cd3f 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 46c804d361c160d783f1b0a85039a27d50041953 +Subproject commit 4e0f77cd3f09acf679b5dad958ea1ec9e333a476 diff --git a/components/esp_wifi/sdkconfig.rename b/components/esp_wifi/sdkconfig.rename index 8d55abed31..c13a1d049b 100644 --- a/components/esp_wifi/sdkconfig.rename +++ b/components/esp_wifi/sdkconfig.rename @@ -2,3 +2,4 @@ # CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION CONFIG_SW_COEXIST_ENABLE CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE +CONFIG_MAC_BB_PD CONFIG_ESP32_PHY_MAC_BB_PD diff --git a/components/esp_wifi/src/lib_printf.c b/components/esp_wifi/src/lib_printf.c index 4ad6106a52..3e76fb7318 100644 --- a/components/esp_wifi/src/lib_printf.c +++ b/components/esp_wifi/src/lib_printf.c @@ -44,7 +44,7 @@ static int lib_printf(const char* tag, const char* format, va_list arg) temp[i] = 0; } if (i > 0) { - ESP_EARLY_LOGI(tag, "%s", temp); + ESP_LOGI(tag, "%s", temp); } va_end(arg); return len; diff --git a/components/esp_wifi/src/phy_init.c b/components/esp_wifi/src/phy_init.c index 1ed2dd25bb..dd0ae40941 100644 --- a/components/esp_wifi/src/phy_init.c +++ b/components/esp_wifi/src/phy_init.c @@ -19,7 +19,6 @@ #include #include "soc/rtc.h" -#include "soc/dport_reg.h" #include "esp_err.h" #include "esp_phy_init.h" #include "esp_system.h" @@ -40,6 +39,9 @@ #include "esp32/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32C3 +#include "soc/rtc_cntl_reg.h" +#include "soc/syscon_reg.h" #endif #if CONFIG_IDF_TARGET_ESP32 @@ -56,6 +58,11 @@ static bool s_is_phy_calibrated = false; /* Reference count of enabling PHY */ static uint8_t s_phy_access_ref = 0; +#if CONFIG_MAC_BB_PD +/* Reference of powering down MAC and BB */ +static uint8_t s_mac_bb_pd_ref = 0; +#endif + #if CONFIG_IDF_TARGET_ESP32 /* time stamp updated when the PHY/RF is turned on */ static int64_t s_phy_rf_en_ts = 0; @@ -64,6 +71,10 @@ static int64_t s_phy_rf_en_ts = 0; /* PHY spinlock for libphy.a */ static DRAM_ATTR portMUX_TYPE s_phy_int_mux = portMUX_INITIALIZER_UNLOCKED; +#if CONFIG_MAC_BB_PD +uint32_t* s_mac_bb_pd_mem = NULL; +#endif + #if CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN /* The following static variables are only used by Wi-Fi tasks, so they can be handled without lock */ static phy_init_data_type_t s_phy_init_data_type = 0; @@ -184,7 +195,7 @@ IRAM_ATTR void esp_phy_common_clock_disable(void) wifi_bt_common_module_disable(); } -void esp_phy_enable(void) +IRAM_ATTR void esp_phy_enable(void) { _lock_acquire(&s_phy_access_lock); @@ -203,11 +214,7 @@ void esp_phy_enable(void) s_is_phy_calibrated = true; } else { -#if CONFIG_IDF_TARGET_ESP32S2 phy_wakeup_init(); -#elif CONFIG_IDF_TARGET_ESP32 - register_chipv7_phy(NULL, NULL, PHY_RF_CAL_NONE); -#endif } #if CONFIG_IDF_TARGET_ESP32 @@ -219,7 +226,7 @@ void esp_phy_enable(void) _lock_release(&s_phy_access_lock); } -void esp_phy_disable(void) +IRAM_ATTR void esp_phy_disable(void) { _lock_acquire(&s_phy_access_lock); @@ -238,6 +245,53 @@ void esp_phy_disable(void) _lock_release(&s_phy_access_lock); } +#if CONFIG_MAC_BB_PD +void esp_mac_bb_pd_mem_init(void) +{ + _lock_acquire(&s_phy_access_lock); + + if (s_mac_bb_pd_mem == NULL) { + s_mac_bb_pd_mem = (uint32_t *)heap_caps_malloc(MAC_BB_PD_MEM_SIZE, MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); + } + + _lock_release(&s_phy_access_lock); +} + +IRAM_ATTR void esp_mac_bb_power_up(void) +{ + uint32_t level = phy_enter_critical(); + + if (s_mac_bb_pd_mem != NULL && s_mac_bb_pd_ref == 0) { + esp_phy_common_clock_enable(); + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD); + SET_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_BB_RST | SYSTEM_FE_RST); + CLEAR_PERI_REG_MASK(SYSCON_WIFI_RST_EN_REG, SYSTEM_BB_RST | SYSTEM_FE_RST); + CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO); + phy_freq_mem_backup(false, s_mac_bb_pd_mem); + esp_phy_common_clock_disable(); + } + s_mac_bb_pd_ref++; + + phy_exit_critical(level); +} + +IRAM_ATTR void esp_mac_bb_power_down(void) +{ + uint32_t level = phy_enter_critical(); + + s_mac_bb_pd_ref--; + if (s_mac_bb_pd_mem != NULL && s_mac_bb_pd_ref == 0) { + esp_phy_common_clock_enable(); + phy_freq_mem_backup(true, s_mac_bb_pd_mem); + 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); + esp_phy_common_clock_disable(); + } + + phy_exit_critical(level); +} +#endif + // PHY init data handling functions #if CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION #include "esp_partition.h" diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index b8aca2ce31..38c9e3d280 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -26,6 +26,7 @@ #include "driver/adc.h" #include "driver/adc2_wifi_private.h" #include "esp_coexist_internal.h" +#include "esp_phy_init.h" #if (CONFIG_ESP32_WIFI_RX_BA_WIN > CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM) #error "WiFi configuration check: WARNING, WIFI_RX_BA_WIN should not be larger than WIFI_DYNAMIC_RX_BUFFER_NUM!" @@ -139,8 +140,8 @@ esp_err_t esp_wifi_deinit(void) #if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER tcpip_adapter_clear_default_wifi_handlers(); #endif -#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if SOC_WIFI_HW_TSF esp_pm_unregister_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active); #endif #endif @@ -194,8 +195,8 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) } } #endif -#if CONFIG_IDF_TARGET_ESP32S2 #if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if SOC_WIFI_HW_TSF esp_err_t ret = esp_pm_register_skip_light_sleep_callback(esp_wifi_internal_is_tsf_active); if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to register skip light sleep callback (0x%x)", ret); @@ -204,6 +205,10 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) esp_sleep_enable_wifi_wakeup(); #endif #endif +#if CONFIG_MAC_BB_PD + esp_mac_bb_pd_mem_init(); + esp_wifi_internal_set_mac_sleep(true); +#endif #if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER esp_err_t err = tcpip_adapter_set_default_wifi_handlers(); if (err != ESP_OK) { diff --git a/components/hal/interrupt_controller_hal.c b/components/hal/interrupt_controller_hal.c index 93bce347c9..2226c4481e 100644 --- a/components/hal/interrupt_controller_hal.c +++ b/components/hal/interrupt_controller_hal.c @@ -19,6 +19,11 @@ static bool is_interrupt_number_reserved(int interrupt_number) { + //TODO. Workaround to reserve interrupt number 0 for Wi-Fi. + if (interrupt_number == 1) { + return true; + } + extern int _vector_table; extern int _interrupt_handler; const intptr_t pc = (intptr_t)(&_vector_table + interrupt_number); diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 2d112540f4..56daa5a4ff 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -108,3 +108,12 @@ * - 0 : not support; */ #define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) 1 + +/*-------------------------- APB BACKUP DMA CAPS -------------------------------*/ +#define SOC_APB_BACKUP_DMA (1) + +/*-------------------------- WI-FI HARDWARE TSF CAPS -------------------------------*/ +#define SOC_WIFI_HW_TSF (1) + +/*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/ +#define SOC_COEX_HW_PTI (1) diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 7f19e8b5c4..f384c42a41 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -289,6 +289,8 @@ #define SOC_AES_SUPPORT_AES_192 (1) #define SOC_AES_SUPPORT_AES_256 (1) +/*-------------------------- WI-FI HARDWARE TSF CAPS -------------------------------*/ +#define SOC_WIFI_HW_TSF (1) /* ---------------------------- Compatibility ------------------------------- */