feat(phy): add esp32c5 beta3 phy support

This commit is contained in:
xuxiao 2024-03-12 15:17:31 +08:00 committed by BOT
parent 82f70e7ad4
commit b1bd9987fe
8 changed files with 409 additions and 3 deletions

View File

@ -0,0 +1,164 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/portmacro.h"
#include "esp_heap_caps.h"
#include "esp_timer.h"
#include "soc/rtc.h"
#include "esp_private/esp_clk.h"
#include "private/esp_coexist_adapter.h"
#include "esp32c5/rom/ets_sys.h"
#define TAG "esp_coex_adapter"
#define OSI_FUNCS_TIME_BLOCKING 0xffffffff
bool IRAM_ATTR esp_coex_common_env_is_chip_wrapper(void)
{
#ifdef CONFIG_IDF_ENV_FPGA
return false;
#else
return true;
#endif
}
void *esp_coex_common_spin_lock_create_wrapper(void)
{
portMUX_TYPE tmp = portMUX_INITIALIZER_UNLOCKED;
void *mux = malloc(sizeof(portMUX_TYPE));
if (mux) {
memcpy(mux, &tmp, sizeof(portMUX_TYPE));
return mux;
}
return NULL;
}
uint32_t IRAM_ATTR esp_coex_common_int_disable_wrapper(void *wifi_int_mux)
{
if (xPortInIsrContext()) {
portENTER_CRITICAL_ISR(wifi_int_mux);
} else {
portENTER_CRITICAL(wifi_int_mux);
}
return 0;
}
void IRAM_ATTR esp_coex_common_int_restore_wrapper(void *wifi_int_mux, uint32_t tmp)
{
if (xPortInIsrContext()) {
portEXIT_CRITICAL_ISR(wifi_int_mux);
} else {
portEXIT_CRITICAL(wifi_int_mux);
}
}
void IRAM_ATTR esp_coex_common_task_yield_from_isr_wrapper(void)
{
portYIELD_FROM_ISR();
}
void *esp_coex_common_semphr_create_wrapper(uint32_t max, uint32_t init)
{
return (void *)xSemaphoreCreateCounting(max, init);
}
void esp_coex_common_semphr_delete_wrapper(void *semphr)
{
vSemaphoreDelete(semphr);
}
int32_t esp_coex_common_semphr_take_wrapper(void *semphr, uint32_t block_time_tick)
{
if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) {
return (int32_t)xSemaphoreTake(semphr, portMAX_DELAY);
} else {
return (int32_t)xSemaphoreTake(semphr, block_time_tick);
}
}
int32_t esp_coex_common_semphr_give_wrapper(void *semphr)
{
return (int32_t)xSemaphoreGive(semphr);
}
void IRAM_ATTR esp_coex_common_timer_disarm_wrapper(void *timer)
{
ets_timer_disarm(timer);
}
void esp_coex_common_timer_done_wrapper(void *ptimer)
{
ets_timer_done(ptimer);
}
void esp_coex_common_timer_setfn_wrapper(void *ptimer, void *pfunction, void *parg)
{
ets_timer_setfn(ptimer, pfunction, parg);
}
void IRAM_ATTR esp_coex_common_timer_arm_us_wrapper(void *ptimer, uint32_t us, bool repeat)
{
ets_timer_arm_us(ptimer, us, repeat);
}
uint32_t esp_coex_common_clk_slowclk_cal_get_wrapper(void)
{
/* The bit width of WiFi light sleep clock calibration is 12 while the one of
* system is 19. It should shift 19 - 12 = 7.
*/
return (esp_clk_slowclk_cal_get() >> (RTC_CLK_CAL_FRACT - SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH));
}
void *IRAM_ATTR esp_coex_common_malloc_internal_wrapper(size_t size)
{
return heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
}
/* static wrapper */
static int32_t IRAM_ATTR esp_coex_semphr_take_from_isr_wrapper(void *semphr, void *hptw)
{
return (int32_t)xSemaphoreTakeFromISR(semphr, hptw);
}
static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, void *hptw)
{
return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
}
coex_adapter_funcs_t g_coex_adapter_funcs = {
._version = COEX_ADAPTER_VERSION,
._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
._semphr_create = esp_coex_common_semphr_create_wrapper,
._semphr_delete = esp_coex_common_semphr_delete_wrapper,
._semphr_take_from_isr = esp_coex_semphr_take_from_isr_wrapper,
._semphr_give_from_isr = esp_coex_semphr_give_from_isr_wrapper,
._semphr_take = esp_coex_common_semphr_take_wrapper,
._semphr_give = esp_coex_common_semphr_give_wrapper,
._is_in_isr = xPortInIsrContext,
._malloc_internal = esp_coex_common_malloc_internal_wrapper,
._free = free,
._esp_timer_get_time = esp_timer_get_time,
._env_is_chip = esp_coex_common_env_is_chip_wrapper,
._timer_disarm = esp_coex_common_timer_disarm_wrapper,
._timer_done = esp_coex_common_timer_done_wrapper,
._timer_setfn = esp_coex_common_timer_setfn_wrapper,
._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
._magic = COEX_ADAPTER_MAGIC,
};

View File

@ -4,7 +4,7 @@ if(${idf_target} STREQUAL "linux")
return() # This component is not supported by the POSIX/Linux simulator
endif()
if(IDF_TARGET STREQUAL "esp32p4" OR IDF_TARGET STREQUAL "esp32c5" OR IDF_TARGET STREQUAL "esp32c61")
if(IDF_TARGET STREQUAL "esp32p4" OR IDF_TARGET STREQUAL "esp32c61")
# TODO: IDF-7460, IDF-8851, IDF-9553
return()
endif()

View File

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// btbb sleep retention reg
#define BB_PART_0_SIZE 93
#define BB_PART_1_SIZE 62
#define BB_PART_2_SIZE 19
#define BB_PART_0_ADDR 0x600A2000
#define BB_PART_1_ADDR 0x600A2800
#define BB_PART_2_ADDR 0x600A2C00
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,199 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef PHY_INIT_DATA_H
#define PHY_INIT_DATA_H /* don't use #pragma once here, we compile this file sometimes */
#include "esp_phy_init.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
// constrain a value between 'low' and 'high', inclusive
#define LIMIT(val, low, high) ((val < low) ? low : (val > high) ? high : val)
#define PHY_INIT_MAGIC "PHYINIT"
// define the lowest tx power as LOWEST_PHY_TX_POWER
#define PHY_TX_POWER_LOWEST LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 52)
#define PHY_TX_POWER_OFFSET 2
#define PHY_TX_POWER_NUM 14
#if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN
#define PHY_CRC_ALGORITHM 1
#define PHY_COUNTRY_CODE_LEN 2
#define PHY_INIT_DATA_TYPE_OFFSET 126
#define PHY_SUPPORT_MULTIPLE_BIN_OFFSET 125
#endif
static const char __attribute__((section(".rodata"))) phy_init_magic_pre[] = PHY_INIT_MAGIC;
/**
* @brief Structure containing default recommended PHY initialization parameters.
*/
static const esp_phy_init_data_t phy_init_data= { {
0x01,
0x00,
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x54),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x50),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x4c),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x48),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x44),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x3C),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x3C),
LIMIT(CONFIG_ESP_PHY_MAX_TX_POWER * 4, 0, 0x3C),
0x00,
0x00,
0x00,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0xff,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0x70
} };
static const char __attribute__((section(".rodata"))) phy_init_magic_post[] = PHY_INIT_MAGIC;
#if CONFIG_ESP_PHY_MULTIPLE_INIT_DATA_BIN
/**
* @brief PHY init data control infomation structure
*/
typedef struct {
uint8_t control_info_checksum[4]; /*!< 4-byte control infomation checksum */
uint8_t multiple_bin_checksum[4]; /*!< 4-byte multiple bin checksum */
uint8_t check_algorithm; /*!< check algorithm */
uint8_t version; /*!< PHY init data bin version */
uint8_t number; /*!< PHY init data bin number */
uint8_t length[2]; /*!< Length of each PHY init data bin */
uint8_t reserved[19]; /*!< 19-byte reserved */
} __attribute__ ((packed)) phy_control_info_data_t;
/**
* @brief Country corresponds to PHY init data type structure
*/
typedef struct {
char cc[PHY_COUNTRY_CODE_LEN];
uint8_t type;
} phy_country_to_bin_type_t;
#endif
#ifdef __cplusplus
}
#endif
#endif /* PHY_INIT_DATA_H */

Binary file not shown.

@ -1 +1 @@
Subproject commit 2d319a382336cf0522ea4bb5a3fbd6701a8633c6
Subproject commit 603b69583635ffcedf2a5e1d0f70da77edf82d10

View File

@ -59,10 +59,12 @@ static _lock_t s_phy_access_lock;
#if SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD
#if !SOC_PMU_SUPPORTED
#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8667
static DRAM_ATTR struct {
int count; /* power on count of wifi and bt power domain */
_lock_t lock;
} s_wifi_bt_pd_controller = { .count = 0 };
#endif
#endif // !SOC_PMU_SUPPORTED
#endif // SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD
@ -326,6 +328,7 @@ void IRAM_ATTR esp_wifi_bt_power_domain_on(void)
{
#if SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD
#if !SOC_PMU_SUPPORTED
#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8667
_lock_acquire(&s_wifi_bt_pd_controller.lock);
if (s_wifi_bt_pd_controller.count++ == 0) {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD);
@ -343,6 +346,7 @@ void IRAM_ATTR esp_wifi_bt_power_domain_on(void)
wifi_bt_common_module_disable();
}
_lock_release(&s_wifi_bt_pd_controller.lock);
#endif
#endif // !SOC_PMU_SUPPORTED
#endif // SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD
}
@ -351,12 +355,14 @@ void esp_wifi_bt_power_domain_off(void)
{
#if SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD
#if !SOC_PMU_SUPPORTED
#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8667
_lock_acquire(&s_wifi_bt_pd_controller.lock);
if (--s_wifi_bt_pd_controller.count == 0) {
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_ISO);
SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PD);
}
_lock_release(&s_wifi_bt_pd_controller.lock);
#endif
#endif // !SOC_PMU_SUPPORTED
#endif // SOC_PM_SUPPORT_MODEM_PD || SOC_PM_SUPPORT_WIFI_PD
}
@ -864,10 +870,13 @@ void esp_phy_load_cal_and_init(void)
#else
esp_phy_release_init_data(init_data);
#endif
#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8638
ESP_ERROR_CHECK(esp_deep_sleep_register_hook(&phy_close_rf));
#endif
#if !CONFIG_IDF_TARGET_ESP32
#if !CONFIG_IDF_TARGET_ESP32C5 // TODO: [ESP32C5] IDF-8638
ESP_ERROR_CHECK(esp_deep_sleep_register_hook(&phy_xpd_tsens));
#endif
#endif
free(cal_data); // PHY maintains a copy of calibration data, so we can free this

View File

@ -18,8 +18,10 @@
*/
static bool s_wifi_adc_xpd_flag;
#if CONFIG_SOC_TEMP_SENSOR_SUPPORTED // TODO: [ESP32C5] IDF-8727 remove me when fix IDF-8727
static bool s_wifi_pwdet_xpd_flag;
static bool s_wifi_tsens_xpd_flag;
#endif
void include_esp_phy_override(void)
{
@ -57,6 +59,7 @@ IRAM_ATTR void phy_i2c_exit_critical(void)
void phy_set_pwdet_power(bool en)
{
#if CONFIG_SOC_TEMP_SENSOR_SUPPORTED // TODO: [ESP32C5] IDF-8727 remove me when fix IDF-8727
if (s_wifi_pwdet_xpd_flag == en) {
/* ignore repeated calls to phy_set_pwdet_power when the state is already correct */
return;
@ -68,10 +71,12 @@ void phy_set_pwdet_power(bool en)
} else {
sar_periph_ctrl_pwdet_power_release();
}
#endif
}
void phy_set_tsens_power(bool en)
{
#if CONFIG_SOC_TEMP_SENSOR_SUPPORTED // TODO: [ESP32C5] IDF-8727 remove me when fix IDF-8727
if (s_wifi_tsens_xpd_flag == en) {
/* ignore repeated calls to phy_set_tsens_power when the state is already correct */
return;
@ -83,9 +88,14 @@ void phy_set_tsens_power(bool en)
} else {
temperature_sensor_power_release();
}
#endif
}
int16_t phy_get_tsens_value(void)
{
#if CONFIG_SOC_TEMP_SENSOR_SUPPORTED // TODO: [ESP32C5] IDF-8727 remove me when fix IDF-8727
return temp_sensor_get_raw_value(NULL);
#else
return 0;
#endif
}