Skip to content

Commit dad039e

Browse files
committed
change(esp_hw_support): support wifi modem state for esp32c5
1 parent eeb55c3 commit dad039e

File tree

8 files changed

+224
-40
lines changed

8 files changed

+224
-40
lines changed

components/esp_hw_support/lowpower/port/esp32c5/sleep_clock.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "esp_private/sleep_clock.h"
88
#include "soc/pcr_reg.h"
9+
#include "soc/rtc.h"
910
#include "modem/modem_syscon_reg.h"
1011
#include "modem/modem_lpcon_reg.h"
1112
#include "soc/i2c_ana_mst_reg.h"
@@ -14,13 +15,43 @@ static const char *TAG = "sleep_clock";
1415

1516
esp_err_t sleep_clock_system_retention_init(void *arg)
1617
{
17-
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
1818
const static sleep_retention_entries_config_t pcr_regs_retention[] = {
19-
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 74, 0, 0, 0xffffffff, 0xffffffff, 0x7f7, 0x0), .owner = ENTRY(0) | ENTRY(1) },
19+
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(0), PCR_AHB_FREQ_CONF_REG, 0, PCR_AHB_DIV_NUM, 1, 0), .owner = ENTRY(0) | ENTRY(1) }, /* Set AHB bus frequency to XTAL frequency */
20+
[1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(1), PCR_BUS_CLK_UPDATE_REG, 1, PCR_BUS_CLOCK_UPDATE, 1, 0), .owner = ENTRY(0) | ENTRY(1) },
21+
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
22+
[2] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(2), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 74, 0, 0, 0xffffffff, 0xffffffff, 0x7f7, 0x0), .owner = ENTRY(0) | ENTRY(1) },
23+
#endif
2024
};
2125
esp_err_t err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_SYS_CLK, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
2226
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention");
27+
28+
const static sleep_retention_entries_config_t modem_ahb_config[] = {
29+
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(3), PCR_AHB_FREQ_CONF_REG, 3, PCR_AHB_DIV_NUM, 1, 0), .owner = ENTRY(1) }, /* Set AHB bus frequency to 40 MHz under PMU MODEM state */
30+
[1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(4), PCR_BUS_CLK_UPDATE_REG, 1, PCR_BUS_CLOCK_UPDATE, 1, 0), .owner = ENTRY(1) },
31+
};
32+
err = sleep_retention_entries_create(modem_ahb_config, ARRAY_SIZE(modem_ahb_config), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
33+
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention, 4 level priority");
34+
35+
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP && CONFIG_XTAL_FREQ_AUTO
36+
uint32_t xtal_freq_mhz = (uint32_t)rtc_clk_xtal_freq_get();
37+
if (xtal_freq_mhz == SOC_XTAL_FREQ_48M) {
38+
39+
/* For the 48 MHz main XTAL, we need regdma to configured BBPLL by exec
40+
* the PHY_I2C_MST_CMD_TYPE_BBPLL_CFG command from PHY i2c master
41+
* command memory */
42+
sleep_retention_entries_config_t bbpll_config[] = {
43+
[0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(5), MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), .owner = ENTRY(1) }, /* I2C MST enable */
44+
[1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(6), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0), .owner = ENTRY(1) },
45+
[2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(7), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0), .owner = ENTRY(1) },
46+
[3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(8), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), .owner = ENTRY(1) }, /* I2C MST disable */
47+
};
48+
extern uint32_t phy_ana_i2c_master_burst_bbpll_config(void);
49+
bbpll_config[1].config.write_wait.value = phy_ana_i2c_master_burst_bbpll_config();
50+
err = sleep_retention_entries_create(bbpll_config, ARRAY_SIZE(bbpll_config), REGDMA_LINK_PRI_SYS_CLK, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
51+
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for bbpll configure, 0 level priority");
52+
}
2353
#endif
54+
2455
ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization");
2556
return ESP_OK;
2657
}

components/esp_hw_support/sleep_modem.c

Lines changed: 87 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -12,6 +12,7 @@
1212
#include "esp_log.h"
1313
#include "esp_attr.h"
1414
#include "esp_sleep.h"
15+
#include "esp_check.h"
1516
#include "soc/soc_caps.h"
1617
#include "esp_private/pm_impl.h"
1718
#include "esp_private/sleep_modem.h"
@@ -136,29 +137,28 @@ void IRAM_ATTR mac_bb_power_up_cb_execute(void)
136137

137138
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
138139

139-
#define PMU_RF_PWR_REG (0x600b0154)
140140
#define SARADC_TSENS_REG (0x6000e058)
141141
#define SARADC_TSENS_PU (BIT(22))
142+
#if CONFIG_IDF_TARGET_ESP32C6
143+
#define PMU_RF_PWR_REG (0x600b0154)
142144
#define FECOEX_SET_FREQ_SET_CHAN_REG (0x600a00c0)
143145
#define FECOEX_SET_CHAN_EN (BIT(14))
144146
#define FECOEX_SET_FREQ_SET_CHAN_ST_REG (0x600a00cc)
145147
#define FECOEX_SET_CHAN_DONE (BIT(8))
148+
#elif CONFIG_IDF_TARGET_ESP32C5
149+
#define PMU_RF_PWR_REG (0x600b0158)
150+
#define FECOEX_SET_FREQ_SET_CHAN_REG (0x600a001c)
151+
#define FECOEX_SET_CHAN_EN (BIT(17))
152+
#define FECOEX_SET_FREQ_SET_CHAN_ST_REG (0x600a0028)
153+
#define FECOEX_SET_CHAN_DONE (BIT(8))
154+
#endif
146155
#define FECOEX_AGC_CONF_REG (0x600a7030)
147156
#define FECOEX_AGC_DIS (BIT(29))
148157
#define WDEVTXQ_BLOCK (0x600A4ca8)
149158
#define WDEV_RXBLOCK (BIT(12))
150159
#define MODEM_FE_DATA_BASE (0x600a0400)
151160
#define MODEM_FE_CTRL_BASE (0x600a0800)
152161

153-
#define I2C_BURST_VAL(host, start, end) (((host) << 31) | ((end) << 22) | ((start) << 16))
154-
155-
typedef struct {
156-
struct {
157-
uint8_t start, end; /* the start and end index of phy i2c master command memory */
158-
uint8_t host_id; /* phy i2c master host id */
159-
} config[2];
160-
} phy_i2c_master_command_attribute_t;
161-
162162
typedef struct sleep_modem_config {
163163
struct {
164164
void *phy_link;
@@ -174,18 +174,63 @@ typedef struct sleep_modem_config {
174174

175175
static sleep_modem_config_t s_sleep_modem = { .wifi.phy_link = NULL, .wifi.flags = 0 };
176176

177-
esp_err_t sleep_modem_wifi_modem_state_init(void)
177+
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
178+
static esp_err_t sleep_modem_phy_wifi_init(void *arg)
178179
{
179-
esp_err_t err = ESP_OK;
180-
phy_i2c_master_command_attribute_t cmd;
180+
#define WIFIMAC_ENTRY() (BIT(SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC))
181181

182-
/* get RF on or off configuration info of i2c master command memory */
183-
extern void phy_i2c_master_mem_cfg(phy_i2c_master_command_attribute_t *);
184-
phy_i2c_master_mem_cfg(&cmd);
182+
static sleep_retention_entries_config_t wifi_modem_config[] = {
183+
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x00), MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN, MODEM_LPCON_CLK_I2C_MST_EN_M, 1, 0), .owner = WIFIMAC_ENTRY() }, /* I2C MST enable */
185184

186-
ESP_LOGD(TAG, "Modem link i2c master configuration: (%d,%d,%d), (%d,%d,%d)", cmd.config[0].host_id, cmd.config[0].start,
187-
cmd.config[0].end, cmd.config[1].host_id, cmd.config[1].start, cmd.config[1].end);
185+
/* PMU or software to trigger enable RF PHY */
186+
[1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x01), I2C_ANA_MST_ANA_CONF0_REG, 0x8, 0xc, 1, 0), .owner = WIFIMAC_ENTRY() }, /* BBPLL calibration enable */
187+
[2] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x02), PMU_RF_PWR_REG, 0xf3800000, 0xf3800000, 1, 0), .owner = WIFIMAC_ENTRY() },
188+
[3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x03), SARADC_TSENS_REG, SARADC_TSENS_PU, 0x400000, 1, 0), .owner = WIFIMAC_ENTRY() },
189+
[4] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x04), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 0), .owner = WIFIMAC_ENTRY() },
190+
[5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x05), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 0), .owner = WIFIMAC_ENTRY() },
191+
[6] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x06), FECOEX_SET_FREQ_SET_CHAN_REG, FECOEX_SET_CHAN_EN, 0x20000, 1, 0), .owner = WIFIMAC_ENTRY() },
192+
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x07), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x20000, 1, 0), .owner = WIFIMAC_ENTRY() },
193+
[8] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x08), FECOEX_SET_FREQ_SET_CHAN_ST_REG, FECOEX_SET_CHAN_DONE, 0x100, 1, 0), .owner = WIFIMAC_ENTRY() },
194+
[9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x09), MODEM_SYSCON_WIFI_BB_CFG_REG, BIT(1), 0x2, 1, 0), .owner = WIFIMAC_ENTRY() },
195+
[10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0a), FECOEX_AGC_CONF_REG, 0, 0x20000000, 1, 0), .owner = WIFIMAC_ENTRY() },
196+
197+
/* PMU to trigger enable RXBLOCK */
198+
[11] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0b), WDEVTXQ_BLOCK, 0, 0x1000, 1, 0), .owner = WIFIMAC_ENTRY() },
199+
200+
/* PMU or software to trigger disable RF PHY */
201+
[12] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0c), FECOEX_AGC_CONF_REG, FECOEX_AGC_DIS, 0x20000000, 0, 1), .owner = WIFIMAC_ENTRY() },
202+
[13] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0d), MODEM_SYSCON_WIFI_BB_CFG_REG, 0, 0x2, 0, 1), .owner = WIFIMAC_ENTRY() },
203+
[14] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0e), FECOEX_SET_FREQ_SET_CHAN_REG, 0, 0x20000, 0, 1), .owner = WIFIMAC_ENTRY() },
204+
[15] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x0f), I2C_ANA_MST_I2C_BURST_CONF_REG, 0, 0xffffffff, 1, 1), .owner = WIFIMAC_ENTRY() },
205+
[16] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x10), I2C_ANA_MST_I2C_BURST_STATUS_REG, I2C_ANA_MST_BURST_DONE, 0x1, 1, 1), .owner = WIFIMAC_ENTRY() },
206+
[17] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x11), SARADC_TSENS_REG, 0, 0x400000, 0, 1), .owner = WIFIMAC_ENTRY() },
207+
[18] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x12), PMU_RF_PWR_REG, 0, 0xf3800000, 0, 1), .owner = WIFIMAC_ENTRY() },
208+
[19] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x13), I2C_ANA_MST_ANA_CONF0_REG, 0x4, 0xc, 0, 1), .owner = WIFIMAC_ENTRY() }, /* BBPLL calibration disable */
188209

210+
[20] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x14), MODEM_LPCON_CLK_CONF_REG, 0, MODEM_LPCON_CLK_I2C_MST_EN_M, 0, 1), .owner = WIFIMAC_ENTRY() }, /* I2C MST disable */
211+
212+
/* PMU to trigger disable RXBLOCK */
213+
[21] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x15), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = WIFIMAC_ENTRY() },
214+
[22] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x16), WDEVTXQ_BLOCK, WDEV_RXBLOCK, 0x1000, 0, 1), .owner = WIFIMAC_ENTRY() },
215+
[23] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PHY_LINK(0x17), WDEVTXQ_BLOCK, 0, 0x6000, 0, 1), .owner = WIFIMAC_ENTRY() },
216+
217+
[24] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x18), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0), .owner = WIFIMAC_ENTRY() },
218+
[25] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x19), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1), .owner = WIFIMAC_ENTRY() }
219+
};
220+
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
221+
wifi_modem_config[4].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
222+
wifi_modem_config[15].config.write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
223+
esp_err_t err = sleep_retention_entries_create(wifi_modem_config, ARRAY_SIZE(wifi_modem_config), 7, SLEEP_RETENTION_MODULE_MODEM_PHY);
224+
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate modem phy link for wifi modem state");
225+
return ESP_OK;
226+
}
227+
#endif
228+
229+
esp_err_t sleep_modem_wifi_modem_state_init(void)
230+
{
231+
esp_err_t err = ESP_OK;
232+
233+
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
189234
static regdma_link_config_t wifi_modem_config[] = {
190235
[0] = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_FE_LINK(0), MODEM_FE_DATA_BASE, MODEM_FE_DATA_BASE, 41, 0, 0),
191236
[1] = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_FE_LINK(1), MODEM_FE_CTRL_BASE, MODEM_FE_CTRL_BASE, 87, 0, 0),
@@ -228,8 +273,9 @@ esp_err_t sleep_modem_wifi_modem_state_init(void)
228273
[27] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1a), PMU_SLP_WAKEUP_CNTL7_REG, 0x200000, 0xffff0000, 1, 0),
229274
[28] = REGDMA_LINK_WRITE_INIT(REGDMA_PHY_LINK(0x1b), PMU_SLP_WAKEUP_CNTL7_REG, 0x9730000, 0xffff0000, 0, 1)
230275
};
231-
wifi_modem_config[7].write_wait.value = I2C_BURST_VAL(cmd.config[1].host_id, cmd.config[1].start, cmd.config[1].end);
232-
wifi_modem_config[18].write_wait.value = I2C_BURST_VAL(cmd.config[0].host_id, cmd.config[0].start, cmd.config[0].end);
276+
extern uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
277+
wifi_modem_config[7].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(true);
278+
wifi_modem_config[18].write_wait.value = phy_ana_i2c_master_burst_rf_onoff(false);
233279

234280
void *link = NULL;
235281
if (s_sleep_modem.wifi.phy_link == NULL) {
@@ -248,13 +294,33 @@ esp_err_t sleep_modem_wifi_modem_state_init(void)
248294
s_sleep_modem.wifi.flags = 0;
249295
}
250296
}
297+
#elif SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
298+
if (s_sleep_modem.wifi.phy_link == NULL) {
299+
sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = sleep_modem_phy_wifi_init, .arg = NULL } } };
300+
err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_MODEM_PHY, &init_param);
301+
if (err == ESP_OK) {
302+
err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_MODEM_PHY);
303+
if (err == ESP_OK) {
304+
s_sleep_modem.wifi.phy_link = sleep_retention_find_link_by_id(REGDMA_PHY_LINK(0x00));
305+
s_sleep_modem.wifi.flags = 0;
306+
}
307+
}
308+
}
309+
#endif
251310
return err;
252311
}
253312

254313
__attribute__((unused)) void sleep_modem_wifi_modem_state_deinit(void)
255314
{
256315
if (s_sleep_modem.wifi.phy_link) {
316+
#if SOC_PM_PAU_REGDMA_LINK_WIFIMAC
257317
regdma_link_destroy(s_sleep_modem.wifi.phy_link, 0);
318+
#elif SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
319+
esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_MODEM_PHY);
320+
if (err == ESP_OK) {
321+
sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_MODEM_PHY);
322+
}
323+
#endif
258324
s_sleep_modem.wifi.phy_link = NULL;
259325
s_sleep_modem.wifi.flags = 0;
260326
}

components/esp_phy/include/esp_private/phy.h

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,12 @@ extern "C" {
1313

1414
#define ESP_CAL_DATA_CHECK_FAIL 1
1515

16-
typedef enum {
17-
PHY_I2C_MST_CMD_TYPE_OFF = 0,
18-
PHY_I2C_MST_CMD_TYPE_ON,
19-
PHY_I2C_MST_CMD_TYPE_MAX
20-
} phy_i2c_master_command_type_t;
21-
2216
typedef struct {
17+
uint8_t cmd_type; /* the command type of the current phy i2c master command memory config */
2318
struct {
2419
uint8_t start, end; /* the start and end index of phy i2c master command memory */
2520
uint8_t host_id; /* phy i2c master host id */
26-
} config[PHY_I2C_MST_CMD_TYPE_MAX];
21+
} config;
2722
} phy_i2c_master_command_attribute_t;
2823

2924
/**
@@ -88,13 +83,14 @@ void phy_xpd_tsens(void);
8883
void phy_init_flag(void);
8984
#endif
9085

91-
#if CONFIG_IDF_TARGET_ESP32C6
86+
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
9287
/**
9388
* @brief Get the configuration info of PHY i2c master command memory.
9489
*
95-
* @param attr the configuration info of PHY i2c master command memory
90+
* @param[out] attr the configuration info of PHY i2c master command memory
91+
* @param[out] size the count of PHY i2c master command memory configuration
9692
*/
97-
void phy_i2c_master_mem_cfg(phy_i2c_master_command_attribute_t *attr);
93+
void phy_i2c_master_command_mem_cfg(phy_i2c_master_command_attribute_t *attr, int *size);
9894
#endif
9995

10096
/**
@@ -217,6 +213,23 @@ void phy_ant_clr_update_flag(void);
217213
*/
218214
void phy_ant_update(void);
219215

216+
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
217+
/**
218+
* @brief Get the REGDMA config value of the BBPLL in analog i2c master burst mode
219+
*
220+
* @return the BBPLL REGDMA configure value of i2c master burst mode
221+
*/
222+
uint32_t phy_ana_i2c_master_burst_bbpll_config(void);
223+
224+
/**
225+
* @brief Get the REGDMA config value of the RF PHY on or off in analog i2c master burst mode
226+
*
227+
* @param[in] on true for enable RF PHY, false for disable RF PHY.
228+
*
229+
* @return the RF on or off configure value of i2c master burst mode
230+
*/
231+
uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on);
232+
#endif
220233

221234
#ifdef __cplusplus
222235
}

components/esp_phy/src/phy_common.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,3 +294,57 @@ esp_err_t esp_phy_get_ant(esp_phy_ant_config_t *config)
294294
memcpy(config, &s_phy_ant_config, sizeof(esp_phy_ant_config_t));
295295
return ESP_OK;
296296
}
297+
298+
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
299+
typedef enum {
300+
PHY_I2C_MST_CMD_TYPE_RF_OFF = 0,
301+
PHY_I2C_MST_CMD_TYPE_RF_ON,
302+
PHY_I2C_MST_CMD_TYPE_BBPLL_CFG,
303+
PHY_I2C_MST_CMD_TYPE_MAX
304+
} phy_i2c_master_command_type_t;
305+
306+
static uint32_t phy_ana_i2c_master_burst_config(phy_i2c_master_command_attribute_t *attr, int size, phy_i2c_master_command_type_t type)
307+
{
308+
#define I2C1_BURST_VAL(en, start, end) (((en) << 31) | ((end) << 22) | ((start) << 16))
309+
#define I2C0_BURST_VAL(en, start, end) (((en) << 15) | ((end) << 6) | ((start) << 0))
310+
311+
uint32_t brust = 0;
312+
for (int i = 0; i < size; i++) {
313+
if (attr[i].config.start == 0xff || attr[i].config.end == 0xff) /* ignore invalid configure */
314+
continue;
315+
316+
if (attr[i].cmd_type == type) {
317+
if (attr[i].config.host_id) {
318+
brust |= I2C1_BURST_VAL(1, attr[i].config.start, attr[i].config.end);
319+
} else {
320+
brust |= I2C0_BURST_VAL(1, attr[i].config.start, attr[i].config.end);
321+
}
322+
}
323+
}
324+
return brust;
325+
}
326+
327+
uint32_t phy_ana_i2c_master_burst_bbpll_config(void)
328+
{
329+
/* PHY supports 2 I2C masters, and the maximum number of configurations
330+
* supported by the I2C master command memory is the command type
331+
* (PHY_I2C_MST_CMD_TYPE_MAX) multiplied by 2 */
332+
phy_i2c_master_command_attribute_t cmd[2 * PHY_I2C_MST_CMD_TYPE_MAX];
333+
int size = sizeof(cmd) / sizeof(cmd[0]);
334+
phy_i2c_master_command_mem_cfg(cmd, &size);
335+
336+
return phy_ana_i2c_master_burst_config(cmd, size, PHY_I2C_MST_CMD_TYPE_BBPLL_CFG);
337+
}
338+
339+
uint32_t phy_ana_i2c_master_burst_rf_onoff(bool on)
340+
{
341+
/* PHY supports 2 I2C masters, and the maximum number of configurations
342+
* supported by the I2C master command memory is the command type
343+
* (PHY_I2C_MST_CMD_TYPE_MAX) multiplied by 2 */
344+
phy_i2c_master_command_attribute_t cmd[2 * PHY_I2C_MST_CMD_TYPE_MAX];
345+
int size = sizeof(cmd) / sizeof(cmd[0]);
346+
phy_i2c_master_command_mem_cfg(cmd, &size);
347+
348+
return phy_ana_i2c_master_burst_config(cmd, size, on ? PHY_I2C_MST_CMD_TYPE_RF_ON : PHY_I2C_MST_CMD_TYPE_RF_OFF);
349+
}
350+
#endif

0 commit comments

Comments
 (0)